#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define mp make_pair
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef complex<double> point;
typedef double DOUBLE;
#define xx real()
#define yy imag()

#define REP(i, a, b) for(int i = (a); i < (int)(b); i++)
#define REPN(i, a, b) for(int i = (a); i <= (int)(b); i++)
#define FA(it, x) for(__typeof((x).begin()) it = (x).begin(); it != (x).end(); it++)
#define SZ(x) (int)(x).size()
#define BE(x) (x).begin(), (x).end()
#define SORT(x) sort(BE(x))
#define _1 first
#define _2 second

#define x1 gray_cat_x1
#define y1 gray_cat_y1
#define j0 gray_cat_j0

template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

#define file "I1"

const double EPS = 1e-9;
const double PI = acos(-1.);
const ll LL_INF = 1e17 + 16;
const int INF = 1e9 + 10;
const ll MOD = 1e9 + 7;

// Trie and Aho - Corasick algorithm.
// Uses O(nk) memory and time for building 
// (n - total length of strings, k - alphabet size).

// Use: call tr.init()
// Call tr.add_string for every string
// Call tr.bfs()

// After it you can go by suffix link, nxt[i] and to[i] for each node.

// Strings total length
const int MAXTOTALLEN = 1e6 + 5;

// Alphabet size
const int MAXSZ = 26;

// Struct for node
struct node {
	// Links by letters (only in initial strings)
	int nxt[MAXSZ];
	
	int cnt[MAXSZ];
	
	// Parent
	int prv;
	
	// If is end of any string
	bool is_leaf;
	
	// Parent letter
	int prv_ch;
	
	// Count of strings ending in the node
	int leafs_cnt;
	
	// Clear all values
	void clear(){
		for(int i = 0; i < MAXSZ; i++){
			nxt[i] = -1;
			cnt[i] = 0;
		}
		prv = -1;
		is_leaf = false;
		prv_ch = -1;
		leafs_cnt = 0;
	}
};

// Struct for trie
struct trie {
	// Nodes
	node tt[MAXTOTALLEN];
	
	// Count of nodes
	int n;
	
	// Used for bfs
	int used[MAXTOTALLEN];
	
	// Queue for bts
	queue<int> qq;
	
	// Init
	void init(){
		// Init root
		tt[0].clear();
		n = 1;
	}
	
	char used_sym[MAXSZ];
	
	// Add string
	// Call only after Init()!!
	void add_string(char *s){
		int cur_ind = 0;
		// Add letter by letter
		for(int i = 0; s[i]; i++){
			int let = s[i] - 'a';
			// Create new node if necessary
			if (tt[cur_ind].nxt[let] == -1){
				tt[n].clear();
				tt[n].prv = cur_ind;
				tt[n].prv_ch = let;
				tt[cur_ind].nxt[let] = n++;
			}
			cur_ind = tt[cur_ind].nxt[let];
		}
		// Set is_leaf flag
		tt[cur_ind].is_leaf = true;
		tt[cur_ind].leafs_cnt++;
		// Count letters in suffix
		REP(i, 0, MAXSZ) {
			used_sym[i] = 0;
		}
		for(int i = cur_ind; ; i = tt[i].prv) {
			REP(j, 0, MAXSZ) {
				tt[i].cnt[j] += used_sym[j];
			}
			if (i == 0) {
				break;
			}
			used_sym[tt[i].prv_ch] = 1;
		}
	}
	
	ll ans;
	void calc_ans() {
		ans = 0;
		REP(i, 0, n) {
			if (tt[i].is_leaf) {
				ll all = tt[tt[i].prv].cnt[tt[i].prv_ch];
				ll cur = tt[i].leafs_cnt;
				ans += cur * (all - cur) + cur * (cur - 1) / 2;
			}
		}
	}
};

trie tr;

char s[MAXTOTALLEN];

void solve(){
	tr.init();
	int n;
	scanf("%d", &n);
	REP(i, 0, n) {
		scanf("%s", &s[0]);
		int l = strlen(s);
		reverse(s, s + l);
		tr.add_string(s);
	}
	tr.calc_ans();
	cout << tr.ans << endl;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif
    //freopen(file".in", "r", stdin); freopen(file".out", "w", stdout);
    int t = 1;
    //cin >> t;
    while(t--){
        solve();    
    }
}


Measured memory_bytes: 222108