#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


enum DIR{
	NONE,
	TATE,
	YOKO,
};

enum Type{
	North,
	East,
	South,
	West,
};

struct Data{
	Data(int arg_row,int arg_col,int arg_cost){
		row = arg_row;
		col = arg_col;
		cost = arg_cost;
	}
	int row,col,cost;
};

struct Info{
	Info(int arg_row,int arg_col,int arg_pre_row,int arg_pre_col,int arg_time,Type arg_dir){
		row = arg_row;
		col = arg_col;
		pre_row = arg_pre_row;
		pre_col = arg_pre_col;
		time = arg_time;
		dir = arg_dir;
	}
	bool operator<(const struct Info &arg) const{
		return time > arg.time;
	}
	int row,col,pre_row,pre_col,time;
	Type dir;
};


int H,W,D;
int num_light,num_load,num_delay;
int cicle[20][20],work_cicle[101][20][20],add_cost[20][20][20][20];
int diff_row[4] = {-1,0,0,1},diff_col[4] = {0,-1,1,0};
bool is_ok[20][20][20][20],is_delay[20][20][20][20],check[20][20][101][4];
DIR light[101][20][20];
vector<Data> G[20][20];

bool rangeCheck(int row,int col){
	if(row >= 0 && row <= H-1 && col >= 0 && col <= W-1)return true;
	else{
		return false;
	}
}

void calc_light(){

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			if(cicle[row][col] == -1){
				light[0][row][col] = NONE;
			}else{
				light[0][row][col] = TATE;
			}
			work_cicle[0][row][col] = cicle[row][col];
		}
	}

	for(int time = 1; time <= 100; time++){

		for(int row = 0; row < H; row++){
			for(int col = 0; col < W; col++){
				if(work_cicle[time-1][row][col] == -1){
					work_cicle[time][row][col] = -1;
					light[time][row][col] = NONE;
				}else{
					work_cicle[time][row][col] = work_cicle[time-1][row][col]-1;
					if(work_cicle[time][row][col] == 0){

						work_cicle[time][row][col] = cicle[row][col];
						if(light[time-1][row][col] == TATE){
							light[time][row][col] = YOKO;
						}else{
							light[time][row][col] = TATE;
						}
					}else{
						light[time][row][col] = light[time-1][row][col];
					}
				}
			}
		}
	}
}



