#include <iostream>
#include <queue>
#include <algorithm>
#include <string>
#include <utility>
#include <cstdio>
using namespace std;

// inputs
int N, M;
int D;
int ns, nc, nj;

const int margin = 2;
bool visited[32][32][128][4];
int map[64][64];

struct status {
	int x, y;
	int t;
	int d;
	status() {}
	status(int x_, int y_, int t_, int d_) {
		x = x_; y = y_; t = t_; d = d_;
	}
	bool operator<(const status obj) const {
		return this->t > obj.t;
	}
};

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

int gcd(int a, int b) {
	return a % b == 0 ? b : gcd(b, a % b);
}
int lcm(int a, int b) {
	return a * b / gcd(a, b);
}

pair<int,int> to_coord(string s) {
	string tmp(s.begin() + 2, s.end());
	int x = 0;
	for(int i = 0; i < tmp.size(); i++) {
		x *= 10;
		x += tmp[i] - '0';
	}
	return pair<int,int>(x - 1, s[0] - 'a');
}

int main() {
	while(cin >> M >> N, M || N) {
		cin >> D;
		for(int i = 0; i < 64; i++)
			for(int j = 0; j < 64; j++)
				map[i][j] = -1;
		for(int i = 0; i < M; i++) {
			for(int j = 0; j < N; j++) {
				map[i*2 + margin][j%(N-1)*2+1 + margin] = D;
				map[i%(M-1)*2+1 + margin][j*2 + margin] = D;
			}
		}
		for(int i = 0; i < 32; i++)
			for(int j = 0; j < 32; j++)
				for(int k = 0; k < 128; k++)
					for(int l = 0; l < 4; l++)
						visited[i][j][k][l] = false;
		cin >> ns;
		for(int i = 0; i < ns; i++) {
			string tmp;
			int k;
			pair<int,int> coord;
			cin >> tmp >> k;
			coord = to_coord(tmp);
			map[coord.second * 2 + margin][coord.first * 2 + margin] = k;
		}
		cin >> nc;
		for(int i = 0; i < nc; i++) {
			string tmp0, tmp1;
			pair<int,int> coord0, coord1;
			cin >> tmp0 >> tmp1;
			coord0 = to_coord(tmp0);
			coord1 = to_coord(tmp1);
			map[coord0.second + coord1.second + margin][coord0.first + coord1.first + margin] = -1;
		}
		cin >> nj;
		for(int i = 0; i < nj; i++) {
			string tmp0, tmp1;
			int d;
			pair<int,int> coord0, coord1;
			cin >> tmp0 >> tmp1 >> d;
			coord0 = to_coord(tmp0);
			coord1 = to_coord(tmp1);
			map[coord0.second + coord1.second + margin][coord0.first + coord1.first + margin] = D + d;
		}

		/*
		for(int i = 0; i < 32; i++) {
			for(int j = 0; j < 32; j++) {
				if(map[i][j] < 0)
					printf(" x");
				else
					printf("% 2d", map[i][j]);
			}
			putchar('\n');
		}
		// */

		string start_str, goal_str;
		pair<int,int> start, goal;
		cin >> start_str >> goal_str;
		start = to_coord(start_str);
		goal = to_coord(goal_str);

		// dijkstra
		priority_queue<status> q;
		q.push(status(start.first, start.second, 0, 1));
		visited[start.second][start.first][0][1] = true;

		while(!q.empty()) {
			status cur;
			cur = q.top(); q.pop();
		//	cout << cur.x << " " << cur.y << " " << cur.t << endl;
			if(cur.x == goal.first && cur.y == goal.second) {
				cout << cur.t << endl;
				break;
			}

			for(int i = 0; i < 4; i++) {
				bool flg = true;
				flg &= !(map[cur.y * 2 + dy[i] + margin][cur.x * 2 + dx[i] + margin] < 0);
				flg &= !visited[cur.y + dy[i]][cur.x + dx[i]][cur.t + map[cur.y * 2 + dy[i] + margin][cur.x* 2 + dx[i] + margin]][i];
				flg &= dx[i]*dx[cur.d] + dy[i]*dy[cur.d] >= 0;
				flg &= (map[(cur.y + dy[i]) * 2 + margin][(cur.x + dx[i]) * 2 + margin] < 0)
					|| (((cur.t + map[cur.y * 2 + dy[i] + margin][cur.x * 2 + dx[i] + margin]) / map[(cur.y + dy[i]) * 2 + margin][(cur.x + dx[i]) * 2 + margin]) % 2
							== !(i / 2));
				if(flg) {
					q.push(status(cur.x + dx[i], cur.y + dy[i], cur.t + map[cur.y * 2 + dy[i] + margin][cur.x * 2 + dx[i] + margin], i));
					visited[cur.y + dy[i]][cur.x + dx[i]][cur.t + map[cur.y * 2 + dy[i] + margin][cur.x * 2 + dx[i] + margin]][i] = true;
				}
			}
		}
	}
}