#include <bits/stdc++.h>

#define F first
#define S second
#define ll long long
#define ull unsigned long long
#define pb push_back

using namespace std;
int a[200], b[200], c[200], d[200], n;
void dfs(int v)
{
    char p = v + 'a';
    cout << p;
    if (c[v]) dfs(a[v]);
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> n;
    for (int i = 0; i < n; i++){
        string s;
        cin >> s;
        for (int j = 1; j < s.length(); j++){
            a[s[j - 1] - 'a'] = s[j] - 'a';
            b[s[j] - 'a'] = 1;
            c[s[j - 1] - 'a'] = 1;
        }
        for (int j = 0; j < s.length(); j++)
            d[s[j] - 'a'] = 1;
    }
    for (int i = 0; i < 26; i++)
        if (b[i] == 0 && d[i]) dfs(i);
}


#include <bits/stdc++.h>

using namespace std;
#define set_precision(ans,l) cout << fixed << setprecision(l)<<ans;
#define rep(i, a, b) for (int i = a; i < b; i++)
#define repb(i, a, b) for (int i = a; i >= b; i--)
#define vi vector<int>
#define vl vector<long long int>
#define Vi vector<vector<int>>
#define vpi vector<pair<int,int>>
#define seti set<int>
#define setl set<ll>
#define dseti set<int, greater<int>>
#define dsetl set<ll, greater<ll>>
#define mseti multiset<int>
#define msetl multiset<ll>
#define dmseti multiset<int, greater<int>>
#define dmsetl multiset<ll, greater<ll>>
#define sortA(arr) sort(arr.begin(), arr.end())
#define dsortA(arr) sort(arr.begin(), arr.end(), greater<ll>())
#define ssort(arr) stable_sort(arr.begin(), arr.end())
#define nth(v,n) nth_element(v.begin,v.begin+n-1,v.end())
#define dnth(v,n) nth_element(v.begin,v.begin+n-1,v.end(), greater<ll>())
#define init(a)  memset((a),0,sizeof(a))
#define pi pair<int,int>
#define pb push_back
#define pl pair<ll,ll>
#define ll long long
#define FIO ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define mod 1000000007
long double EPS = 1e-9;

/*struct comp {
  bool operator() (const int& lhs, const int& rhs) const
  {return lhs<rhs;}
};*/

ll cel(ll a,ll b){return((a-1)/b+1);}
ll gcd(ll a, ll b){
    if (a < b)swap(a, b);
    return (b == 0)? a: gcd(b, a % b);
}
ll lcm(ll a,ll b){return (a*b)/gcd(a,b);}
ll po(ll x,ll y){
    ll ans=1;
    while(y){
        if(y&1){ans=(ans*x)%mod;}
        y>>=1;x=(x*x)%mod;
    }
    return ans;
}

int main()
{
    FIO;
    ll n,t,x,y,m,k;
    cin>>n;string s,ans;queue<int> q;
    vi par(26,-1),ch(26,-1),chk(26,0);
    rep(i,0,n){
        cin>>s;
        rep(i,0,s.size()-1){
            chk[s[i]-'a']=1;
            ch[s[i]-'a']=int(s[i+1]-'a');
        }
        chk[s[s.size()-1]-'a']=1;
        rep(i,1,s.size()){
            chk[s[i]-'a']=1;
            par[s[i]-'a']=int(s[i-1]-'a');
        }
    }
    rep(i,0,26){
        //cout<<chk[i]<<" "<<par[i]<<" ";
        if(chk[i]&&(par[i]==-1)){q.push(i);}
    }
    //cout<<q.size()<<" ";
    char c;
    while(!q.empty()){
        x=q.front();q.pop();
        c='a'+x;ans.pb(c);
        y=ch[x];
        while(y!=-1){
            c='a'+y;ans.pb(c);
            y=ch[y];
        }
    }
    cout<<ans;
    return 0;
}


/* -*- coding: utf-8 -*-
 *
 * 0638B.cc: B. Making Genome in Berland
 */

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>

using namespace std;

/* constant */

/* typedef */

/* global variables */

char s[32];
bool used[26];
int ps[26], qs[26];

/* subroutines */

/* main */

int main() {
  //freopen("input.txt", "r", stdin);
  //freopen("output.txt", "w", stdout);

  int n;
  scanf("%d", &n);

  memset(ps, -1, sizeof(ps));
  memset(qs, -1, sizeof(qs));

  for (int i = 0; i < n; i++) {
    scanf("%s", s);
    int l = strlen(s);
    for (int j = 0; j < l; j++) {
      int sj = s[j] - 'a';
      used[sj] = true;
      if (j > 0) ps[sj] = s[j - 1] - 'a';
      if (j + 1 < l) qs[sj] = s[j + 1] - 'a';
    }
  }

  for (int i = 0; i < 26; i++)
    if (used[i] && ps[i] < 0)
      for (int j = i; j >= 0; j = qs[j]) putchar(j + 'a');
  putchar('\n');

  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define MOD 1000000007
int nxt[26],pre[26];
bool visited[26];
set<int> v;
int main()
{
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    int n,i;
    for(i=0;i<26;i++)
        pre[i]=nxt[i]=-1;
    string s,res="";
    cin>>n;
    while(n--)
    {
        cin>>s;
        for(i=0;s[i];i++)
        {
            v.insert(s[i]-'a');
            if(s[i+1])
                nxt[s[i]-'a']=s[i+1]-'a';
            if(i>0)
                pre[s[i]-'a']=s[i-1]-'a';
        }
    }
    for(auto it=v.begin();it!=v.end();it++)
        if(!visited[*it])
    {
        for(i=*it;pre[i]!=-1;i=pre[i]);
        for(;i!=-1;i=nxt[i])
        {
            visited[i]=true;
            res.push_back((char)(i+'a'));
        }
    }
    cout<<res;
    return 0;
}


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

bool vis[30];
int in[30];
bool taken[30];
vector<int> g[30];
string ans;

void dfs(int r){
     taken[r]=true;
     ans = ans + (char)(r+'a');
     for(int i=0;i<g[r].size();i++){
          if(!taken[g[r][i]]){
               dfs(g[r][i]);
          }
     }
}

int main(){
     int n;
     cin>>n;
     for(int i=0;i<n;i++){
          string s;
          cin>>s;
          vis[s[0]-'a']=true;
          for(int i=0;i<s.size()-1;i++){
               g[s[i]-'a'].push_back(s[i+1]-'a');
               in[s[i+1]-'a']++;
          }
     }

     for(int i=0;i<26;i++){
          if(vis[i] and in[i]==0){
               dfs(i);
          }
     }

     cout<<ans;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long int
ll n, m, k ; ll ls, rs ;

int abc[26];int def[26];
int main()
{
cin>>n ;
string t ;
memset(abc,-1,sizeof(abc));memset(def,-1,sizeof(def));
for(int i = 0 ; i<n ; i++)
{
	cin>>t ;
	for(int j = 0 ; j<t.size()-1; j++)
	{
		char c = t[j];
		abc[int(c-'a')]= int(t[j+1]-'a');
		def[int(t[j+1]-'a')]= 1 ;
	}

	if(def[int(t[0]-'a')]==-1)
	def[int(t[0]-'a')]= 2;

}
int st =0  ;
for(int i = 0;i<26; i++)
{
if(def[i]==2)
{
st = i;
cout<<char(st+'a');
while(abc[st]!=-1)
{
	st = abc[st];
	cout<<char(st+'a');
}

}

}

return(0);
}


    #include <bits/stdc++.h>
    //#define M_PI 3.14159265358979323846

using namespace std;

#define rep(i,a,b) for(int i=a;i<b;++i)
#define repb(i,a,b) for(int i=a;i>=b;--i)
#define vi vector<int>
#define vb vector<bool>
#define vs vector<string>
#define vl vector<long long int>
#define vc vector<char>
#define vld vector<ld>
#define vvi vector<vector<int> >
#define vvl vector<vector<long long> >
#define vvld vector<vector<ld> >
#define vpii vector<pii>
#define vpll vector<pll>
#define ld long double
#define ll long long
#define sz(a) (ll)a.size()
#define ssortA(arr)   stable_sort(arr.begin(),arr.end())
#define ssortB(arr)   stable_sort(arr.begin(),arr.end(),greater<ll >());
#define pii pair<int,int>
#define pll pair<long long,long long>
#define ff first
#define ss second
#define search(arr,c)  binary_search(arr.begin(),arr.end(),c)
#define pb   push_back
#define pf push_front
#define mp make_pair
#define lb lower_bound
#define ub upper_bound
#define endl "\n"
#define PI acos(-1.0)
#define GCD(a,b) __gcd(a,b)
#define popcount(x) __builtin_popcountll(x)
#define IOS ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define r1(x) cin>>x
#define r2(x,y) cin>>x>>y
#define r3(x,y,z) cin>>x>>y>>z
#define r4(a,b,c,d) cin>>a>>b>>c>>d
#define d1(x) cout<<(x)<<" "
#define d2(x,y) cout<<(x)<<" "<<(y)<<endl
#define d3(x,y,z) cout<<(x)<<" "<<(y)<<" "<<(z)<<endl
#define d4(a,b,c,d) cout<<(a)<<" "<<(b)<<" "<<(c)<<" "<<(d)<<endl
#define fix(f,n) fixed<<setprecision(n)<<f<<endl
#define check(ds, a) (ds.find(a)!=ds.end()?1:0)
int main()
{
    int n;cin>>n;
    vi nxt(26,-1);
    vi flag(26,0);
    vi out(26,0);vi in(26,0);
    rep(i,0,n){
        string s;cin>>s;
        flag[s[0]-'a']=1;
        rep(i,0,sz(s)-1){
            out[s[i]-'a']=1;
            in[s[i+1]-'a']=1;
            flag[s[i+1]-'a']=1;
            nxt[s[i]-'a']=s[i+1]-'a';
        }
    }
    vi arr1,arr2;
    string res;
    rep(i,0,26){
        if(out[i]==1&&in[i]==0&&flag[i])arr1.pb(i);
        if(out[i]==0&&in[i]==0&&flag[i])arr2.pb(i);
    }
    rep(i,0,sz(arr1)){
        int j=arr1[i];
        while(1){
            res.pb(char(j+'a'));
            if(out[j]==0)break;
            j=nxt[j];
        }
    }
    rep(i,0,sz(arr2)){
        res.pb(char(arr2[i]+'a'));
    }
    cout<<res<<endl;
}


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
typedef long long LL;
const int MaxN = 3e5 + 5;

int vis[50];
vector<int> G[50];

void dfs(int x) {
	vis[x] = 2; // 表示字符x已经用过
	cout << (char)('a' + x);
	for(int i = 0; i < G[x].size(); i++) {
		int u = G[x][i];
		if(vis[u] != 2) {
			dfs(u);
		}
	}
}

int main()
{
	int n; cin >> n;
	for(int i = 1; i <= n; i++) {
		string s; cin >> s;
		for(int j = 1; j < s.size(); j++) {
			vis[s[j]-'a'] = 1;
			G[s[j-1]-'a'].push_back(s[j] - 'a'); //如果这个字符在 子串的非第一个字符的位置上 出现过就打上标记，说明不是要寻找的无前驱结点
		}
		if(!vis[s[0]-'a']) vis[s[0]-'a'] = 6; //用来寻找无前驱结点
	}
	for(int i = 0; i < 26; i++) {
		if(vis[i] == 6) dfs(i); //如果当前结点没有前驱
	}
	cout << endl;
    return 0;
}
————————————————
版权声明：本文为CSDN博主「千与千寻之前」的原创文章，遵循 CC 4.0 BY-SA 版权协议，转载请附上原文出处链接及本声明。
原文链接：https://ceshi22222.blog.csdn.net/article/details/88739281


#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<string>
#include<iostream>
#include<queue>
#include<stack>
#include<limits.h>
#include<map>
#include<vector>
#include<set>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define mid (L+R)/2
#define lson rt*2,L,mid
#define rson rt*2+1,mid+1,R
const int mod = 1e9+7;
const int maxn = 1e2+200;
//const LL INF = 0x3f3f3f3f3f3f3f3f;
const int INF = 0x3f3f3f3f;
int vis[30];
string s;
int ind[maxn];
vector<int>G[maxn];
void dfs(int u){
    vis[u] = 2;
    s += u + 'a';
    for(int i = 0; i < G[u].size(); i++){
        int& v = G[u][i];
        if(vis[v] != 2){
            dfs(v);
        }
    }
}
int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        for(int i = 1; i <= n; i++){
            cin>>s;
            for(int j = 0; j < s.size()-1; j++){
                G[s[j]-'a'].push_back(s[j+1]-'a');
                vis[s[j+1]-'a'] = 3;
            }
            if(vis[s[0]-'a'] != 3){
                vis[s[0]-'a'] = 1;
            }
        }
        s = "";
        for(int i = 0; i < 26; i++){
            if(vis[i] == 1){
                dfs(i);
            }
        }
        cout<<s<<endl;
    }
    return 0;
}


import java.io.*;

