end.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
struct data{
int nxt[27],end;
data(){memset(nxt,0,sizeof(nxt)); end=0;}
}a[510003];
vector <int> g[100002]; //存边
int n,cnt,len,siz[100002];
long long f[100002];
char q[510003];
inline bool cmp(const int &A,const int &B) {return siz[A]<siz[B];}
inline void read_q(){
char c=getchar(); len=0;
while(c<‘a‘||c>‘z‘) c=getchar();
while(‘a‘<=c&&c<=‘z‘) q[len++]=c,c=getchar();
}
inline void insert_(int id){ //建树
read_q();
int u=0;
for(int i=len-1;i>=0;--i){
int p=q[i]-‘a‘;
if(!a[u].nxt[p]) a[u].nxt[p]=++cnt;
u=a[u].nxt[p];
}a[u].end=id; //编号代替单词
}
inline void rebuild(int x,int p){ //重新建树
if(a[x].end) g[p].push_back(a[x].end); //存在前缀关系连边
for(int i=0;i<26;++i){
int to=a[x].nxt[i];
if(!to) continue;
rebuild(to,a[x].end ? a[x].end:p);
}
}
inline void dfs1(int x){
siz[x]=1;
for(int i=0;i<g[x].size();++i){
int to=g[x][i];
dfs1(to);
siz[x]+=siz[to];
}
sort(g[x].begin(),g[x].end(),cmp); //按子树从小到大排序
}
inline void dfs2(int x){
f[x]=x? 1:0;
long long tmp=0;
for(int i=0;i<g[x].size();++i){
int to=g[x][i];
dfs2(to);
f[x]+=f[to]+tmp; //贪心累加答案
tmp+=siz[to];
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i) insert_(i);
rebuild(0,0);
dfs1(0);
dfs2(0);
printf("%lld",f[0]);
return 0;
}