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         endl     "\n"
#define          EPS     1E-9
#define           PI     acos(-1)
#define        sq(x)     ((x)*(x))
#define           ln     length
#define            F     first
#define            S     second
#define           MP     make_pair
#define           MT     make_tuple
#define           PB     push_back
#define           PF     push_front
#define          PPB     pop_back
#define          PPF     pop_front
#define       ODD(x)     (((x)&1LL) ? (1):(0))
#define       all(v)     (v).begin(), (v).end()
#define    UNIQUE(v)     (v).erase(unique(all(v)), (v).end())
#define     f0(i, n)     for (i = (0); i <  (n); ++i)
#define     f1(i, n)     for (i = (1); i <= (n); ++i)
#define fab(i, a, b)     for (i = (a); i <= (b); ++i)
#define  fr(i, b, a)     for (i = (b); i >= (a); --i)
#define      mark(x)     (marked[(x)>>6] |= (1L<<(((x)%64)>>1)))
#define        on(x)     (marked[(x)>>6] &  (1L<<(((x)%64)>>1)))

using namespace std;

/*
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
typedef tree<int,null_type,less<int>,rb_tree_tag,
    tree_order_statistics_node_update> indexed_set;
//*/
typedef long long int     ll;
#define int               long int
typedef vector<ll>        vll;
typedef pair<ll, ll>      pll;
//typedef tuple<ll, ll, ll> tll;

inline    bool          compare(ll x, ll y)     { return x > y; }
template <typename T> T binaryExpo(T n, T p)    { if (p == 0) { return 1LL;   } if (p&1) { return  n*binaryExpo(n, p - 1);     } T ret = binaryExpo(n, p/2) ; return ret * ret;     }
template <typename T> T bigMod(T n, T p, T m)   { if (p == 0) { return 1LL%m; } if (p&1) { return (n%m*bigMod(n, p - 1, m))%m; } T ret = bigMod(n, p/2, m)%m; return (ret * ret)%m; }
template <typename T> T modInv(T n, T m)        { return bigMod(n, m - 2, m); }

const ll maxN = 2e5+10;   const ll maxB =    320; const ll  INF =  9187201950435737471; //const int  INF =  2139062143;
const ll maxA = 1e6+10;   const ll MOD  = 1e9+7 ; const ll _INF = -9187201950435737472; //const int _INF = -2139062144;

//int dx[8] = { 0,   1,  1,  1,  0,  -1, -1, -1};
//int dy[8] = {-1,  -1,  0,  1,  1,   1,  0, -1};
//              N   NE   E  SE   S   SW   W   NW
//int dx[4] = { 0,       1,      0,      -1    };
//int dy[4] = {-1,       0,      1,       0    };
//int row, column;

int marked[//(maxA>>6) // only for odd numbers
    +2];
vector<ll>prime;

//* function prototypes
void sieve(ll n);
bool is_prime(ll num);
//*/

#ifdef DEBUG
#endif // DEBUG
#ifndef ONLINE_JUDGE
#endif // ONLINE_JUDGE
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ###################################################################################################################
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
map<ll, string>res = {{0, "No"}, {1, "Yes"}};
string s[maxN];

struct node
{
    map<char, node*>path;
    set<int>end_of;
    node() {}
};
unordered_map<char, ll>mp;

signed main()
{
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    cout.precision(15); cout << fixed;
#ifndef ONLINE_JUDGE
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#endif // ONLINE_JUDGE

    //sieve(maxA);
    ll number_of_test_cases = 1, test_case;
    //cin >> number_of_test_cases;
    for (test_case = 1; test_case <= number_of_test_cases; test_case++)
    {
    	//cout << "Test #" << test_case << ": ";
    	//cout << "Case "  << test_case << ": ";
    	ll i, j, k, m, n, query_type, q;

    	cin >> n;
    	f0(i, n) cin >> s[i];
    	f0(i, n)
    	{
    	    reverse(all(s[i]));
    	}

    	node *root = new node;
    	node *curr;

    	f0(i, n)
    	{
    	    curr = root;
    	    f0(j, s[i].length()-1)
    	    {
    	        if (curr->path.count(s[i][j]) == 0)
                {
                    curr->path[s[i][j]] = new node;
                }
                curr = curr->path[s[i][j]];
    	    }
    	    curr->end_of.insert(i);
    	}
    	ll ans = 0;
    	f0(i, n)
    	{
    	    curr = root;
    	    mp.clear();
    	    for (auto c : s[i]) mp[c]++;
    	    for (j = 0; j < s[i].length(); j++)
            {
                for (auto e : curr->end_of)
                {
                    if (e == i) continue;
                    if (mp[s[e].back()] > 0)
                    {
                        ans++;
                    }
                }
                curr = curr->path[s[i][j]];
                mp[s[i][j]]--;
            }
    	}
    	cout << ans << endl;
    }

#ifndef ONLINE_JUDGE
    cerr << "\n........................   execution time : " << 1.0*clock()/CLOCKS_PER_SEC << " s";
#endif // ONLINE_JUDGE
    return 0;
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ###################################################################################################################
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~









bool is_prime(ll num) { return (num > 1 && (num == 2 || (ODD(num) && !on(num))) ); }
void sieve(ll n)
{
    ll i, j; mark(1);
    for (i = 3; i*i <= n; i += 2) { if (!on(i)) { for (j = i*i; j <= n; j += i+i) mark(j); } }
    prime.clear(); prime.push_back(2);
    for (i = 3; i <= n; i += 2) { if (is_prime(i)) prime.push_back(i); }
}