public class VK2016_Qualification2_B {
    public static void main(String []args) throws IOException {
        new Solution().solve();
    }
}

class Solution {
    FastReader fr = new FastReader();
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

    int count;
    String []data;
    boolean []visited;

    public void solve() throws IOException {
        count = fr.nextInt();
        data = new String[count];
        visited = new boolean[count];

        for (int i = 0; i < count; i++) {
            data[i] = fr.nextString();
        }

        String result = "";
        for (int i = 0; i < count; i++) {
            if (!visited[i]) {
                visited[i] = true;
                String resultPart = solvePart(data[i]);
                result += resultPart;
            }
        }
        System.out.println(result);
    }

    public String solvePart(String result) {
        for (int i = 0; i < count; i++) {
            if (!visited[i]) {
                char a = result.charAt(0);
                char b = result.charAt(result.length()-1);
                char c = data[i].charAt(0);
                char d = data[i].charAt(data[i].length()-1);

                int aInd = data[i].indexOf(a);

                int bInd = data[i].indexOf(b);
                int cInd = result.indexOf(c);
                int dInd = result.indexOf(d);

                if (aInd >= 0 || bInd >= 0 || cInd >= 0) {
                    visited[i] = true;
                    if (aInd >= 0 && bInd >= 0) {
                        result = data[i];
                    } else if (aInd >= 0 && dInd >= 0) {
                        result = data[i].substring(0, aInd) + result;
                    } else if (bInd >= 0 && cInd >= 0) {
                        result = result + data[i].substring(bInd+1);
                    } else if (cInd >= 0 && dInd >= 0) {
                        //result = resul;
                    }
                    result = solvePart(result);
                }

            }
        }

        return result;
    }

}

class FastReader {
    private InputStream is;
    private int bufferSize = 1 << 17;
    private byte []buffer = new byte[bufferSize];
    private int currentIndex = 0;
    private int lastIndex = 0;

    public FastReader() {
        is = new BufferedInputStream(System.in);
//		try {
//			is = new BufferedInputStream(new FileInputStream(new File("test.txt")));
//		} catch (FileNotFoundException e) {
//			e.printStackTrace();
//		}
    }

    public int nextInt() {
        int result = 0;
        int minus = 1;

        byte character = readNext();

        while (character == ' ' || character == '\n' || character == '\r') {
            character = readNext();
        }

        if (character == '-') {
            minus = -1;
            character = readNext();
        }

        while (character != ' ' && character != '\n' && character != '\r' && character != -1) {
            result = result * 10 + (character - '0');
            character = readNext();
        }

        return minus*result;
    }

    public long nextLong() {
        long result = 0;
        int minus = 1;

        byte character = readNext();

        while (character == ' ' || character == '\n' || character == '\r') {
            character = readNext();
        }

        if (character == '-') {
            minus = -1;
            character = readNext();
        }

        while (character != ' ' && character != '\n' && character != '\r' && character != -1) {
            result = result * 10 + (character - '0');
            character = readNext();
        }

        return minus*result;
    }

    public String nextString() {
        StringBuffer result = new StringBuffer();

        byte character = readNext();

        while (character == ' ' || character == '\n' || character == '\r') {
            character = readNext();
        }

        while (character != ' ' && character != '\n' && character != '\r' && character != -1) {
            result.append((char)character);
            character = readNext();
        }

        return result.toString();
    }

    public String nextLine() {
        StringBuffer result = new StringBuffer();

        byte character = readNext();

        while (character == '\n' || character == '\r') {
            character = readNext();
        }

        while (character != '\n' && character != '\r' && character != -1) {
            result.append((char)character);
            character = readNext();
        }

        return result.toString();
    }

    private byte readNext() {
        if (currentIndex == lastIndex) {
            try {
                lastIndex = is.read(buffer, 0, bufferSize);
            } catch (IOException e) {
                throw new RuntimeException("What?");
            }
            if (lastIndex == -1) {
                buffer[0] = -1;
            }
            currentIndex = 0;
        }

        return buffer[currentIndex++];
    }
}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class B {

    void solve() throws IOException {
        int n=nextInt();
        String[] s=new String[n];
        for(int i=0;i<n;i++)s[i]=nextToken();
        boolean[] used=new boolean[n];
        for(int i=0;i<n;i++)
            if(!used[i]){
                boolean doWork=true;
                while(doWork) {
                    doWork=false;
                    for (int j = i + 1; j < n; j++)
                        if (!used[j]) {
                            if(s[j].indexOf(s[i])!=-1){
                                s[i]=s[j];
                                used[j]=true;
                                doWork=true;
                                continue;
                            }
                            int ind = s[i].indexOf(s[j].charAt(0));
                            if (ind != -1) {
                                int count = s[i].length() - ind;
                                if (count < s[j].length()) {
                                    s[i] = s[i] + s[j].substring(count);
                                }
                                doWork=true;
                                used[j] = true;
                            } else {
                                ind = s[i].indexOf(s[j].charAt(s[j].length() - 1));
                                if (ind != -1) {
                                    if (s[j].length() > ind + 1) {
                                        s[i] = s[j] + s[i].substring(ind + 1);
                                        doWork=true;
                                        used[j] = true;
                                    }
                                }
                            }
                        }
                }
            }
        String result="";
        for(int i=0;i<n;i++)if(!used[i])result+=s[i];
        out.println(result);
    }

    public static void main(String[] args) throws IOException {
        new B().run();
    }

    void run() throws IOException {
        reader = new BufferedReader(new InputStreamReader(System.in));
//		reader = new BufferedReader(new FileReader("input.txt"));
        tokenizer = null;
        out = new PrintWriter(new OutputStreamWriter(System.out));
//		out = new PrintWriter(new FileWriter("output.txt"));
        solve();
        reader.close();
        out.flush();

    }

    BufferedReader reader;
    StringTokenizer tokenizer;
    PrintWriter out;

    int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    String nextToken() throws IOException {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            tokenizer = new StringTokenizer(reader.readLine());
        }
        return tokenizer.nextToken();
    }
}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class B {

    void solve() throws IOException {
        int n=nextInt();
        String[] s=new String[n];
        for(int i=0;i<n;i++)s[i]=nextToken();
        boolean[] used=new boolean[n];
        for(int i=0;i<n;i++)
            if(!used[i]){
                for(int j=i+1;j<n;j++)
                    if(!used[j]){
                        int ind=s[i].indexOf(s[j].charAt(0));
                        if(ind!=-1){
                            int count=s[i].length()-ind;
                            if(count<s[j].length()){
                                s[i]=s[i]+s[j].substring(count);
                            }
                            used[j]=true;
                        }
                        else{
                            ind=s[i].indexOf(s[j].charAt(s[j].length()-1));
                            if(ind!=-1){
                                if(s[j].length()>ind+1){
                                    s[i]=s[j]+s[i].substring(ind+1);
                                    used[j]=true;
                                }
                            }
                        }
                    }
            }
        String result="";
        for(int i=0;i<n;i++)if(!used[i])result+=s[i];
        out.println(result);
    }

    public static void main(String[] args) throws IOException {
        new B().run();
    }

    void run() throws IOException {
        reader = new BufferedReader(new InputStreamReader(System.in));
//		reader = new BufferedReader(new FileReader("input.txt"));
        tokenizer = null;
        out = new PrintWriter(new OutputStreamWriter(System.out));
//		out = new PrintWriter(new FileWriter("output.txt"));
        solve();
        reader.close();
        out.flush();

    }

    BufferedReader reader;
    StringTokenizer tokenizer;
    PrintWriter out;

    int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    String nextToken() throws IOException {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            tokenizer = new StringTokenizer(reader.readLine());
        }
        return tokenizer.nextToken();
    }
}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class B {

    void solve() throws IOException {
        int n=nextInt();
        String[] s=new String[n];
        for(int i=0;i<n;i++)s[i]=nextToken();
        boolean[] used=new boolean[n];
        for(int i=0;i<n;i++)
            if(!used[i]){
                boolean doWork=true;
                while(doWork) {
                    doWork=false;
                    for (int j = i + 1; j < n; j++)
                        if (!used[j]) {
                            int ind = s[i].indexOf(s[j].charAt(0));
                            if (ind != -1) {
                                int count = s[i].length() - ind;
                                if (count < s[j].length()) {
                                    s[i] = s[i] + s[j].substring(count);
                                }
                                doWork=true;
                                used[j] = true;
                            } else {
                                ind = s[i].indexOf(s[j].charAt(s[j].length() - 1));
                                if (ind != -1) {
                                    if (s[j].length() > ind + 1) {
                                        s[i] = s[j] + s[i].substring(ind + 1);
                                        doWork=true;
                                        used[j] = true;
                                    }
                                }
                            }
                        }
                }
            }
        String result="";
        for(int i=0;i<n;i++)if(!used[i])result+=s[i];
        out.println(result);
    }

    public static void main(String[] args) throws IOException {
        new B().run();
    }

    void run() throws IOException {
        reader = new BufferedReader(new InputStreamReader(System.in));
//		reader = new BufferedReader(new FileReader("input.txt"));
        tokenizer = null;
        out = new PrintWriter(new OutputStreamWriter(System.out));
//		out = new PrintWriter(new FileWriter("output.txt"));
        solve();
        reader.close();
        out.flush();

    }

    BufferedReader reader;
    StringTokenizer tokenizer;
    PrintWriter out;

    int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    String nextToken() throws IOException {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            tokenizer = new StringTokenizer(reader.readLine());
        }
        return tokenizer.nextToken();
    }
}


import java.util.Scanner;

public class VK20162 {

	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);

		int n = sc.nextInt();

		int a = (int)'a';
		int[] word = new int[26];
		for(int i=0; i<26; ++i)
			word[i] = -10;
		int[] start = new int[26];
		String s;
		char[] array;
		int len;
		int last;
		for(int i=0; i<n; ++i){
			s = sc.next();
			array = s.toCharArray();
			len = s.length();

			last = (int)(array[0] - a);
			if(word[last] == -10 )
				start[last] = -1;
			for(int k = 1 ; k < len ; ++k){
				word[last] = (int)(array[k] - a);
				last = (int)(array[k] - a);
				start[last] = 1;
				word[last] = -9;
			}
		}

		for(int i=0; i< 26; ++i){
			if(start[i] == -1){
				last = i;
				while(true){
					System.out.print((char)(last+a));
					last = word[last];
					if(last == -10 || last == -9){
						break;
					}
				}
			}
		}

	}

}


import java.util.Scanner;

public class VK20162 {

	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);

		int n = sc.nextInt();

		int a = (int)'a';
		int[] word = new int[26];
		int[] start = new int[26];
		String s;
		char[] array;
		int len;
		int last;
		for(int i=0; i<n; ++i){
			s = sc.next();
			array = s.toCharArray();
			len = s.length();

			last = (int)(array[0] - a);
			if(word[last] == 0 )
				start[last] = -1;
			for(int k = 1 ; k < len ; ++k){
				word[last] = (int)(array[k] - a);
				last = (int)(array[k] - a);
				start[last] = 1;
			}
		}

		for(int i=0; i< 26; ++i){
			if(start[i] == -1){
				last = i;
				while(true){
					System.out.print((char)(last+a));
					last = word[last];
					if(last == 0){
						break;
					}
				}
			}
		}

	}

}


import java.util.Scanner;

public class VK20162 {

	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);

		int n = sc.nextInt();

		int a = (int)'a';
		int[] word = new int[26];
		for(int i=0; i<26; ++i)
			word[i] = -10;
		int[] start = new int[26];
		String s;
		char[] array;
		int len;
		int last;
		for(int i=0; i<n; ++i){
			s = sc.next();
			array = s.toCharArray();
			len = s.length();

			last = (int)(array[0] - a);
			if(word[last] == -10 )
				start[last] = -1;
			for(int k = 1 ; k < len ; ++k){
				word[last] = (int)(array[k] - a);
				last = (int)(array[k] - a);
				start[last] = 1;
			}
		}

		for(int i=0; i< 26; ++i){
			if(start[i] == -1){
				last = i;
				while(true){
					System.out.print((char)(last+a));
					last = word[last];
					if(last == -10){
						break;
					}
				}
			}
		}

	}

}


import java.util.Scanner;

public class VK20162 {

	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);

		int n = sc.nextInt();

		int a = (int)'a';
		int[] word = new int[26];
		for(int i=0; i<26; ++i)
			word[i] = -10;
		int[] start = new int[26];
		String s;
		char[] array;
		int len;
		int last;
		for(int i=0; i<n; ++i){
			s = sc.next();
			array = s.toCharArray();
			len = s.length();

			last = (int)(array[0] - a);
			if(word[last] == -10   )
				start[last] = -1;

			for(int k = 1 ; k < len ; ++k){
				word[last] = (int)(array[k] - a);
				last = (int)(array[k] - a);
				start[last] = 1;
				if(word[last] == -10)
				word[last] = -9;
			}
		}

		for(int i=0; i< 26; ++i){
			if(start[i] == -1){
				last = i;
				while(true){
					System.out.print((char)(last+a));
					last = word[last];
					if(last == -10 || last == -9){
						break;
					}
				}
			}
		}

	}

}


