#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD=1e9+7;
typedef long double ld;
typedef pair<ll,ll> pll;
const ld pi=3.14159265359;
const ll N=3e5+5;
#define REP(i,n) for(ll i=0;i<n;i++)
#define REP1(i,n) for(ll i=1;i<=n;i++)
#define pb push_back
#define mp make_pair
#define X first
#define Y second
#define setp setprecision
#define lwb lower_bound
#define SZ(a) (ll)a.size()

ll n,ok=1,x;
string s,tmp;
ll u[26][26],vis[26],d[26];
vector<ll> v[26];

void DFS(ll w){
	vis[w]=2;
	for(auto i:v[w]){
		if(vis[i]==2)ok=0;
		if(!vis[i])DFS(i);
	}
	vis[w]=1;
}

int main(){
	ios_base::sync_with_stdio(0);cin.tie(0);
	cin>>n;
	while(n--){
		cin>>s;
		REP(i,SZ(s)-1)u[s[i]-'a'][s[i+1]-'a']=1;
	}
	REP(i,26)REP(j,26)if(u[i][j])v[i].pb(j),d[j]++;
	REP(i,26){
		if(vis[i]==0)DFS(i);
		if(d[i]>1||SZ(v[i])>1)ok=0;
	}
	if(!ok){cout<<"NO\n";return 0;}
	memset(vis,0,sizeof(vis));
	REP(i,26){
		if(d[i]==0&&SZ(v[i])){
			x=i;
			while(SZ(v[x]))tmp.pb(x+'a'),x=v[x][0];
			tmp.pb(x+'a');
		}
	}
	cout<<tmp<<"\n";
	return 0;
}


#include<iostream>
#include<set>
#include<map>
#include<functional>
#include<queue>
#include<string.h>
#include <sstream>
#include<stdio.h>
#include<iomanip>
#include<stdlib.h>
#include<math.h>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<string>
#include<stack>
#include<queue>
#include<bitset>
#include<assert.h>
#include<fstream>
typedef long long ll;
typedef unsigned long long ull;
typedef long double LD;
#define lp(i,n) for (int i = 0; i < n; i++)
#define all(x) x.begin(), x.end()
#define sz(a) (int)a.size()
#define sqr(x) ((x) * (x))
#define pi pair<ll, ll>
#define mk(a, b) make_pair(a, b)
#define nextI nextInt()
#define nextD nextDouble()
#define pb(a) push_back(a)
#define nextL nextLong()
#define nextC nextChar()
#define line newLine()
#define Left(x) (2 * x + 1)
#define Right(x) (2 * x + 2)
int nextInt(){ int x; scanf("%d", &x); return x; }
double nextDouble(){ double x; scanf("%lf", &x); return x; }
ll nextLong(){ ll x; scanf("%I64d", &x); return x; }
char nextChar(){ char x; scanf("%c", &x); return x; }
void newLine(){ printf("\n"); }
ll powM(ll a, ll b, ll MOD){ ll x = 1, y = a; while (b > 0){ if (b % 2 == 1){ x = (x*y); if (x>MOD) x %= MOD; }y = (y*y); if (y>MOD) y %= MOD; b /= 2; }return x; }
ll gcd(ll a, ll b){ return b == 0 ? a : gcd(b, a%b); }
ll lcm(ll a, ll b){ return (a*b) / gcd(a, b); }
int countSetBits(ll n){ int ans = 0;  while (n != 0){ n -= (n & -n); ++ans; } return ans; }
ll mod = 1000000007;
ll mod2 = 1000000009;
const int N = 100100;
const int M = 111;
const int LOG = 21;
const int INF = 1e9;
const LD EPS = 1e-6;
const LD PI = 2 * acos(0);
using namespace std;
int from[26];
int to[26];
bool used[26];
bool exist[26];
vector<char> sol;
bool cycle = false;
void DFS(int x){
	sol.push_back(char(x + 'a'));
	used[x] = 1;
	if (to[x] == -1) return;
	if (used[to[x]]){
		cycle = true;
		return;
	}
	DFS(to[x]);
}
int main(){
#ifdef HOME
	freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
#endif
	memset(from, -1, sizeof from);
	memset(to, -1, sizeof to);
	int n = nextI;
	for (int i = 0; i < n; i++){
		string s; cin >> s;
		int sz = s.length();
		if (sz == 1){
			exist[s[0] - 'a'] = 1;
			continue;
		}
		for (int j = 0; j < sz - 1; j++){
			int c1 = s[j] - 'a';
			int c2 = s[j + 1] - 'a';
			exist[c1] = 1;
			exist[c2] = 1;
			if (to[c1] == -1) to[c1] = c2;
			else{
				if (to[c1] != c2){ puts("NO"); return 0; }
			}

			if (from[c2] == -1) from[c2] = c1;
			else{
				if (from[c2] != c1){ puts("NO"); return 0; }
			}
		}
	}

	for (int i = 0; i < 26; i++){
		if (exist[i] && !used[i] && from[i] == -1){
			DFS(i);
			if (cycle){ puts("NO"); return 0; }

		}
	}
	for (int i = 0; i < 26; i++){
		if (exist[i] && !used[i]){
			puts("NO");
			return 0;
		}
	}

	puts("YES");
	for (int i = 0; i < sol.size(); i++) cout << sol[i];
}


