#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
long long ans;
int n, m, k, sum, cnt, fat[N], head[N];
int fa[N], deep[N], siz[N], son[N], pos[N], top[N];
inline int read() {
  int x = 0, p = 1;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-') p = -1;
    c = getchar();
  }
  while (c <= '9' && c >= '0') {
    x = x * 10 + c - '0';
    c = getchar();
  }
  return x * p;
}
int find(int u) {
  int t1 = u, t2;
  while (fat[u] != u) u = fat[u];
  while (t1 != fat[t1]) {
    t2 = fat[t1];
    fat[t1] = u;
    t1 = t2;
  }
  return u;
}
struct ROAD {
  int des, last;
} road[N << 1];
void add(int u, int v) {
  road[++sum].des = v;
  road[sum].last = head[u];
  head[u] = sum;
}
struct NEED {
  int u, v;
  void add() {
    u = read();
    v = read();
    fat[(find(u))] = find(v);
  }
} d[N];
struct HEVEN {
  int u, v, c;
  void add() {
    u = read();
    v = read();
    c = read();
  }
  bool operator<(const HEVEN& p) const { return c < p.c; }
} line[N];
void dfs1(int u, int fath, int dep) {
  deep[u] = dep;
  siz[u] = 1;
  fa[u] = fath;
  for (int i = head[u]; i; i = road[i].last)
    if (road[i].des != fath) {
      int v = road[i].des;
      dfs1(v, u, dep + 1);
      siz[u] += siz[v];
      if (!son[u] || siz[v] > siz[son[u]]) son[u] = v;
    }
}
void dfs2(int u, int ance) {
  pos[u] = ++sum;
  top[u] = ance;
  if (!son[u]) return;
  dfs2(son[u], ance);
  for (int i = head[u]; i; i = road[i].last)
    if (road[i].des != fa[u] && road[i].des != son[u])
      dfs2(road[i].des, road[i].des);
}
void Kru() {
  if (k == n - 1) return;
  for (int i = 1; i <= m; ++i) {
    int u = line[i].u, v = line[i].v;
    int fu = find(u), fv = find(v);
    if (fu == fv) continue;
    ans -= line[i].c;
    fat[fu] = fv;
    ++cnt;
    d[cnt].u = u;
    d[cnt].v = v;
  }
}
struct TREE {
  int tree[N << 2];
  void pushdown(int root, int l, int r) {
    if (l == r || !tree[root]) return;
    if (!tree[root << 1]) tree[root << 1] = tree[root];
    if (!tree[root << 1 | 1]) tree[root << 1 | 1] = tree[root];
  }
  void update(int root, int l, int r, int a, int b, int c) {
    if (tree[root]) return;
    if (a <= l && b >= r) {
      tree[root] = c;
      return;
    }
    int mid = l + r >> 1;
    if (a <= mid) update(root << 1, l, mid, a, b, c);
    if (b > mid) update(root << 1 | 1, mid + 1, r, a, b, c);
  }
  int query(int root, int l, int r, int x) {
    if (l == r) return tree[root];
    pushdown(root, l, r);
    int mid = l + r >> 1;
    if (x <= mid) return query(root << 1, l, mid, x);
    if (x > mid) return query(root << 1 | 1, mid + 1, r, x);
  }
} zy;
void update(int u, int v, int c) {
  while (top[u] != top[v]) {
    if (deep[top[u]] < deep[top[v]]) swap(u, v);
    zy.update(1, 1, n, pos[top[u]], pos[u], c);
    u = fa[top[u]];
  }
  if (deep[u] > deep[v]) swap(u, v);
  if (u != v) zy.update(1, 1, n, pos[u] + 1, pos[v], c);
}
void deal() {
  for (int i = 1; i <= m; ++i) {
    int u = line[i].u, v = line[i].v, c = line[i].c;
    update(u, v, c);
  }
  for (int i = 2; i <= n; ++i) {
    int ret = zy.query(1, 1, n, i);
    if (!ret) {
      ans = -1;
      return;
    }
    ans += 1ll * ret;
  }
}
int main() {
  n = read();
  k = cnt = read();
  m = read();
  for (int i = 1; i <= n; ++i) fat[i] = i;
  for (int i = 1; i <= k; ++i) d[i].add();
  for (int i = 1; i <= m; ++i) line[i].add();
  sort(line + 1, line + m + 1);
  Kru();
  for (int i = 1; i <= cnt; ++i) {
    int u = d[i].u, v = d[i].v;
    add(u, v);
    add(v, u);
  }
  sum = 0;
  dfs1(1, 0, 1);
  dfs2(1, 1);
  deal();
  cout << ans << '\n';
  return 0;
}