import java.util.Arrays;
import java.util.Scanner;

public class CF638B{
    static int toInt(char x){
        return x-'a';
    }

    public static void main(String[] args){
        Scanner scn = new Scanner(System.in);
        while (scn.hasNext()){
            int n = scn.nextInt();
            scn.nextLine();
            String[] allS = new String[n];
            boolean[] head = new boolean[26];
            boolean[] appears = new boolean[26];
            char[] next = new char[26];
            Arrays.fill(head, true);
            Arrays.fill(appears, false);
            Arrays.fill(next, '\0');
            for (int i=0; i<n; i++){
                allS[i] = scn.nextLine();
                for (int j=0; j<allS[i].length(); j++){
                    appears[toInt(allS[i].charAt(j))] = true;
                    if (j>0){
                        head[toInt(allS[i].charAt(j))] = false;
                    }
                    if (j+1<allS[i].length()){
                        next[toInt(allS[i].charAt(j))] = allS[i].charAt(j+1);
                    }
                }
            }
            StringBuilder sb = new StringBuilder("");
            for (int i=0; i<26; i++){
                if (appears[i]&&head[i]){
                    char x = (char)(i+'a');
                    while (true){
                        sb.append(x);
                        if (next[toInt(x)]=='\0'){
                            break;
                        } else {
                            x = next[toInt(x)];
                        }
                    }
                }
            }
            System.out.println(sb.toString());
        }
    }
}


import java.io.*;
import java.util.*;
public final class making_genome
{
    static FastScanner sc=new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter out=new PrintWriter(System.out);

	static boolean issubString(char[] a,char[] b)
	{
		for(int i=0;i<b.length;i++)
		{
			for(int j=0;j<a.length && i+j<b.length;j++)
			{
				if(a[j]!=b[i+j])
				{
					break;
				}
				if(j==a.length-1)
				{
					return true;
				}
			}
		}
		return false;
	}

	static boolean isSuffix(String s1,String s2)
	{
		char[] a=s2.toCharArray(),b=s1.toCharArray();
		if(issubString(a,b))
		{
			return false;
		}
		boolean curr=false;
		for(int i=a.length-1;i>=0;i--)
		{
			if(a[i]==b[0])
			{
				curr=true;
				int j,k;
				for(j=i,k=0;j<a.length && k<b.length;j++,k++)
				{
					if(a[j]!=b[k])
					{
						return false;
					}
				}
				break;
			}
		}
		if(curr)
		{
			return true;
		}
		return false;
	}

	static void combine(StringBuffer res,String s1)
	{
		int last=res.length()-1;
		for(int i=0;i<s1.length();i++)
		{
			if(s1.charAt(i)==res.charAt(last))
			{
				res.append(s1.substring(i+1,s1.length()));
				break;
			}
		}
	}

	public static void main(String args[]) throws Exception
	{
		int n=sc.nextInt(),last=0,prev=0;
		String[] a=new String[n];
		HashSet<String> s1=new HashSet<String>();
		for(int i=0;i<n;i++)
		{
			String nxt=sc.next();
			s1.add(nxt);
			if(s1.size()!=prev)
			{
				prev++;
				a[last++]=nxt;
			}
		}
		StringBuffer res=new StringBuffer("");
		boolean[] v=new boolean[n];
		for(int i=0;i<last;i++)
		{
			if(!v[i])
			{
				boolean curr=true;
				for(int j=0;j<last;j++)
				{
					if(i!=j && !v[j])
					{
						if(isSuffix(a[i],a[j]))
						{
							//out.println(a[i]+" "+a[j]);
							curr=false;
							break;
						}
					}
				}
				if(curr)
				{
					res.append(a[i]);
					v[i]=true;
					for(int k=0;k<last;k++)
					{
						if(!v[k] && isSuffix(a[k],res.toString()))
						{
							combine(res,a[k]);
							//out.println(res);
							v[k]=true;
							k=-1;
						}
					}
				}
			}
		}
		out.println(res);
		out.close();
	}
}
class FastScanner
{
    BufferedReader in;
    StringTokenizer st;

    public FastScanner(BufferedReader in) {
        this.in = in;
    }

    public String nextToken() throws Exception {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken();
    }

	public String next() throws Exception {
		return nextToken().toString();
	}

    public int nextInt() throws Exception {
        return Integer.parseInt(nextToken());
    }

    public long nextLong() throws Exception {
        return Long.parseLong(nextToken());
    }

    public double nextDouble() throws Exception {
        return Double.parseDouble(nextToken());
    }
}


import java.io.*;
import java.util.*;
public final class road_improvement
{
    static FastScanner sc=new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter out=new PrintWriter(System.out);
	static ArrayList<Integer> al[];
	static boolean[] used,v;
	static List<Integer> list=new ArrayList<Integer>();

	static void dfs(int u)
	{
		v[u]=true;
		for(int x:al[u])
		{
			if(!v[x])
			{
				dfs(x);
			}
		}
		list.add(u);
		used[u]=false;
	}

	@SuppressWarnings("unchecked")
	public static void main(String args[]) throws Exception
	{
		int n=sc.nextInt();
		al=new ArrayList[123];
		for(int i=97;i<=122;i++)
		{
			al[i]=new ArrayList<Integer>();
		}
		used=new boolean[123];v=new boolean[123];
		for(int i=0;i<n;i++)
		{
			char[] a=sc.next().toCharArray();
			for(int j=0;j<a.length;j++)
			{
				used[a[j]]=true;
				if(j<a.length-1)
				{
					al[a[j]].add((int)a[j+1]);
				}
			}
		}
		for(int i=97;i<=122;i++)
		{
			if(!v[i] && used[i] && al[i].size()>0)
			{
				dfs(i);
			}
		}
		for(int i=97;i<=122;i++)
		{
			if(used[i])
			{
				list.add(i);
			}
		}
		for(int i=list.size()-1;i>=0;i--)
		{
			int ch=list.get(i);
			out.print((char)ch);
		}
		out.close();
	}
}
class FastScanner
{
    BufferedReader in;
    StringTokenizer st;

    public FastScanner(BufferedReader in) {
        this.in = in;
    }

    public String nextToken() throws Exception {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken();
    }

	public String next() throws Exception {
		return nextToken().toString();
	}

    public int nextInt() throws Exception {
        return Integer.parseInt(nextToken());
    }

    public long nextLong() throws Exception {
        return Long.parseLong(nextToken());
    }

    public double nextDouble() throws Exception {
        return Double.parseDouble(nextToken());
    }
}


import java.io.*;
import java.util.*;
public final class making_genome
{
    static FastScanner sc=new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter out=new PrintWriter(System.out);

	static boolean issubString(char[] a,char[] b)
	{
		for(int i=0;i<b.length;i++)
		{
			for(int j=0;j<a.length && i+j<b.length;j++)
			{
				if(a[j]!=b[i+j])
				{
					break;
				}
				if(j==a.length-1)
				{
					return true;
				}
			}
		}
		return false;
	}

	static boolean isSuffix(String s1,String s2)
	{
		char[] a=s2.toCharArray(),b=s1.toCharArray();
		if(issubString(a,b))
		{
			return false;
		}
		boolean curr=false;
		for(int i=a.length-1;i>=0;i--)
		{
			if(a[i]==b[0])
			{
				curr=true;
				int j,k;
				for(j=i,k=0;j<a.length && k<b.length;j++,k++)
				{
					if(a[j]!=b[k])
					{
						return false;
					}
				}
				break;
			}
		}
		if(curr)
		{
			return true;
		}
		return false;
	}

	static void combine(StringBuffer res,String s1)
	{
		int last=res.length()-1;
		for(int i=0;i<s1.length();i++)
		{
			if(s1.charAt(i)==res.charAt(last))
			{
				res.append(s1.substring(i+1,s1.length()));
				break;
			}
		}
	}

	public static void main(String args[]) throws Exception
	{
		int n=sc.nextInt(),last=0,prev=0;
		String[] a=new String[n];
		HashSet<String> s1=new HashSet<String>();
		for(int i=0;i<n;i++)
		{
			String nxt=sc.next();
			s1.add(nxt);
			if(s1.size()!=prev)
			{
				prev++;
				a[last++]=nxt;
			}
		}
		StringBuffer res=new StringBuffer("");
		boolean[] v=new boolean[n];
		for(int i=0;i<last;i++)
		{
			if(!v[i])
			{
				boolean curr=true;
				for(int j=0;j<last;j++)
				{
					if(i!=j && !v[j])
					{
						if(isSuffix(a[i],a[j]))
						{
							//out.println(a[i]+" "+a[j]);
							curr=false;
							break;
						}
					}
				}
				if(curr)
				{
					res.append(a[i]);
					v[i]=true;
					for(int k=0;k<last;k++)
					{
						if(!v[k] && isSuffix(a[k],res.toString()))
						{
							combine(res,a[k]);
							v[k]=true;
							k=-1;
						}
					}
				}
			}
		}
		out.println(res);
		out.close();
	}
}
class FastScanner
{
    BufferedReader in;
    StringTokenizer st;

    public FastScanner(BufferedReader in) {
        this.in = in;
    }

    public String nextToken() throws Exception {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken();
    }

	public String next() throws Exception {
		return nextToken().toString();
	}

    public int nextInt() throws Exception {
        return Integer.parseInt(nextToken());
    }

    public long nextLong() throws Exception {
        return Long.parseLong(nextToken());
    }

    public double nextDouble() throws Exception {
        return Double.parseDouble(nextToken());
    }
}


import java.io.*;
import java.util.*;
public final class road_improvement
{
    static FastScanner sc=new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter out=new PrintWriter(System.out);
	static String s1="";
	static int[] used,prev;

	static void dfs(int idx)
	{
		if(prev[i]==0)
		{
			return;
		}
		else
		{
			dfs(prev[i]);
			s1=s1+(char)idx;
		}
	}

	public static void main(String args[]) throws Exception
	{
		int n=sc.nextInt();
		used=new int[123];prev=new int[123];
		for(int i=0;i<n;i++)
		{
			char[] a=sc.next().toCharArray();
			for(int j=0;j<a.length;j++)
			{
				used[a[j]]=true;
				if(j>0)
				{
					prev[a[j]]=a[j-1];
				}
			}
		}
		for(int i=97;i<123;i++)
		{
			if(prev[i]!=0)
			{
				dfs(i);
			}
		}
		for(int i=97;i<=122;i++)
		{
			if(used[i])
			{
				s1=s1+(char)i;
			}
		}
		out.println(s1);
		out.close();
	}
}
class FastScanner
{
    BufferedReader in;
    StringTokenizer st;

    public FastScanner(BufferedReader in) {
        this.in = in;
    }

    public String nextToken() throws Exception {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken();
    }

	public String next() throws Exception {
		return nextToken().toString();
	}

    public int nextInt() throws Exception {
        return Integer.parseInt(nextToken());
    }

    public long nextLong() throws Exception {
        return Long.parseLong(nextToken());
    }

    public double nextDouble() throws Exception {
        return Double.parseDouble(nextToken());
    }
}


import java.io.*;
import java.util.*;
public final class making_genome
{
    static FastScanner sc=new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter out=new PrintWriter(System.out);

	static boolean isSuffix(String s1,String s2)
	{
		char[] a=s2.toCharArray(),b=s1.toCharArray();
		boolean curr=false;
		for(int i=a.length-1;i>=0;i--)
		{
			if(a[i]==b[0])
			{
				curr=true;
				for(int j=i,k=0;j<a.length && k<b.length;j++,k++)
				{
					if(a[j]!=b[k])
					{
						return false;
					}
				}
				break;
			}
		}
		if(curr)
		{
			return true;
		}
		return false;
	}

	static void combine(StringBuffer res,String s1)
	{
		int last=res.length()-1;
		for(int i=0;i<s1.length();i++)
		{
			if(s1.charAt(i)==res.charAt(last))
			{
				res.append(s1.substring(i+1,s1.length()));
				break;
			}
		}
	}

	public static void main(String args[]) throws Exception
	{
		int n=sc.nextInt();
		String[] a=new String[n];
		for(int i=0;i<n;i++)
		{
			a[i]=sc.next();
		}
		StringBuffer res=new StringBuffer("");
		boolean[] v=new boolean[n];
		for(int i=0;i<n;i++)
		{
			if(!v[i])
			{
				boolean curr=true;
				for(int j=0;j<n;j++)
				{
					if(i!=j && !v[j])
					{
						if(isSuffix(a[i],a[j]))
						{
							curr=false;
							break;
						}
					}
				}
				if(curr)
				{
					res.append(a[i]);
					v[i]=true;
					for(int k=0;k<n;k++)
					{
						if(!v[k] && isSuffix(a[k],res.toString()))
						{
							combine(res,a[k]);
							v[k]=true;
							k=-1;
						}
					}
				}
			}
		}
		out.println(res);
		out.close();
	}
}
class FastScanner
{
    BufferedReader in;
    StringTokenizer st;

