#include <bits/stdc++.h>
using namespace std;
const int MAXN1 = 50000;
const int MAXN2 = 50000;
const int MAXM = 1500000;
int n1, n2, edges, last[MAXN1], Prev[MAXM], head[MAXM];
int matching[MAXN2], dist[MAXN1], Q[MAXN1];
bool used[MAXN1], vis[MAXN1];
void init(int _n1, int _n2) {
  n1 = _n1;
  n2 = _n2;
  edges = 0;
  fill(last, last + n1, -1);
}
void addEdge(int u, int v) {
  head[edges] = v;
  Prev[edges] = last[u];
  last[u] = edges++;
}
void bfs() {
  fill(dist, dist + n1, -1);
  int sizeQ = 0;
  for (int u = 0; u < n1; ++u) {
    if (!used[u]) {
      Q[sizeQ++] = u;
      dist[u] = 0;
    }
  }
  for (int i = 0; i < sizeQ; i++) {
    int u1 = Q[i];
    for (int e = last[u1]; e >= 0; e = Prev[e]) {
      int u2 = matching[head[e]];
      if (u2 >= 0 && dist[u2] < 0) {
        dist[u2] = dist[u1] + 1;
        Q[sizeQ++] = u2;
      }
    }
  }
}
bool dfs(int u1) {
  vis[u1] = true;
  for (int e = last[u1]; e >= 0; e = Prev[e]) {
    int v = head[e];
    int u2 = matching[v];
    if (u2 < 0 || !vis[u2] && dist[u2] == dist[u1] + 1 && dfs(u2)) {
      matching[v] = u1;
      used[u1] = true;
      return true;
    }
  }
  return false;
}
int maxMatching() {
  fill(used, used + n1, false);
  fill(matching, matching + n2, -1);
  for (int res = 0;;) {
    bfs();
    fill(vis, vis + n1, false);
    int f = 0;
    for (int u = 0; u < n1; ++u)
      if (!used[u] && dfs(u)) ++f;
    if (!f) return res;
    res += f;
  }
}
const int MD = 1e9 + 7;
struct ship {
  int x, a, f;
};
struct base {
  int x, d;
};
vector<vector<int> > adj;
bool Vis[110];
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  adj.assign(n + 2, vector<int>());
  for (int i = 0; i < m; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  int s, b, h, k;
  scanf("%d%d%d%d", &s, &b, &k, &h);
  vector<ship> ss;
  for (int i = 0; i < s; i++) {
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    ss.push_back({a, b, c});
  }
  vector<base> bs;
  vector<vector<int> > baseinpos(n + 2, vector<int>());
  for (int i = 0; i < b; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    baseinpos[a].push_back(i);
    bs.push_back({a, b});
  }
  vector<vector<int> > pos(s + 1, vector<int>());
  int idx = 0;
  for (ship i : ss) {
    queue<pair<int, int> > q;
    q.push(make_pair(0, i.x));
    for (int j = 0; j <= 101; j++) Vis[j] = false;
    Vis[i.x] = true;
    while (!q.empty()) {
      int d = q.front().first, u = q.front().second;
      q.pop();
      for (int j : baseinpos[u]) {
        if (i.a >= bs[j].d) {
          pos[idx].push_back(j);
        }
      }
      if (d == i.f) continue;
      for (int v : adj[u]) {
        if (!Vis[v]) {
          q.push(make_pair(d + 1, v));
          Vis[v] = true;
        }
      }
    }
    idx++;
  }
  init(s, b);
  for (int i = 0; i < s + 1; ++i)
    for (auto child : pos[i]) addEdge(i, child);
  int maxi = maxMatching();
  cout << min((long long)maxi * (long long)k, (long long)h * (long long)s);
  return 0;
}
