#include <bits/stdc++.h>
#define rep(i, a, n) for(int i = a; i < n; i++)
#define repb(i, a, b) for(int i = a; i >= b; i--)
#define all(a) a.begin(), a.end()
#define o(a) cout << a << endl
#define fi first
#define se second
#define int long long
using namespace std;
typedef pair<int, int> P;

const int MAX_N = 100010;
const int INF = 1e12;

struct edge{
    int to, cost;
};

int n, m, r, q;
int d[11][100110];
vector<edge> G[100110];

void dijkstra(int s){
    rep(i, 0, n + 100) d[s][i] = INF;
    priority_queue<P, vector<P>, greater<P> > q;
    q.push(P(0, s + MAX_N));
    d[s][s + MAX_N] = 0;
    while(!q.empty()){
        P p = q.top(); q.pop();
        int pos = p.se;
        int cost = p.fi;
        if(cost > d[s][pos]) continue;
        rep(i, 0, G[pos].size()){
            edge e = G[pos][i];
            int next = e.to;
            int newCost = e.cost + cost;
            if(newCost < d[s][next]){
                d[s][next] = newCost;
                q.push(P(newCost, next));
            }
        }
    }
}

signed main(){
    cin >> n >> m >> r >> q;
    rep(i, 0, m){
        int a, b, c;
        cin >> a >> b >> c;
        G[b]. push_back((edge){a, c});
    }
    rep(i, 1, n + 1){
        G[MAX_N + i % r]. push_back((edge){i, 0});
    }
    rep(i, 0, r) dijkstra(i);
    // rep(i, 0, r){
    //     rep(j, 1, n + 1){
    //         cout << d[i][j] << " ";
    //     }
    //     cout << endl;
    //     cout << endl;
    // }
    int ans = 0;
    rep(i, 0, q){
        int x, y, z;
        cin >> x >> y >> z;
        int MIN = 1e12;
        rep(j, 0, r){
            MIN = min(MIN, d[j][x] + d[j][y]);
        }
        // cout << MIN << endl;
        if(MIN < z) ans += z - MIN;
    }
    cout << ans << endl;
}