#include <bits/stdc++.h>
using namespace std;
#define all(c) (c).begin(), (c).end()
#define cnt(c, x) ((c).find(x) != (c).end())
#define pb push_back
#define FOR(i, a, n) for(int i = (a); i < (n); i++)
#define REP(i, n) for(int i = 0; i < (n); i++)
#define SZ(x) ((int) (x).size())
#define mp(x,y) make_pair((x), (y))
#define mp3(x,y,z) make_pair((x), make_pair( (y), (z)))
#define foreach(C, i) for(auto i = (C).begin(); i != (C).end(); i++)
#define xx first
#define yy second
#define clr clear()
#define var(x) cout<< #x << " = "<<x<<"\n";
#define print(x) for_each((x).begin(), (x).end(), [](auto n) { cout<<x<<" " })
typedef int32_t i3;
typedef int64_t i6;
typedef vector<i3> vi;
typedef pair<i3,i3> ii;
typedef vector<pair<i3,i3> > vii;
class SuffixArray
{
public:
string str;
vector<array<int,3> > vec;
vector<vector<int> > dp;
vector<int> suff;
SuffixArray(string st)
{
str = st + "$";
vec = vector<array<int,3> >(SZ(str));
dp = vector<vector<int> >(ceil(log2(SZ(str))) + 1, vector<int> (SZ(str),-1));
suff = vector<int> (SZ(str)-1);
}
void construct()
{
vector<pair<string,int > > temp;
REP(i, SZ(str))
temp.pb(make_pair(str.substr(i,1), i));
sort(all(temp));
map<string,int> mp;
int index = 0;
foreach(temp, it)
{
string st = it->first;
if (mp.count(st) == 0)
mp[st] = index++;
}
foreach(temp, it)
dp[0][it->second] = mp[it->first];
int step = 0;
for(step = 0; (1 << step) < SZ(str); step++)
{
for(int i = 0; i < SZ(str); i++)
{
if (i + (1 << step) < SZ(str))
vec[i] = { dp[step][i], dp[step][i + (1 << step)], i };
else
vec[i] = { dp[step][i], -1, i };
}
sort(all(vec));
index = 0;
mp.clear();
for(array<int,3>& arr : vec)
{
string st2 = str.substr(arr[2], min(1 << (step+1), SZ(str) - arr[2] - 1));
if (mp.find(st2) == mp.end())
mp[st2] = index++;
}
for(array<int,3> & arr : vec)
{
string st2 = str.substr(arr[2], min(1 << (step+1), SZ(str) - arr[2] - 1));
dp[step+1][arr[2]] = mp[st2];
}
}
for(int i = 0; i < SZ(str)-1; i++)
suff[i] = dp[step][i] - 1;
}
};
int main()
{
string str; cin >> str;
SuffixArray suff(str);
suff.construct();
for(int num : suff.suff)
cout << num << " ";
cout << "\n";
return (0);
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CiNkZWZpbmUgYWxsKGMpIChjKS5iZWdpbigpLCAoYykuZW5kKCkKI2RlZmluZSBjbnQoYywgeCkgKChjKS5maW5kKHgpICE9IChjKS5lbmQoKSkKI2RlZmluZSBwYiBwdXNoX2JhY2sKI2RlZmluZSBGT1IoaSwgYSwgbikgZm9yKGludCBpID0gKGEpOyBpIDwgKG4pOyBpKyspCiNkZWZpbmUgUkVQKGksIG4pIGZvcihpbnQgaSA9IDA7IGkgPCAobik7IGkrKykKI2RlZmluZSBTWih4KSAoKGludCkgKHgpLnNpemUoKSkKI2RlZmluZSBtcCh4LHkpIG1ha2VfcGFpcigoeCksICh5KSkKI2RlZmluZSBtcDMoeCx5LHopIG1ha2VfcGFpcigoeCksIG1ha2VfcGFpciggKHkpLCAoeikpKQojZGVmaW5lIGZvcmVhY2goQywgaSkgZm9yKGF1dG8gaSA9IChDKS5iZWdpbigpOyBpICE9IChDKS5lbmQoKTsgaSsrKQojZGVmaW5lIHh4IGZpcnN0CiNkZWZpbmUgeXkgc2Vjb25kCiNkZWZpbmUgY2xyIGNsZWFyKCkKI2RlZmluZSB2YXIoeCkgY291dDw8ICN4IDw8ICIgPSAiPDx4PDwiXG4iOwojZGVmaW5lIHByaW50KHgpIGZvcl9lYWNoKCh4KS5iZWdpbigpLCAoeCkuZW5kKCksIFtdKGF1dG8gbikgeyBjb3V0PDx4PDwiICIgfSkKdHlwZWRlZiBpbnQzMl90IGkzOwp0eXBlZGVmIGludDY0X3QgaTY7CnR5cGVkZWYgdmVjdG9yPGkzPiB2aTsKdHlwZWRlZiBwYWlyPGkzLGkzPiBpaTsKdHlwZWRlZiB2ZWN0b3I8cGFpcjxpMyxpMz4gPiB2aWk7CgpjbGFzcyBTdWZmaXhBcnJheQp7CglwdWJsaWM6CgkJc3RyaW5nIHN0cjsKCQl2ZWN0b3I8YXJyYXk8aW50LDM+ID4gdmVjOwoJCXZlY3Rvcjx2ZWN0b3I8aW50PiA+IGRwOwoJCXZlY3RvcjxpbnQ+IHN1ZmY7CgkJU3VmZml4QXJyYXkoc3RyaW5nIHN0KQoJCXsKCQkJc3RyID0gc3QgKyAiJCI7CgkJCXZlYyA9IHZlY3RvcjxhcnJheTxpbnQsMz4gPihTWihzdHIpKTsKCQkJZHAgPSB2ZWN0b3I8dmVjdG9yPGludD4gPihjZWlsKGxvZzIoU1ooc3RyKSkpICsgMSwgdmVjdG9yPGludD4gKFNaKHN0ciksLTEpKTsKCQkJc3VmZiA9IHZlY3RvcjxpbnQ+IChTWihzdHIpLTEpOwoJCX0KCQl2b2lkIGNvbnN0cnVjdCgpCgkJewoJCQl2ZWN0b3I8cGFpcjxzdHJpbmcsaW50ID4gPiB0ZW1wOwoJCQlSRVAoaSwgU1ooc3RyKSkKCQkJCXRlbXAucGIobWFrZV9wYWlyKHN0ci5zdWJzdHIoaSwxKSwgaSkpOwoJCQlzb3J0KGFsbCh0ZW1wKSk7CgkJCW1hcDxzdHJpbmcsaW50PiBtcDsKCQkJaW50IGluZGV4ID0gMDsKCQkJZm9yZWFjaCh0ZW1wLCBpdCkKCQkJewoJCQkJc3RyaW5nIHN0ID0gaXQtPmZpcnN0OwoJCQkJaWYgKG1wLmNvdW50KHN0KSA9PSAwKQoJCQkJCW1wW3N0XSA9IGluZGV4Kys7CgkJCX0KCQkJZm9yZWFjaCh0ZW1wLCBpdCkKCQkJCWRwWzBdW2l0LT5zZWNvbmRdID0gbXBbaXQtPmZpcnN0XTsKCQkJaW50IHN0ZXAgPSAwOwoJCQlmb3Ioc3RlcCA9IDA7ICgxIDw8IHN0ZXApIDwgU1ooc3RyKTsgc3RlcCsrKQoJCQl7CgkJCQlmb3IoaW50IGkgPSAwOyBpIDwgU1ooc3RyKTsgaSsrKQoJCQkJewoJCQkJCWlmIChpICsgKDEgPDwgc3RlcCkgPCBTWihzdHIpKQoJCQkJCQl2ZWNbaV0gPSB7IGRwW3N0ZXBdW2ldLCBkcFtzdGVwXVtpICsgKDEgPDwgc3RlcCldLCBpIH07CgkJCQkJZWxzZQoJCQkJCQl2ZWNbaV0gPSB7IGRwW3N0ZXBdW2ldLCAtMSwgaSB9OwoJCQkJfQoJCQkJc29ydChhbGwodmVjKSk7CgkJCQlpbmRleCA9IDA7CgkJCQltcC5jbGVhcigpOwoJCQkJZm9yKGFycmF5PGludCwzPiYgYXJyIDogdmVjKQoJCQkJewkKCQkJCQlzdHJpbmcgc3QyID0gc3RyLnN1YnN0cihhcnJbMl0sIG1pbigxIDw8IChzdGVwKzEpLCBTWihzdHIpIC0gYXJyWzJdIC0gMSkpOwoJCQkJCWlmIChtcC5maW5kKHN0MikgPT0gbXAuZW5kKCkpCgkJCQkJCW1wW3N0Ml0gPSBpbmRleCsrOwoJCQkJfQoJCQkJZm9yKGFycmF5PGludCwzPiAmIGFyciA6IHZlYykKCQkJCXsKCQkJCQlzdHJpbmcgc3QyID0gc3RyLnN1YnN0cihhcnJbMl0sIG1pbigxIDw8IChzdGVwKzEpLCBTWihzdHIpIC0gYXJyWzJdIC0gMSkpOwoJCQkJCWRwW3N0ZXArMV1bYXJyWzJdXSA9IG1wW3N0Ml07CgkJCQl9CgkJCX0KCQkJZm9yKGludCBpID0gMDsgaSA8IFNaKHN0ciktMTsgaSsrKQoJCQkJc3VmZltpXSA9IGRwW3N0ZXBdW2ldIC0gMTsKCgkJfQp9OwppbnQgbWFpbigpCnsKCXN0cmluZyBzdHI7IGNpbiA+PiBzdHI7CglTdWZmaXhBcnJheSBzdWZmKHN0cik7CglzdWZmLmNvbnN0cnVjdCgpOwoJZm9yKGludCBudW0gOiBzdWZmLnN1ZmYpCgkJY291dCA8PCBudW0gPDwgIiAiOwoJY291dCA8PCAiXG4iOwoJcmV0dXJuICgwKTsKfQkJ