#include <bits/stdc++.h>
using namespace std;
template <class T>
inline void smin(T &a, T b) {
  if (a > b) a = b;
}
template <class T>
inline void smax(T &a, T b) {
  if (a < b) a = b;
}
int V, E, src, tar;
int head[60000], work[60000], dis[60000];
int to[2000000], cap[2000000], nxt[2000000];
int q[60000], qf, qb;
void init(int n) {
  memset(head, -1, sizeof(int) * n);
  V = n;
  E = 0;
}
void add_edge(int u, int v, int c) {
  to[E] = v;
  cap[E] = c;
  nxt[E] = head[u];
  head[u] = E++;
  to[E] = u;
  cap[E] = 0;
  nxt[E] = head[v];
  head[v] = E++;
}
bool bfs() {
  memset(dis, -1, sizeof(dis));
  qf = qb = 0;
  q[qb++] = src;
  dis[src] = 0;
  while (qf < qb && dis[tar] == -1) {
    int u = q[qf++];
    for (int i = head[u]; i >= 0; i = nxt[i]) {
      int v = to[i];
      if (dis[v] == -1 && cap[i] > 0) {
        dis[v] = dis[u] + 1;
        q[qb++] = v;
      }
    }
  }
  return dis[tar] >= 0;
}
int dfs(int u, int &bot) {
  int v, bot1, delta;
  if (u == tar) return bot;
  for (int &i = work[u]; i >= 0; i = nxt[i]) {
    v = to[i];
    if (dis[v] != dis[u] + 1 || cap[i] == 0) continue;
    bot1 = min(bot, cap[i]);
    if (delta = dfs(v, bot1)) {
      cap[i] -= delta;
      cap[i ^ 1] += delta;
      bot = bot1;
      return delta;
    }
  }
  return 0;
}
int dinic() {
  int ans = 0, delta, bot;
  while (bfs()) {
    memcpy(work, head, sizeof(int) * V);
    delta = 0x3f3f3f3f;
    while (delta = dfs(src, bot = 0x3f3f3f3f)) ans += delta;
  }
  return ans;
}
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int n, m, dst[33][33][33][33];
char grid[33][33];
int c[2], x[2][33 * 33], y[2][33 * 33], t[2][33 * 33];
bool can(long long mid) {
  int A = c[0], nm = n * m;
  src = A * 2 + 2 * nm, tar = src + 1;
  init(tar + 10);
  for (int i = (0); i < (A); i++) add_edge(src, i, 1);
  for (int i = (0); i < (A); i++) add_edge(A + 2 * nm + i, tar, 1);
  for (int i = (0); i < (nm); i++) add_edge(A + i, A + nm + i, 1);
  for (int r = (0); r < (2); r++)
    for (int k = (0); k < (A); k++)
      for (int i = (0); i < (n); i++)
        for (int j = (0); j < (m); j++) {
          if (grid[i][j] == '#') continue;
          int xx = x[r][k], yy = y[r][k], tt = t[r][k];
          if (dst[xx][yy][i][j] < 1000 &&
              (long long)dst[xx][yy][i][j] * tt <= mid) {
            if (!r)
              add_edge(k, A + i * m + j, 1);
            else
              add_edge(A + nm + i * m + j, k + A + 2 * nm, 1);
          }
        }
  return dinic() == A;
}
int main() {
  ;
  scanf("%d%d%d%d", &n, &m, &c[0], &c[1]);
  for (int i = (0); i < (n); i++) scanf("%s", grid[i]);
  int u, v, w;
  scanf("%d%d%d", &u, &v, &w);
  u--;
  v--;
  for (int i = (0); i < (2); i++)
    for (int j = (0); j < (c[i]); j++) {
      scanf("%d%d%d", &x[i][j], &y[i][j], &t[i][j]);
      x[i][j]--;
      y[i][j]--;
    }
  if (c[0] < c[1]) {
    x[0][c[0]] = u;
    y[0][c[0]] = v;
    t[0][c[0]++] = w;
  } else {
    x[1][c[1]] = u;
    y[1][c[1]] = v;
    t[1][c[1]++] = w;
  }
  if (c[0] != c[1]) {
    puts("-1");
    return 0;
  }
  memset(dst, 0x3f, sizeof(dst));
  for (int i = (0); i < (n); i++)
    for (int j = (0); j < (m); j++) {
      if (grid[i][j] == '#') continue;
      qb = qf = 0;
      q[qb++] = i;
      q[qb++] = j;
      dst[i][j][i][j] = 0;
      while (qb > qf) {
        u = q[qf++];
        v = q[qf++];
        for (int k = (0); k < (4); k++) {
          int uu = u + dx[k], vv = v + dy[k];
          if ((uu < 0 || vv < 0 || uu >= n || vv >= m)) continue;
          if (grid[uu][vv] == '#') continue;
          if (dst[i][j][uu][vv] > dst[i][j][u][v] + 1) {
            dst[i][j][uu][vv] = dst[i][j][u][v] + 1;
            q[qb++] = uu;
            q[qb++] = vv;
          }
        }
      }
    }
  long long st = -1, ed = (1LL << 40), mid;
  while (st + 1 < ed) {
    mid = (st + ed) >> 1;
    if (can(mid))
      ed = mid;
    else
      st = mid;
  }
  if (ed == (1LL << 40))
    puts("-1");
  else
    printf("%I64d\n", ed);
  return 0;
}
