后缀自动机
// Created by CAD
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
namespace sam{
int len[maxn<<1],link[maxn<<1],Next[maxn<<1][26];
int sz,last;
void init(){ //记得初始化
sz=last=0;
len[0]=0,link[0]=-1;
}
void insert(char c){ //插入字符
int now=++sz;
len[now]=len[last]+1;
int p=last;
while(~p&&!Next[p][c-'a']){
Next[p][c-'a']=now;
p=link[p];
}
if(p==-1) link[now]=0;
else{
int q=Next[p][c-'a'];
if(len[p]+1==len[q]) link[now]=q;
else{
int clone=++sz;
len[clone]=len[p]+1;
memcpy(Next[clone],Next[q],sizeof(Next[q]));
link[clone]=link[q];
while(~p&&Next[p][c-'a']==q){
Next[p][c-'a']=clone;
p=link[p];
}
link[q]=link[now]=clone;
}
}
last=now;
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
sam::init();
string s;cin>>s;
for(auto i:s) sam::insert(i);
return 0;
}