#include <bits/stdc++.h>
using namespace std;
template <class T>
void chkmax(T &a, T b) {
  if (a < b) a = b;
}
vector<int> v[105];
vector<int> vs[105], vb[105];
int n, m;
int nn, mm, kk;
int f[100005], d[100005], g[100005], a[100005], x[100005], y[100005], p[100005];
bool cmpf(int x, int y) { return f[x] < f[y]; }
int dd[105];
int fen[100005 << 1];
int val[100005 << 1], vals;
void update(int k, int v) {
  for (; k <= vals; k += k & -k) {
    chkmax(fen[k], v);
  }
  return;
}
const int inf = 0x3f3f3f3f;
int calc_mx(int k) {
  int res = -inf;
  for (; k; k -= k & -k) {
    chkmax(res, fen[k]);
  }
  return res;
}
void update(int k) {
  for (auto x : vb[k]) {
    update(d[x], g[x]);
  }
}
int rd[100005];
void solve(int k) {
  memset(dd, -1, sizeof dd);
  memset(fen, -1, sizeof fen);
  vector<int> A, B;
  A.push_back(k);
  int now = 0;
  update(k);
  int tot = 1;
  int t = 0;
  while (t < vs[k].size() && f[vs[k][t]] == 0) {
    int kk = vs[k][t];
    chkmax(rd[kk], calc_mx(a[kk]));
    t++;
  }
  while (!A.empty() && t < vs[k].size()) {
    B.clear();
    now++;
    for (auto x : A) {
      for (auto y : v[x]) {
        if (dd[y] < 0) {
          B.push_back(y);
          update(y);
          dd[y] = dd[x] + 1;
        }
      }
    }
    tot += B.size();
    while (t < vs[k].size() && f[vs[k][t]] == now) {
      int kk = vs[k][t];
      chkmax(rd[kk], calc_mx(a[kk]));
      t++;
    }
    A.swap(B);
  }
  while (t < vs[k].size()) {
    int kk = vs[k][t];
    chkmax(rd[kk], calc_mx(a[kk]));
    t++;
  }
  return;
}
vector<int> vv[100005];
bool vd[100005], vis[100005];
void dfs(int k) {
  vd[k] = 1;
  vis[k] = 1;
  for (auto x : vv[k]) {
    if (vd[x]) continue;
    dfs(x);
  }
  return;
}
map<int, int> H;
int tot;
const long long linf = 1e16;
struct Dinic {
  struct edge {
    int u, v;
    long long cap, flow;
    edge() {}
    edge(int u, int v, long long cap) : u(u), v(v), cap(cap), flow(0) {}
  };
  int n;
  vector<edge> E;
  vector<vector<int> > g;
  vector<int> d, pt;
  Dinic(int n) : n(n), E(0), g(n), d(n), pt(n) {}
  Dinic() {}
  void init(int _n) {
    n = _n;
    g.resize(n);
    d.resize(n);
    E.resize(0);
    pt.resize(n);
    for (int i = 0; i < n; i++) g[i].clear();
  }
  void add_edge(int u, int v, long long cap) {
    if (u != v) {
      E.push_back(edge(u, v, cap));
      g[u].push_back(E.size() - 1);
      E.push_back(edge(v, u, 0));
      g[v].push_back(E.size() - 1);
    }
  }
  bool BFS(int S, int T) {
    queue<int> q;
    q.push(S);
    fill(d.begin(), d.end(), n + 1);
    d[S] = 0;
    while (!q.empty()) {
      int u = q.front();
      q.pop();
      if (u == T) break;
      for (int i = 0; i < g[u].size(); i++) {
        int k = g[u][i];
        edge &e = E[k];
        if (e.flow < e.cap && d[e.v] > d[e.u] + 1) {
          d[e.v] = d[e.u] + 1;
          q.push(e.v);
        }
      }
    }
    return d[T] != n + 1;
  }
  long long DFS(int u, int T, long long flow = -1) {
    if (u == T || flow == 0) return flow;
    for (int &i = pt[u]; i < g[u].size(); ++i) {
      edge &e = E[g[u][i]];
      edge &oe = E[g[u][i] ^ 1];
      if (d[e.v] == d[e.u] + 1) {
        long long amt = e.cap - e.flow;
        if (flow != -1 && amt > flow) amt = flow;
        if (long long pushed = DFS(e.v, T, amt)) {
          e.flow += pushed;
          oe.flow -= pushed;
          return pushed;
        }
      }
    }
    return 0;
  }
  long long maxflow(int S, int T) {
    long long res = 0;
    while (BFS(S, T)) {
      fill(pt.begin(), pt.end(), 0);
      while (long long flow = DFS(S, T)) res += flow;
    }
    return res;
  }
} A;
long long tot_sum;
bool vvis[100005];
void add_edge(int x, int y) {
  vvis[x] = vvis[y] = 1;
  if (!H.count(x)) {
    H[x] = ++tot;
    int t = rd[x] - p[x];
    if (t < 0)
      A.add_edge(tot, 1, -t);
    else
      A.add_edge(0, tot, t), tot_sum += t;
  }
  if (!H.count(y)) {
    H[y] = ++tot;
    int t = rd[y] - p[y];
    if (t < 0)
      A.add_edge(tot, 1, -t);
    else
      A.add_edge(0, tot, t), tot_sum += t;
  }
  A.add_edge(H[x], H[y], linf);
}
int main() {
  memset(rd, -1, sizeof rd);
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= m; i++) {
    int x, y;
    scanf("%d %d", &x, &y);
    v[x].push_back(y);
    v[y].push_back(x);
  }
  scanf("%d %d %d", &nn, &mm, &kk);
  for (int i = 1; i <= nn; i++) {
    scanf("%d %d %d %d", &x[i], &a[i], &f[i], &p[i]);
    if (f[i] >= n) f[i] = n - 1;
    val[vals++] = a[i];
    vs[x[i]].push_back(i);
  }
  for (int i = 1; i <= mm; i++) {
    scanf("%d %d %d", &y[i], &d[i], &g[i]);
    vb[y[i]].push_back(i);
    val[vals++] = d[i];
  }
  sort(val, val + vals);
  vals = unique(val, val + vals) - val;
  for (int i = 1; i <= nn; i++) {
    a[i] = lower_bound(val, val + vals, a[i]) - val + 1;
  }
  for (int i = 1; i <= mm; i++) {
    d[i] = lower_bound(val, val + vals, d[i]) - val + 1;
  }
  for (int i = 1; i <= n; i++) sort(vs[i].begin(), vs[i].end(), cmpf);
  for (int i = 1; i <= n; i++)
    if (!vs[i].empty()) solve(i);
  for (int i = 1; i <= nn; i++)
    if (rd[i] < 0) vis[i] = 1;
  while (kk--) {
    int x, y;
    scanf("%d %d", &x, &y);
    vv[y].push_back(x);
  }
  for (int i = 1; i <= nn; i++)
    if (vis[i] && !vd[i]) dfs(i);
  A.init(3000);
  tot = 1;
  for (int i = 1; i <= nn; i++)
    if (!vis[i]) {
      for (auto x : vv[i])
        if (!vis[x]) {
          add_edge(x, i);
        }
    }
  long long flow = A.maxflow(0, 1);
  flow = tot_sum - flow;
  for (int i = 1; i <= nn; i++)
    if (!vvis[i] && !vis[i] && rd[i] - p[i] > 0) flow += rd[i] - p[i];
  printf("%I64d\n", flow);
  return 0;
}
