#include <bits/stdc++.h>
using namespace std;
template <class T, class U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
  os << "(" << p.first << "," << p.second << ")";
  return os;
}
#ifdef __LOCAL
#define debug(x) cerr << __LINE__ << ": " << #x << " = " << x << endl
#define debugArray(x, n)                           \
  cerr << __LINE__ << ": " << #x << " = {";        \
  for (long long hoge = 0; (hoge) < (n); ++(hoge)) \
    cerr << ((hoge) ? "," : "") << x[hoge];        \
  cerr << "}" << endl
#else
#define debug(x) (void(0))
#define debugArray(x, n) (void(0))
#endif

struct RollingHash {
 private:
  static constexpr uint64_t mod = (1ull << 61ull) - 1;
  vector<uint64_t> hash, pw;
  uint64_t base;

 private:
  static inline uint64_t add(uint64_t a, uint64_t b) {
    if ((a += b) >= mod) a -= mod;
    return a;
  }
  static inline uint64_t mul(uint64_t a, uint64_t b) {
    __uint128_t c = (__uint128_t)a * b;
    return add(c >> 61, c & mod);
  }

 public:
  static inline uint64_t generate_base() {
    mt19937_64 mt(chrono::steady_clock::now().time_since_epoch().count());
    uniform_int_distribution<uint64_t> rand(1, RollingHash::mod - 1);
    return rand(mt);
  }

  RollingHash() = default;
  RollingHash(const string& s, uint64_t base)
      : RollingHash(vector<char>(s.begin(), s.end()), base) {}
  template <typename T>
  RollingHash(const vector<T>& s, uint64_t base) : base(base) {
    hash.assign(s.size() + 1, 0);
    pw.assign(s.size() + 1, 0);
    pw[0] = 1;
    for (size_t i = 0; i < s.size(); i++) {
      pw[i + 1] = mul(pw[i], base);
      hash[i + 1] = add(mul(hash[i], base), s[i]);
    }
  }
  // S[l, r)
  uint64_t get_hash(int l, int r) const {
    return add(hash[r], mod - mul(hash[l], pw[r - l]));
  }
  uint64_t combine_hash(uint64_t hash1, uint64_t hash2, int hash2len) {
    return add(mul(hash1, pw[hash2len]), hash2);
  }
};

struct RollingHash_MultiBase {
  vector<RollingHash> rhs;
  vector<uint64_t> bases;
  RollingHash_MultiBase() = default;
  RollingHash_MultiBase(const string& s, vector<uint64_t> bs)
      : RollingHash_MultiBase(vector<char>(s.begin(), s.end()), bs) {}
  template <typename T>
  RollingHash_MultiBase(const vector<T>& s, vector<uint64_t> bs) : bases(bs) {
    for (auto base : bases) rhs.emplace_back(RollingHash(s, base));
  }
  vector<uint64_t> get_hash(int l, int r) const {
    vector<uint64_t> ret(rhs.size());
    for (size_t i = 0; i < rhs.size(); i++) ret[i] = rhs[i].get_hash(l, r);
    return ret;
  }
  bool equal(int l1, int r1, int l2, int r2) const {
    return equal(*this, *this, l1, r1, l2, r2);
  }
  int lcp(int l1, int r1, int l2, int r2) const {
    return lcp(*this, *this, l1, r1, l2, r2);
  }
  static bool equal(const RollingHash_MultiBase& a,
                    const RollingHash_MultiBase& b, int l1, int r1, int l2,
                    int r2) {
    assert(a.bases.size() == b.bases.size());
    for (size_t i = 0; i < a.bases.size(); i++)
      if (a.rhs[i].get_hash(l1, r1) != b.rhs[i].get_hash(l2, r2)) return false;
    return true;
  }
  static int lcp(const RollingHash_MultiBase& a, const RollingHash_MultiBase& b,
                 int l1, int r1, int l2, int r2) {
    int len = min(r1 - l1, r2 - l2);
    int low = 0, high = len + 1;
    while (high - low > 1) {
      int mid = (low + high) / 2;
      if (equal(a, b, l1, l1 + mid, l2, l2 + mid))
        low = mid;
      else
        high = mid;
    }
    return low;
  }
};

double tick() {
  static clock_t oldtick;
  clock_t newtick = clock();
  double diff = 1.0 * (newtick - oldtick) / CLOCKS_PER_SEC;
  oldtick = newtick;
  return diff;
}

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  tick();
  auto base1 = RollingHash::generate_base();
  int N;
  cin >> N;
  string S[N];
  for (int i = 0; i < N; i++) cin >> S[i];
  sort(S, S + N, [](string s, string t) { return s.length() < t.length(); });
  RollingHash rh[N];
  for (int i = 0; i < N; i++) rh[i] = RollingHash(S[i], base1);
  // cerr << tick() << '\n' << flush;
  unordered_map<uint64_t, vector<long long>> mp;
  long long ans = 0;
  for (int i = 0; i < N; i++) {
    int n = S[i].length();
    uint32_t bits = 0;
    for (int j = 0; j < n; j++) {
      bits |= 1 << (S[i][j] - 'a');
      auto itr = mp.find(rh[i].get_hash(j + 1, n));
      if (itr == mp.end()) continue;
      for (int k = 0; k < 26; k++)
        if ((bits >> k) & 1) ans += itr->second[k];
    }
    auto hash = rh[i].get_hash(1, n);
    if (mp.find(hash) == mp.end()) mp[hash].assign(26, 0);
    mp[hash][S[i][0] - 'a']++;
  }
  cout << ans << '\n';
  // cerr << tick() << '\n' << flush;
  return 0;
}


Measured memory_bytes: 81996