#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
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;
}

#ifdef DEBUG
void debug() { cerr << "\n"; }
template <class T> void debug(const T &x) { cerr << x << "\n"; }
template <class T, class... Args> void debug(const T &x, const Args &... args) {
    cerr << x << " ";
    debug(args...);
}
template <class T> void debugVector(const vector<T> &v) {
    for(const T &x : v) {
        cerr << x << " ";
    }
    cerr << "\n";
}
#else
template <class T, class... Args>
void debug(const T &x, const Args &... args) {}
template <class T> void debugVector(const vector<T> &v) {}
#endif

using ll = long long;
#define ALL(v) (v).begin(), (v).end()
#define RALL(v) (v).rbegin(), (v).rend()
const double EPS = 1e-7;
const int INF = 1 << 30;
const ll LLINF = 1LL << 60;
constexpr int MOD = 1000000007;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

//-------------------------------------

struct RollingHash {
    static const int base1 = 1007, base2 = 2009;
    static const int mod1 = 1000000007, mod2 = 1000000009;
    vector<long long> hash1, hash2, power1, power2;

    // construct
    RollingHash(const string &S) {
        int n = (int)S.size();
        hash1.assign(n + 1, 0);
        hash2.assign(n + 1, 0);
        power1.assign(n + 1, 1);
        power2.assign(n + 1, 1);
        for(int i = 0; i < n; ++i) {
            hash1[i + 1] = (hash1[i] * base1 + S[i]) % mod1;
            hash2[i + 1] = (hash2[i] * base2 + S[i]) % mod2;
            power1[i + 1] = (power1[i] * base1) % mod1;
            power2[i + 1] = (power2[i] * base2) % mod2;
        }
    }

    // get hash of S[left:right]
    inline pair<long long, long long> get(int l, int r) const {
        long long res1 = hash1[r] - hash1[l] * power1[r - l] % mod1;
        if(res1 < 0)
            res1 += mod1;
        long long res2 = hash2[r] - hash2[l] * power2[r - l] % mod2;
        if(res2 < 0)
            res2 += mod2;
        return {res1, res2};
    }

    // get lcp of S[a:] and T[b:]
    inline int getLCP(int a, int b) const {
        int len = min((int)hash1.size() - a, (int)hash1.size() - b);
        int low = 0, high = len;
        while(high - low > 1) {
            int mid = (low + high) >> 1;
            if(get(a, a + mid) != get(b, b + mid))
                high = mid;
            else
                low = mid;
        }
        return low;
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N;
    cin >> N;
    vector<string> s(N);
    for(int i = 0; i < N; i++) {
        cin >> s[i];
    }
    sort(ALL(s), [](const string &a, const string &b) {
        return (a.size() < b.size());
    });
    map<pair<ll, ll>, ll> cnt[26];
    ll ans = 0;
    for(int i = 0; i < N; i++) {
        int sz = s[i].size();
        vector<int> exist;
        int num = 0;
        for(int j = 0; j < sz; j++) {
            num |= (1 << (s[i][j] - 'a'));
            exist.emplace_back(num);
        }
        reverse(ALL(exist));
        reverse(ALL(s[i]));
        RollingHash rh(s[i]);
        if(sz <= 1) {
            cnt[s[i][0] - 'a'][make_pair(0LL, 0LL)]++;
            continue;
        }
        for(int j = 0; j < sz - 1; j++) {
            for(int k = 0; k < 26; k++) {
                if(exist[j] & (1 << k)) {
                    if(cnt[k].count(rh.get(0, j)) == 0) {
                        continue;
                    }
                    ans += cnt[k][rh.get(0, j)];
                }
            }
        }
        cnt[s[i].back() - 'a'][rh.get(0, sz - 1)]++;
    }
    cout << ans << endl;
}

Measured memory_bytes: 39880