#include<iostream>
#include<set>
#include<map>
#include<functional>
#include<queue>
#include<string.h>
#include <sstream>
#include<stdio.h>
#include<iomanip>
#include<stdlib.h>
#include<math.h>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<string>
#include<stack>
#include<queue>
#include<bitset>
#include<assert.h>
#include<fstream>
typedef long long ll;
typedef unsigned long long ull;
typedef long double LD;
#define lp(i,n) for (int i = 0; i < n; i++)
#define all(x) x.begin(), x.end()
#define sz(a) (int)a.size()
#define sqr(x) ((x) * (x))
#define pi pair<ll, ll>
#define mk(a, b) make_pair(a, b)
#define nextI nextInt()
#define nextD nextDouble()
#define pb(a) push_back(a)
#define nextL nextLong()
#define nextC nextChar()
#define line newLine()
#define Left(x) (2 * x + 1)
#define Right(x) (2 * x + 2)
int nextInt(){ int x; scanf("%d", &x); return x; }
double nextDouble(){ double x; scanf("%lf", &x); return x; }
ll nextLong(){ ll x; scanf("%I64d", &x); return x; }
char nextChar(){ char x; scanf("%c", &x); return x; }
void newLine(){ printf("\n"); }
ll powM(ll a, ll b, ll MOD){ ll x = 1, y = a; while (b > 0){ if (b % 2 == 1){ x = (x*y); if (x>MOD) x %= MOD; }y = (y*y); if (y>MOD) y %= MOD; b /= 2; }return x; }
ll gcd(ll a, ll b){ return b == 0 ? a : gcd(b, a%b); }
ll lcm(ll a, ll b){ return (a*b) / gcd(a, b); }
int countSetBits(ll n){ int ans = 0;  while (n != 0){ n -= (n & -n); ++ans; } return ans; }
ll mod = 1000000007;
ll mod2 = 1000000009;
const int N = 100100;
const int M = 111;
const int LOG = 21;
const int INF = 1e9;
const LD EPS = 1e-6;
const LD PI = 2 * acos(0);
using namespace std;
int from[26];
int to[26];
bool used[26];
bool exist[26];
vector<char> sol;
bool cycle = false;
void DFS(int x){
	sol.push_back(char(x + 'a'));
	used[x] = 1;
	if (to[x] == -1) return;
	if (used[to[x]]){
		cycle = true;
		return;
	}
	DFS(to[x]);
}
int main(){
#ifdef HOME
	freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
#endif
	memset(from, -1, sizeof from);
	memset(to, -1, sizeof to);
	int n = nextI;
	for (int i = 0; i < n; i++){
		string s; cin >> s;
		int sz = s.length();
		if (sz == 1){
			exist[s[0] - 'a'] = 1;
			continue;
		}
		for (int j = 0; j < sz - 1; j++){
			int c1 = s[j] - 'a';
			int c2 = s[j + 1] - 'a';
			exist[c1] = 1;
			exist[c2] = 1;
			if (to[c1] == -1) to[c1] = c2;
			else{
				if (to[c1] != c2){ puts("NO"); return 0; }
			}

			if (from[c2] == -1) from[c2] = c1;
			else{
				if (from[c2] != c1){ puts("NO"); return 0; }
			}
		}
	}

	for (int i = 0; i < 26; i++){
		if (exist[i] && !used[i] && from[i] == -1){
			DFS(i);
			if (cycle){ puts("NO"); return 0; }

		}
	}
	for (int i = 0; i < 26; i++){
		if (exist[i] && !used[i]){
			puts("NO");
			return 0;
		}
	}

	for (int i = 0; i < sol.size(); i++) cout << sol[i];
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
//#pragma GCC optimize("O3")
//#pragma GCC target("sse4")

#define deb(x) cout << #x << " = " << x << "\n"
#define all(x) (x).begin(), (x).end()
#define len(x) (int) x.size()
#define lsb(x) (x) & -(x)
#define l(x) (x << 1) + 1
#define r(x) (x << 1) + 2
#define v(x) (int)(x - 'a')

#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ld, ld> pld;
typedef pair <ll, ll> pll;

template <class T1, class cmp = less <T1>> using Tree = tree <T1, null_type, cmp, rb_tree_tag, tree_order_statistics_node_update>;
template <class T1, class T2> using um = unordered_map <T1, T2>;
template <class T> using us = unordered_set <T>;
template <class T> using vec = vector <T>;

const ll infll = numeric_limits <ll>::max() >> 1;
const int inf = numeric_limits <int>::max() >> 1;
const int N = 26;
int n;

int nxt[N];
bool vis[N];
bool was[N];
bool stk[N];

vec <int> ts;
vec <string> segs;

void input() {
    cin >> n;
    fill(nxt, nxt + N, -1);
    for(int i = 0; i < n; ++i) {
        string t; cin >> t;
        for(int j = 1; j < len(t); ++j) {
            int x = v(t[j - 1]);
            int y = v(t[j]);
            if(nxt[x] != -1 && nxt[x] != y) {
                cout << "NO\n";
                exit(0);
            }
            nxt[x] = y;
        }
        for(char c: t) {
            was[v(c)] = 1;
        }
    }
}

void dfs(int u) {
    stk[u] = 1;
    vis[u] = 1;
    int v = nxt[u];
    if(v != -1) {
        if(stk[v]) {
            cout << "NO\n";
            exit(0);
        }
        if(!vis[v]) {
            dfs(v);
        }
    }
    stk[u] = 0;
    ts.pb(u);
}

void make(int u, string &s) {
    s += (char)('a' + u);
    vis[u] = 1;
    int v = nxt[u];
    if(v != -1) {
        if(!vis[v]) {
            make(v, s);
        }
    }
}

void solve() {
    for(int i = 0; i < N; ++i) {
        if(was[i] && !vis[i]) {
            dfs(i);
        }
    }
    reverse(all(ts));
    fill(vis, vis + N, 0);
    for(int e: ts) {
        if(!vis[e]) {
            string seg;
            make(e, seg);
            segs.pb(seg);
        }
    }
    sort(all(segs));
    for(string e: segs) {
        cout << e;
    }
    cout << "\n";
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    input();
    solve();
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
//#pragma GCC optimize("O3")
//#pragma GCC target("sse4")

#define deb(x) cout << #x << " = " << x << "\n"
#define all(x) (x).begin(), (x).end()
#define len(x) (int) x.size()
#define lsb(x) (x) & -(x)
#define l(x) (x << 1) + 1
#define r(x) (x << 1) + 2
#define v(x) (int)(x - 'a')

#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ld, ld> pld;
typedef pair <ll, ll> pll;

template <class T1, class cmp = less <T1>> using Tree = tree <T1, null_type, cmp, rb_tree_tag, tree_order_statistics_node_update>;
template <class T1, class T2> using um = unordered_map <T1, T2>;
template <class T> using us = unordered_set <T>;
template <class T> using vec = vector <T>;

const ll infll = numeric_limits <ll>::max() >> 1;
const int inf = numeric_limits <int>::max() >> 1;
const int N = 26;
int n;

int nxt[N];
int pre[N];
bool vis[N];
bool was[N];
bool stk[N];

vec <int> ts;
vec <string> segs;

void input() {
    cin >> n;
    fill(nxt, nxt + N, -1);
    fill(pre, pre + N, -1);
    for(int i = 0; i < n; ++i) {
        string t; cin >> t;
        for(int j = 1; j < len(t); ++j) {
            int x = v(t[j - 1]);
            int y = v(t[j]);
            if(nxt[x] != -1 && nxt[x] != y) {
                cout << "NO\n";
                exit(0);
            }
            if(pre[y] != -1 && pre[y] != x) {
                cout << "NO\n";
                exit(0);
            }
            nxt[x] = y;
            pre[y] = x;
        }
        for(char c: t) {
            was[v(c)] = 1;
        }
    }
}

void dfs(int u) {
    stk[u] = 1;
    vis[u] = 1;
    int v = nxt[u];
    if(v != -1) {
        if(stk[v]) {
            cout << "NO\n";
            exit(0);
        }
        if(!vis[v]) {
            dfs(v);
        }
    }
    stk[u] = 0;
    ts.pb(u);
}

void make(int u, string &s) {
    s += (char)('a' + u);
    vis[u] = 1;
    int v = nxt[u];
    if(v != -1) {
        if(!vis[v]) {
            make(v, s);
        }
    }
}

void solve() {
    for(int i = 0; i < N; ++i) {
        if(was[i] && !vis[i]) {
            dfs(i);
        }
    }
    reverse(all(ts));
    fill(vis, vis + N, 0);
    for(int e: ts) {
        if(!vis[e]) {
            string seg;
            make(e, seg);
            segs.pb(seg);
        }
    }
    sort(all(segs));
    for(string e: segs) {
        cout << e;
    }
    cout << "\n";
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    input();
    solve();
}


#include <bits/stdc++.h>
typedef long long ll;
#define all(c) (c).begin(), (c).end()
#define pb push_back
#define FOR(i,a,b) for( ll i = (ll)(a); i <= (ll)(b); i++ )
#define ROF(i,a,b) for( ll i = (ll)(a); i >= (ll)(b); i-- )
#define debug(x) cerr << "[DEBUG] " << #x << " = " << x << endl;
#define matrix vector< vector<ll> >
#define F first
#define S second
#define mp make_pair
#define INPFILE freopen("input.in","r",stdin)
#define OUTFILE freopen("output.out","w",stdout)
#define BOOST ios_base::sync_with_stdio(false); cin.tie(NULL)
using namespace std;

string join(string base, string ext) {
  ll start = 0;
  while(start < base.size()) {
    if(base[start] == ext[0]) break;
    start++;
  }
  ll cur = 0;
  while(start < base.size() && cur < ext.size()) {
    if(base[start] != ext[cur]) {
      cout << "NO";
      exit(0);
    }
    start++; cur++;
  }
  FOR(i,cur,ext.size()-1) {
    base.pb(ext[i]);
  }
  return base;
}

int main() {
  ll n; cin >> n;
  string s[n + 1];

  vector<pair<ll,ll>> v[256];

  FOR(i,1,n) {
    cin >> s[i];
    v[s[i][0]].pb({s[i].size(), i});
  }

   vector<string> left;

  FOR(i,'a','z') {
    if(v[i].empty()) continue;
    sort(all(v[i]));

    string last = s[v[i].back().S];
    left.pb(last);

    FOR(j,0,v[i].size()-2) {
      string cur = s[v[i][j].S];
      FOR(k,0,cur.size()-1) {
        if(cur[k] != last[k]) {
          cout << "NO";
          return 0;
        }
      }
    }
  }

  ll till = left.size()-1;
  FOR(i,0,till) {
    FOR(j,0,till) {
      if(i == j) continue;
      bool pos = false;
      for(ll c : left[j]) if(c == left[i][0]) {
        pos = true;
        break;
      }
      if(pos) {
        left[j] = join(left[j], left[i]);
        left[i] = "";
        break;
      }
    }
  }

  vector<string> col;
  vector<ll> cnt(256, 0);

  for(string u : left) {
    if(u == "") continue;
    for(char c : u) cnt[c]++;
    col.pb(u);
  }

  FOR(i,'a','z') if(cnt[i] > 1) {
    cout << "NO";
    return 0;
  }

  sort(all(col));

  for(string p : col) cout << p;
}


#include <bits/stdc++.h>
typedef long long ll;
#define all(c) (c).begin(), (c).end()
#define pb push_back
#define FOR(i,a,b) for( ll i = (ll)(a); i <= (ll)(b); i++ )
#define ROF(i,a,b) for( ll i = (ll)(a); i >= (ll)(b); i-- )
#define debug(x) ;//cout << "[DEBUG] " << #x << " = " << x << endl;
#define matrix vector< vector<ll> >
#define F first
#define S second
#define mp make_pair
#define INPFILE freopen("input.in","r",stdin)
#define OUTFILE freopen("output.out","w",stdout)
#define BOOST ios_base::sync_with_stdio(false); cin.tie(NULL)
using namespace std;

string join(string base, string ext) {
  ll start = 0;
  while(start < base.size()) {
    if(base[start] == ext[0]) break;
    start++;
  }
  ll cur = 0;
  while(start < base.size() && cur < ext.size()) {
    if(base[start] != ext[cur]) {
      cout << "NO2";
      exit(0);
    }
    start++; cur++;
  }
  FOR(i,cur,ext.size()-1) {
    base.pb(ext[i]);
  }
  return base;
}

int main() {
  ll n; cin >> n;
  string s[n + 5];

  vector<pair<ll,ll>> v[256];

  FOR(i,1,n) {
    cin >> s[i];
    v[s[i][0]].pb({s[i].size(), i});
  }

   vector<string> left;

  FOR(i,'a','z') {
    if(v[i].empty()) continue;
    sort(all(v[i]));

    debug(v[i].back().S);
    debug(v[i].size())
    string last = s[v[i].back().S];
    left.pb(last);
    debug(last);

    ll sz = v[i].size();
    FOR(j,0,sz-2) {
      string cur = s[v[i][j].S];
      debug(cur);
      FOR(k,0,cur.size()-1) {
        if(cur[k] != last[k]) {
          cout << "NO1";
          return 0;
        }
      }
    }
  }

  ll till = left.size()-1;
  FOR(i,0,till) {
    FOR(j,0,till) {
      if(i == j) continue;
      bool pos = false;
      for(ll c : left[j]) if(c == left[i][0]) {
        pos = true;
        break;
      }
      if(pos) {
        left[j] = join(left[j], left[i]);
        left[i] = "";
        break;
      }
    }
  }

  vector<string> col;
  vector<ll> cnt(256, 0);

  for(string u : left) {
    if(u == "") continue;
    for(char c : u) cnt[c]++;
    col.pb(u);
  }

  FOR(i,'a','z') if(cnt[i] > 1) {
    cout << "NO3";
    return 0;
  }

  sort(all(col));

  for(string p : col) cout << p;
}


#include <bits/stdc++.h>
typedef long long ll;
#define all(c) (c).begin(), (c).end()
#define pb push_back
#define FOR(i,a,b) for( ll i = (ll)(a); i <= (ll)(b); i++ )
#define ROF(i,a,b) for( ll i = (ll)(a); i >= (ll)(b); i-- )
#define debug(x) cerr << "[DEBUG] " << #x << " = " << x << endl;
#define matrix vector< vector<ll> >
#define F first
#define S second
#define mp make_pair
#define INPFILE freopen("input.in","r",stdin)
#define OUTFILE freopen("output.out","w",stdout)
#define BOOST ios_base::sync_with_stdio(false); cin.tie(NULL)
using namespace std;

string join(string base, string ext) {
  ll start = 0;
  while(start < base.size()) {
    if(base[start] == ext[0]) break;
    start++;
  }
  ll cur = 0;
  while(start < base.size() && cur < ext.size()) {
    if(base[start] != ext[cur]) {
      cout << "NO";
      exit(0);
    }
    start++; cur++;
  }
  FOR(i,cur,ext.size()-1) {
    base.pb(ext[i]);
  }
  return base;
}

int main() {
  ll n; cin >> n;
  string s[n + 1];

  vector<pair<ll,ll>> v[256];

  FOR(i,1,n) {
    cin >> s[i];
    v[s[i][0]].pb({s[i].size(), i});
  }

   vector<string> left;

  FOR(i,'a','z') {
    if(v[i].empty()) continue;
    sort(all(v[i]));

    string last = s[v[i].back().S];
    left.pb(last);

    ll sz = v[i].size();
    FOR(j,0,sz-2) {
      string cur = s[v[i][j].S];
      FOR(k,0,cur.size()-1) {
        if(cur[k] != last[k]) {
          cout << "NO";
          return 0;
        }
      }
    }
  }

  ll till = left.size()-1;
  FOR(i,0,till) {
    FOR(j,0,till) {
      if(i == j) continue;
      bool pos = false;
      for(ll c : left[j]) if(c == left[i][0]) {
        pos = true;
        break;
      }
      if(pos) {
        left[j] = join(left[j], left[i]);
        left[i] = "";
        break;
      }
    }
  }

  vector<string> col;
  vector<ll> cnt(256, 0);

  for(string u : left) {
    if(u == "") continue;
    for(char c : u) cnt[c]++;
    col.pb(u);
  }

  FOR(i,'a','z') if(cnt[i] > 1) {
    cout << "NO";
    return 0;
  }

  sort(all(col));

  for(string p : col) cout << p;
}


#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;

#define ff               first
#define ss               second
#define pb               push_back
#define all(x)           (x).begin(), (x).end()
#define mem0(x)          memset(x, 0, sizeof (x))
#define mem1(x)          memset(x, -1, sizeof (x))

typedef pair<int, int> ii;
typedef vector <int> vi;
typedef vector<ii> vii;
typedef vector <vii> vvii;
typedef vector<vi> vvi;
typedef long long ll;
typedef vector <ll> vll;
typedef vector<vll> vvll;
typedef pair<ll, ll> pll;

vector<set<int>> g;

void print(int u){
    cout << (char)(u+'a');
    for (int v: g[u]) print(v);
}

vi vis;
int cy = 0;

void cycle(int u){
    vis[u] = 1;
    for (int v: g[u]){
        if (vis[v] == 1) cy = 1;
        if (!vis[v]) cycle(v);
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    vi flag(26,0);
    vi in_degree(26,0);
    g.assign(26, set<int>());
    int n; cin >> n;
    for (int i = 0; i < n; ++i) {
        string s; cin >> s;
        vi fr(26,0);
        int m = s.size();
        int f = 0;
        for (int j = 0; j < m; ++j) {
            fr[s[j]-'a']++;
            flag[s[j]-'a'] = 1;
            if (j < m-1) g[s[j]-'a'].insert(s[j+1]-'a');
            if (g[s[j]-'a'].size() > 1) f = 1;
        }
        for (int j = 0; j < 26; ++j) if (fr[j] > 1 || f){
            cout << "NO\n";
            return 0;
        }
    }
    for (int k = 0; k < 26; ++k) {
        for (int u: g[k]) in_degree[u]++;
    }
    set<int> st;
    vis.assign(26, 0);
    for (int i = 0; i < 26; ++i) {
        if (!vis[i]) cycle(i);
        if (!in_degree[i] && flag[i]) st.insert(i);
    }
    if (cy){
        cout << "NO\n";
        return 0;
    }
    while (st.size()){
        int u = *st.begin();
        st.erase(u); print(u);
    }
}


#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;

#define ff               first
#define ss               second
#define pb               push_back
#define all(x)           (x).begin(), (x).end()
#define mem0(x)          memset(x, 0, sizeof (x))
#define mem1(x)          memset(x, -1, sizeof (x))

typedef pair<int, int> ii;
typedef vector <int> vi;
typedef vector<ii> vii;
typedef vector <vii> vvii;
typedef vector<vi> vvi;
typedef long long ll;
typedef vector <ll> vll;
typedef vector<vll> vvll;
typedef pair<ll, ll> pll;

vector<set<int>> g;
vector<set<int>> gr;

void print(int u){
    cout << (char)(u+'a');
    for (int v: g[u]) print(v);
}

vi vis;
vi visr;
int cy = 0;

void cycle(int u){
    vis[u] = 1;
    for (int v: g[u]){
        if (vis[v] == 1) cy = 1;
        if (!vis[v]) cycle(v);
    }
    vis[u] = 2;
}

void cycler(int u){
    visr[u] = 1;
    for (int v: gr[u]){
        if (visr[v] == 1) cy = 1;
        if (!visr[v]) cycler(v);
    }
    visr[u] = 2;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    vi flag(26,0);
    vi in_degree(26,0);
    g.assign(26, set<int>());
    gr.assign(26, set<int>());
    int n; cin >> n;
    for (int i = 0; i < n; ++i) {
        string s; cin >> s;
        vi fr(26,0);
        int m = s.size();
        int f = 0;
        for (int j = 0; j < m; ++j) {
            fr[s[j]-'a']++;
            flag[s[j]-'a'] = 1;
            if (j < m-1) {
                g[s[j]-'a'].insert(s[j+1]-'a');
                gr[s[j+1]-'a'].insert(s[j]-'a');
            }
            if (g[s[j]-'a'].size() > 1 || (j < m-1 && gr[s[j+1]-'a'].size() > 1)) f = 1;
        }
        for (int j = 0; j < 26; ++j) if (fr[j] > 1 || f){
            cout << "NO\n";
            return 0;
        }
    }
    for (int k = 0; k < 26; ++k) {
        for (int u: g[k]) in_degree[u]++;
    }
    set<int> st;
    vis.assign(26, 0);
    visr.assign(26, 0);
    for (int i = 0; i < 26; ++i) {
        if (!vis[i]) cycle(i);
        if (!visr[i]) cycler(i);
        if (!in_degree[i] && flag[i]) st.insert(i);
    }
    if (cy){
        cout << "NO\n";
        return 0;
    }
    while (st.size()){
        int u = *st.begin();
        st.erase(u); print(u);
    }
}


#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;

#define ff               first
#define ss               second
#define pb               push_back
#define all(x)           (x).begin(), (x).end()
#define mem0(x)          memset(x, 0, sizeof (x))
#define mem1(x)          memset(x, -1, sizeof (x))

typedef pair<int, int> ii;
typedef vector <int> vi;
typedef vector<ii> vii;
typedef vector <vii> vvii;
typedef vector<vi> vvi;
typedef long long ll;
typedef vector <ll> vll;
typedef vector<vll> vvll;
typedef pair<ll, ll> pll;

vector<set<int>> g;
vector<set<int>> gr;

void print(int u){
    cout << (char)(u+'a');
    for (int v: g[u]) print(v);
}

vi vis;
vi visr;
int cy = 0;

void cycle(int u){
    vis[u] = 1;
    for (int v: g[u]){
        if (vis[v] == 1) cy = 1;
        if (!vis[v]) cycle(v);
    }
    vis[u] = 2;
}

void cycler(int u){
    visr[u] = 1;
    for (int v: gr[u]){
        if (visr[v] == 1) cy = 1;
        if (!visr[v]) cycler(v);
    }
    visr[u] = 2;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    vi flag(26,0);
    vi in_degree(26,0);
    g.assign(26, set<int>());
    gr.assign(26, set<int>());
    int n; cin >> n;
    for (int i = 0; i < n; ++i) {
        string s; cin >> s;
        vi fr(26,0);
        int m = s.size();
        int f = 0;
        for (int j = 0; j < m; ++j) {
            fr[s[j]-'a']++;
            flag[s[j]-'a'] = 1;
            if (j < m-1) {
                g[s[j]-'a'].insert(s[j+1]-'a');
                gr[s[j+1]-'a'].insert(s[j]-'a');
            }
            if (g[s[j]-'a'].size() > 1 || gr[s[j+1]-'a'].size() > 1) f = 1;
        }
        for (int j = 0; j < 26; ++j) if (fr[j] > 1 || f){
            cout << "NO\n";
            return 0;
        }
    }
    for (int k = 0; k < 26; ++k) {
        for (int u: g[k]) in_degree[u]++;
    }
    set<int> st;
    vis.assign(26, 0);
    visr.assign(26, 0);
    for (int i = 0; i < 26; ++i) {
        if (!vis[i]) cycle(i);
        if (!visr[i]) cycler(i);
        if (!in_degree[i] && flag[i]) st.insert(i);
    }
    if (cy){
        cout << "NO\n";
        return 0;
    }
    while (st.size()){
        int u = *st.begin();
        st.erase(u); print(u);
    }
}


#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;

#define ff               first
#define ss               second
#define pb               push_back
#define all(x)           (x).begin(), (x).end()
#define mem0(x)          memset(x, 0, sizeof (x))
#define mem1(x)          memset(x, -1, sizeof (x))

typedef pair<int, int> ii;
typedef vector <int> vi;
typedef vector<ii> vii;
typedef vector <vii> vvii;
typedef vector<vi> vvi;
typedef long long ll;
typedef vector <ll> vll;
typedef vector<vll> vvll;
typedef pair<ll, ll> pll;

vector<set<int>> g;

void print(int u){
    cout << (char)(u+'a');
    for (int v: g[u]) print(v);
}

vi vis;
int cy = 0;

void cycle(int u){
    vis[u] = 1;
    for (int v: g[u]){
        if (vis[v] == 1) cy = 1;
        if (!vis[v]) cycle(v);
    }
    vis[u] = 2;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    vi flag(26,0);
    vi in_degree(26,0);
    g.assign(26, set<int>());
    int n; cin >> n;
    for (int i = 0; i < n; ++i) {
        string s; cin >> s;
        vi fr(26,0);
        int m = s.size();
        int f = 0;
        for (int j = 0; j < m; ++j) {
            fr[s[j]-'a']++;
            flag[s[j]-'a'] = 1;
            if (j < m-1) g[s[j]-'a'].insert(s[j+1]-'a');
            if (g[s[j]-'a'].size() > 1) f = 1;
        }
        for (int j = 0; j < 26; ++j) if (fr[j] > 1 || f){
            cout << "NO\n";
            return 0;
        }
    }
    for (int k = 0; k < 26; ++k) {
        for (int u: g[k]) in_degree[u]++;
    }
    set<int> st;
    vis.assign(26, 0);
    for (int i = 0; i < 26; ++i) {
        if (!vis[i]) cycle(i);
        if (!in_degree[i] && flag[i]) st.insert(i);
    }
    if (cy){
        cout << "NO\n";
        return 0;
    }
    while (st.size()){
        int u = *st.begin();
        st.erase(u); print(u);
    }
}


#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;cin>>n;
	int f=1;
	vector<string>word(n);
	vector<vector<int>>adj(26);
	vector<int>vis(26,-1),parent(26,-1);
	for(auto&i:word)cin>>i;
	for(auto&s:word){
		if(f==0)break;
		vector<int>st(26);
		char p=s[0];
		vis[p-'a']=0;
		for(int i=1;i<s.size() && f;i++){
			st[p-'a']=1;
			int sz= adj[p-'a'].size();
			if(st[s[i]-'a']==1)f=0;
			else if(sz==0)adj[p-'a'].push_back(s[i]-'a');
			else if(adj[p-'a'][0]!=(s[i]-'a'))f=0;
			parent[s[i]-'a']=p-'a';
			p=s[i];
			vis[p-'a']=0;
		}
	}
	if (f==0){cout<<"NO";return 0;}
	vector<string>parts;
	for(int i=0;i<26;i++){
		if(vis[i]==0 && parent[i]==-1){
			string temp="";
			int p=i;
			vis[p]=1;
			temp+=char(p+'a');
			while(adj[p].size()==1){
				p=adj[p][0];
				vis[p]=1;
				temp+=char(p+'a');
			}
			parts.push_back(temp);
		}
	}
	sort(parts.begin(),parts.end());
	for(auto s:parts)
		cout<<s;
}


#include<bits/stdc++.h>
using namespace std;
vector<vector<int>>adj(26);
vector<int>vis(26,-1),parent(26,-1),c(26),st(26);
bool check(int x){
	bool t=1;
	c[x]=1;
	st[x]=1;
	for(auto&v:adj[x]){
		if(st[v]==1)return 0;
		if(c[v]==0)t=t&check(v);
	}
	st[x]=0;
	return t;
}
int main(){
	int n;cin>>n;
	int f=1;
	vector<string>word(n);
	for(auto&i:word)cin>>i;
	for(auto&s:word){
		if(f==0)break;
		vector<int>st(26);
		char p=s[0];
		vis[p-'a']=0;
		for(int i=1;i<s.size() && f;i++){
			st[p-'a']=1;
			int sz= adj[p-'a'].size();
			if(st[s[i]-'a']==1)f=0;
			else if(sz==0)adj[p-'a'].push_back(s[i]-'a');
			else if(adj[p-'a'][0]!=(s[i]-'a'))f=0;
			parent[s[i]-'a']=p-'a';
			p=s[i];
			vis[p-'a']=0;
		}
	}
	for(int i=0;i<26;i++)
		if(c[i]==0)
			f=(f&check(i));
	if (f==0){cout<<"NO";return 0;}
	vector<string>parts;
	for(int i=0;i<26;i++){
		if(vis[i]==0 && parent[i]==-1){
			string temp="";
			int p=i;
			vis[p]=1;
			temp+=char(p+'a');
			while(adj[p].size()==1){
				p=adj[p][0];
				vis[p]=1;
				temp+=char(p+'a');
			}
			parts.push_back(temp);
		}
	}
	sort(parts.begin(),parts.end());
	for(auto s:parts)
		cout<<s;
}


#include<bits/stdc++.h>
using namespace std;
vector<vector<int>>adj(26);
vector<int>vis(26,-1),parent(26,-1),c(26),st(26),cnt(26);
bool check(int x){
	bool t=1;
	c[x]=1;
	st[x]=1;
	for(auto&v:adj[x]){
		if(st[v]==1)return 0;
		if(c[v]==0)t=t&check(v);
	}
	st[x]=0;
	return t;
}
int main(){
	int n;cin>>n;
	int f=1;
	vector<string>word(n);
	for(auto&i:word)cin>>i;
	for(auto&s:word){
		if(f==0)break;
		vector<int>st(26);
		char p=s[0];
		vis[p-'a']=0;
		for(int i=1;i<s.size() && f;i++){
			st[p-'a']=1;
			int sz= adj[p-'a'].size();
			if(st[s[i]-'a']==1)f=0;
			else if(sz==0){adj[p-'a'].push_back(s[i]-'a');cnt[s[i]-'a']+=1;}
			else if(adj[p-'a'][0]!=(s[i]-'a'))f=0;
			parent[s[i]-'a']=p-'a';
			p=s[i];
			vis[p-'a']=0;
		}
	}
	for(int i=0;i<26;i++){
		f=f&(cnt[i]<2);
		if(c[i]==0)
			f=(f&check(i));
	}
	if (f==0){cout<<"NO";return 0;}
	vector<string>parts;
	for(int i=0;i<26;i++){
		if(vis[i]==0 && parent[i]==-1){
			string temp="";
			int p=i;
			vis[p]=1;
			temp+=char(p+'a');
			while(adj[p].size()==1){
				p=adj[p][0];
				vis[p]=1;
				temp+=char(p+'a');
			}
			parts.push_back(temp);
		}
	}
	sort(parts.begin(),parts.end());
	for(auto s:parts)
		cout<<s;
}


#include <cstdio>
#include <cstring>

const int MAX_N = 1e5 + 5;

int n, m;
char s[MAX_N], p[256], c[256];
bool k[256];

int main()
{
	scanf("%d", &n);
	while (n--)
	{
		scanf("%s", s); m = strlen(s);
		for (int i = 0; i < m; ++i) k[s[i]] = true;
		for (int i = 0; i + 1 < m; ++i)
			if (c[s[i]] && p[s[i + 1]] && (c[s[i]] != s[i + 1] || p[s[i + 1]] != s[i]))
			{
				printf("NO\n");
				return 0;
			}
			else
			{
				c[s[i]] = s[i + 1];
				p[s[i + 1]] = s[i];
			}
	}
	for (char i = 'a'; i <= 'z'; ++i)
		if (!p[i] && k[i]) for (char j = i; j; j = c[j])
			printf("%c", j);
	printf("\n");
	return 0;
}


#include <cstdio>
#include <cstring>
#include <vector>
#include <bitset>

const int MAX_N = 1e5 + 5;

int n, m;
char str[MAX_N], nxt[256];
bool chk[256], vis[256], not_root[256], flag;
std::vector<char> ans;

void dfs(char c)
{
	if (!vis[c])
	{
		vis[c] = true;
		ans.push_back(c);
		if (nxt[c]) dfs(nxt[c]);
	}
	else flag = true;
}

int main()
{
	scanf("%d", &n);
	while (n--)
	{
		scanf(" %s", str); m = strlen(str);
		for (int i = 0; i < m; ++i) chk[str[i]] = true;
		for (int i = 0; i + 1 < m; ++i)
		{
			if (nxt[str[i]] == 0) nxt[str[i]] = str[i + 1];
			else if (nxt[str[i]] != str[i + 1]) { printf("NO\n"); return 0; }
			not_root[str[i + 1]] = true;
		}
	}
	for (char i = 'a'; i <= 'z'; ++i)
		if (!not_root[i] && chk[i]) dfs(i);
	for (char i = 'a'; i <= 'z'; ++i)
		flag |= chk[i] != vis[i];
	if (flag) { printf("NO\n"); return 0; }
	for (char c : ans) printf("%c", c);
	printf("\n");
	return 0;
}


#include <iostream>
#include <vector>
#include <set>
#include <fstream>
#include <algorithm>
#include <map>
#include <cmath>
#include <queue>
#include <stack>

using namespace std;
#define ll long long
#define vpii vector<pair<int,int>>
#define pb push_back
#define vi vector<int>
#define find(set0, x) (set0.find(x)!=set0.end())
#define sort(vector) sort(vector.begin(), vector.end())
#define vvi vector<vector<int>>
int n;
const int maxn = 1e5 + 1;
const int mod = 1e9 + 7;

void init() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
}

int main() {
    init();
    vvi g(26);
    vector<bool> b(26);
    for (int i = 0; i < n; ++i) {
        string str;
        cin >> str;
        for (int j = 0; j < str.length(); ++j) b[str[j] - 'a'] = 1;
        for (int j = 0; j < str.length() - 1; ++j) {
            int idx0 = str[j] - 'a';
            int idx1 = str[j + 1] - 'a';
            if (g[idx0].size() == 0) {
                g[idx0].pb(idx1);
            } else {
                if (idx1 == g[idx0][0]) continue;
                cout << "NO" << endl;
                return 0;
            }
        }
    }
    vector<int> cnt(26);
    for (int i = 0; i < 26; ++i) {
        for (auto x: g[i]) {
            cnt[x]++;
        }
    }
    vector<string> ans;
    vector<bool> b0(26, 1);
    for (int i = 0; i < 26; ++i) {
        if (cnt[i] > 1) {
            cout << "NO" << endl;
            return 0;
        }
        if (cnt[i] == 0) {
            set<int> set0;
            b0[i] = 0;
            if (g[i].size() == 0) {
                if (b[i]) {
                    string r;
                    r += (i + 'a');
                    ans.pb(r);
                }
                continue;
            }
            string r;
            r += (i + 'a');
            int idx = i;
            set0.insert(i);
            while (true) {
                r += (g[idx][0] + 'a');
                idx = g[idx][0];
                b0[idx] = 0;
                if (find(set0, idx)) {
                    cout << "NO" << endl;
                    return 0;
                }
                set0.insert(idx);
                if (g[idx].size() == 0) break;
            }
            ans.pb(r);
        }
    }
    for (auto x: b0) {
        if (x) {
            cout << "NO" << endl;
            return 0;
        }
    }
    sort(ans);
    for (auto x: ans) cout << x;
    return 0;
}


#include <iostream>
#include <vector>
#include <set>
#include <fstream>
#include <algorithm>
#include <map>
#include <cmath>
#include <queue>
#include <stack>

using namespace std;
#define ll long long
#define vpii vector<pair<int,int>>
#define pb push_back
#define vi vector<int>
#define find(set0, x) (set0.find(x)!=set0.end())
#define sort(vector) sort(vector.begin(), vector.end())
#define vvi vector<vector<int>>
int n;
const int maxn = 1e5 + 1;
const int mod = 1e9 + 7;

void init() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
}

