#include <bits/stdc++.h>   using namespace std;   const int N = 2e5 + 1;   inline int min(const int& x, const int& y) { return (x - y >> 31) ? x : y; }   namespace ST {   int lg[N], t[20][N];   inline void build(int* a, int n) {     copy(a + 1, a + 1 + n, t[0] + 1);     for (int i = 2; i <= n; i++) lg[i] = lg[i >> 1] + 1;     for (int i = 1; i <= 19; i++)       for (int j = 1; j <= n - (1 << i); j++)         t[i][j] = min(t[i - 1][j], t[i - 1][j + (1 << i - 1)]);   }   inline int ask(int l, int r) {     int p = lg[r - l];     return min(t[p][l], t[p][r - (1 << p)]);   }   }  // namespace ST   namespace SA {   int n, m, sa[N], x[N], y[N], c[N], h[N];   char* st;   inline void input(char* a, int len) {     n = len, m = 128, st = a;     for (int i = 1; i <= n; i++) x[i] = st[i], sa[i] = i;   }   inline void radix_sort() {     for (int i = 1; i <= m; i++) c[i] = 0;     for (int i = 1; i <= n; i++) c[x[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];   }   inline void init() {     for (int k = 0, p = 0; k <= n; k = k << 1 | !k) {       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;       radix_sort(), swap(x, y), p = 0;       for (int i = 1; i <= n; i++)         x[sa[i]] = p +=             y[sa[i]] != y[sa[i - 1]] || y[sa[i] + k] != y[sa[i - 1] + k];       if (p >= n) break;       m = p, p = 0;     }     for (int i = 1; i <= n; i++) {       int& p = h[x[i]] = max(0, h[x[i - 1]] - 1);       while (st[i + p] == st[sa[x[i] + 1] + p]) h[x[i]]++;     }     ST::build(h, n);   }   }  // namespace SA   struct tree {     set<int> mp;     long long int val;     inline void init() { mp.clear(), mp.insert(0), mp.insert(N), val = 0; }     inline int pre(int x) { return *--mp.lower_bound(x); }     inline int nxt(int x) { return *mp.upper_bound(x); }     inline void add(int x, int y, int w) {       if (x && y != N) val += ST::ask(x, y) * w;     }     inline void ins(int x) {       int p = pre(x), q = nxt(x);       add(p, q, 1), add(p, x, -1), add(x, q, -1), mp.insert(x);     }   } t[N];   namespace SAM {   int n, tot, last, top;   int fa[N], len[N], ch[N][26], d[N], sta[N], pos[N];   inline void cpy(int x, int y) {     for (int i = 0; i <= 25; i++) ch[x][i] = ch[y][i];   }   inline void ins(int x) {     int p(last), np, q, nq;     len[np = last = ++tot] = len[p] + 1;     while (p && !ch[p][x]) ch[p][x] = np, p = fa[p];     if (!p) return void(fa[np] = 1);     if (len[q = ch[p][x]] == len[p] + 1) return void(fa[np] = q);     cpy(nq = ++tot, q), len[nq] = len[p] + 1, fa[nq] = fa[q], fa[q] = fa[np] = nq;     while (p && ch[p][x] == q) ch[p][x] = nq, p = fa[p];   }   inline void input(char* a, int len) {     n = len, tot = last = pos[0] = 1;     for (int i = 1; i <= n; i++) ins(a[i] -  a ), pos[i] = last;   }   inline void merge(tree& x, tree& y) {     if (x.mp.size() < y.mp.size()) swap(x, y);     for (int v : y.mp)       if (v && v != N) x.ins(v), x.val += n - SA::sa[v] + 1;   }   inline void work() {     long long int ans = 0;     for (int i = 0; i <= tot; i++) d[fa[i]]++, t[i].init();     for (int i = 1; i <= tot; i++)       if (!d[i]) sta[++top] = i;     for (int i = 0; i <= n - 2; i++)       t[pos[i]].ins(SA::x[i + 2]), t[pos[i]].val += n - i - 1;     for (int i = 1; i <= tot; i++) ans += len[i] - len[fa[i]] << (i != pos[n]);     while (int u = sta[top--]) {       ans += t[u].val * (len[u] - len[fa[u]]);       if (fa[u]) merge(t[fa[u]], t[u]);       if (!--d[fa[u]]) sta[++top] = fa[u];     }     cout << ans + t[1].val + 2;   }   };  // namespace SAM   int n;   char a[N];   int main() {     scanf( %s , a + 1), n = strlen(a + 1), SA::input(a, n);     SA::init(), SAM::input(a, n), SAM::work();     return 0;   }