#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAXN=1000001;
struct poll{
ll maxlen=0,trans[30]={0},link=0;
};
ll len;
char c0[MAXN];
queue<ll>q;
struct SAM{
ll L=1,B=1;
poll c[MAXN];
ll allx[MAXN]={0};
ll mx[MAXN]={0};
ll bs()
{
ll ans=0;
for (ll i=1;i<=B;i++)
mx[c[i].link]++;
ll p=1;
for (ll i=len-1;i>=0;i--)
{
// cout<<p<<'-'<<c0[i];
p=c[p].trans[c0[i]];
// cout<<'-'<<p<<endl;
allx[p]=1;
}
for (ll i=1;i<=B;i++){
if (mx[i]==0)
q.push(i);
}
// cout<<endl;
while (!q.empty())
{
ll s=q.front();
q.pop();
// if (c[s].link>0){
allx[c[s].link]+=allx[s];
mx[c[s].link]--;
ans+=(len-allx[s])*allx[s]*(c[s].maxlen-c[c[s].link].maxlen);
if (mx[c[s].link]==0)
q.push(c[s].link);
// }
}
return ans;
}
void add(ll ch)
{
ll now=++B;
ll l=L;
c[now].maxlen=c[L].maxlen+1;
while (l!=0&&c[l].trans[ch]==0)
{
c[l].trans[ch]=now;
l=c[l].link;
}
if (l==0) c[now].link = 1;
else {
ll q = c[l].trans[ch];
if (c[q].maxlen == c[l].maxlen + 1) c[now].link = q;
else {
ll nxt = (++ B);
c[nxt].maxlen = c[l].maxlen + 1;
memcpy(c[nxt].trans, c[q].trans,sizeof(c[q].trans));
c[nxt].link = c[q].link;
while(l && c[l].trans[ch] == q) {
l=c[l].link;
c[l].trans[ch] = nxt;
}
c[now].link = c[q].link = nxt;
}
}
L = now;
}
ll minlen(ll i)
{
return c[c[i].link].maxlen+1;
}
ll all()
{
ll ans=0;
for (ll i=2;i<=B;i++){
cout<<c[i].maxlen<<' '<<minlen(i)<<endl;
ans+=c[i].maxlen-minlen(i)+1;
}
return ans;
}
};
SAM q0;
int main()
{
cin>>c0;
len=strlen(c0);
for (ll i=len-1;i>=0;i--){
// for (ll i=0;c[i]!=0;i++){
c0[i]-=('a'-1);
q0.add(c0[i]);
}
// }
// cout<<q0.L<<' '<<q0.B<<endl;
// q0.all();
// cout<<endl;
cout<<q0.bs()<<endl;
}