#include <bits/stdc++.h>
using namespace std;
const long long INF = 1e18;
class edge {
 public:
  int e, nxt;
  long long cap;
  edge(int e1 = -1, int nxt1 = -1, long long cap1 = 0) {
    e = e1, nxt = nxt1, cap = cap1;
  }
};
int S, T;
int dep[2510];
bool vis[2510];
class graph {
 public:
  edge g[3000000];
  int head[2510], tmpcnt;
  int cur[2510];
  void init() {
    memset(head, 255, sizeof(head));
    tmpcnt = 0;
  }
  void addedge(int s, int e, long long cap) {
    if (cap == 0) return;
    g[tmpcnt] = edge(e, head[s], cap), head[s] = tmpcnt++;
    g[tmpcnt] = edge(s, head[e], 0), head[e] = tmpcnt++;
  }
  bool bfs() {
    memset(vis, 0, sizeof(vis));
    memset(dep, 0, sizeof(dep));
    queue<int> q;
    q.push(S);
    vis[S] = 1;
    while (!q.empty()) {
      int fr = q.front();
      q.pop();
      for (int i = head[fr]; i != -1; i = g[i].nxt) {
        if (g[i].cap > 0 && !vis[g[i].e]) {
          dep[g[i].e] = dep[fr] + 1;
          vis[g[i].e] = 1;
          q.push(g[i].e);
        }
      }
    }
    return vis[T];
  }
  long long dfs(int np, long long maxflow) {
    long long f, flow = 0;
    if (np == T || !maxflow) return maxflow;
    for (int i = cur[np]; i != -1; i = g[i].nxt) {
      cur[np] = i;
      if (g[i].cap > 0 && dep[g[i].e] == dep[np] + 1 &&
          (f = dfs(g[i].e, min(g[i].cap, maxflow))) > 0) {
        g[i].cap -= f;
        g[i ^ 1].cap += f;
        flow += f;
        maxflow -= f;
        if (!maxflow) break;
      }
    }
    return flow;
  }
  long long dinic() {
    long long out = 0;
    while (bfs()) memcpy(cur, head, sizeof(cur)), out += dfs(S, INF);
    return out;
  }
} G;
int n, m, dis[110][110], s, B, K;
long long vl[100010];
class ship {
 public:
  int x, a, f, p;
} sp[100010];
vector<pair<int, int> > bas[110];
class dependency {
 public:
  int s, e;
} dpd[1010];
int flag[1000010];
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, ti, tj; i <= m; i++) {
    scanf("%d%d", &ti, &tj);
    dis[ti][tj] = dis[tj][ti] = min(dis[ti][tj], 1);
  }
  for (int k = 1; k <= n; k++)
    for (int i = 1; i <= n; i++)
      for (int j = 1; j <= n; j++)
        dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
  scanf("%d%d%d", &s, &B, &K);
  for (int i = 1; i <= s; i++)
    scanf("%d%d%d%d", &sp[i].x, &sp[i].a, &sp[i].f, &sp[i].p);
  for (int i = 1, ti, tj, tk; i <= B; i++) {
    scanf("%d%d%d", &ti, &tj, &tk);
    bas[ti].push_back(make_pair(tj, tk));
  }
  for (int i = 1; i <= n; i++) {
    sort(bas[i].begin(), bas[i].end());
    reverse(bas[i].begin(), bas[i].end());
    vector<pair<int, int> > tmp;
    for (auto &x : bas[i]) {
      while (!tmp.empty() && x.second >= tmp.back().second) tmp.pop_back();
      tmp.push_back(x);
    }
    reverse(tmp.begin(), tmp.end());
    bas[i] = tmp;
  }
  for (int i = 1; i <= K; i++)
    scanf("%d%d", &dpd[i].s, &dpd[i].e), flag[dpd[i].s] = flag[dpd[i].e] = 1;
  for (int i = 1; i <= s; i++) {
    int mxp = -1e9;
    for (int j = 1; j <= n; j++) {
      if (dis[sp[i].x][j] <= sp[i].f) {
        auto x = upper_bound(bas[j].begin(), bas[j].end(),
                             make_pair(sp[i].a + 1, -1000000000));
        if (x == bas[j].begin()) continue;
        x--;
        mxp = max(mxp, x->second);
      }
    }
    if (mxp == -1e9)
      vl[i] = -1e18;
    else
      vl[i] = mxp - sp[i].p;
  }
  vector<int> used;
  used.push_back(0);
  long long ans = 0;
  for (int i = 1; i <= s; i++) {
    if (!flag[i]) {
      if (vl[i] > 0) ans += vl[i];
    } else
      flag[i] = used.size(), used.push_back(i);
  }
  int cnt = used.size();
  cnt--;
  S = cnt + 1;
  T = cnt + 2;
  G.init();
  for (int i = 1; i <= cnt; i++) {
    if (vl[used[i]] >= 0)
      G.addedge(S, i, vl[used[i]]), ans += vl[used[i]];
    else
      G.addedge(i, T, -vl[used[i]]);
  }
  for (int i = 1; i <= K; i++) G.addedge(flag[dpd[i].s], flag[dpd[i].e], INF);
  printf("%lld\n", ans - G.dinic());
  return 0;
}
