#include<bits/stdc++.h>

#define ld double long
#define ll long long
#define ull unsigned long long
#define all(A) A.begin(), A.end()
#define pb push_back
#define fri(start , end , step)  for(int i = start; i < end ; i = i + step)
#define frj(start , end , step)  for(int j = start; j < end ; j = j + step)
#define fast ios_base::sync_with_stdio(0); cin.tie(0)
#define debug(x) cerr<<#x<<": "<<x<<endl;

using namespace std; 

void pv(vector<ll>& vec ){
    fri(0 , vec.size() , 1) cout << vec[i] << " ";
    cout << "\n";
}
multiset<string> A;
mt19937 rng(time(0));
char ans[20][20];

string ss = "ABCDEFGH";

pair<int  , multiset<string>> check(multiset<string> tec , int i1 , int j1){
	
	int cof = 0;
	fri(0 , 20 , 1){
		string s;
		frj(i , i + 12 , 1){
			if(ans[i1][j % 20] != '0' ) s += ans[i1][j % 20];
			else break;  
			int c = tec.count(s) ;
			if(c) {
				cof += c;
				tec.erase(s);
				}
			}
			
		}
	fri(0 , 20 , 1){
		string s;
		frj(i , i + 12 , 1){
			if(ans[j % 20][j1] != '0' ) s += ans[j % 20][j1];
			else break;  
			int c = tec.count(s) ;
			if(c) {
				cof += c;
				tec.erase(s);
				}
			}
			
		}
	return {cof , tec};
	
	
	}

bool vis[20][20];
//
signed main(){
	fast;
    int n , m;
    cin >> n >> m;
	map<char ,  int > M;
	fri(0 , 20   , 1){
		frj(0 , 20 , 1){
			ans[i][j] = '0';
			}
		}
    
    fri(0 , m , 1 ){
		string s;
		cin >> s;
		for(char x : s) M[x] ++;
		A.insert(s);
		}
	
    queue<pair<int , int>> q;
    q.push({0 , 0 });
    
    while(!q.empty()){
		int i = q.front().first ;
		int j = q.front().second;
		//debug(i);
		//debug(j);
		vis[i][j] = 1;
		q.pop();
		multiset<string> good;
		int mx = -1;
		char best;
		
		for(char x : ss){
			ans[i][j] = x;
			pair<int  , multiset<string>> f = check(A, i , j);
			int ls= mx;
			mx = max(mx , f.first);
			if(ls != mx) {
				good= f.second;
				best = x;
				}
			}
		
		
		if(mx == 0){
			int y = rng() % 8;
			best = ss[y];
			
			}
		ans[i][j] = best;
		/*for(int i1 = 0; i1 < 20 ; i1 ++){
			for(int j1 = 0; j1 < 20 ; j1 ++){
				cout << ans[i1][j1];
				}
			cout << endl;
			}
		cout << endl;
		cout << i << " " << j << endl;*/
		
		
		A = good;
		if(i < 19 && vis[i+  1][j] == 0) {
			q.push({i + 1 , j } );
			vis[i + 1][j ] = 1;
			}
		if(j < 19 && vis[i][j+ 1] == 0) {
			q.push({i , j + 1 } );
			vis[i][j + 1] = 1;
			}
		}
    
	fri(0 , 20 , 1){
		frj(0 , 20 , 1) cout << ans[i][j] ;
		cout << "\n";
		}
    return 0;
}

#pragma GCC optimize("Ofast")

#define _GLIBCXX_DEBUG

#include <bits/stdc++.h>

#include <sys/time.h>

using namespace std;


class XorShift128 {
private:
	uint32_t x, y, z, w;

public:
	XorShift128() : x(123456789), y(362436069), z(521288629), w(88675123) { }
	uint32_t rnd() {
		uint32_t t = x ^ (x << 11);
		x = y;
		y = z;
		z = w;
		return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
	}

	uint32_t rnd(const int n) {
		return rnd() % n;
	}

	uint32_t rnd(const int l, const int r) { // [l, r]
		return rnd() % (r - l + 1) + l;
	}
};

long long get_time() {
	struct timeval tv;
	gettimeofday(&tv, NULL);
	long long result =  tv.tv_sec * 1000LL + tv.tv_usec / 1000LL;
	return result;
}

XorShift128 xor_shift_128;
long long start;


const int NIL = -1;


const int dh[2] = {0, 1};
const int dw[2] = {1, 0};

class Solver {
	int N, M;
	vector<string> strs;

	vector<vector<int>> datas;

	vector<vector<int>> ans;
public:
	Solver();
	void run();
private:
	int compute_score() const;

	void output_answer() const;
};

Solver::Solver() {
	cin >> N >> M;
	strs.resize(M);
	for(int i = 0; i < M; ++i) {
		cin >> strs[i];
	}

	datas.resize(M);
	for(int i = 0; i < M; ++i) {
		for(int j = 0; j < strs[i].size(); ++j) {
			int x = strs[i][j] - 'A';
			datas[i].emplace_back(x);
		}
	}

	ans.resize(N);
	for(int hi = 0; hi < N; ++hi) {
		for(int wi = 0; wi < N; ++wi) {
			ans[hi].emplace_back(xor_shift_128.rnd(8));
		}
	}
}

void Solver::run() {
	cerr << compute_score() << endl;

	output_answer();
}

int Solver::compute_score() const {
	int cnt = 0;

	for(const vector<int>& data : datas) {
		for(int i = 0; i < 2; ++i) {
			for(int hi = 0; hi < N; ++hi) {
				for(int wi = 0; wi < N; ++wi) {
					bool match = true;

					for(int j = 0; j < data.size(); ++j) {
						int h = (hi + j * dh[i]) % N;
						int w = (wi + j * dw[i]) % N;
						if(ans[h][w] != data[j]) {
							match = false;
							break;
						}
					}

					if(match) {
						++cnt;
						goto SEARCH_END;
					}
				}
			}
		}

		SEARCH_END:
		cnt;
	}

	if(cnt < M) {
		return round(1e8 * cnt / M);
	} else {
		int dots = 0;
		for(int hi = 0; hi < N; ++hi) {
			for(int wi = 0; wi < N; ++wi) {
				dots += ans[hi][wi] == -1;
			}
		}

		return round(1e8 * 2 * N * N / (2 * N * N - dots));
	}
}

void Solver::output_answer() const {
	for(int hi = 0; hi < N; ++hi) {
		for(int wi = 0; wi < N; ++wi) {
			if(ans[hi][wi] == NIL) {
				cout << '.';
			} else {
				cout << char(int('A') + ans[hi][wi]);
			}
		}
		cout << endl;
	}
}
int main() {
	Solver solver;
	solver.run();
}