int main() {
    init();
    vvi g(26);
    vector<bool> b(26);
    for (int i = 0; i < n; ++i) {
        string str;
        cin >> str;
        for (int j = 0; j < str.length(); ++j) b[str[j] - 'a'] = 1;
        for (int j = 0; j < str.length() - 1; ++j) {
            int idx0 = str[j] - 'a';
            int idx1 = str[j + 1] - 'a';
            if (g[idx1].size() > 0) {
                cout << "NO" << endl;
                return 0;
            }
            if (g[idx0].size() == 0) {
                g[idx0].pb(idx1);
            } else {
                if (idx1 == g[idx0][0]) continue;
                cout << "NO" << endl;
                return 0;
            }
        }
    }
    vector<int> cnt(26);
    for (int i = 0; i < 26; ++i) {
        for (auto x: g[i]) {
            cnt[x]++;
        }
    }
    vector<string> ans;
    for (int i = 0; i < 26; ++i) {
        if (cnt[i] == 0) {
            if (g[i].size() == 0) {
                if (b[i]) {
                    string r;
                    r += (i + 'a');
                    ans.pb(r);
                }
                continue;
            }
            string r;
            r += (i + 'a');
            int idx = i;
            while (true) {
                r += (g[idx][0] + 'a');
                idx = g[idx][0];
                if (g[idx].size() == 0) break;
            }
            ans.pb(r);
        }
    }
    sort(ans);
    for (auto x: ans) cout << x;
    return 0;
}


#include <iostream>
#include <vector>
#include <set>
#include <fstream>
#include <algorithm>
#include <map>
#include <cmath>
#include <queue>
#include <stack>

using namespace std;
#define ll long long
#define vpii vector<pair<int,int>>
#define pb push_back
#define vi vector<int>
#define find(set0, x) (set0.find(x)!=set0.end())
#define sort(vector) sort(vector.begin(), vector.end())
#define vvi vector<vector<int>>
int n;
const int maxn = 1e5 + 1;
const int mod = 1e9 + 7;

void init() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
}

