#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define ll long long
#define rep(i,n) for(ll i=0;i<(n);i++)
#define pll pair<ll,ll>
#define pii pair<int,int>
#define pq priority_queue
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define endl '\n'
#define ios ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define lb(c,x) distance(c.begin(),lower_bound(all(c),x))
#define ub(c,x) distance(c.begin(),upper_bound(all(c),x))

using namespace std;

template<class T> inline bool chmax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
template<class T> inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;}

struct rolling_hash {
    using ull = unsigned long long int;
    using uint = unsigned int;
    const ull MASK30 = (1ULL << 30) - 1;
    const ull MASK31 = (1ULL << 31) - 1;
    const ull MOD = (1ULL << 61) - 1;
    const ull POSITIVIZER = MOD * ((1ULL << 3) - 1);
 
     uint base;
    vector<ull> pow_memo, hash;
 
    rolling_hash(const string& s) {
        random_device rd;
        uniform_int_distribution<uint> dist(129, numeric_limits<int>::max() - 1);
        base = dist(rd);
        init(s);
    }
 
    rolling_hash(const string& s, uint base) : base(base) { init(s); }
 
    void init(const string& s) {
        pow_memo.resize(s.size() + 1, 1);
        hash.resize(s.size() + 1);
        for (int i = 0; i < (int)s.size(); ++i) {
            pow_memo[i+1] = calc_mod(mul(pow_memo[i], base));
            hash[i+1] = calc_mod(mul(hash[i], base) + s[i]);
        }
    }
 
    ull substr(int begin, int length) {
        return calc_mod(hash[begin + length] + POSITIVIZER - mul(hash[begin], pow_memo[length]));
    }
 
    ull mul(ull a, ull b) {
        ull au = a >> 31;
        ull al = a & MASK31;
        ull bu = b >> 31;
        ull bl = b & MASK31;
        ull mid = au * bl + al * bu;
        ull midu = mid >> 30;
        ull midl = mid & MASK30;
        return ((au * bu) << 1) + midu + (midl << 31) + al * bl;
    }
 
    ull mul(ull a, uint b) {
        ull au = a >> 31;
        ull al = a & MASK31;
        ull bl = b & MASK31;
        ull mid = au * bl;
        ull midu = mid >> 30;
        ull midl = mid & MASK30;
        return midu + (midl << 31) + al * bl;
    }
 
    ull calc_mod(ull x) {
        ull xu = x >> 61;
        ull xl = x & MOD;
        ull res = xu + xl;
        if (res >= MOD) res -= MOD;
        return res;
    }
};

//使い方
int main() {
    ios;
 
    int n;
    cin >> n;
    vector<string> s(n);
    rep(i, n) cin >> s[i];
    rep(i, n) reverse(s[i].begin(), s[i].end());
    sort(s.begin(), s.end(), [](string a, string b) { return a.size() < b.size(); });
 
    map<unsigned long long, int> mp;
    ll ans = 0;
    unsigned int base = rolling_hash(s[0]).base; //baseをランダム生成
    rep(i, n) {
        rolling_hash rh(s[i], base);
        int mask = 0; //s[i]の先頭j文字以降に現れた文字を管理
        for (int j = s[i].size() - 1; j >= 0; --j) {
            mask |= 1 << (s[i][j] - 'a');
            ans += __builtin_popcount(mask & mp[rh.substr(0, j)]);//「s[i].substr(0,j)+それ以降に現れた1文字」で表される文字の個数を解に加算
        }
        mp[rh.substr(0, s[i].size() - 1)] += 1 << (s[i].back() - 'a');
    }
    cout << ans << '\n';
}

Measured memory_bytes: 80780