#include "testlib.h"
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
// #include <ext/pb_ds/tree_policy.hpp>
// #include <ext/pb_ds/assoc_container.hpp>
 
// constexpr int MAX_N = 1'000'000;
// constexpr int MAX_A = (int)1e9;

constexpr int N_MAX = (int)2e5;
constexpr int NM_MAX = (int)2e5;
constexpr int K_MAX = 100;

const int MAX_N[] = {
	N_MAX, // sample
	1,
	1,
	5000,
	5000,
	N_MAX,
	N_MAX
};

const int MAX_M[] = {
	N_MAX, // sample
	2,
	N_MAX,
	5000,
	5000,
	N_MAX,
	N_MAX
};

const int MAX_K[] = {
    K_MAX, // sample
	K_MAX,
	K_MAX,
	1,
	K_MAX,
	1,
	K_MAX
};

const int MAX_NM[] = {
	NM_MAX, // sample
	2,
	NM_MAX,
	5000,
	5000,
	NM_MAX,
	NM_MAX
};

int c = 0;

const int dx[] = {0,1,0,-1};
const int dy[] = {1,0,-1,0};
int n,m;

void dfs(int x,int y,char** g){
	if(g[x][y] == '.' || c == 0)
		return;
	c--;
	g[x][y] = '.';	
	std::vector<int> perm = rnd.perm(4);
	for(int i = 0; i < 4; i++){
		int dir = perm[i];
		int xn = x + dx[dir], yn = y + dy[dir];
		if(xn >= 0 && xn < n && yn >= 0 && yn < m)
			dfs(xn,yn,g);
	}
}

signed main(int argc,char* argv[]){
	registerGen(argc,argv,1);
 
	int group = atoi(argv[1]);
	n = rnd.next(1,(int)sqrt(MAX_N[group]));
	m = rnd.next(1,MAX_NM[group]/n);
	int k = rnd.next(1,std::min(n*m,MAX_K[group]));

	if(argc > 2 && atoi(argv[2]) > 0)
		k = atoi(argv[2]);

	char* g[n];
	for(int i = 0; i < n; i++){
		g[i] = new char[m];
	}
	for(int i = 0; i < n; i++){
		for(int j = 0; j < m; j++){
			g[i][j] = 'F';
		}
	}

	c = rnd.next(k,n*m);

	int x = rnd.next(0,n-1);
	int y = rnd.next(0,m-1);
	dfs(x,y,g);

	std::vector<std::pair<int,int>> free;
	for(int i = 0; i < n; i++){
		for(int j = 0; j < m; j++){
			if(g[i][j] == '.')
				free.push_back(std::make_pair(i,j));
		}
	}

	std::vector<int> perm = rnd.perm((int)free.size());
	for(int i = 0; i < k; i++){
		auto[x,y] = free[perm[i]];
		g[x][y] = 'H';
	}

	std::cout << n << " " << m << "\n";
	for(int i = 0; i < n; i++){
		for(int j = 0; j < m; j++){
			std::cout << g[i][j];
		}
		std::cout << "\n";
	}

	return 0;
}