#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> usingnamespace std; #define MAXN 500006 #define C 130 namespace wtf { char ch[MAXN]; int sa[MAXN], tp[MAXN], rnk[MAXN], buc[MAXN], len; int P[MAXN][20], ht[MAXN];
intque(int l, int r){ int L = (31 - __builtin_clz(r - l + 1)); return (ht[P[l][L]] < ht[P[r - (1 << L) + 1][L]] ? P[l][L] : P[r - (1 << L) + 1][L]); }
voidinit(){ len = strlen(ch + 1); int m = C; for (int i = 1; i <= len; ++i) ++buc[rnk[i] = ch[i]]; for (int i = 1; i <= m; ++i) buc[i] += buc[i - 1]; for (int i = len; i >= 1; --i) sa[buc[rnk[i]]--] = i; for (int k = 1, p = 0; p < len; k <<= 1) { p = 0; for (int i = 0; i <= m; ++i) buc[i] = 0; for (int i = len - k + 1; i <= len; ++i) tp[++p] = i; for (int i = 1; i <= len; ++i) if (sa[i] > k) tp[++p] = sa[i] - k; for (int i = 1; i <= len; ++i) ++buc[rnk[i]]; for (int i = 1; i <= m; ++i) buc[i] += buc[i - 1]; for (int i = len; i >= 1; --i) sa[buc[rnk[tp[i]]]--] = tp[i]; p = 1; swap(rnk, tp); rnk[sa[1]] = 1; for (int i = 2; i <= len; ++i) rnk[sa[i]] = (tp[sa[i]] == tp[sa[i - 1]] && tp[sa[i] + k] == tp[sa[i - 1] + k]) ? p : ++p; m = p; } for (int i = 1; i <= len; ++i) rnk[sa[i]] = i; for (int i = 1, k = 0; i <= len; ++i) { if (k) --k; while (ch[i + k] == ch[sa[rnk[i] - 1] + k]) ++k; ht[rnk[i]] = k; P[i][0] = i; } ht[0] = 0x3f3f3f3f; for (int i = 1; i < 20; ++i) for (int j = 1; j <= len - (1 << i) + 1; ++j) P[j][i] = (ht[P[j][i - 1]] < ht[P[j + (1 << i - 1)][i - 1]] ? P[j][i - 1] : P[j + (1 << i - 1)][i - 1]);
}
longlong res = 0;
voiddiv(int l, int r){ if( l > r ) return; int ps = que( l , r ); res += 1ll * ht[ps] * ( ps - l + 1 ) * ( r - ps + 1 ); div( l , ps - 1 ) , div( ps + 1 , r ); }
voidmain(){ // freopen("1.in","r",stdin); scanf("%s", ch + 1); init(); div( 1 , len ); cout << 1ll * ( len - 1 ) * ( len + 1 ) * len / 2 - 2 * res << endl; } } intmain(){ wtf::main(); }