#include <bits/stdc++.h>
using namespace std;
const int oo = 0x3f3f3f3f;
const double eps = 1e-9;
const long long INF = 1000000000000000ll;
const long long maxN = 2000;
long long N, SRC, DST;
vector<long long> adj[maxN];
long long residual[maxN][maxN];
long long dx[] = {-1, 0, 0, 1};
long long dy[] = {0, -1, 1, 0};
struct scayger {
  long long x, y, t;
  vector<vector<long long>> distTo;
  void bfs(vector<string> &area) {
    distTo = vector<vector<long long>>(
        int((area).size()), vector<long long>(int((area[0]).size()), INF));
    queue<long long> q;
    distTo[x][y] = 0;
    q.push(x);
    q.push(y);
    while (int((q).size())) {
      long long cx = q.front();
      q.pop();
      long long cy = q.front();
      q.pop();
      for (int k = (0); k < (4); k++) {
        long long nx = cx + dx[k], ny = cy + dy[k];
        if (area[nx][ny] == '#' || distTo[nx][ny] < INF) continue;
        distTo[nx][ny] = distTo[cx][cy] + t;
        q.push(nx);
        q.push(ny);
      }
    }
  }
};
void reset(long long n, long long s, long long t) {
  N = n, SRC = s, DST = t;
  for (int i = (0); i < (N); i++) adj[i].clear();
  for (int i = (0); i < (N); i++)
    for (int j = (0); j < (N); j++) residual[i][j] = 0;
}
void add_edge(long long a, long long b, long long c) {
  adj[a].push_back(b);
  adj[b].push_back(a);
  residual[a][b] += c;
}
bool mark[maxN];
long long dfs(long long n, long long cap, long long delta) {
  if (n == DST) return cap;
  mark[n] = true;
  for (const long long &to : adj[n]) {
    if (mark[to] || residual[n][to] < delta) continue;
    if (long long c = dfs(to, min(cap, residual[n][to]), delta)) {
      residual[n][to] -= c;
      residual[to][n] += c;
      return c;
    }
  }
  return 0;
}
long long maxflow() {
  long long flow = 0, delta = 1;
  while (delta) {
    fill_n(mark, N, 0);
    long long c = dfs(SRC, INF, delta);
    if (c)
      flow += c;
    else
      delta /= 2;
  }
  return flow;
}
int main() {
  ios_base::sync_with_stdio(false);
  long long n, m, males, females;
  cin >> n >> m >> males >> females;
  if (abs(males - females) != 1) {
    cout << -1 << endl;
    return 0;
  }
  vector<string> area(n + 2, string(m + 2, '#'));
  for (int i = (1); i < (n + 1); i++)
    for (int j = (1); j < (m + 1); j++) cin >> area[i][j];
  vector<scayger> scay[2];
  long long boss = males > females;
  {
    scayger s;
    cin >> s.x >> s.y >> s.t;
    scay[boss].push_back(s);
  }
  for (int k = (0); k < (males); k++) {
    scayger s;
    cin >> s.x >> s.y >> s.t;
    scay[0].push_back(s);
  }
  for (int k = (0); k < (females); k++) {
    scayger s;
    cin >> s.x >> s.y >> s.t;
    scay[1].push_back(s);
  }
  long long k = max(males, females);
  assert(k == int((scay[0]).size()));
  assert(k == int((scay[1]).size()));
  for (int h = (0); h < (2); h++)
    for (int i = (0); i < (k); i++) {
      scay[h][i].bfs(area);
    }
  long long tmin = -1, tmax = 100000000000000ll;
  while (tmax - tmin > 1) {
    long long t = (tmin + tmax + 1) / 2;
    long long h = 2 * (k + n * m);
    reset(h + 2, h, h + 1);
    for (int i = (0); i < (k); i++) {
      add_edge(h, i, 1);
      add_edge(k + i, h + 1, 1);
    }
    for (int i = (0); i < (k); i++) {
      auto &s = scay[0][i];
      for (int x = (1); x < (n + 1); x++)
        for (int y = (1); y < (m + 1); y++) {
          if (s.distTo[x][y] <= t) add_edge(i, 2 * k + (x - 1) * m + y - 1, 1);
        }
    }
    for (int i = (0); i < (n * m); i++)
      add_edge(2 * k + i, 2 * k + n * m + i, 1);
    for (int i = (0); i < (k); i++) {
      auto &s = scay[1][i];
      for (int x = (1); x < (n + 1); x++)
        for (int y = (1); y < (m + 1); y++) {
          if (s.distTo[x][y] <= t)
            add_edge(2 * k + n * m + (x - 1) * m + y - 1, k + i, 1);
        }
    }
    if (maxflow() == k)
      tmax = t;
    else
      tmin = t;
  }
  if (tmax >= 100000000000000ll)
    cout << -1 << endl;
  else
    cout << tmax << endl;
}
