#include <bits/stdc++.h>

using namespace std;

const int MAX_DIM = 2025;
vector<string> grid;

long long calcRect(int n, int m) { // cells
    return n*(n-1LL)/2 * m*(m-1LL)/2;
}
pair<int, int> genRect(long long mx) {
    const int MAX_N = MAX_DIM - 8;
    const int MAX_M = MAX_DIM - 3;

    // int n = sqrtl(sqrtl(mx)), m = n;
    // while (calcRect(n, m) > mx) --n, --m;
    // while (calcRect(n+1, m) <= mx) ++n;
    // while (calcRect(n, m+1) <= mx) ++m;
    pair<long long, pair<int, int>> best = {0, {0, 0}};
    for (int n = 2; n <= MAX_N; ++n) {
        long long a = n*(n-1LL)/2;
        if (a > mx) continue;
        int m = min((long long)MAX_M, (long long)sqrtl(mx/a));
        while (calcRect(n, m) > mx) --m;
        while (calcRect(n, m+1) <= mx && m+1 <= MAX_M) ++m;

        // cout << " " << n << " gave " << m << endl;

        long long v = calcRect(n, m);
        if (v >= best.first) best = {v, {n, m}};
    }
    return best.second;
}
// int genClose(long long mx) {
//     auto [n, m] = genRect(mx);
//     cout << n << ' ' << m << endl;
//     long long cur = calcRect(n, m);
//     cout << " " << mx-cur << " start\n";

//     bool changing = true;
//     int lastStop = m;
//     int extraRow = 0;
//     while (changing && n < MAX_DIM) {
//         changing = false;
//         int i;
//         for (i = 0; i < lastStop; ++i) {
//             int extra = n*i;
//             if (cur + extra > mx) break;
//             cur += extra;
//         }
//         lastStop = i;
//         if (lastStop > 1) changing = true;

//         if (changing) ++n, ++extraRow;
//     }
//     cout << mx-cur << " finish\n";
//     cout << extraRow << ' ' << extraRow << endl;
//     cout << endl;
//     return mx-cur;
// }


int genClose(long long mx) {
    auto [n, m] = genRect(mx);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) grid[i][j] = '#';
    }

    // cout << n << ' ' << m << endl;
    long long cur = calcRect(n, m);
    // cout << " " << mx-cur << " start\n";

    bool changing = true;
    int lastStop = m;
    int extraRow = 0;
    while (changing && n < MAX_DIM) {
        changing = false;
        int i;
        for (i = 0; i < lastStop; ++i) {
            int extra = n*i;
            if (cur + extra > mx) break;
            cur += extra;
            grid[n][i] = '#';
        }
        lastStop = i;
        if (lastStop > 1) changing = true;

        if (changing) ++n, ++extraRow;
    }
    // cout << mx-cur << " finish\n";
    // cout << extraRow << ' ' << extraRow << endl;
    // cout << endl;
    return mx-cur;
}

int score(int v) {
    return v*(v-1)/2;
}
int undercut(int x) {
    int v = sqrtl(x);
    while (score(v) > x) --v;
    while (score(v+1) <= x) ++v;
    return v;
}

int solve(long long k) {
    int remaining = genClose(k);
    int rowsUsed = 0;
    while (remaining) { // && rowsUsed < 1000
        int v = undercut(remaining);
        for (int i = 0; i < v; ++i) {
            grid[rowsUsed][MAX_DIM-1] = '#';
            grid[rowsUsed][MAX_DIM-2] = '#';
            ++rowsUsed;
        }
        ++rowsUsed;
        remaining -= score(v);
    }
    return rowsUsed;
}

// void testGen(int t = 1000) {
//     const long long MX = 4e12;
//     vector<int> er;
//     for (int i = 0; i < t; ++i) {
//         long long r = (long long)rand() * rand() % MX;
//         er.push_back(solve(r));
//         // auto [n, m] = genRect(r);
//         // long long r2 = calcRect(n, m);
//         // cout << r-r2 << " (" << r << ' ' << n << ' ' << m << ")\n";
//     }
//     cout << *max_element(er.begin(), er.end()) << endl;
//     for (int x : er) cout << x << ' ' ; cout << endl;
// }

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    grid = vector<string>(MAX_DIM, string(MAX_DIM, '.'));
    
    long long k; cin >> k;
    solve(k);

    cout << MAX_DIM << ' ' << MAX_DIM << endl;
    for (int i = 0; i < MAX_DIM; ++i) {
        cout << grid[i] << '\n';
    }
    // testGen();
    return 0;
}