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

public class gen_railroads implements Runnable {
	public static void main(String[] args) {
		if (args.length < 1) {
			for (I = 1; (new File(getName(I) + ".t")).exists(); I++)
				;
		} else {
			I = Integer.parseInt(args[0]);
		}
		new Thread(new gen_railroads()).start();
	}

	PrintWriter out;

	Random rand = new Random(6439586L);

	static int I;

	static String getName(int i) {
		return ((i < 10) ? "0" : "") + i;
	}

	void open() {
		try {
			System.out.println("Generating test " + I);
			out = new PrintWriter(getName(I));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			System.exit(-1);
		}
	}

	void close() {
		out.close();
		I++;
	}

	final String ALPHA = "abcdefghijklmnopqrstuvwxyz";

	String randString(int len, String alpha) {
		StringBuilder ans = new StringBuilder();
		int k = alpha.length();
		for (int i = 0; i < len; i++) {
			ans.append(alpha.charAt(rand.nextInt(k)));
		}
		return ans.toString();
	}

	long rand(long l, long r) {
		return l + (rand.nextLong() >>> 1) % (r - l + 1);
	}

	int rand(int l, int r) {
		return l + rand.nextInt(r - l + 1);
	}

	class Edge {
		int a, b;
		
		public Edge(int a, int b) {
			if (rand.nextBoolean()) {
				this.a = a;
				this.b = b;
			} else {
				this.a = b;
				this.b = a;
			}
		}
	}
	
	
	void genTest(int n, int m, int k, int r, int p, int c, int comp, int MAXA) {
		if (k == 1) p = 0;
		if (n == comp) m = 0;
		int[] par = new int[n];
		Arrays.fill(par, -1);
		ArrayList<Integer>[] vl = new ArrayList[comp];		
		for (int i = 0; i < comp; ++i) {
			vl[i] = new ArrayList<Integer>();
			vl[i].add(i);
		}
		for (int j = comp + 1; j < n; ++j) {
			int cl = rand(0, comp - 1);
			par[j] = vl[cl].get(rand(0, vl[cl].size() - 1));
			vl[cl].add(j);
		}
		
		int[] perm = new int[n];
		for (int i = 1; i < n; ++i) {
			int j = rand.nextInt(i);
			perm[i] = perm[j];
			perm[j] = i;
		}
		
		ArrayList<Edge> e = new ArrayList<Edge>();
		for (int i = 0; i < n; ++i) {
			if (par[i] >= 0) {
				e.add(new Edge(perm[par[i]] + 1, perm[i] + 1));			
			}
		}
		
		ArrayList<Integer> gc = new ArrayList<Integer>();
		for (int i = 0; i < comp; ++i){
			if (vl[i].size() > 1) {
				gc.add(i);
			}
		}
		
		while (gc.size() > 0 && e.size() < m) {			
			int cl = gc.get(rand(0, gc.size() - 1));
			int a = 0, b = 0;
			while (a == b) {
				a = perm[vl[cl].get(rand.nextInt(vl[cl].size()))] + 1;
				b = perm[vl[cl].get(rand.nextInt(vl[cl].size()))] + 1;
			}
			e.add(new Edge(a, b));
		}
		
		Collections.shuffle(e);
		
		int[] rC = new int[n];		
		for (int i = 0; i < r; ++i) {
			++rC[rand.nextInt(n)];
		}		
		int[] pC = new int[n];
		for (int i = 0; i < p; ++i) {
			++pC[rand.nextInt(n)];
		}
		int[] cC = new int[n];
		for (int i = 0; i < c; ++i) {
			++cC[rand.nextInt(n)];
		}
		
		open();		
		out.println(n + " " + e.size() + " " + k);
		for (Edge edge : e) {
			out.println(edge.a + " " + edge.b);
		}
		
		for (int i = 0; i < n; ++i) {
			out.println(rC[i]);
			for (int j = 0; j < rC[i]; ++j) {
				out.println(rand(1, k) + " " + rand(1, MAXA));
			}
			out.println(pC[i]);
			for (int j = 0; j < pC[i]; ++j) {
				int g1 = 0, g2 = 0;
				while (g1 == g2) {
					g1 = rand(1, k);
					g2 = rand(1, k);
				}			
				out.println(g1 + " " + g2 + " " + rand(1, MAXA));
			}
			out.println(cC[i]);
			for (int j = 0; j < cC[i]; ++j) {
				out.println(rand(1, k) + " " + rand(1, MAXA));
			}
		}
		
		close();
	}
	
	final int MAXN = 100;
	final int MAXM = 5000;	
	final int MAXK = 10;
	final int MAXSUM = 50000;
	final int MAXA = (int)1e9;
	
	
	
	public void solve() throws IOException {
		for (int i = 0; i < 10; ++i) {
			int n = rand(1, 5);
			int comp = rand(1, n);
			genTest(n, rand(n - comp, 10), rand(1, 3), rand(1, 3), rand(1, 3), rand(1, 3), comp, 5);
		}
		
		for (int i = 0; i < 4; ++i) {
			int n = rand(MAXN / 2, MAXN);
			int comp = rand(1, 10);
			genTest(n, rand(n - comp, MAXM), rand(1, MAXK), rand(MAXSUM / 6, MAXSUM / 3), rand(MAXSUM / 6, MAXSUM / 3), rand(MAXSUM / 6, MAXSUM / 3), comp, MAXA);
		}
		
		for (int i = 0; i < 4; ++i) {
			int n = rand(MAXN / 2, MAXN);
			int comp = rand(n / 10, n);
			genTest(n, rand(n - comp, MAXM), rand(1, MAXK), rand(MAXSUM / 6, MAXSUM / 3), rand(MAXSUM / 6, MAXSUM / 3), rand(MAXSUM / 6, MAXSUM / 3), comp, MAXA);
		}
		
		genTest(MAXN, MAXM, MAXK, 0, 0, MAXSUM, 1, MAXA);
		genTest(MAXN, MAXM, MAXK, 0, MAXSUM, 0, 1, MAXA);
		genTest(MAXN, MAXM, MAXK, MAXSUM, 0, 0, 1, MAXA);		
		genTest(MAXN, MAXM, MAXK, 0, MAXSUM / 2, MAXSUM / 2, 1, MAXA);
		genTest(MAXN, MAXM, MAXK, MAXSUM / 2, 0, MAXSUM / 2, 1, MAXA);
		genTest(MAXN, MAXM, MAXK, MAXSUM / 2, MAXSUM / 2, 0, 1, MAXA);
		genTest(MAXN, MAXM, MAXK, 0, 0, MAXSUM, MAXN / 10, MAXA);
		genTest(MAXN, MAXM, MAXK, 0, MAXSUM, 0, MAXN / 10, MAXA);
		genTest(MAXN, MAXM, MAXK, MAXSUM, 0, 0, MAXN / 10, MAXA);		
		genTest(MAXN, MAXM, MAXK, MAXSUM / 3, MAXSUM / 3, MAXSUM / 3, MAXN / 10, MAXA);
		genTest(MAXN, MAXM, MAXK, MAXSUM / 3, MAXSUM / 3, MAXSUM / 3, MAXN, MAXA);
		genTest(MAXN, MAXM, MAXK, MAXSUM / 3, MAXSUM / 3, MAXSUM / 3, 1, MAXA);		
	}
	
	void myAssert(boolean e) {
		if (!e) {
			throw new Error("Assertion failed");
		}
	}

	public void run() {
		try {
			solve();
		} catch (Throwable e) {
			e.printStackTrace();
			System.exit(-1);
		}
	}
}