#ifdef LOCAL
    #define _GLIBCXX_DEBUG
    #define __clock__
#else
    #pragma GCC optimize("Ofast")
#endif
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using VI = vector<ll>;
using VV = vector<VI>;
using VS = vector<string>;
using PII = pair<ll, ll>;

// tourist set
template <typename A, typename B>
string to_string(pair<A, B> p);

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);

string to_string(const string& s) {
  return '"' + s + '"';
}

string to_string(const char* s) {
  return to_string((string) s);
}

string to_string(bool b) {
  return (b ? "true" : "false");
}

string to_string(vector<bool> v) {
  bool first = true;
  string res = "{";
  for (int i = 0; i < static_cast<int>(v.size()); i++) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(v[i]);
  }
  res += "}";
  return res;
}

template <size_t N>
string to_string(bitset<N> v) {
  string res = "";
  for (size_t i = 0; i < N; i++) {
    res += static_cast<char>('0' + v[i]);
  }
  return res;
}

template <typename A>
string to_string(A v) {
  bool first = true;
  string res = "{";
  for (const auto &x : v) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(x);
  }
  res += "}";
  return res;
}

template <typename A, typename B>
string to_string(pair<A, B> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p) {
  return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p) {
  return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}

void debug_out() { cerr << '\n'; }

template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cerr << " " << to_string(H);
  debug_out(T...);
}

#ifdef LOCAL
#define debug(...) 42
//#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif
// tourist set end

template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }

#define FOR(i,a,b) for(ll i=(a);i<(b);++i)
#define rep(i,b) FOR(i, 0, b)
#define ALL(v) (v).begin(), (v).end()
#define p(s) cout<<(s)<<'\n'
#define p2(s, t) cout << (s) << " " << (t) << '\n'
#define br() p("")
#define pn(s) cout << (#s) << " " << (s) << '\n'
#define SZ(x) ((int)(x).size())
#define SORT(A) sort(ALL(A))
#define RSORT(A) sort(ALL(A), greater<ll>())
#define MP make_pair
#define p_yes() p("YES")
#define p_no() p("NO")

ll SUM(VI& V){
  return accumulate(ALL(V), 0LL);
}

ll MIN(VI& V){return *min_element(ALL(V));}
ll MAX(VI& V){return *max_element(ALL(V));}

void print_vector(VI& V){
  ll n = V.size();
  rep(i, n){
    if(i) cout << ' ';
    cout << V[i];
  }
  cout << endl;
}

ll gcd(ll a,ll b){
    if(b == 0) return a;
    return gcd(b,a%b);
}

ll lcm(ll a,ll b){
    ll g = gcd(a,b);
    return a / g * b;
}

// long double
using ld = long double;
#define EPS (1e-14)
#define equals(a,b) (fabs((a)-(b)) < EPS)

void no(){p_no(); exit(0);}
void yes(){p_yes(); exit(0);}

const ll mod = 1e9 + 7;
const ll inf = 1e18;
const double PI = acos(-1);

