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

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
  
#define oset tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());

typedef long long           lol;
#define veci                vector<int> 
#define pii                 pair<int,int>
#define pb                  push_back
#define ub                  upper_bound
#define lb                  lower_bound
#define all(x)              x.begin(),x.end()
#define fo(i,a,n,p)         for(int i=a;(p<0 and i>n) or (p>0 and i<n);i+=p)
#define foim                fo(i,0,m,1)
#define fojm                fo(j,0,m,1)
#define ff                  first
#define ss                  second    
#define cnu                 continue
#define N                   801

int n=20, m;
vector<string> a;

bool cmp(string a, string b){
    if(a.size()-b.size()) return a.size()<b.size();
    else return a<b;
}

vector<pii> g[N];

int sprefix(string a){
    veci pi(a.size(),0);
    int i=0, n=a.size();
    while(++i<n){
        int j=pi[i-1];
        while(j>0 and a[j]!=a[i]) j=pi[j-1];
        if(a[j]==a[i]) j++;
        pi[i]=j;
    }
    return pi[a.size()-1];
}

int main(){
    ios_base::sync_with_stdio(0), cin.tie(0);

    cin>>n>>m;

    foim {string s; cin>>s; a.pb(s);}
    sort(all(a),cmp);

    foim{
        fojm{
            if(i==j) cnu;
            int k=sprefix(a[j]+"$"+a[i]);
            g[i].pb({a[j].size()-k,j});
        }
        sort(all(g[i]));
    }

    vector<pair<int,string>> an;
    bool vis[m]{0};

    foim{
        if(vis[i]) cnu; vis[i]=1;
        string s=a[i]; int c=i, o=1, cou=0;
        while(s.size()<=20){
            for(auto [sc, x]: g[c]){
                if(!vis[x]){
                    if(sc) s+=a[x].substr(a[x].size()-sc,sc);
                    c=x, o++, vis[x]=1; break;
                }
            }
            cou++;
            if(cou==m) break;
        }
        // cout<<s.size()<<'\n';
        an.pb({-o,s.substr(0,min(20,(int)s.size()))});
    }

    sort(all(an));
    fo(i,0,20,1){
        cout<<an[i].ss;
        fo(j,0,20-an[i].ss.size(),1) cout<<'.';
        cout<<'\n';
    }


}
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <cmath>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <sstream>
#include <iomanip>
using namespace std;

using VI = vector <int>;
using VVI = vector <VI>;
using VVVI = vector <VVI>;
using VLL = vector <long long>;
using VVLL = vector <VLL>;
using UMI = unordered_map<int, int>;
using UMLL = unordered_map<long long, long long>;
using VS = vector <string>;

bool cmp(const string& a, const string& b) {
    if (a.size() != b.size()) {
        return a.size() < b.size();
    }

    return a < b;
}

string comb(const string& a, const string& b) {
    int maxlen = min(a.size(), b.size());
    for (int suf = maxlen; suf > 0; --suf) {
        bool pass = true;

        int start = a.size()-suf;
        for (int i = 0; i < suf; ++i) {
            if (a[start+i] != b[i]) {
                pass = false;
                break;
            }
        }

        if (pass) {
            return a.substr(0, a.size()-suf) + b;
        }
    }

    return a + b;
}

int main() {
    int N;
    int M;

    cin >> N >> M;

    VS gene(M);
    for (int i = 0; i < M; ++i) {
        cin >> gene[i];
    }

    while (true) {
        bool changed = false;
        VI used(gene.size());
        VS ngene;

        for (int i = 0; i < gene.size(); i++) {
            if (used[i]) {
                continue;
            }

            for (int j = i+1; j < gene.size(); ++j) {
                if (used[j]) {
                    continue;
                }

                string res = comb(gene[i], gene[j]);
                if (res.size() <= N) {
                    used[i] = used[j] = 1;
                    changed = true;
                    ngene.push_back(res);
                    break;
                }
            }
        }

        if (!changed) {
            break;
        }

        for (int i = 0; i < gene.size(); ++i) {
            if (used[i] == 0) {
                ngene.push_back(gene[i]);
            }
        }
        gene = ngene;
    }

    sort(gene.begin(), gene.end(), cmp);

    VS ans(N);
    int idx = 0;

    for (int i = 0; i < gene.size(); ++i) {
        if (ans[idx].size() + gene[i].size() < N) {
            ans[idx] += gene[i];
        } else {
            // fill in
            while (ans[idx].size() < N) {
                ans[idx] += ".";
            }
            ++idx;
        }

        if (idx == N) {
            break;
        }
    }

    for (int i = 0; i < N; ++i) {
        cout << ans[i] << endl;
    }

    return 0;
}