#include <bits/stdc++.h>
using namespace std;
#define itachi ios::sync_with_stdio(0); cin.tie(0);
struct Node {
int nxt[26];
int word;
vector<int> pal;
Node() {
memset(nxt, -1, sizeof(nxt));
word = -1;
}
};
const uint64_t base = 1315423911ull; // big base
const uint64_t mod1 = 1000000007ull;
const uint64_t p = 911382323ull; // random odd base
vector<uint64_t> pw; // powers of base
struct HString {
string s;
int n;
vector<uint64_t> Hf, Hr;
void build(const string &t) {
s = t;
n = s.size();
Hf.assign(n+1, 0);
Hr.assign(n+1, 0);
for (int i = 0; i < n; ++i) {
Hf[i+1] = Hf[i] * p + (s[i] + 1);
Hr[i+1] = Hr[i] * p + (s[n-1-i] + 1);
}
}
// hash forward of s[l..r]
uint64_t getF(int l, int r) const {
return Hf[r+1] - Hf[l] * pw[r-l+1];
}
// hash backward of s[l..r]
uint64_t getR(int l, int r) const {
// map s[l..r] to reversed index
int rl = n-1-r;
int rr = n-1-l;
return Hr[rr+1] - Hr[rl] * pw[rr-rl+1];
}
inline bool isPal(int l, int r) const {
return getF(l, r) == getR(l, r);
}
};
int main(){
itachi;
int n;
cin >> n;
vector<string> a(n);
long long total = 0;
for(int i = 0; i < n; ++i){
cin >> a[i];
total += a[i].size();
}
// Precompute powers
pw.resize(total + 5);
pw[0] = 1;
for (int i = 1; i <= total; ++i)
pw[i] = pw[i-1] * p;
// Build hash objects
vector<HString> H(n);
for (int i = 0; i < n; ++i)
H[i].build(a[i]);
vector<Node> trie;
trie.reserve(total + 5);
trie.emplace_back(); // root = 0
// Insert reversed words
for (int idx = 0; idx < n; ++idx) {
const string &w = a[idx];
int L = w.size();
int node = 0;
for (int i = L - 1; i >= 0; --i) {
if (H[idx].isPal(0, i))
trie[node].pal.push_back(idx);
int c = w[i] - 'a';
if (trie[node].nxt[c] == -1) {
trie[node].nxt[c] = trie.size();
trie.emplace_back();
}
node = trie[node].nxt[c];
}
trie[node].pal.push_back(idx);
trie[node].word = idx;
}
long long ans = 0;
// Searching
for (int i = 0; i < n; ++i) {
const string &w = a[i];
int node = 0;
int L = w.size();
for (int j = 0; j < L; ++j) {
if (trie[node].word != -1 && trie[node].word != i
&& H[i].isPal(j, L-1)) {
ans++;
}
int c = w[j] - 'a';
if (trie[node].nxt[c] == -1) {
node = -1;
break;
}
node = trie[node].nxt[c];
}
if (node != -1) {
for (int idx : trie[node].pal) {
if (idx != i)
ans++;
}
}
}
cout << ans << "\n";
return 0;
}