#include <bits/stdc++.h>
using namespace std;
template <typename T>
struct Dinic {
  static const int MAXN = 100005, MAXM = 1000005;
  struct Edge {
    int to, next;
    T cap;
  } edge[MAXM];
  int head[MAXN], tot;
  void clear() {
    memset(head, -1, sizeof(head));
    tot = 0;
  }
  Dinic() { clear(); }
  void add(int u, int v, T c) {
    edge[tot] = (Edge){v, head[u], c};
    head[u] = tot++;
    edge[tot] = (Edge){u, head[v], (T)0};
    head[v] = tot++;
  }
  int dis[MAXN], que[MAXN], id[MAXN];
  bool bfs(int s, int t) {
    memset(dis, -1, sizeof(dis));
    memcpy(id, head, sizeof(id));
    int he = 0, ta = 0;
    dis[que[ta++] = s] = 0;
    while (he < ta) {
      int u = que[he++];
      for (int i = head[u]; ~i; i = edge[i].next) {
        int v = edge[i].to;
        if (dis[v] < 0 && edge[i].cap) {
          dis[que[ta++] = v] = dis[u] + 1;
          if (v == t) return true;
        }
      }
    }
    return false;
  }
  T dfs(int u, int t, T f) {
    if (u == t) return f;
    T flow = 0;
    for (int &i = id[u]; ~i; i = edge[i].next) {
      int v = edge[i].to;
      if (dis[v] > dis[u] && edge[i].cap) {
        int d = dfs(v, t, min(f, edge[i].cap));
        if (!d) continue;
        edge[i].cap -= d, edge[i ^ 1].cap += d;
        flow += d, f -= d;
        if (f == 0) return flow;
      }
    }
    dis[u] = -1;
    return flow;
  }
  T dinic(int s, int t, T inf = 1E9) {
    T flow = 0;
    while (bfs(s, t)) flow += dfs(s, t, inf);
    return flow;
  }
};
const long long INF = 1E15;
Dinic<long long> din;
const int MAXN = 100005;
int dis[105][105], xx[MAXN], aa[MAXN], ff[MAXN], pp[MAXN], qq[MAXN], vis[MAXN],
    n, m;
struct Node {
  int d, g;
} sh[MAXN];
vector<Node> nd[105];
bool cmp(const Node &a, const Node &b) { return a.d < b.d; }
int main() {
  scanf("%d%d", &n, &m);
  memset(dis, 0x3f, sizeof(dis));
  for (int i = 1; i <= n; i++) dis[i][i] = 0;
  for (int i = 1; i <= m; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    dis[u][v] = dis[v][u] = 1;
  }
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++)
      for (int k = 1; k <= n; k++)
        dis[j][k] = min(dis[i][j] + dis[i][k], dis[j][k]);
  int S, B, K;
  scanf("%d%d%d", &S, &B, &K);
  for (int i = 1; i <= S; i++) {
    scanf("%d%d%d%d", xx + i, aa + i, ff + i, pp + i);
    sh[i] = (Node){aa[i], i};
  }
  sort(sh + 1, sh + 1 + S, cmp);
  for (int i = 1; i <= B; i++) {
    int x, d, g;
    scanf("%d%d%d", &x, &d, &g);
    nd[x].push_back((Node){d, g});
  }
  for (int i = 1; i <= n; i++) {
    sort(nd[i].begin(), nd[i].end(), cmp);
    int mx = 0;
    for (Node &d : nd[i]) {
      mx = max(mx, d.g);
      d.g = mx;
    }
  }
  fill(qq + 1, qq + 1 + S, -1E9 - 555);
  for (int i = 1; i <= n; i++) {
    int s = nd[i].size();
    for (int j = 1, k = 0; j <= S; j++) {
      for (; k < s && nd[i][k].d <= sh[j].d; ++k)
        ;
      if (k > 0 && dis[i][xx[sh[j].g]] <= ff[sh[j].g])
        qq[sh[j].g] = max(qq[sh[j].g], nd[i][k - 1].g);
    }
  }
  for (int i = 1; i <= S; i++) pp[i] = qq[i] - pp[i];
  for (int i = 1; i <= K; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    din.add(u, v, INF);
    vis[u] = vis[v] = 1;
  }
  long long ans = 0;
  int s = S + 1, t = s + 1;
  for (int i = 1; i <= S; i++)
    if (!vis[i] && pp[i] > 0) ans += pp[i];
  for (int i = 1; i <= S; i++)
    if (vis[i]) {
      if (pp[i] > 0)
        din.add(s, i, pp[i]), ans += pp[i];
      else
        din.add(i, t, -pp[i]);
    }
  printf("%lld\n", ans - din.dinic(s, t, INF));
  return 0;
}
