#include <bits/stdc++.h>
using namespace std;
const int Maxn = 425100;
const int zimu = 26;
char cc[Maxn * 5];
int n, lene, qwer;
long long ans;
int poi[Maxn];
inline int read() {
  int fl = 1, rt = 0;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') fl = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    rt = rt * 10 + ch - '0';
    ch = getchar();
  }
  return fl * rt;
}
struct NOd {
  bool a[27];
} zifu[Maxn];
multiset<int> zybnb;
map<int, int> rqynb;
int main() {
  n = read();
  for (int i = 1; i <= n; ++i) {
    scanf("%s", cc + 1);
    lene = strlen(cc + 1);
    for (register int j = 1; j <= lene; ++j) zifu[i].a[cc[j] - 'a' + 1] ^= 1;
    qwer = 0;
    for (int j = 1; j <= zimu; ++j)
      if (zifu[i].a[j]) qwer += 1 << (zimu - j);
    zybnb.insert(qwer);
    poi[i] = qwer;
  }
  for (int i = 1; i <= n; ++i) {
    if (rqynb.count(poi[i]) >= 1) {
      ans += rqynb[poi[i]];
      continue;
    }
    qwer = 0;
    qwer += zybnb.count(poi[i]) - 1;
    poi[i] ^= 1 << (zimu - 1);
    qwer += zybnb.count(poi[i]);
    for (register int j = 2; j <= zimu; ++j) {
      poi[i] ^= (3 << (zimu - j));
      qwer += zybnb.count(poi[i]);
    }
    ans += qwer;
    rqynb[poi[i] ^ 1] = qwer;
  }
  ans /= 2;
  printf("%I64d", ans);
  return 0;
}
