Problem:
 Score : 700 points    Problem Statement Limak can repeatedly remove one of the first two characters of a string,
    for example abcxyx \rightarrow acxyx \rightarrow cxyx \rightarrow cyx .  You are given N different strings S_1, S_2, \ldots, S_N .
Among N \cdot (N-1) / 2 pairs (S_i, S_j) ,
    in how many pairs could Limak obtain one string from the other?      Constraints  2 \leq N \leq 200\,000  S_i consists of lowercase English letters a - z .  S_i \neq S_j  1 \leq |S_i|  |S_1| + |S_2| + \ldots + |S_N| \leq 10^6         Input Input is given from Standard Input in the following format.  N  S_1  S_2  \vdots  S_N       Output Print the number of unordered pairs (S_i, S_j) where i \neq j and Limak can obtain one string from the other.        Sample Input 1 3
abcxyx
cyx
abc      Sample Output 1 1  The only good pair is (abcxyx, cyx) .       Sample Input 2 6
b
a
abc
c
d
ab      Sample Output 2 5  There are five good pairs: (b, abc) , (a, abc) , (abc, c) , (b, ab) , (a, ab) .

Solution (Python):
import sys
sys.setrecursionlimit(10**8)
from collections import defaultdict,Counter
def saiki(cnts):
  hitomozi = []
  d = defaultdict(lambda: [])
  heads = defaultdict(lambda: 0)
  for s,c in cnts:
    if len(s)==1:
      hitomozi.append(s[0])
    else:
      for k,v in c.items():
        if v>0:
          heads[k] += 1
      t = s[-1]
      c[t] -= 1
      s.pop(-1)
      d[t].append([s,c])
  for h in hitomozi:
    ans[0] += heads[h]
  for v in d.values():
    if len(v)<=1:
      continue
    if len(v)==2:
      s1,c1 = v[0]
      s2,c2 = v[1]
      l1,l2 = len(s1),len(s2)
      if l1==1:
        if l2>1 and c2[s1[0]]>0:
          ans[0] += 1
        continue
      else:
        if l2==1:
          if c1[s2[0]]>0:
            ans[0] += 1
          continue
        elif (l1>l2 and s2==s1[l1-l2:]) or (l2>l1 and s1==s2[l2-l1:]):
          ans[0] += 1
          continue
    saiki(v)
  return 

N = int(input())
S = [list(input()) for _ in range(N)]
ans = [0]
cnts = []
for s in S:
  cnts.append([s,Counter(s)])
saiki(cnts)
print(ans[0])

Solution (Python):

import sys
input = sys.stdin.readline
from collections import defaultdict

def empty_list():
    return [0] * 26

class RollingHash():
    def __init__(self, s):
        length = len(s)
        base = 1009
        
        self.mod = 67280421310721
        self.hash = [0] * (length + 2)
        self.pow = [1] * (length + 2)

        for i in range(length):
            self.hash[i+1] = (self.hash[i] + s[i]) * base % self.mod
            self.pow[i+1] = self.pow[i] * base % self.mod
        self.pow[length+1] = self.pow[length] * base % self.mod 

    def get(self, l, r):
        t = self.hash[r] - self.hash[l] * self.pow[r-l] % self.mod
        return t % self.mod

ss = []
n = int(input())
for _ in range(n):
    ss.append([ord(item) for item in input().rstrip()])
ss.sort(key=lambda x: len(x), reverse=True)

orda = ord("a")
words = defaultdict(empty_list)
ans = 0
for s in ss:
    word_len = len(s)
    s_rev = s[::-1]
    RH = RollingHash(s_rev)
    rh = RH.get(0, word_len-1)
    ans += words[rh][s_rev[-1] - orda]
    initial = [0] * 26 
    for i, ch in enumerate(s):
        initial[ch - orda] = 1
        for j, is_initial in enumerate(initial):
            if is_initial:
                rh = RH.get(0, word_len-i-1)
                words[rh][j] += 1
print(ans)

Solution (Python):
import sys
INF = 1 << 60
MOD = 10**9 + 7 
sys.setrecursionlimit(2147483647)
input = lambda:sys.stdin.readline().rstrip()

