import java.io.*;
import java.util.*;
import java.math.*;

public class railroads_ab implements Runnable {

	final int MAXN = 100;
	final int MAXM = 5000;
	final int MAXK = 10;
	final int MAXSUM = 50000;
	final int MAXA = (int)1e9;
	
	private void solve() throws IOException {
		int n = in.nextInt();
		assert 1 <= n && n <= MAXN;
		int m = in.nextInt();
		assert 0 <= m && m <= MAXM;
		int k = in.nextInt();
		assert 1 <= k && k <= MAXK;
		DS ds = new DS(n);
		
		for (int i = 0; i < m; ++i) {
			int a = in.nextInt() - 1;
			int b = in.nextInt() - 1;
			assert 0 <= a && a < n;
			assert 0 <= b && b < n;			
			ds.union(a, b);
		}
				
		E = new long[n][2 * k + 2][2 * k + 2];
		
		int sum = 0;
		
		for (int i = 0; i < n; ++i) {
			int j = ds.get(i);
			for (int l = 1; l <= k; ++l) {
				E[j][l][k + l] = INF;
			}
			int r = in.nextInt();
			sum += r;
			for (int l = 0; l < r; ++l) {
				int g1 = in.nextInt();
				assert 1 <= g1 && g1 <= k;
				int a = in.nextInt();
				assert 1 <= a && a <= MAXA;
				E[j][0][g1] += a;
			}
			
			r = in.nextInt();
			sum += r;
			for (int l = 0; l < r; ++l) {
				int g1 = in.nextInt();
				assert 1 <= g1 && g1 <= k;
				int g2 = in.nextInt();
				assert 1 <= g2 && g2 <= k;
				int a = in.nextInt();
				assert 1 <= a && a <= MAXA;
				assert g1 != g2;
				E[j][g1][k + g2] += a;
			}
			
			r = in.nextInt();
			sum += r;
			for (int l = 0; l < r; ++l) {
				int g2 = in.nextInt();
				assert 1 <= g2 && g2 <= k;
				int a = in.nextInt();
				assert 1 <= a && a <= MAXA;
				E[j][k + g2][2 * k + 1] += a;
			}			
			assert sum <= MAXSUM;
		}

		long ans = 0;
		
		for (int i = 0; i < n; ++i) {
			if (ds.p[i] == i) {
				ans += maxFlow(E[i], 0, 2 * k + 1);
			}
		}
		
		out.println(ans);
	}

	
	boolean[] u;
	
	long dfs(long[][] E, int i, int t, long MAX) {
		u[i] = true;
		if (i == t) {
			return MAX;
		}		
		for (int j = 0; j < E[i].length; ++j) {
			if (E[i][j] > 0 && !u[j]) {
				long f = dfs(E, j, t, Math.min(MAX, E[i][j]));
				if (f == 0) continue;
				E[i][j] -= f;
				E[j][i] += f;				
				return f;
			}
		}		
		return 0;
	}
	
	private long maxFlow(long[][] E, int s, int t) {
		long ans = 0;
		u = new boolean[E.length];		
		while (true) {
			Arrays.fill(u, false);
			ans += dfs(E, s, t, INF);
			if (!u[t]) break;
		}
		return ans;
	}

	long INF = (long)(1e18);
		
	long[][][] E;
	
	
	class DS {
		int[] r, p;
		
		public DS(int n) {
			r = new int[n];
			p = new int[n];
			for (int i = 0; i < n; ++i) {
				p[i] = i;
			}
		}
		
		int get(int i) {
			if (i != p[i]) p[i] = get(p[i]);
			return p[i];
		}
		
		void union(int i, int j) {
			i = get(i);
			j = get(j);
			if (r[i] == r[j]) ++r[i];
			if (r[i] > r[j]) {
				p[j] = i;
			} else {
				p[i] = j;
			}
		}
	}
	
	SimpleScanner in;
	PrintWriter out;

	@Override
	public void run() {
		try {
			in = new SimpleScanner(new FileReader("railroads.in"));
			out = new PrintWriter("railroads.out");
			solve();
			out.close();
		} catch (Throwable e) {
			e.printStackTrace();
			System.exit(-1);
		}
	}

	public static void main(String[] args) {
		new Thread(new railroads_ab()).start();
	}

	class SimpleScanner extends BufferedReader {

		private StringTokenizer st;
		private boolean eof;

		public SimpleScanner(Reader a) {
			super(a);
		}

		String next() {
			while (st == null || !st.hasMoreElements()) {
				try {
					st = new StringTokenizer(readLine());
				} catch (Exception e) {
					eof = true;
					return "";
				}
			}
			return st.nextToken();
		}

		boolean seekEof() {
			String s = next();
			if ("".equals(s) && eof)
				return true;
			st = new StringTokenizer(s + " " + st.toString());
			return false;
		}

		private String cnv(String s) {
			if (s.length() == 0)
				return "0";
			return s;
		}

		int nextInt() {
			return Integer.parseInt(cnv(next()));
		}

		double nextDouble() {
			return Double.parseDouble(cnv(next()));
		}

		long nextLong() {
			return Long.parseLong(cnv(next()));
		}
	}
}