#include <bits/stdc++.h>   #pragma GCC optimize( Ofast,no-stack-protector )   #pragma GCC target(         sse,sse2,sse3,ssse3,sse4,sse4.1,sse4.2,popcnt,abm,mmx,avx,avx2,tune=native )   using namespace std;   struct Dinic {     struct Edge {       long long flow;       int to, next;     };     vector<Edge> edges;     vector<int> adia, at, dist;     int S, D;     void add_Edge(int from, int to, long long cap) {       edges.push_back({cap, to, adia[from]});       adia[from] = edges.size() - 1;       edges.push_back({0, from, adia[to]});       adia[to] = edges.size() - 1;     }     bool bfs() {       queue<int> q;       fill(dist.begin(), dist.end(), 1e9);       dist[S] = 0;       q.push(S);       while (!q.empty()) {         int x = q.front();         q.pop();         for (int i = adia[x]; i != -1; i = edges[i].next) {           if (dist[edges[i].to] > dist[x] + 1 && edges[i].flow) {             dist[edges[i].to] = 1 + dist[x];             q.push(edges[i].to);           }         }       }       return dist[D] < 1e9;     }     long long dfs(int nod, long long fmax) {       if (nod == D) return fmax;       while (at[nod] != -1) {         Edge& e = edges[at[nod]];         long long f;         if (dist[e.to] == dist[nod] + 1 && e.flow &&             (f = dfs(e.to, min(fmax, e.flow)))) {           e.flow -= f;           edges[at[nod] ^ 1].flow += f;           return f;         }         at[nod] = edges[at[nod]].next;       }       return 0;     }     long long GetFlow() {       long long f = 0;       while (bfs()) {         at = adia;         while (long long x = dfs(S, 1e18)) f += x;       }       return f;     }     Dinic(int n = 0, int s = 0, int d = 0) {       S = s, D = d;       at = dist = adia = vector<int>(n + 1, -1);     }   };   const int NMAX = 110;   int dmin[NMAX][NMAX];   struct Object {     int cost, nod, power, id, fuel, atac;   };   vector<Object> ships, bases;   vector<pair<int, int>> dependencies;   int n;   int best_cost[NMAX];   void get_cost_nave() {     fill(best_cost, best_cost + n + 1, -1);     vector<int> nv(ships.size());     iota(nv.begin(), nv.end(), 0);     sort(nv.begin(), nv.end(),          [](int a, int b) { return ships[a].power < ships[b].power; });     sort(bases.begin(), bases.end(),          [](Object a, Object b) { return a.power < b.power; });     int it = 0;     for (auto i : nv) {       while (it != bases.size() && ships[i].power >= bases[it].power) {         best_cost[bases[it].nod] = max(best_cost[bases[it].nod], bases[it].cost);         it++;       }       int best = -1;       for (int nod = 1; nod <= n; nod++)         if (dmin[nod][ships[i].nod] <= ships[i].fuel)           best = max(best, best_cost[nod]);       ships[i].atac = best;     }   }   void read() {     int m, a, b;     scanf( %d%d , &n, &m);     fill(dmin[0], dmin[n + 1], 1e9);     for (int i = 1; i <= n; i++) dmin[i][i] = 0;     while (m--) {       scanf( %d%d , &a, &b);       dmin[a][b] = dmin[b][a] = 1;     }     for (int k = 1; k <= n; k++)       for (int i = 1; i <= n; i++)         for (int j = 1; j <= n; j++)           dmin[i][j] = min(dmin[i][j], dmin[i][k] + dmin[k][j]);     int s, k;     scanf( %d%d%d , &s, &b, &k);     ships.resize(s);     bases.resize(b);     dependencies.resize(k);     for (auto& i : ships) {       scanf( %d%d%d%d , &i.nod, &i.power, &i.fuel, &i.cost);       i.fuel = min(i.fuel, 1000000);     }     for (auto& i : bases) scanf( %d%d%d , &i.nod, &i.power, &i.cost);     for (auto& i : dependencies) scanf( %d%d , &i.first, &i.second);   }   int main() {     read();     get_cost_nave();     long long ans = 0;     int cnt = 2, S = 1, D = 2;     const long long inf = 1e18;     for (auto& i : dependencies) i.first--, i.second--;     for (int i = 0; i < ships.size(); i++) ships[i].id = ++cnt;     Dinic flow(cnt + 1, S, D);     for (auto i : ships) {       if (i.atac == -1)         flow.add_Edge(i.id, D, inf);       else {         int castig = i.atac - i.cost;         if (castig > 0) {           ans += castig;           flow.add_Edge(S, i.id, castig);         } else           flow.add_Edge(i.id, D, -castig);       }     }     for (auto i : dependencies)       flow.add_Edge(ships[i.first].id, ships[i.second].id, inf);     ans -= flow.GetFlow();     cout << ans <<   n ;     return 0;   }