class RollingHash(object):
    _base1, _base2 = 1007, 1009
    _mod1, _mod2 = 10**9 + 9, 10**9 + 7

    def __init__(self,s):
        self._n=len(s)
        H1, H2 = [0] * (self._n + 1), [0] * (self._n + 1)
        P1, P2 = [1] * (self._n + 1), [1] * (self._n + 1)
        for i in range(self._n):
            H1[i + 1] = (H1[i] * self._base1 + ord(s[i])) % self._mod1
            H2[i + 1] = (H2[i] * self._base2 + ord(s[i])) % self._mod2
            P1[i + 1] = P1[i] * self._base1 % self._mod1
            P2[i + 1] = P2[i] * self._base2 % self._mod2
        self._H1, self._H2 = H1, H2
        self._P1, self._P2 = P1, P2

    def __len__(self):
        return self._n

    def __getitem__(self,x):
        l, r = x.start, x.stop;
        return ((self._H1[r] - self._P1[r - l] * self._H1[l] % self._mod1) % self._mod1,
                (self._H2[r] - self._P2[r - l] * self._H2[l] % self._mod2) % self._mod2)

from collections import defaultdict
def resolve():
    n = int(input())
    X = [input() for _ in range(n)]
    X.sort(key = len, reverse = 1)

    count = defaultdict(lambda:[0] * 26)
    ans = 0

    for S in X:
        k = len(S)
        rh = RollingHash(S)
        ok = [False] * 26
        ans += count[rh[1 : k]][ord(S[0]) - ord('a')]
        for i, c in enumerate(S):
            ok[ord(c) - ord('a')] = True
            for j in range(26):
                if ok[j]:
                    count[rh[i + 1 : k]][j] += 1
    print(ans)
resolve()

Solution (Python):
import sys
input = sys.stdin.readline

base = 30
mod = 10**17 + 3

N = int(input())
S = [input().rstrip()[::-1] for _ in range(N)]
S.sort(key=lambda s: -len(s))
cnt = {}
ans = 0
one = [0] * 26
for s in S:
    n = len(s)
    if n == 1:
        ans += one[ord(s[0]) - ord('a')]
        continue
    hashes = [0] * (n - 1)
    hashes[0] = ord(s[0]) - ord('a') + 1
    for i in range(1, n - 1):
        hashes[i] = (hashes[i-1] * base + ord(s[i]) - ord('a') + 1) % mod
    if hashes[-1] in cnt:
        ans += cnt[hashes[-1]][ord(s[-1]) - ord('a')]
    found = [0] * 26
    found[ord(s[-1]) - ord('a')] = 1
    for i in range(n - 2, 0, -1):
        found[ord(s[i]) - ord('a')] = 1
        if hashes[i-1] not in cnt:
            cnt[hashes[i-1]] = [0] * 26
        for c in range(26):
            cnt[hashes[i-1]][c] += found[c]
    found[ord(s[0]) - ord('a')] = 1
    for c in range(26):
        one[c] += found[c]
print(ans)

Solution (Python):
import sys
input = sys.stdin.readline

base = 1000
mod = 10**23 + 117

N = int(input())
S = [input().rstrip()[::-1] for _ in range(N)]
S.sort(key=lambda s: -len(s))
cnt = {}
ans = 0
one = [0] * 26
for s in S:
    n = len(s)
    if n == 1:
        ans += one[ord(s[0]) - ord('a')]
        continue
    hashes = [0] * (n - 1)
    hashes[0] = ord(s[0])
    for i in range(1, n - 1):
        hashes[i] = (hashes[i-1] * base + ord(s[i])) % mod
    if hashes[-1] in cnt:
        ans += cnt[hashes[-1]][ord(s[-1]) - ord('a')]
    found = [0] * 26
    found[ord(s[-1]) - ord('a')] = 1
    for i in range(n - 2, 0, -1):
        found[ord(s[i]) - ord('a')] = 1
        if hashes[i-1] not in cnt:
            cnt[hashes[i-1]] = [0] * 26
        for c in range(26):
            cnt[hashes[i-1]][c] += found[c]
    found[ord(s[0]) - ord('a')] = 1
    for c in range(26):
        one[c] += found[c]
print(ans)

Solution (Python):
import sys
input = sys.stdin.readline

base = 27
mod = (1 << 61) - 1

