#include <algorithm>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define rep(i, n) for(int(i) = 0; (i) < (n); (i)++)
#define FOR(i, m, n) for(int(i) = (m); (i) < (n); (i)++)
#define All(v) (v).begin(), (v).end()
#define pb push_back
#define MP(a, b) make_pair((a), (b))
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
const int INF = 1 << 30;
const ll LINF = 1LL << 60;
const int MOD = 1e9 + 7;

// Trie木
// 参考：https://algo-logic.info/trie-tree/
// 挿入、検索ともにO(|文字列の長さ|)
template <int char_size, int base> struct Trie {
    struct Node {
        vector<int> next; //子の頂点のインデックス
        int last;         // 終端する単語数
        int count;        // Nodeを共有する単語数
        Node() : count(0), last(0) { next.assign(char_size, -1); }
    };
    vector<Node> nodes; // Trie木本体
    Trie() { nodes.push_back(Node()); }

    // 単語の挿入
    void insert(const string &word) {
        int node_idx = 0;
        for(int i = 0; i < word.size(); i++) {
            int c = word[i] - base;
            int &next_idx = nodes[node_idx].next[c];
            if(next_idx == -1) {
                next_idx = nodes.size();
                nodes.push_back(Node());
            }
            nodes[node_idx].count++;
            node_idx = next_idx;
        }
        nodes[node_idx].count++;
        nodes[node_idx].last++;
    }

    // 単語の検索（数を返す）
    int search_count(const string &word, bool prefix = false) {
        int node_idx = 0;
        for(int i = 0; i < word.size(); i++) {
            int c = word[i] - base;
            int next_idx = nodes[node_idx].next[c];
            if(next_idx == -1) {
                return 0;
            }
            node_idx = next_idx;
        }
        return prefix ? nodes[node_idx].count : nodes[node_idx].last;
    }

    // prefixを持つ単語の検索（数を返す）
    int prefix_count(const string &prefix) {
        return search_count(prefix, true);
    }

    int word_count() { return nodes[0].count; }

    int size() { return nodes.size(); }

    int count_over(const string &word, vector<int> &hist) {
        int node_idx = 0;
        ll ret = 0;
        for(int i = 0; i < word.size(); i++) {
            for(int k = 0; k < 26; k++) {
                if(hist[k] > 0 && nodes[node_idx].next[k] != -1)
                    ret += nodes[nodes[node_idx].next[k]].last;
            }
            int c = word[i] - base;
            int next_idx = nodes[node_idx].next[c];
            if(next_idx == -1) {
                return ret;
            }
            node_idx = next_idx;
            hist[c]--;
        }
        return ret;
    }
};

int main() {
    int N;
    cin >> N;
    vector<string> S(N);
    rep(i, N) cin >> S[i];
    vector<vector<int>> cnt(N, vector<int>(26));
    sort(All(S),
         [](const string &a, const string &b) { return a.size() < b.size(); });
    for(int i = 0; i < N; i++) {
        reverse(All(S[i]));
        for(int j = 0; j < S[i].size(); j++) {
            cnt[i][(int)(S[i][j] - 'a')]++;
        }
    }
    Trie<26, 'a'> trie;

    ll res = 0;
    rep(i, N) {
        res += trie.count_over(S[i], cnt[i]);
        trie.insert(S[i]);
    }
    cout << res << endl;
    return 0;
}

Measured memory_bytes: 145188