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 in Rust (1.42.0) (judge verdict: Runtime Error)

pub trait IterScan: Sized {
    type Output;
    fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output>;
}
pub trait MarkedIterScan: Sized {
    type Output;
    fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output>;
}
#[derive(Debug)]
pub struct Scanner<'a> {
    iter: std::str::SplitAsciiWhitespace<'a>,
}
impl<'a> Scanner<'a> {
    #[inline]
    pub fn new(s: &'a str) -> Self {
        let iter = s.split_ascii_whitespace();
        Self { iter }
    }
    #[inline]
    pub fn scan<T: IterScan>(&mut self) -> <T as IterScan>::Output {
        T::scan(&mut self.iter).unwrap()
    }
    #[inline]
    pub fn mscan<T: MarkedIterScan>(&mut self, marker: T) -> <T as MarkedIterScan>::Output {
        marker.mscan(&mut self.iter).unwrap()
    }
    #[inline]
    pub fn scan_vec<T: IterScan>(&mut self, size: usize) -> Vec<<T as IterScan>::Output> {
        (0..size)
            .map(|_| T::scan(&mut self.iter).unwrap())
            .collect()
    }
    #[inline]
    pub fn scan_chars(&mut self) -> Vec<char> {
        self.iter.next().unwrap().chars().collect::<Vec<char>>()
    }
}
mod scanner_impls {
    use super::*;
    macro_rules !iter_scan_impls {($($t :ty ) *) =>{$(impl IterScan for $t {type Output =Self ;#[inline ] fn scan <'a ,I :Iterator <Item =&'a str >>(iter :&mut I ) ->Option <Self >{iter .next () ?.parse ::<$t >() .ok () } } ) *} ;}
    iter_scan_impls !(char u8 u16 u32 u64 usize i8 i16 i32 i64 isize f32 f64 u128 i128 String ) ;
    macro_rules !iter_scan_tuple_impl {($($T :ident ) *) =>{impl <$($T :IterScan ) ,*>IterScan for ($($T ,) *) {type Output =($(<$T as IterScan >::Output ,) *) ;#[inline ] fn scan <'a ,It :Iterator <Item =&'a str >>(_iter :&mut It ) ->Option <Self ::Output >{Some (($($T ::scan (_iter ) ?,) *) ) } } } ;}
    iter_scan_tuple_impl!();
    iter_scan_tuple_impl!(A);
    iter_scan_tuple_impl !(A B ) ;
    iter_scan_tuple_impl !(A B C ) ;
    iter_scan_tuple_impl !(A B C D ) ;
    iter_scan_tuple_impl !(A B C D E ) ;
    iter_scan_tuple_impl !(A B C D E F ) ;
    iter_scan_tuple_impl !(A B C D E F G ) ;
    iter_scan_tuple_impl !(A B C D E F G H ) ;
    iter_scan_tuple_impl !(A B C D E F G H I ) ;
    iter_scan_tuple_impl !(A B C D E F G H I J ) ;
    iter_scan_tuple_impl !(A B C D E F G H I J K ) ;
    pub struct ScannerIter<'a, 'b, T> {
        inner: &'b mut Scanner<'a>,
        _marker: std::marker::PhantomData<fn() -> T>,
    }
    impl<'a, 'b, T: IterScan> Iterator for ScannerIter<'a, 'b, T> {
        type Item = <T as IterScan>::Output;
        fn next(&mut self) -> Option<Self::Item> {
            T::scan(&mut self.inner.iter)
        }
    }
    impl<'a> Scanner<'a> {
        #[inline]
        pub fn iter<'b, T: IterScan>(&'b mut self) -> ScannerIter<'a, 'b, T> {
            ScannerIter {
                inner: self,
                _marker: std::marker::PhantomData,
            }
        }
    }
}
mod marker {
    use super::*;
    pub struct Usize1;
    impl IterScan for Usize1 {
        type Output = usize;
        #[inline]
        fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
            usize::scan(iter).map(|x| x.wrapping_sub(1))
        }
    }
    pub struct Isize1;
    impl IterScan for Isize1 {
        type Output = isize;
        #[inline]
        fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
            isize::scan(iter).map(|x| x.wrapping_sub(1))
        }
    }
}
#[macro_export]
macro_rules !min {($e :expr ) =>{$e } ;($e :expr ,$($es :expr ) ,+) =>{std ::cmp ::min ($e ,min !($($es ) ,+) ) } ;}
#[macro_export]
macro_rules !chmin {($dst :expr ,$($src :expr ) ,+) =>{{let x =std ::cmp ::min ($dst ,min !($($src ) ,+) ) ;$dst =x ;} } ;}
#[macro_export]
macro_rules !max {($e :expr ) =>{$e } ;($e :expr ,$($es :expr ) ,+) =>{std ::cmp ::max ($e ,max !($($es ) ,+) ) } ;}
#[macro_export]
macro_rules !chmax {($dst :expr ,$($src :expr ) ,+) =>{{let x =std ::cmp ::max ($dst ,max !($($src ) ,+) ) ;$dst =x ;} } ;}
#[derive(Clone, Debug)]
pub struct Xorshift {
    y: u64,
}
impl Xorshift {
    pub fn new(seed: u64) -> Self {
        Xorshift { y: seed }
    }
    pub fn time() -> Self {
        let seed = std::time::SystemTime::now()
            .duration_since(std::time::UNIX_EPOCH)
            .ok()
            .unwrap_or_default()
            .as_secs() as u64;
        Xorshift::new(seed)
    }
    #[inline]
    pub fn next(&mut self) -> u64 {
        self.y ^= self.y << 5;
        self.y ^= self.y >> 17;
        self.y ^= self.y << 11;
        self.y
    }
    #[inline]
    pub fn rand(&mut self, k: u64) -> u64 {
        self.next() % k
    }
    #[inline]
    pub fn rands(&mut self, k: u64, n: usize) -> Vec<u64> {
        (0..n).map(|_| self.rand(k)).collect::<Vec<_>>()
    }
    #[inline]
    pub fn randf(&mut self) -> f64 {
        const UPPER_MASK: u64 = 0x3FF0000000000000;
        const LOWER_MASK: u64 = 0xFFFFFFFFFFFFF;
        let tmp = UPPER_MASK | (self.next() & LOWER_MASK);
        let result: f64 = unsafe { std::mem::transmute(tmp) };
        result - 1.0
    }
    #[inline]
    pub fn gen_bool(&mut self, p: f64) -> bool {
        self.randf() < p
    }
}
impl Default for Xorshift {
    fn default() -> Self {
        Xorshift::new(0x2b992ddfa23249d6)
    }
}
#[derive(Clone, Debug)]
pub struct RollingHash {
    base: u64,
    hash: Vec<u64>,
    pow: Vec<u64>,
}
impl RollingHash {
    const MASK30: u64 = (1 << 30) - 1;
    const MASK31: u64 = (1 << 31) - 1;
    const MASK61: u64 = (1 << 61) - 1;
    pub const MOD: u64 = Self::MASK61;
    #[inline]
    pub fn mersenne_mod(a: u64) -> u64 {
        let mut res = (a >> 61) + (a & Self::MASK61);
        if res >= Self::MASK61 {
            res -= Self::MASK61;
        }
        res
    }
    #[inline]
    pub fn mersenne_mul(a: u64, b: u64) -> u64 {
        let au = a >> 31;
        let ad = a & Self::MASK31;
        let bu = b >> 31;
        let bd = b & Self::MASK31;
        let mid = ad * bu + au * bd;
        let midu = mid >> 30;
        let midd = mid & Self::MASK30;
        au * bu * 2 + midu + (midd << 31) + ad * bd
    }
    #[inline]
    pub fn mersenne_mul_mod(a: u64, b: u64) -> u64 {
        Self::mersenne_mod(Self::mersenne_mul(a, b))
    }
    pub fn new(v: &Vec<u64>, base: u64) -> Self {
        let n = v.len();
        let mut hash = vec![0; n + 1];
        let mut pow = vec![1; n + 1];
        for i in 0..n {
            hash[i + 1] = Self::mersenne_mod(Self::mersenne_mul(hash[i], base) + v[i]);
            pow[i + 1] = Self::mersenne_mul_mod(pow[i], base);
        }
        Self { base, hash, pow }
    }
    pub fn hash_once(&self, v: &Vec<u64>) -> u64 {
        let n = v.len();
        let mut hash = 0;
        let mut pow = 1;
        for i in 0..n {
            hash = Self::mersenne_mod(Self::mersenne_mul(hash, self.base) + v[i]);
            pow = Self::mersenne_mul_mod(pow, self.base);
        }
        hash
    }
    /// S [l, r)
    pub fn find(&self, l: usize, r: usize) -> u64 {
        Self::mersenne_mod(
            self.hash[r] + Self::MOD - Self::mersenne_mul_mod(self.hash[l], self.pow[r - l]),
        )
    }
    pub fn concat(&self, h1: u64, h2: u64, l2: usize) -> u64 {
        Self::mersenne_mod(Self::mersenne_mul(h1, self.pow[l2]) + h2)
    }
}
#[derive(Clone, Debug)]
pub struct MultipleRollingHash {
    rh: Vec<RollingHash>,
}
impl MultipleRollingHash {
    pub fn new(v: &Vec<u64>, bases: &Vec<u64>) -> Self {
        let rh = bases
            .iter()
            .map(|&base| RollingHash::new(v, base))
            .collect::<Vec<_>>();
        Self { rh }
    }
    pub fn new_rand(v: &Vec<u64>, n: usize) -> Self {
        let mut rand = Xorshift::time();
        let bases = rand
            .rands(RollingHash::MASK61 - 2, n)
            .into_iter()
            .map(|base| base + 2)
            .collect::<Vec<_>>();
        Self::new(v, &bases)
    }
    pub fn find(&self, l: usize, r: usize) -> Vec<u64> {
        self.rh.iter().map(|h| h.find(l, r)).collect::<Vec<_>>()
    }
    pub fn concat(&self, h1: &Vec<u64>, h2: &Vec<u64>, l2: usize) -> Vec<u64> {
        self.rh
            .iter()
            .zip(h1.iter().zip(h2.iter()))
            .map(|(h, (&hi1, &hi2))| h.concat(hi1, hi2, l2))
            .collect::<Vec<_>>()
    }
}
/// binary search helper
pub trait Bisect: Copy {
    /// return between two elements
    fn halve(self, other: Self) -> Self;
    /// the end condition of binary search
    fn section_end(self, other: Self) -> bool;
}
mod bisect_impl {
    use super::*;
    macro_rules !impl_bisect_unsigned {($($t :ty ) *) =>{$(impl Bisect for $t {fn halve (self ,other :Self ) ->Self {if self >other {other +(self -other ) /2 } else {self +(other -self ) /2 } } fn section_end (self ,other :Self ) ->bool {(if self >other {self -other } else {other -self } ) <=1 } } ) *} ;}
    macro_rules !impl_bisect_signed {($($t :ty ) *) =>{$(impl Bisect for $t {fn halve (self ,other :Self ) ->Self {(self +other ) /2 } fn section_end (self ,other :Self ) ->bool {(self -other ) .abs () <=1 } } ) *} ;}
    macro_rules !impl_bisect_float {($($t :ty ) *) =>{$(impl Bisect for $t {fn halve (self ,other :Self ) ->Self {(self +other ) /2. } fn section_end (self ,other :Self ) ->bool {(self -other ) .abs () <=1e-8 } } ) *} ;}
    impl_bisect_unsigned !(u8 u16 u32 u64 usize ) ;
    impl_bisect_signed !(i8 i16 i32 i64 isize ) ;
    impl_bisect_float !(f32 f64 ) ;
}
pub fn binary_search<T: Bisect, F: Fn(T) -> bool>(f: F, ok: T, err: T) -> T {
    let mut ok = ok;
    let mut err = err;
    while !ok.section_end(err) {
        let m = ok.halve(err);
        if f(m) {
            ok = m;
        } else {
            err = m;
        }
    }
    ok
}
pub fn lower_bound<T: Bisect + Ord>(v: &[T], x: T) -> usize {
    binary_search(|i| v[i as usize] >= x, v.len() as i64, -1) as usize
}
pub fn upper_bound<T: Bisect + Ord>(v: &[T], x: T) -> usize {
    binary_search(|i| v[i as usize] > x, v.len() as i64, -1) as usize
}
fn main() {
    #[allow(unused_imports)]
    use std::io::{Read as _, Write as _};
    let __out = std::io::stdout();
    let mut __in_buf = String::new();
    std::io::stdin().read_to_string(&mut __in_buf).unwrap();
    let mut __scanner = Scanner::new(&__in_buf);
    #[allow(unused_macros)]
    macro_rules !scan {() =>{scan !(usize ) } ;(($($t :tt ) ,*) ) =>{($(scan !($t ) ) ,*) } ;([$t :tt ;$len :expr ] ) =>{(0 ..$len ) .map (|_ |scan !($t ) ) .collect ::<Vec <_ >>() } ;({$t :tt =>$f :expr } ) =>{$f (scan !($t ) ) } ;(chars ) =>{__scanner .scan_chars () } ;($t :ty ) =>{__scanner .scan ::<$t >() } ;}
    let mut __out = std::io::BufWriter::new(__out.lock());
    #[allow(unused_macros)]
    macro_rules !print {($($arg :tt ) *) =>(::std ::write !(__out ,$($arg ) *) .unwrap () ) }
    #[allow(unused_macros)]
    macro_rules !println {($($arg :tt ) *) =>(::std ::writeln !(__out ,$($arg ) *) .unwrap () ) }
    #[allow(unused_macros)]
    macro_rules! echo {
        ($iter :expr ) => {
            echo!($iter, "\n")
        };
        ($iter :expr ,$sep :expr ) => {
            let mut iter = $iter;
            if let Some(item) = iter.next() {
                print!("{}", item);
            }
            for item in iter {
                print!("{}{}", $sep, item);
            }
            println!();
        };
    }
    let n = scan!();
    let s = scan!([chars; n]);
    let mut ones = vec![0; 26];
    let mut s = s
        .into_iter()
        .filter_map(|mut s| {
            if s.len() > 1 {
                s.reverse();
                Some(s)
            } else {
                let b = ch2usize(s[0]);
                ones[b] += 1;
                None
            }
        })
        .collect::<Vec<_>>();
    let n = s.len();
    s.sort();
    let ss = s
        .iter()
        .map(|s| s.iter().map(|&c| ch2usize(c) as u64).collect::<Vec<_>>())
        .flatten()
        .collect::<Vec<_>>();
    let mut lrc = vec![0; n + 1];
    for i in 0..n {
        lrc[i + 1] = lrc[i] + s[i].len();
    }
    let v: Vec<_> = s
        .iter()
        .map(|s| {
            let mut v = s
                .iter()
                .rev()
                .scan(0u32, |acc, &c| {
                    *acc |= 1 << ch2usize(c);
                    Some(*acc)
                })
                .collect::<Vec<_>>();
            v.reverse();
            v
        })
        .collect();
    let h = MultipleRollingHash::new_rand(&ss, 3);
    let mut cnt = v
        .iter()
        .map(|v| {
            v.iter()
                .map(|x| {
                    (0..26)
                        .map(|i| (x & 1 << i != 0) as u32)
                        .collect::<Vec<_>>()
                })
                .collect::<Vec<_>>()
        })
        .collect::<Vec<_>>();
    let mut ans = 0;
    if n > 0 {
        for i in 0..n - 1 {
            for j in 0..cnt[i].len().min(cnt[i + 1].len()) {
                for k in 0..26 {
                    cnt[i + 1][j][k] += cnt[i][j][k];
                }
            }
        }
        for i in 0..n - 1 {
            let m = s[i].len();
            let b = ch2usize(s[i][m - 1]);
            let j = binary_search(
                |j| {
                    m <= s[j].len()
                        && h.find(lrc[i], lrc[i] + m - 1) == h.find(lrc[j], lrc[j] + m - 1)
                },
                i,
                n,
            );
            if i < j {
                ans += cnt[j][m - 1][b] - cnt[i][m - 1][b];
            }
        }
    }
    for i in 0..26 {
        if ones[i] == 1 {
            ans += cnt[n - 1][0][i];
        }
    }
    println!("{}", ans);
}
fn ch2usize(c: char) -> usize {
    (c as u8 - 'a' as u8) as usize
}