#include <bits/stdc++.h>
using namespace std;
const long long oo = 1LL << 60;
const double EPS = 1e-9;
const long long MAXN = (long long)1e5 + 10;
bool dbg = false;
template <typename flow_type>
struct dinic {
  struct edge {
    size_t src, dst, rev;
    flow_type flow, cap;
  };
  int n;
  vector<vector<edge>> adj;
  dinic(int n) : n(n), adj(n), level(n), q(n), it(n) {}
  void add_edge(size_t src, size_t dst, flow_type cap, flow_type rcap = 0) {
    adj[src].push_back({src, dst, adj[dst].size(), 0, cap});
    if (src == dst) adj[src].back().rev++;
    adj[dst].push_back({dst, src, adj[src].size() - 1, 0, rcap});
  }
  vector<int> level, q, it;
  bool bfs(int source, int sink) {
    fill(level.begin(), level.end(), -1);
    for (int qf = level[q[0] = sink] = 0, qb = 1; qf < qb; ++qf) {
      sink = q[qf];
      for (edge &e : adj[sink]) {
        edge &r = adj[e.dst][e.rev];
        if (r.flow < r.cap && level[e.dst] == -1)
          level[q[qb++] = e.dst] = 1 + level[sink];
      }
    }
    return level[source] != -1;
  }
  flow_type augment(int source, int sink, flow_type flow) {
    if (source == sink) return flow;
    for (; it[source] != adj[source].size(); ++it[source]) {
      edge &e = adj[source][it[source]];
      if (e.flow < e.cap && level[e.dst] + 1 == level[source]) {
        flow_type delta = augment(e.dst, sink, min(flow, e.cap - e.flow));
        if (delta > 0) {
          e.flow += delta;
          adj[e.dst][e.rev].flow -= delta;
          return delta;
        }
      }
    }
    return 0;
  }
  flow_type max_flow(int source, int sink) {
    for (int u = 0; u < n; ++u)
      for (edge &e : adj[u]) e.flow = 0;
    flow_type flow = 0;
    while (bfs(source, sink)) {
      fill(it.begin(), it.end(), 0);
      for (flow_type f;
           (f = augment(source, sink, numeric_limits<flow_type>::max())) > 0;)
        flow += f;
    }
    return flow;
  }
};
struct scayger {
  long long x, y, v;
};
long long n, m, males, females;
char Map[30][30];
long long ID[2][30][30];
long long Dist[30][30][30][30];
long long dx[4] = {0, 0, -1, 1};
long long dy[4] = {1, -1, 0, 0};
bool valid(long long x, long long y) {
  return 0 <= x && x < n && 0 <= y && y < m && Map[x][y] != '#';
}
void bfs(long long x, long long y) {
  for (long long i = 0; i < n; ++i)
    for (long long j = 0; j < m; ++j) Dist[x][y][i][j] = oo;
  Dist[x][y][x][y] = 0;
  queue<pair<long long, long long>> Q;
  Q.push(make_pair(x, y));
  while (!Q.empty()) {
    pair<long long, long long> cur = Q.front();
    Q.pop();
    long long dst = Dist[x][y][cur.first][cur.second];
    for (int i = 0; i < 4; ++i) {
      long long nx = cur.first + dx[i], ny = cur.second + dy[i];
      if (valid(nx, ny) && Dist[x][y][nx][ny] > dst + 1) {
        Dist[x][y][nx][ny] = dst + 1;
        Q.push(make_pair(nx, ny));
      }
    }
  }
}
bool myvalid(long long v) { return v != oo; }
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cin >> n >> m >> males >> females;
  for (long long i = 0; i < n; ++i) {
    cin >> Map[i];
  }
  if (abs(males - females) != 1) {
    cout << -1 << endl;
    return 0;
  }
  long long vmax = 0;
  vector<scayger> vm, vf;
  scayger SB;
  cin >> SB.x >> SB.y >> SB.v;
  SB.x--;
  SB.y--;
  vmax = SB.v;
  if (males < females)
    vm.push_back(SB);
  else
    vf.push_back(SB);
  for (long long i = 0; i < males; ++i) {
    scayger cur;
    cin >> cur.x >> cur.y >> cur.v;
    cur.x--;
    cur.y--;
    vm.push_back(cur);
    vmax = max(vmax, cur.v);
  }
  for (long long i = 0; i < females; ++i) {
    scayger cur;
    cin >> cur.x >> cur.y >> cur.v;
    cur.x--;
    cur.y--;
    vf.push_back(cur);
    vmax = max(vmax, cur.v);
  }
  for (long long i = 0; i < n; ++i) {
    for (long long j = 0; j < m; ++j) {
      if (Map[i][j] != '#') bfs(i, j);
    }
  }
  long long lo = 0, hi = m * n * vmax + 1;
  long long top = hi;
  for (long long i = 0, cnt = 2 + 2 * (long long)((vm).size()); i < n; ++i)
    for (long long j = 0; j < m; ++j)
      for (long long k = 0; k < 2; ++k) ID[k][i][j] = cnt++;
  while (lo < hi) {
    long long mid = (lo + hi) >> 1;
    dbg = false;
    dinic<long long> flow(2 + 2 * (long long)((vm).size()) + 2 * n * m);
    for (long long i = 0; i < (long long)((vm).size()); ++i) {
      flow.add_edge(0, i + 2, 1);
      flow.add_edge(i + 2 + (long long)((vm).size()), 1, 1);
    }
    for (long long i = 0; i < n; ++i) {
      for (long long j = 0; j < m; ++j) {
        flow.add_edge(ID[0][i][j], ID[1][i][j], 1);
      }
    }
    for (long long i = 0; i < (long long)((vm).size()); ++i) {
      scayger cur1 = vm[i];
      scayger cur2 = vf[i];
      for (long long j = 0; j < n; ++j) {
        for (long long k = 0; k < m; ++k) {
          if (Map[j][k] == '#') continue;
          if (dbg && !i)
            cout << "ID " << j << " " << k << " "
                 << 2 + 2 * (long long)((vm).size()) + j * m + k << endl;
          if (myvalid(Dist[cur1.x][cur1.y][j][k]) &&
              Dist[cur1.x][cur1.y][j][k] * cur1.v <= mid)
            flow.add_edge(i + 2, ID[0][j][k], 1);
          if (myvalid(Dist[cur2.x][cur2.y][j][k]) &&
              Dist[cur2.x][cur2.y][j][k] * cur2.v <= mid)
            flow.add_edge(ID[1][j][k], 2 + (long long)((vm).size()) + i, 1);
        }
      }
    }
    long long value = flow.max_flow(0, 1);
    if (value == (long long)((vm).size()))
      hi = mid;
    else
      lo = mid + 1;
  }
  if (hi == top)
    cout << -1 << endl;
  else
    cout << hi << endl;
  return 0;
}
