#include <bits/stdc++.h>
using namespace std;
const long long mod = 1000000007;
const long long INF = 100000000000000;
const long double eps = 1e-8;
struct edge {
  int to;
  long long cap;
  int rev;
};
vector<edge> G[100000];
bool used[100000];
void add_edge(int from, int to, long long cap) {
  G[from].push_back(edge{to, cap, (int)G[to].size()});
  G[to].push_back(edge{from, 0, (int)G[from].size() - 1});
}
long long dfs(int v, int t, long long f) {
  if (v == t) return f;
  used[v] = true;
  for (int i = 0; i < (int)G[v].size(); i++) {
    edge &e = G[v][i];
    if (!used[e.to] && e.cap > 0) {
      int d = dfs(e.to, t, min(f, e.cap));
      if (d > 0) {
        e.cap -= d;
        G[e.to][e.rev].cap += d;
        return d;
      }
    }
  }
  return 0;
}
long long max_flow(int s, int t) {
  long long flow = 0;
  for (;;) {
    memset(used, 0, sizeof(used));
    long long f = dfs(s, t, INF);
    if (f == 0) return flow;
    flow += f;
  }
}
int distr[101][101];
void solve() {
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (i == j)
        distr[i][j] = 0;
      else
        distr[i][j] = mod;
    }
  }
  for (int i = 0; i < m; i++) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    distr[a][b] = distr[b][a] = 1;
  }
  for (int k = 0; k < n; k++) {
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        distr[i][j] = min(distr[i][j], distr[i][k] + distr[k][j]);
      }
    }
  }
  int nl, nr, nrel;
  cin >> nl >> nr >> nrel;
  vector<int> xl(nl), a(nl), f(nl), p(nl);
  vector<int> xr(nr), b(nr), g(nr);
  for (int i = 0; i < nl; i++) {
    cin >> xl[i] >> a[i] >> f[i] >> p[i];
    xl[i]--;
  }
  for (int i = 0; i < nr; i++) {
    cin >> xr[i] >> b[i] >> g[i];
    xr[i]--;
  }
  vector<pair<int, int>> rel(nrel);
  for (int i = 0; i < nrel; i++) {
    int u, v;
    cin >> u >> v;
    u--;
    v--;
    rel[i] = {u, v};
  }
  vector<vector<pair<int, int>>> vb(n);
  for (int i = 0; i < nr; i++) {
    vb[xr[i]].push_back({b[i], g[i]});
  }
  vector<vector<int>> bb(n), hg(n);
  for (int i = 0; i < n; i++) {
    sort(vb[i].begin(), vb[i].end());
    bb[i].resize(vb[i].size());
    hg[i].resize(vb[i].size() + 1);
    int ma = -2 * mod;
    for (int j = 0; j < (int)vb[i].size(); j++) {
      bb[i][j] = vb[i][j].first;
      hg[i][j] = ma;
      ma = max(ma, vb[i][j].second);
    }
    hg[i][vb[i].size()] = ma;
  }
  vector<bool> cant(nl, false);
  vector<long long> val(nl);
  for (int i = 0; i < nl; i++) {
    int maval = -2 * mod;
    for (int j = 0; j < n; j++) {
      int d = distr[xl[i]][j];
      if (d > f[i]) continue;
      int id = upper_bound(bb[j].begin(), bb[j].end(), a[i]) - bb[j].begin();
      maval = max(maval, hg[j][id]);
    }
    if (maval == -2 * mod) {
      cant[i] = true;
    }
    val[i] = (long long)maval - (long long)p[i];
  }
  vector<bool> exi(nl, false);
  for (int i = 0; i < nrel; i++) {
    int u = rel[i].first, v = rel[i].second;
    exi[u] = exi[v] = true;
  }
  vector<int> ids;
  vector<int> trans(nl);
  long long ans = 0;
  for (int i = 0; i < nl; i++) {
    if (!exi[i]) {
      ans += max((long long)0, val[i]);
    } else {
      trans[i] = ids.size();
      ids.push_back(i);
    }
  }
  int s = ids.size();
  int t = s + 1;
  for (int i = 0; i < ids.size(); i++) {
    int id = ids[i];
    long long cost = val[id];
    if (cost < 0) {
      add_edge(s, i, -cost);
      add_edge(i, t, 0);
    } else {
      add_edge(s, i, 0);
      add_edge(i, t, cost);
    }
    if (cant[id]) {
      add_edge(s, i, INF);
    }
  }
  for (int i = 0; i < nrel; i++) {
    int u = rel[i].first, v = rel[i].second;
    u = trans[u], v = trans[v];
    add_edge(v, u, INF);
  }
  long long sum = 0;
  for (int i = 0; i < ids.size(); i++) {
    if (val[ids[i]] >= 0) {
      sum += val[ids[i]];
    }
  }
  long long z = max_flow(s, t);
  sum -= z;
  ans += sum;
  cout << ans << endl;
}
signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  solve();
  return 0;
}
