#include <algorithm>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <vector>

using namespace std;

#define reps(i,f,n) for(int i=f; i<int(n); ++i)
#define rep(i,n) reps(i,0,n)

typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;

const int INF = 1001001001;

pii convert(const char* str)
{
	return pii(str[0]-'a', atoi(str+2)-1);
}

const int dy[] = {-1, 0, 1, 0};
const int dx[] = {0, -1, 0, 1};

struct Data
{
	int y, x, d, t;
	Data(int y, int x, int d, int t) : y(y), x(x), d(d), t(t) {}
	bool operator< (const Data& d)const{
		return t > d.t;
	}
};

int main()
{
	int h, w;
	while(scanf("%d%d", &h, &w), h){
		int D, ns;
		scanf("%d%d", &D, &ns);

		int sign[20][20] = {{0}};
		rep(i, ns){
			char str[128];
			int k;
			scanf("%s%d", str, &k);
			pii p = convert(str);
			sign[p.first][p.second] = k;
		}

		bool work[20][20][4] = {{{false}}};
		int nc;
		scanf("%d", &nc);
		rep(i, nc){
			char str1[128], str2[128];
			scanf("%s%s", str1, str2);
			pii p1 = convert(str1), p2 = convert(str2);
			rep(j, 4){
				if(pii(p1.first+dy[j], p1.second+dx[j]) == p2){
					work[p1.first][p1.second][j] = true;
					work[p2.first][p2.second][(j+2)%2] = true;
					break;
				}
			}
		}

		int cost[20][20][4] = {{{0}}};
		int nj;
		scanf("%d", &nj);
		rep(i, nj){
			char str1[128], str2[128];
			int d;
			scanf("%s%s%d", str1, str2, &d);
			pii p1 = convert(str1), p2 = convert(str2);
			rep(j, 4){
				if(pii(p1.first+dy[j], p1.second+dx[j]) == p2){
					cost[p1.first][p1.second][j] = d;
					cost[p2.first][p2.second][(j+2)%2] = d;
					break;
				}
			}
		}

		char str1[128], str2[128];
		scanf("%s%s", str1, str2);
		pii start = convert(str1), goal = convert(str2);

		int ans = -1;
		bool visited[20][20][4][101] = {{{{false}}}};
		priority_queue<Data> Q;
		Q.push(Data(start.first, start.second, 3, 0));
		while(!Q.empty()){
			Data d = Q.top();
			Q.pop();
			if(visited[d.y][d.x][d.d][d.t])
				continue;
			visited[d.y][d.x][d.d][d.t] = true;
			if(d.y==goal.first && d.x==goal.second){
				ans = d.t;
				break;
			}
			rep(i, 4){
				if(abs(d.d-i) == 2 || work[d.y][d.x][i])
					continue;

				int py = d.y + dy[i];
				int px = d.x + dx[i];
				if(py<0 || h<=py || px<0 || w<=px)
					continue;

				int pt = d.t + D + cost[d.y][d.x][i];
				if(sign[py][px]==0 || (((pt/sign[py][px])%2) ^ (i%2==0))){
					Q.push(Data(py, px, i, pt));
				}
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}