#include <bits/stdc++.h>
using namespace std;
template <class T>
void debug(T a, T b) {
  ;
}
template <class T>
void chmin(T& a, const T& b) {
  if (a > b) a = b;
}
template <class T>
void chmax(T& a, const T& b) {
  if (a < b) a = b;
}
namespace std {
template <class S, class T>
ostream& operator<<(ostream& out, const pair<S, T>& a) {
  out << '(' << a.first << ',' << a.second << ')';
  return out;
}
}  // namespace std
long long int readL() {
  long long int res;
  scanf("%I64d", &res);
  return res;
}
void printL(long long int res) { printf("%I64d", res); }
int src, sink;
static const int MAX_SIZE = 2005;
struct edge {
  int to, cap, rev;
  edge(int st, int second, int sr) {
    to = st;
    cap = second;
    rev = sr;
  }
};
const int INF = 5e8;
vector<edge> g[MAX_SIZE];
int rankk[MAX_SIZE], seen[MAX_SIZE];
void add_edge(int from, int to, int cap) {
  g[from].push_back(edge(to, cap, g[to].size()));
  g[to].push_back(edge(from, 0, g[from].size() - 1));
}
void bfs(int v) {
  memset(rankk, -1, sizeof(rankk));
  rankk[v] = 0;
  queue<int> q;
  q.push(v);
  while (!q.empty()) {
    int cur = q.front();
    q.pop();
    for (int i = 0; i < (g[cur].size()); ++i) {
      edge& e = g[cur][i];
      if (e.cap > 0 && rankk[e.to] == -1) {
        rankk[e.to] = rankk[cur] + 1;
        q.push(e.to);
      }
    }
  }
}
int dfs(int v, int f) {
  if (v == sink) return f;
  for (int& i = seen[v]; i < g[v].size(); ++i) {
    edge& e = g[v][i];
    if (e.cap > 0 && rankk[e.to] > rankk[v]) {
      int d = dfs(e.to, min(e.cap, f));
      if (d > 0) {
        e.cap -= d;
        g[e.to][e.rev].cap += d;
        return d;
      }
    }
  }
  return 0;
}
int max_flow(int s, int t) {
  src = s;
  sink = t;
  int flow = 0;
  while (1) {
    bfs(src);
    if (rankk[sink] == -1) return flow;
    int f;
    memset(seen, 0, sizeof(seen));
    while ((f = dfs(src, INF)) > 0) {
      flow += f;
    }
  }
}
int h, w;
int n, m;
char buf[25][25];
int mat[500][500];
int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};
int N;
int cnt[2];
pair<pair<int, int>, int> ar[2][500];
void read_(int ind) {
  int a, b, c;
  cin >> a >> b >> c;
  --a;
  --b;
  ar[ind][cnt[ind]] = make_pair(make_pair(a, b), c);
  ++cnt[ind];
}
bool check(long long int time) {
  int S = 2 * (n + N), T = S + 1;
  ;
  for (int i = 0; i < (T + 1); ++i) g[i].clear();
  for (int i = 0; i < (n); ++i) {
    int p = ar[0][i].first.first * w + ar[0][i].first.second;
    add_edge(S, i, 1);
    for (int j = 0; j < (N); ++j)
      if (mat[p][j] < INF) {
        long long int cost = mat[p][j] * (long long int)ar[0][i].second;
        if (cost <= time) add_edge(i, n + j, 1);
      }
  }
  for (int j = 0; j < (N); ++j) add_edge(n + j, n + N + j, 1);
  for (int i = 0; i < (n); ++i) {
    int p = ar[1][i].first.first * w + ar[1][i].first.second;
    add_edge(i + n + N + N, T, 1);
    for (int j = 0; j < (N); ++j)
      if (mat[p][j] < INF) {
        long long int cost = mat[p][j] * (long long int)ar[1][i].second;
        if (cost <= time) add_edge(n + N + j, i + n + N + N, 1);
      }
  }
  if (max_flow(S, T) == n) return true;
  return false;
}
int main() {
  cin >> h >> w >> n >> m;
  for (int i = 0; i < (h); ++i) scanf("%s", buf[i]);
  N = h * w;
  for (int i = 0; i < (N); ++i)
    for (int j = 0; j < (N); ++j) mat[i][j] = INF;
  for (int i = 0; i < (N); ++i) mat[i][i] = 0;
  for (int i = 0; i < (h); ++i)
    for (int j = 0; j < (w); ++j)
      if (buf[i][j] == '.') {
        int c1 = i * w + j;
        for (int d = 0; d < (4); ++d) {
          int px = j + dx[d], py = i + dy[d];
          if (px < 0 || py < 0 || px >= w || py >= h || buf[py][px] == '#')
            continue;
          int c2 = py * w + px;
          mat[c1][c2] = mat[c2][c1] = 1;
        }
      }
  for (int i = 0; i < (N); ++i)
    for (int j = 0; j < (N); ++j)
      for (int k = 0; k < (N); ++k) chmin(mat[j][k], mat[j][i] + mat[i][k]);
  if (abs(n - m) > 1 || n == m) {
    puts("-1");
    return 0;
  }
  if (n > m)
    read_(1);
  else
    read_(0);
  for (int i = 0; i < (n); ++i) read_(0);
  for (int i = 0; i < (m); ++i) read_(1);
  n = m = max(n, m);
  long long int MX = 1e17;
  long long int lb = -1, ub = MX;
  while (ub - lb > 1) {
    long long int md = (lb + ub) >> 1;
    if (check(md))
      ub = md;
    else
      lb = md;
  }
  if (ub == MX) ub = -1;
  cout << ub << endl;
  return 0;
}
