Problem: Consider a string s of n lowercase English letters. Let t_i be the string obtained by replacing the i-th character of s with an asterisk character *. For example, when s = abc, we have t_1 = \tt{*bc}, t_2 = \tt{a*c}, and t_3 = \tt{ab*}.

Given a string s, count the number of distinct strings of lowercase English letters and asterisks that occur as a substring of at least one string in the set \\{s, t_1, …, t_n \}. The empty string should be counted.

Note that *'s are just characters and do not play any special role as in, for example, regex matching.

Input

The only line contains a string s of n lowercase English letters (1 ≤ n ≤ 10^5).

Output

Print a single integer — the number of distinct strings of s, t_1, …, t_n.

Example

Input


abc


Output


15

Note

For the sample case, the distinct substrings are (empty string), a, b, c, *, ab, a*, bc, b*, *b, *c, abc, ab*, a*c, *bc.

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch - '0' < 0 || ch - '0' > 9) {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch - '0' >= 0 && ch - '0' <= 9) {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
int n, m = 128;
char ch[100010];
int lg[100010];
long long ans;
struct ST {
  int st[100010][20];
  void init(int *a) {
    for (int i = 1; i <= n; i++) st[i][0] = a[i];
    for (int j = 1; j <= 17; j++)
      for (int i = 1; i + (1 << j) - 1 <= n; i++)
        st[i][j] = min(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
  }
  int query(int l, int r) {
    if (!l || !r) return 0;
    l++;
    int d = lg[r - l + 1];
    return min(st[l][d], st[r - (1 << d) + 1][d]);
  }
} st;
struct SA {
  int x[100010], y[100010], sa[100010], c[100010], rnk[100010];
  int height[100010];
  void get_SA() {
    for (int i = 0; i <= m; i++) c[i] = 0;
    for (int i = 1; i <= n; i++) c[x[i] = ch[i]]++;
    for (int i = 1; i <= m; i++) c[i] += c[i - 1];
    for (int i = n; i >= 1; i--) sa[c[x[i]]--] = i;
    for (int k = 1; k <= n; k <<= 1) {
      int p = 0;
      for (int i = n - k + 1; i <= n; i++) y[++p] = i;
      for (int i = 1; i <= n; i++)
        if (sa[i] > k) y[++p] = sa[i] - k;
      for (int i = 0; i <= m; i++) c[i] = 0;
      for (int i = 1; i <= n; i++) c[x[y[i]]]++;
      for (int i = 1; i <= m; i++) c[i] += c[i - 1];
      for (int i = n; i >= 1; i--) sa[c[x[y[i]]]--] = y[i];
      p = 1;
      swap(x, y);
      x[sa[1]] = 1;
      for (int i = 2; i <= n; i++) {
        if (y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k] &&
            sa[i] + k <= n && sa[i - 1] + k <= n)
          x[sa[i]] = p;
        else
          x[sa[i]] = ++p;
      }
      m = p;
    }
  }
  void get_Height() {
    for (int i = 1; i <= n; i++) rnk[sa[i]] = i;
    int k = 0;
    for (int i = 1; i <= n; i++) {
      if (rnk[i] == 1) continue;
      int j = sa[rnk[i] - 1];
      if (k) k--;
      while (ch[i + k] == ch[j + k] && i + k <= n && j + k <= n) k++;
      height[rnk[i]] = k;
    }
    st.init(height);
  }
  int Len(int x) {
    if (!x) return 0;
    return n - sa[x] + 1;
  }
} sa;
int rt[100010 * 2];
struct Segment_Tree {
  int ls[100010 * 40], rs[100010 * 40], L[100010 * 40], R[100010 * 40], tot;
  long long t[100010 * 40];
  void update(int k) {
    if (L[ls[k]])
      L[k] = L[ls[k]];
    else
      L[k] = L[rs[k]];
    if (R[rs[k]])
      R[k] = R[rs[k]];
    else
      R[k] = R[ls[k]];
    t[k] = t[ls[k]] + t[rs[k]];
    t[k] -= st.query(R[ls[k]], L[rs[k]]);
  }
  void modi(int &k, int l, int r, int x) {
    if (!k) k = ++tot;
    if (l == r) {
      L[k] = R[k] = l;
      t[k] = sa.Len(l);
      return;
    }
    int mid = (l + r) / 2;
    if (mid >= x)
      modi(ls[k], l, mid, x);
    else
      modi(rs[k], mid + 1, r, x);
    update(k);
  }
  int merge(int x, int y) {
    if (!x || !y) return x + y;
    ls[x] = merge(ls[x], ls[y]);
    rs[x] = merge(rs[x], rs[y]);
    update(x);
    return x;
  }
} S;
struct SAM {
  int fa[100010 * 2], len[100010 * 2], ch[100010 * 2][30], tot, las, p, np;
  long long f[100010 * 2];
  void insert(int c, int id) {
    p = las, np = ++tot;
    las = tot;
    len[np] = len[p] + 1;
    while (!ch[p][c] && p) {
      ch[p][c] = np;
      p = fa[p];
    }
    if (!p)
      fa[np] = 1;
    else {
      int q = ch[p][c];
      if (len[q] == len[p] + 1)
        fa[np] = q;
      else {
        int nq = ++tot;
        len[nq] = len[p] + 1;
        memcpy(ch[nq], ch[q], sizeof(ch[q]));
        fa[nq] = fa[q];
        fa[q] = fa[np] = nq;
        while (ch[p][c] == q) {
          ch[p][c] = nq;
          p = fa[p];
        }
      }
    }
    if (id < n - 1) S.modi(rt[np], 1, n, sa.rnk[id + 2]);
  }
  int deg[100010 * 2];
  queue<int> q;
  void solve() {
    for (int i = 2; i <= tot; i++) deg[fa[i]]++;
    for (int i = 1; i <= tot; i++)
      if (!deg[i]) q.push(i);
    while (q.size()) {
      int now = q.front();
      q.pop();
      ans += 1ll * S.t[rt[now]] * (len[now] - len[fa[now]]);
      if (now != 1) rt[fa[now]] = S.merge(rt[fa[now]], rt[now]);
      deg[fa[now]]--;
      if (!deg[fa[now]]) q.push(fa[now]);
    }
  }
  void print() {
    for (int i = 1; i <= tot; i++) cout << fa[i] << " ";
    cout << endl;
    for (int i = 1; i <= tot; i++) {
      for (int j = 0; j < 26; j++) {
        if (ch[i][j])
          cout << i << " " << ch[i][j] << " " << (char)(j + 'a') << endl;
      }
    }
  }
} sam;
int main() {
  scanf("%s", ch + 1);
  n = strlen(ch + 1);
  sa.get_SA();
  sa.get_Height();
  sam.las = sam.tot = 1;
  for (int i = 1; i <= n; i++) {
    sam.insert(ch[i] - 'a', i);
    if (i == n - 1) {
      for (int j = 2; j <= sam.tot; j++) {
        ans += sam.len[j] - sam.len[sam.fa[j]];
      }
    }
  }
  if (n >= 2) S.modi(rt[1], 1, n, sa.rnk[2]);
  lg[1] = 0;
  for (int i = 2; i <= n; i++) lg[i] = lg[i >> 1] + 1;
  sam.len[0] = -1;
  long long sum = 0;
  for (int i = 2; i <= sam.tot; i++) sum -= sam.len[sam.fa[i]] - sam.len[i];
  ans += sum + 2;
  sam.solve();
  cout << ans << endl;
  return 0;
}