import java.io.OutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.util.Arrays; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; import java.util.StringTokenizer; import java.io.Writer; import java.io.OutputStreamWriter; import java.io.BufferedReader; import java.util.Comparator; import java.io.InputStream; /** * Built using CHelper plug-in * Actual solution is at the top * * @author lewin */ public class kings_guards_lewin { public static void main(String[] args) { InputStream inputStream = System.in; OutputStream outputStream = System.out; InputReader2 in = new InputReader2(inputStream); OutputWriter out = new OutputWriter(outputStream); kingguard solver = new kingguard(); solver.solve(1, in, out); out.close(); } static class kingguard { List[] graph; List[] ngraph; int[] par; int[] guard; int[] node; int[] prev; int n; int m; int g; boolean findPath(int g, boolean[] vis) { vis[g] = true; for (int v : graph[g]) { int g2 = guard[v]; if (g2 == -1 || !vis[g2] && findPath(g2, vis)) { guard[v] = g; node[g] = v; return true; } } return false; } boolean make_empty(int x) { if (guard[x] == -1) return true; if (prev[x] == -1) return false; int g = guard[x]; node[g] = prev[x]; guard[x] = -1; while (prev[x] != -1) { int tg = guard[prev[x]]; guard[prev[x]] = g; node[g] = prev[x]; g = tg; x = prev[x]; } return true; } void fill_prev() { int[] q = new int[n]; Arrays.fill(prev, -1); int f = 0, b = 0; boolean[] v = new boolean[n]; for (int i = 0; i < n; i++) { int ni = DisjointSets.root(par, i); if (guard[ni] == -1) { q[b++] = ni; v[ni] = true; } } while (f < b) { int cur_node = q[f++]; for (int g : ngraph[cur_node]) { if (node[g] == cur_node || node[g] == -1) continue; if (!v[node[g]]) { q[b++] = node[g]; prev[node[g]] = cur_node; v[node[g]] = true; } } } } public void solve(int testNumber, InputReader2 in, OutputWriter out) { n = in.nextInt(); m = in.nextInt(); g = in.nextInt(); kingguard.Edge[] es = new kingguard.Edge[m]; for (int i = 0; i < m; i++) { int a = in.nextInt() - 1, b = in.nextInt() - 1, c = in.nextInt(); es[i] = new kingguard.Edge(a, b, c); } Arrays.sort(es, Comparator.comparingInt(x -> x.c)); graph = LUtils.genArrayList(g); ngraph = LUtils.genArrayList(n); for (int i = 0; i < g; i++) { int t = in.nextInt(); while (t-- > 0) { int a = in.nextInt() - 1; graph[i].add(a); ngraph[a].add(i); } } guard = new int[n]; node = new int[g]; Arrays.fill(node, -1); Arrays.fill(guard, -1); int matches = 0; for (int guard = 0; guard < g; guard++) { if (findPath(guard, new boolean[g])) { ++matches; } } if (matches < g) { out.println(-1); return; } prev = new int[n]; par = DisjointSets.createSets(n); fill_prev(); long ans = 0; int ecount = 0; for (kingguard.Edge e : es) { int a = e.a, b = e.b; a = DisjointSets.root(par, a); b = DisjointSets.root(par, b); if (a != b && (make_empty(a) || make_empty(b))) { DisjointSets.unite(par, a, b); int na = DisjointSets.root(par, a); ngraph[na].addAll(ngraph[na ^ a ^ b]); if (guard[a] != -1) { guard[na] = guard[a]; node[guard[a]] = na; } if (guard[b] != -1) { guard[na] = guard[b]; node[guard[b]] = na; } fill_prev(); ans += e.c; ecount++; } } out.println(ecount + g == n ? ans : -1); } static class Edge { public int a; public int b; public int c; public Edge(int a, int b, int c) { this.a = a; this.b = b; this.c = c; } } } static class DisjointSets { public static int[] createSets(int size) { int[] p = new int[size]; for (int i = 0; i < size; i++) p[i] = i; return p; } public static int root(int[] p, int x) { return x == p[x] ? x : (p[x] = root(p, p[x])); } public static boolean unite(int[] p, int a, int b) { a = root(p, a); b = root(p, b); if (a != b) { if (Math.random() < 0.5) p[a] = b; else p[b] = a; return true; } return false; } } static class OutputWriter { private final PrintWriter writer; public OutputWriter(OutputStream outputStream) { writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream))); } public OutputWriter(Writer writer) { this.writer = new PrintWriter(writer); } public void close() { writer.close(); } public void println(long i) { writer.println(i); } public void println(int i) { writer.println(i); } } static class InputReader2 { private BufferedReader in; private StringTokenizer st; public InputReader2(InputStream stream) { in = new BufferedReader(new InputStreamReader(stream)); st = null; } public int nextInt() { return Integer.parseInt(next()); } public String next() { if (st == null || !st.hasMoreTokens()) { try { st = new StringTokenizer(in.readLine()); } catch (IOException e) { e.printStackTrace(); } } return st.nextToken(); } } static class LUtils { public static List[] genArrayList(int size) { return Stream.generate(ArrayList::new).limit(size).toArray(List[]::new); } } }