N = int(input())
S = [input().rstrip()[::-1] for _ in range(N)]
S.sort(key=lambda s: -len(s))
cnt = {}
ans = 0
one = [0] * 26
for s in S:
    n = len(s)
    if n == 1:
        ans += one[ord(s[0]) - ord('a')]
        continue
    hashes = [0] * (n - 1)
    hashes[0] = ord(s[0]) - ord('a') + 1
    for i in range(1, n - 1):
        hashes[i] = (hashes[i-1] * base + ord(s[i]) - ord('a') + 1) % mod
    if hashes[-1] in cnt:
        ans += cnt[hashes[-1]][ord(s[-1]) - ord('a')]
    found = [0] * 26
    found[ord(s[-1]) - ord('a')] = 1
    for i in range(n - 2, 0, -1):
        found[ord(s[i]) - ord('a')] = 1
        if hashes[i-1] not in cnt:
            cnt[hashes[i-1]] = [0] * 26
        for c in range(26):
            cnt[hashes[i-1]][c] += found[c]
    found[ord(s[0]) - ord('a')] = 1
    for c in range(26):
        one[c] += found[c]
print(ans)

Solution (Python):
import sys
input = sys.stdin.readline

base = 1999849216943526259
mod = (1 << 61) - 1

N = int(input())
S = [input().rstrip()[::-1] for _ in range(N)]
S.sort(key=lambda s: -len(s))
cnt = {}
ans = 0
one = [0] * 26
for s in S:
    n = len(s)
    if n == 1:
        ans += one[ord(s[0]) - ord('a')]
        continue
    hashes = [0] * (n - 1)
    hashes[0] = ord(s[0])
    for i in range(1, n - 1):
        hashes[i] = (hashes[i-1] * base + ord(s[i])) % mod
    if hashes[-1] in cnt:
        ans += cnt[hashes[-1]][ord(s[-1]) - ord('a')]
    found = [0] * 26
    found[ord(s[-1]) - ord('a')] = 1
    for i in range(n - 2, 0, -1):
        found[ord(s[i]) - ord('a')] = 1
        if hashes[i-1] not in cnt:
            cnt[hashes[i-1]] = [0] * 26
        for c in range(26):
            cnt[hashes[i-1]][c] += found[c]
    found[ord(s[0]) - ord('a')] = 1
    for c in range(26):
        one[c] += found[c]
print(ans)

Solution (Python):
class SparseTable():
    def __init__(self,A):
        N=len(A)
        n=N.bit_length()
        self.table=[[-1 for i in range(n)] for i in range(N)]

        for i in range(N):
            self.table[i][0]=A[i]

        for j in range(1,n):
            for i in range(0,N-2**j+1):
                f=self.table[i][j-1]
                s=self.table[i+2**(j-1)][j-1]
                self.table[i][j]=min(f,s)

    def query(self,s,t):
        b=t-s+1
        m=b.bit_length()-1
        return min(self.table[s][m],self.table[t-2**m+1][m])

class BIT():
    def __init__(self,n):
        self.BIT=[0]*(n+1)
        self.num=n

    def query(self,idx):
        res_sum = 0
        while idx > 0:
            res_sum += self.BIT[idx]
            idx -= idx&(-idx)
        return res_sum

    
    def update(self,idx,x):
        while idx <= self.num:
            self.BIT[idx] += x
            idx += idx&(-idx)
        return

alphabetlist=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
dic={i:e for e,i in enumerate(alphabetlist)}


import sys

input=sys.stdin.readline

N=int(input())
S=[input().rstrip() for i in range(N)]
for i in range(N):
    temp=[S[i][-j-1] for j in range(len(S[i]))]
    S[i]="".join(temp)
S.sort()

def Solve(S):
    exact=[0 for i in range(N)]
    for i in range(1,N):
        id=0
        limit=min(len(S[i]),len(S[i-1]))
        while limit>id and S[i][id]==S[i-1][id]:
            id+=1
        exact[i]=id

    lastappear=[[-1 for i in range(26)] for j in range(N)]
    for i in range(N):
        for j in range(len(S[i])):
            id=dic[S[i][j]]
            lastappear[i][id]=j

    Sparse=SparseTable(exact)

    def cond(s,n,val):
        if n==N or s==-1:
            return False
        check=Sparse.query(s,n)
        return check>=val

    query=[]
    bit=[BIT(N) for i in range(26)]
    res=-N
    for i in range(N):
        L,R=i+1,i+1
        if i!=N-1 and exact[i+1]>=len(S[i])-1:
            start=i+1
            end=N
            while end-start>1:
                test=(end+start)//2
                if cond(i+1,test,len(S[i])-1):
                    start=test
                else:
                    end=test
            R=start+1
        if i!=0 and exact[i]>=len(S[i])-1:
            start=-1
            end=i
            while end-start>1:
                test=(end+start)//2
                if cond(test,i,len(S[i])-1):
                    end=test
                else:
                    start=test
            L=end
        query.append((len(S[i])-1,L,R,dic[S[i][-1]]))
        for j in range(26):
            if lastappear[i][j]!=-1:
                query.append((lastappear[i][j],N+1,i+1,j))

    query.sort(reverse=True)

    for val,l,r,id in query:
        if l==N+1:
            bit[id].update(r,1)
        else:
            res+=bit[id].query(r)-bit[id].query(l-1)
    return res

