#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1001;
const long long INF = (long long)1000 * 1000 * 1000 * 1000;
const int INF_SMAL = 1000 * 1000 * 1000;
const int K = 13;
struct edge {
  int u, v, cap, flow;
  edge(){};
  edge(int u, int v, int cap) : u(u), v(v), cap(cap), flow(0){};
};
int x[2 * K * K], y[2 * K * K], ti[2 * K * K];
char p[K][K];
int n, m, female, male;
bool was[K][K];
int s, t;
vector<edge> ed;
vector<int> g[MAXN];
int dx[4] = {0, 1, 0, -1};
int dy[4] = {-1, 0, 1, 0};
void add_edge(int u, int v, int cap) {
  g[u].push_back(((int)(ed.size())));
  ed.push_back(edge(u, v, cap));
  g[v].push_back(((int)(ed.size())));
  ed.push_back(edge(v, u, 0));
}
int getc(edge &a) { return a.cap - a.flow; }
bool in_range(int l, int s, int r) { return (l <= s && s < r); }
pair<int, int> deq[MAXN];
void get_g(int ind, int x, int y, long long ti, int fl) {
  int di[K][K];
  int l = 0, r = 0;
  memset(was, 0, sizeof was);
  di[x][y] = 0;
  was[x][y] = 1;
  deq[r++] = {x, y};
  while (l < r) {
    int x = deq[l].first, y = deq[l].second;
    l++;
    if (p[x][y] == '#') continue;
    if (di[x][y] <= ti) {
      if (fl == 0) {
        add_edge(ind, x * m + y + male + female, 1);
      } else {
        add_edge(x * m + y + male + female + n * m, ind, 1);
      }
    }
    for (int i = 0; i < 4; i++) {
      if (in_range(0, x + dx[i], n) && in_range(0, y + dy[i], m)) {
        if (!was[x + dx[i]][y + dy[i]]) {
          was[x + dx[i]][y + dy[i]] = 1;
          deq[r++] = {x + dx[i], y + dy[i]};
          di[x + dx[i]][y + dy[i]] = di[x][y] + 1;
        }
      }
    }
  }
}
int di[MAXN];
int bfs(int s, int t) {
  int deq[MAXN];
  int l = 0, r = 0;
  bool was[MAXN];
  memset(was, 0, sizeof was);
  memset(di, 0, sizeof di);
  di[s] = 0;
  was[s] = 1;
  deq[r++] = s;
  while (l < r) {
    int u = deq[l++];
    for (int i = 0; i < ((int)(g[u].size())); i++) {
      if (getc(ed[g[u][i]]) > 0) {
        edge buf = ed[g[u][i]];
        if (!was[buf.v]) {
          was[buf.v] = 1;
          di[buf.v] = di[buf.u] + 1;
          deq[r++] = buf.v;
        }
      }
    }
  }
  if (was[t]) return 1;
  return 0;
}
int pnt[MAXN];
int dfs(int u, int t, int flow) {
  if (u == t || flow == 0) return flow;
  for (int &i = pnt[u]; i < ((int)(g[u].size())); i++) {
    edge buf = ed[g[u][i]];
    if (di[u] + 1 == di[buf.v] && getc(buf) > 0) {
      int lans = dfs(buf.v, t, min(flow, getc(buf)));
      if (lans > 0) {
        ed[g[u][i]].flow += lans;
        ed[g[u][i] ^ 1].flow -= lans;
        return lans;
      }
    }
  }
  return 0;
}
int find_max_flow(int s, int t) {
  int ans = 0;
  while (bfs(s, t) > 0) {
    int lans = -1;
    memset(pnt, 0, sizeof pnt);
    while ((lans = dfs(s, t, INF_SMAL)) > 0) {
      ans += lans;
    }
  }
  return ans;
}
bool check(long long s) {
  int t = male + female + 2 * n * m;
  int st = t + 1;
  for (int i = 0; i < MAXN; i++) {
    g[i].clear();
  }
  ed.clear();
  for (int i = 0; i < male; i++) {
    get_g(i, x[i], y[i], s / ti[i], 0);
    add_edge(st, i, 1);
  }
  for (int i = 0; i < female; i++) {
    get_g(male + i, x[male + i], y[male + i], s / ti[male + i], 1);
    add_edge(male + i, t, 1);
  }
  for (int i = 0; i < n * m; i++) {
    add_edge(male + female + i, male + female + i + n * m, 1);
  }
  int ans = find_max_flow(st, t);
  if (ans == male) return 1;
  return 0;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> m >> male >> female;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) cin >> p[i][j];
  if (abs(male - female) != 1) {
    cout << -1;
    return 0;
  }
  for (int i = 0; i < 1 + female + male; i++) {
    cin >> x[i] >> y[i] >> ti[i];
    x[i]--;
    y[i]--;
  }
  if (male > female) {
    swap(x[0], x[male]);
    swap(y[0], y[male]);
    swap(ti[0], ti[male]);
  }
  male = female = max(male, female);
  long long l = -1, r = INF;
  while (l + 1 < r) {
    long long s = (l + r) / 2;
    if (check(s))
      r = s;
    else
      l = s;
  }
  if (r == INF) {
    cout << -1;
    return 0;
  }
  cout << r;
  return 0;
}