int main() {
    init();
    vvi g(26);
    vector<bool> b(26);
    for (int i = 0; i < n; ++i) {
        string str;
        cin >> str;
        for (int j = 0; j < str.length(); ++j) b[str[j] - 'a'] = 1;
        for (int j = 0; j < str.length() - 1; ++j) {
            int idx0 = str[j] - 'a';
            int idx1 = str[j + 1] - 'a';
            if (g[idx0].size() == 0) {
                g[idx0].pb(idx1);
            } else {
                if (idx1 == g[idx0][0]) continue;
                cout << "NO" << endl;
                return 0;
            }
        }
    }
    vector<int> cnt(26);
    for (int i = 0; i < 26; ++i) {
        for (auto x: g[i]) {
            cnt[x]++;
        }
    }
    vector<string> ans;
    vector<bool> b0(26, 1);
    for (int i = 0; i < 26; ++i) {
        if (cnt[i] == 0) {
            set<int> set0;
            b0[i] = 0;
            if (g[i].size() == 0) {
                if (b[i]) {
                    string r;
                    r += (i + 'a');
                    ans.pb(r);
                }
                continue;
            }
            string r;
            r += (i + 'a');
            int idx = i;
            set0.insert(i);
            while (true) {
                r += (g[idx][0] + 'a');
                idx = g[idx][0];
                b0[idx] = 0;
                if (find(set0, idx)) {
                    cout << "NO" << endl;
                    return 0;
                }
                set0.insert(idx);
                if (g[idx].size() == 0) break;
            }
            ans.pb(r);
        }
    }
    for (auto x: b0) {
        if (x) {
            cout << "NO" << endl;
            return 0;
        }
    }
    sort(ans);
    for (auto x: ans) cout << x;
    return 0;
}


#include <iostream>
#include <vector>
#include <set>
#include <fstream>
#include <algorithm>
#include <map>
#include <cmath>
#include <queue>
#include <stack>

using namespace std;
#define ll long long
#define vpii vector<pair<int,int>>
#define pb push_back
#define vi vector<int>
#define find(set0, x) (set0.find(x)!=set0.end())
#define sort(vector) sort(vector.begin(), vector.end())
#define vvi vector<vector<int>>
int n;
const int maxn = 1e5 + 1;
const int mod = 1e9 + 7;

void init() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
}

int main() {
    init();
    vvi g(26);
    for (int i = 0; i < n; ++i) {
        string str;
        cin >> str;
        for (int j = 0; j < str.length() - 1; ++j) {
            int idx0 = str[j] - 'a';
            int idx1 = str[j + 1] - 'a';
            if (g[idx0].size() == 0) {
                g[idx0].pb(idx1);
            } else {
                if (idx1 == g[idx0][0]) continue;
                cout << "NO" << endl;
                return 0;
            }
        }
    }
    vector<int> cnt(26);
    for (int i = 0; i < 26; ++i) {
        for (auto x: g[i]) {
            cnt[x]++;
        }
    }
    vector<string> ans;
    for (int i = 0; i < 26; ++i) {
        if (cnt[i] == 0) {
            if (g[i].size() == 0) {
                string r;
                r += (i + 'a');
                ans.pb(r);
                continue;
            }
            string r;
            r += (i + 'a');
            int idx = i;
            while (true) {
                r += (g[idx][0] + 'a');
                idx = g[idx][0];
                if (g[idx].size() == 0) break;
            }
            ans.pb(r);
        }
    }
    sort(ans);
    for (auto x: ans) cout << x;
    return 0;
}


#include <iostream>
#include <vector>
#include <set>
#include <fstream>
#include <algorithm>
#include <map>
#include <cmath>
#include <queue>
#include <stack>

using namespace std;
#define ll long long
#define vpii vector<pair<int,int>>
#define pb push_back
#define vi vector<int>
#define find(set0, x) (set0.find(x)!=set0.end())
#define sort(vector) sort(vector.begin(), vector.end())
#define vvi vector<vector<int>>
int n;
const int maxn = 1e5 + 1;
const int mod = 1e9 + 7;

void init() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
}

int main() {
    init();
    vvi g(26);
    for (int i = 0; i < n; ++i) {
        string str;
        cin >> str;
        for (int j = 0; j < str.length() - 1; ++j) {
            int idx0 = str[j] - 'a';
            int idx1 = str[j + 1] - 'a';
            if (g[idx0].size() == 0) {
                g[idx0].pb(idx1);
            } else {
                if (idx1 == g[idx0][0]) continue;
                cout << "NO" << endl;
                return 0;
            }
        }
    }
    vector<int> cnt(26);
    for (int i = 0; i < 26; ++i) {
        for (auto x: g[i]) {
            cnt[x]++;
        }
    }
    vector<string> ans;
    for (int i = 0; i < 26; ++i) {
        if (cnt[i] == 0) {
            if (g[i].size() == 0) continue;
            string r;
            r += (i + 'a');
            int idx = i;
            while (true) {
                r += (g[idx][0] + 'a');
                idx = g[idx][0];
                if (g[idx].size() == 0) break;
            }
            ans.pb(r);
        }
    }
    sort(ans);
    for (auto x: ans) cout << x;
    return 0;
}


#include <iostream>
#include <vector>
#include <set>
#include <fstream>
#include <algorithm>
#include <map>
#include <cmath>
#include <queue>
#include <stack>

using namespace std;
#define ll long long
#define vpii vector<pair<int,int>>
#define pb push_back
#define vi vector<int>
#define find(set0, x) (set0.find(x)!=set0.end())
#define sort(vector) sort(vector.begin(), vector.end())
#define vvi vector<vector<int>>
int n;
const int maxn = 1e5 + 1;
const int mod = 1e9 + 7;

void init() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
}

int main() {
    init();
    vvi g(26);
    for (int i = 0; i < n; ++i) {
        string str;
        cin >> str;
        for (int j = 0; j < str.length() - 1; ++j) {
            int idx0 = str[j] - 'a';
            int idx1 = str[j + 1] - 'a';
            if (g[idx0].size() == 0) {
                g[idx0].pb(idx1);
            } else {
                if (idx1 == g[idx0][0]) continue;
                cout << "No" << endl;
                return 0;
            }
        }
    }
    vector<int> cnt(26);
    for (int i = 0; i < 26; ++i) {
        for (auto x: g[i]) {
            cnt[x]++;
        }
    }
    vector<string> ans;
    for (int i = 0; i < 26; ++i) {
        if (cnt[i] == 0) {
            if (g[i].size() == 0) continue;
            string r;
            r += (i + 'a');
            int idx = i;
            while (true) {
                r += (g[idx][0] + 'a');
                idx = g[idx][0];
                if (g[idx].size() == 0) break;
            }
            ans.pb(r);
        }
    }
    sort(ans);
    for (auto x: ans) cout << x;
    return 0;
}


#include <iostream>
#include <vector>
#include <set>
#include <fstream>
#include <algorithm>
#include <map>
#include <cmath>
#include <queue>
#include <stack>

using namespace std;
#define ll long long
#define vpii vector<pair<int,int>>
#define pb push_back
#define vi vector<int>
#define find(set0, x) (set0.find(x)!=set0.end())
#define sort(vector) sort(vector.begin(), vector.end())
#define vvi vector<vector<int>>
int n;
const int maxn = 1e5 + 1;
const int mod = 1e9 + 7;

void init() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
}

int main() {
    init();
    vvi g(26);
    vector<bool> b(26);
    for (int i = 0; i < n; ++i) {
        string str;
        cin >> str;
        for (int j = 0; j < str.length(); ++j) b[str[j] - 'a'] = 1;
        for (int j = 0; j < str.length() - 1; ++j) {
            int idx0 = str[j] - 'a';
            int idx1 = str[j + 1] - 'a';
            if (g[idx0].size() == 0) {
                g[idx0].pb(idx1);
            } else {
                if (idx1 == g[idx0][0]) continue;
                cout << "NO" << endl;
                return 0;
            }
        }
    }
    vector<int> cnt(26);
    for (int i = 0; i < 26; ++i) {
        for (auto x: g[i]) {
            cnt[x]++;
        }
    }
    vector<string> ans;
    for (int i = 0; i < 26; ++i) {
        if (cnt[i] == 0) {
            if (g[i].size() == 0) {
                if (b[i]) {
                    string r;
                    r += (i + 'a');
                    ans.pb(r);
                }
                continue;
            }
            string r;
            r += (i + 'a');
            int idx = i;
            while (true) {
                r += (g[idx][0] + 'a');
                idx = g[idx][0];
                if (g[idx].size() == 0) break;
            }
            ans.pb(r);
        }
    }
    sort(ans);
    for (auto x: ans) cout << x;
    return 0;
}


#include<bits/stdc++.h>
#define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define pb emplace_back
#define mp make_pair
#define all(v) v.begin(),v.end()
#define sz(x) (ll)x.size()
#define F first
#define S second
#define FOR(i,a,b) for(ll i=a;i<=b;++i)
#define ROF(i,a,b) for(ll i=a;i>=b;--i)
typedef long long ll;
using namespace std;

const int N = 26;

bool g[N][N];
bool in[N];
bool vis[N];
bool exist[N];
bool yes = 1;

string dfs(int u){
    string ret = "";
    ret += (char)('a' + u);
    FOR(i,0,25){
        if(g[u][i]){
            if(vis[i]){
                yes = 0;
                return "0";
            }
            else{
                vis[i] = 1;
                ret = ret + dfs(i);
            }
        }
    }
    return ret;
}

int main(){
    IOS

    int n;
    cin >> n;
    FOR(i,1,n){
        string s;
        cin >> s;
        for(int j = 0; j < s.length() - 1; j++){
            g[s[j]-'a'][s[j+1]-'a'] = 1;
            in[s[j+1]-'a'] = 1;
        }
        for(int j = 0; j < s.length(); j++){
            exist[s[j]-'a'] = 1;
        }
    }
    string ans = "";
    FOR(i,0,25){
        if(in[i] == 0 && !vis[i] && exist[i]){
            string x = dfs(i);
            if(!yes){
                cout << "NO";
                return 0;
            }
            else{
                ans += x;
            }
        }
    }
    cout << ans;

    return 0;
}


#include<bits/stdc++.h>
#define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define pb emplace_back
#define mp make_pair
#define all(v) v.begin(),v.end()
#define sz(x) (ll)x.size()
#define F first
#define S second
#define FOR(i,a,b) for(ll i=a;i<=b;++i)
#define ROF(i,a,b) for(ll i=a;i>=b;--i)
typedef long long ll;
using namespace std;

const int N = 26;

bool g[N][N];
set<int> in[N], out[N];
bool vis[N];
bool exist[N];
bool yes = 1;

string dfs(int u){
    string ret = "";
    ret += (char)('a' + u);
    FOR(i,0,25){
        if(g[u][i]){
            if(vis[i]){
                yes = 0;
                return "0";
            }
            else{
                vis[i] = 1;
                ret = ret + dfs(i);
            }
        }
    }
    return ret;
}

int main(){
    IOS

    int n;
    cin >> n;
    FOR(i,1,n){
        string s;
        cin >> s;
        for(int j = 0; j < s.length() - 1; j++){
            g[s[j]-'a'][s[j+1]-'a'] = 1;
            in[s[j+1]-'a'].insert(s[j]-'a');
            out[s[j]-'a'].insert(s[j+1]-'a');
        }
        for(int j = 0; j < s.length(); j++){
            exist[s[j]-'a'] = 1;
        }
    }
    FOR(i,0,25){
        if(sz(in[i]) > 1 || sz(out[i]) > 1){
            cout << "NO";
            return 0;
        }
    }
    string ans = "";
    FOR(i,0,25){
        if(sz(in[i]) == 0 && !vis[i] && exist[i]){
            string x = dfs(i);
            if(!yes){
                cout << "NO";
                return 0;
            }
            else{
                ans += x;
            }
        }
    }
    if(sz(ans) == 0)
        ans = "NO";
    cout << ans;

    return 0;
}


#include<bits/stdc++.h>
#define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define pb emplace_back
#define mp make_pair
#define all(v) v.begin(),v.end()
#define sz(x) (ll)x.size()
#define F first
#define S second
#define FOR(i,a,b) for(ll i=a;i<=b;++i)
#define ROF(i,a,b) for(ll i=a;i>=b;--i)
typedef long long ll;
using namespace std;

const int N = 26;

bool g[N][N];
set<int> in[N], out[N];
bool vis[N];
bool exist[N];
bool yes = 1;

string dfs(int u){
    string ret = "";
    ret += (char)('a' + u);
    FOR(i,0,25){
        if(g[u][i]){
            if(vis[i]){
                yes = 0;
                return "0";
            }
            else{
                vis[i] = 1;
                ret = ret + dfs(i);
            }
        }
    }
    return ret;
}

int main(){
    IOS

    int n;
    cin >> n;
    set<int>t;
    FOR(i,1,n){
        string s;
        cin >> s;
        for(int j = 0; j < s.length() - 1; j++){
            g[s[j]-'a'][s[j+1]-'a'] = 1;
            in[s[j+1]-'a'].insert(s[j]-'a');
            out[s[j]-'a'].insert(s[j+1]-'a');
        }
        for(int j = 0; j < s.length(); j++){
            t.insert(s[j]-'a');
            exist[s[j]-'a'] = 1;
        }
    }
    FOR(i,0,25){
        if(sz(in[i]) > 1 || sz(out[i]) > 1){
            cout << "NO";
            return 0;
        }
    }
    string ans = "";
    FOR(i,0,25){
        if(sz(in[i]) == 0 && !vis[i] && exist[i]){
            string x = dfs(i);
            if(!yes){
                cout << "NO";
                return 0;
            }
            else{
                ans += x;
            }
        }
    }
    if(sz(ans) == 0 || sz(t) != sz(ans))
        ans = "NO";
    cout << ans;

    return 0;
}


#include<bits/stdc++.h>
#define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define pb emplace_back
#define mp make_pair
#define all(v) v.begin(),v.end()
#define sz(x) (ll)x.size()
#define F first
#define S second
#define FOR(i,a,b) for(ll i=a;i<=b;++i)
#define ROF(i,a,b) for(ll i=a;i>=b;--i)
typedef long long ll;
using namespace std;

const int N = 26;

bool g[N][N];
int in[N], out[N];
bool vis[N];
bool exist[N];
bool yes = 1;

string dfs(int u){
    string ret = "";
    ret += (char)('a' + u);
    FOR(i,0,25){
        if(g[u][i]){
            if(vis[i]){
                yes = 0;
                return "0";
            }
            else{
                vis[i] = 1;
                ret = ret + dfs(i);
            }
        }
    }
    return ret;
}

