#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")

#include <bits/stdc++.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp> 
using namespace __gnu_pbds; 
typedef long long ll;
typedef long double ld;
#define INF LLONG_MAX
#define F first
#define S second
#define PB push_back
#define MP make_pair
#define MT make_tuple
#define g(a,b) get<a>(b)
#define REP(i,a,b) for(ll i = a; i<=b; i++)
#define REPI(i, a, n)  for(ll i = a; i >= (n); --i)
#define ordered_set tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update> 
#define endl "\n"
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//ordered_set member functions :
//1. order_of_key(k) : number of elements strictly lesser than k
//2. find_by_order(k) : k-th element in the set*/
 
// DISJOINT SET UNION START
ll fn(ll x,ll rn[]) // finding the component
{
    if(x==rn[x]) // Top of its component
        return x;
    else //making parent node of each node of the component the highest node
        return rn[x]=fn(rn[x],rn);
}
bool un(ll x,ll y,ll rn[],ll sz[])// union of components
{
    x=fn(x,rn);
    y=fn(y,rn);
    if(x==y)// if connected already
        return false;
    if(sz[x]<sz[y])// otherwise connectiing light to heavy by swapping
        swap(x,y);
    sz[x]+=sz[y];
    rn[y]=x;// making parent node;
    return true;
}
//DISJOINT SET UNION END

/*/SEGMENT TREE START
ll t[2][4*200000];
void build(ll a[], ll v, ll tl, ll tr,ll par) 
{
    if (tl==tr)
    {
        t[par][v] = a[tl];
    }
    else 
    {
        ll tm = (tl + tr) / 2;
        build(a, v*2, tl, tm,par);
        build(a, v*2+1, tm+1, tr,par);
        t[par][v] = max(t[par][2*v],t[par][2*v+1]);
    }
}
ll query(ll v, ll tl, ll tr, ll l, ll r,ll par) 
{
    if(tl>r || tr<l)
    {
        return 0;
    }
    if(tl>=l and tr<=r) return t[par][v];
    ll tm = (tl + tr) / 2;
    return max(query(2*v, tl, tm, l, r,par),query(2*v+1, tm+1, tr, l, r,par));
}
void update(ll v, ll tl, ll tr, ll pos, ll new_val,ll a[],ll par) 
{
    if (tl == tr) 
    {
        t[par][v]=new_val;
    }
    else 
    {
        ll tm = (tl + tr) / 2;
        if (pos <= tm)
            update(v*2, tl, tm, pos, new_val,a,par);
        else
            update(v*2+1, tm+1, tr, pos, new_val,a,par);
 
        t[par][v] = max(t[par][2*v],t[par][2*v+1]);
    }
}
//SEGMENT TREE END*/
ll gcd(ll a, ll b){if(!b)return a;return gcd(b, a % b);}
ll lcm(ll a , ll b){return (a*b)/gcd(a,b);}
ll MOD=998244353;
ll mod=1000000007;
ll power(ll x,ll y, ll p){ll res=1;x%=p;while(y>0){if(y&1)res=(res*x)%p;y=y>>1;x=(x*x)%p;}return res;}
ll inv(ll val, ll MODx = MOD) 
{
    return power(val, MODx - 2, MODx);
}
vector <ll> fac, ifac;
void preFac(ll sz) 
{
    fac.resize(sz + 1),
    ifac.resize(sz + 1);
    fac[0] = 1;
    for(int i = 1; i <= sz; i++) 
    {
        fac[i] = (i * fac[i - 1]) % MOD;
    }
    ifac[sz] = inv(fac[sz]);
    for(int i=sz-1;i>=0;i--) 
    {
        ifac[i]=((i+1)*ifac[i+1])%MOD;
    }
}
ll nCr(ll N, ll R)
{
    if(R <= N  and  R >= 0) {
        return ((fac[N] * ifac[R]) % MOD * ifac[N - R]) % MOD;
    }
    return 0;
}
set<char> direct[26];
set<char> vis;
vector<char> ans;
void dfs(char t)
{
    if(vis.count(t))
    {
        return;
    }
    vis.insert(t);
    for(auto u:direct[t-'a'])
    {
        if(vis.count(u)==0)
        {
            dfs(u);
        }
    }
    ans.PB(t);
}
string res;
void dfs1(char t)
{
    vis.insert(t);
    res+=t;
    for(auto u:direct[t-'a'])
    {
        if(vis.count(u)==0)
        {
            dfs1(u);
        }
    }
}
int main() 
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    
    ll n;
    cin>>n;
    vector<pair<ll,string>> vec;
    REP(i,0,n-1)
    {
        string s;
        cin>>s;
        vec.PB({s.size(),s});
    }
    sort(vec.begin(),vec.end());
    reverse(vec.begin(),vec.end());
    for(auto u:vec)
    {
        REP(i,0,(ll)u.S.size()-2)
        {
            direct[u.S[i]-'a'].insert(u.S[i+1]);
        }
    }
    set<char> ux;
    REP(i,0,25)
    {
        if(direct[i].size()>1)
        {
            cout<<"NO";
            return 0;
        }
        if(direct[i].size()==1)
        {
            if(ux.count(*direct[i].begin())==1)
            {
                cout<<"NO";
                return 0;
            }
            else
            {
                ux.insert(*direct[i].begin());
            }
        }
    }
    for(auto u:vec)
    {
        if(vis.count(u.S[0])==0)
        {
            dfs(u.S[0]);
        }
    }
    map<char,ll> uxx;
    reverse(ans.begin(),ans.end());
    ll cnt=0;
    for(auto u:ans)
    {
        uxx[u]=cnt;
        cnt++;
    }
    ll flg=0;
    for(char x='a'; x<='z'; x++)
    {
        for(auto u:direct[x-'a'])
        {
            if(uxx[u]<uxx[x])
            {
                flg=1;
            }
        }
    }
    if(flg==1)
    {
        cout<<"NO"<<endl;
        return 0;
    }
    for(auto u:ans)
    {
        cout<<u;
    }
}
//try thinking from a different angle after spending some time
//PLEASE CHECK EDGE CASES!!!