#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define ll long long
#define pb push_back
#define all(x) x.begin(),x.end()
#define f first
#define s second

using namespace __gnu_pbds;
using namespace std;
template<class T> using ordered_set=tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;
template<class T1,class T2> ostream& operator<<(ostream& out,pair<T1,T2> a){out << "[" << a.f << "," << a.s << "]"; return out;}
template<class T> ostream& operator<<(ostream& out, vector<T> a){out << "{";for(auto p:a)out << p << ",";out << "}";return out;}

const int N=14;
int dp[1<<N][N];
string dodajem[1<<N][N];
pair<int,int> nxt[1<<N][N];
string razlika[N][N];
int nn;
int calc(int mask,int last)
{
    if(mask==(1<<nn)-1)
        return 0;
    if(dp[mask][last]!=-1)
        return dp[mask][last];
    dp[mask][last]=INT_MAX;
    for(int i=0;i<nn;i++)
    {
        if(mask&(1<<i))
            continue;
        int trsol=razlika[last][i].size()+calc(mask|(1<<i),i);
        if(trsol<dp[mask][last])
        {
            dp[mask][last]=trsol;
            nxt[mask][last]={mask|(1<<i),i};
            dodajem[mask][last]=razlika[last][i];
        }
    }
    return dp[mask][last];
}
int Resi(int n,int k,int *l,char **a,char* s)
{
    nn=n;
    memset(dp,-1,sizeof(dp));
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            for(int x=1;x<=l[i];x++)
            {
                bool moze=true;
                for(int y=1;y+x-1<=l[i]&&y<=l[j];y++)
                    if(a[i][x+y-1]!=a[j][y])
                        moze=false;
                //printf("Gledam %i %i %i: %i\n",i,j,x,moze);
                if(moze)
                {
                    int siz=l[j]-(l[i]-x+1);
                    for(int y=l[j]-siz+1;y<=l[j];y++)
                        razlika[i-1][j-1]+=a[j][y];
                    break;
                }
                if(x==l[i])
                {
                    for(int y=1;y<=l[j];y++)
                        razlika[i-1][j-1]+=a[j][y];
                    break;
                }
            }
            //printf("%i %i: ",i,j);
            //cout << razlika[i-1][j-1] << endl;
        }
    }

    int sol=INT_MAX;
    int gde;
    for(int i=0;i<n;i++){
        int tr=l[i+1]+calc(1<<i,i);
        if(tr<sol)
        {
            sol=tr;
            gde=i;
        }
    }
    string ans;
    for(int i=1;i<=l[gde+1];i++)
        ans+=a[gde+1][i];
    pair<int,int> tr={1<<gde,gde};
    while(tr.f!=(1<<n)-1)
    {
        ans+=dodajem[tr.f][tr.s];
        tr=nxt[tr.f][tr.s];
    }
    for(int i=0;i<ans.size();i++)
        s[i+1]=ans[i];
    return sol;
}