#include <bits/stdc++.h>
using namespace std;
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) {}
};
struct Dinic {
  const static long long INFTY = 1LL << 60;
  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) {}
  void addEdge(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 k : g[u]) {
        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 = INFTY) {
    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 = min(flow, e.cap - e.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 total = 0;
    while (BFS(S, T)) {
      fill(pt.begin(), pt.end(), 0);
      while (long long flow = DFS(S, T)) total += flow;
    }
    return total;
  }
};
int N, M, S, B, K, H;
long long dist[105][105];
int pos[1005], att[1005], F[1005];
int X[1005], def[1005];
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> N >> M;
  for (int i = 0; i < N; i++)
    for (int j = i + 1; j < N; j++) dist[i][j] = dist[j][i] = 1LL << 60;
  for (int i = 0, a, b; i < M; i++) {
    cin >> a >> b;
    a--, b--;
    dist[a][b] = dist[b][a] = 1;
  }
  cin >> S >> B >> K >> H;
  for (int i = 0; i < S; i++) cin >> pos[i] >> att[i] >> F[i];
  for (int i = 0; i < B; i++) cin >> X[i] >> def[i];
  for (int k = 0; k < N; k++)
    for (int i = 0; i < N; i++)
      for (int j = 0; j < N; j++)
        dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
  Dinic dinic(S + B + 2);
  for (int i = 0; i < S; i++)
    for (int j = 0; j < B; j++)
      if (att[i] >= def[j] && F[i] >= dist[pos[i]][X[j]])
        dinic.addEdge(i, S + j, 1);
  for (int i = 0; i < S; i++) dinic.addEdge(S + B, i, 1);
  for (int i = 0; i < B; i++) dinic.addEdge(S + i, S + B + 1, 1);
  long long ans = min((long long)H * S, K * dinic.maxFlow(S + B, S + B + 1));
  cout << ans << "\n";
  return 0;
}
