#include <bits/stdc++.h>
using namespace std;
int cap[1000000], flow[1000000];
int to[1000000], _prev[1000000], last[10000], used[10000], level[10000];
struct MaxFlow {
  int V, E;
  MaxFlow(int n) {
    int i;
    V = n;
    E = 0;
    for ((i) = 0; (i) < (int)(V); (i)++) last[i] = -1;
  }
  void add_edge(int x, int y, int f) {
    cap[E] = f;
    flow[E] = 0;
    to[E] = y;
    _prev[E] = last[x];
    last[x] = E;
    E++;
    cap[E] = 0;
    flow[E] = 0;
    to[E] = x;
    _prev[E] = last[y];
    last[y] = E;
    E++;
  }
  bool bfs(int s, int t) {
    int i;
    for ((i) = 0; (i) < (int)(V); (i)++) level[i] = -1;
    queue<int> q;
    q.push(s);
    level[s] = 0;
    while (!q.empty()) {
      int x = q.front();
      q.pop();
      for (i = last[x]; i >= 0; i = _prev[i])
        if (level[to[i]] == -1 && cap[i] > flow[i]) {
          q.push(to[i]);
          level[to[i]] = level[x] + 1;
        }
    }
    return (level[t] != -1);
  }
  int dfs(int v, int t, int f) {
    int i;
    if (v == t) return f;
    for (i = used[v]; i >= 0; used[v] = i = _prev[i])
      if (level[to[i]] > level[v] && cap[i] > flow[i]) {
        int tmp = dfs(to[i], t, min(f, cap[i] - flow[i]));
        if (tmp > 0) {
          flow[i] += tmp;
          flow[i ^ 1] -= tmp;
          return tmp;
        }
      }
    return 0;
  }
  int maxflow(int s, int t) {
    int i;
    while (bfs(s, t)) {
      for ((i) = 0; (i) < (int)(V); (i)++) used[i] = last[i];
      while (dfs(s, t, (1 << 29)) != 0)
        ;
    }
    int ans = 0;
    for (i = last[s]; i >= 0; i = _prev[i]) ans += flow[i];
    return ans;
  }
};
int dx[] = {1, -1, 0, 0}, dy[] = {0, 0, 1, -1};
int X, Y;
string board[30];
int dist[30][30][30][30];
int A, B;
int cx, cy, ct;
int ax[500], ay[500], at[500];
int bx[500], by[500], bt[500];
queue<int> q;
void bfs(int s, int t) {
  int i, j;
  for ((i) = 0; (i) < (int)(X); (i)++)
    for ((j) = 0; (j) < (int)(Y); (j)++) dist[s][t][i][j] = (1 << 29);
  if (board[s][t] == '#') return;
  dist[s][t][s][t] = 0;
  q.push(s);
  q.push(t);
  while (!q.empty()) {
    int x = q.front();
    q.pop();
    int y = q.front();
    q.pop();
    for ((i) = 0; (i) < (int)(4); (i)++) {
      int x2 = x + dx[i], y2 = y + dy[i];
      if (x2 >= 0 && x2 < X && y2 >= 0 && y2 < Y && board[x2][y2] != '#' &&
          dist[s][t][x2][y2] == (1 << 29)) {
        dist[s][t][x2][y2] = dist[s][t][x][y] + 1;
        q.push(x2);
        q.push(y2);
      }
    }
  }
}
bool check(long long T) {
  int i, j, k;
  MaxFlow mf(A + A + 2 * (X * Y) + 2);
  int V = A + A + 2 * (X * Y) + 2;
  for ((i) = 0; (i) < (int)(A); (i)++) mf.add_edge(V - 2, i, 1);
  for ((i) = 0; (i) < (int)(A); (i)++) mf.add_edge(A + i, V - 1, 1);
  for ((i) = 0; (i) < (int)(X * Y); (i)++)
    mf.add_edge(A + A + i, A + A + X * Y + i, 1);
  for ((i) = 0; (i) < (int)(A); (i)++)
    for ((j) = 0; (j) < (int)(X); (j)++)
      for ((k) = 0; (k) < (int)(Y); (k)++) {
        int d = dist[ax[i]][ay[i]][j][k];
        if (d != (1 << 29) && (long long)d * at[i] <= T)
          mf.add_edge(i, A + A + j * Y + k, 1);
      }
  for ((i) = 0; (i) < (int)(A); (i)++)
    for ((j) = 0; (j) < (int)(X); (j)++)
      for ((k) = 0; (k) < (int)(Y); (k)++) {
        int d = dist[bx[i]][by[i]][j][k];
        if (d != (1 << 29) && (long long)d * bt[i] <= T)
          mf.add_edge(A + A + X * Y + j * Y + k, A + i, 1);
      }
  int f = mf.maxflow(V - 2, V - 1);
  return (f == A);
}
int main(void) {
  int i, j;
  cin >> X >> Y >> A >> B;
  for ((i) = 0; (i) < (int)(X); (i)++) cin >> board[i];
  for ((i) = 0; (i) < (int)(X); (i)++)
    for ((j) = 0; (j) < (int)(Y); (j)++) bfs(i, j);
  cin >> cx >> cy >> ct;
  for ((i) = 0; (i) < (int)(A); (i)++) cin >> ax[i] >> ay[i] >> at[i];
  for ((i) = 0; (i) < (int)(B); (i)++) cin >> bx[i] >> by[i] >> bt[i];
  cx--;
  cy--;
  for ((i) = 0; (i) < (int)(A); (i)++) {
    ax[i]--;
    ay[i]--;
  }
  for ((i) = 0; (i) < (int)(B); (i)++) {
    bx[i]--;
    by[i]--;
  }
  if (A < B) {
    ax[A] = cx;
    ay[A] = cy;
    at[A] = ct;
    A++;
  } else {
    bx[B] = cx;
    by[B] = cy;
    bt[B] = ct;
    B++;
  }
  if (A != B) {
    cout << -1 << endl;
    return 0;
  }
  long long low = -1, high = (1ll << 40);
  while (high - low > 1) {
    long long mid = (low + high) / 2;
    if (check(mid))
      high = mid;
    else
      low = mid;
  }
  if (high == (1ll << 40)) high = -1;
  cout << high << endl;
  return 0;
}
