#include <bits/stdc++.h>
using namespace std;
struct Sp {
  long long x, a, f;
};
struct Ba {
  long long x, d;
};
const long long N = 111, S = 1111;
long long mat[N][N], match[S << 1];
bool vis[S << 1];
vector<long long> graph[S << 1];
Sp sp[S];
Ba ba[S];
long long n, m, s, b, k, h;
bool canAttack(Sp& sp, Ba& ba) {
  return mat[sp.x][ba.x] <= sp.f && sp.a >= ba.d;
}
bool augment(long long u) {
  for (auto v : graph[u]) {
    if (!vis[v]) {
      vis[v] = true;
      if (!match[v] || augment(match[v])) {
        match[v] = u;
        return true;
      }
    }
  }
  return false;
}
void bipartiteMatching(long long n) {
  fill(match + 1, match + n + 1, 0);
  for (long long u = (1); u <= (n); u++) {
    fill(vis + 1, vis + n + 1, false);
    augment(u);
  }
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> m;
  for (long long i = (1); i <= (n); i++) {
    for (long long j = (1); j <= (n); j++) {
      mat[i][j] = i == j ? 0 : 1e9;
    }
  }
  for (long long i = (1); i <= (m); i++) {
    long long u, v;
    cin >> u >> v;
    mat[u][v] = 1;
    mat[v][u] = 1;
  }
  cin >> s >> b >> k >> h;
  for (long long i = (1); i <= (s); i++) {
    cin >> sp[i].x >> sp[i].a >> sp[i].f;
  }
  for (long long i = (1); i <= (b); i++) {
    cin >> ba[i].x >> ba[i].d;
  }
  for (long long k = (1); k <= (n); k++) {
    for (long long i = (1); i <= (n); i++) {
      for (long long j = (1); j <= (n); j++) {
        mat[i][j] = min(mat[i][j], mat[i][k] + mat[k][j]);
      }
    }
  }
  for (long long i = (1); i <= (s); i++) {
    for (long long j = (1); j <= (b); j++) {
      if (canAttack(sp[i], ba[j])) {
        graph[i].push_back(S + j);
        graph[S + j].push_back(i);
      }
    }
  }
  bipartiteMatching(S + b);
  long long ma = 0;
  for (long long u = (1); u <= (s); u++) {
    ma += match[u] != 0;
  }
  long long ans = min(ma * k, s * h);
  cout << ans << "\n";
  return 0;
}
