#include <bits/stdc++.h>
using namespace std;
const int N = 35, M = 200010 + N;
char s[N][M];
int len[N], n;
struct edge {
  int to, pre;
} e[M << 1];
int u[M << 1], l = 0;
namespace SAM {
void ins(int a, int b) { e[++l] = (edge){b, u[a]}, u[a] = l; }
struct node {
  node *trans[26], *par;
  int l;
} T[M << 1], *S = &T[1];
int tl = 1;
node *nn() { return &T[++tl]; }
node *add(node *p, int x) {
  node *w = p;
  if (w->trans[x] && w->trans[x]->l == w->l + 1) return w->trans[x];
  p = nn(), p->l = w->l + 1;
  for (; w && !w->trans[x]; w = w->par) w->trans[x] = p;
  if (!w)
    p->par = S;
  else {
    node *q = w->trans[x];
    if (q->l == w->l + 1)
      p->par = q;
    else {
      node *r = nn();
      *r = *q;
      r->l = w->l + 1;
      for (; w && w->trans[x] == q; w = w->par) w->trans[x] = r;
      p->par = q->par = r;
    }
  }
  return p;
}
node *nd[N][M];
int pre[M << 1], ed[M << 1], dfn = 0, ind[N];
void dfs(int x, int f) {
  pre[x] = ++dfn;
  for (int i = u[x]; i; i = e[i].pre)
    if (e[i].to != f) dfs(e[i].to, x);
  ed[x] = dfn;
}
void build() {
  for (int i = 1; i <= n; i++) nd[i][len[i] + 1] = S, ind[i] = len[i];
  for (int k = 1; k <= 100000; k++)
    for (int i = 1; i <= n; i++)
      if (ind[i]) {
        int j = ind[i];
        nd[i][j] = add(nd[i][j + 1], s[i][j] - 'a');
        ind[i]--;
      }
  for (int i = 1; i <= tl; i++)
    if (T[i].par) ins(T[i].par - T, i);
  dfs(1, 0);
}
bool subtree(int x, int y) {
  bool ans = (pre[x] <= pre[y]) && (pre[y] <= ed[x]);
  return ans;
}
}  // namespace SAM
namespace Graph {
edge e[M * N];
int u[M], l, d[M];
void ins(int a, int b) {
  d[b]++;
  e[++l] = (edge){b, u[a]}, u[a] = l;
}
void init() { memset(u, 0, sizeof(u)), l = 0, memset(d, 0, sizeof(d)); }
int s[N];
int L;
void build(int l, int r) {
  s[l] = 0;
  for (int i = l; i <= r - 1; i++) s[i + 1] = s[i] + len[i] + 1;
  L = s[r] + len[r] + 1;
  for (int i = l; i <= r; i++)
    for (int j = 1; j <= len[i] + 1; j++) {
      int x = s[i] + j;
      for (int k = l; k <= r; k++)
        if (j != 1 || len[k] != len[i]) {
          if (len[k] < len[i] - j + 1) {
            if (SAM::subtree(SAM::nd[k][1] - SAM::T, SAM::nd[i][j] - SAM::T))
              ins(x, s[i] + j + len[k]);
          } else {
            if (SAM::subtree(SAM::nd[i][j] - SAM::T, SAM::nd[k][1] - SAM::T))
              ins(x, s[k] + (len[i] - j + 1) + 1);
          }
        }
    }
}
int q[M];
bool sort() {
  int l = 0, r = 0;
  for (int i = 1; i <= L; i++)
    if (!d[i]) q[r++] = i;
  while (l < r) {
    int x = q[l++];
    for (int i = u[x]; i; i = e[i].pre) {
      d[e[i].to]--;
      if (!d[e[i].to]) q[r++] = e[i].to;
    }
  }
  for (int i = 1; i <= L; i++)
    if (d[i]) return false;
  return true;
}
}  // namespace Graph
bool check(int l, int r) {
  if (l > r) return true;
  Graph::init();
  Graph::build(l, r);
  return Graph::sort();
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) scanf("%s", s[i] + 1), len[i] = strlen(s[i] + 1);
  SAM::build();
  int ans = 0;
  for (int l = 1, r = 0; l <= n; l++) {
    while (r + 1 <= n && check(l, r + 1)) r++;
    ans += r - l + 1;
  }
  printf("%d\n", ans);
  return 0;
}
