#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
int n, m, mel, fel;
int dis[1005][505];
char mp[25][25];
struct Node {
  int x, y, vi;
} a[1005];
int dir[][2] = {1, 0, -1, 0, 0, 1, 0, -1};
int tot, head[3010];
struct Edge {
  int to, w, next;
} edge[2000005];
int id[2][25][25];
void init() {
  tot = 0;
  memset(head, -1, sizeof(head));
}
void addedge(int u, int v, int w) {
  edge[tot].to = v;
  edge[tot].w = w;
  edge[tot].next = head[u];
  head[u] = tot++;
  edge[tot].to = u;
  edge[tot].w = 0;
  edge[tot].next = head[v];
  head[v] = tot++;
}
void get_bfs(int k) {
  queue<Node> Q;
  Node u, v;
  u.x = a[k].x;
  u.y = a[k].y;
  u.vi = 0;
  dis[k][(u.x - 1) * m + u.y] = 0;
  Q.push(u);
  while (!Q.empty()) {
    u = Q.front();
    Q.pop();
    for (int i = 0; i < 4; i++) {
      int x = u.x + dir[i][0];
      int y = u.y + dir[i][1];
      if (x < 1 || x > n || y < 1 || y > m || mp[x][y] == '#' ||
          dis[k][(x - 1) * m + y] != -1)
        continue;
      dis[k][(x - 1) * m + y] = u.vi + 1;
      v.x = x;
      v.y = y;
      v.vi = u.vi + 1;
      Q.push(v);
    }
  }
}
int st, ed;
int d[3010], cur[3010], gap[3010];
void BFS() {
  memset(gap, 0, sizeof(gap));
  memset(d, -1, sizeof(d));
  gap[d[ed] = 0]++;
  for (int i = st; i <= ed; i++) cur[i] = head[i];
  queue<int> Q;
  Q.push(ed);
  while (!Q.empty()) {
    int x = Q.front();
    Q.pop();
    for (int i = head[x]; i != -1; i = edge[i].next) {
      int v = edge[i].to;
      if (d[v] == -1) {
        gap[d[v] = d[x] + 1]++;
        Q.push(v);
      }
    }
  }
}
int DFS(int x, int w) {
  if (x == ed || w == 0) return w;
  int f, ret = 0;
  for (int &i = cur[x]; i != -1; i = edge[i].next) {
    int v = edge[i].to;
    if (d[x] == d[v] + 1 && (f = DFS(v, min(w, edge[i].w)))) {
      edge[i].w -= f;
      edge[i ^ 1].w += f;
      ret += f;
      w -= f;
      if (!w) return ret;
    }
  }
  if (!(--gap[d[x]])) d[st] = ed;
  gap[++d[x]]++;
  cur[x] = head[x];
  return ret;
}
int ISAP() {
  BFS();
  int flow = 0;
  while (d[st] < ed) {
    flow += DFS(st, INF);
  }
  return flow;
}
void build(long long x) {
  init();
  st = 0, ed = 1 + mel + fel + 2 * n * m + 10;
  for (int i = 1; i <= mel; i++) addedge(st, 1 + i, 1);
  for (int i = 1; i <= fel; i++) addedge(1 + mel + i, ed, 1);
  if (mel < fel)
    addedge(st, 1, 1);
  else
    addedge(1, ed, 1);
  for (int i = 2; i <= mel + 1; i++) {
    for (int j = 1; j <= n; j++) {
      for (int k = 1; k <= m; k++) {
        if (dis[i][(j - 1) * m + k] == -1) continue;
        if ((long long)dis[i][(j - 1) * m + k] * a[i].vi <= x)
          addedge(i, id[0][j][k], 1);
      }
    }
  }
  for (int i = mel + 2; i <= 1 + mel + fel; i++) {
    for (int j = 1; j <= n; j++) {
      for (int k = 1; k <= m; k++) {
        if (dis[i][(j - 1) * m + k] == -1) continue;
        if ((long long)dis[i][(j - 1) * m + k] * a[i].vi <= x)
          addedge(id[1][j][k], i, 1);
      }
    }
  }
  if (mel < fel) {
    for (int j = 1; j <= n; j++) {
      for (int k = 1; k <= m; k++) {
        if (dis[1][(j - 1) * m + k] == -1) continue;
        if ((long long)dis[1][(j - 1) * m + k] * a[1].vi <= x)
          addedge(1, id[0][j][k], 1);
      }
    }
  } else {
    for (int j = 1; j <= n; j++) {
      for (int k = 1; k <= m; k++) {
        if (dis[1][(j - 1) * m + k] == -1) continue;
        if ((long long)dis[1][(j - 1) * m + k] * a[1].vi <= x)
          addedge(id[1][j][k], 1, 1);
      }
    }
  }
  for (int j = 1; j <= n; j++) {
    for (int k = 1; k <= m; k++) {
      addedge(id[0][j][k], id[1][j][k], 1);
    }
  }
}
bool ok(long long x) {
  build(x);
  int sum = (1 + mel + fel) / 2;
  if (sum == ISAP())
    return true;
  else
    return false;
}
void work() {
  memset(dis, -1, sizeof(dis));
  for (int i = 1; i <= mel + fel + 1; i++) get_bfs(i);
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      id[0][i][j] = 1 + mel + fel + (i - 1) * m + j;
      id[1][i][j] = 1 + mel + fel + n * m + (i - 1) * m + j;
    }
  }
  long long ans = -1, l = 0, r = 1e12;
  while (l <= r) {
    long long mid = (l + r) >> 1;
    if (ok(mid)) {
      ans = mid;
      r = mid - 1;
    } else
      l = mid + 1;
  }
  printf("%lld\n", ans);
}
int main() {
  scanf("%d%d%d%d", &n, &m, &mel, &fel);
  for (int i = 1; i <= n; i++) scanf("%s", mp[i] + 1);
  for (int i = 1; i <= mel + fel + 1; i++) {
    scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].vi);
  }
  if (min(fel, mel) + 1 == max(fel, mel))
    work();
  else
    puts("-1");
}
