#include <bits/stdc++.h>
using namespace std;
const long long INF = 1e17;
const long long maxn = 100015;
const long long maxm = 1000005;
long long g[105][105];
long long num[maxn];
long long id[maxn];
long long cnt;
void floyed(long long n) {
  for (long long k = 1; k <= n; k++) {
    for (long long i = 1; i <= n; i++) {
      for (long long j = 1; j <= n; j++) {
        g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
      }
    }
  }
};
inline long long read() {
  long long x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
struct Edge {
  long long to, next, cap, flow;
} edge[maxm];
long long tol, head[maxn];
void init() {
  tol = 2;
  memset(head, -1, sizeof(head));
}
void addedge(long long u, long long v, long long w, long long rw = 0) {
  edge[tol].to = v;
  edge[tol].cap = w;
  edge[tol].flow = 0;
  edge[tol].next = head[u];
  head[u] = tol++;
  edge[tol].to = u;
  edge[tol].cap = rw;
  edge[tol].flow = 0;
  edge[tol].next = head[v];
  head[v] = tol++;
}
long long Q[maxn];
long long dep[maxn], cur[maxn], sta[maxn];
bool bfs(long long s, long long t, long long n) {
  long long front = 0, tail = 0;
  memset(dep, -1, sizeof(dep[0]) * (n + 1));
  dep[s] = 0;
  Q[tail++] = s;
  while (front < tail) {
    long long u = Q[front++];
    for (long long i = head[u]; i != -1; i = edge[i].next) {
      long long v = edge[i].to;
      if (edge[i].cap > edge[i].flow && dep[v] == -1) {
        dep[v] = dep[u] + 1;
        if (v == t) {
          return true;
        }
        Q[tail++] = v;
      }
    }
  }
  return false;
}
long long dinic(long long s, long long t, long long n) {
  long long maxflow = 0;
  while (bfs(s, t, n)) {
    for (long long i = 0; i < n; i++) {
      cur[i] = head[i];
    }
    long long u = s, tail = 0;
    while (cur[s] != -1) {
      if (u == t) {
        long long tp = INF;
        for (long long i = tail - 1; i >= 0; i--) {
          tp = min(tp, edge[sta[i]].cap - edge[sta[i]].flow);
        }
        maxflow += tp;
        for (long long i = tail - 1; i >= 0; i--) {
          edge[sta[i]].flow += tp;
          edge[sta[i] ^ 1].flow -= tp;
          if (edge[sta[i]].cap - edge[sta[i]].flow == 0) {
            tail = i;
          }
        }
        u = edge[sta[tail] ^ 1].to;
      } else if (cur[u] != -1 && edge[cur[u]].cap > edge[cur[u]].flow &&
                 dep[u] + 1 == dep[edge[cur[u]].to]) {
        sta[tail++] = cur[u];
        u = edge[cur[u]].to;
      } else {
        while (u != s && cur[u] == -1) {
          u = edge[sta[--tail] ^ 1].to;
        }
        cur[u] = edge[cur[u]].next;
      }
    }
  }
  return maxflow;
}
long long fuckacm[100005];
long long ps[105];
long long shipos[maxn], atk[maxn], f[maxn], p[maxn], baspos[maxn], d[maxn],
    gold[maxn], val[maxn], D[maxn];
bool svis[maxn];
vector<pair<long long, long long> > v1[105];
long long e[maxn][2];
bool cmp(long long x, long long y) { return atk[x] < atk[y]; }
long long ans = 0;
signed main() {
  long long n, m, u, v, s, b, k;
  n = read(), m = read();
  for (long long i = 1; i <= n; i++) {
    for (long long j = 1; j <= n; j++) {
      if (i == j)
        g[i][j] = 0;
      else
        g[i][j] = g[j][i] = INF;
    }
  }
  for (long long i = 1; i <= m; i++) {
    u = read(), v = read();
    g[u][v] = g[v][u] = 1;
  }
  floyed(n);
  s = read(), b = read(), k = read();
  for (long long i = 1; i <= s; i++) {
    shipos[i] = read(), atk[i] = read(), f[i] = read(), p[i] = read();
    id[i] = i;
  }
  for (long long i = 1; i <= b; i++) {
    baspos[i] = read(), d[i] = read(), gold[i] = read();
    v1[baspos[i]].emplace_back(pair<long long, long long>(d[i], gold[i]));
  }
  sort(id + 1, id + 1 + s, cmp);
  for (long long i = 1; i <= n; i++) {
    sort(v1[i].begin(), v1[i].end());
    ps[i] = 0;
    for (long long j = 1; j < v1[i].size(); j++) {
      v1[i][j].second = max(v1[i][j].second, v1[i][j - 1].second);
    }
  }
  for (long long I = 1; I <= s; I++) {
    long long i = id[I];
    long long ma = -INF;
    for (long long j = 1; j <= n; j++) {
      if (g[shipos[i]][j] <= f[i]) {
        if (v1[j].empty()) continue;
        while (ps[j] < v1[j].size() - 1 && v1[j][ps[j] + 1].first <= atk[i])
          ps[j]++;
        if (v1[j][ps[j]].first <= atk[i]) ma = max(ma, v1[j][ps[j]].second);
      }
    }
    val[i] = ma - p[i];
    if (val[i] > 0) ans += val[i];
  }
  for (long long i = 1; i <= k; i++) {
    e[i][0] = read(), e[i][1] = read();
    D[e[i][0]]++, D[e[i][1]]++;
  }
  long long S = 2015 + 1, T = S + 1;
  init();
  for (long long i = 1; i <= s; i++) {
    if (D[i]) id[i] = ++cnt;
  }
  for (long long i = 1; i <= s; i++) {
    if (D[i]) {
      if (val[i] > 0)
        addedge(S, id[i], val[i]);
      else
        addedge(id[i], T, -val[i]);
    }
  }
  for (long long i = 1; i <= k; i++) {
    addedge(id[e[i][0]], id[e[i][1]], INF);
  }
  ans -= dinic(S, T, T + 1);
  cout << ans;
  return 0;
}
