#include <iostream>
#include <cstring>
using namespace std;
const int N = 1000010;
int n, m;
char str[N];
int x[N], y[N], c[N];
int sa[N], rk[N], height[N];
void get_suffix_array () {
memset(c, 0, sizeof(c));
for (int i = 1; i <= n; ++ i) ++ c[x[i] = str[i]];
for (int i = 1; i <= m; ++ i) c[i] += c[i - 1];
for (int i = n; i >= 1; -- i) sa[c[x[i]] --] = i;
for (int k = 1; k <= n; k <<= 1) {
int cnt = 0;
for (int i = n - k + 1; i <= n; ++ i) y[++ cnt] = i;
for (int i = 1; i <= n; ++ i)
if (sa[i] > k)
y[++ cnt] = sa[i] - k;
memset(c, 0, sizeof(c));
for (int i = 1; i <= n; ++ i) ++ c[x[i]];
for (int i = 1; i <= m; ++ i) c[i] += c[i - 1];
for (int i = n; i >= 1; -- i) sa[c[x[y[i]]] --] = y[i];
for (int i = 1; i <= n; ++ i) y[i] = x[i];
x[sa[1]] = 1;
cnt = 1;
for (int i = 2; i <= n; ++ i)
x[sa[i]] = (y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k] ? cnt : ++ cnt);
if (cnt == n) break;
m = cnt;
}
}
void get_height () {
for (int i = 1; i <= n; ++ i) rk[sa[i]] = i;
int k = 0;
for (int i = 1; i <= n; ++ i) {
if (rk[i] == 1) continue;
if (k > 0) -- k;
int j = sa[rk[i]- 1];
while (str[i + k] == str[j + k]) ++ k;
height[rk[i]] = k;
}
}
int main () {
scanf("%s", str + 1);
n = strlen(str + 1), m = 122;
get_suffix_array();
get_height();
for (int i = 1; i <= n; ++ i)
printf("%d ", sa[i] - 1);
printf("\n");
for (int i = 1; i <= n; ++ i)
printf("%d ", height[i]);
return 0;
}
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1000010;
int n, m;
char str[N];
int x[N], y[N], c[N];
int sa[N], rk[N], height[N];
void get_suffix_array () {
for (int i = 1; i <= n; ++ i) {
x[i] = str[i];
++ c[x[i]];
}
for (int i = 1; i <= m; ++ i) c[i] += c[i - 1];
for (int i = n; i >= 1; -- i) {
sa[c[x[i]]] = i;
-- c[x[i]];
}
for (int k = 1; k <= n; k <<= 1) {
int cnt = 0;
for (int i = n - k + 1; i <= n; ++ i) y[++ cnt] = i;
for (int i = 1; i <= n; ++ i)
if (sa[i] > k)
y[++ cnt] = sa[i] - k;
memset(c, 0, sizeof(c));
for (int i = 1; i <= n; ++ i) ++ c[x[i]];
for (int i = 1; i <= m; ++ i) c[i] += c[i - 1];
for (int i = n; i >= 1; -- i) {
sa[c[x[y[i]]]] = y[i];
-- c[x[y[i]]];
}
for (int i = 1; i <= n; ++ i) y[i] = x[i];
x[sa[1]] = 1;
cnt = 1;
for (int i = 2; i <= n; ++ i) {
if (y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k])
x[sa[i]] = cnt;
else
x[sa[i]] = ++ cnt;
}
if (cnt == n) break;
m = cnt;
}
}
void get_height () {
for (int i = 1; i <= n; ++ i) rk[sa[i]] = i;
int k = 0;
for (int i = 1; i <= n; ++ i) {
if (rk[i] == 1) continue;
if (k > 0) -- k;
int j = sa[rk[i]- 1];
while (str[i + k] == str[j + k]) ++ k;
height[rk[i]] = k;
}
}
int main () {
scanf("%s", str + 1);
n = strlen(str + 1);
m = 122;
get_suffix_array();
get_height();
for (int i = 1; i <= n; ++ i)
printf("%d ", sa[i] - 1);
printf("\n");
for (int i = 1; i <= n; ++ i)
printf("%d ", height[i]);
return 0;
}