#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;
}