    public FastScanner(BufferedReader in) {
        this.in = in;
    }

    public String nextToken() throws Exception {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken();
    }

	public String next() throws Exception {
		return nextToken().toString();
	}

    public int nextInt() throws Exception {
        return Integer.parseInt(nextToken());
    }

    public long nextLong() throws Exception {
        return Long.parseLong(nextToken());
    }

    public double nextDouble() throws Exception {
        return Double.parseDouble(nextToken());
    }
}


import java.io.*;
import java.util.*;
public final class making_genome
{
    static FastScanner sc=new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter out=new PrintWriter(System.out);

	static boolean isSuffix(String s1,String s2)
	{
		char[] a=s2.toCharArray(),b=s1.toCharArray();
		boolean curr=false;
		for(int i=a.length-1;i>=0;i--)
		{
			if(a[i]==b[0])
			{
				curr=true;
				int j,k;
				for(j=i,k=0;j<a.length && k<b.length;j++,k++)
				{
					if(a[j]!=b[k])
					{
						return false;
					}
				}
				if(k<=b.length-1)
				{
					curr=false;
				}
				break;
			}
		}
		if(curr)
		{
			return true;
		}
		return false;
	}

	static void combine(StringBuffer res,String s1)
	{
		int last=res.length()-1;
		for(int i=0;i<s1.length();i++)
		{
			if(s1.charAt(i)==res.charAt(last))
			{
				res.append(s1.substring(i+1,s1.length()));
				break;
			}
		}
	}

	public static void main(String args[]) throws Exception
	{
		int n=sc.nextInt(),last=0,prev=0;
		String[] a=new String[n];
		HashSet<String> s1=new HashSet<String>();
		for(int i=0;i<n;i++)
		{
			String nxt=sc.next();
			s1.add(nxt);
			if(s1.size()!=prev)
			{
				prev++;
				a[last++]=nxt;
			}
		}
		StringBuffer res=new StringBuffer("");
		boolean[] v=new boolean[n];
		for(int i=0;i<last;i++)
		{
			if(!v[i])
			{
				boolean curr=true;
				for(int j=0;j<last;j++)
				{
					if(i!=j && !v[j])
					{
						if(isSuffix(a[i],a[j]))
						{
							curr=false;
							break;
						}
					}
				}
				if(curr)
				{
					res.append(a[i]);
					v[i]=true;
					for(int k=0;k<last;k++)
					{
						if(!v[k] && isSuffix(a[k],res.toString()))
						{
							combine(res,a[k]);
							v[k]=true;
							k=-1;
						}
					}
				}
			}
		}
		out.println(res);
		out.close();
	}
}
class FastScanner
{
    BufferedReader in;
    StringTokenizer st;

    public FastScanner(BufferedReader in) {
        this.in = in;
    }

    public String nextToken() throws Exception {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken();
    }

	public String next() throws Exception {
		return nextToken().toString();
	}

    public int nextInt() throws Exception {
        return Integer.parseInt(nextToken());
    }

    public long nextLong() throws Exception {
        return Long.parseLong(nextToken());
    }

    public double nextDouble() throws Exception {
        return Double.parseDouble(nextToken());
    }
}


//package com.company;

import javax.xml.stream.events.Characters;
import java.io.*;
import java.lang.reflect.Array;
import java.math.BigInteger;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        new Main().run();
    }

    public void run() throws IOException {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        String[] o = new String[26];
        for (int i = 0; i < 26; i++)
            o[i] = "";
        byte[] by = new byte[26];
        char[] ch = {'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'z', 'x', 'c', 'v', 'b', 'n', 'm'};
        String ans = "";
        int max = 0;
        int j1 = 0;
        String[] s = new String[n];
        for (int i = 0; i < n; i++) {
            s[i] = in.next();
            for (int k = 0; k < s[i].length(); k++) {
                for (int j = 0; j < 26; j++)
                    if (s[i].charAt(k) == ch[j]) {
                        j1 = j;
                        break;
                    }
                if (k > 0) by[j1] = 2;
                if ((k == 0) && (by[j1] != 2)) by[j1] = 1;
                if (s[i].length() - k > o[j1].length()) {
                    String s1 = "";
                    for (int j = k; j < s[i].length(); j++)
                        s1 = s1 + Character.toString(s[i].charAt(j));
                    o[j1] = s1;
                }
            }
        }

        for (int i = 0; i < 26; i++) {
            if (by[i] == 1) {
                for (int k = 1; k < o[i].length(); k++) {
                    for (int j = 0; j < 26; j++)
                        if (o[i].charAt(k) == ch[j]) {
                            j1 = j;
                            break;
                        }
                    if (!(o[i].contains(o[j1]))) o[i] = o[i] + o[j1];
                }
            }
        }
        String s1 = "",s2 = "", odo = "", oposl = "";
        int k2 = 0;
        for(int i = 0; i < 26; i++){
            if (by[i] == 1){
                for(int j = 0; j < o[i].length()/2; j++) {
                    for(int j2 = 0; j2 < o[i].length() - j*2 - 2; j2++) {
                        odo = "";
                        oposl = "";
                        for(int h = 0; h < j2; h++)
                            odo = odo + Character.toString(o[i].charAt(h));
                        for(int h = j2+(j+1)*2; h < o[i].length(); h++)
                            oposl = oposl + Character.toString(o[i].charAt(h));
                        s1 = "";
                        s2 = "";
                        ans = "";
                        k2 = j2;
                        for (int k = 0; k < j + 1; k++) {
                            s1 = s1 + Character.toString(o[i].charAt(k2));
                            k2++;
                        }
                        for (int k = 0; k < j + 1; k++) {
                            s2 = s2 + Character.toString(o[i].charAt(k2));
                            k2++;
                        }
                        if (s1.equals(s2)){
                            o[i] = odo + s1 + oposl;
                        }
                    }
                }
            }
        }
        for(int i = 0; i < 26; i++) {
            if (by[i] == 1)
                out.print(o[i]);
        }
        out.close();
    }
}


import java.util.*;

public class VK {

    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int n = new Integer(s.nextLine());

        List<String> list = new ArrayList<String>();
        for (int i = 0; i < n; i++) {
            list.add(s.nextLine());
        }
        List<String> res = new ArrayList<String>();

        clearSubString(list);
        while (list.size() > 0) {
            String first = list.get(0);
            boolean hasSubstringed = false;
            for (int i = 1; i < list.size(); i++) {
                if (!longestCS(first, list.get(i)).isEmpty()) {
                    first = combine(first, list.get(i));
                    list.set(0, first);
                    list.remove(i);
                    hasSubstringed = true;
                    break;
                }
            }
            clearSubString(list);
            if (!hasSubstringed || list.size() == 0) {
                res.add(first);
                if(list.size() > 0)
                list.remove(first);
            }
        }

        StringBuilder sc = new StringBuilder();

        for (String st : res) {
            sc.append(st);
        }

        System.out.println(sc.toString());

        /*
        Set<String> hs = new HashSet<String>();
        hs.addAll(list);
        list.clear();
        list.addAll(hs);

        hs.clear();
        hs = null;

        Collections.sort(list, new Comparator<String>() {
            public int compare(String s1, String s2) {
                return s1.length() - s2.length();
            }
        });

        for (int i = 0; i < list.size(); i++) {
            for (int j = i + 1; j < list.size(); j++) {
                String it = list.get(i);
                String jt = list.get(j);
                String lCS = longestCS(it, jt);
                list.set(i, it.replaceAll(lCS, ""));
            }
        }

        List<String> cleared = new ArrayList<String>();

        Iterator<String> iter = list.iterator();
        while (iter.hasNext()) {
            String a = iter.next();
            if (a.length() > 0) {
                cleared.add(a);
            }
        }

        String[] clearedA = new String[cleared.size()];
        list.toArray(clearedA);
        showPermutations(clearedA, result);
        */
    }

    private static String combine(String a, String b) {
        String longestCS = longestCS(a, b);
        if (a.indexOf(longestCS) == 0) {
            return b.replaceAll(longestCS, "") + a;
        } else {
            return a.replaceAll(longestCS, "") + b;
        }
    }

    private static void clearSubString(List<String> t) {
        Set<String> hs = new HashSet<String>();
        hs.addAll(t);
        t.clear();
        t.addAll(hs);
    }

    private static String longestCS(String a, String b) {
        if (a == null || b == null || a.length() == 0 || b.length() == 0) {
            return "";
        }

        if (a.equals(b)) {
            return a;
        }

        int[][] matrix = new int[a.length()][];

        int maxLength = 0;
        int maxI = 0;

        for (int i = 0; i < matrix.length; i++) {
            matrix[i] = new int[b.length()];
            for (int j = 0; j < matrix[i].length; j++) {
                if (a.charAt(i) == b.charAt(j)) {
                    if (i != 0 && j != 0) {
                        matrix[i][j] = matrix[i - 1][j - 1] + 1;
                    } else {
                        matrix[i][j] = 1;
                    }
                    if (matrix[i][j] > maxLength) {
                        maxLength = matrix[i][j];
                        maxI = i;
                    }
                }
            }
        }
        return a.substring(maxI - maxLength + 1, maxI + 1);
    }
}


import java.util.*;

public class VK {

    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int n = new Integer(s.nextLine());

        String[] result = new String[n];
        for (int i = 0; i < n; i++) {
            result[i] = s.nextLine();
        }

        List<String> list = new ArrayList<String>(Arrays.asList(result));

        Set<String> hs = new HashSet<String>();
        hs.addAll(list);
        list.clear();
        list.addAll(hs);

        hs.clear();
        hs = null;

        Collections.sort(list, new Comparator<String>() {
            public int compare(String s1, String s2) {
                return s1.length() - s2.length();
            }
        });

        for (int i = 0; i < list.size(); i++) {
            for (int j = i + 1; j < list.size(); j++) {
                String it = list.get(i);
                String jt = list.get(j);
                String lCS = longestCS(it, jt);
                list.set(i, it.replaceAll(lCS, ""));
            }
        }

        List<String> cleared = new ArrayList<String>();

        Iterator<String> iter = list.iterator();
        while (iter.hasNext()) {
            String a = iter.next();
            if (a.length() > 0) {
                cleared.add(a);
            }
        }

        String[] clearedA = new String[cleared.size()];
        list.toArray(clearedA);
        showPermutations(clearedA, result);
    }

    private static String longestCS(String a, String b) {
        if (a == null || b == null || a.length() == 0 || b.length() == 0) {
            return "";
        }

        if (a.equals(b)) {
            return a;
        }

        int[][] matrix = new int[a.length()][];

        int maxLength = 0;
        int maxI = 0;

        for (int i = 0; i < matrix.length; i++) {
            matrix[i] = new int[b.length()];
            for (int j = 0; j < matrix[i].length; j++) {
                if (a.charAt(i) == b.charAt(j)) {
                    if (i != 0 && j != 0) {
                        matrix[i][j] = matrix[i - 1][j - 1] + 1;
                    } else {
                        matrix[i][j] = 1;
                    }
                    if (matrix[i][j] > maxLength) {
                        maxLength = matrix[i][j];
                        maxI = i;
                    }
                }
            }
        }
        return a.substring(maxI - maxLength + 1, maxI + 1);
    }

    static void showPermutations(String[] arr, String[] res) {
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr.length - 1; j++) {
                StringBuilder builder = new StringBuilder();
                for (String s : arr) {
                    builder.append(s);
                }
                boolean ok = true;
                String resSeq = builder.toString();
                for (String check : res) {
                    if (!resSeq.contains(check)) {
                        ok = false;
                        break;
                    }
                }
                if (ok) {
                    System.out.println(resSeq);
                    return;
                }

                String tmp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = tmp;
            }
        }
    }
}


import java.util.*;

public class VK {

    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int n = new Integer(s.nextLine());

        List<String> list = new ArrayList<String>();
        for (int i = 0; i < n; i++) {
            list.add(s.nextLine());
        }
        List<String> res = new ArrayList<String>();

        list = new ArrayList<String>(clearSubString(list));
        while (list.size() > 0) {
            String first = list.get(0);
            boolean hasSubstringed = false;
            for (int i = 1; i < list.size(); i++) {
                if (!longestCS(first, list.get(i)).isEmpty()) {
                    first = combine(first, list.get(i));
                    list.set(0, first);
                    list.remove(i);
                    hasSubstringed = true;
                    break;
                }
            }
            list = new ArrayList<String>(clearSubString(list));
            if (!hasSubstringed || list.size() == 0) {
                res.add(first);
                if (list.size() > 0)
                    list.remove(first);
            }
        }

        StringBuilder sc = new StringBuilder();

        for (String st : res) {
            sc.append(st);
        }

        System.out.println(sc.toString());

