#include<bits/stdc++.h>
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,a,n) for(int i=n;i>=a;--i)
#define pb push_back
#define fi first
#define se second
#define io std::ios::sync_with_stdio(false)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int P = 1e9+7, INF = 0x3f3f3f3f;
ll gcd(ll a,ll b)
{
return b?gcd(b,a%b):a;
}
ll qpow(ll a,ll n)
{
ll r=1%P;
for (a%=P; n; a=a*a%P,n>>=1)if(n&1)r=r*a%P;
return r;
}
const int maxn=2e6;
struct Suffix_Automata {
int maxlen[maxn], trans[maxn][26], link[maxn], Size, Last;
int siz[maxn];
int t[maxn],A[maxn];
Suffix_Automata() { Size = Last = 1; }
inline void Extend(int id) {
int cur = (++ Size), p;
siz[Size]=1;
maxlen[cur] = maxlen[Last] + 1;
for (p = Last; p && !trans[p][id]; p = link[p]) trans[p][id] = cur;
if (!p) link[cur] = 1;
else {
int q = trans[p][id];
if (maxlen[q] == maxlen[p] + 1) link[cur] = q;
else {
int clone = (++ Size);
maxlen[clone] = maxlen[p] + 1;
memcpy(trans[clone], trans[q],sizeof(trans[q]));
link[clone] = link[q];
for (; p && trans[p][id] == q; p = link[p]) trans[p][id] = clone;
link[cur] = link[q] = clone;
}
}
Last = cur;
}
void buildtree()
{
for(int i=1;i<=Size;i++) t[maxlen[i]]++;
for(int i=1;i<=Size;i++) t[i]+=t[i-1];
for(int i=1;i<=Size;i++) A[t[maxlen[i]]--]=i;
for(int i=Size;i>=1;i--)
{ int now=A[i];
int fa=link[now];
siz[fa]+=siz[now];
}
}
} T;
int main()
{
char s[maxn];
cin>>s+1;
int n=strlen(s+1);
for(int i=1;i<=n;i++)
{
T.Extend(s[i]-'a');
}
}