#include<iostream>
using namespace std;
//这道题目主要考你KMP算法的next数组的用法
//只有深刻的理解了,才能明白
char s[400001];
int next[400001];
int res[400001],n;
/*举个例子啊:
//就如题目中的例子原串=ababcababababcabab,next=0 1 1 2 3 1 2 3 4 5 4 5 4 5 6 7 8 9 10
//我们知道next【19】=10,意思也就是说你当前的字符串与原串在第19个字符不同了,你下一次跳到你要比较的字符串的第10位和原串
//的第19位进行比较,根据next数组的定义,也就是说前缀的9个字符和后缀的9个是一样的所以直接让你的串的第10个和原串的19位相比较
//而next【10】=5,也就是说你已经比较完了前四个,直接第五个和19位比较,下面的一致类推。
//next数组想法很犀利啊&……
//学习了。kmp
*/
void Next()//数组从1开始,一直到strlen(s)+1
{
int i=1,j=0;next[1]=0;
while(i<=n)//一直找有多少个相同的前缀和后缀
{
if(j==0||s[i]==s[j])
{
++i;
++j;
next[i]=j;
}
else
{
j=next[j];
}
}
//for(i=0;i<=n;i++)
// printf("%d ",next[i]);
// printf("/n");
}
void Kmp()
{
int k=0,i;
res[k++]=n;//最长的肯定是一个
i=n;
while(i!=1)//其实next【i】=j的话也就证明前j-1个字符已经匹配,其实也就是前缀和后缀多少个相等。
{
if(next[i]!=1)
res[k++]=next[i];
i=next[i];
}
for(i=k-1;i>0;i--)
printf("%d ",res[i]-1);
printf("%d/n",res[i]-1);
}
int main()
{
while(scanf("%s",s+1)!=EOF)
{
s[0]='0';
n=strlen(s);
Next();
Kmp();
}
return 0;
}