        /*
        Set<String> hs = new HashSet<String>();
        hs.addAll(list);
        list.clear();
        list.addAll(hs);

        hs.clear();
        hs = null;

        Collections.sort(list, new Comparator<String>() {
            public int compare(String s1, String s2) {
                return s1.length() - s2.length();
            }
        });

        for (int i = 0; i < list.size(); i++) {
            for (int j = i + 1; j < list.size(); j++) {
                String it = list.get(i);
                String jt = list.get(j);
                String lCS = longestCS(it, jt);
                list.set(i, it.replaceAll(lCS, ""));
            }
        }

        List<String> cleared = new ArrayList<String>();

        Iterator<String> iter = list.iterator();
        while (iter.hasNext()) {
            String a = iter.next();
            if (a.length() > 0) {
                cleared.add(a);
            }
        }

        String[] clearedA = new String[cleared.size()];
        list.toArray(clearedA);
        showPermutations(clearedA, result);
        */
    }

    private static String combine(String a, String b) {
        String longestCS = longestCS(a, b);
        if (a.indexOf(longestCS) == 0) {
            return b.replaceAll(longestCS, "") + a;
        } else {
            return a.replaceAll(longestCS, "") + b;
        }
    }

    private static List<String> clearSubString(List<String> t) {
        Set<String> hs = new HashSet<String>();
        hs.addAll(t);

        List<String> l = new ArrayList<String>(hs);
        List<String> res = new ArrayList<String>();

        for (int i = 0; i < l.size(); i++) {
            boolean contain = false;
            for (int j = 0; j < l.size(); j++) {
                if (i == j)
                    continue;
                if (l.get(j).contains(l.get(i))) {
                    contain = true;
                    break;
                }
            }
            if (!contain)
                res.add(l.get(i));
        }

        return res;
    }

    private static String longestCS(String a, String b) {
        if (a == null || b == null || a.length() == 0 || b.length() == 0) {
            return "";
        }

        if (a.equals(b)) {
            return a;
        }

        int[][] matrix = new int[a.length()][];

        int maxLength = 0;
        int maxI = 0;

        for (int i = 0; i < matrix.length; i++) {
            matrix[i] = new int[b.length()];
            for (int j = 0; j < matrix[i].length; j++) {
                if (a.charAt(i) == b.charAt(j)) {
                    if (i != 0 && j != 0) {
                        matrix[i][j] = matrix[i - 1][j - 1] + 1;
                    } else {
                        matrix[i][j] = 1;
                    }
                    if (matrix[i][j] > maxLength) {
                        maxLength = matrix[i][j];
                        maxI = i;
                    }
                }
            }
        }
        return a.substring(maxI - maxLength + 1, maxI + 1);
    }
}


#include <bits/stdc++.h>

using namespace std;

bool used[30];
bool used1[32];
string s[200];
char m[400], k[400];
int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("a.in", "r", stdin);
    //freopen("output.txt", "w", stdout);
    int n;
    cin >> n;
    for (int i = 0; i < 26; ++i) {
        m[i] = '!';
        k[i] = '!';
    }
    int cnt = 0;
    for (int i = 0; i < n; ++i) {
        cin >> s[i];
        //cout << s[i].size();
        for (int j = 0; j < s[i].size(); ++j)
            if (!used[s[i][j] - 'a']) {
                ++cnt;
                used[s[i][j] - 'a'] = true;
            }
    }
    //sort(s, s + n);
    string ans = "";
    for (int i = 0; i < n; ++i) {
        if (s[i].size() > 1) {
            for (int j = 0; j < s[i].size() - 1; ++j)
                m[s[i][j] - 'a'] = s[i][j + 1];
            for (int j = s[i].size() - 1; j > 0; --j)
                k[s[i][j] - 'a'] = s[i][j - 1];
        }
    }
//    for (int i = 0; i < 26; ++i)
//        cout << (char) (i + 'a') << ' ' << (char) (m[i]) << endl;
    for (int i = 0; i < 26; ++i) {
        if ((m[i] == '!') && (k[i] == '!') && (used[i])) {
            cnt--;
            ans += i + 'a';
            used1[i] = true;
        }
    }
    while (cnt > 0) {
        int c;
        for (int i = 0; i < 26; ++i)
            if ((used[i]) && (k[i] == '!') && (!used1[i])) {
                ans += i + 'a';
                c = i;
                used1[i] = true;
                break;
            }
        --cnt;
        while (cnt > 0) {
            int i = 0;
            while ((k[i] != (c + 'a')) && (i < 26))
                ++i;
            if (i != 26) {
                ans += i + 'a';
                c = i;
                used1[i] = true;
                cnt--;
                continue;
            }
            else
                break;
        }
    }
    //reverse(ans.begin(), ans.end());
    cout << ans;
}


#include <bits/stdc++.h>

using namespace std;

bool used[30];
string s[200];

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("a.in", "r", stdin);
    //freopen("output.txt", "w", stdout);
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i)
        cin >> s[i];
    sort(s, s + n);
    string ans = "";
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < s[i].size(); ++j)
            if (!used[s[i][j] - 'a']) {
                ans += s[i][j];
                used[s[i][j] - 'a'] = true;
            }
    }
    cout << ans;
}


#include <bits/stdc++.h>

using namespace std;

string s[200];
int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("a.in", "r", stdin);
    //freopen("output.txt", "w", stdout);

     int n;
     cin >> n;
     vector<string> strings(n);
     for (int i = 0;i < n;i++)
        cin >> strings[i];
     sort(strings.begin(), strings.end());
     set<char> nucleos;
     string result;
     for (int i = 0;i < n;i++)
     {
      for (int j = 0;j < strings[i].size();j++)
       if (nucleos.find(strings[i][j]) == nucleos.end())
       {
        result += strings[i][j];
        nucleos.insert(strings[i][j]);
       }
     }
     cout << result;

     return 0;

}


#include <vector>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>

using namespace std;

#define fi first
#define se second
#define mp make_pair
#define sz(x) ((int)(x).size())
#define re return
#define pb(x) push_back(x)
#define pf(x) push_front(x)
#define abs(x) ((x) < 0 ? -(x) : (x))
#define INF 2000000000
#define sqr(x) ((x) * (x))
#define all(x) x.begin(), x.end()
#define fname "a"
#define MOD 1000000007

typedef long long ll;

int prv[26], nxt[26], pos;
int n;
string s;

int main() {

	ios_base::sync_with_stdio(0);

	#ifndef ONLINE_JUDGE
		freopen("a.in", "r", stdin);
	#endif

	cin >> n;

	memset(prv, 255, 26 * 4);
	memset(nxt, 255, 26 * 4);

	for(int i = 1; i <= n; i++) {
		cin >> s;
		if(sz(s) > 1) {
			nxt[s[0] - 'a'] = s[1] - 'a';
			prv[s[sz(s) - 1] - 'a'] = s[sz(s) - 2] - 'a';
			for(int i = 1; i < sz(s) - 1; i++)
				nxt[s[i] - 'a'] = s[i + 1] - 'a', prv[s[i] - 'a'] = s[i - 1] - 'a';
		}
	}

	for(int i = 0; i < 26; i++)
		if(prv[i] == -1 && nxt[i] != -1) {
			pos = i;
			break;
		}

	while(pos != -1) {
		cout << char(pos + 'a');
		pos = nxt[pos];
	}
	return 0;
}


#include <vector>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>

using namespace std;

#define fi first
#define se second
#define mp make_pair
#define sz(x) ((int)(x).size())
#define re return
#define pb(x) push_back(x)
#define pf(x) push_front(x)
#define abs(x) ((x) < 0 ? -(x) : (x))
#define INF 2000000000
#define sqr(x) ((x) * (x))
#define all(x) x.begin(), x.end()
#define fname "a"
#define MOD 1000000007

typedef long long ll;

int prv[26], nxt[26], pos = -1, used[26], was[26];
int n;
string s;

int main() {

	ios_base::sync_with_stdio(0);

	#ifndef ONLINE_JUDGE
		freopen("a.in", "r", stdin);
	#endif

	cin >> n;

	memset(prv, 255, 26 * 4);
	memset(nxt, 255, 26 * 4);

	for(int i = 1; i <= n; i++) {
		cin >> s;
		for(int j = 0; j < sz(s); j++)
			used[s[j] - 'a'] = 1;
		if(sz(s) > 1) {
			nxt[s[0] - 'a'] = s[1] - 'a';
			prv[s[sz(s) - 1] - 'a'] = s[sz(s) - 2] - 'a';
			for(int i = 1; i < sz(s) - 1; i++)
				nxt[s[i] - 'a'] = s[i + 1] - 'a', prv[s[i] - 'a'] = s[i - 1] - 'a';
		}
	}

	for(int i = 0; i < 26; i++)
		if(prv[i] == -1 && nxt[i] != -1) {
			pos = i;
			break;
		}

	while(pos != -1) {
		was[pos] = 1;
		cout << char(pos + 'a');
		pos = nxt[pos];
	}
	for(int i = 0; i < 26; i++)
		if(used[i] && !was[i]) cout << char(i + 'a');
	return 0;
}


#include <vector>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>

using namespace std;

#define fi first
#define se second
#define mp make_pair
#define sz(x) ((int)(x).size())
#define re return
#define pb(x) push_back(x)
#define pf(x) push_front(x)
#define abs(x) ((x) < 0 ? -(x) : (x))
#define INF 2000000000
#define sqr(x) ((x) * (x))
#define all(x) x.begin(), x.end()
#define fname "a"
#define MOD 1000000007

typedef long long ll;

int prv[26], nxt[26], pos = -1, used[26], was[26];
int n;
string s;

int main() {

	ios_base::sync_with_stdio(0);

	#ifndef ONLINE_JUDGE
		freopen("a.in", "r", stdin);
	#endif

	cin >> n;

	memset(prv, 255, 26 * 4);
	memset(nxt, 255, 26 * 4);

	for(int i = 1; i <= n; i++) {
		cin >> s;
		for(int j = 0; j < sz(s); j++)
			used[s[j] - 'a'] = 1;
		if(sz(s) > 1) {
			nxt[s[0] - 'a'] = s[1] - 'a';
			prv[s[sz(s) - 1] - 'a'] = s[sz(s) - 2] - 'a';
			for(int j = 1; j < sz(s) - 1; j++)
				nxt[s[j] - 'a'] = s[j + 1] - 'a', prv[s[j] - 'a'] = s[j - 1] - 'a';
		}
	}

	for(int i = 0; i < 26; i++)
		if(prv[i] == -1 && nxt[i] != -1) {
			pos = i;
			while(pos != -1) {
				was[pos] = 1;
				cout << char(pos + 'a');
				pos = nxt[pos];
			}
		}

	for(int i = 0; i < 26; i++)
		if(used[i] && !was[i]) cout << char(i + 'a');
	return 0;
}


#include <stdio.h>
#include <iostream>

using namespace std;

int gi(char sym){
	return sym-'a';
}

int main(int argc, char **argv)
{
	#ifdef LOCAL
	  freopen("in","r",stdin);
	#endif
	int n;
	string* words = new string[n];
	cin>>n;
	for(int i = 0 ; i < n ; i++)
		cin>>words[i];
	char childs[26];
	bool has_parent[26];
	bool used[26];
	for (int i = 0 ; i < 26 ; i++)
	{
	  childs[i] = -1;
	  has_parent[i] = false;
	  used[i] = false;
	}
	for (int j = 0 ; j < n ; j++){
	  used[gi(words[j][0])] = true;
	  for (int i = 1 ; i < words[j].length() ; i++)
	  {
		used[gi(words[j][i])] = true;
		has_parent[gi(words[j][i])] = true;
		childs[gi(words[j][i-1])] = gi(words[j][i]);
	  }
	}
	for (int i = 0 ; i < 26 ; i++)
		if (used[i] && !has_parent[i]){
			int ind = i;
			while(childs[ind] != -1){
				cout<<(char)(ind+'a');
				ind = childs[ind];
			}
			cout<<(char)(ind+'a');
		}
	cout<<'\n';
	return 0;
}


#include <stdio.h>
#include <iostream>

using namespace std;

int gi(char sym){
	return sym-'a';
}

int main(int argc, char **argv)
{
	#ifdef LOCAL
	  freopen("in","r",stdin);
	#endif
	int n;
	cin>>n;
	string* words = new string[n];
	for(int i = 0 ; i < n ; i++)
		cin>>words[i];
	char childs[26];
	bool has_parent[26];
	bool used[26];
	for (int i = 0 ; i < 26 ; i++)
	{
	  childs[i] = -1;
	  has_parent[i] = false;
	  used[i] = false;
	}
	for (int j = 0 ; j < n ; j++){
	  used[gi(words[j][0])] = true;
	  for (unsigned int i = 1 ; i < words[j].length() ; i++)
	  {
		used[gi(words[j][i])] = true;
		has_parent[gi(words[j][i])] = true;
		childs[gi(words[j][i-1])] = gi(words[j][i]);
	  }
	}
	for (int i = 0 ; i < 26 ; i++)
		if (used[i] && !has_parent[i]){
			int ind = i;
			while(childs[ind] != -1){
				cout<<(char)(ind+'a');
				ind = childs[ind];
			}
			cout<<(char)(ind+'a');
		}
	cout<<'\n';
	return 0;
}


