#include <bits/stdc++.h>

using namespace std;


using int64 = long long;

const int64 infll = (1LL << 62) - 1;
const int inf = (1 << 30) - 1;

struct IoSetup {
  IoSetup() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);
    cerr << fixed << setprecision(10);
  }
} iosetup;


template< typename T1, typename T2 >
ostream &operator<<(ostream &os, const pair< T1, T2 > &p) {
  os << p.first << " " << p.second;
  return os;
}

template< typename T1, typename T2 >
istream &operator>>(istream &is, pair< T1, T2 > &p) {
  is >> p.first >> p.second;
  return is;
}

template< typename T >
ostream &operator<<(ostream &os, const vector< T > &v) {
  for(int i = 0; i < (int) v.size(); i++) {
    os << v[i] << (i + 1 != v.size() ? " " : "");
  }
  return os;
}

template< typename T >
istream &operator>>(istream &is, vector< T > &v) {
  for(T &in : v) is >> in;
  return is;
}

template< typename T1, typename T2 >
inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); }

template< typename T1, typename T2 >
inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); }

template< typename T = int64 >
vector< T > make_v(size_t a) {
  return vector< T >(a);
}

template< typename T, typename... Ts >
auto make_v(size_t a, Ts... ts) {
  return vector< decltype(make_v< T >(ts...)) >(a, make_v< T >(ts...));
}

template< typename T, typename V >
typename enable_if< is_class< T >::value == 0 >::type fill_v(T &t, const V &v) {
  t = v;
}

template< typename T, typename V >
typename enable_if< is_class< T >::value != 0 >::type fill_v(T &t, const V &v) {
  for(auto &e : t) fill_v(e, v);
}

template< typename F >
struct FixPoint : F {
  FixPoint(F &&f) : F(forward< F >(f)) {}

  template< typename... Args >
  decltype(auto) operator()(Args &&... args) const {
    return F::operator()(*this, forward< Args >(args)...);
  }
};

template< typename F >
inline decltype(auto) MFP(F &&f) {
  return FixPoint< F >{forward< F >(f)};
}


uint64_t power[1010101];
using uint128_t = __uint128_t;
static const uint64_t mod = (1ull << 61ull) - 1;

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

/**
 * @brief Rolling-Hash(ローリングハッシュ)
 * @see https://qiita.com/keymoon/items/11fac5627672a6d6a9f6
 * @docs docs/rolling-hash.md
 */
struct RollingHash {
  vector< uint64_t > hashed;
  const uint64_t base;

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

  RollingHash() = default;

  RollingHash(const string &s, uint64_t base) : base(base) {
    size_t sz = s.size();
    hashed.assign(sz + 1, 0);
    for(int i = 0; i < sz; i++) {
      hashed[i + 1] = add(mul(hashed[i], base), s[i]);
    }
  }

  template< typename T >
  RollingHash(const vector< T > &s, uint64_t base) : base(base) {
    size_t sz = s.size();
    hashed.assign(sz + 1, 0);
    for(int i = 0; i < sz; i++) {
      hashed[i + 1] = add(mul(hashed[i], base), s[i]);
    }
  }

  uint64_t query(int l, int r) const {
    return add(hashed[r], mod - mul(hashed[l], power[r - l]));
  }

  uint64_t combine(uint64_t h1, uint64_t h2, size_t h2len) const {
    return add(mul(h1, power[h2len]), h2);
  }

  int lcp(const RollingHash &b, int l1, int r1, int l2, int r2) const {
    assert(base == b.base);
    int len = min(r1 - l1, r2 - l2);
    int low = 0, high = len + 1;
    while(high - low > 1) {
      int mid = (low + high) / 2;
      if(query(l1, l1 + mid) == b.query(l2, l2 + mid)) low = mid;
      else high = mid;
    }
    return low;
  }
};


int main() {
  int N;
  cin >> N;
  vector< string > S(N);
  cin >> S;

  auto base = RollingHash::generate_base();

  power[0] = 1;
  for(int i = 0; i < 1010100; i++) {
    power[i + 1] = mul(power[i], base);
  }

  vector< uint64_t > vs;
  for(int i = 0; i < 26; i++) {
    string s;
    s += (char) (i + 'a');
    vs.emplace_back(RollingHash(s, base).query(0, 1));
  }

  map< uint64_t, int > mp[1010101];
  int64 ret = 0;
  vector< RollingHash > rols;
  for(int i = 0; i < N; i++) {
    rols.emplace_back(RollingHash(S[i], base));
    mp[S[i].size()][rols.back().query(0, S[i].size())]++;
  }
  for(int i = 0; i < N; i++) {
    auto &roll = rols[i];
    int ok = 0;
    for(int j = 0; j <= S[i].size(); j++) {
      if(j == S.size()) {
        for(int k = 0; k < 26; k++) {
          if((ok >> k) & 1) {
            auto it = mp[S[i].size() - j + 1].find(vs[k]);
            if(it != end(mp[S[i].size() - j + 1])) ret += it->second;
          }
        }
      } else if(j > 0) {
        for(int k = 0; k < 26; k++) {
          if((ok >> k) & 1) {
            auto it = mp[S[i].size() - j + 1].find(roll.combine(vs[k], roll.query(j, S[i].size()), S[i].size() - j));
            if(it != end(mp[S[i].size() - j + 1])) ret += it->second;
          }
        }
      } else {
        auto it = mp[S[i].size() - j + 1].find(roll.query(j, S[i].size()));
        if(it != end(mp[S[i].size() - j + 1])) ret += it->second;
      }
      if(j < S[i].size()) {
        ok |= 1 << (S[i][j] - 'a');
      }
    }
  }

  cout << ret - N << "\n";
}





Measured memory_bytes: 94820