#include <bits/stdc++.h>   using namespace std;   struct Tree {     static const int MAXN = 500010;     struct Edge {       int son, dis;       Edge *pre;       void add(int _s, int _d, Edge *_p) { son = _s, dis = _d, pre = _p; }     } edge[MAXN << 1], *pos[MAXN];     int sum;     void clear() {       sum = 0;       memset(pos, 0, sizeof(pos));     }     void add(int a, int b, int c) {       edge[++sum].add(b, c, pos[a]);       pos[a] = edge + sum;     }   } T;   const int MAXN = 500010, MAXK = 500010, MAXM = 500010;   struct Edge {     int from, to, price;   } E[MAXK + MAXM];   int n, m, k;   void init() {     scanf( %d%d%d , &n, &k, &m);     for (int i = 1; i <= k + m; ++i) {       int u, v, w;       scanf( %d%d , &u, &v);       if (i <= k)         w = -1;       else         scanf( %d , &w);       E[i] = (Edge){u, v, w};     }   }   struct DisjointSet {     static const int MAXN = 500010;     int fa[MAXN], n;     void clear(int _n) {       n = _n;       for (int i = 1; i <= n; ++i) fa[i] = i;     }     int find(int x) {       if (fa[x] == x) return x;       return fa[x] = find(fa[x]);     }     bool merge(int u, int v) {       int fx = find(u), fy = find(v);       if (fx == fy) return false;       fa[fx] = fy;       return true;     }   } DS;   void buildTree() {     DS.clear(n);     T.clear();     for (int i = 1; i <= k + m; ++i)       if (DS.merge(E[i].from, E[i].to)) {         T.add(E[i].from, E[i].to, E[i].price);         T.add(E[i].to, E[i].from, E[i].price);       }   }   const int MAXL = 20;   int fa[MAXN][MAXL], l2[MAXN], dep[MAXN];   void dfs(int x, int f) {     for (int l = 1; l <= l2[dep[x]]; ++l) fa[x][l] = fa[fa[x][l - 1]][l - 1];     for (Tree::Edge *i = T.pos[x]; i; i = i->pre)       if (i->son != f) {         fa[i->son][0] = x;         dep[i->son] = dep[x] + 1;         dfs(i->son, x);       }   }   void preset() {     l2[0] = -1, l2[1] = 0;     for (int i = 2; i <= n; ++i) l2[i] = l2[i >> 1] + 1;     memset(fa, 0, sizeof(fa)), dep[1] = 1;     dfs(1, 0);   }   int lca(int u, int v) {     if (dep[u] > dep[v]) swap(u, v);     for (int l = l2[dep[v] - dep[u]]; l >= 0; --l)       if (dep[v] - (1 << l) >= dep[u]) v = fa[v][l];     if (u == v) return u;     for (int l = l2[dep[u]]; l >= 0; --l)       if (fa[u][l] != fa[v][l]) u = fa[u][l], v = fa[v][l];     return fa[u][0];   }   const long long INF = ~0ull >> 3;   multiset<int> F[MAXN];   vector<int> ins[MAXN];   long long solve(int x, int f, bool mask) {     long long ans = 0;     for (Tree::Edge *i = T.pos[x]; i; i = i->pre)       if (i->son != f) {         long long ret = solve(i->son, x, (i->dis == -1));         if (ret == INF) return INF;         ans += ret;         if (F[x].size() < F[i->son].size()) F[x].swap(F[i->son]);         F[x].insert(F[i->son].begin(), F[i->son].end());       }     for (int val : ins[x])       if (val > 0)         F[x].insert(val);       else         F[x].erase(F[x].find(-val));     if (!mask) return ans;     if (x > 1 && F[x].empty()) return INF;     ans += *F[x].begin();     return ans;   }   int main() {     init();     buildTree();     preset();     for (int i = k + 1; i <= k + m; ++i) {       int u = E[i].from, v = E[i].to, w = E[i].price;       int z = lca(u, v);       if (u != z) ins[u].push_back(w), ins[z].push_back(-w);       if (v != z) ins[v].push_back(w), ins[z].push_back(-w);     }     long long ans = solve(1, 0, false);     if (ans == INF)       cout << -1 << endl;     else       cout << ans << endl;     return 0;   }