#include<bits/stdc++.h>
using namespace std;
#define MAXN 200005
#define lowbit(x) (x&-x)
#define reg register
#define mkpr make_pair
typedef long long LL;
typedef unsigned long long uLL;
const int INF=0x3f3f3f3f;
const int mod1=998244353;
const int mod2=1e9+7;
const int mod3=1e9+9;
const int iv2=5e8+4;
const int lim=1000000;
const int jzm=1e6+7;
const int orG=3,invG=332748118;
const double Pi=acos(-1.0);
typedef pair<int,int> pii;
const double PI=acos(-1.0);
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){
	_T f=1;x=0;char s=getchar();
	while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
	while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}
	x*=f;
}
template<typename _T>
void print(_T x){if(x<0){x=(~x)+1;putchar('-');}if(x>9)print(x/10);putchar(x%10+'0');}
int gcd(int x,int y){return !y?x:gcd(y,x%y);}
int n,sum,num[30],tot,id[MAXN],n1,root[MAXN];LL ans;
char str[MAXN],ss[10];
struct hashnode{
	int fir,sec,tri;
	int ask(int dep){
		if(dep>=60)return (fir>>dep-60)&1;
		if(dep>=30)return (sec>>dep-30)&1;
		return (tri>>dep)&1;
	}
	bool operator == (const hashnode &rhs)const{
		return fir==rhs.fir&&sec==rhs.sec&&tri==rhs.tri;
	}
}suf[MAXN],pre[MAXN];
struct ming{int st,ed,len,hs;}a[MAXN];
struct node{int ch[2],sum;};
struct node1{int ch[30],sum;};
vector<int>vec[MAXN],tp[30];
map<int,int>mp;
class TrieTree{
	public:
		int tot;node tr[MAXN*90];
		void clear(){tot=0;tr[0].sum=tr[0].ch[0]=tr[0].ch[1]=0;}
		void insert(int &now,int las,hashnode val,int dep=89){
			if(now==las||!now)tr[now=++tot]=tr[las];
			if(dep<0){tr[now].sum++;return ;}
			if(val.ask(dep))insert(tr[now].ch[1],tr[las].ch[1],val,dep-1);
			else insert(tr[now].ch[0],tr[las].ch[0],val,dep-1);
		}
		int query(int rt,hashnode val,int dep=89){
			if(!rt)return 0;if(dep<0)return tr[rt].sum;
			if(val.ask(dep))return query(tr[rt].ch[1],val,dep-1);
			return query(tr[rt].ch[0],val,dep-1);
		}
}T;
class superTrie{
	public:
		int tot;node1 tr[MAXN*10];
		void clear(){tot=0;tr[0].sum=tr[0].ch[0]=tr[0].ch[1]=0;}
		void insert(int &now,int las,int dep){
			if(now==las||!now)tr[now=++tot]=tr[las];
			if(dep<0){tr[now].sum++;return ;}
			insert(tr[now].ch[ss[dep]-'a'],tr[las].ch[ss[dep]-'a'],dep-1);
		}
		int query(int rt,int dep){
			if(!rt)return 0;if(dep<0)return tr[rt].sum;
			return query(tr[rt].ch[ss[dep]-'a'],dep-1);
		}
}T1;
bool compare(int x,int y,int len){if(!len)return 1;return pre[len+a[x].st-1]==pre[len+a[y].st-1];}
void modify(int i,int l,int r){
	if(n1>9)T.insert(root[i],root[i-1],suf[l]);
	else{
		for(int j=0;j<n1;j++)ss[j]=0;
		int sm=0;for(int j=l;j<r;j++)ss[sm++]=str[j];
		//printf("insert %s\n",ss);
		T1.insert(root[i],root[i-1],sm-1);
	}
}
int found(int i,int l,int r){
	if(n1>9)return T.query(root[i],suf[l]);
	else{
		for(int j=0;j<n1;j++)ss[j]=0;
		int sm=0;for(int j=l;j<r;j++)ss[sm++]=str[j];
		//printf("query %s\n",ss);
		return T1.query(root[i],sm-1);
	}
}
signed main(){
	read(n);
	for(int i=1;i<=n;i++){
		scanf("\n%s",str+sum);a[i].st=sum;
		a[i].len=(int)strlen(str+sum);sum+=a[i].len;n1=a[i].len;a[i].ed=sum;
		for(int j=1;j<=26;j++)num[j]=0;
		for(int j=0;j<a[i].len;j++)num[str[j+a[i].st]-'a'+1]++;
		for(int j=1;j<=26;j++)a[i].hs=(1ll*jzm*a[i].hs+1ll*num[j])%mod1;
		if(n1>9)for(int j=n1-1;j>=0;j--)
			suf[j+a[i].st].fir=(31ll*suf[j+a[i].st+1].fir+1ll*(str[j+a[i].st]-'a'+1))%mod1,
			suf[j+a[i].st].sec=(31ll*suf[j+a[i].st+1].sec+1ll*(str[j+a[i].st]-'a'+1))%mod2,
			suf[j+a[i].st].tri=(31ll*suf[j+a[i].st+1].tri+1ll*(str[j+a[i].st]-'a'+1))%mod3;
				//printf("%s:%d\n",str+j+a[i].st,suf[j+a[i].st].fir);
		pre[a[i].st].fir=pre[a[i].st].sec=pre[a[i].st].tri=str[a[i].st]-'a'+1;
		for(int j=1;j<n1;j++)
			pre[j+a[i].st].fir=(31ll*pre[j+a[i].st-1].fir+1ll*(str[j+a[i].st]-'a'+1))%mod1,
			pre[j+a[i].st].sec=(31ll*pre[j+a[i].st-1].sec+1ll*(str[j+a[i].st]-'a'+1))%mod2,
			pre[j+a[i].st].tri=(31ll*pre[j+a[i].st-1].tri+1ll*(str[j+a[i].st]-'a'+1))%mod3;
		if(!mp[a[i].hs])mp[a[i].hs]=++tot;vec[mp[a[i].hs]].push_back(i);
	}
	int pre=0;mp.clear();
	for(int i=1;i<=tot;i++){
		int siz=vec[i].size();ans+=1ll*siz*(siz-1);ans+=1337ll*siz*pre;pre+=siz;
		for(int j=1;j<=siz;j++)id[j]=vec[i][j-1];
		for(int j=n1-1;j>=0;j--){
			for(int k=1;k<=siz;k++)tp[str[j+a[id[k]].st]-'a'+1].push_back(id[k]);int sum=0;
			for(int k=26;k>0;k--){for(int l=0;l<(int)tp[k].size();l++)id[++sum]=tp[k][l];tp[k].clear();}
		}
		for(int j=2;j<=siz;j++){
			//printf("%d %d:%d\n",i,j,id[j]);
			int l=1,r=j-1,tmp=j-1;for(int k=0;k<n1;k++)modify(j-1,a[id[j-1]].st+k,a[id[j-1]].ed);//printf("insert %d %d\n",suf[a[id[j]].st+k].fir,a[id[j]].st+k);
			if(compare(id[j-1],id[j],n1)){while(l<r){int mid=l+r>>1;if(compare(id[j],id[mid],n1))r=mid;else l=mid+1;}tmp=l-1;}
			ans-=2ll*(j-tmp-1);int head=0;if(!tmp)continue;
			for(int k=1;k<n1;k++)
				if(str[k+a[id[j]].st]<str[k+a[id[j]].st-1]){
					l=1,r=tmp;if(!compare(id[tmp],id[j],head)){head=k;continue;}
					while(l<r){int mid=l+r>>1;if(compare(id[j],id[mid],head))r=mid;else l=mid+1;}
					ans-=1ll*found(tmp,a[id[j]].st+k,a[id[j]].ed)-1ll*found(l-1,a[id[j]].st+k,a[id[j]].ed);head=k;
					//printf("%d range %d %d:%lld %d %c %c\n",j,head,k,ans,l,str[k+a[id[j]].st],str[k+a[id[j]].st-1]);
				}
			if(compare(id[tmp],id[j],head)){l=1,r=tmp;while(l<r){int mid=l+r>>1;if(compare(id[j],id[mid],head))r=mid;else l=mid+1;}ans-=1ll*(tmp-l+1);}
			//printf("%d range %d %d:%lld\n",j,head,n1,ans);
		}
		for(int j=0;j<=siz;j++)root[j]=0;if(n1>9)T.clear();else T1.clear();
	}
	printf("%lld\n",ans);
	return 0;
}
/*
bac
acb
abc
*/