#include<bits/stdc++.h>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)

using namespace std;

typedef pair<int,int> ii;

struct Data {
  int cur, dir, time;
  bool operator < ( const Data &data ) const {
    if( time != data.time ) return time > data.time;
    if( dir != data.dir ) return dir > data.dir;
    return cur > data.cur;
  }
};

int w,h,D,sp,ep;
int field[30][30];
map<ii,int> coef;
set<ii> S;
vector<int> wigwag;
bool visited[500][110][4];
int dx[] = {0,1,0,-1};
int dy[] = {1,0,-1,0};

bool isValid(int x,int y) { return 0 <= x && x < w && 0 <= y && y < h; }

int getPoint(string s){
  rep(i,s.size()) if( s[i] == '-' ) { s[i] = ' '; break; }
  stringstream ss;
  ss << s;
  string temp[2];
  ss >> temp[0] >> temp[1];
  int x = (atoi)(temp[1].c_str());
  int y = temp[0][0] - 'a';
  --x;
  return x + y * w;
}

void compute(){
  rep(i,h*w) rep(j,110) rep(k,4) visited[i][j][k] = false;
  visited[sp][0][1] = true;
  priority_queue<Data> Q;
  Q.push((Data){sp,1,0});
  while( !Q.empty() ){
    Data data = Q.top(); Q.pop();
    if( data.cur == ep ) { cout << data.time << endl; return; }
    rep(i,4) if( (data.dir+2)%4 != i ){
      int nx = data.cur % w + dx[i], ny = data.cur / w + dy[i];
      int next = nx + ny * w;
      if( !isValid(nx,ny) ) continue;
      ii coor = ii(data.cur,next);
      if( coor.first > coor.second ) swap(coor.first,coor.second);
      if( S.count(coor) ) continue;
      int ntime = data.time + D + coef[coor];
      if( ntime > 100 ) continue;

      if( field[ny][nx] != -1 ) {
        bool failed = false;
        int cycle = wigwag[field[ny][nx]];
        int now   = ntime / cycle;
        //cout << nx << "," << ny << " " << cycle << " and " << now << " ndir = " << i<< endl;
        if( now & 1 ) {
          if( i == 0 || i == 2 ) failed = true;
        } else {
          if( i == 1 || i == 3 ) failed = true;
        }
        if( failed ) continue;
      }
      
      if( !visited[next][ntime][i] ){
        //cout << coor.first << " < " << coor.second << endl;
        //cout << ntime << " : (" << data.cur % w << "," << data.cur / w << ") " << data.dir << " => (" << nx << "," << ny << ") dir = " << i << endl; 
        visited[next][ntime][i] = true;
        Q.push((Data){next,i,ntime});
      }
      
    }
  }
}

int main(){
  while( cin >> h >> w, w|h ){
    cin >> D;
    rep(i,h) rep(j,w) field[i][j] = -1;
    wigwag.clear();
    int temp;
    cin >> temp;
    wigwag.resize(temp);
    rep(i,temp) {
      string s;
      int k;
      cin >> s >> k;
      rep(j,s.size()) if( s[j] == '-' ) { s[j] = ' '; break; }
      stringstream ss;
      ss << s;
      string stemp[2];
      ss >> stemp[0] >> stemp[1];
      int x = (atoi)(stemp[1].c_str());
      int y = stemp[0][0] - 'a';
      --x;
      field[y][x] = wigwag.size();
      wigwag.push_back(k);
    }
    
    S.clear();
    cin >> temp;
    rep(i,temp){
      string s,s2;
      cin >> s >> s2;
      int p1 = getPoint(s), p2 = getPoint(s2);
      if( p1 > p2 ) swap(p1,p2);
      S.insert(ii(p1,p2));
    }

    coef.clear();
    cin >> temp;
    rep(i,temp){
      string s,s2;
      int itemp;
      cin >> s >> s2 >> itemp;
      int p1 = getPoint(s), p2 = getPoint(s2);
      if( p1 > p2 ) swap(p1,p2);
      coef[ii(p1,p2)] = itemp;
    }

    string ssp,sep;
    cin >> ssp >> sep;
    sp = getPoint(ssp);
    ep = getPoint(sep);

    compute();

  }
  return 0;
}

Measured memory_bytes: 1516