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>
using namespace std;

#define REP(i,m,n) for(int i=(m); i<(int)(n); i++)
#define RREP(i,m,n) for(int i=(int)((n)-1); i>=m; i--)
#define rep(i,n) REP(i,0,n)
#define rrep(i,n) RREP(i,0,n)
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define fi first
#define se second
#define debug(...) {cerr<<"[L"<<__LINE__<<"] "; _debug(__VA_ARGS__);}

template<typename T>
string join(const vector<T>&v, string del=", "){ stringstream s;
    for(auto x : v) s << del << x; return s.str().substr(del.size());
}
template<typename T>
ostream& operator<<(ostream& o, const vector<T>&v){
    if(v.size()) o << "[" << join(v) << "]"; return o;
}
template<typename T>
ostream& operator<<(ostream& o, const vector<vector<T> >&vv){
    int l = vv.size();
    if(l){ o<<endl; rep(i,l) o << (i==0 ? "[ " : ",\n  " ) << vv[i] << (i==l-1 ? " ]" : ""); }
    return o;
}
template<typename T1, typename T2>
ostream& operator<<(ostream& o, const pair<T1, T2>& p){
    return o << "(" << p.first << ", " << p.second << ")";
}
inline void _debug(){cerr<<endl;}
template<class First, class... Rest>
void _debug(const First& first, const Rest&... rest){cerr<<first<<" ";_debug(rest...);}

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;

const double PI = (1*acos(0.0));
const double EPS = 1e-9;
const int INF = 0x3f3f3f3f;
const ll INFL = 0x3f3f3f3f3f3f3f3fLL;
const ll mod = 1e9 + 7;

inline void finput(string filename) {
    freopen(filename.c_str(), "r", stdin);
}

struct RollingHash{
    static const ll base1 = 1009;
    static const ll base2 = 2009;
    static const ll mod1 = 1000000009;
    static const ll mod2 = 1000000007;
    int n;
    vl hash1,hash2,pow1,pow2;
    RollingHash() = default;
    RollingHash(const string &s){
        n = s.size();
        hash1.assign(n+1, 0);
        hash2.assign(n+1, 0);
        pow1.assign(n+1, 1);
        pow2.assign(n+1, 1);
        rep(i,n){
            hash1[i+1] = (hash1[i] * base1 + s[i]) % mod1;
            hash2[i+1] = (hash2[i] * base2 + s[i]) % mod2;
            pow1[i+1] = (pow1[i] * base1) % mod1;
            pow2[i+1] = (pow2[i] * base2) % mod2;
        }
    }
    // S[l,r)のハッシュ値を返す.
    // O(1)
    inline pair<ll,ll> hash(int l, int r) const {
        ll res1 = (hash1[r] - (hash1[l]*pow1[r-l] % mod1) + mod1) % mod1;
        ll res2 = (hash2[r] - (hash2[l]*pow2[r-l] % mod2) + mod2) % mod2;
        return make_pair(res1, res2);
    }
    inline pair<ll,ll> hash() const {
        return hash(0, n);
    }
    // Longest Common Prefix.
    // O(logN)
    inline int calcLCP(const RollingHash & rh, int l1, int r1, int l2, int r2) const {
        int low = 0, high = min(r1-l1, r2-l2);
        while(high - low > 1){
            int mid = (low + high) / 2;
            if(hash(l1, l1+mid) == hash(l2, l2+mid)){
                low = mid;
            }else{
                high = mid;
            }
        }
        return low;
    }
    // hash h1とhash h2を結合.
    pair<ll,ll> concat(pair<ll,ll> h1, pair<ll,ll> h2, int h2len){
        ll res1 = h1.first * pow1[h2len] + h2.first % mod1;
        ll res2 = h1.second * pow2[h2len] + h2.second % mod2;
        return make_pair(res1, res2);
    }
};

int main(){
    ios_base::sync_with_stdio(0);
    // finput("./input");
    int n; cin >> n;
    vector<string> ss(n);
    rep(i,n) cin >> ss[i];

    vector<RollingHash> rhs(n);
    rep(i,n) rhs[i] = RollingHash(ss[i]);
    vi cnt(26);
    vi cnt_total(26);
    map<pll,array<int, 26>> mp;
    rep(i,n){
        fill(all(cnt), 0);
        cnt[ss[i][0]-'a'] = 1;
        REP(j,1,ss[i].size()){
            auto h = rhs[i].hash(j, ss[i].size());
            rep(c,26) if(cnt[c]) ++mp[h][c];
            cnt[ss[i][j]-'a'] = 1;
        }
        rep(c,26) cnt_total[c] += cnt[c];
    }

    ll ans = 0;
    rep(i,n){
        if(ss[i].size() == 1){
            ans += cnt_total[ss[i][0]-'a'];
        }else{
            auto h = rhs[i].hash(1,ss[i].size());
            ans += mp[h][ss[i][0]-'a'];
        }
        ans--;
    }
    cout << ans << endl;
    return 0;
}