#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MN (20)
#define ML (30009)
#define MCFG (262144)
char sraw[MN][ML];
int svalid[MN], sprefix[MN][ML], prefix[ML], slen[MN];
int graw[MN][MN], g[MN][MN], s[MN];
int N, newN;
int _c[MN][MCFG], _prev[MN][MCFG];
int cmax, start;
int c(int start, int cfg)
{
if(_c[start][cfg] != -1)
return _c[start][cfg];
int i, tmp;
for(i = 0; (1 << i) <= cfg; ++ i) if(cfg&(1 << i) && i-start) {
tmp = c(i, cfg-(1 << start));
tmp += g[start][i];
if(tmp > _c[start][cfg]) {
_c[start][cfg] = tmp;
_prev[start][cfg] = i;
}
}
return _c[start][cfg];
}
void gen_prefix(int *p, char *s)
{
int i, k;
memset(p, 0, sizeof(p));
-- s;
for(k = 0, i = 2; isalpha(s[i]); p[i ++] = k) {
for(; k && s[k+1] != s[i]; k = p[k]);
k += s[k+1] == s[i];
}
}
void kmp(int *out, char *h, char *n, int *p) // h = haystack, n = needle, p[i] = prefix(n[i])
{
int i, k;
memset(out, 0, sizeof(out));
-- h; -- n;
for(k = 0, i = 1; isalpha(h[i]); out[i ++] = k) {
for(; k && n[k+1] != h[i]; k = p[k]);
k += n[k+1] == h[i];
}
}
int main()
{
int i, j, k;
freopen("adn.in", "r", stdin);
scanf("%d", &N);
for(i = 0; i < N; ++ i)
scanf("%s", sraw[i]);
fclose(stdin);
// Generate prefixes
for(i = 0; i < N; ++ i) {
slen[i] = strlen(sraw[i]);
gen_prefix(sprefix[i], sraw[i]);
}
/*
// Print prefixes
for(i = 0; i < N; ++ i) {
for(j = 0; j < slen[i]; ++ j)
printf("%c ", sraw[i][j]);
printf("\n");
for(j = 1; j <= slen[i]; ++ j)
printf("%d ", sprefix[i][j]);
printf("\n");
}
*/
// Remove inclusions && calc edge weights
memset(svalid, 0x3f, sizeof(svalid));
for(i = 0; i < N; ++ i)
for(j = 0; svalid[i] && j < N; ++ j) if(j-i && svalid[j]) {
kmp(prefix, sraw[j], sraw[i], sprefix[i]);
/*
for(printf("Test %d %d: ", i, j), k = 1; k <= slen[j]; ++ k)
printf(" %d", prefix[k]); printf("\n");
*/
for(k = 1; k <= slen[j]; ++ k) if(prefix[k] == slen[i])
break;
if(k <= slen[j])
svalid[i] = 0;
graw[j][i] = prefix[slen[j]];
}
/*
for(printf("svalid[] ="), i = 0; i < N; ++ i)
printf(" %d", svalid[i]); printf("\n");
*/
for(i = 0, newN = 0; i < N; ++ i) if(svalid[i])
s[newN ++] = i;
N = newN;
for(i = 0; i < N; ++ i) {
for(j = 0; j < N; ++ j) {
g[i][j] = (i-j)? graw[s[i]][s[j]] : 0;
//printf("%d ", g[i][j]);
}
//printf("\n");
}
memset(_c, -1, sizeof(_c));
memset(_prev, -1, sizeof(_prev));
for(i = 0; i < N; ++ i)
_c[i][1 << i] = 0;
cmax = 0;
for(i = 0; i < N; ++ i) if(c(i, (1 << N)-1) > cmax)
cmax = c(i, (1 << N)-1), start= i;
//printf("%d %d\n", cmax, start);
freopen("adn.out", "w", stdout);
int p = 0, cfg = (1 << N)-1;
for(; cfg; start = i, cfg = j) {
for(i = p; i < slen[s[start]]; ++ i)
printf("%c", sraw[s[start]][i]);
p = g[start][_prev[start][cfg]];
i = _prev[start][cfg];
j = cfg-(1 << start);
}
printf("\n");
fclose(stdout);
return 0;
}