#include <bits/stdc++.h>
using namespace std;
struct Edge {
  int a, b, cap, flow;
};
struct MaxFlow {
  int n, s, t;
  vector<int> d, ptr, q;
  vector<Edge> e;
  vector<vector<int> > g;
  MaxFlow(int n) : n(n), d(n), ptr(n), g(n), q(n) {
    e.clear();
    for (int _n(n - 1), i(0); i <= _n; i++) {
      g[i].clear();
      ptr[i] = 0;
    }
  }
  void addEdge(int a, int b, int cap) {
    Edge e1 = {a, b, cap, 0};
    Edge e2 = {b, a, 0, 0};
    g[a].push_back((int)e.size());
    e.push_back(e1);
    g[b].push_back((int)e.size());
    e.push_back(e2);
  }
  int getMaxFlow(int _s, int _t) {
    s = _s;
    t = _t;
    int flow = 0;
    for (;;) {
      if (!bfs()) break;
      for (int _n(n - 1), i(0); i <= _n; i++) ptr[i] = 0;
      while (int pushed = dfs(s, 1011111111)) flow += pushed;
    }
    return flow;
  }

 private:
  bool bfs() {
    int qh = 0, qt = 0;
    q[qt++] = s;
    for (int _n(n - 1), i(0); i <= _n; i++) d[i] = -1;
    d[s] = 0;
    while (qh < qt && d[t] == -1) {
      int v = q[qh++];
      for (int _n((int)g[v].size() - 1), i(0); i <= _n; i++) {
        int id = g[v][i], to = e[id].b;
        if (d[to] == -1 && e[id].flow < e[id].cap) {
          q[qt++] = to;
          d[to] = d[v] + 1;
        }
      }
    }
    return d[t] != -1;
  }
  int dfs(int v, int flow) {
    if (!flow) return 0;
    if (v == t) return flow;
    for (; ptr[v] < (int)g[v].size(); ++ptr[v]) {
      int id = g[v][ptr[v]], to = e[id].b;
      if (d[to] != d[v] + 1) continue;
      int pushed = dfs(to, min(flow, e[id].cap - e[id].flow));
      if (pushed) {
        e[id].flow += pushed;
        e[id ^ 1].flow -= pushed;
        return pushed;
      }
    }
    return 0;
  }
};
int m, n, males, females;
char a[33][33];
pair<pair<int, int>, long long> x[2][33 * 33];
long long d[33][33][33][33], g[33][33];
const int di[] = {-1, 1, 0, 0};
const int dj[] = {0, 0, -1, 1};
void bfs(int u, int v) {
  queue<pair<int, int> > qu;
  qu.push(make_pair(u, v));
  memset(g, -1, sizeof g);
  g[u][v] = 0;
  while (!qu.empty()) {
    int u = qu.front().first, v = qu.front().second;
    qu.pop();
    for (int _n(4 - 1), dir(0); dir <= _n; dir++) {
      int uu = u + di[dir], vv = v + dj[dir];
      if (uu < 1 || uu > m || vv < 1 || vv > n || g[uu][vv] >= 0) continue;
      if (a[uu][vv] == '#') continue;
      g[uu][vv] = g[u][v] + 1;
      qu.push(make_pair(uu, vv));
    }
  }
}
int getId1(int i, int j) { return males + females + (i - 1) * n + j; }
int getId2(int i, int j) { return males + females + m * n + (i - 1) * n + j; }
bool solve(long long mid) {
  int source = 0, sink = getId2(m, n) + 1;
  MaxFlow flow(sink + 1);
  for (int _n(males), i(1); i <= _n; i++) flow.addEdge(0, i, 1);
  for (int _n(females), i(1); i <= _n; i++) flow.addEdge(males + i, sink, 1);
  for (int _n(males), i(1); i <= _n; i++)
    for (int _n(m), u(1); u <= _n; u++)
      for (int _n(n), v(1); v <= _n; v++)
        if (a[u][v] != '#' &&
            d[x[0][i].first.first][x[0][i].first.second][u][v] >= 0 &&
            d[x[0][i].first.first][x[0][i].first.second][u][v] *
                    x[0][i].second <=
                mid)
          flow.addEdge(i, getId1(u, v), 1);
  for (int _n(m), u(1); u <= _n; u++)
    for (int _n(n), v(1); v <= _n; v++)
      if (a[u][v] != '#') flow.addEdge(getId1(u, v), getId2(u, v), 1);
  for (int _n(females), i(1); i <= _n; i++)
    for (int _n(m), u(1); u <= _n; u++)
      for (int _n(n), v(1); v <= _n; v++) {
        if (a[u][v] != '#' &&
            d[x[1][i].first.first][x[1][i].first.second][u][v] >= 0 &&
            d[x[1][i].first.first][x[1][i].first.second][u][v] *
                    x[1][i].second <=
                mid) {
          flow.addEdge(getId2(u, v), males + i, 1);
        }
      }
  auto res = flow.getMaxFlow(source, sink);
  if (res == males)
    return true;
  else
    return false;
}
int main() {
  ios::sync_with_stdio(false);
  while (cin >> m >> n >> males >> females) {
    for (int _n(m), i(1); i <= _n; i++)
      for (int _n(n), j(1); j <= _n; j++) cin >> a[i][j];
    int rt, ct, tt;
    cin >> rt >> ct >> tt;
    for (int _n(males), i(1); i <= _n; i++)
      cin >> x[0][i].first.first >> x[0][i].first.second >> x[0][i].second;
    for (int _n(females), i(1); i <= _n; i++)
      cin >> x[1][i].first.first >> x[1][i].first.second >> x[1][i].second;
    if (males < females) {
      ++males;
      x[0][males] = make_pair(make_pair(rt, ct), tt);
    } else {
      ++females;
      x[1][females] = make_pair(make_pair(rt, ct), tt);
    }
    if (males != females)
      cout << -1 << endl;
    else {
      for (int _n(m), i(1); i <= _n; i++)
        for (int _n(n), j(1); j <= _n; j++)
          if (a[i][j] != '#') {
            bfs(i, j);
            for (int _n(m), u(1); u <= _n; u++)
              for (int _n(n), v(1); v <= _n; v++)
                if (a[u][v] != '#') {
                  d[i][j][u][v] = g[u][v];
                }
          }
      long long l = 0, r = 1000111000111000LL, res = r;
      while (l <= r) {
        long long mid = (l + r) >> 1;
        if (solve(mid)) {
          res = mid;
          r = mid - 1;
        } else
          l = mid + 1;
      }
      if (res == 1000111000111000LL) res = -1;
      cout << res << endl;
    }
  }
  return 0;
}