int main(){
    IOS

    int n;
    cin >> n;
    FOR(i,1,n){
        string s;
        cin >> s;
        for(int j = 0; j < s.length() - 1; j++){
            g[s[j]-'a'][s[j+1]-'a'] = 1;
            in[s[j+1]-'a']++;
            out[s[j]-'a']++;
        }
        for(int j = 0; j < s.length(); j++){
            exist[s[j]-'a'] = 1;
        }
    }
    FOR(i,0,25){
        if(in[i] > 1 || out[i] > 1){
            cout << "NO";
            return 0;
        }
    }
    string ans = "";
    FOR(i,0,25){
        if(in[i] == 0 && !vis[i] && exist[i]){
            string x = dfs(i);
            if(!yes){
                cout << "NO";
                return 0;
            }
            else{
                ans += x;
            }
        }
    }
    if(sz(ans) == 0)
        ans = "NO";
    cout << ans;

    return 0;
}


#include<bits/stdc++.h>
#define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define pb emplace_back
#define mp make_pair
#define all(v) v.begin(),v.end()
#define sz(x) (ll)x.size()
#define F first
#define S second
#define FOR(i,a,b) for(ll i=a;i<=b;++i)
#define ROF(i,a,b) for(ll i=a;i>=b;--i)
typedef long long ll;
using namespace std;

const int N = 26;

bool g[N][N];
bool in[N];
bool vis[N];
bool exist[N];
bool yes = 1;

string dfs(int u){
    string ret = "";
    ret += (char)('a' + u);
    FOR(i,0,25){
        if(g[u][i]){
            if(vis[i]){
                yes = 0;
                return "0";
            }
            else{
                vis[i] = 1;
                ret = ret + dfs(i);
            }
        }
    }
    return ret;
}