ans=0
ans+=Solve(S)
print(ans)

Solution (Python):
from collections import Counter
from string import ascii_lowercase

n = int(input())
sss = [input() for _ in range(n)]
flags = {c: 1 << (ord(c) - 97) for c in ascii_lowercase}

trie_chr = [-1]
trie_children = [{}]
trie_fin = [0]
l = 1

for s in sss:
    node = 0
    for i in range(len(s) - 1, 0, -1):
        c = ord(s[i]) - 97
        if c in trie_children[node]:
            node = trie_children[node][c]
        else:
            trie_chr.append(c)
            trie_children.append({})
            trie_fin.append(0)
            trie_children[node][c] = l
            node = l
            l += 1
    trie_fin[node] |= flags[s[0]]

ans = 0

for s in sss:
    cnt = Counter(s)
    flag = 0
    for c in cnt:
        flag |= flags[c]
    node = 0
    if len(s) > 1 and trie_fin[node] > 0:
        ans += bin(trie_fin[node] & flag).count('1')

    for i in range(len(s) - 1, 1, -1):
        c = s[i]
        cnt[c] -= 1
        if cnt[c] == 0:
            flag ^= flags[c]
        k = ord(c) - 97
        node = trie_children[node][k]
        if trie_fin[node] > 0:
            ans += bin(trie_fin[node] & flag).count('1')

print(ans)

Solution (Python):
from collections import Counter
from string import ascii_lowercase

n = int(input())
sss = [input() for _ in range(n)]
flags = {c: 1 << (ord(c) - 97) for c in ascii_lowercase}

trie_chr = [-1]
trie_children = [{}]
trie_counter = [0]
trie_fin = [0]
l = 1

for s in sss:
    node = 0
    trie_counter[node] += 1
    for i in range(len(s) - 1, 0, -1):
        c = ord(s[i]) - 97
        if c in trie_children[node]:
            node = trie_children[node][c]
            trie_counter[node] += 1
        else:
            trie_chr.append(c)
            trie_children.append({})
            trie_fin.append(0)
            trie_children[node][c] = l
            trie_counter.append(1)
            node = l
            l += 1
    trie_fin[node] |= flags[s[0]]

ans = 0

for s in sss:
    cnt = Counter(s)
    flag = 0
    for c in cnt:
        flag |= flags[c]
    node = 0
    if len(s) > 1 and trie_fin[node] > 0:
        ans += bin(trie_fin[node] & flag).count('1')

    for i in range(len(s) - 1, 1, -1):
        c = s[i]
        cnt[c] -= 1
        if cnt[c] == 0:
            flag ^= flags[c]
        k = ord(c) - 97
        node = trie_children[node][k]
        if trie_counter[node] == 1:
            break
        if trie_fin[node] > 0:
            ans += bin(trie_fin[node] & flag).count('1')

print(ans)

Solution (Python):
import sys
sys.setrecursionlimit(10**7) 
import math
from copy import copy, deepcopy
from copy import deepcopy as dcp
from operator import itemgetter
from bisect import bisect_left, bisect, bisect_right

from collections import deque, defaultdict


from collections import Counter

from itertools import accumulate,combinations,permutations,product

from heapq import heapify,heappop,heappush

from functools import reduce,lru_cache

from decimal import Decimal

def input(): 
    x=sys.stdin.readline()
    return x[:-1] if x[-1]=="\n" else x