// snuke's mint
// auto mod int
// https://youtu.be/L8grWxBlIZ4?t=9858
// https://youtu.be/ERZuLAxZffQ?t=4807 : optimize
// https://youtu.be/8uowVvQ_-Mo?t=1329 : division
// const int mod = 1000000007;
struct mint {
  ll x; // typedef long long ll;
  mint(ll x=0):x((x%mod+mod)%mod){}
  mint operator-() const { return mint(-x);}
  mint& operator+=(const mint a) {
    if ((x += a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator-=(const mint a) {
    if ((x += mod-a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator*=(const mint a) {
    (x *= a.x) %= mod;
    return *this;
  }
  mint operator+(const mint a) const {
    mint res(*this);
    return res+=a;
  }
  mint operator-(const mint a) const {
    mint res(*this);
    return res-=a;
  }
  mint operator*(const mint a) const {
    mint res(*this);
    return res*=a;
  }
  mint pow(ll t) const {
    if (!t) return 1;
    mint a = pow(t>>1);
    a *= a;
    if (t&1) a *= *this;
    return a;
  }

  // for prime mod
  mint inv() const {
    return pow(mod-2);
  }
  mint& operator/=(const mint a) {
    return (*this) *= a.inv();
  }
  mint operator/(const mint a) const {
    mint res(*this);
    return res/=a;
  }
};

// from けんちょんさん
template< unsigned mod >
struct RollingHash {
  vector< unsigned > hashed, power;
 
  inline unsigned mul(unsigned a, unsigned b) const {
    unsigned long long x = (unsigned long long) a * b;
    unsigned xh = (unsigned) (x >> 32), xl = (unsigned) x, d, m;
    asm("divl %4; \n\t" : "=a" (d), "=d" (m) : "d" (xh), "a" (xl), "r" (mod));
    return m;
  }

  RollingHash(){
  }
 
  RollingHash(const string &s, unsigned base = 10007) {
    int sz = (int) s.size();
    hashed.assign(sz + 1, 0);
    power.assign(sz + 1, 0);
    power[0] = 1;
    for(int i = 0; i < sz; i++) {
      power[i + 1] = mul(power[i], base);
      hashed[i + 1] = mul(hashed[i], base) + s[i];
      if(hashed[i + 1] >= mod) hashed[i + 1] -= mod;
    }
  }
 
  // 半開区間
  unsigned get(int l, int r) const {
    unsigned ret = hashed[r] + mod - mul(hashed[l], power[r - l]);
    if(ret >= mod) ret -= mod;
    return ret;
  }
 
  unsigned connect(unsigned h1, int h2, int h2len) const {
    unsigned ret = mul(h1, power[h2len]) + h2;
    if(ret >= mod) ret -= mod;
    return ret;
  }
 
  int LCP(const RollingHash< mod > &b, int l1, int r1, int l2, int r2) {
    int len = min(r1 - l1, r2 - l2);
    int low = -1, high = len + 1;
    while(high - low > 1) {
      int mid = (low + high) / 2;
      if(get(l1, l1 + mid) == b.get(l2, l2 + mid)) low = mid;
      else high = mid;
    }
    return (low);
  }
};

// 1029392827
// 1000000007
using RH = RollingHash< 998244353 >;
using RH2 = RollingHash< 924844033 >;

// super rolling hash
struct SRH {
  RH rh;
  RH2 rh2;
  SRH(){}
  SRH(const string &s){
    rh = RH(s);
    rh2 = RH2(s);
  }
  ll get(ll l, ll r){
    return rh.get(l,r) + 1e9 * rh2.get(l,r);
  }
};

// できること
// 一点追加
// 範囲和
// ei1333's BIT
struct BIT {
  VI data;

  BIT(ll sz) {
    data.assign(++sz, 0);
  }

  ll sum(ll k) {
    ll ret = 0;
    for(++k; k > 0; k -= k & -k) ret += data[k];
    return (ret);
  }

  // [i, j]
  ll range_sum(ll i, ll j){
    if(i==0){
      return sum(j);
    }else{
      return sum(j) - sum(i-1);    
    }
  }

  void add(ll k, ll x) {
    for(++k; k < SZ(data); k += k & -k) data[k] += x;
  }
};

// 26本のBITを持つ。範囲内の文字数をカウント
struct Hoge{
  vector<BIT> bits;

  Hoge(string& s){
    ll N = s.size();
    rep(i,26){
      auto bi = BIT(N);
      bits.push_back(bi);
    }
    rep(i,N){
      ll v = s[i]-'a';
      bits[v].add(i, 1);
    }
  }

  // 閉区間
  ll range_count(ll l, ll r, char c){
    ll v = c-'a';
    return bits[v].range_sum(l,r);
  }
};

// 文字列を長さでソート
bool comp(const std::string& lh, const std::string& rh) {
     // 文字列lhの長さが文字列rhより短かったらtrueを返す
     return lh.length() < rh.length();
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);

    // input
    ll N; 
    cin>>N;

    VS S(N);
    rep(i,N){
      string s;cin>>s;
      S[i]=s;
    }
    sort(ALL(S), comp); // 短い順にソート
    debug(S);

    ll cnt=0;

    // 先頭文字と「それ以外の文字列のhash」　＝＞　出現回数
    // (char, hash) => count
    map<pair<char,ll>, ll> mp;
    
    for(string s : S){
      ll L = SZ(s);
      auto rh = SRH(s);

      auto hoge = Hoge(s);

      // 長さ1は特別対応
      if(L==1){
        // 登録だけしておく
        auto key = make_pair(s[0], 0);
        mp[key]++;

        // 検索は不要なのでもう戻す
        continue;
      }

      ll null_hash = -1;

      // 長さ1のやつとのマッチング
      {
        set<char> se;
        for(char c : s) se.insert(c);
        for(char c : se){
          auto key = make_pair(c, 0);
          if(mp.count(key)) cnt++;
        }
      }
      
      // 探す
      if(L>1){
        FOR(i,1,L){
          // i以降をtail
          ll tail_hash = rh.get(i,L);
          
          debug("[search] tail", s.substr(i, L-i));
          
          // それ以外の左の部分について
          // 遅いVer (これでTLEのみであることを確認)
          // set<char> se;
          // FOR(j,0,i) se.insert(s[j]); // O(L)
          // for(char c : se){
          //   auto key = make_pair(c, tail_hash);
          //   if(mp.count(key)){
          //     debug("hit!", s, i, mp[key]);
          //     cnt += mp[key];               
          //   }
          // }

          // 速いVer
          // 0 to i-1までにcがあればいい
          rep(j,26){
            char c = j+'a';
            if(hoge.range_count(0, i-1, c)){
              auto key = make_pair(c, tail_hash);
              if(mp.count(key)){
                debug("hit!", s, i, mp[key]);
                cnt += mp[key];               
              }
            }
          }
        }
      }

      // 自身を登録
      ll tail_hash = rh.get(1,L);
      auto key = make_pair(s[0], tail_hash);
      //cerr << "[register] head " << s[0] << " hash " << tail_hash << endl;
      mp[key]++;
    }
    p(cnt);

    return 0;
}

Measured memory_bytes: 225804