#include <stdio.h>
#include <iostream>

using namespace std;

int gi(char sym){
	return sym-'a';
}

int main(int argc, char **argv)
{
	#ifdef LOCAL
	  freopen("in","r",stdin);
	#endif
	int n;
	string* words = new string[n];
	cin>>n;
	for(int i = 0 ; i < n ; i++)
		cin>>words[i];
	char childs[26];
	bool has_parent[26];
	bool used[26];
	for (int i = 0 ; i < 26 ; i++)
	{
	  childs[i] = -1;
	  has_parent[i] = false;
	  used[i] = false;
	}
	for (int j = 0 ; j < n ; j++){
	  used[gi(words[j][0])] = true;
	  for (unsigned int i = 1 ; i < words[j].length() ; i++)
	  {
		used[gi(words[j][i])] = true;
		has_parent[gi(words[j][i])] = true;
		childs[gi(words[j][i-1])] = gi(words[j][i]);
	  }
	}
	for (int i = 0 ; i < 26 ; i++)
		if (used[i] && !has_parent[i]){
			int ind = i;
			while(childs[ind] != -1){
				cout<<(char)(ind+'a');
				ind = childs[ind];
			}
			cout<<(char)(ind+'a');
		}
	cout<<'\n';
	return 0;
}


#include <bits/stdc++.h>
typedef long long ll;
typedef long double ld;
using namespace std;
set<string> res;
ll maxx=23094312;
set<string> findMax(set<string> gens, set<string>::iterator itt){
	//cout << s << "=" << ' ' << endl;
	set<string> del;
	set<string>::iterator it1 = gens.begin();
	while (it1 != gens.end()){
		set<string>::iterator jt=gens.begin();
		while (jt != gens.end()){
			if ((jt!=it1)&&((*it1).find(*jt) != std::string::npos))
				del.insert(*jt);
					//gens.erase(*jt);
	   	 	jt++;
		}
		it1++;
	}
	for (auto&d:del)
		gens.erase(d);
	bool b=false;
	if (gens.size()==1){
		//cout << (*gens.begin()) <<  "+++" << endl;
		if((*gens.begin()).size()<=maxx){
			res=gens, maxx=(*gens.begin()).size();
		return gens;
		}
		else
			return gens;
	}

	set<string> res;
	res=gens;
	set<string>::iterator it;
	if (del.size()>0)
		it = gens.begin();
	else
		it = itt;
	string s = *it;
	if ((*it)==(*(gens.rbegin()))){
		set<string> ss;
		ss = gens;
		string s1, s2;
		s1=*gens.begin();
		s2=*(++gens.begin());
		ss.erase(s1);
		ss.erase(s2);
		string t=s1+s2;
		//cout << t << "+" << endl;
		ss.insert(t);
		b=true;
		res = findMax(ss, ss.begin());
	}
	//cout << "++++++++++++++++++++" << endl;

	for (ll i=0; i<s.length(); i++){
		for (auto&gen:gens){
			//cout << gen << ' ' << s << "++"<< ((gen!=s)&&(gen.find(s.substr(i))==0)) << endl;
			if ((gen!=s)&&(gen.find(s.substr(i))==0)){
				b=true;
				set<string> ss;
				ss = gens;
				ss.erase(gen);
				ss.erase(s);
				string t=s+gen.substr(s.length()-i);
				ss.insert(t);
				//cout << t << '-' << endl;
				res = findMax(ss, ss.begin());
			}
		}
	}
	if (!b)
		res=findMax(gens, ++it);
	return res;
}

int main()
{
	cin.sync_with_stdio(false);
	cout.sync_with_stdio(false);
   ll n, a;
   cin >> n;
   string s;
   set<string> gens;
	for (ll i=0; i<n; i++){
	  	cin >> s;
	  	gens.insert(s);
   }
   set<string> del;
   set<string>::iterator it = gens.begin();
   while (it != gens.end()){
	  	set<string>::iterator jt=gens.begin();
		 while (jt != gens.end()){
			if ((jt!=it)&&((*it).find(*jt) != std::string::npos))
				del.insert(*jt);
				//gens.erase(*jt);
   	 	jt++;
		}
		it++;
	}

	for (auto&d:del)
		gens.erase(d);
	/*for (auto&gen:gens)
		cout << gen << endl;*/

	set<string> res1;
	res1 = findMax(gens, gens.begin());

	for (auto&gen:res)
		cout << gen << endl;

   return 0;
}


#include <bits/stdc++.h>
typedef long long ll;
typedef long double ld;
using namespace std;

set<string> findMax(set<string> gens, set<string>::iterator itt){
	set<string> res;
	res=gens;
	set<string>::iterator it = itt;
	string s = *it;
	//cout << s << "=" << ' ' << endl;
	bool b=false;

	if (gens.size()==1)
		return gens;
	if ((*itt)==(*(--gens.end()))){
		set<string> ss;
		ss = gens;
		string s1, s2;
		s1=*gens.begin();
		s2=*(++gens.begin());
		ss.erase(s1);
		ss.erase(s2);
		string t=s1+s2;
		//cout << t << "+" << endl;
		ss.insert(t);
		b=true;
		res = findMax(ss, ss.begin());
	}
	for (ll i=1; i<s.length(); i++){
		for (auto&gen:gens){
			if ((gen!=s)&&(gen.find(s.substr(i))==0)){
				b=true;
				set<string> ss;
				ss = gens;
				ss.erase(gen);
				ss.erase(s);
				string t=s+gen.substr(i);
				ss.insert(t);
				//cout << t << '-' << endl;
				res = findMax(ss, ss.begin());
			}
		}
		if (b)
			break;
	}
	if (!b)
		res=findMax(gens, ++it);
	return res;
}

int main()
{
	cin.sync_with_stdio(false);
	cout.sync_with_stdio(false);
   ll n, a;
   cin >> n;
   string s;
   set<string> gens;
	for (ll i=0; i<n; i++){
	  	cin >> s;
	  	gens.insert(s);
   }
   set<string> del;
   set<string>::iterator it = gens.begin();
   while (it != gens.end()){
	  	set<string>::iterator jt=gens.begin();
		 while (jt != gens.end()){
			if ((jt!=it)&&((*it).find(*jt) != std::string::npos))
				del.insert(*jt);
				//gens.erase(*jt);
   	 	jt++;
		}
		it++;
	}

	/*for (auto&d:del)
		gens.erase(d);
	for (auto&gen:gens)
		cout << gen << endl;

*/
	set<string> res;
	res = findMax(gens, gens.begin());

	for (auto&gen:res)
		cout << gen << endl;

   return 0;
}


#include <bits/stdc++.h>
typedef long long ll;
typedef long double ld;
using namespace std;
set<string> res;
ll maxx=0;
set<string> findMax(set<string> gens, set<string>::iterator itt){
	set<string> res;
	res=gens;
	set<string>::iterator it = itt;
	string s = *it;
	//cout << s << "=" << ' ' << endl;
	bool b=false;
	if (gens.size()==1){
		//cout << (*gens.begin()) <<  "+++" << endl;
		if((*gens.begin()).size()<maxx){
			res=gens, maxx=(*gens.begin()).size();
		return gens;
		}
		else
			return res;
	}
	if ((*itt)==(*(gens.rbegin()))){
		set<string> ss;
		ss = gens;
		string s1, s2;
		s1=*gens.begin();
		s2=*(++gens.begin());
		ss.erase(s1);
		ss.erase(s2);
		string t=s1+s2;
		//cout << t << "+" << endl;
		ss.insert(t);
		b=true;
		res = findMax(ss, ss.begin());
	}
	//cout << "++++++++++++++++++++" << endl;
	for (ll i=0; i<s.length(); i++){
		for (auto&gen:gens){
			//cout << gen << ' ' << s << "++"<< ((gen!=s)&&(gen.find(s.substr(i))==0)) << endl;
			if ((gen!=s)&&(gen.find(s.substr(i))==0)){
				b=true;
				set<string> ss;
				ss = gens;
				ss.erase(gen);
				ss.erase(s);
				string t=s+gen.substr(s.length()-i);
				ss.insert(t);
				//cout << t << '-' << endl;
				res = findMax(ss, ss.begin());
			}
		}
	}
	if (!b)
		res=findMax(gens, ++it);
	return res;
}

int main()
{
	cin.sync_with_stdio(false);
	cout.sync_with_stdio(false);
   ll n, a;
   cin >> n;
   string s;
   set<string> gens;
	for (ll i=0; i<n; i++){
	  	cin >> s;
	  	gens.insert(s);
   }
   set<string> del;
   set<string>::iterator it = gens.begin();
   while (it != gens.end()){
	  	set<string>::iterator jt=gens.begin();
		 while (jt != gens.end()){
			if ((jt!=it)&&((*it).find(*jt) != std::string::npos))
				del.insert(*jt);
				//gens.erase(*jt);
   	 	jt++;
		}
		it++;
	}

	for (auto&d:del)
		gens.erase(d);
	/*for (auto&gen:gens)
		cout << gen << endl;*/

	set<string> res1;
	res1 = findMax(gens, gens.begin());

	for (auto&gen:res1)
		cout << gen << endl;

   return 0;
}


#include <bits/stdc++.h>
typedef long long ll;
typedef long double ld;
using namespace std;

set<string> findMax(set<string> gens, set<string>::iterator itt){
	set<string> res;
	res=gens;
	set<string>::iterator it = itt;
	string s = *it;
	//cout << s << "=" << ' ' << endl;
	bool b=false;
	if (gens.size()==1)
		return gens;
	if ((*itt)==(*(gens.rbegin()))){
		set<string> ss;
		ss = gens;
		string s1, s2;
		s1=*gens.begin();
		s2=*(++gens.begin());
		ss.erase(s1);
		ss.erase(s2);
		string t=s1+s2;
		//cout << t << "+" << endl;
		ss.insert(t);
		b=true;
		res = findMax(ss, ss.begin());
	}
	//cout << "++++++++++++++++++++" << endl;
	for (ll i=1; i<s.length(); i++){
		for (auto&gen:gens){
			//cout << gen << ' ' << s << "++"<< ((gen!=s)&&(gen.find(s.substr(i))==0)) << endl;
			if ((gen!=s)&&(gen.find(s.substr(i))==0)){
				b=true;
				set<string> ss;
				ss = gens;
				ss.erase(gen);
				ss.erase(s);
				string t=s+gen.substr(s.length()-i);
				ss.insert(t);
				//cout << t << '-' << endl;
				res = findMax(ss, ss.begin());
			}
		}
		if (b)
			break;
	}
	if (!b)
		res=findMax(gens, ++it);
	return res;
}