int main(){
    IOS

    int n;
    cin >> n;
    FOR(i,1,n){
        string s;
        cin >> s;
        for(int j = 0; j < s.length() - 1; j++){
            g[s[j]-'a'][s[j+1]-'a'] = 1;
            in[s[j+1]-'a'] = 1;
        }
        for(int j = 0; j < s.length(); j++){
            exist[s[j]-'a'] = 1;
        }
    }
    string ans = "";
    FOR(i,0,25){
        if(in[i] == 0 && !vis[i] && exist[i]){
            string x = dfs(i);
            if(!yes){
                cout << "NO";
                return 0;
            }
            else{
                ans += x;
            }
        }
    }
    if(sz(ans) == 0)
        ans = "NO";
    cout << ans;

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define F(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define R(i,b,a) for(int i=(int)(b);i>=(int)(a);i--)
#define endl "\n"
#define ios ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define out(x) cout<<setprecision(15)<<x<<endl,exit(0)
#define pii pair<int,int>
#define pb push_back
#define all(v) v.begin(),v.end()
#define I first
#define S second
#define ld long double
ld pi=3.14159265359;

set <string> con;

bool com(string s,string w){
	int cnt[26]={0};
	for(auto it:s) cnt[it-'a']++;
	for(auto it:w) cnt[it-'a']++;
	F(j,0,25) if(cnt[j]>1) return true;
	return false;
}
string ovl(string s,string w){
	if(s.find(w)!=string::npos) return s;
	R(i,min(s.size(),w.size())-1,0){
		int f=0;
		F(j,0,i) if(w[j]!=s[s.size()-i-1+j]) f=1;
		if(f==0) return s.substr(0,s.size()-i-1)+w;
	}
	return "";
}

int32_t main(){
	ios;
	int n,f=0;
	cin>>n;
	string s;
	cin>>s;
	if(com(s,"")) f=1;
	con.insert(s);

	F(i,1,n-1){
		cin>>s;
		if(com(s,"")) f=1;
		string w=s,e(".");
		for(auto it:con){
			if(!com(it,s)) continue;

			string tmp=ovl(it,s);
			if(tmp.size()==0) tmp=ovl(s,it);
			if(tmp.size()==0) f=2;
			w=tmp;
			e=it;
			break;
		}
		if(con.find(e)!=con.end()) con.erase(e);
		con.insert(w);
	}
	//cout<<f<<" ";
	if(f) out("NO");

	string ans;
	for(auto it:con) ans+=it;
	if(com(ans,"")) out("NO");
	cout<<ans;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define F(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define R(i,b,a) for(int i=(int)(b);i>=(int)(a);i--)
#define endl "\n"
#define ios ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define out(x) cout<<setprecision(15)<<x<<endl,exit(0)
#define pii pair<int,int>
#define pb push_back
#define all(v) v.begin(),v.end()
#define I first
#define S second
#define ld long double
ld pi=3.14159265359;

const int N=1e5+3;
set <int> v[26];
string a[N],ans;
int vis[26],mrk[26];

bool chk(string s){
	int cnt[26]={0};
	for(auto it:s) cnt[it-'a']++;
	F(j,0,25) if(cnt[j]>1) return false;
	return true;
}
void dfs(int x,int par=-1){
	mrk[x]=1;
	ans+=char(x+'a');
	for(auto it:v[x]){
		if(it==par || mrk[it]==2) continue;
		if(mrk[it]==1) out("NO");
		dfs(it,x);
	}
	mrk[x]=2;
}
int32_t main(){
	ios;
	int n;
	cin>>n;
	F(i,1,n) cin>>a[i];

	F(i,1,n){
		string s;
		s=a[i];
		if(!chk(s)) out("NO");

		vis[s[0]-'a']=1;
		F(i,1,s.size()-1){
			v[s[i]-'a'].insert(s[i-1]-'a');
			v[s[i-1]-'a'].insert(s[i]-'a');
			vis[s[i]-'a']=1;
		}
	}

	F(i,0,25) if(v[i].size()>2) out("NO");
	F(i,0,25){
		if(vis[i]==0 || mrk[i] || v[i].size()>1) continue;
		dfs(i);
	}
	cout<<ans;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define F(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define R(i,b,a) for(int i=(int)(b);i>=(int)(a);i--)
#define endl "\n"
#define ios ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define out(x) cout<<setprecision(15)<<x<<endl,exit(0)
#define pii pair<int,int>
#define pb push_back
#define all(v) v.begin(),v.end()
#define I first
#define S second
#define ld long double
ld pi=3.14159265359;

const int N=1e5+3;
set <int> v[26],u[26];
string a[N],ans;
int vis[26],mrk[26];

bool chk(string s){
	int cnt[26]={0};
	for(auto it:s) cnt[it-'a']++;
	F(j,0,25) if(cnt[j]>1) return false;
	return true;
}
void dfs(int x){
	mrk[x]=1;
	ans+=char(x+'a');
	for(auto it:v[x]){
		if(mrk[it]==2) continue;
		if(mrk[it]==1) out("NO");
		dfs(it);
	}
	mrk[x]=2;
}
int32_t main(){
	ios;
	int n;
	cin>>n;
	F(i,1,n) cin>>a[i];

	F(i,1,n){
		string s;
		s=a[i];
		if(!chk(s)) out("NO");

		vis[s[0]-'a']=1;
		F(i,1,s.size()-1){
			v[s[i-1]-'a'].insert(s[i]-'a');
			u[s[i]-'a'].insert(s[i-1]-'a');
			vis[s[i]-'a']=1;
		}
	}

	F(i,0,25) if(v[i].size()>1 || u[i].size()>1) out("NO");
	F(i,0,25){
		if(vis[i]==0 || mrk[i] || u[i].size()) continue;
		dfs(i);
	}
	F(i,1,25) if(vis[i]==1 && mrk[i]==0) out("NO");
	cout<<ans;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define F(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define R(i,b,a) for(int i=(int)(b);i>=(int)(a);i--)
#define endl "\n"
#define ios ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define out(x) cout<<setprecision(15)<<x<<endl,exit(0)
#define pii pair<int,int>
#define pb push_back
#define all(v) v.begin(),v.end()
#define I first
#define S second
#define ld long double
ld pi=3.14159265359;

const int N=1e5+3;
set <int> v[26],u[26];
string a[N],ans;
int vis[26],mrk[26];

bool chk(string s){
	int cnt[26]={0};
	for(auto it:s) cnt[it-'a']++;
	F(j,0,25) if(cnt[j]>1) return false;
	return true;
}
void dfs(int x){
	mrk[x]=1;
	ans+=char(x+'a');
	for(auto it:v[x]){
		if(mrk[it]==2) continue;
		if(mrk[it]==1) out("NO");
		dfs(it);
	}
	mrk[x]=2;
}
int32_t main(){
	ios;
	int n;
	cin>>n;
	F(i,1,n) cin>>a[i];

	F(i,1,n){
		string s;
		s=a[i];
		if(!chk(s)) out("NO");

		vis[s[0]-'a']=1;
		F(i,1,s.size()-1){
			v[s[i-1]-'a'].insert(s[i]-'a');
			u[s[i]-'a'].insert(s[i-1]-'a');
			vis[s[i]-'a']=1;
		}
	}

	F(i,0,25) if(v[i].size()>1 || u[i].size()>1) out("NO");
	F(i,0,25){
		if(vis[i]==0 || mrk[i] || u[i].size()) continue;
		dfs(i);
	}
	if(ans.size()==0) out("NO");
	cout<<ans;
}


#include<bits/stdc++.h>
using namespace std;
signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int n;
    cin >> n;
    vector <vector <int> > ind(n, vector <int> (26, -1));
    vector <set <int> > ind2(26);
    vector <bool> used(n, 1);
    vector <string> vec(n);
    for(int i = 0; i < n; i++)
    {
    	string w;
    	cin >> w;
    	if(i == 0)
    	{
    		for(int j = 0; j < w.size(); j++)
    		{
    			if(ind[i][w[j] - 'a'] != -1)
    			{
    				cout << "NO";
    				return 0;
				}
				ind2[w[j] - 'a'].insert(i);
    			ind[i][w[j] - 'a'] = j;
			}
		}
		else
		{
			string s1 = "";
			bool flag = 0;
			for(int j = 0; j < w.size(); j++)
			{
				if(ind[i][w[j] - 'a'] != -1)
				{
					cout << "NO";
					return 0;
				}
				ind[i][w[j] - 'a'] = j;
			}
			for(int j = 0; j < 26;j++)
			{
				if(ind[i][j] != -1)
				{
					while(ind2[j].size() > 0)
					{
						s1 = "";
						int a1 = *ind2[j].begin();
						string w1 = vec[a1];
						used[a1] = 0;
						int ind1 = ind[a1][j];
						for(int k = 0; k < 26; k++)
						{
							if(ind[a1][k] != -1)
							{
								ind2[k].erase(a1);
							}
						}
						int t1 = min(ind1 + 1, ind[i][j] + 1);
						int t2 = min(w1.size() - ind1, w.size() - ind[i][j]);
						for(int k1 = 0; k1 < t1; k1++)
						{
							if(w[ind[i][j] - k1] != w1[ind1 - k1])
							{
								cout << "NO";
								return 0;
							}
						}
						for(int k1 = 0; k1 < t2; k1++)
						{
							if(w[ind[i][j] + k1] != w1[ind1 + k1])
							{
								cout << "NO";
								return 0;
							}
						}
						for(int k1 = ind[i][j]; k1 > t1; k1--)
						{
							s1 += w[ind[i][j] - k1];
						}
						s1 += w1;
						for(int k1 = ind[i][j] + t2; k1 < w.size(); k1++)
						{
							s1 += w[k1];
						}
						for(int a = 0;  a< 26; a++)
						{
							ind[i][a] = -1;
						}
						w = s1;
						for(int a = 0; a < w.size(); a++)
						{
							if(ind[i][w[a] - 'a'] != -1)
							{
								cout << "NO";
								return 0;
							}
							ind[i][w[a] - 'a'] = a;
						}
					}
					}
			}
			for(int j = 0; j < 26;j++)
			{
				if(ind[i][j] != -1)
				{
					ind2[j].insert(i);
				}
			}
		}
		vec[i] = w;
	}
	vector <string> mass;
	vector <int> cnt(26, 0);
	for(int j = 0; j < n; j++)
	{
		if(used[j])
		{
			for(int k = 0; k < vec[j].size(); k++)
			{
				cnt[vec[j][k] - 'a']++;
				if(cnt[vec[j][k] - 'a'] > 1)
				{
					cout << "NO";
					return 0;
				}
			}
			mass.push_back(vec[j]);
		}
	}
	for(int i = 0; i < 26; i++)
	{
		char t = i + 'a';
		for(int j = 0; j < mass.size(); j++)
		{
			if(mass[j][0] == t)
			{
				cout << mass[j];
			}
		}
	}
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int n;
    cin >> n;
    vector <vector <int> > ind(n, vector <int> (26, -1));
    vector <set <int> > ind2(26);
    vector <bool> used(n, 1);
    vector <string> vec(n);
    for(int i = 0; i < n; i++)
    {
    	string w;
    	cin >> w;
    	if(i == 0)
    	{
    		for(int j = 0; j < w.size(); j++)
    		{
    			if(ind[i][w[j] - 'a'] != -1)
    			{
    				cout << "NO";
    				return 0;
				}
				ind2[w[j] - 'a'].insert(i);
    			ind[i][w[j] - 'a'] = j;
			}
		}
		else
		{
			string s1 = "";
			bool flag = 0;
			for(int j = 0; j < w.size(); j++)
			{
				if(ind[i][w[j] - 'a'] != -1)
				{
					cout << "NO";
					return 0;
				}
				ind[i][w[j] - 'a'] = j;
			}
			for(int j = 0; j < 26;j++)
			{
				if(ind[i][j] != -1)
				{
					while(ind2[j].size() > 0)
					{
						s1 = "";
						int a1 = *ind2[j].begin();
						string w1 = vec[a1];
						used[a1] = 0;
						int ind1 = ind[a1][j];
						for(int k = 0; k < 26; k++)
						{
							if(ind[a1][k] != -1)
							{
								ind2[k].erase(a1);
							}
						}
						int t1 = min(ind1 + 1, ind[i][j] + 1);
						int t2 = min(w1.size() - ind1, w.size() - ind[i][j]);
						for(int k1 = 0; k1 < t1; k1++)
						{
							if(w[ind[i][j] - k1] != w1[ind1 - k1])
							{
								cout << "NO";
								return 0;
							}
						}
						for(int k1 = 0; k1 < t2; k1++)
						{
							if(w[ind[i][j] + k1] != w1[ind1 + k1])
							{
								cout << "NO";
								return 0;
							}
						}
						for(int k1 = ind[i][j]; k1 >= t1; k1--)
						{
							s1 += w[ind[i][j] - k1];
						}
						s1 += w1;
						for(int k1 = ind[i][j] + t2; k1 < w.size(); k1++)
						{
							s1 += w[k1];
						}
						for(int a = 0;  a< 26; a++)
						{
							ind[i][a] = -1;
						}
						w = s1;
						for(int a = 0; a < w.size(); a++)
						{
							if(ind[i][w[a] - 'a'] != -1)
							{
								cout << "NO";
								return 0;
							}
							ind[i][w[a] - 'a'] = a;
						}
					}
					}
			}
			for(int j = 0; j < 26;j++)
			{
				if(ind[i][j] != -1)
				{
					ind2[j].insert(i);
				}
			}
		}
		vec[i] = w;
	}
	vector <string> mass;
	vector <int> cnt(26, 0);
	for(int j = 0; j < n; j++)
	{
		if(used[j])
		{
			for(int k = 0; k < vec[j].size(); k++)
			{
				cnt[vec[j][k] - 'a']++;
				if(cnt[vec[j][k] - 'a'] > 1)
				{
					cout << "NO";
					return 0;
				}
			}
			mass.push_back(vec[j]);
		}
	}
	for(int i = 0; i < 26; i++)
	{
		char t = i + 'a';
		for(int j = 0; j < mass.size(); j++)
		{
			if(mass[j][0] == t)
			{
				cout << mass[j];
			}
		}
	}
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int n;
    cin >> n;
    vector <vector <int> > ind(n, vector <int> (26, -1));
    vector <set <int> > ind2(26);
    vector <bool> used(n, 1);
    vector <string> vec(n);
    for(int i = 0; i < n; i++)
    {
    	string w;
    	cin >> w;
    	if(i == 0)
    	{
    		for(int j = 0; j < w.size(); j++)
    		{
    			if(ind[i][w[j] - 'a'] != -1)
    			{
    				cout << "NO";
    				return 0;
				}
				ind2[w[j] - 'a'].insert(i);
    			ind[i][w[j] - 'a'] = j;
			}
		}
		else
		{
			string s1 = "";
			bool flag = 0;
			for(int j = 0; j < w.size(); j++)
			{
				if(ind[i][w[j] - 'a'] != -1)
				{
					cout << "NO";
					return 0;
				}
				ind[i][w[j] - 'a'] = j;
			}
			for(int j = 0; j < 26;j++)
			{
				if(ind[i][j] != -1)
				{
					while(ind2[j].size() > 0)
					{
						s1 = "";
						int a1 = *ind2[j].begin();
						string w1 = vec[a1];
						used[a1] = 0;
						int ind1 = ind[a1][j];
						for(int k = 0; k < 26; k++)
						{
							if(ind[a1][k] != -1)
							{
								ind2[k].erase(a1);
							}
						}
						int t1 = min(ind1 + 1, ind[i][j] + 1);
						int t2 = min(w1.size() - ind1, w.size() - ind[i][j]);
						for(int k1 = 0; k1 < t1; k1++)
						{
							if(w[ind[i][j] - k1] != w1[ind1 - k1])
							{
								cout << "NO";
								return 0;
							}
						}
						for(int k1 = 0; k1 < t2; k1++)
						{
							if(w[ind[i][j] + k1] != w1[ind1 + k1])
							{
								cout << "NO";
								return 0;
							}
						}
						for(int k1 = ind[i][j]; k1 > t1; k1--)
						{
							s1 += w[ind[i][j] - k1];
						}
						s1 += w1;
						for(int k1 = ind[i][j] + t2; k1 < w.size(); k1++)
						{
							s1 += w[k1];
						}
						for(int a = 0;  a< 26; a++)
						{
							ind[i][a] = -1;
						}
						w = s1;
						for(int a = 0; a < w.size(); a++)
						{
							if(ind[i][w[a] - 'a'] != -1)
							{
								cout << "NO";
								return 0;
							}
							ind[i][w[a] - 'a'] = a;
						}
					}
					}
			}
			for(int j = 0; j < 26;j++)
			{
				if(ind[i][j] != -1)
				{
					ind2[j].insert(i);
				}
			}
		}
		vec[i] = w;
	}
	vector <pair <string, int> > mass;
	vector <int> cnt(26, 0);
	int maxcnt = 0;
	for(int j = 0; j < n; j++)
	{
		if(used[j])
		{
			for(int d = 0; d < 26; d++)
			{
				cnt[d] = 0;
			}
			int pr = 0;
			for(int k = 0; k < vec[j].size(); k++)
			{
				cnt[vec[j][k] - 'a']++;
				pr = max(pr, cnt[vec[j][k] - 'a']);
			}
			if(pr > 1 && maxcnt > 1)
			{
				cout << "NO";
				return 0;
			}
			maxcnt = max(maxcnt, pr);
			mass.push_back({vec[j], pr});
		}
	}
	for(int i = 0; i < 26; i++)
	{
		char t = i + 'a';
		for(int j = 0; j < mass.size(); j++)
		{
			if(mass[j].first[0] == t)
			{
				if(mass[j].second == 1)
				{
				for(int d = 0; d < maxcnt; d++)
				{
					cout << mass[j].first;
				}
				}
				else
				{
					cout << mass[j].first;
				}
			}
		}
	}
    return 0;
}


#include <bits/stdc++.h>
#define ll long long int
#define P pair
#define F first
#define S second
#define p_b push_back
#define ld long double
#define N 5000005
//#include <wadim>
ll mod = 1000000000 + 7; //4294967296; 1000000000 + 7; 998244353; 2*3*5*7*11*13*17*19*23 + 1
ll inf = (ll)(5e18);
using namespace std;

mt19937 unlucko(chrono::steady_clock::now().time_since_epoch().count());

//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//using ordered_set_pair = tree<pair<ll, ll>, null_type, less<pair<ll, ll> >, rb_tree_tag, tree_order_statistics_node_update>;
//using ordered_set=tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;
//typedef tree<ll, null_type, less_equal<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset;
//typedef tree<pair<ll, ll>, null_type, less_equal<pair<ll, ll> >, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset_pair;

vector<int> tree[26];
vector<bool> to(26, false), used(26, false), xist(26, false);
bool a[26][26];
bool ok = true;

void dfs(int node){
    used[node] = true;
    for(auto it:tree[node]){
        if(used[it]){
            ok = false;
            continue;
        }
        dfs(it);
    }
}

void ans(int node){
    cout << char(node + 'a');
    for(auto it:tree[node]){
        ans(it);
    }
}

int main() {
    iostream::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n; cin >> n;
    for(int i=0;i<n;i++){
        string s; cin >> s;
        for(int j=0;j<s.length();j++){
            xist[s[j] - 'a'] = true;
            if(j != s.length() - 1){
                if(!a[s[j] - 'a'][s[j + 1] - 'a'])
                    tree[s[j] - 'a'].push_back(s[j + 1] - 'a');
                a[s[j] - 'a'][s[j + 1] - 'a'] = true;
                to[s[j + 1] - 'a'] = true;
            }
        }
    }
    for(int i=0;i<26;i++){
        if(tree[i].size() > 1){
            ok = false;
            break;
        }else if(tree[i].empty())
            continue;
        if(!to[i]){
            dfs(i);
        }
    }
    for(int i=0;i<26;i++){
        if(!used[i] && to[i]){
            ok = false;
        }
    }
    if(!ok){
        cout << "NO\n";
        return 0;
    }
    for(int i=0;i<26;i++)
        used[i] = false;
    for(int i=0;i<26;i++){
        if(xist[i] && !to[i]){
            ans(i);
        }
    }
    cout << "\n";
}


#include <bits/stdc++.h>
#define ll long long int
#define P pair
#define F first
#define S second
#define p_b push_back
#define ld long double
#define N 5000005
//#include <wadim>
ll mod = 1000000000 + 7; //4294967296; 1000000000 + 7; 998244353; 2*3*5*7*11*13*17*19*23 + 1
ll inf = (ll)(5e18);
using namespace std;

mt19937 unlucko(chrono::steady_clock::now().time_since_epoch().count());

//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//using ordered_set_pair = tree<pair<ll, ll>, null_type, less<pair<ll, ll> >, rb_tree_tag, tree_order_statistics_node_update>;
//using ordered_set=tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;
//typedef tree<ll, null_type, less_equal<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset;
//typedef tree<pair<ll, ll>, null_type, less_equal<pair<ll, ll> >, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset_pair;

vector<int> tree[26];
vector<bool> to(26, false), used(26, false), xist(26, false);
bool a[26][26];
bool ok = true;

void dfs(int node){
    used[node] = true;
    for(auto it:tree[node]){
        if(used[it]){
            ok = false;
            continue;
        }
        dfs(it);
    }
}

void ans(int node){
    cout << char(node + 'a');
    for(auto it:tree[node]){
        ans(it);
    }
}

int main() {
    iostream::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n; cin >> n;
    for(int i=0;i<n;i++){
        string s; cin >> s;
        for(int j=0;j<s.length();j++){
            xist[s[j] - 'a'] = true;
            if(j != s.length() - 1){
                if(!a[s[j] - 'a'][s[j + 1] - 'a'])
                    tree[s[j] - 'a'].push_back(s[j + 1] - 'a');
                a[s[j] - 'a'][s[j + 1] - 'a'] = true;
                to[s[j + 1] - 'a'] = true;
            }
        }
    }
    for(int i=0;i<26;i++){
        if(tree[i].size() > 1){
            ok = false;
            break;
        }else if(tree[i].empty())
            continue;
        if(!to[i]){
            dfs(i);
        }
    }
    if(!ok){
        cout << "NO\n";
        return 0;
    }
    for(int i=0;i<26;i++)
        used[i] = false;
    for(int i=0;i<26;i++){
        if(xist[i] && !to[i]){
            ans(i);
        }
    }
    cout << "\n";
}


#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define pll pair<ll,ll>
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
#define abs(x) ((x)<0?(-(x)):(x))
#define SZ(x) ((int)x.size())
#define all(x) x.begin(),x.end()

const int LOG = 18;
const int NN = 2e5+5;
const int MOD = (int)1e9+7;
const int INF = 1LL << 28;

bool adj[30][30];
char clr[30];
int in_deg[30];
bool exist[30];

string ans;
bool good;

void dfs(int x) {
	if(clr[x] == 'g') {
		good = false;
		return;
	}
	if(clr[x] != 'w') return;
	clr[x] = 'g';
	ans += ((char)(x + 'a'));
	for(int y = 0; y < 30; y ++) if(adj[x][y]) {
		dfs(y);
	}
	clr[x] = 'b';
}

char s[1 << 17];

int main() {
	#ifdef XOX
		freopen("in.txt", "r", stdin);
	#endif
	ios_base::sync_with_stdio(0);

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

	memset(adj, false, sizeof(adj));

	while(n --) {
		fgets(s, 1 << 19, stdin);
		int l = strlen(s);
		if(s[l - 1] == '\n') s[l - 1] = '\0', l --;
		for(int i = 0; i < l; i ++) {
			exist[s[i] - 'a'] = true;
			if(i > 0) adj[s[i - 1] - 'a'][s[i] - 'a'] = true;
		}
	}
	good = true;
	ans.clear();
	for(int i = 0; i < 30; i ++) {
		in_deg[i] = 0;
		int out = 0;
		for(int j = 0; j < 30; j ++) {
			in_deg[i] += adj[j][i];
			out += adj[i][j];
		}
		if(in_deg[i] >= 2 || out >= 2) {
			// printf("FUCK: %c\n", (char)(i + 'a'));
			good = false;
		}
	}

	memset(clr, 'w', sizeof(clr));
	for(int i = 0; i < 30; i ++) if(exist[i] == true && in_deg[i] == 0) {
		dfs(i);
	}

	for(int i = 0; i < 30; i ++) if(exist[i] == true && clr[i] == 'w') good = false;

	if(good) printf("%s\n", ans.c_str());
	else printf("NO\n");
	return 0;
}


///****In the name of Allah, most Gracious, most Compassionate****//

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

typedef long long ll;
typedef pair <int, int> pii;

#define ALL(a) a.begin(), a.end()
#define FastIO ios::sync_with_stdio(false); cin.tie(nullptr);cout.tie(nullptr)
#define IN freopen("input.txt","r+",stdin)
#define OUT freopen("output.txt","w+",stdout)

#define DBG(a) cout<< #a <<" --> "<<(a)<<endl
#define NL cout<<"\n"

template < class T1,class T2>
ostream &operator <<(ostream &os,const pair < T1,T2 > &p)
{
    os<<"{"<<p.first<<","<<p.second<<"}";
    return os;
}

const int N=3e5+5;
const int oo=1e9+7;

bool check(string s)
{
    sort(ALL(s));
    for(int i=1; i<s.size(); i++)
        if(s[i]==s[i-1]) return 0;
    return 1;
}
int exist[26];
string  tot[26];

bool  ispref(string s,string &t)
{
    for(int i=0; i<min(s.size(), t.size()) ; i++)
        if(s[i]!=t[i]) return 0;
    return 1;
}
bool contain(string &s,char c)
{
    for(char cc: s) if(cc==c) return 1;
    return 0;
}

bool pos(int j)
{
    for(int i=0; i<26; i++)
    {
        if(i!=j and  contain(tot[i], 'a'+j)) return 0;
    }
    return 1;
}
bool used[26];
bool process(string &ans)
{
    for(int i=0; i<ans.size(); i++)
    {
        string &t= tot[ans[i]-'a'];
        if(ispref(ans.substr(i), t))
        {
            if(ans.size()- i < t.size())
            {
                for(int j=(ans.size()-i); j<t.size(); j++) {
                    if(used[t[j]-'a']) return 0;
                    used[t[j]-'a']=1;
                    ans.push_back(t[j]);
                }
            }
        }
        else return 0;
    }
    return 1;
}
int32_t main()
{
    FastIO;
    int n;
    cin>>n;
    vector<string > ss;

    while(n--)
    {
        string s;
        cin>>s;
        if(check(s))
            ss.push_back(s);
        else
        {
            cout<<"NO\n";
            return 0;
        }
    }
    sort(ALL(ss));

    ss.erase(unique(ALL(ss)), ss.end());
    for(string s: ss)
    {
        for(char c: s)
            exist[c-'a']++;
        for(int i=0; i<s.size(); i++)
        {
            string x= s.substr(i);
            if(ispref(tot[x[0]-'a'], x))
            {
                if(x.size()>tot[x[0]-'a'].size())
                    tot[x[0]-'a'] = x;
            }
            else
            {
                cout<<"NO\n";
                return 0;
            }
        }
    }
//    for(int i=0; i<26; i++)
//        DBG(tot[i]);
//    for(int i=0;i<26;i++)
//        DBG(pos(i));
    string ans = "";
    int sz= 0;
    for(int i=0; i<26; i++)
        sz+=exist[i]>0;
    while(ans.size()<sz)
    {
        bool paisi =0;
        for(int i=0; i<26; i++)
        {
            if(used[i] == 0 and exist[i]>0 and pos(i))
            {
                paisi=1;
                ans+=tot[i];
                for(char c: ans)
                used[c-'a']=1;
                if(process(ans)) break;
                else
                {
                    cout<<"NO\n";
                    return 0;
                }
            }

        }

        if(paisi==0)
        {
             cout<<"NO\n";
                    return 0;
        }

//        DBG(ans);
    }
    if(check(ans))
    cout<<ans<<"\n";
    else
        cout<<"NO\n";
}


///****In the name of Allah, most Gracious, most Compassionate****//

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

typedef long long ll;
typedef pair <int, int> pii;

#define ALL(a) a.begin(), a.end()
#define FastIO ios::sync_with_stdio(false); cin.tie(nullptr);cout.tie(nullptr)
#define IN freopen("input.txt","r+",stdin)
#define OUT freopen("output.txt","w+",stdout)

#define DBG(a) cout<< #a <<" --> "<<(a)<<endl
#define NL cout<<"\n"

template < class T1,class T2>
ostream &operator <<(ostream &os,const pair < T1,T2 > &p)
{
    os<<"{"<<p.first<<","<<p.second<<"}";
    return os;
}

const int N=3e5+5;
const int oo=1e9+7;

bool check(string s)
{
    sort(ALL(s));
    for(int i=1; i<s.size(); i++)
        if(s[i]==s[i-1]) return 0;
    return 1;
}
int exist[26];
string  tot[26];

bool  ispref(string s,string &t)
{
    for(int i=0; i<min(s.size(), t.size()) ; i++)
        if(s[i]!=t[i]) return 0;
    return 1;
}
bool contain(string &s,char c)
{
    for(char cc: s) if(cc==c) return 1;
    return 0;
}

bool pos(int j)
{
    for(int i=0; i<26; i++)
    {
        if(i!=j and  contain(tot[i], 'a'+j)) return 0;
    }
    return 1;
}
bool used[26];
bool process(string &ans)
{
    for(int i=0; i<ans.size(); i++)
    {
        string &t= tot[ans[i]-'a'];
        if(ispref(ans.substr(i), t))
        {
            if(ans.size()- i < t.size())
            {
                for(int j=(ans.size()-i); j<t.size(); j++)
                    ans.push_back(t[j]);
            }
        }
        else return 0;
    }
    return 1;
}
int32_t main()
{
    FastIO;
    int n;
    cin>>n;
    vector<string > ss;

    while(n--)
    {
        string s;
        cin>>s;
        if(check(s))
            ss.push_back(s);
        else
        {
            cout<<"NO\n";
            return 0;
        }
    }
    sort(ALL(ss));

    ss.erase(unique(ALL(ss)), ss.end());
    for(string s: ss)
    {
        for(char c: s)
            exist[c-'a']++;
        for(int i=0; i<s.size(); i++)
        {
            string x= s.substr(i);
            if(ispref(tot[x[0]-'a'], x))
            {
                if(x.size()>tot[x[0]-'a'].size())
                    tot[x[0]-'a'] = x;
            }
            else
            {
                cout<<"NO\n";
                return 0;
            }
        }
    }
//    for(int i=0; i<26; i++)
//        DBG(tot[i]);
//    for(int i=0;i<26;i++)
//        DBG(pos(i));
    string ans = "";
    int sz= 0;
    for(int i=0; i<26; i++)
        sz+=exist[i]>0;
    while(ans.size()<sz)
    {
        bool paisi =0;
        for(int i=0; i<26; i++)
        {
            if(used[i] == 0 and exist[i]>0 and pos(i))
            {
                paisi=1;
                ans+=tot[i];
                if(process(ans)) break;
                else
                {
                    cout<<"NO\n";
                    return 0;
                }
            }

        }

        if(paisi==0)
        {
             cout<<"NO\n";
                    return 0;
        }
        for(char c: ans)
            used[c-'a']=1;
//        DBG(ans);
    }

    cout<<ans<<"\n";

}


///****In the name of Allah, most Gracious, most Compassionate****//

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

typedef long long ll;
typedef pair <int, int> pii;

#define ALL(a) a.begin(), a.end()
#define FastIO ios::sync_with_stdio(false); cin.tie(nullptr);cout.tie(nullptr)
#define IN freopen("input.txt","r+",stdin)
#define OUT freopen("output.txt","w+",stdout)

#define DBG(a) cout<< #a <<" --> "<<(a)<<endl
#define NL cout<<"\n"

template < class T1,class T2>
ostream &operator <<(ostream &os,const pair < T1,T2 > &p)
{
    os<<"{"<<p.first<<","<<p.second<<"}";
    return os;
}

const int N=3e5+5;
const int oo=1e9+7;

bool check(string s)
{
    sort(ALL(s));
    for(int i=1; i<s.size(); i++)
        if(s[i]==s[i-1]) return 0;
    return 1;
}
int exist[26];
string  tot[26];

bool  ispref(string s,string &t)
{
    for(int i=0; i<min(s.size(), t.size()) ; i++)
        if(s[i]!=t[i]) return 0;
    return 1;
}
bool contain(string &s,char c)
{
    for(char cc: s) if(cc==c) return 1;
    return 0;
}

bool pos(int j)
{
    for(int i=0; i<26; i++)
    {
        if(i!=j and  contain(tot[i], 'a'+j)) return 0;
    }
    return 1;
}
bool used[26];
bool process(string &ans)
{
    for(int i=0; i<ans.size(); i++)
    {
        string &t= tot[ans[i]-'a'];
        if(ispref(ans.substr(i), t))
        {
            if(ans.size()- i < t.size())
            {
                for(int j=(ans.size()-i); j<t.size(); j++)
                    ans.push_back(t[j]);
            }
        }
        else return 0;
    }
    return 1;
}
int32_t main()
{
    FastIO;
    int n;
    cin>>n;
    vector<string > ss;

    while(n--)
    {
        string s;
        cin>>s;
        if(check(s))
            ss.push_back(s);
        else
        {
            cout<<"NO\n";
            return 0;
        }
    }
    sort(ALL(ss));

    ss.erase(unique(ALL(ss)), ss.end());
    for(string s: ss)
    {
        for(char c: s)
            exist[c-'a']++;
        for(int i=0; i<s.size(); i++)
        {
            string x= s.substr(i);
            if(ispref(tot[x[0]-'a'], x))
            {
                if(x.size()>tot[x[0]-'a'].size())
                    tot[x[0]-'a'] = x;
            }
            else
            {
                cout<<"NO\n";
                return 0;
            }
        }
    }
//    for(int i=0; i<26; i++)
//        DBG(tot[i]);
//    for(int i=0;i<26;i++)
//        DBG(pos(i));
    string ans = "";
    int sz= 0;
    for(int i=0; i<26; i++)
        sz+=exist[i]>0;
    while(ans.size()<sz)
    {
        bool paisi =0;
        for(int i=0; i<26; i++)
        {
            if(used[i] == 0 and exist[i]>0 and pos(i))
            {
                paisi=1;
                ans+=tot[i];
                if(process(ans)) break;
                else
                {
                    cout<<"NO\n";
                    return 0;
                }
            }

        }

        if(paisi==0)
        {
             cout<<"NO\n";
                    return 0;
        }
        for(char c: ans)
            used[c-'a']=1;
//        DBG(ans);
    }
    if(check(ans))
    cout<<ans<<"\n";
    else
        cout<<"NO\n";
}


///****In the name of Allah, most Gracious, most Compassionate****//

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

typedef long long ll;
typedef pair <int, int> pii;

#define ALL(a) a.begin(), a.end()
#define FastIO ios::sync_with_stdio(false); cin.tie(nullptr);cout.tie(nullptr)
#define IN freopen("input.txt","r+",stdin)
#define OUT freopen("output.txt","w+",stdout)

#define DBG(a) cout<< #a <<" --> "<<(a)<<endl
#define NL cout<<"\n"

template < class T1,class T2>
ostream &operator <<(ostream &os,const pair < T1,T2 > &p)
{
    os<<"{"<<p.first<<","<<p.second<<"}";
    return os;
}

const int N=3e5+5;
const int oo=1e9+7;

bool check(string s)
{
    sort(ALL(s));
    for(int i=1; i<s.size(); i++)
        if(s[i]==s[i-1]) return 0;
    return 1;
}
int exist[26];
string  tot[26];

bool  ispref(string s,string &t)
{
    for(int i=0; i<min(s.size(), t.size()) ; i++)
        if(s[i]!=t[i]) return 0;
    return 1;
}
bool contain(string &s,char c)
{
    for(char cc: s) if(cc==c) return 1;
    return 0;
}

bool pos(int j)
{
    for(int i=0; i<26; i++)
    {
        if(i!=j and  contain(tot[i], 'a'+j)) return 0;
    }
    return 1;
}
bool used[26];
bool process(string &ans)
{
    for(int i=0; i<ans.size(); i++)
    {
        string &t= tot[ans[i]-'a'];
        if(ispref(ans.substr(i), t))
        {
            if(ans.size()- i < t.size())
            {
                for(int j=(ans.size()-i); j<t.size(); j++)
                    ans.push_back(t[j]);
            }
        }
        else return 0;
    }
    return 1;
}
int32_t main()
{
    FastIO;
    int n;
    cin>>n;
    vector<string > ss;

    while(n--)
    {
        string s;
        cin>>s;
        if(check(s))
            ss.push_back(s);
        else
        {
            cout<<"NO\n";
            return 0;
        }
    }
    sort(ALL(ss));

    ss.erase(unique(ALL(ss)), ss.end());
    for(string s: ss)
    {
        for(char c: s)
            exist[c-'a']++;
        for(int i=0; i<s.size(); i++)
        {
            string x= s.substr(i);
            if(ispref(tot[x[0]-'a'], x))
            {
                if(x.size()>tot[x[0]-'a'].size())
                    tot[x[0]-'a'] = x;
            }
            else
            {
                cout<<"NO\n";
                return 0;
            }
        }
    }
//    for(int i=0; i<26; i++)
//        DBG(tot[i]);
//    for(int i=0;i<26;i++)
//        DBG(pos(i));
    string ans = "";
    int sz= 0;
    for(int i=0; i<26; i++)
        sz+=exist[i]>0;
    while(ans.size()<sz)
    {
        for(int i=0; i<26; i++)
        {
            if(used[i] == 0 and exist[i]>0 and pos(i))
            {
                ans+=tot[i];
                if(process(ans)) break;
                else
                {
                    cout<<"NO\n";
                    return 0;
                }
            }

        }
        for(char c: ans)
            used[c-'a']=1;
//        DBG(ans);
    }

    cout<<ans<<"\n";

}


#include <bits/stdc++.h>
#define IO ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
using namespace std;
int n, nxt[26], prv[26], v[26], vv[26];
vector<string> ans;
void kill()
{
    cout << "NO";
    exit(0);
}
int main()
{
    IO;
    cin >> n;
    memset(nxt, -1, sizeof nxt);
    memset(prv, -1, sizeof prv);
    for(int i = 0; i < n; i++)
    {
        string s;
        cin >> s;
        bool vis[26] = {};
        for(auto x : s)
        {
            if(vis[x - 'a'])
                kill();
            vis[x - 'a'] = v[x - 'a'] = 1;
        }
        for(int j = 0; j + 1 < s.size(); j++)
        {
            int x = s[j] - 'a', z = s[j + 1] - 'a';
            if(nxt[x] != -1 && nxt[x] != z)
                kill();
            if(prv[z] != -1 && prv[z] != x)
                kill();
            nxt[x] = z;
            prv[z] = x;
        }
    }
    for(int i = 0; i < 26; i++)
    {
        if(prv[i] == -1 && v[i])
        {
            string x;
            for(int j = i; j != -1; j = nxt[j])
            {
                vv[j] = 1;
                x += char(j + 'a');
            }
            ans.push_back(x);
        }
    }
    for(int i = 0; i < 26; i++)
        if(v[i] && !vv[i])
            kill();
    sort(ans.begin(), ans.end());
    for(auto i : ans)
        cout << i;
}


#include "bits/stdc++.h"
using namespace std;
#include "vector"
#define endl '\n'
#ifndef dgb
#define dbg(...)
#define dbgv(x)
#define debug(...)
#endif
#define pb push_back
#define eb emplace_back
#define rep(i, a, b) for(auto i = a;i != b;i++)
#define brep(i, a, b) for(auto i = a;i >= b;i--)
#define repi(i, a, b) for(auto i = a;i <= b;i++)
template<class t>t mag(t a){return a>0?a:-a;}
template <class T, class U>T cdiv(T num,U den){return (num/den)+((num%den)>0);}
std::ifstream term("/dev/tty");std::string tempstring;
using ll=int_fast64_t;using ii=pair<int,int>;using vi=vector<int>;
using vl=vector<ll>;using vii = vector<ii>;
const int &sij = 400010;const ll &mod = 1000000007ll;
int n, pre[200], nx[200], fre[200], vis[200];
string prt;
vector<string> vec;
void fail(){
  cout << "NO";
  exit(0);
}
int esc(int tcase){
  cin >> n;
  vec.resize(n);
  memset(pre, -1, sizeof(pre));
  memset(nx, -1, sizeof(nx));
  for(auto &e:vec)  cin >> e;
  for(auto &e:vec){
    if(e.size() > 26){
      fail();
    }
    fre[e[0]] = 1;
    rep(i, 0, e.size() - 1){
      fre[e[i]] = fre[e[i + 1]] = 1;
      if(nx[e[i]] == -1){
        nx[e[i]] = e[i + 1];
      }
      else if(nx[e[i]] != e[i + 1]){
        fail();
      }
      if(pre[e[i + 1]] == -1){
        pre[e[i + 1]] = e[i];
      }
      else if(pre[e[i + 1]] != e[i]){
        fail();
      }
    }
  }
  repi(i, 'a', 'z'){
    if(pre[i] == -1 and fre[i]){
      if(vis[i] == 1) fail();
      vis[i] = 1;
      char cr = i;
      prt += cr;
      while(nx[cr] != -1){
        if(vis[nx[cr]]) fail();
        vis[nx[cr]] = 1;
        prt += char(nx[cr]);
        cr = nx[cr];
      }
    }
  }
  cout << prt << endl;
  return 0;
}
int main(){
  ios_base::sync_with_stdio(0);
#ifndef sep
  cin.tie(0);
  cout.tie(0);
#endif
  int tc = 1;
  for(int i = 1;i <= tc;i++)
    esc(i);
#ifdef sep
  cerr << "\n\nTime : "<<1.0* clock()/CLOCKS_PER_SEC << "s.\n\n";
#endif
}


#include "bits/stdc++.h"
using namespace std;
#include "vector"
#define endl '\n'
#ifndef dgb
#define dbg(...)
#define dbgv(x)
#define debug(...)
#endif
#define pb push_back
#define eb emplace_back
#define rep(i, a, b) for(auto i = a;i != b;i++)
#define brep(i, a, b) for(auto i = a;i >= b;i--)
#define repi(i, a, b) for(auto i = a;i <= b;i++)
template<class t>t mag(t a){return a>0?a:-a;}
template <class T, class U>T cdiv(T num,U den){return (num/den)+((num%den)>0);}
std::ifstream term("/dev/tty");std::string tempstring;
using ll=int_fast64_t;using ii=pair<int,int>;using vi=vector<int>;
using vl=vector<ll>;using vii = vector<ii>;
const int &sij = 400010;const ll &mod = 1000000007ll;
int n, pre[200], nx[200], fre[200], vis[200], cyc;
string prt;
vector<string> vec;
void fail(){
  cout << "NO";
  exit(0);
}
int esc(int tcase){
  cin >> n;
  vec.resize(n);
  memset(pre, -1, sizeof(pre));
  memset(nx, -1, sizeof(nx));
  for(auto &e:vec)  cin >> e;
  for(auto &e:vec){
    if(e.size() > 26){
      fail();
    }
    fre[e[0]] = 1;
    rep(i, 0, e.size() - 1){
      fre[e[i]] = fre[e[i + 1]] = 1;
      if(nx[e[i]] == -1){
        nx[e[i]] = e[i + 1];
      }
      else if(nx[e[i]] != e[i + 1]){
        fail();
      }
      if(pre[e[i + 1]] == -1){
        pre[e[i + 1]] = e[i];
      }
      else if(pre[e[i + 1]] != e[i]){
        fail();
      }
    }
  }
  function<void(char)> dfs;
  dfs = [&](int x){
    vis[x] = 1;
    if(nx[x] != -1){
      if(vis[nx[x]] == 1){
        fail();
      }
      if(vis[nx[x]] == 0) dfs(nx[x]);
    }
    vis[x] = 2;
  };
  repi(i, 'a', 'z'){
    if(vis[i] == 0) dfs(i);
  }
  repi(i, 'a', 'z'){
    if(pre[i] == -1 and fre[i]){
      char cr = i;
      prt += cr;
      while(nx[cr] != -1){
        prt += char(nx[cr]);
        cr = nx[cr];
      }
    }
  }
  cout << prt << endl;
  return 0;
}
int main(){
  ios_base::sync_with_stdio(0);
#ifndef sep
  cin.tie(0);
  cout.tie(0);
#endif
  int tc = 1;
  for(int i = 1;i <= tc;i++)
    esc(i);
#ifdef sep
  cerr << "\n\nTime : "<<1.0* clock()/CLOCKS_PER_SEC << "s.\n\n";
#endif
}


#include "bits/stdc++.h"
using namespace std;
#include "vector"
#define endl '\n'
#ifndef dgb
#define dbg(...)
#define dbgv(x)
#define debug(...)
#endif
#define pb push_back
#define eb emplace_back
#define rep(i, a, b) for(auto i = a;i != b;i++)
#define brep(i, a, b) for(auto i = a;i >= b;i--)
#define repi(i, a, b) for(auto i = a;i <= b;i++)
template<class t>t mag(t a){return a>0?a:-a;}
template <class T, class U>T cdiv(T num,U den){return (num/den)+((num%den)>0);}
std::ifstream term("/dev/tty");std::string tempstring;
using ll=int_fast64_t;using ii=pair<int,int>;using vi=vector<int>;
using vl=vector<ll>;using vii = vector<ii>;
const int &sij = 400010;const ll &mod = 1000000007ll;
int n, pre[200], nx[200], fre[200], vis[200];
string prt;
vector<string> vec;
void fail(){
  cout << "NO";
  exit(0);
}
int esc(int tcase){
  cin >> n;
  vec.resize(n);
  memset(pre, -1, sizeof(pre));
  memset(nx, -1, sizeof(nx));
  for(auto &e:vec)  cin >> e;
  for(auto &e:vec){
    if(e.size() > 26){
      fail();
    }
    rep(i, 0, e.size() - 1){
      fre[e[i]] = fre[e[i + 1]] = 1;
      if(nx[e[i]] == -1){
        nx[e[i]] = e[i + 1];
      }
      else if(nx[e[i]] != e[i + 1]){
        fail();
      }
      if(pre[e[i + 1]] == -1){
        pre[e[i + 1]] = e[i];
      }
      else if(pre[e[i + 1]] != e[i]){
        fail();
      }
    }
  }
  repi(i, 'a', 'z'){
    if(pre[i] == -1 and fre[i]){
      if(vis[i] == 1) fail();
      vis[i] = 1;
      char cr = i;
      prt += cr;
      while(nx[cr] != -1){
        if(vis[nx[cr]]) fail();
        vis[nx[cr]] = 1;
        prt += char(nx[cr]);
        cr = nx[cr];
      }
    }
  }
  cout << prt << endl;
  return 0;
}
int main(){
  ios_base::sync_with_stdio(0);
#ifndef sep
  cin.tie(0);
  cout.tie(0);
#endif
  int tc = 1;
  for(int i = 1;i <= tc;i++)
    esc(i);
#ifdef sep
  cerr << "\n\nTime : "<<1.0* clock()/CLOCKS_PER_SEC << "s.\n\n";
#endif
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define pii pair<int,int>
#define pll pair<ll, ll>
#define pil pair<int,ll>
#define pli pair<ll,int>
#define ppi pair<pii,int>
#define pip pair<int,pii>
#define pdd pair<double, double>
#define f first
#define s second
#define MOD 1000000007
#define mkp make_pair
#define M_PI 3.14159265358979323846
#define FOR(i,l,r) for (int i=l;i<=r;i++)
#define LOR(i,l,r) for (ll i=l;i<=r;i++)
#define FORD(i,r,l) for (int i=r;i>=l;i--)
#define LORD(i,r,l) for (ll i=r;i>=l;i--)
#define INF 1000000000
#define CL(x) memset(x,0,sizeof(x))
#define DEB(x) cout << #x << " : " << x << '\n'
#define ALL(x) x.begin(), x.end()
#define SZ(x) x.size()
#define UI(x) (int)(x-'A')
#define LI(x) (int)(x-'a')
typedef long long ll;

/*

1. check that every letter is distinct in that string
2. check that every letter is distinct in whole set, if not->
    try to insert it into another string, if fail then fail

optimize:
1. since all letters appear once, use linked list on letters
*/

int N;
bool has[30];
bool ghas[30];
int pos[30];
int ri[30],lf[30];//1~26
string str;
bool f;
bool vis[30];
vector<int> ans;

bool con(int a, int b)
{
    if( ri[a] && lf[b] )
    {
        //if(ri[a]!=b)cout<<a<<' '<<b<<'\n';
        return (ri[a]==b);
    }
    else if( !ri[a] && !lf[b] )
    {
        ri[a]=b;
        lf[b]=a;
        return true;
    }
    //cout<<a<<' '<<b<<'\n';
    return false;
}

void dfs(int u)
{
    vis[u]=true;
    ans.pb(u);
    int v = ri[u];
    if( !v )return;
    else if( vis[v] )
    {
        f=true;
        return;
    }
    dfs(v);
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    cin>>N;
    FOR(i,1,N)
    {
        cin>>str;
        CL(has);
        for(char c : str)
        {
            int ai = c-'a'+1;
            if(has[ai])
            {
                f=true;
                break;
            }
            has[ai]=true;
            ghas[ai]=true;
        }
        if(f)break;
        //update linked list
        int S = SZ(str);
        if(S==1)continue;
        int nx,ai;
        FOR(i,0,S-2)
        {
            ai=str[i]-'a'+1;
            nx=str[i+1]-'a'+1;
            //cout<<"con "<<ai<<' '<<nx<<'\n';
            if(!con(ai,nx))
            {
                f=true;
                break;
            }
        }
        if(f)break;
        //handle tail
        if( ri[nx] )
        {
            if( !con(nx,ri[nx]) )
            {
                f=true;
                break;
            }
        }
    }

    if(f)
    {
        cout<<"NO"<<'\n';
        return 0;
    }

    //topo sort
    FOR(i,1,26)if(ghas[i] && !lf[i])dfs(i);
    if(f)
    {
        cout<<"NO"<<'\n';
        return 0;
    }
    FOR(i,1,26)if(ghas[i] && !vis[i])f=true;
    if(f)
    {
        cout<<"NO"<<'\n';
        return 0;
    }
    for(int ai:ans)cout<<(char)('a'+ai-1);
    cout<<'\n';

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define pii pair<int,int>
#define pll pair<ll, ll>
#define pil pair<int,ll>
#define pli pair<ll,int>
#define ppi pair<pii,int>
#define pip pair<int,pii>
#define pdd pair<double, double>
#define f first
#define s second
#define MOD 1000000007
#define mkp make_pair
#define M_PI 3.14159265358979323846
#define FOR(i,l,r) for (int i=l;i<=r;i++)
#define LOR(i,l,r) for (ll i=l;i<=r;i++)
#define FORD(i,r,l) for (int i=r;i>=l;i--)
#define LORD(i,r,l) for (ll i=r;i>=l;i--)
#define INF 1000000000
#define CL(x) memset(x,0,sizeof(x))
#define DEB(x) cout << #x << " : " << x << '\n'
#define ALL(x) x.begin(), x.end()
#define SZ(x) x.size()
#define UI(x) (int)(x-'A')
#define LI(x) (int)(x-'a')
typedef long long ll;

/*

1. check that every letter is distinct in that string
2. check that every letter is distinct in whole set, if not->
    try to insert it into another string, if fail then fail

optimize:
1. since all letters appear once, use linked list on letters
*/

int N;
bool has[30];
bool ghas[30];
int pos[30];
int ri[30],lf[30];//1~26
string str;
bool f;
bool vis[30];

bool con(int a, int b)
{
    if( ri[a] && lf[b] )
    {
        //if(ri[a]!=b)cout<<a<<' '<<b<<'\n';
        return (ri[a]==b);
    }
    else if( !ri[a] && !lf[b] )
    {
        ri[a]=b;
        lf[b]=a;
        return true;
    }
    //cout<<a<<' '<<b<<'\n';
    return false;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    cin>>N;
    FOR(i,1,N)
    {
        cin>>str;
        CL(has);
        for(char c : str)
        {
            int ai = c-'a'+1;
            if(has[ai])
            {
                f=true;
                break;
            }
            has[ai]=true;
            ghas[ai]=true;
        }
        if(f)break;
        //update linked list
        int S = SZ(str);
        if(S==1)continue;
        int nx,ai;
        FOR(i,0,S-2)
        {
            ai=str[i]-'a'+1;
            nx=str[i+1]-'a'+1;
            //cout<<"con "<<ai<<' '<<nx<<'\n';
            if(!con(ai,nx))
            {
                f=true;
                break;
            }
        }
        if(f)break;
        //handle tail
        if( ri[nx] )
        {
            if( !con(nx,ri[nx]) )
            {
                f=true;
                break;
            }
        }
    }

    if(f)
    {
        cout<<"NO"<<'\n';
        return 0;
    }
    vector<int> ans;
    FOR(i,1,26)
    {
        if(vis[i] || !ghas[i] || lf[i])continue;
        int now = i;
        while( now && !vis[now] )
        {
            ans.pb(now);
            now = ri[now];
        }
    }
    for(int ai : ans)cout<<(char)('a'+ai-1);
    cout<<'\n';

    return 0;
}


#pragma GCC optimize("O3")
//#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include<bits/stdc++.h>
using namespace std;
#define bll __int128
#define ll long long
#define ld  double
#define pii pair<int,int>
#define pip pair<int,pii>
#define ppi pair<pii,int>
#define ppp pair<pii,pii>
#define pb push_back
#define ppb pop_back
#define pf push_front
#define ppf pop_front
#define ff first
#define ss second
#define warmup ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
const int N = 200003, mod=1e9+7;
const ll inf=(1e18+11);
int freq[26], indeg[26], pres[26];
unordered_set<int> g[26];
string ans;

void dfs(int i)
{
    bool f=0;
    ans+=(char)(i+'a');

    for(auto it:g[i])
    {
        if(f)
            ans+=(char)(i+'a');

        --indeg[it];
        if(!indeg[it])
            --indeg[it];

        dfs(it);
        f=1;
    }
}

signed main()
{
    warmup

    int n;
    cin>>n;
    int i,j,x,y,sz;
    char ch;
    string s;
    for(j=0;j<n;++j)
    {
        cin>>s;
        sz=s.size();
        fill(freq,freq+26,0);
        freq[s[0]-'a']++;
        pres[s[0]-'a']=1;
        for(i=1;i<sz;++i)
            g[s[i-1]-'a'].insert(s[i]-'a'), ++freq[s[i]-'a'], ++indeg[s[i]-'a'], pres[s[i]-'a']=1;

        for(i=0;i<26;++i)
            if(freq[i]>1)
                return cout<<"NO", 0;
    }

    ans="";
    for(i=0;i<26;++i)
        if(pres[i] and !indeg[i])
            dfs(i);

    if(!ans.size())
        ans="NO";

    cout<<ans;

    return 0;
}