#include <bits/stdc++.h>
using namespace std;
using ll = long long;
class flow {
 private:
  int n;
  vector<int> head, d, cur;
  vector<tuple<int, ll, int>> edge;
  bool bfs(int s, int t) {
    d.assign(n, -1);
    queue<int> que;
    que.push(s);
    d[s] = 0;
    while (!que.empty()) {
      int u = que.front();
      que.pop();
      for (int i = head[u]; i != -1; i = get<2>(edge[i])) {
        int v = get<0>(edge[i]);
        if (get<1>(edge[i]) && d[v] == -1) {
          d[v] = d[u] + 1;
          if (v == t) {
            return true;
          }
          que.push(v);
        }
      }
    }
    return false;
  }
  ll dfs(int u, int t, ll f) {
    if (u == t) {
      return f;
    }
    ll res = f;
    for (int &i = cur[u]; i != -1 && res; i = get<2>(edge[i])) {
      int v = get<0>(edge[i]);
      ll &c = get<1>(edge[i]);
      if (d[v] == d[u] + 1 && c) {
        ll aug = dfs(v, t, min(res, c));
        res -= aug;
        c -= aug;
        get<1>(edge[i ^ 1]) += aug;
      }
    }
    return f - res;
  }

 public:
  flow(int _n) {
    n = _n;
    head.assign(n, -1);
  }
  void insert_edge(int u, int v, ll c) {
    edge.emplace_back(v, c, head[u]);
    head[u] = edge.size() - 1;
    edge.emplace_back(u, 0, head[v]);
    head[v] = edge.size() - 1;
  }
  ll max_flow(int s, int t) {
    ll flow = 0;
    while (bfs(s, t)) {
      cur = head;
      flow += dfs(s, t, 1e18);
    }
    return flow;
  }
};
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int n, m;
  cin >> n >> m;
  vector<vector<int>> dis(n, vector<int>(n, 1e9));
  for (int i = 0; i < n; ++i) {
    dis[i][i] = 0;
  }
  for (int i = 0; i < m; ++i) {
    int u, v;
    cin >> u >> v;
    --u;
    --v;
    dis[u][v] = 1;
    dis[v][u] = 1;
  }
  for (int k = 0; k < n; ++k) {
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
      }
    }
  }
  int s, b, k;
  cin >> s >> b >> k;
  vector<tuple<int, int, int, int>> ship;
  vector<vector<pair<int, int>>> base(n);
  for (int i = 0; i < s; ++i) {
    int x, a, f, p;
    cin >> x >> a >> f >> p;
    --x;
    ship.emplace_back(x, a, f, p);
  }
  for (int i = 0; i < b; ++i) {
    int x, d, g;
    cin >> x >> d >> g;
    --x;
    base[x].emplace_back(d, g);
  }
  for (int i = 0; i < n; ++i) {
    sort(base[i].begin(), base[i].end());
    for (int j = 1; j < base[i].size(); ++j) {
      base[i][j].second = max(base[i][j].second, base[i][j - 1].second);
    }
  }
  vector<ll> gain(s);
  for (int i = 0; i < s; ++i) {
    int x = get<0>(ship[i]);
    int a = get<1>(ship[i]);
    int f = get<2>(ship[i]);
    int p = get<3>(ship[i]);
    gain[i] = -1e14;
    for (int j = 0; j < n; ++j) {
      if (dis[x][j] <= f && !base[j].empty() && a >= base[j][0].first) {
        gain[i] =
            max(gain[i], 1ll * (--upper_bound(base[j].begin(), base[j].end(),
                                              make_pair(a, (int)1e9)))
                                     ->second -
                             p);
      }
    }
  }
  vector<bool> used(s);
  vector<pair<int, int>> rel;
  for (int i = 0; i < k; ++i) {
    int x, y;
    cin >> x >> y;
    --x;
    --y;
    used[x] = true;
    used[y] = true;
    rel.emplace_back(x, y);
  }
  int cnt = 0;
  ll ans = 0;
  vector<int> id(s, -1);
  for (int i = 0; i < s; ++i) {
    if (used[i]) {
      id[i] = cnt++;
    } else if (gain[i] > 0) {
      ans += gain[i];
    }
  }
  flow G(cnt + 2);
  int S = cnt;
  int T = cnt + 1;
  for (int i = 0; i < s; ++i) {
    if (used[i]) {
      if (gain[i] > 0) {
        G.insert_edge(S, id[i], gain[i]);
        ans += gain[i];
      } else if (gain[i] < 0) {
        G.insert_edge(id[i], T, -gain[i]);
      }
    }
  }
  for (int i = 0; i < k; ++i) {
    G.insert_edge(id[rel[i].first], id[rel[i].second], 1e18);
  }
  ans -= G.max_flow(S, T);
  cout << ans << endl;
  return 0;
}
