#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-9;
const int oo = 0x3f3f3f3f;
const int mod = 1000000007;
struct ss {
  int x, a, f;
};
struct bs {
  int x, d;
};
template <typename flow_type>
struct dinic {
  struct edge {
    size_t src, dst, rev;
    flow_type flow, cap;
  };
  int n;
  vector<vector<edge>> adj;
  dinic(int n) : n(n), adj(n), level(n), q(n), it(n) {}
  void add_edge(size_t src, size_t dst, flow_type cap, flow_type rcap = 0) {
    adj[src].push_back({src, dst, adj[dst].size(), 0, cap});
    if (src == dst) adj[src].back().rev++;
    adj[dst].push_back({dst, src, adj[src].size() - 1, 0, rcap});
  }
  vector<int> level, q, it;
  bool bfs(int source, int sink) {
    fill(level.begin(), level.end(), -1);
    for (int qf = level[q[0] = sink] = 0, qb = 1; qf < qb; ++qf) {
      sink = q[qf];
      for (edge &e : adj[sink]) {
        edge &r = adj[e.dst][e.rev];
        if (r.flow < r.cap && level[e.dst] == -1)
          level[q[qb++] = e.dst] = 1 + level[sink];
      }
    }
    return level[source] != -1;
  }
  flow_type augment(int source, int sink, flow_type flow) {
    if (source == sink) return flow;
    for (; it[source] != adj[source].size(); ++it[source]) {
      edge &e = adj[source][it[source]];
      if (e.flow < e.cap && level[e.dst] + 1 == level[source]) {
        flow_type delta = augment(e.dst, sink, min(flow, e.cap - e.flow));
        if (delta > 0) {
          e.flow += delta;
          adj[e.dst][e.rev].flow -= delta;
          return delta;
        }
      }
    }
    return 0;
  }
  flow_type max_flow(int source, int sink) {
    for (int u = 0; u < n; ++u)
      for (edge &e : adj[u]) e.flow = 0;
    flow_type flow = 0;
    flow_type oo = numeric_limits<flow_type>::max();
    while (bfs(source, sink)) {
      fill(it.begin(), it.end(), 0);
      for (flow_type f; (f = augment(source, sink, oo)) > 0;) flow += f;
    }
    return flow;
  }
};
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  vector<vector<int>> dist(n, vector<int>(n, oo));
  for (int i = 0; i < m; ++i) {
    int u, v;
    cin >> u >> v;
    u--;
    v--;
    dist[u][v] = dist[v][u] = 1;
  }
  for (int i = 0; i < n; ++i) dist[i][i] = 0;
  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]);
  int s, b, k, h;
  cin >> s >> b >> k >> h;
  dinic<int> bip(b + s + 2);
  vector<ss> SS(s);
  for (int i = 0; i < s; ++i) {
    int x, a, f;
    cin >> x >> a >> f;
    SS[i] = {x - 1, a, f};
    bip.add_edge(0, i + 2, 1);
  }
  vector<bs> BS(b);
  for (int i = 0; i < b; ++i) {
    int x, d;
    cin >> x >> d;
    BS[i] = {x - 1, d};
    bip.add_edge(i + s + 2, 1, 1);
  }
  for (int i = 0; i < s; ++i) {
    int xi = SS[i].x, ai = SS[i].a, fi = SS[i].f;
    for (int j = 0; j < b; ++j) {
      int xj = BS[j].x, dj = BS[j].d;
      if (dist[xi][xj] <= fi && dj <= ai) {
        bip.add_edge(i + 2, j + s + 2, 1);
      }
    }
  }
  int ans = bip.max_flow(0, 1);
  cout << min(1LL * ans * k, 1LL * s * h) << '\n';
  return 0;
}
