Problem:
Score : 700 points

Problem Statement

Limak can repeatedly remove one of the first two characters of a string,
for example abcxyx \rightarrow acxyx \rightarrow cxyx \rightarrow cyx.

You are given N different strings S_1, S_2, \ldots, S_N.
Among N \cdot (N-1) / 2 pairs (S_i, S_j),
in how many pairs could Limak obtain one string from the other?

Constraints

2 \leq N \leq 200\,000

S_i consists of lowercase English letters a-z.

S_i \neq S_j

1 \leq |S_i|

|S_1| + |S_2| + \ldots + |S_N| \leq 10^6

Input

Input is given from Standard Input in the following format.

N
S_1
S_2
\vdots
S_N

Output

Print the number of unordered pairs (S_i, S_j)
where i \neq j and Limak can obtain one string from the other.

Sample Input 1

3
abcxyx
cyx
abc

Sample Output 1

1

The only good pair is (abcxyx, cyx).

Sample Input 2

6
b
a
abc
c
d
ab

Sample Output 2

5

There are five good pairs: (b, abc), (a, abc), (abc, c), (b, ab), (a, ab).

Solution in C++ (GCC 9.2.1) (judge verdict: Accepted)

#include<bits/stdc++.h>
#define ALL(c) begin(c), end(c)
using namespace std;
using ll = long long;
using ld = long double;

const int N = 1e6+6, A = 26;

int to[N][A], td;
int code(char c){return c-'a';}

int cnt[N][A];
void add(vector<bool> &u, string &s, int i = 0, int v = 0){
	if(i == size(s)) return ;
	int c = code(s[i]);
	if(!to[v][c]) to[v][c] = ++td;
	
	add(u, s, i+1, to[v][c]);
	u[c] = 1;
	
	for(int x=0;x<A;++x) if(u[x]) cnt[v][x]++;
}

int main(){
	//freopen("input.txt","r",stdin); //freopen("output.txt","w",stdout);
	ios::sync_with_stdio(0);cin.tie(0);//cout.precision(12);cout<<fixed;
	
	int n;
	
	cin>>n;
	vector<string> s(n);
	for(auto &_ : s) cin>>_;
	
	sort(ALL(s),[](auto &x, auto& y){
		return size(x) > size(y);
	});
	
	ll ans = 0;
	for(string w : s){
		//cerr<<"?"<<w<<endl;
		
		reverse(ALL(w));
		
		int v = 0;
		for(int k=0;k+1<size(w);++k){
			int c = code(w[k]);
			if(!to[v][c]) {v = -1; break;}
			v = to[v][c];
		}
		
		//cerr<<"?"<<v<<endl;
		
		if(v!=-1){
			int cx = code(w.back());
			ans+=cnt[v][cx];
			//cerr<<":"<<ans<<endl;
		}
		
		
		vector<bool> u(A);
		add(u,w);
		
	}
	
	cout<<ans<<endl;
	
	return 0;
}