#include <fstream>
#pragma GCC optimize("O3,unroll-loops")
#include <algorithm>
#include <cstring>
#include <climits>
#include <iomanip>
#include <numeric>
#include <bitset>
#include <string>
#include <vector>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#define int long long
//#define int short
using namespace std;
ifstream cin("adn.in");
ofstream cout("adn.out");
const int nmax = 18;
const int lenmax = 3e4;
int n, scor[nmax + 5][nmax + 5], pi[2 * lenmax + 5], dp[nmax + 5][(1 << nmax) + 5];
string v[nmax + 5];
int calculatescor(int x, int y){
string a = v[y] + "#" + v[x];
for (int i = 1; i < a.size(); i++){
int j = pi[i - 1];
while (j && a[i] != a[j]){
j = pi[j - 1];
}
if (a[i] == a[j]){
j++;
}
pi[i] = j;
}
return pi[a.size() - 1];
}
void fastio(){
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
}
void handleinput(){
cin>>n;
for (int i = 0; i < n; i++){
cin>>v[i];
}
}
void setup(){
for (int i = 0; i < n; i++){
for (int j = 0; j < n; j++){
scor[i][j] = calculatescor(i, j);
}
}
int cnt = 0;
for (int i = 0; i < n; i++){
for (int j = 0; j < n; j++){
if (i != j && v[j].find(v[i]) != string::npos){
v[i] = " ";
break;
}
}
}
for (int i = 0; i < n - cnt; i++){
while (i + cnt < n && v[i + cnt] == " "){
cnt++;
}
if (i + cnt == n){
break;
}
if (v[i + cnt] != " "){
v[i] = v[i + cnt];
}
}
n -= cnt;
for (int i = 0; i < n; i++){
for (int j = 0; j < n; j++){
scor[i][j] = calculatescor(i, j);
}
}
for (int mask = 0; mask < (1 << n); mask++){
for (int i = 0; i < n; i++){
dp[i][mask] = 1e9;
}
}
for (int i = 0; i < n; i++){
dp[i][(1 << i)] = v[i].size();
}
for (int mask = 1; mask < (1 << n); mask++){
for (int i = 0; i < n; i++){
if (!(mask & (1 << i))){
continue;
}
for (int j = 0; j < n; j++){
if (!(mask & (1 << j))){
dp[j][mask ^ (1 << j)] = min(dp[j][mask ^ (1 << j)], dp[i][mask] + (int)v[j].size() - scor[i][j]);
}
}
}
}
}
string buildanswer(){
int last = 0, mask = (1 << n) - 1;
for (int i = 0; i < n; i++){
//cout<<dp[i][mask]<<" ";
if (dp[last][mask] > dp[i][mask]){
last = i;
}
}
string rez;
while (__builtin_popcount(mask) > 1){
for (int i = 0; i < n; i++){
if (!(mask & (1 << i)) || i == last){
continue;
}
int newmask = mask ^ (1 << last);
int cur = dp[last][mask];
int cont = dp[i][newmask] + v[last].size() - scor[i][last];
if (cont == cur && cur){
rez = v[last].substr(scor[i][last]) + rez;
mask = newmask;
last = i;
break;
}
}
}
return v[last] + rez;
}
void handleoutput(){
cout<<buildanswer();
}
signed main(){
fastio();
handleinput();
setup();
handleoutput();
}
/*
*/