#include <bits/stdc++.h>   using namespace std;   struct edge {     long long to, cost;     edge() {}     edge(long long a, long long b) { to = a, cost = b; }   };   const long long dx[] = {1, 0, -1, 0}, dy[] = {0, -1, 0, 1};   const long long mod = 1000000007;   struct mint {     long long x = 0;     mint(long long y = 0) {       x = y;       if (x < 0 || x >= mod) x = (x % mod + mod) % mod;     }     mint(const mint& ope) { x = ope.x; }     mint operator-() { return mint(-x); }     mint operator+(const mint& ope) { return mint(x) += ope; }     mint operator-(const mint& ope) { return mint(x) -= ope; }     mint operator*(const mint& ope) { return mint(x) *= ope; }     mint operator/(const mint& ope) { return mint(x) /= ope; }     mint& operator+=(const mint& ope) {       x += ope.x;       if (x >= mod) x -= mod;       return *this;     }     mint& operator-=(const mint& ope) {       x += mod - ope.x;       if (x >= mod) x -= mod;       return *this;     }     mint& operator*=(const mint& ope) {       x *= ope.x, x %= mod;       return *this;     }     mint& operator/=(const mint& ope) {       long long n = mod - 2;       mint mul = ope;       while (n) {         if (n & 1) *this *= mul;         mul *= mul;         n >>= 1;       }       return *this;     }     mint inverse() { return mint(1) / *this; }     bool operator==(const mint& ope) { return x == ope.x; }     bool operator!=(const mint& ope) { return x != ope.x; }   };   mint modpow(mint a, long long n) {     if (n == 0) return mint(1);     if (n % 2)       return a * modpow(a, n - 1);     else       return modpow(a * a, n / 2);   }   istream& operator>>(istream& is, mint& ope) {     long long t;     is >> t, ope.x = t;     return is;   }   ostream& operator<<(ostream& os, mint& ope) { return os << ope.x; }   ostream& operator<<(ostream& os, const mint& ope) { return os << ope.x; }   bool exceed(long long x, long long y, long long m) { return x >= m / y + 1; }   void mark() { cout <<  *  << endl; }   void yes() { cout <<  YES  << endl; }   void no() { cout <<  NO  << endl; }   long long gcd(long long a, long long b) {     if (b == 0) return a;     return gcd(b, a % b);   }   long long digitnum(long long x, long long b = 10) {     long long ret = 0;     for (; x; x /= b) ret++;     return ret;   }   long long digitsum(long long x, long long b = 10) {     long long ret = 0;     for (; x; x /= b) ret += x % b;     return ret;   }   string lltos(long long x) {     string ret;     for (; x; x /= 10) ret += x % 10 +  0 ;     reverse(ret.begin(), ret.end());     return ret;   }   long long stoll(string& s) {     long long ret = 0;     for (auto c : s) ret *= 10, ret += c -  0 ;     return ret;   }   template <typename T>   void uniq(T& vec) {     sort(vec.begin(), vec.end());     vec.erase(unique(vec.begin(), vec.end()), vec.end());   }   template <typename T>   ostream& operator<<(ostream& os, vector<T>& vec) {     for (int i = 0; i < vec.size(); i++)       os << vec[i] << (i + 1 == vec.size() ?    :    );     return os;   }   template <typename T>   ostream& operator<<(ostream& os, deque<T>& deq) {     for (int i = 0; i < deq.size(); i++)       os << deq[i] << (i + 1 == deq.size() ?    :    );     return os;   }   template <typename T, typename U>   ostream& operator<<(ostream& os, pair<T, U>& pair_var) {     os <<  (  << pair_var.first <<  ,   << pair_var.second <<  ) ;     return os;   }   template <typename T, typename U>   ostream& operator<<(ostream& os, const pair<T, U>& pair_var) {     os <<  (  << pair_var.first <<  ,   << pair_var.second <<  ) ;     return os;   }   template <typename T, typename U>   ostream& operator<<(ostream& os, map<T, U>& map_var) {     for (typename map<T, U>::iterator itr = map_var.begin(); itr != map_var.end();          itr++) {       os <<  (  << itr->first <<  ,   << itr->second <<  ) ;       itr++;       if (itr != map_var.end()) os <<  , ;       itr--;     }     return os;   }   template <typename T>   ostream& operator<<(ostream& os, set<T>& set_var) {     for (typename set<T>::iterator itr = set_var.begin(); itr != set_var.end();          itr++) {       os << *itr;       ++itr;       if (itr != set_var.end()) os <<    ;       itr--;     }     return os;   }   template <typename T>   ostream& operator<<(ostream& os, multiset<T>& set_var) {     for (typename multiset<T>::iterator itr = set_var.begin();          itr != set_var.end(); itr++) {       os << *itr;       ++itr;       if (itr != set_var.end()) os <<    ;       itr--;     }     return os;   }   template <typename T>   void outa(T a[], long long s, long long t) {     for (long long i = s; i <= t; i++) {       cout << a[i];       if (i < t) cout <<    ;     }     cout << endl;   }   void dump_func() { cout << endl; }   template <class Head, class... Tail>   void dump_func(Head&& head, Tail&&... tail) {     cout << head;     if (sizeof...(Tail) > 0) cout <<    ;     dump_func(std::move(tail)...);   }   void z_algorithm(string& s, int z[]) {     z[0] = s.size();     int x = 0, y = 0;     for (int i = 1; i < s.size(); i++) {       if (i > y) {         z[i] = 0;         for (int j = 0; j < s.size(); j++) {           if (i + j >= s.size() || s[i + j] != s[j]) break;           z[i]++;         }         x = i, y = i + z[i] - 1;       } else if (i + z[i - x] <= y)         z[i] = z[i - x];       else {         z[i] = y - i + 1;         for (int j = y - i + 1; j < s.size(); j++) {           if (i + j >= s.size() || s[i + j] != s[j]) break;           z[i]++;         }         x = i, y = i + z[i] - 1;       }     }   }   struct SCC {     int n;     vector<vector<int> > G, revG, compG;     vector<int> used, scc, topo;     int sccid, sccnum;     void tpdfs(int v) {       used[v] = 1;       for (int i = 0; i < G[v].size(); i++) {         if (!used[G[v][i]]) tpdfs(G[v][i]);       }       topo.push_back(v);     }     void sccdfs(int v, int id) {       used[v] = 1;       scc[v] = id;       for (int i = 0; i < revG[v].size(); i++) {         if (!used[revG[v][i]]) sccdfs(revG[v][i], id);       }     }     SCC() {}     SCC(int n) {       this->n = n;       G.resize(n + 1);       revG.resize(n + 1);       used.resize(n + 1);     }     void init() {       for (int i = 1; i <= n; i++) {         G[i].clear(), revG[i].clear();         used[i] = 0;       }       topo.clear();     }     void add_edge(int u, int v) { G[u].push_back(v); }     void tpsort() {       topo.clear();       for (int i = 1; i <= n; i++) used[i] = 0;       for (int i = 1; i <= n; i++)         if (!used[i]) tpdfs(i);       reverse(topo.begin(), topo.end());     }     bool checkDAG() {       for (int i = 1; i <= n; i++) used[i] = 0;       for (int i = 0; i < topo.size(); i++) {         int v = topo[i];         used[v] = 1;         for (int j = 0; j < G[v].size(); j++) {           if (used[G[v][j]]) return false;         }       }       return true;     }     int calcSCC() {       scc.resize(n + 1);       for (int i = 1; i <= n; i++) revG[i].clear();       for (int i = 1; i <= n; i++) {         for (int j = 0; j < G[i].size(); j++) {           revG[G[i][j]].push_back(i);         }       }       sccid = 1;       for (int i = 1; i <= n; i++) used[i] = 0;       for (int i = 0; i < topo.size(); i++)         if (!used[topo[i]]) sccdfs(topo[i], sccid++);       return sccnum = sccid - 1;     }     void compressSCC(bool simple = false) {       compG.resize(sccnum + 1);       for (int i = 1; i <= n; i++) {         for (int j = 0; j < G[i].size(); j++) {           int u = G[i][j];           if (scc[i] != scc[u]) compG[scc[i]].push_back(scc[u]);         }       }       if (simple) {         for (int i = 1; i <= sccnum; i++) {           sort(compG[i].begin(), compG[i].end());           compG[i].erase(unique(compG[i].begin(), compG[i].end()),                          compG[i].end());         }       }     }   };   long long n;   string s[35];   pair<long long, long long> p[100005];   map<pair<long long, long long>, long long> mp;   vector<pair<long long, long long> > vec[35];   int z[200005];   int main(void) {     ios::sync_with_stdio(0);     cin.tie(0);     cin >> n;     for (long long(i) = (1); (i) <= (n); (i)++) cin >> s[i];     long long id = 0;     for (long long(i) = (1); (i) <= (n); (i)++) {       for (long long(j) = 0; (j) < (long long)(s[i]).size(); (j)++)         id++, p[id] = pair<long long, long long>(i, j), mp[p[id]] = id;     }     long long S = id;     for (long long(i) = (1); (i) <= (n); (i)++)       vec[i].push_back(           pair<long long, long long>(0, mp[pair<long long, long long>(i, 0)]));     for (long long(i) = (1); (i) <= (n); (i)++) {       for (long long(j) = (1); (j) <= (n); (j)++) {         string str = s[j] +  #  + s[i];         z_algorithm(str, z);         for (long long(k) = 0; (k) < (long long)(s[i]).size(); (k)++) {           if (k == 0 && i == j) continue;           long long I = ((long long)(s[i]).size()),                     J = ((long long)(s[j]).size()),                     v = mp[pair<long long, long long>(i, k)], nv;           if (I - k < J) nv = mp[pair<long long, long long>(j, I - k)];           if (I - k == J) nv = 0;           if (I - k > J) nv = mp[pair<long long, long long>(i, k + J)];           if (z[J + 1 + k] == min(I - k, J))             vec[j].push_back(pair<long long, long long>(v, nv));         }       }     }     long long ans = 0;     for (long long(i) = (1); (i) <= (n); (i)++) {       SCC scc(S + 1);       set<string> S;       for (long long(j) = (i); (j) <= (n); (j)++) {         if (S.count(s[j])) {           ans++;           continue;         }         S.insert(s[j]);         for (auto p : vec[j]) scc.add_edge(p.first + 1, p.second + 1);         scc.tpsort();         if (scc.checkDAG())           ans++;         else           break;       }     }     dump_func(ans);     return 0;   }