#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;


template<typename T> T rng(T left, T right) {
  static mt19937 mt(chrono::steady_clock::now().time_since_epoch().count());
  return uniform_int_distribution<T>(left, right - 1)(mt);
}

class RollingHash {
private:
  static constexpr int mod_1 = 1000000007;
  static constexpr int mod_2 = 1000000009;
  static long long base_1;
  static long long base_2;
  static vector<long long> pow_1;
  static vector<long long> pow_2;
  vector<long long> hash_1;
  vector<long long> hash_2;
  const int siz;
  template<typename Itr> void build(Itr first, Itr last) {
    hash_1.resize(siz + 1);
    hash_2.resize(siz + 1);
    for (int i = 0; i < siz; ++i, ++first) {
      hash_1[i + 1] = (hash_1[i] * base_1 % mod_1 + *first) % mod_1;
      hash_2[i + 1] = (hash_2[i] * base_2 % mod_2 + *first) % mod_2;
    }
    while ((int) pow_1.size() <= siz) {
      pow_1.push_back(pow_1.back() * base_1 % mod_1);
      pow_2.push_back(pow_2.back() * base_2 % mod_2);
    }
  }
  long long get_1(int left, int right) { return (hash_1[right] + (mod_1 - hash_1[left]) * pow_1[right - left] % mod_1) % mod_1; }
  long long get_2(int left, int right) { return (hash_2[right] + (mod_2 - hash_2[left]) * pow_2[right - left] % mod_2) % mod_2; }
public:
  template<typename Itr> RollingHash(Itr first, Itr last) : siz(distance(first, last)) { build(first, last); }
  template<typename T> RollingHash(const T in) : siz(distance(in.begin(), in.end())) { build(in.begin(), in.end()); }

  // [left, right)
  pair<long long, long long> get(int left, int right) { return make_pair(get_1(left, right), get_2(left, right)); }
  bool is_same(int left_1, int right_1, int left_2, int right_2) { return get(left_1, right_1) == get(left_1, right_2); }
  bool is_same(int left_1, int left_2, int len) { return is_same(left_1, left_1 + len, left_2, left_2 + len); }
  bool is_same(int left, int right, pair<long long, long long> hash) { return get(left, right) == hash; }

  pair<long long, long long> const show_base() { return make_pair(base_1, base_2); }
  void show_hashes() {
    for (int i = 0; i < (int) hash_1.size(); i++) {
      cerr << "i = " << i << " " << hash_1[i] << " " << hash_2[i] << endl;
    }
  }
  void show_pows() {
    for (int i = 0; i < (int) pow_1.size(); i++) {
      cerr << "i = " << i << " " << pow_1[i] << " " << pow_2[i] << endl;
    }
  }
};

long long RollingHash::base_1 = rng<unsigned>(1, RollingHash::mod_1);
long long RollingHash::base_2 = rng<unsigned>(1, RollingHash::mod_2);
vector<long long> RollingHash::pow_1{1};
vector<long long> RollingHash::pow_2{1};
using RH = RollingHash;

signed main() { 
  ios::sync_with_stdio(false); cin.tie(0);
  int n;
  cin >> n;
  vector<string> s(n);
  for (auto& ss : s) cin >> ss;
  for (auto& ss : s) reverse(ss.begin(), ss.end());
  sort(s.begin(), s.end(), [] (const string& x, const string& y) {return x.size() < y.size();});
  vector<vector<int>> v(n);
  for (int i = 0; i < n; i++) {
    int m = s[i].size();
    v[i].resize(m + 1);
    for (int j = m - 1; j >= 0; j--) {
      v[i][j] = v[i][j + 1] | (1 << (s[i][j] - 'a'));
    }
  }
  vector<RH> rhs;
  for (int i = 0; i < n; i++) {
    rhs.push_back(RH(s[i]));
  }
  map<pair<long long, long long>, int> mp;
  long long ans = 0;
  for (int i = 0; i < n; i++) {
    //cerr << "idx = " << i << " " << s[i] << endl;
    for (int j = 0; j < (int) s[i].size(); j++) {
      if (mp.count(rhs[i].get(0, j))) {
        ans += __builtin_popcount(mp[rhs[i].get(0, j)] & v[i][j]);
        //cerr << "inner loop " << i << " " << j << " " << v[i][j] << endl;
      }
    }
    //cerr << i << " " << rhs[i].get(0, (int) s[i].size() - 1).first << " " << rhs[i].get(0, (int) s[i].size() - 1).second << endl;
    //cerr << ans << endl;
    mp[rhs[i].get(0, (int) s[i].size() - 1)] |= (1 << (s[i].back() - 'a'));
  }
  cout << ans << endl;
  return 0;
}

Measured memory_bytes: 63552