import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;

public class TestsGen {

	final static int MAXN = 100000;

	static class Pair {
		int a, b;

		public Pair(int a, int b) {
			this.a = a;
			this.b = b;
		}
	}

	static Random rnd = new Random(3);

	static class Test {
		int n;
		Pair[] edges;

		Test(Pair[] p) {
			edges = p;
			n = p.length + 1;
		}

		Test(int[] p) {
			n = p.length;
			edges = new Pair[n - 1];
			for (int i = 1; i < n; i++) {
				edges[i - 1] = new Pair(p[i], i);
			}
		}

		Test shuffle() {
			for (int i = 0; i < edges.length; i++) {
				int pos = rnd.nextInt(i + 1);
				Pair tmp = edges[i];
				edges[i] = edges[pos];
				edges[pos] = tmp;
			}
			return this;
		}

		Test shuffleVertices() {
			ArrayList<Integer> perm = new ArrayList<Integer>();
			for (int i = 0; i < n; i++) {
				perm.add(i);
			}
			Collections.shuffle(perm, rnd);
			for (Pair p : edges) {
				p.a = perm.get(p.a);
				p.b = perm.get(p.b);
			}
			return this;
		}

		Test shufflePairs() {
			for (Pair p : edges) {
				if (rnd.nextBoolean()) {
					int tmp = p.a;
					p.a = p.b;
					p.b = tmp;
				}
			}
			return this;
		}

		Test fullShuffle() {
			shuffle();
			shufflePairs();
			shuffleVertices();
			return this;
		}

		Test(int n) {
			this.n = n;
			int[] p = new int[n];
			for (int i = 1; i < n; i++) {
				p[i] = rnd.nextInt(i);
			}
			edges = new Pair[n - 1];
			for (int i = 1; i < n; i++) {
				edges[i - 1] = new Pair(p[i], i);
			}
		}
	}

	static Test YES(Test t) {
		int n = t.edges.length;
		Pair[] p2 = new Pair[n * 2 + 2];
		for (int i = 0; i < n; i++) {
			Pair now = t.edges[i];
			p2[i] = now;
			p2[i + n] = new Pair(now.a + n + 1, now.b + n + 1);
		}
		// [0..2*n+2)
		p2[2 * n] = new Pair(2 * n + 2, 0);
		p2[2 * n + 1] = new Pair(2 * n + 2, n + 1);
		return new Test(p2);
	}

	static int cnt = 0;

	static void out(Test t) throws FileNotFoundException {
		cnt++;
		PrintWriter out = new PrintWriter(String.format("%02d", cnt));
		out.println(t.n);
		for (Pair p : t.edges) {
			out.println((p.a + 1) + " " + (p.b + 1));
		}
		out.close();
	}

	public static void main(String[] args) throws FileNotFoundException {
		out(new Test(new int[] { 0, 0 }));
		out(new Test(new int[] { 0, 0, 1 }));
		for (int i = 0; i < 31; i++) {
			int n = 1 << i;
			if (n > MAXN) {
				continue;
			}
			out(new Test(n).fullShuffle());
			out(YES(new Test(n / 2 + 1)));// .fullShuffle());
			if (n > 2) {
				Pair[] p = new Pair[n - 2];
				for (int j = 1; j < n - 1; j++)
					p[j - 1] = new Pair(j, (j - 1) / 2);
				out(new Test(p));
			}
		}
		{
		int[] p = new int[MAXN];
		out(new Test(p));
		
		for (int i = 0; i < 5; i++) {
			out(new Test(MAXN));
			out(YES(new Test(MAXN / 2 - 1)));
		}

		p = new int[MAXN / 2 - 1];
		for (int i = 0; i < MAXN / 4 + 1; i++)
			p[i] = i - 1;
		for (int i = MAXN / 4 + 1; i < MAXN / 2 - 1; i++)
			p[i] = MAXN / 4;
		out(YES(new Test(p)).fullShuffle());
		}
		cnt++;
		
		for (int i = 0; i < 31; i++) {
			int n = 1 << i;
			if (n > MAXN) {
				continue;
			}
			out((new Test(n / 2 + 1)));// .fullShuffle());
			if (n > 2) {
				Pair[] p = new Pair[n - 2];
				for (int j = 1; j < n - 1; j++)
					p[j - 1] = new Pair(j, (j - 1) / 2);
//				out(new Test(p));
			}
		}
		for (int i = 0; i < 5; i++) {
			out((new Test(MAXN / 2 - 1)));
		}

		int[] p = new int[MAXN];
		out(new Test(p));
		
		for (int i = 0; i < 5; i++) {
			out(new Test(MAXN));
			out(YES(new Test(MAXN / 2 - 1)));
		}

		p = new int[MAXN / 2 - 1];
		for (int i = 0; i < MAXN / 4 + 1; i++)
			p[i] = i - 1;
		for (int i = MAXN / 4 + 1; i < MAXN / 2 - 1; i++)
			p[i] = MAXN / 4;
		out((new Test(p)).fullShuffle());
	}
}
