#include <bits/stdc++.h>
using namespace std;
int w, h;
int n;
char s[25][25];
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
int x[25 * 25], y[25 * 25], t[25 * 25];
int X[25 * 25], Y[25 * 25], T[25 * 25];
int flag[25][25], tot;
int chk[25][25], chkn;
int sink;
void End() {
  puts("-1");
  exit(0);
}
void input() {
  int na = 0, nb = 0;
  int nn, mm;
  scanf("%d %d %d %d", &w, &h, &nn, &mm);
  for (int i = 1; i <= w; i++) scanf("%s", s[i] + 1);
  for (int i = 1; i <= w; i++)
    for (int j = 1; j <= h; j++)
      if (s[i][j] != '#') flag[i][j] = ++tot;
  if (nn == mm) End();
  if (nn > mm + 1 || mm > nn + 1) End();
  if (nn == mm - 1) {
    scanf("%d %d %d", &x[1], &y[1], &t[1]);
    na++;
  } else {
    scanf("%d %d %d", &X[1], &Y[1], &T[1]);
    nb++;
  }
  for (int i = 1; i <= nn; i++) {
    ++na;
    scanf("%d %d %d", &x[na], &y[na], &t[na]);
  }
  for (int i = 1; i <= mm; i++) {
    ++nb;
    scanf("%d %d %d", &X[nb], &Y[nb], &T[nb]);
  }
  n = na;
  for (int i = 0; i <= w + 1; i++)
    for (int j = 0; j <= h + 1; j++)
      if (!i || !j || i > w || j > h || s[i][j] == '#') {
        chk[i][j] = 1e8;
      }
  sink = n + tot + tot + n + 1;
}
const int MaxV = 100000;
const int MaxE = MaxV * 10;
const int inf = 1000000000;
struct Goldberg_Tarjan {
  int head[MaxV];
  int cap[MaxE], to[MaxE], next[MaxE];
  int ecnt;
  int maxFlow;
  int height[MaxV], C[MaxV];
  int S, T, V;
  void init() {
    memset(head, -1, sizeof(int) * (sink + 10));
    memset(height, 0, sizeof(int) * (sink + 10));
    memset(C, 0, sizeof(C));
    ecnt = 0;
  }
  void add(int s, int e, int c) {
    cap[ecnt] = c, to[ecnt] = e, next[ecnt] = head[s], head[s] = ecnt++;
    cap[ecnt] = 0, to[ecnt] = s, next[ecnt] = head[e], head[e] = ecnt++;
  }
  int ISAP(int x, int y) {
    int mn = V - 1, F = 0, R = y, t;
    if (x == T) return y;
    for (int i = head[x]; i != -1; i = next[i]) {
      if (cap[i] > 0) {
        if (height[x] == height[to[i]] + 1) {
          t = ISAP(to[i], min(cap[i], R));
          cap[i] -= t;
          cap[i ^ 1] += t;
          R -= t;
          F += t;
          if (height[S] >= V) return F;
          if (!R) break;
        }
        mn = min(mn, height[to[i]]);
      }
    }
    if (!F) {
      C[height[x]]--;
      if (!C[height[x]]) height[S] = V;
      height[x] = mn + 1;
      C[height[x]]++;
    }
    return F;
  }
  int GT(int src, int dst, int cnt) {
    S = src, T = dst, V = cnt;
    C[0] = V;
    maxFlow = 0;
    while (height[S] < V) maxFlow += ISAP(S, inf);
    return maxFlow;
  }
} G;
int q[25 * 25 * 2], st, en;
int d[25][25];
void prepare(int id, int x, int y, int t, long long dis) {
  st = en = 0;
  chk[x][y] = ++chkn;
  q[++en] = x;
  q[++en] = y;
  d[x][y] = 0;
  dis /= t;
  if (dis > 1ll * w * h)
    t = w * h;
  else
    t = dis;
  int X, Y, i;
  while (st < en) {
    x = q[++st], y = q[++st];
    if (id <= n)
      G.add(id, n + flag[x][y], 1);
    else
      G.add(n + tot + flag[x][y], id, 1);
    if (d[x][y] == t) continue;
    for (i = 0; i < 4; i++) {
      X = x + dx[i], Y = y + dy[i];
      if (chk[X][Y] >= chkn) continue;
      chk[X][Y] = chkn;
      q[++en] = X;
      q[++en] = Y;
      d[X][Y] = d[x][y] + 1;
    }
  }
}
bool ok(long long dis) {
  G.init();
  for (int i = 1; i <= n; i++) {
    prepare(i, x[i], y[i], t[i], dis);
  }
  for (int j = 1; j <= n; j++) {
    prepare(j + tot + tot + n, X[j], Y[j], T[j], dis);
  }
  for (int i = 1; i <= tot; i++) G.add(n + i, n + tot + i, 1);
  for (int i = 1; i <= n; i++) G.add(0, i, 1);
  for (int i = 1; i <= n; i++) G.add(n + tot + tot + i, sink, 1);
  int max_flow = G.GT(0, sink, sink + 1);
  return max_flow == n;
}
void solve() {
  long long mn = 0, mx = 1e12;
  if (ok(mn)) {
    puts("0");
    return;
  }
  if (!ok(mx)) {
    End();
  }
  while (mn < mx - 1) {
    long long mid = (mn + mx) / 2;
    if (ok(mid))
      mx = mid;
    else
      mn = mid;
  }
  printf("%I64d\n", mx);
}
int main() {
  input();
  solve();
  return 0;
}
