#include <bits/stdc++.h>
using namespace std;
const int MAXN = 50 + 2;
const int MAX = MAXN * MAXN;
const int MAXE = 5e6 + 3;
const long long INF = 1e15 + 1000;
const int FF = 1e9;
long long n, m, x, y, ec;
char c[MAXN][MAXN];
int lvl[MAX];
int q[MAX];
int dis[MAX][MAX];
int from[2 * MAXE], to[2 * MAXE], prv[2 * MAXE];
long long cap[2 * MAXE];
int head[MAX];
int ptr[MAX];
bool mark[MAX];
int hs[MAXN][MAXN];
vector<pair<long long, long long>> vec, sec;
bool fit(int a, int b) { return a >= 0 && a < n && b >= 0 && b < m; }
int hhash(int a, int b) { return a * m + b; }
void init() {
  for (int i = 0; i < n * m; i++)
    for (int j = 0; j < n * m; j++)
      if (i != j) dis[i][j] = FF;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) {
      if (c[i][j] == '#') continue;
      long long h = hs[i][j];
      if (fit(i + 1, j) && c[i + 1][j] != '#') dis[h][hs[i + 1][j]] = 1;
      if (fit(i - 1, j) && c[i - 1][j] != '#') dis[h][hs[i - 1][j]] = 1;
      if (fit(i, j + 1) && c[i][j + 1] != '#') dis[h][hs[i][j + 1]] = 1;
      if (fit(i, j - 1) && c[i][j - 1] != '#') dis[h][hs[i][j - 1]] = 1;
    }
  for (int k = 0; k < n * m; k++)
    for (int i = 0; i < n * m; i++)
      for (int j = 0; j < n * m; j++)
        dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
}
void put_edge(int u, int v, long long uv, long long vu = 0) {
  from[ec] = u, to[ec] = v, cap[ec] = uv, prv[ec] = head[u];
  head[u] = ec++;
  from[ec] = v, to[ec] = u, cap[ec] = vu, prv[ec] = head[v];
  head[v] = ec++;
}
void put(long long maxi) {
  memset(head, -1, sizeof(head)), ec = 0;
  int source = x + y + 2 * n * m;
  int sink = source + 1;
  for (int i = 0; i < x; i++) put_edge(source, i, 1);
  for (int i = 0; i < x; i++) {
    long long h = vec[i].first, v = vec[i].second;
    for (int j = 0; j < n; j++)
      for (int w = 0; w < m; w++) {
        long long hh = hs[j][w];
        if (dis[h][hh] == FF) continue;
        long long time = v * dis[h][hh];
        if (time > maxi) continue;
        put_edge(i, x + hh, 1);
      }
  }
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) {
      long long hh = hs[i][j];
      hh += x;
      put_edge(hh, hh + n * m, 1);
    }
  for (int i = 0; i < y; i++) {
    int id = x + 2 * n * m + i;
    long long h = sec[i].first, v = sec[i].second;
    for (int j = 0; j < n; j++)
      for (int w = 0; w < m; w++) {
        long long hh = hs[j][w];
        if (dis[h][hh] == FF) continue;
        long long temp = v * dis[h][hh];
        if (temp > maxi) continue;
        put_edge(x + hh + n * m, id, 1);
      }
  }
  for (int i = 0; i < y; i++) {
    int id = x + 2 * n * m + i;
    put_edge(id, sink, 1);
  }
}
bool bfs(int v, int des) {
  fill(lvl, lvl + MAX, FF);
  lvl[v] = 0;
  long long h = 0, t = 0;
  q[t++] = v;
  while (h < t) {
    v = q[h++];
    for (int e = head[v]; e != -1; e = prv[e]) {
      int u = to[e];
      if (cap[e] && lvl[u] > lvl[v] + 1) {
        lvl[u] = lvl[v] + 1;
        q[t++] = u;
      }
    }
  }
  return lvl[des] != FF;
}
long long dfs(int v, int sink, long long flow = INF) {
  if (flow == 0 || v == sink) return flow;
  long long ret = 0;
  for (; ptr[v] != -1; ptr[v] = prv[ptr[v]])
    if (lvl[to[ptr[v]]] == lvl[v] + 1) {
      long long xx = dfs(to[ptr[v]], sink, min(flow, cap[ptr[v]]));
      cap[ptr[v]] -= xx;
      cap[ptr[v] ^ 1] += xx;
      flow -= xx;
      ret += xx;
      if (flow == 0) break;
    }
  return ret;
}
long long max_flow(int source, int sink) {
  long long ret = 0;
  while (bfs(source, sink)) {
    memcpy(ptr, head, sizeof(head));
    ret += dfs(source, sink);
  }
  return ret;
}
int main() {
  cin >> n >> m >> x >> y;
  if ((x + y + 1) % 2) {
    cout << -1 << endl;
    return 0;
  }
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) hs[i][j] = hhash(i, j);
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) cin >> c[i][j];
  init();
  {
    int a, b;
    long long v;
    cin >> a >> b >> v;
    a--, b--;
    if (x < y) {
      x++;
      vec.push_back({hs[a][b], v});
    } else
      sec.push_back({hs[a][b], v}), y++;
    int i = 0;
    if (vec.size()) i++;
    for (; i < x; i++) {
      cin >> a >> b >> v;
      a--, b--;
      vec.push_back({hs[a][b], v});
    }
    i = 0;
    if (sec.size()) i++;
    for (; i < y; i++) {
      cin >> a >> b >> v;
      a--, b--;
      sec.push_back({hs[a][b], v});
    }
  }
  long long b = 0, e = 1e12, mid, ret = -1;
  while (b <= e) {
    mid = (b + e) / 2;
    put(mid);
    if (max_flow(x + y + 2 * n * m, x + y + 2 * n * m + 1) == max(x, y)) {
      e = mid - 1;
      ret = mid;
    } else
      b = mid + 1;
  }
  cout << ret << endl;
  return 0;
}
