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

public class TestGen {

	PrintWriter out;
	Random rnd;
	int tNumber;

	class Test {
		int[][] a;

		void printTest() throws IOException {
			if (tNumber < 10)
				out = new PrintWriter("../tests/0" + tNumber);
			else
				out = new PrintWriter("../tests/" + tNumber);
			tNumber++;
			if (rnd.nextBoolean()) {
				int t = rnd.nextInt(20);
				for (int i = 0; i < t; i++) {
					a[rnd.nextInt(a.length)][rnd.nextInt(a[0].length)] = 1 + rnd
							.nextInt(100);
				}
			}
			out.println(a.length + " " + a[0].length);
			for (int i = 0; i < a.length; i++) {
				for (int j = 0; j < a[0].length; j++) {
					out.print(a[i][j]);
					if (j < a[0].length - 1)
						out.print(' ');
				}
				out.println();
			}
			out.close();
		}

		public void generateEqual(int n, int m) throws IOException {
			a = new int[n][m];
			int t = rnd.nextInt(100) + 1;
			for (int[] x : a) {
				Arrays.fill(x, t);
			}
			printTest();
		}

		public void generateChess(int n, int m) throws IOException {
			a = new int[n][m];
			int[] c = new int[2];
			c[0] = rnd.nextInt(100) + 1;
			c[1] = rnd.nextInt(100) + 1;
			for (int x = 0; x < n; x++) {
				for (int y = 0; y < m; y++) {
					a[x][y] = c[(x + y) % 2];
				}
			}
			printTest();
		}

		public void generateOne(int n, int m) throws IOException {
			a = new int[n][m];
			int t = rnd.nextInt(100) + 1;
			for (int[] x : a) {
				Arrays.fill(x, t);
			}
			a[rnd.nextInt(n)][rnd.nextInt(m)] = t + 1;
			printTest();
		}

		public void generateLadder(int n, int m, boolean b) throws IOException {
			a = new int[n][m];
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < m; j++) {
					a[i][j] = 1 + (b ? (i + j) : (n + m - i - j - 2));
				}
			}
			printTest();
		}

		public void generateHereThere(int n) throws IOException {
			a = new int[1][n];
			for (int i = 0; i < n / 2; i++) {
				a[0][i] = i * 2 + 1;
			}
			for (int i = n - 1; i >= n / 2; i--) {
				a[0][i] = (n - i) * 2;
			}
			printTest();
		}

		public void genLeftRight(int n, int m) throws IOException {
			a = new int[n][m];
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < m; j++) {
					a[i][j] = j + 1;
				}
			}
			printTest();
		}

		public void genRightLeft(int n, int m) throws IOException {
			a = new int[n][m];
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < m; j++) {
					a[i][j] = m - j;
				}
			}
			printTest();
		}

		public void genTopBottom(int n, int m) throws IOException {
			a = new int[n][m];
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < m; j++) {
					a[i][j] = i + 1;
				}
			}
			printTest();
		}

		public void genBottomTop(int n, int m) throws IOException {
			a = new int[n][m];
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < m; j++) {
					a[i][j] = n - i;
				}
			}
			printTest();
		}

		public void generateRandom(int n, int m) throws IOException {
			a = new int[n][m];
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < m; j++) {
					a[i][j] = rnd.nextInt(100) + 1;
				}
			}
			printTest();
		}
	}

	public void solve() throws IOException {
		out = new PrintWriter("../preliminary/01");
		out.println("4 4");
		out.println("1 2 1 2");
		out.println("2 1 2 1");
		out.println("1 2 1 2");
		out.println("2 1 2 1");
		out.close();
		tNumber = 1;
		rnd = new Random(31);
		Test t = new Test();

		t.generateEqual(1, 1);
		t.generateChess(1, 3);
		t.generateEqual(1, 100);
		t.generateChess(1, 100);
		t.generateOne(1, 100);

		t.generateLadder(1, 100, true);
		t.generateLadder(1, 100, false);
		t.generateHereThere(100);
		t.genLeftRight(1, 100);
		t.genRightLeft(1, 100);

		t.generateRandom(1, 100);
		t.generateRandom(1, 100);

		t.genTopBottom(100, 99);
		t.genBottomTop(99, 100);
		t.generateLadder(50, 49, true);
		t.generateLadder(49, 50, false);

		t.generateChess(100, 100);
		t.generateEqual(99, 97);
		t.generateOne(100, 100);
		t.generateRandom(100, 100);

	}

	public void run() {
		try {

			solve();

		} catch (IOException e) {
			e.printStackTrace();
		}
	}

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