import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;

public class TestsGen {
	static final Random rand = new Random(32476353L);

	static class Place {
		int a;
		int b;

		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + a;
			result = prime * result + b;
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			Place other = (Place) obj;
			if (a != other.a)
				return false;
			if (b != other.b)
				return false;
			return true;
		}

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

	}

	static class Test {
		int n;
		Place[] p;

		public Test(int n, Place[] p) {
			this.n = n;
			this.p = p;
			for (int i = 0; i < p.length; i++) {
				int j = rand.nextInt(i + 1);
				Place t = p[i];
				p[i] = p[j];
				p[j] = t;
			}
		}

		void printMe(PrintWriter out) {
			out.println(n + " " + p.length);
			for (Place e : p) {
				out.println((n - e.a) + " " + (e.b + 1));
			}
		}
	}

	static int testNumber = 0;

	static void printTest(Test test) {
		System.err.printf("[%02d]\n", ++testNumber);
		try {
			PrintWriter out = new PrintWriter("../tests/" + testNumber / 10
					+ "" + testNumber % 10);
			test.printMe(out);
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	static Test genAllFreeTest(int n) {
		return new Test(n, new Place[0]);
	}

	public static void main(String[] args) {
		printTest(new Test(2, new Place[] { new Place(1, 1) }));
		printTest(new Test(1, new Place[] { new Place(0, 0) }));
		for (int i : new int[] { 1, 2, 3, 4, 5, 1999, 2000, 6, 7, 8, 9, 10, 37,
				239, 566, 1024, 1007 }) {
			printTest(genAllFreeTest(i));
		}

		for (int mask = 1; mask < 1 << 4; mask++) {
			List<Place> e = new ArrayList<Place>();
			for (int i = 0; i < 4; i++) {
				if (((mask >> i) & 1) == 1) {
					e.add(i == 0 ? new Place(0, 0) : new Place(1, i - 1));
				}
			}
			printTest(new Test(2, (Place[]) e.toArray(new Place[e.size()])));
		}
		for (int i = 1; i <= 30; i++) {
			printTest(genAllNonFreeTest(i));
		}
		for (int i = 0; i < 15; i++) {
			printTest(genRandomTest(rand.nextInt(20) + 4));
		}
		for (int i = 0; i < 5; i++) {
			printTest(genRandomTest(2000));
		}
		while (testNumber < 99) {
			printTest(genRandomTest(rand.nextInt(1900) + 100));
		}
	}

	static Test genRandomTest(int n) {
		int m = rand.nextInt(Math.min(1000, n * n)) + 1;
		Place[] p = new Place[m];
		Set<Place> set = new HashSet<Place>();
		for (int i = 0; i < m; i++) {
			Place e;
			do {
				int a = rand.nextInt(n);
				int b = rand.nextInt(2 * a + 1);
				e = new Place(a, b);
			} while (set.contains(e));
			p[i] = e;
		}
		return new Test(n, p);
	}

	static Test genAllNonFreeTest(int n) {
		Place[] p = new Place[n * n];
		for (int i = 0, k = 0; i < n; i++) {
			for (int j = 0; j < 2 * i + 1; j++) {
				p[k++] = new Place(i, j);
			}
		}
		return new Test(n, p);
	}
}
