#include "bits/stdc++.h"
using namespace std;

#define DEBUG(x) cout<<#x<<": "<<x<<endl;
#define DEBUG_VEC(v) cout<<#v<<":";for(int i=0;i<v.size();i++) cout<<" "<<v[i]; cout<<endl

typedef long long ll;
#define vi vector<int>
#define vl vector<ll>
#define vii vector< vector<int> >
#define vll vector< vector<ll> >
#define vs vector<string>
#define pii pair<int,int>
#define pis pair<int,string>
#define psi pair<string,int>
#define pll pair<ll,ll>
#define fi first
#define se second
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define rep1(i,n) for(int i=1;i<=(int)(n);i++)
#define all(c) c.begin(),c.end()
const int inf = 1000000001;
const ll INF = 2e18;
const ll MOD = 1000000007;
const ll mod = 1000000009;
const double pi = 3.14159265358979323846;
#define Sp(p) cout<<setprecision(15)<< fixed<<p<<endl;
int dx[4] = { 1,0,-1,0 }, dy[4] = { 0,1,0,-1 };
int dx2[8] = { 1,1,0,-1,-1,-1,0,1 }, dy2[8] = { 0,1,1,1,0,-1,-1,-1 };





class UnionFind {
public:
	int n;
	vi par; //親
	vi ran; //木の深さ
	vi num; //要素数

	UnionFind(int _n) {
		n = _n;
		par.resize(n); ran.resize(n); num.resize(n);
		for (int i = 0; i < n; i++) {
			par[i] = i; ran[i] = 0; num[i] = 1;
		}
	}

	//木の根を求める
	int find(int x) {
		if (par[x] == x) {
			return x;
		}
		else {
			return par[x] = find(par[x]);
		}
	}

	//xとyの属する集合を併合
	void unite(int x, int y) {
		x = find(x); y = find(y);
		int numsum = num[x] + num[y];
		if (x == y) {
			return;
		}
		if (ran[x]<ran[y]) {
			par[x] = y;
		}
		else {
			par[y] = x;
			if (ran[x] == ran[y]) {
				ran[x]++;
			}
		}
		num[x] = num[y] = numsum;
	}

	//xとyが同じ集合に属するか否か
	bool same(int x, int y) {
		return find(x) == find(y);
	}

};

int main() {
	int a, b;
	cin >> a >> b;
	bool black = false;
	if (a < b) {
		swap(a, b);
		black = true;
	}
	int h = 100, w = 100;
	cout << h << " " << w << endl;
	vector<vector<char> > c(h + 2, vector<char>(w + 2, '?'));
	int bcnt = 0;
	int i;
	bool flag = true;
	for (i = 1; i <= h; i++) {
		for (int j = i % 2; j <= w; j+= 2) {
			if (b == 1) {
				flag = false;
				break;
			}
			if (j == 0) {
				continue;
			}
			c[i][j] = '#';
			rep(k, 4) {
				c[i + dx[k]][j + dy[k]] = '.';
			}
			bcnt++;
			if (bcnt == b - 1) {
				flag = false;
				break;
			}
		}
		if (!flag) {
			break;
		}
	}
	rep1(j, w) {
		if (c[i][j] == '?') {
			c[i][j] = '.';
		}
		if (c[i + 1][j] == '?') {
			c[i + 1][j] = '.';
		}
	}
	int cnt = 0;
	map<pii, int> mp;
	rep1(i, h) {
		rep1(j, w) {
			if (c[i][j] == '.') {
				mp[pii(i, j)] = ++cnt;
			}
		}
	}
	UnionFind uf(cnt);
	rep1(i, h) {
		rep1(j, w) {
			if (c[i][j] == '.') {
				rep(k, 4) {
					int temp = mp[pii(i + dx[k], j + dy[k])];
					if (temp > 0) {
						uf.unite(temp - 1, mp[pii(i, j)] - 1);
					}
				}
			}
		}
	}
	set<int> st;
	cnt = 0;
	rep1(i, h) {
		rep1(j, w) {
			int temp = mp[pii(i, j)];
			if (temp == 0) {
				continue;
			}
			int root = uf.find(temp - 1);
			if (st.count(root) == 0) {
				cnt++;
				st.insert(root);
			}
		}
	}
	int acnt = st.size();
	/*
	rep1(i, h) {
		rep1(j, w) {
			cout << c[i][j];
		}
		cout << endl;
	}
	cout << endl;
	//*/
	i += 3;
	flag = true;
	for (; i <= h; i += 2) {
		for (int j = 1; j <= w; j += 2) {
			if (acnt == a) {
				flag = false;
				break;
			}
			c[i][j] = '.';
			acnt++;
		}
		if (!flag) {
			break;
		}
	}
	rep1(i, h) {
		rep1(j, w) {
			if (c[i][j] == '?') {
				c[i][j] = '#';
			}
			if (!black) {
				cout << c[i][j];
			}
			else {
				if (c[i][j] == '#') {
					cout << '.';
				}
				else {
					cout << '#';
				}
			}
		}
		cout << endl;
	}
}

Measured memory_bytes: 896