#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)n; ++i)
#define rrep(i, n) for (int i = (int)n-1; i >= 0; --i)
using namespace std;
using ll = long long;
template<typename T>
inline bool chmax(T& a, const T& b) {
    if (a < b){
        a = b;
        return true;
    }
    return false;
}
template<typename T>
inline bool chmin(T& a, const T& b) {
    if (b < a) {
        a = b;
        return true;
    }
    return false;
}
template<typename T> vector<T> make_vec(size_t n) { return vector<T>(n); }
template<typename T, typename... Args> auto make_vec(size_t n, Args... args) {
    return vector<decltype(make_vec<T>(args...))>(n, make_vec<T>(args...));
}
template<typename T, typename U, typename... V>
typename enable_if<is_same<T, U>::value>::type fill_v(U& u, const V... v) { u = U(v...); }
template<typename T, typename U, typename... V>
typename enable_if<!is_same<T, U>::value>::type fill_v(U& u, const V... v) {
    for (auto& e : u) fill_v<T>(e, v...);
}

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::sync_with_stdio(false);
    cin.tie(nullptr);

    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;
    rep(i, n) {
        rolling_hash rh(s[i], base);
        int mask = 0;
        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)]);
        }
        mp[rh.substr(0, s[i].size() - 1)] += 1 << (s[i].back() - 'a');
    }
    cout << ans << '\n';
}


Measured memory_bytes: 80868