#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = double;
using ull = unsigned long long;
void useiostream() {
  ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  cout.setf(ios::fixed), cout.precision(20);
}
void drop(char const *bu) {
  printf("%s", bu);
  exit(0);
}
ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }
ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }
ld const pi = acos(-1.0L);
ld const eps = 0.0001L;
template <typename T, typename TT>
bool mi(T &a, TT b) {
  return a > b ? (a = b, true) : false;
}
template <typename T, typename TT>
bool ma(T &a, TT b) {
  return a < b ? (a = b, true) : false;
}
mt19937 ran(time(0));
int const mod = (int)1e9 + 7;
int bp(int a, int p) {
  int re = 1;
  while (p) {
    if (p & 1) re = (re * 1LL * a) % mod;
    p >>= 1;
    a = (a * 1LL * a) % mod;
  }
  return re;
}
int inv(int a) { return bp(a, mod - 2); }
int n, m;
vector<int> g[105];
int s, b, k, h;
vector<pair<int, int> > bases[105];
int dd[105][105];
int used[1005];
int par[1005];
vector<int> gg[1005];
tuple<int, int, int> keka[1005];
bool push(int v, int t) {
  used[v] = t;
  for (auto &x : gg[v]) {
    if (par[x] == -1) {
      par[x] = v;
      return true;
    }
    if (used[par[x]] < t && push(par[x], t)) {
      par[x] = v;
      return true;
    }
  }
  return false;
}
int main() {
  useiostream();
  for (int j = 0; j < 105; j++) {
    for (int i = 0; i < 105; i++) {
      dd[i][j] = 5000000;
      dd[i][i] = 0;
    }
  }
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    int a, b;
    cin >> a >> b;
    a--, b--;
    g[a].push_back(b);
    g[b].push_back(a);
    mi(dd[a][b], 1);
    mi(dd[b][a], 1);
  }
  cin >> s >> b >> k >> h;
  for (int i = 0; i < s; i++) {
    int x, a, f;
    cin >> x >> a >> f;
    x--;
    keka[i] = {x, a, f};
  }
  for (int i = 0; i < b; i++) {
    int x, d;
    cin >> x >> d;
    x--;
    bases[x].emplace_back(d, i);
  }
  for (int i = 0; i < n; i++) {
    sort(bases[i].begin(), bases[i].end());
  }
  for (int k = 0; k < n; k++) {
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        mi(dd[i][j], dd[i][k] + dd[k][j]);
      }
    }
  }
  int id = 0;
  for (auto &y : keka) {
    int x, a, f;
    tie(x, a, f) = y;
    for (int v = 0; v < n; v++) {
      if (dd[x][v] <= f) {
        for (auto &b : bases[v]) {
          if (b.first <= a) {
            gg[id].push_back(b.second);
          } else {
            break;
          }
        }
      }
    }
    id++;
  }
  for (auto &x : par) x = -1;
  for (int i = 0; i < s; i++) {
    for (auto &x : gg[i]) {
      if (par[x] == -1) {
        par[x] = i;
        break;
      }
    }
  }
  for (int i = 0; i < s; i++) {
    used[i] = i;
  }
  for (int i = 0; i < s; i++) {
    bool good = 0;
    for (auto &x : gg[i]) {
      if (par[x] == i) {
        good = 1;
        break;
      }
    }
    if (good) continue;
    push(i, i + s);
  }
  ll cnt = 0;
  for (int i = 0; i < b; i++) cnt += (par[i] != -1);
  ll res = cnt * k;
  for (ll a = 1; a <= s; a++) {
    ll su = a * h;
    ll last = s - a;
    if (last < cnt) {
      mi(res, su + last * k);
    }
  }
  cout << res;
  return 0;
}
