#include <bits/stdc++.h>
using namespace std;
template <class T>
T inline sqr(T x) {
  return x * x;
}
const long double pi = 3.1415926535897932384626433832795;
const long double eps = 1e-8;
const int maxn = 1050;
const int inf = 1e9;
struct Edge {
  int to, cap, fl;
  Edge(int to, int cap, int fl) : to(to), cap(cap), fl(fl) {}
};
vector<Edge> edges;
vector<int> g[maxn];
int d[maxn], p[maxn], q[maxn];
void addedge(int from, int to, int cap = 1) {
  g[from].push_back(edges.size());
  edges.push_back(Edge(to, cap, 0));
  g[to].push_back(edges.size());
  edges.push_back(Edge(from, 0, 0));
}
bool dfs(int v, int fin, int lim) {
  if (v == fin) return true;
  while (p[v] < (int)g[v].size()) {
    int num = g[v][p[v]];
    Edge ed = edges[num];
    if (d[ed.to] == d[v] + 1 && ed.cap - ed.fl >= lim) {
      if (dfs(ed.to, fin, lim)) {
        edges[num].fl += lim;
        edges[num ^ 1].fl -= lim;
        return true;
      }
    }
    p[v]++;
  }
  return false;
}
void bfs(int st, int lim, int n) {
  fill(d, d + n + 1, inf);
  q[0] = st;
  d[st] = 0;
  int head = 0, tail = 1;
  while (head < tail) {
    int v = q[head++];
    for (int i = 0; i < (int)(g[v].size()); ++i) {
      Edge ed = edges[g[v][i]];
      if (ed.cap - ed.fl >= lim && d[ed.to] > d[v] + 1) {
        d[ed.to] = d[v] + 1;
        q[tail++] = ed.to;
      }
    }
  }
}
int calcFlow(int n, int st, int fin) {
  int lim = 1e9, ans = 0;
  while (lim) {
    while (true) {
      bfs(st, lim, n);
      if (d[fin] == inf) break;
      fill(p, p + n + 1, 0);
      while (dfs(st, fin, lim)) ans += lim;
    }
    lim /= 2;
  }
  return ans;
}
int SG = 0;
void init() {
  SG = 0;
  for (int i = 0; i < (int)(maxn); ++i) g[i].clear();
  edges.clear();
}
int newV() { return SG++; }
const int N = 30;
char field[N][N];
const int NDIR = 4;
const int di[4] = {0, 1, 0, -1};
const int dj[4] = {1, 0, -1, 0};
int a[N * N][3];
int b[N * N][3];
vector<vector<int> > dist[N][N];
int n, m;
vector<vector<int> > bfs(int i, int j) {
  vector<vector<int> > d(n + 1, vector<int>(m + 1, inf));
  queue<pair<int, int> > q;
  q.push(make_pair(i, j));
  d[i][j] = 0;
  while (!q.empty()) {
    pair<int, int> cur = q.front();
    q.pop();
    for (int dir = 0; dir < (int)(NDIR); ++dir) {
      pair<int, int> nex(cur.first + di[dir], cur.second + dj[dir]);
      if (field[nex.first][nex.second] && d[nex.first][nex.second] == inf) {
        d[nex.first][nex.second] = d[cur.first][cur.second] + 1;
        q.push(nex);
      }
    }
  }
  return d;
}
int q0, q1;
int cells[N][N][2];
bool can(long long T0) {
  assert(q0 == q1);
  init();
  for (int i = 1; i <= (int)(n); ++i)
    for (int j = 1; j <= (int)(m); ++j) {
      for (int t = 0; t < (int)(2); ++t) cells[i][j][t] = newV();
      addedge(cells[i][j][0], cells[i][j][1]);
    }
  int st = newV();
  int fin = newV();
  for (int t = 0; t < (int)(q0); ++t) {
    int cur = newV();
    addedge(st, cur);
    long long s = T0 / a[t][2];
    int i0 = a[t][0], j0 = a[t][1];
    for (int i = 1; i <= (int)(n); ++i)
      for (int j = 1; j <= (int)(m); ++j)
        if (dist[i0][j0][i][j] != inf && dist[i0][j0][i][j] <= s)
          addedge(cur, cells[i][j][0]);
  }
  for (int t = 0; t < (int)(q1); ++t) {
    int cur = newV();
    long long s = T0 / b[t][2];
    int i0 = b[t][0], j0 = b[t][1];
    for (int i = 1; i <= (int)(n); ++i)
      for (int j = 1; j <= (int)(m); ++j)
        if (dist[i0][j0][i][j] != inf && dist[i0][j0][i][j] <= s)
          addedge(cells[i][j][1], cur);
    addedge(cur, fin);
  }
  int f = calcFlow(SG, st, fin);
  return (f == q0);
}
int main() {
  cin >> n >> m >> q0 >> q1;
  for (int i = 1; i <= (int)(n); ++i)
    for (int j = 1; j <= (int)(m); ++j) {
      char c;
      cin >> c;
      field[i][j] = (c == '.');
    }
  if (abs(q0 - q1) != 1) {
    cout << "-1\n";
    return 0;
  }
  if (q0 == q1 + 1) {
    for (int i = 0; i < (int)(3); ++i) cin >> b[q1][i];
  } else {
    for (int i = 0; i < (int)(3); ++i) cin >> a[q0][i];
  }
  for (int i = 0; i < (int)(q0); ++i)
    for (int j = 0; j < (int)(3); ++j) cin >> a[i][j];
  for (int i = 0; i < (int)(q1); ++i)
    for (int j = 0; j < (int)(3); ++j) cin >> b[i][j];
  if (q0 == q1 + 1)
    q1++;
  else
    q0++;
  for (int i = 1; i <= (int)(n); ++i)
    for (int j = 1; j <= (int)(m); ++j)
      if (field[i][j]) dist[i][j] = bfs(i, j);
  long long l = -1, r = 1e18;
  if (!can(r)) {
    cout << "-1" << endl;
    return 0;
  }
  while (l + 1 < r) {
    long long mid = (l + r) / 2;
    if (can(mid))
      r = mid;
    else
      l = mid;
  }
  cout << r << endl;
  return 0;
}
