#include <bits/stdc++.h>
using namespace std;
vector<int32_t> getSuffixArray(string& str) {
vector<int32_t> ranks(str.size());
vector<int32_t> newranks(str.size());
for (int x = 0; x < str.size(); ++x)
newranks[x] = x;
sort(newranks.begin(), newranks.end(), [&](int32_t i, int32_t j) -> bool {
assert(i < str.size());
assert(j < str.size());
return str[i] <= str[j];
});
cout << "here" << endl;
for (int x = 0; x < str.size(); ++x)
ranks[newranks[x]] = x;
for (int x = 1; x <= str.size(); x <<= 1) {
for (int y = 0; y < str.size(); ++y)
newranks[y] = y;
sort(newranks.begin(), newranks.end(), [&](int32_t i, int32_t j) -> bool {
unsigned long long ki = 1ull*(ranks[i] + 1) << 32, kj = 1ull*(ranks[j] + 1) << 32;
if (i + x < str.size())
ki |= ranks[i + x] + 1;
if (j + x < str.size())
kj |= ranks[j + x] + 1;
return ki <= kj;
});
// cout << newranks << endl;
for (int x = 0; x < str.size(); ++x)
ranks[newranks[x]] = x;
}
return move(newranks);
}
int main() {
string str;
vector<int32_t> prtemp;
cin >> str;
prtemp = getSuffixArray(str);
// cout << prtemp << endl;
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp2ZWN0b3I8aW50MzJfdD4gZ2V0U3VmZml4QXJyYXkoc3RyaW5nJiBzdHIpIHsKICAgIHZlY3RvcjxpbnQzMl90PiByYW5rcyhzdHIuc2l6ZSgpKTsKICAgIHZlY3RvcjxpbnQzMl90PiBuZXdyYW5rcyhzdHIuc2l6ZSgpKTsKICAgIGZvciAoaW50IHggPSAwOyB4IDwgc3RyLnNpemUoKTsgKyt4KQogICAgICAgIG5ld3JhbmtzW3hdID0geDsKICAgIHNvcnQobmV3cmFua3MuYmVnaW4oKSwgbmV3cmFua3MuZW5kKCksIFsmXShpbnQzMl90IGksIGludDMyX3QgaikgLT4gYm9vbCB7CiAgICAgICAgYXNzZXJ0KGkgPCBzdHIuc2l6ZSgpKTsKICAgICAgICBhc3NlcnQoaiA8IHN0ci5zaXplKCkpOwogICAgICAgIHJldHVybiBzdHJbaV0gPD0gc3RyW2pdOwogICAgfSk7CiAgICBjb3V0IDw8ICJoZXJlIiA8PCBlbmRsOwogICAgZm9yIChpbnQgeCA9IDA7IHggPCBzdHIuc2l6ZSgpOyArK3gpCiAgICAgICAgcmFua3NbbmV3cmFua3NbeF1dID0geDsKICAgIGZvciAoaW50IHggPSAxOyB4IDw9IHN0ci5zaXplKCk7IHggPDw9IDEpIHsKICAgICAgICBmb3IgKGludCB5ID0gMDsgeSA8IHN0ci5zaXplKCk7ICsreSkKICAgICAgICAgICAgbmV3cmFua3NbeV0gPSB5OwogICAgICAgIHNvcnQobmV3cmFua3MuYmVnaW4oKSwgbmV3cmFua3MuZW5kKCksIFsmXShpbnQzMl90IGksIGludDMyX3QgaikgLT4gYm9vbCB7CiAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgbG9uZyBraSA9IDF1bGwqKHJhbmtzW2ldICsgMSkgPDwgMzIsIGtqID0gMXVsbCoocmFua3Nbal0gKyAxKSA8PCAzMjsKICAgICAgICAgICAgaWYgKGkgKyB4IDwgc3RyLnNpemUoKSkKICAgICAgICAgICAgICAgIGtpIHw9IHJhbmtzW2kgKyB4XSArIDE7CiAgICAgICAgICAgIGlmIChqICsgeCA8IHN0ci5zaXplKCkpCiAgICAgICAgICAgICAgICBraiB8PSByYW5rc1tqICsgeF0gKyAxOwogICAgICAgICAgICByZXR1cm4ga2kgPD0ga2o7CiAgICAgICAgfSk7CiAgICAgICAgLy8gY291dCA8PCBuZXdyYW5rcyA8PCBlbmRsOwogICAgICAgIGZvciAoaW50IHggPSAwOyB4IDwgc3RyLnNpemUoKTsgKyt4KQogICAgICAgICAgICByYW5rc1tuZXdyYW5rc1t4XV0gPSB4OwogICAgfQogICAgcmV0dXJuIG1vdmUobmV3cmFua3MpOwp9CgppbnQgbWFpbigpIHsKICAgIHN0cmluZyBzdHI7CiAgICB2ZWN0b3I8aW50MzJfdD4gcHJ0ZW1wOwogICAgY2luID4+IHN0cjsKICAgIHBydGVtcCA9IGdldFN1ZmZpeEFycmF5KHN0cik7CiAgICAvLyBjb3V0IDw8IHBydGVtcCA8PCBlbmRsOwogICAgcmV0dXJuIDA7Cn0K