#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
typedef pair<int,int> PII;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef vector<string> VS;
typedef vector<int> VI;
typedef vector<vector<int>> VVI;
inline int log_2(int x) {return 31-__builtin_clz(x);}
inline int popcount(int x) {return __builtin_popcount(x);}
inline int lowbit(int x) {return x&-x;}
const ull P=131,N=3e5+3;//根據經驗進位制P取為131不易衝突
ull h[N],p[N];//ull相當於一個數對2^64取模,p陣列裡存的是進位制次冪運算預處理的結果
char ch[N];
int SA[N];
int n;
ull _hash(int l,int r)
{
return h[r]-h[l-1]*p[r-l+1];//處理h陣列時將第一位字元作為最高位處理
//故此時要運算出h[r]-h[l-1]的雜湊值需要將h[l-1]乘P的r-l+1次
}
void init()
{
h[0]=0,p[0]=1;
for(int i=1;i<=n;++i)
{
h[i]=h[i-1]*P+ch[i];//用的是ascii碼參與運算
p[i]=p[i-1]*P;
}
}
int find_pos(int x,int y)
{
//返回相同的最大長度
auto check = [&](int M)->bool
{
if(!M) return true;
if(x+M-1>n||y+M-1>n) return false;
return _hash(x,x+M-1)==_hash(y,y+M-1);
};
int L = 0, R = min(n-x+1,n-y+1)+1;
while(L+1<R)
{
int M = (L+R)/2;
if(check(M)) L = M;
else R = M;
}
return L;
}
bool cmp(int x,int y)
{
int pos = find_pos(x,y);
return ch[x+pos] < ch[y+pos];
}
void solve()
{
scanf("%s",ch+1);
n = strlen(ch+1);
init();
for(int i=1;i<=n;++i) SA[i] = i;
sort(SA+1,SA+1+n,cmp);
for(int i=1;i<=n;++i) cout<<SA[i]-1<<" \n"[i==n];
cout<<"0 ";
for(int i=2;i<=n;++i) cout<<find_pos(SA[i],SA[i-1])<<" ";
}
int main()
{
int T = 1;
//cin>>T;
while(T--)
{
solve();
}
}