import std.stdio;
import std.range;
import std.array;
import std.string;
import std.conv;
import std.typecons;
import std.algorithm;
import std.container;
import std.typecons;
import std.random;
import std.math;
import core.time;

int[][] ofs = [
	[0, 1],
	[1, 0],
	[-1, 0],
	[0, -1]
];

void fill(bool[][] field, bool[][] done, int x, int y, bool color)
{
	foreach (d; ofs) {
		int nx = d[0] + x;
		int ny = d[1] + y;
		if (nx < 0 || field[0].length <= nx
				|| ny < 0 || field.length <= ny) {
			continue;
		}
		if (field[ny][nx] != color) {
			continue;
		}
		if (done[ny][nx]) {
			continue;
		}
		done[ny][nx] = true;
		fill(field, done, nx, ny, color);
	}
}

alias Ret = Tuple!(int, "a", int, "b");
Ret cal(bool[][] field) {
	if (field.length == 0) {
		return Ret.init;
	}
	bool[][] done = new bool[][](field.length, field[0].length);
	Ret ret;
	foreach (int y, arr; field) {
		foreach (int x, color; arr) {
			if (done[y][x]) {
				continue;
			}
			done[y][x] = true;
			if (field[y][x]) {
				ret.b++;
			} else {
				ret.a++;
			}
			fill(field, done, x, y, color);
		}
	}
	return ret;
}

void main()
{
	auto inp = readln.chomp.split.map!(to!int);
	int a = inp.front;
	int b = inp.back;
	int x = a.max(b);
	int y = a.min(b);
	int iteX = 0;
	int iteY = 0;
	bool[][] field;
	bool fixedX = false;
	for (int k = 0;;++k) {
		if (fixedX) {
			if (iteY == y) {
				break;
			}
			if (iteY >= y + 100) {
				ulong target = -1;
				foreach (index, arr; field) {
					if (index <= 1 || index == field.length - 1) {
						continue;
					}
					auto brr = field[index - 1].retro;
					if (arr.equal(brr)) {
						target = index;
					}
				}
				bool[] line = new bool[](100);
				line []= false;
				field = field[0..target] ~ line ~ field[target..$];
				iteY -= 100;
			} else if (iteY >= y + 50) {
				bool[] line = new bool[](100);
				line []= false;
				field = line ~ field;
				iteY -= 49;
			} else {
				if (field.length >= 4) {
					bool[] line = new bool[](100);
					line []= false;
					if (field[1].equal(field[2].retro)
						&& field[0].equal(line)
						&& field[3].equal(line)) {
						field = field[0..2] ~ line ~ field[2..$];
						--iteY;
						stderr.writeln("-1 : ", [iteX, iteY]);
						continue;
					}
				}
				bool[] line = new bool[](100);
				line []= false;
				foreach (i, arr; field) {
					if (arr == line) {
						continue;
					}
					bool[] next = arr.dup;
					for (int j = 0; j < 100; ++j) {
						next[j] = false;
						auto tmp = field[0..i+1] ~ next ~ field[i+1..$];
						if (tmp.cal.a == y) {
							break;
						}
					}
					field = field[0..i+1] ~ next ~ field[i+1..$];
					Ret ret = field.cal;
					iteX = ret.b;
					iteY = ret.a;
					break;
				}
			}
		} else {
			if (iteX + 50 <= x) {
				bool[] line = new bool[](100);
				foreach (i, ref v; line) {
					v = (i + k) % 2 == 0;
				}
				iteX += 50;
				iteY += 50;
				stderr.writeln(line, ", ", [iteX, iteY]);
				field ~= line;
			} else if (iteX + 50 > x) {
				bool[] line = new bool[](100);
				foreach (i, ref v; line) {
					if (iteX < x) {
						v = (i + k) % 2 == 0;
						if (v == 0) {
							iteY++;
						} else {
							iteX++;
						}
					}
				}
				++iteY;
				fixedX = true;
				field ~= line;
			}
		}
	}
	writeln(field.length, " ", field[0].length);
	foreach (arr; field) {
		foreach (v; arr) {
			if (x == b) {
				write = v ? "#" : ".";
			} else {
				write = !v ? "#" : ".";
			}
		}
		writeln;
	}
}
