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

public class TestGen {
	public static void main(String[] args) {
		new TestGen().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;

	void print(int n, int m, char[][] a) throws IOException {
		if (tNumber < 10) {
			out = new PrintWriter("../tests/0" + tNumber);
		} else {
			out = new PrintWriter("../tests/" + tNumber);
		}
		tNumber++;
		out.println(n + " " + m);
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				out.print(a[i][j]);
			}
			out.println();
		}
		out.close();
	}
	
	void genPreliminary() throws FileNotFoundException {
		out = new PrintWriter("../preliminary/01");
		out.println("3 2");
		out.println("+.");
		out.println("..");
		out.println(".-");
		out.close();
	}
	static final char[] c = { '+', '-', '.', '.' };

	void gen(int n, int m) throws IOException {
		char[][] a = new char[n][m];
		for (int i = 0; i < n; i++) {
			Arrays.fill(a[i], '.');
		}
		int upx = rnd.nextInt(n) + 1;
		int upy = rnd.nextInt(m) + 1;
		boolean[][] wasx = new boolean[n][2];
		boolean[][] wasy = new boolean[m][2];
		int cx = 0, cy = 0;
		while (cx < upx || cy < upy) {
			int x = rnd.nextInt(n);
			int y = rnd.nextInt(m);
			if (a[x][y] != '.') {
				continue;
			}
			int col = rnd.nextInt(2);
			int numy = (y % 2) ^ col;
			int numx = (x % 2) ^ col;
			if (wasx[x][1 - numy]) {
				continue;
			}
			if (wasy[y][1 - numx]) {
				continue;
			}
			if (!wasx[x][numy]) {
				if (cx == upx) {
					continue;
				}
				cx++;
			}
			if (!wasy[y][numx]) {
				if (cy == upy) {
					continue;
				}
				cy++;
			}

			wasx[x][numy] = true;
			wasy[y][numx] = true;
			a[x][y] = c[col];
		}
		print(n, m, a);
	}

	void genempty(int n, int m) throws IOException {
		char[][] a = new char[n][m];
		for (int i = 0; i < n; i++) {
			Arrays.fill(a[i], '.');
		}
		print(n, m, a);
	}

	void gensame(int n, int m) throws IOException {
		char[][] a = new char[n + 1][m + 1];
		int col = rnd.nextInt(2);
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				a[i][j] = c[(i + j) % 2 ^ col];
			}
		}
		for (int i = 0; i < n * m / 3; i++) {
			int x = rnd.nextInt(n);
			int y = rnd.nextInt(m);
			a[x][y] = '.';
		}
		for (int i = 0; i < n * m / 3; i++) {
			int x = rnd.nextInt(n);
			int y = rnd.nextInt(m);
			a[x][y] = c[1 - (x + y) % 2 ^ col];
		}
		print(n, m, a);
	}

	void genchess(int n, int m, int k) throws IOException {
		char[][] a = new char[n][m];
		int col = rnd.nextInt(2);
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				a[i][j] = c[(i + j) % 2 ^ col];
			}
		}
		for (int i = 0; i < k; i++) {
			if (rnd.nextBoolean()) {
				int x = rnd.nextInt(n);
				for (int j = 0; j < m; j++) {
					a[x][j] = '.';
				}
			} else {
				int y = rnd.nextInt(m);
				for (int j = 0; j < n; j++) {
					a[j][y] = '.';
				}
			}
		}
		print(n, m, a);
	}

	void genAnother(int n, int m) throws IOException {
		char[][] a = new char[n][m];
		int col = rnd.nextInt(2);
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				a[i][j] = c[col ^ ((i + j) % 2)];
			}
		}
		int upx = rnd.nextInt(n / 4 + 1) + n / 2;
		for (int i = 0; i < upx; i++) {
			int x = rnd.nextInt(n);
			for (int j = 0; j < m; j++) {
				a[x][j] = '.';
			}
		}
		int upy = rnd.nextInt(n / 4 + 1) + n / 2;
		for (int i = 0; i < upy; i++) {
			int y = rnd.nextInt(m);
			for (int j = 0; j < n; j++) {
				a[j][y] = '.';
			}
		}
		for (int i = 0; i < n / 3 * m; i++) {
			a[rnd.nextInt(n)][rnd.nextInt(m)] = '.';
		}
		for (int i = 0; i < n * m / 6; i++) {
			int x = rnd.nextInt(n - 1);
			int y = rnd.nextInt(m - 1);
			a[x][y] = a[x + 1][y] = a[x][y + 1] = a[x + 1][y + 1] = '.';
		}
		print(n, m, a);
	}

	public void generate() throws IOException {
		genPreliminary();
		tNumber = 1;
		rnd = new Random(239);

		genempty(4, 5);
		for (int i = 0; i < 3; i++) {
			int x, y;
			do {
				x = rnd.nextInt(4) + 2;
				y = rnd.nextInt(4) + 2;
			} while (x * y >= 20);
			gen(x, y);
		}

		for (int i = 0; i < 4; i++) {
			int x, y;
			do {
				x = rnd.nextInt(4) + 2;
				y = rnd.nextInt(4) + 2;
			} while (x * y >= 20);
			genAnother(x, y);
		}
		gensame(4, 5);
		genchess(4, 5, 1);
		System.err.println("first group" + " " + tNumber);
		for (int it = 0; it < 2; it++) {
			genempty(rnd.nextInt(6) + 5, rnd.nextInt(11) + 40);
			for (int i = 0; i < 3 - it; i++) {
				boolean dx = (rnd.nextInt(4) == 0);
				boolean dy = (rnd.nextInt(4) == 0);
				gen(rnd.nextInt(9) + 2, rnd.nextInt(11) + 40);
			}
			for (int i = 0; i < 3; i++) {
				genAnother(rnd.nextInt(9) + 2, rnd.nextInt(11) + 40);
			}
			if (it == 0) {
				gensame(rnd.nextInt(6) + 5, rnd.nextInt(11) + 40);
//				genchess(rnd.nextInt(6) + 5, rnd.nextInt(11) + 40, 0);
			} else {
				genchess(rnd.nextInt(6) + 5, rnd.nextInt(6) + 5, 3 - it);
				// genchess(rnd.nextInt(6) + 5, rnd.nextInt(6) + 5, 3 - it);
			}
		}
		System.err.println("second group" + " " + tNumber);
		genempty(rnd.nextInt(2) + 14, rnd.nextInt(11) + 40);
		for (int i = 0; i < 3; i++) {
			boolean dx = (rnd.nextInt(4) == 0);
			boolean dy = (rnd.nextInt(4) == 0);
			gen(rnd.nextInt(2) + 14, rnd.nextInt(11) + 40);
		}
		for (int i = 0; i < 3; i++) {
			genAnother(rnd.nextInt(2) + 14, rnd.nextInt(11) + 90);
		}
		gensame(rnd.nextInt(2) + 14, rnd.nextInt(11) + 40);
		genchess(rnd.nextInt(2) + 14, rnd.nextInt(11) + 90, rnd.nextInt(4) + 1);
		genchess(rnd.nextInt(2) + 14, rnd.nextInt(11) + 90, rnd.nextInt(4) + 1);
		System.err.println("third group" + " " + tNumber);
		for (int it = 0; it < 2; it++) {
			if (it != 1) {
				genempty(rnd.nextInt(501) + 500, rnd.nextInt(501) + 500);
			} else {
				genempty(1000, 1000);
			}
			for (int i = 0; i < 4; i++) {
				boolean dx = (rnd.nextInt(4) == 0);
				boolean dy = (rnd.nextInt(4) == 0);
				gen(rnd.nextInt(501) + 500, rnd.nextInt(501) + 500);
			}
			for (int i = 0; i < 4; i++) {
				genAnother(rnd.nextInt(501) + 500, rnd.nextInt(501) + 500);
			}
			if (it != 1) {
				gensame(rnd.nextInt(501) + 500, rnd.nextInt(501) + 500);
			} else {
				genchess(rnd.nextInt(501) + 500, rnd.nextInt(501) + 500, 4 - it);
				// genchess(rnd.nextInt(501) + 500, rnd.nextInt(501) + 500, 4 -
				// it);
			}
		}
		System.err.println("fourth group" + " " + tNumber);

	}

	public void run() {
		try {
			generate();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
			System.exit(1);
		}
	}
}