# include <stdio.h>
# include <string.h>
# define _fin "adn.in"
# define _fout "adn.out"
# define maxn 20
# define maxw 30004
# define pow2n 262244
int c[maxn][maxn], out[maxn], n,
a[maxn][pow2n], sol[maxn],
p[maxn][maxw], f[maxn][pow2n];
char w[maxn][maxw];
void readf()
{
freopen(_fin, "r", stdin);
scanf("%d\n", &n);
for (int i=1; i<=n; i++)
scanf("%s\n", w[i]+1), w[i][0]='0';
// memmove(w[i]+1, w[i], sizeof(w[i])), w[i][0]='0';
}
int kmp(int a, int b, int &match)
{
int k=0, i, to=strlen(w[a]);
for (i=1; i<to; i++)
{
while ( k>0 && w[b][k+1] != w[a][i] ) k=p[b][k];
k += ( w[b][k+1]==w[a][i] );
if ( k==strlen(w[b])-1 ) {
match=strlen(w[b])-1;
return 1;
}
}
match=k;
return 0;
}
void presolve()
{
// precalculate N and C
int i, j, k, foo, to;
// calculate pi for all
for (j=1; j<=n; j++)
for (i=2, k=0, to=strlen(w[j]); i<to; i++)
{
while ( k>0 && w[j][k+1] != w[j][i] ) k=p[j][k];
k += ( w[j][k+1]==w[j][i] );
p[j][i]=k;
}
// first, take out all words that we don't need
for (i=1; i<=n; i++)
for (j=1; j<=n; j++)
{
if ( i==j ) continue;
if ( kmp(i, j, foo) )
out[j]=1;
}
for (i=n; i>=1; i--)
if ( out[i] )
memcpy(w[i], w[n], sizeof(w[n])), n--;
for (i=1; i<=n; i++)
for (j=1; j<=n; j++)
{
if ( i==j ) continue;
kmp(i, j, c[i][j]);
}
}
void solve()
{
int i, j, k, l, to=(1<<n)-1, pw;
memset(a, 0xff, sizeof(a));
for (i=1; i<=n; i++) a[i][1<<(i-1)]=0;
for (i=3; i<=to; i++)
for (j=1, pw=1; j<=n; j++, pw<<=1)
{
if ( !(i & pw) ) continue;
for (k=1; k<=n; k++)
if ( i & (1<<(k-1)) )
if ( c[j][k] + a[k][ i ^ pw ] > a[j][i] )
a[j][i] = c[j][k] + a[k][i^pw], f[j][i]=k;
}
int max=1;
for (i=2; i<=n; i++)
if ( a[i][to] > a[max][to] ) max=i;
for (i=max, j=to; f[i][j] && sol[0] < n; k=i, i=f[i][j], j^=(1<<(k-1)))
sol[ ++sol[0] ] = i;
sol[ ++sol[0] ] = i;
}
void writef()
{
freopen(_fout, "w", stdout);
int i;
for (printf("%s", w[sol[1]]+1), i=2; i<=sol[0]; i++)
printf("%s", w[sol[i]] + c[sol[i-1]][sol[i]]+1);
printf("\n");
}
int main()
{
readf();
presolve();
solve();
writef();
return 0;
}