#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);
  }
};

template <size_t SIZE>
struct RollingHash_MultiBase {
  using Array = array<uint64_t, SIZE>;
  array<RollingHash, SIZE> rhs;
  Array bases;
  RollingHash_MultiBase() = default;
  RollingHash_MultiBase(const string& s, Array bs)
      : RollingHash_MultiBase(vector<char>(s.begin(), s.end()), bs) {}
  template <typename T>
  RollingHash_MultiBase(const vector<T>& s, Array bs) : bases(bs) {
    for (size_t i = 0; i < SIZE; i++) rhs[i] = RollingHash(s, bases[i]);
  }
  Array get_hash(int l, int r) const {
    Array ret;
    for (size_t i = 0; i < 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) {
    for (size_t i = 0; i < 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();
  auto base2 = RollingHash::generate_base();
  using RHMB = RollingHash_MultiBase<2>;
  int N;
  cin >> N;
  string S[N];
  for (int i = 0; i < N; i++) cin >> S[i];
  RHMB rh[N];
  for (int i = 0; i < N; i++) rh[i] = RHMB(S[i], {base1, base2});
  map<RHMB::Array, vector<long long>> mp;
  for (int i = 0; i < N; i++) {
    auto hash = rh[i].get_hash(1, S[i].length());
    if (mp.find(hash) == mp.end()) mp[hash].assign(26, 0);
    mp[hash][S[i][0] - 'a']++;
  }
  // cerr << tick() << '\n' << flush;
  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');
      if (j >= 1) {
        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];
      }
    }
  }
  cout << ans << '\n';
  // cerr << tick() << '\n' << flush;
  return 0;
}


Measured memory_bytes: 121344