void func(){
	scanf("%d",&D);

	scanf("%d",&num_light);

	char buf[10];
	int tmp_row,tmp_col,tmp_cicle;

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			cicle[row][col] = -1;
		}
	}

	for(int i = 0; i < num_light; i++){
		scanf("%s %d",buf,&tmp_cicle);

		tmp_row = buf[0]-'a';
		tmp_col = buf[2]-'0';
		if(buf[3] != '\0'){
			tmp_col = 10*tmp_col+buf[3]-'0';
		}
		tmp_col--;
		cicle[tmp_row][tmp_col] = tmp_cicle;
	}

	scanf("%d",&num_load);

	for(int a = 0; a < H; a++){
		for(int b = 0; b < W; b++){
			for(int c = 0; c < H; c++){
				for(int d = 0; d < W; d++){
					is_ok[a][b][c][d] = true;
				}
			}
		}
	}

	int from_row,from_col,to_row,to_col;

	for(int i = 0; i < num_load; i++){
		scanf("%s",buf);

		from_row = buf[0]-'a';
		from_col = buf[2]-'0';
		if(buf[3] != '\0'){
			from_col = 10*from_col+buf[3]-'0';
		}
		from_col--;

		scanf("%s",buf);

		to_row = buf[0]-'a';
		to_col = buf[2]-'0';
		if(buf[3] != '\0'){
			to_col = 10*to_col+buf[3]-'0';
		}
		to_col--;
		is_ok[from_row][from_col][to_row][to_col] = false;
		is_ok[to_row][to_col][from_row][from_col] = false;
	}

	scanf("%d",&num_delay);

	for(int a = 0; a < H; a++){
		for(int b = 0; b < W; b++){
			for(int c = 0; c < H; c++){
				for(int d = 0; d < W; d++){
					is_delay[a][b][c][d] = false;
				}
			}
		}
	}

	int tmp_add;

	for(int i = 0; i < num_delay; i++){
		scanf("%s",buf);

		from_row = buf[0]-'a';
		from_col = buf[2]-'0';
		if(buf[3] != '\0'){
			from_col = 10*from_col+buf[3]-'0';
		}
		from_col--;

		scanf("%s %d",buf,&tmp_add);

		to_row = buf[0]-'a';
		to_col = buf[2]-'0';
		if(buf[3] != '\0'){
			to_col = 10*to_col+buf[3]-'0';
		}
		to_col--;

		is_delay[from_row][from_col][to_row][to_col] = true;
		is_delay[to_row][to_col][from_row][from_col] = true;
		add_cost[from_row][from_col][to_row][to_col] = tmp_add;
		add_cost[to_row][to_col][from_row][from_col] = tmp_add;
	}

	int start_row,start_col,goal_row,goal_col;

	scanf("%s",buf);

	start_row = buf[0]-'a';
	start_col = buf[2]-'0';
	if(buf[3] != 0){
		start_col = 10*start_col+buf[3]-'0';
	}
	start_col--;

	scanf("%s",buf);

	goal_row = buf[0]-'a';
	goal_col = buf[2]-'0';
	if(buf[3] != '\0'){
		goal_col = 10*goal_col+buf[3]-'0';
	}
	goal_col--;

	calc_light();

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++)G[row][col].clear();
	}

	int adj_row,adj_col;
	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){

			for(int i = 0; i < 4; i++){
				adj_row = row+diff_row[i];
				adj_col = col+diff_col[i];

				if(rangeCheck(adj_row,adj_col) == false || is_ok[row][col][adj_row][adj_col] == false)continue;

				if(is_delay[row][col][adj_row][adj_col]){
					G[row][col].push_back(Data(adj_row,adj_col,D+add_cost[row][col][adj_row][adj_col]));
				}else{
					G[row][col].push_back(Data(adj_row,adj_col,D));
				}
			}
		}
	}

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			for(int time = 0; time <= 100; time++){
				for(int dir = 0; dir < 4; dir++)check[row][col][time][dir] = false;
			}
		}
	}

	check[start_row][start_col][0][East] = true;
	priority_queue<Info> Q;

	Q.push(Info(start_row,start_col,start_row,start_col-1,0,East));

	int next_time,next_row,next_col,next_cost;
	Type next_dir;

	while(!Q.empty()){

		if(Q.top().row == goal_row && Q.top().col == goal_col){
			printf("%d\n",Q.top().time);
			return;
		}else{

			for(int i = 0; i < G[Q.top().row][Q.top().col].size(); i++){

				next_row = G[Q.top().row][Q.top().col][i].row;
				next_col = G[Q.top().row][Q.top().col][i].col;

				if(next_row == Q.top().pre_row && next_col == Q.top().pre_col)continue;

				if(next_row == Q.top().row){
					if(next_col < Q.top().col){
						next_dir = West;
					}else{
						next_dir = East;
					}
				}else{
					if(next_row < Q.top().row){
						next_dir = North;
					}else{
						next_dir = South;
					}
				}

				next_cost = G[Q.top().row][Q.top().col][i].cost;
				next_time = Q.top().time+next_cost;

				if(next_time > 100)continue;

				if(light[next_time][next_row][next_col] == TATE && (next_dir == West || next_dir == East))continue;

				if(light[next_time][next_row][next_col] == YOKO && (next_dir == North || next_dir == South))continue;

				if(check[next_row][next_col][next_time][next_dir])continue;

				check[next_row][next_col][next_time][next_dir] = true;
				Q.push(Info(next_row,next_col,Q.top().row,Q.top().col,next_time,next_dir));
			}
			Q.pop();
		}
	}
}

int main(){

	while(true){
		scanf("%d %d",&H,&W);
		if(H == 0 && W == 0)break;

		func();
	}

	return 0;
}

