#include <bits/stdc++.h>
#define int long long
#define ll long long
#define sz(x) (int)(x).size()
#define all(x) begin(x),end(x)
#define rep(i,a,b) for (int i=(a);i<(b);i++)
using namespace std;

string to_string (string s) {return s; }
template <typename T> string to_string(T v) {
    bool first = true;
    string res = "[";
    for (const auto & x : v) {
        if (!first) res += ", ";
        first = false;
        res += to_string(x);
    }
    res += "]";
    return res;
}

void dbg_out() { cout << endl;} 
template <typename Head, typename... Tail> void dbg_out(Head H, Tail... T) {
    cout << ' ' << to_string(H);
    dbg_out(T...);
}

#ifdef DEBUG
#define dbg(...) cout << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
#else
#define dbg(...)
#endif

const int MAXN = 2026;
int dp[MAXN][MAXN];

int doDP(int N, int M) {
    if (N == 2 && M == 2) {
        dp[2][2] = 1;
        return 1;
    }
    if (N <= 1 || M <= 1) return 0;
    if (dp[N][M] != -1) return dp[N][M];
    if (N < M) swap (N , M);
    dp[N][M] = doDP(N - 1, M);
    dp[N][M] += (N - 1) * M * (M - 1)/2;
    return dp[N][M];
}

struct Point {
    int val,N,M;
    bool operator < (const Point & autre) const{
        return val < autre.val;
    }
};

bool grid[MAXN][MAXN];
signed main(void) {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    for (int i = 0 ; i < MAXN ; i++) {
        for (int j = 0 ; j < MAXN ; j++) {
            dp[i][j] = -1;
        }
    }

    doDP(MAXN - 1, MAXN - 1);
    int voeu;
    cin >> voeu;
    if (voeu == 0) {
        cout<<1<<" " <<1<<endl;
        cout<<"."<<endl;
        return 0;
    }
    vector <Point> sols;
    for (int i = 0 ; i < MAXN ; i++) {
        for (int j = 0 ; j < MAXN ; j++) {
            if (dp[i][j] != -1) sols.push_back({dp[i][j],i,j});
        }
    }
    int diffMax = 0;
    sort(sols.begin() , sols.end());
    int id1 = sz(sols) - 1;
    while (id1 >= 0 && sols[id1].val >= voeu) {
        id1--;
    }
    id1++;

    for (int i = 0 ; i < sols[id1].N ; i++) {
        for (int j = 0 ; j < sols[id1].M ; j++) {
            grid[i][j] = true;
        }
    }
    voeu -= sols[id1].val;
    dbg(dp[3][3]);
    dbg(voeu);
    for (int j = 0 ; j < sols[id1].M ; j++) {
        if (voeu < 0) {
            voeu += (sols[id1].N - 1) * (sols[id1].M - j - 1); 
            grid[0][j] = false;
        }
        dbg(j , voeu);
    }

    assert(voeu >= 0);
    
    int deltaM = sols[id1].M + 1;

    int newS = 0;
    while (doDP(3 , newS + 1) <= voeu) {
        voeu -= doDP(3 , newS + 1);
        newS++;
    }

    for (int i = 0 ; i < newS ; i++) {
        for (int j = 0 ; j < 3 ; j++) {
            grid[i][j + deltaM] = true;
        }
    }
    deltaM += 4;

    int deltaN = 0;
    while (voeu > 0) {
        int newN = 1;
        while (doDP(2 , 1 + newN) <= voeu) {
            newN++;
            voeu -= doDP(2 , newN);
        }
        if (deltaN + newN >= 2025) {
            deltaN = 0;
            deltaM += 3;
            assert(deltaM < 2025);
        }
        for (int i = 0 ; i < newN ; i++) {
            for (int j = 0 ; j < 2 ; j++) {
                grid[i + deltaN][j + deltaM] = true;
            }
        }
        deltaN += newN + 1;
    }

    int taille = 2025;
    cout<<taille<<" "<<taille<<endl;
    for (int i = 0 ; i <taille ; i++) {
        for (int j = 0 ; j < taille ; j++) {
            if (grid[i][j] == false) cout<<'.';
            else cout<<'#';
        }
        cout<<endl;
    }
/*
    for (int i = 0 ; i < sz(sols) - 1 ; i++) {
        diffMax = max(diffMax , sols[i + 1].val - sols[i].val);
    }
    for (auto el : sols) cout<<4 * 1e12 - el.val<<" "<<el.val<<" "<<el.N<<" "<<el.M<<" "<<2025 * 2025<<" "<<el.N * (el.N - 1) / 2 - el.val << endl;
    cout<<diffMax<<endl;
*/
    return 0;
}