#include <bits/stdc++.h>   using namespace std;   inline char nc() {     return getchar();     static char buf[100000], *l = buf, *r = buf;     return l == r && (r = (l = buf) + fread(buf, 1, 100000, stdin), l == r)                ? EOF                : *l++;   }   template <class T>   void read(T &x) {     x = 0;     int f = 1, ch = nc();     while (ch <  0  || ch >  9 ) {       if (ch ==  - ) f = -1;       ch = nc();     }     while (ch >=  0  && ch <=  9 ) {       x = x * 10 -  0  + ch;       ch = nc();     }     x *= f;   }   const int inf = 1e9 + 1;   const int maxn = 100 + 5;   const int maxs = 1e5 + 5;   const int maxb = 1e5 + 5;   int n, m;   int s, b, k;   int st, ed;   int val[maxn];   int dis[maxn][maxn];   int head[maxs];   vector<int> adj[maxn];   struct data {     int a, b, c, d, id;     inline bool operator<(const data &other) const { return b < other.b; }   } A[maxs], B[maxb];   struct edge {     int to, nex;     long long cap, flow;     edge(int to = 0, int nex = 0, long long cap = 0, long long flow = 0)         : to(to), nex(nex), cap(cap), flow(flow) {}   };   vector<edge> G;   inline void adde(int u, int v) {     adj[u].push_back(v);     adj[v].push_back(u);   }   inline void addedge(int u, int v, long long c) {     G.push_back(edge(v, head[u], c, 0)), head[u] = G.size() - 1;     G.push_back(edge(u, head[v], 0, 0)), head[v] = G.size() - 1;   }   namespace dinic {   int dis[maxs], cur[maxs];   bool BFS() {     static int q[maxs];     int hd = 0, tl = 0;     memset(dis, -1, sizeof(dis));     dis[st] = 0;     q[tl++] = st;     while (hd < tl) {       int u = q[hd++];       for (int i = head[u]; ~i; i = G[i].nex) {         int v = G[i].to;         if (dis[v] == -1 && G[i].cap != G[i].flow) {           dis[v] = dis[u] + 1;           q[tl++] = v;         }       }     }     return dis[ed] != -1;   }   long long DFS(int u, long long flow) {     if (u == ed || flow == 0) return flow;     long long rec = flow;     for (int &i = cur[u]; ~i; i = G[i].nex) {       int v = G[i].to;       if (dis[v] == dis[u] + 1) {         long long d = DFS(v, min(flow, G[i].cap - G[i].flow));         G[i].flow += d;         G[i ^ 1].flow -= d;         flow -= d;         if (flow == 0) break;       }     }     return rec - flow;   }   long long maxflow() {     long long flow = 0;     while (BFS()) {       memcpy(cur, head, sizeof(head));       flow += DFS(st, 1e18);     }     return flow;   }   }  // namespace dinic   int adde(int x) {     int mx = -1;     for (int i = 1; i <= n; ++i)       if (dis[A[x].a][i] <= A[x].c) {         mx = max(mx, val[i]);       }     if (mx == -1) {       addedge(A[x].id, ed, 1e18);       return 0;     }     mx -= A[x].d;     if (mx < 0) {       addedge(A[x].id, ed, -mx);       return 0;     }     addedge(st, A[x].id, mx);     return mx;   }   void BFS(int st) {     static int q[maxn];     int hd = 0, tl = 0;     for (int i = 1; i <= n; ++i) dis[st][i] = inf;     dis[st][st] = 0;     q[tl++] = st;     while (hd < tl) {       int u = q[hd++];       for (unsigned int i = 0; i < adj[u].size(); ++i) {         int v = adj[u][i];         if (dis[st][v] == inf) {           dis[st][v] = dis[st][u] + 1;           q[tl++] = v;         }       }     }   }   void init() {     for (int i = 1; i <= n; ++i) BFS(i);   }   long long solve() {     init();     sort(A + 1, A + s + 1);     sort(B + 1, B + b + 1);     long long an = 0;     int i = 1, j = 1;     st = 0, ed = s + 1;     memset(val, -1, sizeof(val));     while (i <= s && j <= b) {       if (B[j].b <= A[i].b) {         val[B[j].a] = max(val[B[j].a], B[j].c);         ++j;       } else {         an += adde(i++);       }     }     while (i <= s) an += adde(i++);     return an - dinic ::maxflow();   }   int main() {     read(n), read(m);     for (int i = 1; i <= m; ++i) {       int u, v;       read(u), read(v);       adde(u, v);     }     read(s), read(b), read(k);     for (int i = 1; i <= s; ++i) {       read(A[i].a), read(A[i].b), read(A[i].c), read(A[i].d);       A[i].id = i;     }     for (int i = 1; i <= b; ++i) {       read(B[i].a), read(B[i].b), read(B[i].c);     }     memset(head, -1, sizeof(head));     for (int i = 1; i <= k; ++i) {       int s1, s2;       read(s1), read(s2);       addedge(s1, s2, 1e18);     }     printf( %I64d n , solve());     return 0;   }