#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;
const int SIZE = 1e3 + 10;
using namespace std;
int n, m;
struct E {
  int k, c;
  E() {}
  E(int _k, int _c) : k(_k), c(_c) {}
} es[4200010];
struct Flow {
  int n, m, dis[500010];
  int qq[500010], qr, ql;
  vector<int> e[500010];
  void init(int _n) {
    n = _n;
    m = 0;
    for (int i = 0; i < n; i++) e[i] = vector<int>();
  }
  void add_edge(int a, int b, int c) {
    e[a].push_back(m);
    es[m] = E(b, c);
    m++;
    e[b].push_back(m);
    es[m] = E(a, 0);
    m++;
  }
  bool BFS() {
    memset(dis, -1, n * sizeof(int));
    ql = qr = 0;
    qq[qr++] = 0;
    dis[0] = 0;
    while (ql != qr && dis[n - 1] == -1) {
      int p = qq[ql++];
      for (__typeof((e[p]).begin()) it = (e[p]).begin(); it != (e[p]).end();
           it++) {
        E ee = es[*it];
        if (ee.c == 0 || dis[ee.k] != -1) continue;
        dis[ee.k] = dis[p] + 1;
        qq[qr++] = ee.k;
      }
    }
    return dis[n - 1] != -1;
  }
  long long go(int p, long long c) {
    if (p == n - 1) return c;
    long long ret = 0, tmp;
    for (__typeof((e[p]).begin()) it = (e[p]).begin(); it != (e[p]).end();
         it++) {
      E &ee = es[*it];
      if (ee.c == 0 || dis[p] + 1 != dis[ee.k]) continue;
      tmp = go(ee.k, min(c - ret, (long long)ee.c));
      ret += tmp;
      ee.c -= tmp;
      es[(*it) ^ 1].c += tmp;
      if (ret == c) break;
    }
    if (ret == 0) dis[p] = -1;
    return ret;
  }
  long long maxflow() {
    long long ret = 0;
    while (BFS()) ret += go(0, 1LL << 60);
    return ret;
  }
} flow;
char s[24][24];
int id[24][24];
struct data {
  int x, y, t;
  void scan() {
    scanf("%d%d%d", &(x), &(y), &(t));
    x--;
    y--;
  }
} males[300], females[300];
int tt, used[24][24];
long long dis[24][24];
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
bool Out(int x, int y) { return x < 0 || y < 0 || x >= n || y >= m; }
void BFS(int x, int y, int me, int ty, long long bound, int v) {
  queue<pair<int, int> > bfs;
  used[x][y] = tt;
  dis[x][y] = 0;
  bfs.push(make_pair(x, y));
  while (((int)(bfs).size())) {
    x = bfs.front().first;
    y = bfs.front().second;
    if (ty) {
      flow.add_edge(id[x][y] + 1, me, 1);
    } else {
      flow.add_edge(me, id[x][y], 1);
    }
    bfs.pop();
    for (int k = 0; k < (4); ++k) {
      int nx = x + dx[k];
      int ny = y + dy[k];
      if (Out(nx, ny)) continue;
      if (s[nx][ny] == '#') continue;
      if (used[nx][ny] == tt) continue;
      used[nx][ny] = tt;
      dis[nx][ny] = dis[x][y] + v;
      if (dis[nx][ny] <= bound) {
        bfs.push(make_pair(nx, ny));
      }
    }
  }
}
bool valid(long long v, int N, int flowN) {
  flow.init(flowN);
  for (int i = (2 * N + 1); i < (flowN - 1); ++i) {
    flow.add_edge(i, i + 1, 1);
    i++;
  }
  for (int i = 0; i < (N); ++i) {
    flow.add_edge(0, i + 1, 1);
    flow.add_edge(i + 1 + N, flowN - 1, 1);
  }
  for (int i = 0; i < (N); ++i) {
    tt++;
    BFS(males[i].x, males[i].y, i + 1, 0, v, males[i].t);
    tt++;
    BFS(females[i].x, females[i].y, i + N + 1, 1, v, females[i].t);
  }
  return flow.maxflow() == N;
}
int main() {
  scanf("%d%d", &(n), &(m));
  int malesN, femalesN;
  scanf("%d%d", &malesN, &femalesN);
  if (abs(malesN - femalesN) != 1) {
    puts("-1");
    return 0;
  }
  for (int i = 0; i < (n); ++i) scanf("%s", (s[i]));
  if (malesN < femalesN)
    males[malesN].scan();
  else
    females[femalesN].scan();
  for (int i = 0; i < (malesN); ++i) males[i].scan();
  for (int i = 0; i < (femalesN); ++i) females[i].scan();
  int N = max(malesN, femalesN);
  int flowN;
  {
    int now = 2 * N + 1;
    for (int i = 0; i < (n); ++i)
      for (int j = 0; j < (m); ++j) {
        if (s[i][j] == '.') {
          id[i][j] = now;
          now += 2;
        }
      }
    flowN = now + 1;
  }
  long long ll = 0, rr = 4e12;
  while (ll < rr) {
    long long mm = (ll + rr) >> 1;
    if (valid(mm, N, flowN))
      rr = mm;
    else
      ll = mm + 1;
  }
  if (ll == (long long)(4e12)) ll = -1;
  cout << ll << endl;
  return 0;
}
