#include <bits/stdc++.h>
using namespace std;
long long mod = 1000000007LL;
long long large = 2000000000000000000LL;
struct Edge {
  int from, to;
  long long cap, flow;
};
struct Dinic {
  int n, m, s, t;
  vector<Edge> edges;
  vector<vector<int> > G;
  vector<bool> vis;
  vector<int> dis;
  vector<int> cur;
  void init(int maxn) {
    edges.clear();
    G.assign(maxn + 10, vector<int>(0));
    vis.assign(maxn + 10, false);
    dis.assign(maxn + 10, 0);
    cur.assign(maxn + 10, 0);
    n = maxn;
  }
  void addEdge(int from, int to, long long cap) {
    edges.push_back((Edge){from, to, cap, 0});
    edges.push_back((Edge){to, from, 0, 0});
    m = edges.size();
    G[from].push_back(m - 2);
    G[to].push_back(m - 1);
  }
  bool BFS() {
    vis.assign(n + 10, false);
    queue<int> q;
    q.push(s);
    dis[s] = 0;
    vis[s] = true;
    while (!q.empty()) {
      int u = q.front();
      q.pop();
      for (int i = 0; i < (int)G[u].size(); i++) {
        Edge& e = edges[G[u][i]];
        if (!vis[e.to] && e.cap > e.flow) {
          vis[e.to] = 1;
          dis[e.to] = dis[u] + 1;
          q.push(e.to);
        }
      }
    }
    return vis[t];
  }
  long long DFS(int x, long long a) {
    if (x == t || a == 0) return a;
    long long flow = 0, f;
    for (int& i = cur[x]; i < (int)G[x].size(); i++) {
      Edge& e = edges[G[x][i]];
      if (dis[x] + 1 == dis[e.to] &&
          (f = DFS(e.to, min(a, e.cap - e.flow))) > 0) {
        e.flow += f;
        edges[G[x][i] ^ 1].flow -= f;
        flow += f;
        a -= f;
        if (a == 0) break;
      }
    }
    return flow;
  }
  long long maxflow(int s, int t) {
    this->s = s;
    this->t = t;
    long long flow = 0;
    while (BFS()) {
      cur.assign(n + 10, 0);
      flow += DFS(s, large);
    }
    return flow;
  }
  void clearflow() {
    vis.assign(n + 10, false);
    dis.assign(n + 10, 0);
    cur.assign(n + 10, 0);
    for (int i = 0; i < (int)edges.size(); i++) {
      edges[i].flow = 0;
    }
  }
};
int main() {
  int n, m;
  cin >> n >> m;
  vector<vector<int> > g(n, vector<int>(n, 1000000000));
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    x--;
    y--;
    g[x][y] = g[y][x] = 1;
  }
  for (int i = 0; i < n; i++) g[i][i] = 0;
  for (int k = 0; k < n; k++)
    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++) g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
  int s, b;
  cin >> s >> b;
  int k;
  cin >> k;
  vector<int> ps(s, 0), a(s, 0), f(s, 0), p(s, 0);
  vector<int> pb(b, 0), d(b, 0), gold(b, 0);
  for (int i = 0; i < s; i++) {
    cin >> ps[i] >> a[i] >> f[i] >> p[i];
    ps[i]--;
  }
  for (int i = 0; i < b; i++) {
    cin >> pb[i] >> d[i] >> gold[i];
    pb[i]--;
  }
  vector<vector<pair<int, int> > > adj(n, vector<pair<int, int> >());
  for (int i = 0; i < b; i++) {
    adj[pb[i]].push_back(pair<int, int>(d[i], gold[i]));
  }
  for (int i = 0; i < n; i++) sort(adj[i].begin(), adj[i].end());
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < (int)adj[i].size(); j++) {
      if (j) adj[i][j].second = max(adj[i][j].second, adj[i][j - 1].second);
    }
  }
  for (int i = 0; i < s; i++) {
    int ans = -1;
    for (int j = 0; j < n; j++) {
      if (g[ps[i]][j] > f[i]) continue;
      int pt = upper_bound(adj[j].begin(), adj[j].end(),
                           pair<int, int>(a[i], 1000000010)) -
               adj[j].begin();
      pt--;
      if (pt >= 0) ans = max(ans, adj[j][pt].second);
    }
    if (ans != -1)
      p[i] = ans - p[i];
    else
      p[i] = -large;
  }
  Dinic din;
  din.init(s + 10);
  int st = s;
  int en = st + 1;
  long long sum = 0;
  for (int i = 0; i < s; i++) {
    if (p[i] > 0) {
      din.addEdge(st, i, p[i]);
      sum += p[i];
    } else
      din.addEdge(i, en, -p[i]);
  }
  for (int i = 0; i < k; i++) {
    int x, y;
    cin >> x >> y;
    x--;
    y--;
    din.addEdge(x, y, large);
  }
  cout << sum - din.maxflow(st, en) << endl;
  return 0;
}
