#include <bits/stdc++.h>
#define fst first
#define snd second
#define fore(i,a,b) for(int i=a,ThxDem=b;i<ThxDem;++i)
#define pb push_back
#define ALL(s) s.begin(),s.end()
#define FIN ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define SZ(s) int(s.size())
using namespace std;
typedef long long ll;
typedef pair<int,int> ii;

#define bint __int128
struct Hash {
	bint MOD=212345678987654321LL,P=1777771,PI=106955741089659571LL;
	vector<bint> h,pi;
	Hash(){}
    Hash(string& s){
		assert((P*PI)%MOD==1);
		h.resize(s.size()+1);pi.resize(s.size()+1);
		h[0]=0;pi[0]=1;
		bint p=1;
		fore(i,1,s.size()+1){
			h[i]=(h[i-1]+p*s[i-1])%MOD;
			pi[i]=(pi[i-1]*PI)%MOD;
			p=(p*P)%MOD;
		}
	}
	ll get(int s, int e){
		return (((h[e]-h[s]+MOD)%MOD)*pi[s])%MOD;
	}
};

ll getsorted(string s){
    sort(ALL(s));
    return Hash(s).get(0,SZ(s));
}

int sorted(string &s, vector<int> &d, int now){
    while(d[now]<SZ(s) && s[now]<s[d[now]]) now=d[now];
    return d[now]-1;
}

bool can(string &s, string &t, vector<int> &ds, vector<int> &dt, Hash &hs, Hash &ht){
    int l=0,r=SZ(s)-1;
    while(l<=r){
        int m=(l+r)/2;
        if(hs.get(0,m+1)==ht.get(0,m+1)) l=m+1;
        else r=m-1;
    }

    int st=l;

    l=0; r=SZ(s)-1;
    while(l<=r){
        int m=(l+r)/2;
        if(hs.get(m,SZ(s)) == ht.get(m,SZ(s))) r=m-1;
        else l=m+1;
    }
    int en=r;

    return sorted(s,ds,st)>=en || sorted(t,dt,st)>=en;
}

const int MAXN=2e5+10;
vector<int> df[MAXN];
Hash hs[MAXN];

ll brute(vector<string> &v){
    int n=SZ(v);
    ll ans=0;
    fore(i,0,n) fore(j,i+1,n) ans+=1+(!can(v[i],v[j],df[i],df[j],hs[i],hs[j]));
    return ans;
}

vector<ll> mp[510];
vector<pair<ll,int>> mp2[510];

int get(vector<ll> &v, ll x){
    return upper_bound(ALL(v),x)-lower_bound(ALL(v),x);
}

int get(vector<pair<ll,int>> &v, pair<ll,int> x){
    return upper_bound(ALL(v),x)-lower_bound(ALL(v),x);
}

//prefijo de k, difiere en k+1
ll get(vector<string> &v, int k){
    int pos=0,n=SZ(v),me=SZ(v[0]);
    ll ans=0;
    while(pos<n){
        int id=pos;
        while(id<n&&hs[pos].get(0,k)==hs[id].get(0,k)) id++;
        //ver el rango [pos,id)
        
        fore(i,pos,id){
            fore(j,k,me+1){
                mp[j].pb(hs[i].get(j,me));
                mp2[j].pb({hs[i].get(j,me),v[i][k]});
            }
        }
        fore(j,k,me+1){
            sort(ALL(mp[j]));
            sort(ALL(mp2[j]));
        }

        fore(i,pos,id){
            int to=sorted(v[i],df[i],k)+1;
            ll h=hs[i].get(to,me);
            ans+=get(mp[to],h);
            ans-=get(mp2[to],{h,v[i][k]});
        }

        fore(j,k,me+1){
            mp[j].clear();
            mp2[j].clear();
        }
        pos=id;
    }
    //cout<<"for "<<k<<": "<<ans<<endl;
    return ans;
}

ll linear(vector<string> &v){
    int n=SZ(v),k=SZ(v[0]);
    ll ans=0;
    fore(i,0,k) ans+=get(v,i);
    ans=n*(n-1)-ans;
    return ans;
}

void compute(vector<string> &v){
    int n=SZ(v);
    fore(i,0,n){
        hs[i]=Hash(v[i]);
        int k=SZ(v[i]);
        df[i].resize(k);
        int id=k;
        for(int j=k-1;j>=0;j--){
            if(j==k-1||v[i][j]!=v[i][j+1]) id=j+1;
            df[i][j]=id;
        }
    }
}

int main(){FIN;
    int n; cin>>n;
    vector<string> v(n);
    vector<pair<ll,int>> gr;
    fore(i,0,n) cin>>v[i];
    sort(ALL(v));
    fore(i,0,n) gr.pb({getsorted(v[i]),i});
    sort(ALL(gr));

    ll bad=0,ans=0;
    int pos=0;
    while(pos<n){
        vector<string> now;
        int id=pos;
        while(id<n&&gr[pos].fst==gr[id].fst){
            now.pb(v[gr[id].snd]);
            id++;
        }
        bad+=1ll*SZ(now)*(n-SZ(now));
        compute(now);
        if(n<=1000) ans+=brute(now);
        else ans+=linear(now);
        
        pos=id;
    }
    bad/=2;
    ans+=bad*1337;
    cout<<ans<<"\n";
}