#include <bits/stdc++.h>
using namespace std;
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, -1, 0, 1};
char s[13][13];
bool nn[13][13];
int x, y, mc, fc;
long long INF;
set<pair<long long, pair<int, int> > > ss;
set<pair<long long, pair<int, int> > >::iterator pt;
struct sk {
  int Y, X, T;
  long long a[13][13];
  void read() { scanf("%i%i%i", &Y, &X, &T); }
  void debug() {
    for (int i = 1; i <= y; ++i) {
      for (int j = 1; j <= x; ++j)
        if (a[i][j] < INF)
          printf("%2i ", a[i][j]);
        else
          printf("** ");
      printf("\n");
    }
    printf("\n");
  }
  long long dey() {
    ss.clear();
    for (int i = 1; i <= y; ++i)
      for (int j = 1; j <= x; ++j) {
        a[i][j] = INF;
        ss.insert(make_pair(INF, make_pair(i, j)));
      }
    pt = ss.find(make_pair(INF, make_pair(Y, X)));
    ss.erase(pt);
    a[Y][X] = 0;
    ss.insert(make_pair(0, make_pair(Y, X)));
    while (ss.size() != 0) {
      long long best = INF;
      int ii, jj;
      ii = jj = 0;
      pt = ss.begin();
      best = pt->first;
      if (best == INF) break;
      ii = pt->second.first;
      jj = pt->second.second;
      ss.erase(pt);
      for (int i = 0; i < 4; ++i) {
        int i1 = ii + dy[i];
        int j1 = jj + dx[i];
        if (s[i1][j1] != '#' && a[i1][j1] > best + T) {
          pt = ss.find(make_pair(a[i1][j1], make_pair(i1, j1)));
          ss.erase(pt);
          a[i1][j1] = best + T;
          ss.insert(make_pair(a[i1][j1], make_pair(i1, j1)));
        }
      }
    }
    long long r = 0;
    for (int i = 1; i <= y; ++i)
      for (int j = 1; j <= x; ++j)
        if (a[i][j] < INF) r = max(r, a[i][j]);
    return r;
  }
} mm[13 * 13], ff[13 * 13];
int c[(13 * 13 * 4)][(13 * 13 * 4)];
int f[(13 * 13 * 4)][(13 * 13 * 4)];
int n, t, st;
vector<int> g[(13 * 13 * 4)];
bool was[(13 * 13 * 4)];
int d[(13 * 13 * 4)];
int o[(13 * 13 * 4)];
int from[(13 * 13 * 4)];
void add(int x, int y, int cup) {
  c[x][y] = cup;
  g[x].push_back(y);
  g[y].push_back(x);
}
vector<int> e((13 * 13 * 4));
vector<int> h((13 * 13 * 4));
vector<int> maxh((13 * 13 * 4));
int max_flow(int n, int s, int t) {
  for (int i = 0; i < n; ++i) {
    e[i] = h[i] = maxh[i] = 0;
  }
  h[s] = n - 1;
  for (int i = 0; i < n; ++i) {
    f[s][i] = c[s][i];
    f[i][s] = -f[s][i];
    e[i] = c[s][i];
  }
  int sz = 0;
  for (;;) {
    if (!sz)
      for (int i = 0; i < n; ++i)
        if (i != s && i != t && e[i] > 0) {
          if (sz && h[i] > h[maxh[0]]) sz = 0;
          if (!sz || h[i] == h[maxh[0]]) maxh[sz++] = i;
        }
    if (!sz) break;
    while (sz) {
      int i = maxh[sz - 1];
      bool pushed = false;
      for (int j = 0; j < n && e[i]; ++j)
        if (c[i][j] - f[i][j] > 0 && h[i] == h[j] + 1) {
          pushed = true;
          int addf = min(c[i][j] - f[i][j], e[i]);
          f[i][j] += addf, f[j][i] -= addf;
          e[i] -= addf, e[j] += addf;
          if (e[i] == 0) --sz;
        }
      if (!pushed) {
        h[i] = INF;
        for (int j = 0; j < n; ++j)
          if (c[i][j] - f[i][j] > 0 && h[j] + 1 < h[i]) h[i] = h[j] + 1;
        if (h[i] > h[maxh[0]]) {
          sz = 0;
          break;
        }
      }
    }
  }
  int sum = 0;
  for (int i = 0; i < n; ++i) sum += f[0][i];
  return sum;
}
int max_flow2(int n, int s, int t) {
  int tail, head;
  int v, w, cap;
  int z, q;
  while (true) {
    tail = head = 0;
    for (int i = 0; i < n; ++i) {
      was[i] = false;
      d[i] = 0;
    }
    d[s] = n;
    o[s] = 0;
    was[s] = true;
    while (tail <= head) {
      v = o[tail];
      for (int i = 0; i < g[v].size(); ++i) {
        w = g[v][i];
        cap = c[v][w] - f[v][w] + f[w][v];
        if (!was[w] && cap > 0) {
          from[w] = v;
          d[w] = min(d[v], cap);
          was[w] = true;
          o[++head] = w;
        }
      }
      tail++;
    }
    if (!was[t]) break;
    q = d[t];
    v = t;
    while (v != s) {
      q = d[t];
      w = from[v];
      z = min(f[v][w], q);
      f[v][w] -= z;
      q -= z;
      f[w][v] += q;
      v = w;
    }
  }
  int sum = 0;
  for (int i = 0; i < n; ++i) sum += f[s][i] - f[i][s];
  return sum;
}
bool solve(long long C) {
  memset(f, 0, sizeof(f));
  memset(c, 0, sizeof(c));
  int xy1 = mc + 1;
  int xy2 = xy1 + x * y;
  int fs = xy2 + x * y;
  t = fs + fc;
  for (int i = 0; i <= t; ++i) g[i].clear();
  for (int i = 1; i <= mc; ++i) add(0, i, 1);
  for (int i = 0; i < fc; ++i) add(i + fs, t, 1);
  int q = 0;
  for (int i = 1; i <= y; ++i)
    for (int j = 1; j <= x; ++j) {
      if (s[i][j] != '#') add(xy1 + q, xy2 + q, 1);
      for (int z = 0; z < mc; ++z)
        if (mm[z].a[i][j] <= C) add(1 + z, xy1 + q, 1);
      for (int z = 0; z < fc; ++z)
        if (ff[z].a[i][j] <= C) add(xy2 + q, fs + z, 1);
      ++q;
    }
  int flow = max_flow2(t + 1, 0, t);
  return flow == fc;
}
int main() {
  INF = 1;
  for (int i = 0; i < 17; ++i) INF = INF * 10;
  scanf("%i%i%i%i", &y, &x, &mc, &fc);
  for (int i = 1; i <= y; ++i) {
    scanf("%s", &s[i][1]);
    s[i][0] = '#';
    s[i][x + 1] = '#';
  }
  for (int i = 0; i <= x + 1; ++i) {
    s[0][i] = '#';
    s[y + 1][i] = '#';
  }
  if (mc + 1 == fc) {
    mm[0].read();
    for (int i = 1; i <= mc; ++i) mm[i].read();
    mc++;
    for (int i = 0; i < fc; ++i) ff[i].read();
  } else if (mc == fc + 1) {
    ff[0].read();
    for (int i = 0; i < mc; ++i) mm[i].read();
    for (int i = 1; i <= fc; ++i) ff[i].read();
    fc++;
  } else {
    printf("-1\n");
    return 0;
  }
  long long A = 0;
  long long B = 0;
  long long C = 0;
  for (int i = 0; i < mc; ++i) {
    B = max(B, mm[i].dey());
  }
  for (int i = 0; i < fc; ++i) {
    B = max(B, ff[i].dey());
  }
  if (!solve(B)) {
    cout << -1 << endl;
    return 0;
  }
  while (B - A > 1) {
    C = (A + B) / 2;
    if (solve(C))
      B = C;
    else
      A = C;
  }
  if (!solve(A)) {
    A++;
  }
  cout << A << endl;
  return 0;
}
