#include <cstdio>
#include <cstring>
#include <climits>
#include <queue>
#include <algorithm>
const int MAX_N = 100 + 10;
const int MAX_M = 20 + 10;
const int MAX_E = MAX_M * MAX_M;
const int INF = 2e9;
struct Edge {
int x, y, w;
int ne;
} e[MAX_E + 10];
int v[MAX_M + 1], num;
inline void put(int x, int y, int z) {
num++;
e[num].x = x, e[num].y = y, e[num].w = z;
e[num].ne = v[x], v[x] = num;
}
int n, m, k, tot;
bool del[MAX_M + 1][MAX_N + 1], invalid[MAX_M + 1];
int f[MAX_N + 1], cost[MAX_N + 1][MAX_N + 1];
int dist[MAX_M + 1];
bool inq[MAX_M + 1];
inline int spfa() {
std::queue<int> q;
memset(inq, 0, sizeof(inq));
memset(dist, 0x7f, sizeof(dist));
dist[1] = 0;
inq[1] = true;
while (!q.empty()) q.pop();
q.push(1);
while (!q.empty()) {
int x = q.front();
q.pop();
inq[x] = false;
for (int i = v[x]; i; i = e[i].ne) {
int y = e[i].y;
if (!invalid[y] && dist[y] > dist[x] + e[i].w) {
dist[y] = dist[x] + e[i].w;
if (!inq[y]) {
inq[y] = true;
q.push(y);
}
}
}
}
return dist[m];
}
int main() {
scanf("%d %d %d %d", &n, &m, &k, &tot);
for (int i = 1; i <= tot; i++) {
int x, y, z;
scanf("%d %d %d", &x, &y, &z);
put(x, y, z);
put(y, x, z);
}
int d;
scanf("%d", &d);
for (int i = 1; i <= d; i++) {
int p, a, b;
scanf("%d %d %d", &p, &a, &b);
for (int j = a; j <= b; j++) {
del[p][j] = true;
}
}
for (int i = 1; i <= n; i++) {
for (int j = i; j <= n; j++) {
memset(invalid, 0, sizeof(invalid));
for (int k = 1; k <= m; k++)
for (int a = i; a <= j; a++)
invalid[k] |= del[k][a];
cost[i][j] = spfa();
}
}
for (int i = 1; i <= n; i++) {
for (int j = i; j <= n; j++) {
if (cost[i][j] < INF) cost[i][j] *= (j - i + 1);
}
}
for (int i = 1; i <= n; i++) f[i] = cost[1][i];
for (int i = 2; i <= n; i++) {
for (int j = 1; j < i; j++) {
f[i] = std::min(f[i], f[j] + cost[j + 1][i] + k);
}
}
printf("%d\n", f[n]);
return 0;
}