#include<iostream>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<functional>

#define MAX 21

#define INV (-1)
#define ALL 0
#define SN 1
#define WE 2

#define NA 100

const int di[] = {-1,0,1,0};
const int dj[] = {0,1,0,-1};

using namespace std;

bool isinside( int i ,int j , int m, int n ){
  return 0<=i&&i<m&&0<=j&&j<n;
}

class Signal{
public:

  bool sig[MAX][MAX]; // allowable pass direction
  int sig_freq[MAX][MAX];

  Signal(){
    for(int i = 0; i < MAX; ++i){
      for(int j = 0; j < MAX; ++j){
	sig[i][j] = false;
	sig_freq[i][j] = 0;
      }
    }
  }

  bool getEnterableAt(int fromi, int fromj, int i, int j, int t)const{
    if( !sig[i][j] ) return true;
    else{
      int dir = (fromi == i ? SN : WE);
      int div = t / sig_freq[i][j];
      if( div % 2 == 1 ) return dir == SN;
      else return dir == WE;
    }
  }

};

class State{
public:
  int prei, prej;
  int i,j;
  int cost;
  State():i(0),j(0),cost(0){}
  State(int pi, int pj, int i, int j, int cost):
    prei(pi),prej(pj),i(i),j(j),cost(cost){}
  bool operator>(const State &t)const{
    return cost > t.cost;
  }
};

bool adj[MAX][MAX][MAX][MAX];
int add[MAX][MAX][MAX][MAX];

void ResetGraph()
{
  for(int i = 0; i < MAX; ++i){
    for(int j = 0; j < MAX; ++j){
      for(int k = 0; k < MAX; ++k){
	for(int l = 0; l < MAX; ++l){
	  adj[i][j][k][l] = true;
	  add[i][j][k][l] = 0;
	}
      }
    }
  }
}

int getShortestTime(int m, int n, int D,
		    int si, int sj, int gi, int gj,
		    const Signal &sig)
{
  State init(si,sj,si,sj,0);
  priority_queue< State,vector<State>,greater<State> > q;

  static bool vis[MAX][MAX][MAX][MAX][101];
  fill( &vis[0][0][0][0][0], &vis[MAX-1][MAX-1][MAX-1][MAX-1][100], false);
  
  q.push( init );
  while(!q.empty()){

    State now = q.top();
    q.pop();
    
    //cout << "(" << now.i << ',' << now.j << "), from (" << now.prei << "," << now.prej << ") cost = " << now.cost << endl;

    if( now.cost + D*(abs(now.i-gi)+abs(now.j-gj)) > NA ) continue;
    if( now.i == gi && now.j == gj ) return now.cost;

    if( vis[now.prei][now.prej][now.i][now.j][now.cost] )continue;
    vis[now.prei][now.prej][now.i][now.j][now.cost] = true;
    
    for(int k = 0; k < sizeof(di)/sizeof(*di); ++k){

      int ti = now.i + di[k];
      int tj = now.j + dj[k];

      //cout << "(" << ti << ',' << tj << ")" << endl;

      if( !isinside( ti, tj, m, n ) ) continue;
      if( ti == now.prei && tj == now.prej ) continue;
      if( !adj[now.i][now.j][ti][tj] ) continue;

      int ncost = now.cost + D + add[now.i][now.j][ti][tj];
      if( !sig.getEnterableAt( now.i, now.j, ti, tj, ncost ) ) continue;

      q.push( State( now.i, now.j, ti, tj, ncost ) );
    }
    
  }

  return -1;
}

int main()
{
  while(true){
    int M,N;
    Signal sigs;
    cin >> M >> N;
    if( M == 0 && N == 0 ) break;

    ResetGraph();

    int D;
    cin >> D;
    int ns;
    cin >> ns;
    for(int i = 0; i < ns; ++i){
      char y,c;
      int x,k;
      cin >> y >> c >> x >> k;
      y-='a';
      x--;

      sigs.sig[y][x] = true;
      sigs.sig_freq[y][x] = k;
    }
    int nc;
    cin >> nc;
    for(int i = 0; i < nc; ++i){
      char y,c,y2;
      int x,x2;
      cin >> y >> c >> x >> y2 >> c >> x2;
      y-='a';
      y2-='a';
      --x;
      --x2;

      adj[y][x][y2][x2]=false;
      adj[y2][x2][y][x]=false;
    }
    int nj;
    cin >> nj;
    for(int i = 0; i < nj; ++i){
      char y,c,y2;
      int x,x2;
      int d;
      cin >> y >> c >> x >> y2 >> c >> x2 >> d;
      y-='a';
      y2-='a';
      --x;
      --x2;

      add[y][x][y2][x2]=d;
      add[y2][x2][y][x]=d;
      
    }

    char sy,gy,c;
    int sx,gx;
    cin >> sy >> c >> sx >> gy >> c >> gx;
    sy-='a';--sx;
    gy-='a';--gx;
    
    cout << getShortestTime( M,N,D,sy,sx,gy,gx,sigs ) << endl;
  }
  return 0;
}

Measured memory_bytes: 20000