def printe(*x):print("
def printl(li): _=print(*li, sep="\n") if li else None
def argsort(s, return_sorted=False): 
    inds=sorted(range(len(s)), key=lambda k: s[k])
    if return_sorted: return inds, [s[i] for i in inds]
    return inds
def alp2num(c,cap=False): return ord(c)-97 if not cap else ord(c)-65
def num2alp(i,cap=False): return chr(i+97) if not cap else chr(i+65)
def matmat(A,B):
    K,N,M=len(B),len(A),len(B[0])
    return [[sum([(A[i][k]*B[k][j]) for k in range(K)]) for j in range(M)] for i in range(N)]
def matvec(M,v):
    N,size=len(v),len(M)
    return [sum([M[i][j]*v[j] for j in range(N)]) for i in range(size)]
def T(M):
    n,m=len(M),len(M[0])
    return [[M[j][i] for j in range(n)] for i in range(m)]
def binr(x): return bin(x)[2:]
def bitcount(x): 
    x= x - ((x >> 1) & 0x5555555555555555)
    x= (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333)
    x= (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f 
    x+= (x >> 8); x+= (x >> 16); x+= (x >> 32) 
    return x & 0x7f
import random
class rh:
    def __init__(self,base,max_n):
        self.mod=random.randrange(1<<54-1,1<<55-1,2)
        self.base=int(base*0.5+0.5)*2
        self.max_n=max_n
        self.pows1=[1]*(max_n+1)
        cur1=1
        for i in range(1,max_n+1):
            cur1=cur1*base%self.mod
            self.pows1[i]=cur1

    def convert(self,c): return alp2num(c,False)
    
    def get(self, s):
        n=len(s)
        mod=self.mod
        si=[self.convert(ss) for ss in s]
        h1=0
        for i in range(n):h1=(h1+si[i]*self.pows1[n-1-i])%mod
        return h1
    
    def get_roll(self, s, k, uroboros=False):
        
        n=len(s)
        maxitr=n-k+1
        if uroboros: maxitr=n
    
        si=[self.convert(ss) for ss in s]
        mod=self.mod
        h1=0
        for i in range(k):h1=(h1+si[i%n]*self.pows1[k-1-i])%mod
        hs=[0]*maxitr
        hs[0]=h1
        mbase1=self.pows1[k]
        base=self.base
        
        for i in range(1,maxitr): 
            front=si[i-1];back=si[(i+k-1)%n]
            h1=(h1*base-front*mbase1+back)%mod
            hs[i]=h1
        return hs

def main():
    mod = random.randrange(1<<54-1,1<<55-1,2)
    

    N = int(input())
    
    mod2=999999937

    
    
    L=["" for _ in range(N)]
    ll=[0]*N
    for i in range(N):
        s=input()
        ls=len(s)
        ll[i]=ls
        L[i]=s

    

    inds=argsort(ll)
    d=Counter()
    ans=0
    base=26

    for im in inds:
        
        s=L[im]

        ls=len(s)
        cur=0
        cur2=0
        se=Counter(s)
        
        for i in range(ls):
            for a,val in se.items():
                if val:
                    ai=alp2num(a)
                    ans+=d[(i+1,(cur*base+ai)%mod)]
                    
            si=s[-1-i]
            sin=alp2num(si)
            cur=(cur*base+sin)%mod
            

            se[si]-=1

        d[(ls,cur)]+=1

    print(ans)
            





if __name__ == "__main__":
    main()

Solution (Python):
import sys
def input():
	return sys.stdin.readline()[:-1]

BASE, MOD = 1999849216943526259, (1<<61)-1

d = dict()
ans = 0
ss = [str(input())[::-1] for _ in range(int(input()))]
zero = [0 for _ in range(26)]
ss.sort(key=lambda x: -len(x))
for s in ss:
	n = len(s)
	if n == 1:
		ans += zero[ord(s[n-1])-97]
	else:
		hashes = [0 for _ in range(n-1)]
		hashes[0] = ord(s[0])
		for i in range(1, n-1):
			hashes[i] = (hashes[i-1] * BASE + ord(s[i])) % MOD
		if hashes[n-2] in d:
			ans += d[hashes[n-2]][ord(s[n-1])-97]
		alph = [0 for _ in range(26)]
		alph[ord(s[n-1])-97] = 1
		for i in range(n-2, 0, -1):
			alph[ord(s[i])-97] = 1
			if hashes[i-1] not in d:
				d[hashes[i-1]] = [0 for _ in range(26)]
			for j, a in enumerate(alph):
				d[hashes[i-1]][j] += a
		alph[ord(s[0])-97] = 1
		for j, a in enumerate(alph):
			zero[j] += a
print(ans)

Solution (Python):
inn = lambda : int(input())
ins = lambda : input().strip()
DBG = True 

def ddprint(x):
  if DBG:
    print(x)

import sys,resource
def setrlim():
  sys.setrecursionlimit(250000)
  soft,hard = resource.getrlimit(resource.RLIMIT_STACK)
  
  resource.setrlimit(resource.RLIMIT_STACK, (128*1024*1024,hard))

def dfs(l,k):
    global ans
    
    ll = [[] for i in range(26)]
    x = [0]*26
    for z in l:
        
        c = ord(ls[z][-k-1])-orda
        if len(ls[z])==k+1:
            x[c] += 1
        else:
            ll[c].append(z)
    
    for c in range(26):
        for z in l:
            
            
            if first[z][c]>=k and len(ls[z])>k+1:
                ans += x[c]
                
                
    for c in range(26):
        if len(ll[c])>1:
            dfs(ll[c],k+1)

setrlim()
n = inn()
ls = []
first = [[-1]*26 for i in range(n)]
orda = ord('a')
for i in range(n):
    s = ins()
    ls.append(s)
    for c in range(26):
        p = s.find(chr(orda+c))
        first[i][c] = (len(s)-1-p) if p>=0 else -1


ans = 0
dfs(list(range(n)),0)
print(ans)

Solution (Python):
import sys
def input():
	return sys.stdin.buffer.readline()[:-1]

BASE, MOD = 1999849216943526259, (1<<61)-1

d = dict()
ans = 0
ss = [str(input())[2:-1][::-1] for _ in range(int(input()))]
zero = [0 for _ in range(26)]
ss.sort(key=lambda x: -len(x))
for s in ss:
	n = len(s)
	if n == 1:
		ans += zero[ord(s[n-1])-97]
	else:
		hashes = [0 for _ in range(n-1)]
		hashes[0] = ord(s[0])
		for i in range(1, n-1):
			hashes[i] = (hashes[i-1] * BASE + ord(s[i])) % MOD
		if hashes[n-2] in d:
			ans += d[hashes[n-2]][ord(s[n-1])-97]
		alph = [0 for _ in range(26)]
		alph[ord(s[n-1])-97] = 1
		for i in range(n-2, 0, -1):
			alph[ord(s[i])-97] = 1
			if hashes[i-1] not in d:
				d[hashes[i-1]] = [0 for _ in range(26)]
			for j, a in enumerate(alph):
				d[hashes[i-1]][j] += a
		alph[ord(s[0])-97] = 1
		for j, a in enumerate(alph):
			zero[j] += a
print(ans)

Solution (Python):
import sys

sys.setrecursionlimit(10**7)

N = int(input())
S = []
a = ord('a')
for _ in range(N):
  S.append([ord(c) - a for c in input()][::-1])

_end = -1  
_count = -2 
def get_count(root):
  to_visit = [root]
  while to_visit:
    current = to_visit[-1]
    if _count in current:
      to_visit.pop()
      continue
    else:
      done = True
      c = [0] * 26 + [1 if _end in current else 0]
      for k, n in current.items():
        if k in (_end, _count):
          continue
        if _count not in n:
          done = False
          break
        if k not in (_end, _count):
          cc = n[_count]
          
          for i, v in enumerate(cc):
            if i == k:
              c[k] += cc[-1]
            else:
              c[i] += v
      if done:
        current[_count] = c
        to_visit.pop()
      else:
        for k, v in current.items():
          if k not in (_end, _count):
            to_visit.append(v)
  return current[_count]
        
  
  
  if _count in root:
    return root[_count]
  else:
    c = [0] * 26 + [1 if _end in root else 0]
    for k, n in root.items():
      if k not in (_end, _count):
        cc = get_count(n)
        
        for i, v in enumerate(cc):
          if i == k:
            c[k] += cc[-1]
          else:
            c[i] += v
    root[_count] = c
    return c
    
def make_trie(words):
  root = dict()
  for word in words:
    current_dict = root
    for letter in word:
      
      current_dict = current_dict.setdefault(letter, {})
    current_dict[_end] = _end
 
  return root

def get_subtree(trie, word):
  current_dict = trie
  for letter in word:
    
    if letter not in current_dict:
      return {}
    current_dict = current_dict[letter]
  return current_dict
  
def in_trie(trie, word):
  return _end in get_subtree(trie, word)

trie = make_trie(S)





ans = 0
for s in S:
  count = get_count(get_subtree(trie, s[:-1]))
  
  ans += count[s[-1]]

print((ans - N))

Solution (Python):
class Node:
    def __init__(self):
        self.child = [None] * 26
        self.counts = [0] * 26

    
    
    
    
    
    
    
    
    
    
    
    

    def add(self, s, bucket):
        node = self
        for idx_s, c in zip(range(len(s)-1, -1, -1), s[::-1]):
            if node.child[c] is None:
                node.child[c] = Node()
            for i, cnt in enumerate(bucket):
                if cnt:
                    node.counts[i] += 1
            bucket[c] -= 1
            if idx_s > 0:
                node = node.child[c]
        Leaves.append(node.counts)

    
    
    
    
    
    

Leaves = []
trie = Node()
N = int(input())
S = [[ord(c)-97 for c in input()] for _ in range(N)]
for s in S:
    b = [0] * 26
    for c in s:
        b[c] += 1
    trie.add(s, b)
ans = -N


for s, l in zip(S, Leaves):
    ans += l[s[0]]
print(ans)

Solution (Python):
import sys;input=sys.stdin.readline
N, = map(int, input().split())
MOD=67280421310721
S = []
for _ in range(N):
    s = input().strip()
    S.append(s)
S.sort(key=lambda x:len(x))
D = dict()
dd = set()
R = 0
for s in S:
    l = len(s)
    d = [0]*26
    for c in dd:
        d[c] += 1
    tmp=0
    for i in range(l-1, -1, -1):
        ee = ord(s[i]) - 97
        tmp = 100*tmp+(ee+1)
        tmp %= MOD
        R += d[ee]
        d[ee] = 0
        if tmp in D:
            for c in D[tmp]:
                d[c] += 1
        if i == 1:
            nn = tmp
    if l != 1:
        if nn not in D:
            D[nn] = set()
        D[nn].add(ee)
    else:
        dd.add(ee)
print(R)

Solution (Python):
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**9)

def solve():
    ordA = ord('a')

    N = int(input())
    Ass = []
    for _ in range(N):
        Ss = input().rstrip()
        As = [ord(S)-ordA for S in Ss[::-1]]
        Ass.append(As)

    Ass.sort(key=lambda x: len(x))

    fsss = []
    for As in Ass:
        fss = []
        fs = [0] * 26
        for i in reversed(range(len(As))):
            fs[As[i]] = 1
            fss.append(fs[:])
        fsss.append(fss[::-1])

    ans = 0
    nodes = []
    nodes.append([-1]*26)
    nums = []
    nums.append([0]*26)
    numNode = 1
    for As, fss in zip(Ass, fsss):
        lenA = len(As)
        iNode = 0
        for j in range(lenA):
            A = As[j]
            fs = fss[j]
            for c in range(26):
                if fs[c]:
                    ans += nums[iNode][c]

            if nodes[iNode][A] == -1:
                nodes.append([-1]*26)
                nums.append([0]*26)
                nodes[iNode][A] = numNode
                numNode += 1
            else:
                pass

            if j == lenA-1:
                nums[iNode][As[-1]] += 1

            iNode = nodes[iNode][A]

    print(ans)


solve()

Solution (Python):
import sys
sys.setrecursionlimit(10**8)
from collections import defaultdict,Counter
def saiki(cnts):
  hitomozi = []
  d = defaultdict(lambda: [])
  heads = defaultdict(lambda: 0)
  for s,c in cnts:
    if len(s)==1:
      hitomozi.append(s[0])
    else:
      for k,v in c.items():
        if v>0:
          heads[k] += 1
      t = s[-1]
      c[t] -= 1
      s.pop(-1)
      d[t].append([s,c])
  for h in hitomozi:
    ans[0] += heads[h]
  for v in d.values():
    if len(v)<=1:
      continue
    saiki(v)
  return 

N = int(input())
S = [list(input()) for _ in range(N)]
ans = [0]
cnts = []
for s in S:
  cnts.append([s,Counter(s)])
saiki(cnts)
print(ans[0])

Solution (Python):
import sys


input = sys.stdin.readline
N = int(input())
S = [input().replace('\n', '')[::-1] for _ in range(N)]
S1 = []
Slong = []
for s in S:
    if len(s) == 1:
        S1.append(s)
    else:
        Slong.append(s)

ans = 0

Slong = sorted(Slong, key=lambda x: x[:-1])
for i in range(len(Slong)):
    s = Slong[i]
    j = i + 1
    n = len(s)-1
    while j<len(Slong) and Slong[j][:n] == s[:n]:
        ans += Slong[j][n:].find(s[-1]) != -1
        j += 1


S1 = sorted(S1)
for i in range(len(S1)):
    s = S1[i]
    j = i + 1
    while j<len(S1) and S1[j] == s:
        ans += 1
        j += 1



a2z = [chr(i) for i in range(97, 97+26)]
wcnt = {i: 0for i in a2z}
for s in Slong:
    for c in set(s):
        wcnt[c] += 1
for s in S1:
    ans += wcnt[s]
print(ans)

Solution (Python):
import sys
import math
import copy
import heapq
from functools import cmp_to_key
from bisect import bisect_left, bisect_right
from collections import defaultdict, deque, Counter
sys.setrecursionlimit(1000000)


input = sys.stdin.readline
getS = lambda: input().strip()
getN = lambda: int(input())
getList = lambda: list(map(int, input().split()))
getZList = lambda: [int(x) - 1 for x in input().split()]

INF = float("inf")
MOD = 10**9 + 7
divide = lambda x: pow(x, MOD-2, MOD)

def nck(n, k, kaijyo):
    return (npk(n, k, kaijyo) * divide(kaijyo[k])) % MOD

def npk(n, k, kaijyo):
    if k == 0 or k == n:
        return n % MOD
    return (kaijyo[n] * divide(kaijyo[n-k])) % MOD

def fact_and_inv(SIZE):
    inv = [0] * SIZE  
    fac = [0] * SIZE  
    finv = [0] * SIZE  
    inv[1] = 1
    fac[0] = fac[1] = 1
    finv[0] = finv[1] = 1
    for i in range(2, SIZE):
        inv[i] = MOD - (MOD // i) * inv[MOD % i] % MOD
        fac[i] = fac[i - 1] * i % MOD
        finv[i] = finv[i - 1] * inv[i] % MOD

    return fac, finv

def renritsu(A, Y):
    
    
    
    A = np.matrix(A)
    Y = np.matrix(Y)
    Y = np.reshape(Y, (-1, 1))
    X = np.linalg.solve(A, Y)

    
    return X.flatten().tolist()[0]

class TwoDimGrid:
    
    def __init__(self, h, w, wall="
        self.h = h
        self.w = w
        self.size = (h+2) * (w+2)
        self.wall = wall
        self.get_grid()
        

    def get_grid(self):
        grid = [self.wall * (self.w + 2)]
        for i in range(self.h):
            grid.append(self.wall + getS() + self.wall)

        grid.append(self.wall * (self.w + 2))
        self.grid = grid
    def init_cost(self):
        self.cost = [INF] * self.size

    def pos(self, x, y):
        
        return y * (self.w + 2) + x
    def getgrid(self, x, y):
        return self.grid[y][x]
    def get(self, x, y):
        return self.cost[self.pos(x, y)]
    def set(self, x, y, v):
        self.cost[self.pos(x, y)] = v
        return
    def show(self):
        for i in range(self.h+2):
            print(self.cost[(self.w + 2) * i:(self.w + 2) * (i+1)])
    def showsome(self, tgt):
        for t in tgt:
            print(t)
        return
    def showsomejoin(self, tgt):
        for t in tgt:
            print("".join(t))
        return

    def search(self):
        grid = self.grid
        move = [(0, 1), (0, -1), (1, 0), (-1, 0)]
        move_eight = [(0, 1), (0, -1), (1, 0), (-1, 0), (1, 1), (1, -1), (-1, 1), (-1, -1)]
        
        
        
        
        
def getc():
    a = ord("a")
    ret = dict()
    for i in range(1, 27):
        ret[chr(a - 1 + i)] = i
    
    return ret

def solve():
    MOD = 67280421310721
    
    
    
    n = getN()
    lis = []
    for i in range(n):
        S = list(getS())
        S.reverse()
        lis.append(S)


    lis.sort(key=lambda x: len(x))
    
    
    ans = 0
    single = dict()
    hash = dict()
    cd = getc()
    for s in lis:
        if len(s) == 1:
            single[s[0]] = 1
            continue
        base = 27
        tmp = 0
        hakken = defaultdict(int)
        singlec = copy.deepcopy(single)
        for c in s[:-1]:
            if c in hakken:
                ans += hakken[c]
                del hakken[c]
            if c in singlec:
                ans += singlec[c]
                del singlec[c]

            tmp = tmp + (base * cd[c]) % MOD
            
            base = (base * 27) % MOD
            
            if tmp in hash:
                for tgt in hash[tmp]:
                    hakken[tgt] += 1


        if s[-1] in hakken:
            ans += hakken[s[-1]]
        if s[-1] in singlec:
            ans +=singlec[s[-1]]

        if tmp in hash:
            hash[tmp].append(s[-1])
        else:
            hash[tmp] = [s[-1]]
        

    print(ans)







def main():
    n = getN()
    for _ in range(n):
        solve()

    return
if __name__ == "__main__":
    
    solve()