#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll LINF = (ll)9e18;
 
struct Edge {
    int to;
    int w;
};
 
struct DEdge {
    int from, to;
    ll w;
    bool covered;
    DEdge(int _f=0,int _t=0,ll _w=0):from(_f),to(_t),w(_w),covered(false){}
};
 
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
 
    int N, M, K;
    if(!(cin >> N >> M >> K)) return 0;
    vector<int> U(M), V(M);
    vector<int> W(M);
    vector<vector<Edge>> g(N+1);
    for(int i=0;i<M;i++){
        int u,v; int w;
        cin >> u >> v >> w;
        U[i]=u; V[i]=v; W[i]=w;
        g[u].push_back({v,w});
        g[v].push_back({u,w});
    }
    // data for K people: index 1 is Nam
    vector<int> a(K+1), b(K+1), p(K+1, 1); // p unused for Nam
    cin >> a[1] >> b[1];
    for(int i=2;i<=K;i++){
        int pi, ai, bi;
        cin >> pi >> ai >> bi;
        p[i] = pi; a[i] = ai; b[i] = bi;
    }
 
    auto dijkstra = [&](int src)->vector<ll>{
        vector<ll> dist(N+1, LINF);
        priority_queue<pair<ll,int>, vector<pair<ll,int>>, greater<pair<ll,int>>> pq;
        dist[src]=0;
        pq.push({0, src});
        while(!pq.empty()){
            auto cur = pq.top(); pq.pop();
            ll d = cur.first;
            int u = cur.second;
            if(d != dist[u]) continue;
            for(const Edge &e : g[u]){
                int v = e.to; ll nd = d + e.w;
                if(nd < dist[v]){
                    dist[v] = nd;
                    pq.push({nd, v});
                }
            }
        }
        return dist;
    };
 
    // Dijkstra cho Nam: từ a1 và từ b1
    vector<ll> distA1 = dijkstra(a[1]);
    vector<ll> distB1 = dijkstra(b[1]);
    ll D = distA1[b[1]];
    if(D>=LINF){
        // không có đường từ a1 tới b1 (không hợp lý theo đề nhưng phòng hờ)
        cout << 0 << "\n";
        return 0;
    }
 
    // Xây DAG gồm các cạnh (u->v) nằm trên một đường ngắn nhất từ a1 đến b1
    vector<DEdge> dedges;
    dedges.reserve(2*M);
    vector<vector<int>> dagAdj(N+1); // lưu indices của dedges
    for(int i=0;i<M;i++){
        int u = U[i], v = V[i]; ll w = W[i];
        // hướng u -> v
        if(distA1[u] < LINF && distA1[v] < LINF && distA1[u] + w == distA1[v]){
            if(distA1[v] + distB1[v] == D){
                dedges.emplace_back(u, v, w);
                dagAdj[u].push_back((int)dedges.size()-1);
            }
        }
        // hướng v -> u
        if(distA1[v] < LINF && distA1[u] < LINF && distA1[v] + w == distA1[u]){
            if(distA1[u] + distB1[u] == D){
                dedges.emplace_back(v, u, w);
                dagAdj[v].push_back((int)dedges.size()-1);
            }
        }
    }
 
    // Với mỗi bạn (ngoại trừ Nam), chạy Dijkstra từ a_i và b_i, đánh dấu các directed-edge nào
    // nằm trên một đường ngắn nhất của bạn đó; nếu bạn dễ tính p=1 -> luôn có thể thay đổi thời gian;
    // nếu khó tính p=0 -> cần distAi[u] == distA1[u] để gặp tại bắt đầu cạnh.
    for(int i=2;i<=K;i++){
        vector<ll> distAi = dijkstra(a[i]);
        vector<ll> distBi = dijkstra(b[i]);
        ll Di = distAi[b[i]];
        if(Di >= LINF) continue; // bạn này không có đường hợp lệ
 
        // duyệt các directed edges
        for(size_t idx=0; idx<dedges.size(); ++idx){
            if(dedges[idx].covered) continue; // đã có ai cover thì khỏi kiểm tra
            int u = dedges[idx].from, v = dedges[idx].to;
            ll w = dedges[idx].w;
            // cần kiểm tra cạnh có thuộc đường ngắn nhất của bạn i
            if(distAi[u] < LINF && distAi[v] < LINF && distAi[u] + w == distAi[v] && distAi[v] + distBi[v] == Di){
                if(p[i] == 1){
                    dedges[idx].covered = true;
                }else{
                    // khó tính: bắt đầu điểm u phải đến đúng lúc như Nam
                    if(distAi[u] == distA1[u]){
                        dedges[idx].covered = true;
                    }
                }
            }
        }
    }
 
    // DP tìm đường (a1 -> b1) trên DAG maximize tổng w của các cạnh được covered
    // Sắp xếp các đỉnh theo distA1 tăng dần (đây là topological order trên DAG)
    vector<int> order(N);
    for(int i=0;i<N;i++) order[i] = i+1;
    sort(order.begin(), order.end(), [&](int x, int y){
        if(distA1[x] != distA1[y]) return distA1[x] < distA1[y];
        return x < y;
    });
 
    vector<ll> dp(N+1, -LINF);
    dp[a[1]] = 0;
    for(int u : order){
        if(dp[u] == -LINF) continue;
        // duyệt các cạnh u -> v
        for(int idx : dagAdj[u]){
            int v = dedges[idx].to;
            ll add = dedges[idx].covered ? dedges[idx].w : 0LL;
            if(dp[u] + add > dp[v]){
                dp[v] = dp[u] + add;
            }
        }
    }
 
    ll ans = dp[b[1]];
    if(ans < 0) ans = 0; // phòng hờ
    cout << ans << "\n";
    return 0;
}