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

public class TestsGen {
	public static void main(String[] args) {
		new TestsGen().run();
	}

	BufferedReader br;
	StringTokenizer in;
	PrintWriter out;

	public String nextToken() throws IOException {
		while (in == null || !in.hasMoreTokens()) {
			in = new StringTokenizer(br.readLine());
		}
		return in.nextToken();
	}

	public int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}

	public long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}

	public double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}

	int tNumber;
	Random rnd;

	class Test {
		int n, m, k;
		ArrayList<Integer> a, b;

		public void printTest() throws IOException {
			if (tNumber < 10)
				out = new PrintWriter("0" + tNumber);
			else
				out = new PrintWriter("" + tNumber);
			tNumber++;

			out.println(n + " " + m + " " + k);
			int t = rnd.nextInt();
			Random tmp = new Random(t);
			Collections.shuffle(a, tmp);
			tmp = new Random(t);
			Collections.shuffle(b, tmp);
			for (int i = 0; i < m; i++)
				if (rnd.nextBoolean())
					out.println(a.get(i) + " " + b.get(i));
				else
					out.println(b.get(i) + " " + a.get(i));
			out.close();
		}

		public void genTree(int N) throws IOException {
			n = N;
			m = n - 1;
			k = rnd.nextInt((int) 1e9 - n) + n;
			a = new ArrayList<Integer>();
			b = new ArrayList<Integer>();
			for (int i = 1; i < n; i++) {
				a.add(i + 1);
				if (i > 2)
					b.add(rnd.nextInt(i - 1) + 1);
				else
					b.add(1);
			}
			printTest();
		}

		public void genTreeWithKCycles(int N, int K) throws IOException {
			n = N;
			m = n - 1 + K;
			k = rnd.nextInt(n / 5) + 1;
			a = new ArrayList<Integer>();
			b = new ArrayList<Integer>();
			boolean[][] was = new boolean[n][n];
			for (int i = 1; i < n; i++) {
				a.add(i + 1);
				if (i > 2) {
					int z = rnd.nextInt(i - 1);
					b.add(z + 1);
					was[i][z] = true;
					was[z][i] = true;
				} else {
					b.add(1);
					was[i][0] = true;
					was[0][i] = true;
				}
			}
			for (int i = 0; i < K; i++) {
				int x = rnd.nextInt(n);
				int y = rnd.nextInt(n);
				while ((was[x][y])) {
					x = rnd.nextInt(n);
					y = rnd.nextInt(n);
				}
				a.add(x);
				b.add(y);
				was[x][y] = true;
				was[y][x] = true;

			}
			printTest();
		}

		public void genRandomGraph(int N, int K) throws IOException {
			n = N;
			m = K;
			k = rnd.nextInt((int) 1e9) + 1;
			if (rnd.nextInt(8) == 0)
				k = (int) 1e9;
			a = new ArrayList<Integer>();
			b = new ArrayList<Integer>();
			boolean[][] was = new boolean[n][n];
			for (int i = 0; i < K; i++) {
				int x = rnd.nextInt(n);
				int y = rnd.nextInt(n);
				while ((was[x][y])) {
					x = rnd.nextInt(n);
					y = rnd.nextInt(n);
				}
				a.add(x + 1);
				b.add(y + 1);
				was[x][y] = true;
				was[y][x] = true;

			}
			if (!was[0][1]) {
				m++;
				a.add(1);
				b.add(2);
			}
			printTest();
		}

	}

	public void solve() throws IOException {
		tNumber = 2;
		rnd = new Random(1543);

		Test t = new Test();
		for (int i = 2; i <= 10; i++)
			t.genTree(i * 100);

		for (int j = 1; j < 11; j++)
			t.genTreeWithKCycles(j * 100, 1);

		for (int j = 1; j < 11; j++)
			t.genRandomGraph(j * 100,
					rnd.nextInt(rnd.nextInt(3) * j * 100 + 1) + 300);

	}

	public void run() {
		try {

			solve();

			out.close();
		} catch (IOException e) {
			e.printStackTrace();
			System.exit(1);
		}
	}
}