int main()
{
	cin.sync_with_stdio(false);
	cout.sync_with_stdio(false);
   ll n, a;
   cin >> n;
   string s;
   set<string> gens;
	for (ll i=0; i<n; i++){
	  	cin >> s;
	  	gens.insert(s);
   }
   set<string> del;
   set<string>::iterator it = gens.begin();
   while (it != gens.end()){
	  	set<string>::iterator jt=gens.begin();
		 while (jt != gens.end()){
			if ((jt!=it)&&((*it).find(*jt) != std::string::npos))
				del.insert(*jt);
				//gens.erase(*jt);
   	 	jt++;
		}
		it++;
	}

	for (auto&d:del)
		gens.erase(d);
	/*for (auto&gen:gens)
		cout << gen << endl;*/

	set<string> res;
	res = findMax(gens, gens.begin());

	for (auto&gen:res)
		cout << gen << endl;

   return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <utility>
#include <string>
using namespace std;
pair <int, string> a[200];

int cmp(string big, string little) {
	int i, j, lenb = big.length(), lenl = little.length();

	for (i = 0; i < lenb; i++) {
		if (big[i] == little[0]) {
			for (j = 0; j < lenl && i+j < lenb; j++) {
				if (little[j] != big[i + j])
					return 0;
			}
			return lenb - i;
		}
	}
	for (i = lenb-1; i >= 0; i--) {
		if (big[i] == little[lenl-1]) {
			for (j = 0; j < lenl && i - j >= 0; j++) {
				if (little[lenl-1-j] != big[i - j])
					return 0;
			}
			return -i-1;
		}
	}
	return 0;
}

int main() {
	int n,i,j,k;

	cin >> n;
	for (i = 0; i < n; i++){
		cin >> a[i].second;
		a[i].first = a[i].second.length();
	}
	sort(a, a + n);
	string genom[200];
	int m = 0;
	for (k = n - 1; k >= 0; k--) {
		if(a[k].first!=0){
			genom[m] = a[k].second;
			m++;
			int lenb, lenl, res;
			for (i = 0; i < k; i++) {
				for (j = k-1; j >= 0; j--) {

					if (a[j].first!=0) {
						lenl = a[j].first;
						res = cmp(genom[m-1], a[j].second);
						if (res > 0) {
							if (lenl > res) {
								genom[m - 1] = genom[m - 1] + a[j].second.substr(res, lenl - res);
							}
							a[j].first = 0;
						}
						if (res < 0) {
							if (lenl > -res) {
								genom[m - 1] = a[j].second.substr(0, lenl + res) + genom[m - 1];
							}
							a[j].first = 0;
						}
						if (res == 0) {
							continue;
						}
					}
				}
			}
		}
	}
	/*
	for (i = 0; i < n - 1; i++) {
		for (j = i+1; j < n - 1; j++) {
			if (a[i].second == a[j].second)
				a[j].first = 0;
		}
	}
	for (j = 0; j < n - 1; j++) {
		if (a[j].first != 0) {
			cout << a[j].second;
		}
	}*/
	for (i = 0; i < m; i++) {
		cout << genom[i];
	}

}


#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <utility>
#include <string>
using namespace std;
pair <int, string> a[200];
string genom;
int cmp(string big, string little) {
	int i, j, lenb = big.length(), lenl = little.length();

	for (i = 0; i < lenb; i++) {
		if (big[i] == little[0]) {
			for (j = 0; j < lenl && i+j < lenb; j++) {
				if (little[j] != big[i + j])
					return 0;
			}
			return lenb - i;
		}
	}
	for (i = lenb-1; i >= 0; i--) {
		if (big[i] == little[lenl-1]) {
			for (j = 0; j < lenl && i - j >= 0; j++) {
				if (little[lenl-1-j] != big[i - j])
					return 0;
			}
			return -i-1;
		}
	}
	return 0;
}

int main() {
	int n,i,j;

	cin >> n;
	for (i = 0; i < n; i++){
		cin >> a[i].second;
		a[i].first = a[i].second.length();
	}
	sort(a, a + n);
	genom = a[n - 1].second;
	int lenb, lenl,res;
	for (i = 0; i < n-1; i++) {
		for (j = 0; j < n-1; j++) {

			if (a[j].first != 0) {
				lenl = a[j].first;
				res = cmp(genom, a[j].second);
				if (res > 0) {
					if (lenl > res) {
						genom = genom + a[j].second.substr(res, lenl - res);
					}
					a[j].first = 0;
				}
				if (res < 0) {
					if (lenl > -res) {
						genom = a[j].second.substr(0,lenl+res) + genom;
					}
					a[j].first = 0;
				}
				if (res == 0) {
					continue;
				}
			}
		}
	}
	for (i = 0; i < n - 1; i++) {
		for (j = i+1; j < n - 1; j++) {
			if (a[i].second == a[j].second)
				a[j].first = 0;
		}
	}
	for (j = 0; j < n - 1; j++) {
		if (a[j].first != 0) {
			cout << a[j].second;
		}
	}
	cout << genom;

}


#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <utility>
#include <string>
using namespace std;
pair <int, string> a[200];
string genom;
int cmp(string big, string little) {
	int i, j, lenb = big.length(), lenl = little.length();

	for (i = 0; i < lenb; i++) {
		if (big[i] == little[0]) {
			for (j = 0; j < lenl && i+j < lenb; j++) {
				if (little[j] != big[i + j])
					return 0;

			}
			return lenb - i;
		}
	}
	for (i = lenb-1; i >= 0; i--) {
		if (big[i] == little[lenl-1]) {
			for (j = 0; j < lenl && i - j >= 0; j++) {
				if (little[lenl-1-j] != big[i - j])
					return 0;
			}
			return -i-1;
		}
	}
	return 0;
}

int main() {
	int n,i,j;

	cin >> n;
	for (i = 0; i < n; i++){
		cin >> a[i].second;
		a[i].first = a[i].second.length();
	}
	sort(a, a + n);
	genom = a[n - 1].second;
	int lenb, lenl,res;
	for (i = 0; i < n; i++) {
		for (j = 0; j < n-1; j++) {
			if (a[j].first != 0) {
				lenl = a[j].first;
				res = cmp(genom, a[j].second);
				if (res > 0) {
					if (lenl > res) {
						genom = genom + a[j].second.substr(res, lenl - res);
					}
					a[j].first = 0;
				}
				if (res < 0) {
					if (lenl > -res) {
						genom = a[j].second.substr(0,lenl+res) + genom;
					}
					a[j].first = 0;
				}
				if (res == 0) {
					continue;
				}
			}
		}
	}
	for (j = 0; j < n - 1; j++) {
		if (a[j].first != 0) {
			cout << a[j].second;
		}
	}
	cout << genom;

}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <cstdlib>
#include <iomanip>
#include <ctime>
#include <utility>

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(x) (x)*(x)
#define _with_file
#define TASK ""
#define forn(i, n) for(int i = 0; i < (int)n; ++i)

void quit();

using namespace std;

typedef long long i64;
typedef unsigned long long u64;
#ifdef local
typedef double ld;
#else
typedef long double ld;
#endif
typedef pair <int, int> PII;
typedef pair <i64, i64> PII64;
typedef pair <ld, ld> PLL;

const ld PI = acos(-1);
const ld EPS = 1e-10;
double __t;

int n;
string s[128];
bool bad[128];

inline void mergeLeft(const string &s1, string &s2, int c) {
	s2 = s1.substr(0, s1.size() - c) + s2;
}

inline void mergeRight(const string &s1, string &s2, int c) {
	s2 += s1.substr(c, s1.size() - c);
}

inline bool checkLeft(const string &s1, const string &s2, int c) {
	if (c == 0)
		return 1;
   	int p1 = s1.size() - c;
   	int p2 = 0;
	for(int i = 0; i < c; ++i) {
    	if (s1[p1] != s2[p2])
    		return 0;
   		++p1;
   		++p2;
   	}
   	return 1;
}

inline bool checkRight(const string &s1, const string &s2, int c) {
	if (c == 0)
		return 1;
	int p1 = 0;
	int p2 = s2.size() - c;
	for(int i = 0; i < c; ++i){
    	if (s1[p1] != s2[p2])
    		return 0;
   		++p1;
   		++p2;
   	}
   	return 1;
}

int main()
{
	#ifdef local
		__t = clock();
		#ifndef _with_files
			freopen("z.in", "rt", stdin);
			freopen("z.out", "wt", stdout);
		#endif
	#endif
	#ifdef _with_files
		freopen(TASK".in", "rt", stdin);
		freopen(TASK".out", "wt", stdout);
	#endif
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for(int i = 0; i < n; ++i) {
		cin >> s[i];
	}
	int cnt = n;
	while(1) {
		bool one = 0;
		for(int i = 0; i < n; ++i) {
			if (bad[i])
				continue;
			for(int j = i + 1; j < n; ++j) {
				if (bad[j])
					continue;
				if (s[i].find(s[j]) != string::npos) {
					bad[j] = 1;
					one = 1;
				}
				if (s[j].find(s[i]) != string::npos) {
					bad[i] = 1;
					one = 1;
				}
				for(int k = min((int)s[i].size(), (int)s[j].size()) - 1; k > 0; --k) {
					if (checkLeft(s[i], s[j], k)) {
						mergeLeft(s[i], s[j], k);
						bad[i] = 1;
						one = 1;
						break;
					}
					if (checkRight(s[i], s[j], k)) {
						mergeRight(s[i], s[j], k);
						bad[i] = 1;
						one = 1;
						break;
					}
					if (checkLeft(s[j], s[i], k)) {
						mergeLeft(s[j], s[i], k);
						bad[j] = 1;
						one = 1;
						break;
					}
					if (checkRight(s[j], s[i], k)) {
						mergeRight(s[j], s[i], k);
						bad[j] = 1;
						one = 1;
						break;
					}
				}
			}
		}
		if (!one)
			break;
	}
	for(int i = 0; i < n; ++i) {
		if (!bad[i]) {
			cout << s[i];
		}
	}
	quit();
}

void quit()
{
	#ifdef local
		cerr << "\nTOTAL TIME: "<< (clock() - __t)/1000.0 << " s\n";
	#endif
	exit(0);
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <cstdlib>
#include <iomanip>
#include <ctime>
#include <utility>

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(x) (x)*(x)
#define _with_file
#define TASK ""
#define forn(i, n) for(int i = 0; i < (int)n; ++i)

void quit();

using namespace std;

typedef long long i64;
typedef unsigned long long u64;
#ifdef local
typedef double ld;
#else
typedef long double ld;
#endif
typedef pair <int, int> PII;
typedef pair <i64, i64> PII64;
typedef pair <ld, ld> PLL;

const ld PI = acos(-1);
const ld EPS = 1e-10;
double __t;

int n;
string s[128];
bool bad[128];
vector<int> g[26];

vector<int> ts;

bool u[26];
bool u2[26];

void dfs(int v) {
	u[v] = 1;
	for(int x : g[v]) {
		if (!u[x])
			dfs(x);
	}
	ts.pb(v);
}

int main()
{
	#ifdef local
		__t = clock();
		#ifndef _with_files
			freopen("z.in", "rt", stdin);
			freopen("z.out", "wt", stdout);
		#endif
	#endif
	#ifdef _with_files
		freopen(TASK".in", "rt", stdin);
		freopen(TASK".out", "wt", stdout);
	#endif
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for(int i = 0; i < n; ++i) {
		cin >> s[i];
		for(int j = 0; j < (int)s[i].size() - 1; ++j) {
			g[s[i][j] - 'a'].pb(s[i][j + 1] - 'a');
		}
		for(char c : s[i]) {
			u2[c - 'a'] = 1;
		}
	}
	for(int i = 0; i < 26; ++i) {
		if (!u[i]) {
			dfs(i);
		}
	}
	reverse(ts.begin(), ts.end());
	for(int i = 0; i < 26; ++i) {
		if (u2[ts[i]]) {
			cout << (char)(ts[i] + 'a');
		}
	}
	quit();
}

void quit()
{
	#ifdef local
		cerr << "\nTOTAL TIME: "<< (clock() - __t)/1000.0 << " s\n";
	#endif
	exit(0);
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <cstdlib>
#include <iomanip>
#include <ctime>
#include <utility>

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(x) (x)*(x)
#define _with_file
#define TASK ""
#define forn(i, n) for(int i = 0; i < (int)n; ++i)

void quit();

using namespace std;

typedef long long i64;
typedef unsigned long long u64;
#ifdef local
typedef double ld;
#else
typedef long double ld;
#endif
typedef pair <int, int> PII;
typedef pair <i64, i64> PII64;
typedef pair <ld, ld> PLL;

const ld PI = acos(-1);
const ld EPS = 1e-10;
double __t;

int n;
string s[128];

inline void mergeLeft(const string &s1, string &s2, int c) {
	s2 = s1.substr(0, s1.size() - c) + s2;
}

inline void mergeRight(const string &s1, string &s2, int c) {
	s2 += s1.substr(c, s1.size() - c);
}

inline bool checkLeft(const string &s1, const string &s2, int c) {
	if (c == 0)
		return 1;
   	int p1 = s1.size() - c;
   	int p2 = 0;
	for(int i = 0; i < c; ++i) {
    	if (s1[p1] != s2[p2])
    		return 0;
   		++p1;
   		++p2;
   	}
   	return 1;
}

inline bool checkRight(const string &s1, const string &s2, int c) {
	if (c == 0)
		return 1;
	int p1 = 0;
	int p2 = s2.size() - c;
	for(int i = 0; i < c; ++i){
    	if (s1[p1] != s2[p2])
    		return 0;
   		++p1;
   		++p2;
   	}
   	return 1;
}

int main()
{
	#ifdef local
		__t = clock();
		#ifndef _with_files
			freopen("z.in", "rt", stdin);
			freopen("z.out", "wt", stdout);
		#endif
	#endif
	#ifdef _with_files
		freopen(TASK".in", "rt", stdin);
		freopen(TASK".out", "wt", stdout);
	#endif
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for(int i = 0; i < n; ++i) {
		cin >> s[i];
	}
	sort(s, s + n, [](const string &a, const string &b) -> bool {
		return a.size() > b.size();
	});
	string ans;
	for(int i = 0; i < n; ++i) {
		auto pos = ans.find(s[i]);
		if (pos != string::npos)
			continue;
		for(int j = max(min((int)ans.size(), (int)s[i].size()) - 1, 0); j >= 0; --j) {
			if (checkLeft(s[i], ans, j)) {
				mergeLeft(s[i], ans, j);
				break;
			}
			if (checkRight(s[i], ans, j)) {
				mergeRight(s[i], ans, j);
				break;
			}
		}
	}
	cout << ans;
	quit();
}

void quit()
{
	#ifdef local
		cerr << "\nTOTAL TIME: "<< (clock() - __t)/1000.0 << " s\n";
	#endif
	exit(0);
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <cstdlib>
#include <iomanip>
#include <ctime>
#include <utility>

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(x) (x)*(x)
#define _with_file
#define TASK ""
#define forn(i, n) for(int i = 0; i < (int)n; ++i)

void quit();

using namespace std;

typedef long long i64;
typedef unsigned long long u64;
#ifdef local
typedef double ld;
#else
typedef long double ld;
#endif
typedef pair <int, int> PII;
typedef pair <i64, i64> PII64;
typedef pair <ld, ld> PLL;

const ld PI = acos(-1);
const ld EPS = 1e-10;
double __t;

int n;
string s[128];
bool bad[128];
vector<int> g[26];

vector<int> ts;

bool u[26];
bool u2[26];

void dfs(int v) {
	u[v] = 1;
	if (u2[v])
		cout << (char)(v + 'a');
	for(int x : g[v]) {
		if (!u[x])
			dfs(x);
	}
}

int main()
{
	#ifdef local
		__t = clock();
		#ifndef _with_files
			freopen("z.in", "rt", stdin);
			freopen("z.out", "wt", stdout);
		#endif
	#endif
	#ifdef _with_files
		freopen(TASK".in", "rt", stdin);
		freopen(TASK".out", "wt", stdout);
	#endif
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for(int i = 0; i < n; ++i) {
		cin >> s[i];
		for(int j = 0; j < (int)s[i].size() - 1; ++j) {
			g[s[i][j] - 'a'].pb(s[i][j + 1] - 'a');
		}
		for(char c : s[i]) {
			u2[c - 'a'] = 1;
		}
	}
	for(int i = 0; i < 26; ++i) {
		bool ok = 1;
		for(int j = 0; j < 26; ++j) {
			for(int x : g[j]) {
				if (i == x)
				 ok = 0;
			}
		}
		if (ok)
			dfs(i);
	}
	quit();
}

void quit()
{
	#ifdef local
		cerr << "\nTOTAL TIME: "<< (clock() - __t)/1000.0 << " s\n";
	#endif
	exit(0);
}


#include<bits/stdc++.h>
using namespace std;
vector<char> v[255];
int f[255];
vector<char>ans;
void dfs(char i)
{
     f[i]=2;
     vector<char>::iterator it;
     it=v[i].begin();
      for(;it!=v[i].end();it++){

                   if(f[*it]!=2)
                    dfs(*it);

      }
      ans.push_back(i);

}
 int main()
 {

     int n;
      cin>>n;
  string s;
       while(n--)
       {
           cin>>s;
            if(f[s[0]]==0)
               f[s[0]]=1;
           for(int i=0;i<s.size();i++)
            {
                v[s[i]].push_back(s[i+1]);
                      f[s[i+1]]=3;
            }

       }
       for(int i=0;i<255;i++)
        if(f[i]==1)
        dfs(i);
      reverse(ans.begin(),ans.end());
     for(int i=0;i<ans.size();i++)
      cout<<(ans[i]);
return 0;
}


#include<bits/stdc++.h>
using namespace std;
vector<int> v[255];
int f[255];
vector<char>ans;
void dfs(char i)
{
     f[i]=2;
     vector<int>::iterator it;
     it=v[i].begin();
      for(;it!=v[i].end();it++){

                   if(f[*it]!=2)
                    dfs(*it);

      }
      ans.push_back(i);

}
 int main()
 {

     int n;
      cin>>n;
  string s;
       while(n--)
       {
           cin>>s;
            if(f[s[0]]==0)
               f[s[0]]=1;
           for(int i=0;i<s.size();i++)
            {
                v[s[i]].push_back(s[i+1]);
                      f[s[i+1]]=3;
            }

       }
       for(int i=0;i<255;i++)
        if(f[i]==1)
        dfs(i);
      reverse(ans.begin(),ans.end());
     for(int i=0;i<ans.size();i++)
      cout<<char(ans[i]);
return 0;
}


#include<bits/stdc++.h>
using namespace std;
vector<int> v[255];
int f[255];
vector<char>ans;
void dfs(char i)
{
     f[i]=2;
     vector<int>::iterator it;
     it=v[i].begin();
      for(;it!=v[i].end();it++){

                   if(f[*it]!=2)
                    dfs(*it);

      }
      ans.push_back(i);

}
 int main()
 {

     int n;
      cin>>n;
  string s;
       while(n--)
       {
           cin>>s;
            if(f[s[0]]==0)
               f[s[0]]=1;
           for(int i=0;i<s.size();i++)
            {
                v[s[i]].push_back(s[i+1]);
                      f[s[i+1]]=3;
            }

       }
       for(int i=0;i<255;i++)
        if(f[i]==1)
        dfs(i);
      reverse(ans.begin(),ans.end());
     for(int i=0;i<ans.size();i++)
      cout<<(ans[i]);
return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n,mark[255];
string s;
vector<char> g[255],ans;
void dfs(char ch)
{
	mark[ch]=2;
	for (auto u:g[ch])
		if (mark[u]!=2)
			dfs(u);
	ans.push_back(ch);
}
int main()
{
	cin>>n;
	while (n--)
	{
		cin>>s;
		for (int i=0;i<(int)s.size()-1;i++) g[s[i]].push_back(s[i+1]),mark[s[i+1]]=3;
		if (mark[s[0]]!=3) mark[s[0]]=1;
	}
	for (int i=0;i<255;i++) if (mark[i]==1) dfs(i);
	reverse(ans.begin(),ans.end());
	for (auto i:ans) cout<<i;
}


#include <cstdio>

int const N = 222;

int next[N];
bool was[N];
bool slave[N];
char s[N];

int main() {
	int n;
	scanf("%d ", &n);
	for (int i = 0; i < n; ++i) {
		gets(s);
		for (int i = 0; s[i]; ++i) {
			was[s[i]] = true;
			if (s[i + 1]) {
				next[s[i]] = s[i + 1];
				slave[s[i + 1]] = true;
			}
		}
	}
	int size = 0;
	for (char x = 'a'; x <= 'z'; ++x) {
		if (was[x] && !slave[x]) {
			for (char v = x; v; v = next[v]) {
				s[size++] = v;
			}
		}
	}
	s[size] = 9;
	puts(s);
}


#include "bits/stdc++.h"
#define puba push_back
#define mapa make_pair
#define ff first
#define ss second
#define bend(_x) (_x).begin(), (_x).end()
#define szof(_x) ((int) (_x).size())
#define TASK_NAME ""

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;

int n;
char s[30];
int following[30];
string ans;
bool used[30];

int dfs(int v) {
 	used[v] = true;
 	if (following[v] != -1 && !used[following[v]]) {
 	 	dfs(following[v]);
 	}
 	ans += 'a' + v;
 	return 0;
}

int main() {
	//freopen(TASK_NAME ".in", "r", stdin);
	//freopen(TASK_NAME ".out", "w", stdout);

	memset(following, -1, sizeof following);
	memset(used, 1, sizeof used);
	scanf("%d", &n);

	for (int i = 0; i < n; ++i) {
	 	scanf("%s", s);
	 	int l = strlen(s);

	 	for (int j = 0; j < l - 1; ++j) {
	 	 	following[s[j] - 'a'] = s[j + 1] - 'a';
	 	}

	 	for (int j = 0; j < l; ++j) {
	 	 	used[s[j] - 'a'] = false;
	 	}
	}

	for (int i = 0; i < 26; ++i) {
	 	if (!used[i]) {
	 	 	dfs(i);
	 	}
	}

	reverse(bend(ans));

	cout << ans << "\n";

	return 0;
}


#include "bits/stdc++.h"
#define puba push_back
#define mapa make_pair
#define ff first
#define ss second
#define bend(_x) (_x).begin(), (_x).end()
#define szof(_x) ((int) (_x).size())
#define TASK_NAME ""

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;

int n;
char s[30];
int following[30];
int previous[30];
string ans;
bool used[30];

int main() {
	//freopen(TASK_NAME ".in", "r", stdin);
	//freopen(TASK_NAME ".out", "w", stdout);

	memset(following, -1, sizeof following);
	memset(previous, -1, sizeof previous);
	memset(used, 1, sizeof used);
	scanf("%d", &n);

	for (int i = 0; i < n; ++i) {
	 	scanf("%s", s);
	 	int l = strlen(s);

	 	for (int j = 0; j < l - 1; ++j) {
	 	 	following[s[j] - 'a'] = s[j + 1] - 'a';
	 	 	previous[s[j + 1] - 'a'] = s[j] - 'a';
	 	}

	 	for (int j = 0; j < l; ++j) {
	 	 	used[s[j] - 'a'] = false;
	 	}
	}

	for (int i = 0; i < 26; ++i) {
	 	if (previous[i] == -1 && !used[i]) {
	 	 	int pos = i;
	 	 	while (true) {
	 	 	 	ans += 'a' + pos;
	 	 	 	if (following[pos] == -1) {
	 	 	 	 	break;
	 	 	 	}
	 	 	 	pos = following[pos];
	 	 	}
	 	}
	}

	cout << ans << "\n";

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

vector< int > a[100000];
string s;
bool b[100000], b1[100000];
int n, st[100000];

void dfs(int v){
    cout << char(v);
    b[v] = true;
    for (int i = 0; i < a[v].size(); i++){
        if (!b[a[v][i]]){
            dfs(a[v][i]);
        }
    }
}

main(){
    cin >> n;
    for (int i = 1; i <= n; i++){
        cin >> s;
        for (int j = 1; j < s.length(); j++){
            int t = s[j - 1];
            a[t].push_back(s[j]);
            st[s[j]]++;
            b1[s[j]] = true;
        }
        b1[s[0]] = true;
    }
    for (int i = 'a'; i <= 'z'; i++){
        if (!b[i] && b1[i] && st[i] == 0){
            dfs(i);
        }
    }
}


#include<bits/stdc++.h>

using namespace std;
struct my{
    int v;
    int cost;
};

vector< my > a[100000];
string s[100000], ans;
bool b[100000], b1[100000];
int n, st[100000];

bool podstrok(string s1, string s2){
    if (s1 == s2) return false;
    int j = 0;
    for (int i = 0; i < s1.length(); i++){
        if (s1[i] == s2[j]) j++;
        else j = 0;
        if (j == s2.length()) return true;
    }
    return false;
}

int pref(string s1, string s2){
    int l = 0;
    int r = -1;
    int j = 0;
    for (int i = 0; i < s1.length(); i++){
        if (s1[i] == s2[j]) {r++; j++;}
        else{
                l = i;
                r = i - 1;
                j = 0;
        }
    }
    return (r - l + 1);
}

void dfs(int v, int need){
    b1[v] = true;
    int t = s[v].length();
    for (int i = need; i < t; i++)
        ans = ans + s[v][i];
    for (int i = 0; i < a[v].size(); i++){
        if (!b1[a[v][i].v]) dfs(a[v][i].v, a[v][i].cost);
    }
}

main(){
    cin >> n;
    for (int i = 1; i <= n; i++){
        cin >> s[i];
        b[i] = true;
    }
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
        if (i != j){
            if (podstrok(s[i],s[j])){
            b[j] = false;
        }
        }
    for (int i = 1; i <= n; i++)
        for (int j = i + 1; j <= n; j++)
        if (s[i]==s[j]){
            b[j] = false;
        }
   // cout << pref(s[2],s[1]) << endl;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            if (i != j && b[i] && b[j] && (pref(s[i],s[j])!=0)){
            my t;
            t.v = j;
            t.cost = pref(s[i],s[j]);
            a[i].push_back(t);
            st[j]++;
        }
    ans = "";
    for (int i = 1; i <= n; i++){
        if (b[i] && st[i] == 0){
            dfs(i, 0);
        }
    }
    cout << ans;
}


#include<bits/stdc++.h>

using namespace std;
struct my{
    int v;
    int cost;
};

vector< my > a[100000];
string s[100000], ans;
bool b[100000];
int n, st[100000];

bool podstrok(string s1, string s2){
    if (s1 == s2) return false;
    int j = 0;
    for (int i = 0; i < s1.length(); i++){
        if (s1[i] == s2[j]) j++;
        else j = 0;
        if (j == s2.length()) return true;
    }
    return false;
}

int pref(string s1, string s2){
    int l = 0;
    int r = -1;
    int j = 0;
    for (int i = 0; i < s1.length(); i++){
        if (s1[i] == s2[j]) {r++; j++;}
        else{
                l = i;
                r = i - 1;
                j = 0;
        }
    }
    return (r - l + 1);
}

void dfs(int v, int need){
    int t = s[v].length();
    for (int i = need; i < t; i++)
        ans = ans + s[v][i];
    for (int i = 0; i < a[v].size(); i++){
        dfs(a[v][i].v, a[v][i].cost);
    }
}

main(){
    cin >> n;
    for (int i = 1; i <= n; i++){
        cin >> s[i];
        b[i] = true;
    }
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
        if (i != j){
            if (podstrok(s[i],s[j])){
            b[j] = false;
        }
        }
    for (int i = 1; i <= n; i++)
        for (int j = i + 1; j <= n; j++)
        if (s[i]==s[j]){
            b[j] = false;
        }
   // cout << pref(s[2],s[1]) << endl;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            if (i != j && b[i] && b[j] && (pref(s[i],s[j])!=0)){
            my t;
            t.v = j;
            t.cost = pref(s[i],s[j]);
            a[i].push_back(t);
            st[j]++;
        }
    ans = "";
    for (int i = 1; i <= n; i++){
        if (b[i] && st[i] == 0){
            dfs(i, 0);
        }
    }
    cout << ans;
}