// Generated by 2.3.1 https://github.com/kyuridenamida/atcoder-tools

#include <bits/stdc++.h>
// #include "atcoder/all"

#define SUBMIT

using namespace std;

using i64 = long long;

const i64 MOD = 1e9 + 7;
const i64 INF = i64(1e18) + 7;


template <typename T>
bool chmin(T& x, T y){
    if(x > y){
        x = y;
        return true;
    }
    return false;
}

template <typename T>
bool chmax(T& x, T y){
    if(x < y){
        x = y;
        return true;
    }
    return false;
}


using Uint = uint64_t;

constexpr int n = 20;
array<Uint, n> h_res, w_res;

void solve(long long m, std::vector<std::string> s){

    // sort(s.begin(), s.end(), [](auto x, auto y){return x.size() < y.size();});
    int min_len = 100;
    int max_len = 0;

    vector<pair<int,Uint>> target(m);
    for(int i = 0; i < m; ++i){
        chmin(min_len, int(s[i].size()));
        chmax(max_len, int(s[i].size()));
        target[i].first = s[i].size();
        target[i].second = 0;
        for(int j = 0; j < s[i].size(); ++j){
            target[i].second |= ((s[i][j] - 'A') << (3 * j));
        }
    }

    for(int i = 0; i < n; ++i){
        for(int j = 0; j < n; ++j){
            Uint val = (rand() & 7);
            h_res[i] |= val << (j * 3);
            w_res[j] |= val << (i * 3);
        }
    }

    auto get = [&](int i, int j){
        Uint h = (h_res[i] >> (3 * j)) & 7;
        Uint w = (w_res[j] >> (3 * i)) & 7;
        assert(h == w);
        return h;
    };
    auto get_h = [&](int i, int j, int len){
        Uint h = (h_res[i] >> (3 * j)) & ((1uLL << (3 * len)) - 1);
        if(j + len > n){
            int over = j + len - n;
            return h | Uint((h_res[i] & ((1uLL << (3 * over)) - 1)) << (3 * (n - j)));
        }
        return h;
    };
    auto get_w = [&](int i, int j, int len){
        Uint w = (w_res[j] >> (3 * i)) & ((1uLL << (3 * len)) - 1);
        if(i + len > n){
            int over = i + len - n;
            return w | Uint((w_res[j] & ((1uLL << (3 * over)) - 1)) << (3 * (n - i)));
        }
        return w;
    };

    // TODO: hash_map
    vector<unordered_map<Uint, int>> now_hash(max_len + 1);
    for(int i = 0; i < n; ++i){
        for(int j = 0; j < n; ++j){
            for(int l = min_len; l <= max_len; ++l){
                ++now_hash[l][get_h(i, j, l)];
                ++now_hash[l][get_w(i, j, l)];
            }
        }
    }


    // 以下回答関連
#ifndef SUBMIT
    int ans = 0;
    for(int i = 0; i < m; ++i){
        auto t = target[i];
        if(now_hash[t.first].count(t.second)){
            cout << "correct: " << i << "  " << s[i] << endl;
            ++ans;
        }
    }

    cout << "ans: " << ans << endl;
    cout << Uint(round(1e8 * ans / m)) << endl;
#endif

    for(int i = 0; i < n; ++i){
        for(int j = 0; j < n; ++j){
            cout << char('A' + ((h_res[i] >> (3 * j)) & 7));
        }
        cout << endl;
    }

    cout << endl;
}


signed main(){

#ifndef SUBMIT
    long long N;
    long long M;
    ifstream fs("../contests/ahc004/A/in/0001.txt");
    assert(fs.is_open());
    fs >> N >> M;
    std::vector<std::string> s(M);
    for(int i = 0 ; i < M ; i++){
        fs >> s[i];
    }
#else

    long long N;
    std::scanf("%lld", &N);
    long long M;
    std::scanf("%lld", &M);
    std::vector<std::string> s(M);
    for(int i = 0 ; i < M ; i++){
        std::cin >> s[i];
    }
#endif
    solve(M, std::move(s));
    return 0;
}

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int N,M;
    int x,y;
    string A[800];
    int score[800]={0};
    char dna[20][20];

    cin >> N >> M;


    for(int i=0; i<M; i++) {
        string a;
        cin >> a;

        bool iscontain=false;
        int conv=0;
        int convj=0;
        for( int j=0; j<i; j++)
            if(A[j].find(a)!=string::npos) {
                iscontain=true;
                if(score[j]>conv) {
                    conv=score[j];
                    convj=j;
                }
                break;
            }
        if(iscontain!=true) {
            A[i]=a;
            score[i]++; 
        } else {
            score[convj]++;
            A[i]="";
        }
    }

    bool convine=true;

    while(convine) {
        convine=false;
        for(int i=0; i<M; i++) {
            if(A[i].size()>2){
                string b=A[i].substr(A[i].size()-2);
                for(int j=0; j<M; j++) {
                    if( i==j ) continue;
                    if( A[j][0]==b[0] && A[j][1]==b[1] ){
                        if( A[i].size()+A[j].size()-2 <= N) {
                            A[i] = A[i] + A[j].substr(2);
                            A[j] ="";
                            score[i]+=score[j];
                            score[j]=0;
                            convine=true;
                            break;
                        }
                    }
                }
            }
        }
    }

    convine=true;

    while(convine) {
        convine=false;
        for(int i=0; i<M; i++) {
            if(A[i].size()>2 && A[i].size()<N){
                for(int j=0; j<M; j++) {
                    if( i==j ) continue;
                    if( (A[j].size() > 2) && ((A[i].size()+A[j].size()) <= N) ){
                        A[i] = A[i] + A[j];
                        A[j] ="";
                        score[i]+=score[j];
                        score[j]=0;
                        convine=true;
                        break;
                    }
                }
            }
        }
    }

    for(int i=0; i<M; i++){
        int max=score[i];
        int maxj=i;
        for(int j=i; j<M; j++){
            if(score[j]>max) {
                max=score[j];
                maxj=j;
            }
        }
        if( i!=maxj){
            string tmp;
            tmp=A[maxj];
            A[maxj]=A[i];
            A[i]=tmp;
            int ti=score[maxj];
            score[maxj]=score[i];
            score[i]=ti;
        }
    }

    for(int i=0; i<N; i++) {
        if(A[i].size() < 20) A[i]+="....................";
    }

    for(int i=0; i<N; i++) {
        cout << A[i].substr(0,20) << endl;
    }
};
