#include <bits/stdc++.h>
using namespace std;
const long long INF = 1 << 28;
const long long LINF = 1ll << 61;
inline long long getnum() {
  register long long r = 0;
  register bool ng = 0;
  register char c;
  c = getchar();
  while (c != '-' && (c < '0' || c > '9')) c = getchar();
  if (c == '-') ng = 1, c = getchar();
  while (c != ' ' && c != '\n') r = r * 10 + c - '0', c = getchar();
  if (ng) r = -r;
  return r;
}
template <class T>
inline void putnum(T x) {
  if (x < 0) putchar('-'), x = -x;
  register short a[20] = {}, sz = 0;
  while (x > 0) a[sz++] = x % 10, x /= 10;
  if (sz == 0) putchar('0');
  for (int i = sz - 1; i >= 0; i--) putchar('0' + a[i]);
}
inline void putsp() { putchar(' '); }
inline void putendl() { putchar('\n'); }
inline char mygetchar() {
  register char c = getchar();
  while (c == ' ' || c == '\n') c = getchar();
  return c;
}
struct graph {
  int curflow, head[2000], to[1000000], nxt[1000000], cap[1000000], tot;
  void init() {
    memset(head, 0, sizeof(head));
    tot = 1;
    curflow = 0;
  }
  void operator=(const graph &tmp) {
    curflow = tmp.curflow;
    for (int i = 0; i < 2000; i++) head[i] = tmp.head[i];
    tot = tmp.tot;
    for (int i = 0; i <= tot; i++)
      to[i] = tmp.to[i], nxt[i] = tmp.nxt[i], cap[i] = tmp.cap[i];
  }
  int dis[2000], que[2000], qb, qe;
  void bfs(int S) {
    memset(dis, -1, sizeof(dis));
    dis[S] = 0;
    qb = qe = 0;
    que[qe++] = S;
    while (qb < qe) {
      int x = que[qb++];
      for (int i = head[x]; i; i = nxt[i]) {
        if (cap[i] && dis[to[i]] == -1) {
          dis[to[i]] = dis[x] + 1;
          que[qe++] = to[i];
        }
      }
    }
  }
  int it[2000];
  int dfs(int x, int T, int f) {
    if (x == T) return f;
    for (int &i = it[x]; i; i = nxt[i]) {
      if (cap[i] && dis[x] + 1 == dis[to[i]]) {
        int d = dfs(to[i], T, min(f, cap[i]));
        if (d > 0) {
          cap[i] -= d;
          cap[i ^ 1] += d;
          return d;
        }
      }
    }
    return 0;
  }
  int max_flow(int S, int T) {
    int flow = 0;
    while (true) {
      bfs(S);
      if (dis[T] == -1) {
        curflow += flow;
        return curflow;
      }
      for (int i = 0; i < 2000; i++) it[i] = head[i];
      int f;
      while ((f = dfs(S, T, INF)) > 0) flow += f;
    }
  }
  void add_edge(int x, int y, int c) {
    nxt[++tot] = head[x];
    head[x] = tot;
    to[tot] = y;
    cap[tot] = c;
    nxt[++tot] = head[y];
    head[y] = tot;
    to[tot] = x;
    cap[tot] = 0;
  }
} last, cur;
int n, m, n1, n2;
int dis[500][500];
int id[23][23];
vector<int> con[500];
char g[23][23];
vector<pair<int, int> > v1, v2;
const int dx[] = {1, -1, 0, 0};
const int dy[] = {0, 0, 1, -1};
pair<int, int> readperson() {
  int r, c, t;
  r = getnum(), c = getnum(), t = getnum();
  return make_pair(id[r][c], t);
}
void bfs(int x) {
  dis[x][x] = 0;
  queue<int> q;
  q.push(x);
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int i = 0; i < con[u].size(); i++) {
      if (dis[x][con[u][i]] == -1) {
        dis[x][con[u][i]] = dis[x][u] + 1;
        q.push(con[u][i]);
      }
    }
  }
}
int main() {
  n = getnum(), m = getnum();
  n1 = getnum(), n2 = getnum();
  if (n1 + 1 != n2 && n2 + 1 != n1) {
    puts("-1");
    return 0;
  }
  int ttot = 0;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) {
      g[i][j] = mygetchar();
      if (g[i][j] == '.') {
        id[i][j] = ++ttot;
      }
    }
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) {
      if (g[i][j] == '.') {
        for (int _ = 0; _ < 4; _++) {
          int ni = i + dx[_], nj = j + dy[_];
          if (ni > 0 && ni <= n && nj > 0 && nj <= m && g[ni][nj] == '.') {
            con[id[i][j]].push_back(id[ni][nj]);
          }
        }
      }
    }
  v1.push_back(make_pair(0, 0));
  v2.push_back(make_pair(0, 0));
  if (n1 < n2)
    v1.push_back(readperson());
  else
    v2.push_back(readperson());
  for (int i = 1; i <= n1; i++) v1.push_back(readperson());
  for (int i = 1; i <= n2; i++) v2.push_back(readperson());
  if (n1 < n2) n1++;
  if (n1 > n2) n2++;
  memset(dis, -1, sizeof(dis));
  for (int i = 1; i <= ttot; i++) bfs(i);
  last.init();
  int S = ttot * 2 + n1 + n2 + 1, T = S + 1;
  for (int i = 1; i <= ttot; i++) last.add_edge(i, ttot + i, 1);
  for (int i = 1; i <= n1; i++) last.add_edge(S, ttot * 2 + i, 1);
  for (int i = 1; i <= n2; i++) last.add_edge(ttot * 2 + n1 + i, T, 1);
  long long lastt = -1;
  for (long long delta = 1ll << 40; delta > 0; delta >>= 1) {
    long long curt = lastt + delta;
    cur = last;
    for (int i = 1; i <= n1; i++) {
      for (int j = 1; j <= ttot; j++) {
        if (dis[v1[i].first][j] == -1) continue;
        long long tneed = 1ll * v1[i].second * dis[v1[i].first][j];
        if (lastt < tneed && curt >= tneed) {
          cur.add_edge(ttot * 2 + i, j, 1);
        }
      }
    }
    for (int i = 1; i <= n2; i++) {
      for (int j = 1; j <= ttot; j++) {
        if (dis[v2[i].first][j] == -1) continue;
        long long tneed = 1ll * v2[i].second * dis[v2[i].first][j];
        if (lastt < tneed && curt >= tneed) {
          cur.add_edge(ttot + j, ttot * 2 + n1 + i, 1);
        }
      }
    }
    if (cur.max_flow(S, T) < n1) {
      last = cur;
      lastt += delta;
    }
  }
  if (lastt > (1ll << 40))
    puts("-1");
  else
    cout << lastt + 1 << endl;
  return 0;
}
