#include <bits/stdc++.h>
using namespace std;
#define int ll
#define ll long long
#define I32_MAX 2147483647
#define I64_MAX 9223372036854775807LL
#define I64_MAX2 1223372036854775807LL
#define INF I64_MAX2
#define MOD 1000000007
// #define MOD 998244353
#define MEM_SIZE 101010
#define DEBUG_OUT true
#define ALL(x) (x).begin(), (x).end()

template <typename T>
void DEBUG(T e)
{
  if (DEBUG_OUT == false)
    return;
  std::cout << e << " ";
}
template <typename T>
void DEBUG(const std::vector<T> &v)
{
  if (DEBUG_OUT == false)
    return;
  for (const auto &e : v)
  {
    std::cout << e << " ";
  }
  std::cout << std::endl;
}
template <typename T>
void DEBUG(const std::vector<std::vector<T>> &vv)
{
  if (DEBUG_OUT == false)
    return;
  for (const auto &v : vv)
  {
    DEBUG(v);
  }
}
template <class T, class... Ts>
void DEBUG(T d, Ts... e)
{
  if (DEBUG_OUT == false)
    return;
  DEBUG(d);
  DEBUG(e...);
}
template <class T>
void corner(bool flg, T hoge)
{
  if (flg)
  {
    cout << hoge << endl;
    abort();
  }
}
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); }

//BELOW
template <int K, class T>
struct Trie
{
  struct Node
  {
    int c;
    std::array<int, K> nxt;
    std::array<int, K> cnt; // 文字cを含むような子孫の数
    int sz;                 // 部分木のサイズ

    explicit Node(int c) : c(c), sz(0)
    {
      nxt.fill(-1);
      cnt.fill(0);
    }
  };

  std::vector<Node> nodes;
  std::function<int(T)> enc;

  explicit Trie(T base)
  {
    nodes.emplace_back(-1);
    enc = [=](T c) { return c - base; };
  }

  explicit Trie(const std::function<int(T)> &enc) : enc(enc)
  {
    nodes.emplace_back(-1);
  }

  template <class Container>
  void add(const Container &s)
  {
    int pos = 0;
    for (T c : s)
    {
      int ci = enc(c);

      int npos = nodes[pos].nxt[ci];
      if (npos == -1)
      {
        npos = nodes.size();
        nodes[pos].nxt[ci] = npos;
        nodes.emplace_back(ci);
      }
      pos = npos;
    }

    ++nodes[pos].sz;
  }

  template <class Container>
  int find(const Container &s) const
  {
    int pos = 0;
    for (char c : s)
    {
      int ci = enc(c);
      pos = nodes[pos].nxt[ci];
      if (pos == -1)
        return -1;
    }
    return pos;
  }

  // cntを埋める
  void fillcnt()
  {
    for (int pos = (int)nodes.size() - 1; pos >= 0; --pos)
    {
      auto &node = nodes[pos];

      for (int c = 0; c < 26; ++c)
      {
        int npos = node.nxt[c];
        if (npos == -1)
          continue;

        const auto &cnode = nodes[npos];
        node.sz += cnode.sz;
        for (int d = 0; d < 26; ++d)
        {
          node.cnt[d] += cnode.cnt[d];
        }
      }

      // 全ての子孫はcを含む
      if (node.c != -1)
        node.cnt[node.c] = node.sz;
    }
  }
};

//BELOW
void solve(void)
{
  int n;
  cin >> n;
  vector<string> vs(n);
  for (int i = 0; i < n; i++)
  {
    cin >> vs[i];
    reverse(ALL(vs[i]));
  }
  Trie<26, char> trie('a');
  for (auto &&s : vs)
  {
    trie.add(s);
  }
  trie.fillcnt();
  int res = 0;
  for (auto &&s : vs)
  {
    int last = s.back() - 'a';
    s.pop_back();
    int pos = trie.find(s);
    for (int ci = 0; ci < 26; ci++)
    {
      int npos = trie.nodes[pos].nxt[ci];
      if (npos == -1)
        continue;
      res += trie.nodes[npos].cnt[last];
      if (ci == last)
        res--;
    }
  }
  cout << res << endl;

  return;
}

int32_t main(int32_t argc, const char *argv[])
{
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);

  std::cout << std::fixed;
  std::cout << std::setprecision(11);
  solve();

  return 0;
}


Measured memory_bytes: 448948