#include <bits/stdc++.h>   using namespace std;   const int MAXN = 1001;   const long long INF = (long long)1000 * 1000 * 1000 * 1000;   const int INF_SMAL = 1000 * 1000 * 1000;   const int K = 13;   struct edge {     int u, v, cap, flow;     edge(){};     edge(int u, int v, int cap) : u(u), v(v), cap(cap), flow(0){};   };   int x[2 * K * K], y[2 * K * K], ti[2 * K * K];   char p[K][K];   int n, m, female, male;   bool was[K][K];   int s, t;   vector<edge> ed;   vector<int> g[MAXN];   int dx[4] = {0, 1, 0, -1};   int dy[4] = {-1, 0, 1, 0};   void add_edge(int u, int v, int cap) {     g[u].push_back(((int)(ed.size())));     ed.push_back(edge(u, v, cap));     g[v].push_back(((int)(ed.size())));     ed.push_back(edge(v, u, 0));   }   int getc(edge &a) { return a.cap - a.flow; }   bool in_range(int l, int s, int r) { return (l <= s && s < r); }   pair<int, int> deq[MAXN];   void get_g(int ind, int x, int y, long long ti, int fl) {     int di[K][K];     int l = 0, r = 0;     memset(was, 0, sizeof was);     di[x][y] = 0;     was[x][y] = 1;     deq[r++] = {x, y};     while (l < r) {       int x = deq[l].first, y = deq[l].second;       l++;       if (p[x][y] ==  # ) continue;       if (di[x][y] <= ti) {         if (fl == 0) {           add_edge(ind, x * m + y + male + female, 1);         } else {           add_edge(x * m + y + male + female + n * m, ind, 1);         }       }       for (int i = 0; i < 4; i++) {         if (in_range(0, x + dx[i], n) && in_range(0, y + dy[i], m)) {           if (!was[x + dx[i]][y + dy[i]]) {             was[x + dx[i]][y + dy[i]] = 1;             deq[r++] = {x + dx[i], y + dy[i]};             di[x + dx[i]][y + dy[i]] = di[x][y] + 1;           }         }       }     }   }   int di[MAXN];   int bfs(int s, int t) {     int deq[MAXN];     int l = 0, r = 0;     bool was[MAXN];     memset(was, 0, sizeof was);     memset(di, 0, sizeof di);     di[s] = 0;     was[s] = 1;     deq[r++] = s;     while (l < r) {       int u = deq[l++];       for (int i = 0; i < ((int)(g[u].size())); i++) {         if (getc(ed[g[u][i]]) > 0) {           edge buf = ed[g[u][i]];           if (!was[buf.v]) {             was[buf.v] = 1;             di[buf.v] = di[buf.u] + 1;             deq[r++] = buf.v;           }         }       }     }     if (was[t]) return 1;     return 0;   }   int pnt[MAXN];   int dfs(int u, int t, int flow) {     if (u == t || flow == 0) return flow;     for (int &i = pnt[u]; i < ((int)(g[u].size())); i++) {       edge buf = ed[g[u][i]];       if (di[u] + 1 == di[buf.v] && getc(buf) > 0) {         int lans = dfs(buf.v, t, min(flow, getc(buf)));         if (lans > 0) {           ed[g[u][i]].flow += lans;           ed[g[u][i] ^ 1].flow -= lans;           return lans;         }       }     }     return 0;   }   int find_max_flow(int s, int t) {     int ans = 0;     while (bfs(s, t) > 0) {       int lans = -1;       memset(pnt, 0, sizeof pnt);       while ((lans = dfs(s, t, INF_SMAL)) > 0) {         ans += lans;       }     }     return ans;   }   bool check(long long s) {     int t = male + female + 2 * n * m;     int st = t + 1;     for (int i = 0; i < MAXN; i++) {       g[i].clear();     }     ed.clear();     for (int i = 0; i < male; i++) {       get_g(i, x[i], y[i], s / ti[i], 0);       add_edge(st, i, 1);     }     for (int i = 0; i < female; i++) {       get_g(male + i, x[male + i], y[male + i], s / ti[male + i], 1);       add_edge(male + i, t, 1);     }     for (int i = 0; i < n * m; i++) {       add_edge(male + female + i, male + female + i + n * m, 1);     }     int ans = find_max_flow(st, t);     if (ans == male) return 1;     return 0;   }   int main() {     ios_base::sync_with_stdio(false);     cin.tie(0);     cin >> n >> m >> male >> female;     for (int i = 0; i < n; i++)       for (int j = 0; j < m; j++) cin >> p[i][j];     if (abs(male - female) != 1) {       cout << -1;       return 0;     }     for (int i = 0; i < 1 + female + male; i++) {       cin >> x[i] >> y[i] >> ti[i];       x[i]--;       y[i]--;     }     if (male > female) {       swap(x[0], x[male]);       swap(y[0], y[male]);       swap(ti[0], ti[male]);     }     male = female = max(male, female);     long long l = -1, r = INF;     while (l + 1 < r) {       long long s = (l + r) / 2;       if (check(s))         r = s;       else         l = s;     }     if (r == INF) {       cout << -1;       return 0;     }     cout << r;     return 0;   }