#include <bits/stdc++.h>
using namespace std;
class Dinic {
 private:
  struct Edge {
    long long to, cap, rev;
    Edge(long long t, long long c, long long r) : to(t), cap(c), rev(r) {}
  };
  long long V;
  std::vector<std::vector<Edge>> graph;
  std::vector<long long> level, iter;

 public:
  Dinic(long long v) : V(v) {
    graph.resize(v);
    level.resize(v, -1);
    iter.resize(v, 0);
  }
  void add_edge(long long from, long long to, long long cap) {
    graph[from].emplace_back(to, cap, graph[to].size());
    graph[to].emplace_back(from, 0, graph[from].size() - 1);
  }
  void bfs(long long s) {
    std::fill(level.begin(), level.end(), -1);
    std::queue<long long> queue;
    level[s] = 0;
    queue.push(s);
    while (!queue.empty()) {
      long long v = queue.front();
      queue.pop();
      for (long long i = 0; i < (long long)graph[v].size(); ++i) {
        Edge& e = graph[v][i];
        if (e.cap > 0 && level[e.to] < 0) {
          level[e.to] = level[v] + 1;
          queue.push(e.to);
        }
      }
    }
  }
  long long dfs(long long v, long long t, long long f) {
    if (v == t) return f;
    for (long long& i = iter[v]; i < (long long)graph[v].size(); ++i) {
      Edge& e = graph[v][i];
      if (e.cap > 0 && level[v] < level[e.to]) {
        long long d = dfs(e.to, t, std::min(f, e.cap));
        if (d > 0) {
          e.cap -= d;
          graph[e.to][e.rev].cap += d;
          return d;
        }
      }
    }
    return 0;
  }
  long long max_flow(long long s, long long t) {
    long long res = 0;
    while (true) {
      bfs(s);
      if (level[t] < 0) return res;
      std::fill(iter.begin(), iter.end(), 0);
      long long f;
      while ((f = dfs(s, t, LLONG_MAX)) > 0) {
        res += f;
      }
    }
  }
};
long long dist[200][200];
long long x[200000], a[200000], f[200000], p[200000];
long long y[200000], d[200000], g[200000];
vector<pair<long long, long long>> v[200][200];
bool used[200000];
long long s1[2000], s2[2000];
signed main() {
  long long n, m;
  cin >> n >> m;
  memset(d, 0x3f, sizeof(d));
  for (long long i = 0; i < (n); i++) dist[i][i] = 0;
  for (long long i = 0; i < (m); i++) {
    long long a, b;
    scanf("%lld%lld", &a, &b);
    a--;
    b--;
    if (a == b) continue;
    dist[a][b] = dist[b][a] = 1;
  }
  for (long long k = 0; k < (n); k++)
    for (long long i = 0; i < (n); i++)
      for (long long j = 0; j < (n); j++) {
        dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
      }
  long long s, b, k;
  scanf("%lld%lld%lld", &s, &b, &k);
  for (long long i = 0; i < (s); i++) {
    scanf("%lld%lld%lld%lld", &x[i], &a[i], &f[i], &p[i]);
    x[i]--;
  }
  for (long long i = 0; i < (b); i++) {
    scanf("%lld%lld%lld", &y[i], &d[i], &g[i]);
    y[i]--;
  }
  for (long long i = 0; i < (k); i++) {
    scanf("%lld%lld", &s1[i], &s2[i]);
    s1[i]--;
    s2[i]--;
    used[s1[i]] = used[s2[i]] = true;
  }
  for (long long i = 0; i < (n); i++) {
    for (long long j = 0; j < (b); j++) {
      if (dist[i][y[j]] != 0x3f3f3f3f3f3f3f3f) {
        v[i][dist[i][y[j]]].push_back(pair<long long, long long>(d[j], g[j]));
      }
    }
    for (long long j = 0; j < (n); j++) {
      sort(v[i][j].begin(), v[i][j].end(),
           [](pair<long long, long long> a, pair<long long, long long> b) {
             if (a.first == b.first) return a.second > b.second;
             return a.first < b.first;
           });
      vector<pair<long long, long long>> u;
      for (pair<long long, long long> p : v[i][j]) {
        if (u.empty() || u.back().second < p.second) u.push_back(p);
      }
      v[i][j] = u;
    }
  }
  long long ans = 0;
  vector<long long> vs;
  for (long long i = 0; i < (s); i++) {
    if (used[i]) vs.push_back(i);
  }
  sort(vs.begin(), vs.end());
  vs.erase(unique(vs.begin(), vs.end()), vs.end());
  Dinic dinic(vs.size() + 2);
  for (long long i = 0; i < (s); i++) {
    long long Max = -1;
    for (long long j = 0; j < (min(n, f[i] + 1)); j++) {
      long long it = upper_bound(v[x[i]][j].begin(), v[x[i]][j].end(),
                                 pair<long long, long long>(a[i], INT_MAX)) -
                     v[x[i]][j].begin();
      if (it) {
        it--;
        Max = max(Max, v[x[i]][j][it].second);
      }
    }
    if (!used[i]) {
      if (Max - p[i] > 0) ans += Max - p[i];
    } else {
      long long id = lower_bound(vs.begin(), vs.end(), i) - vs.begin();
      if (Max == -1) {
        dinic.add_edge(vs.size(), id, 0);
        dinic.add_edge(id, vs.size() + 1, LLONG_MAX / 100000);
      } else if (Max - p[i] > 0) {
        ans += Max - p[i];
        dinic.add_edge(vs.size(), id, Max - p[i]);
        dinic.add_edge(id, vs.size() + 1, 0);
      } else {
        dinic.add_edge(vs.size(), id, 0);
        dinic.add_edge(id, vs.size() + 1, p[i] - Max);
      }
    }
  }
  for (long long i = 0; i < (k); i++) {
    long long S1 = lower_bound(vs.begin(), vs.end(), s1[i]) - vs.begin();
    long long S2 = lower_bound(vs.begin(), vs.end(), s2[i]) - vs.begin();
    if (S1 == S2) continue;
    dinic.add_edge(S1, S2, LLONG_MAX / 100000);
  }
  cout << ans - dinic.max_flow(vs.size(), vs.size() + 1) << endl;
}
