#define NDEBUG
NDEBUG


#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <memory>
#include <queue>
#include <random>

#define FOR(i, n) for (int i = 0; i < (n); ++i)


using namespace std;

// TC_REMOVE_BEGIN
/// caide keep
bool __hack = std::ios::sync_with_stdio(false);
/// caide keep
auto __hack1 = cin.tie(nullptr);
// TC_REMOVE_END


// Section with adoption of array and vector algorithms.


namespace template_util {
    

    constexpr int bytecount(uint64_t x) {
        return x ? 1 + bytecount(x >> 8) : 0;
    }

    template<int N>
    struct bytetype {
        
    };

    
    /// caide keep
    template<uint64_t N>
    struct minimal_uint : bytetype<bytecount(N)> {
    };
}


template<class T>
T next(istream& in) {
    T ret;
    in >> ret;
    return ret;
}


#define dbg(...) ;


constexpr int MAXN = 100;

int cc;
bool u[MAXN][MAXN];

void dfs(const vector<string>& f, int x, int y) {
    if (x < 0 || y < 0 || x >= MAXN || y >= MAXN) {
        return;
    }
    if (f[x][y] == '#') return;
    if (u[x][y]) {
        return;
    }
    u[x][y] = true;
    dfs(f, x + 1, y);
    dfs(f, x - 1, y);
    dfs(f, x, y + 1);
    dfs(f, x, y - 1);
}

bool check(vector<string> f, int a, int b) {
    cc = 0;
    memset(u, false, sizeof u);
    FOR(i, MAXN) {
        FOR(j, MAXN) {
            if (f[i][j] == '#') {
                continue;
            }
            if (u[i][j]) {
                continue;
            }
            ++cc;
            dfs(f, i, j);
        }
    }
    if (a != cc) {
        dbg("wrong A", a, cc);
        return false;
    }
    memset(u, false, sizeof u);
    FOR(i, MAXN) {
        FOR(j, MAXN) {
            if (f[i][j] == '#') {
                f[i][j] = '.';
            } else {
                f[i][j] = '#';
            }
        }
    }
    cc = 0;
    FOR(i, MAXN) {
        FOR(j, MAXN) {
            if (f[i][j] == '#') {
                continue;
            }
            if (u[i][j]) {
                continue;
            }
            ++cc;
            dfs(f, i, j);
        }
    }
    if (b != cc) {
        dbg("wrong B", b, cc);
        return false;
    }
    return true;
}

void solve(istream &in, ostream &out) {

    auto a = next<int>(in);
    auto b = next<int>(in);
    int temp_a = a, temp_b = b;


    vector<string> f(MAXN);
    string tmp = "";
    FOR(i, MAXN) {
        tmp.push_back('.');
    }
    FOR(i, MAXN) {
        f[i] = tmp;
    }
    FOR(i, MAXN) {
        f[i][MAXN-1] = '#';
    }
    --a;
    for (int row = 3; a && row < MAXN-1; row += 4, a--) {
        FOR(i, MAXN) {
            f[row][i] = '#';
        }
    }
    while (a) {
        for (int col = 3; a && col < MAXN; col += 4) {
            for (int row = 0; a && row < MAXN; row += 4) {
                int to_row = min(row + 3, MAXN-1);
                for (int j = row; j <= to_row; ++j) {
                    f[j][col] = '#';
                }
                --a;
            }
        }
    }
    --b;

    for (int r = 1; b && r < MAXN; r += 4) {
        for (int c = 1; b && c < MAXN-1; c += 4, --b) {
            f[r][c] = '#';
        }
    }
    out << MAXN << " " << MAXN << "\n";
    for (auto ff : f) {
        out << ff << "\n";
    }
    if (!check(f, temp_a, temp_b)) {
        throw 42;
    }


}

//#include <fstream>


int main() {
//    ifstream fin("input.txt");
//    ofstream fout("output.txt");
//    solve(fin, fout);
    solve(cin, cout);
    return 0;
}



Measured memory_bytes: 1024