Link to this code: https://cses.fi/paste/e5b55ebbccab6e5cfffd5d/
#include <algorithm>
#include <functional>
#include <iostream>
#include <string>
#include <utility>
#include <vector>
#ifndef ONLINE_JUDGE
#define test(...) do { cerr << "Line(" << __LINE__ << ") [" #__VA_ARGS__ "] =>"; ([](auto&&... args){ ((cerr << ' ' << args), ...); }(__VA_ARGS__)); cerr << endl; } while(0)
#define testv(x) do { cerr << "Line(" << __LINE__ << ") " #x " => ["; int _i=0; for (auto& _e : (x)) cerr << (_i++ ? ", " : "") << _e; cerr << "]" << endl; } while(0)
#else
#define test(...) 0
#define testv(...) 0
#endif
#define printv(x) { for (auto i : (x)) cout << i << ' '; cout << endl; }
#define SQ(x) ((x) * (x))
#define SZ(x) ((int)x.size())
#define eb emplace_back
#define ALL(x) begin(x), end(x)
#define rALL(x) rbegin(x), rend(x)
#define fst first
#define sec second

using namespace std;
using lli = long long int;

vector<int> z_function(string s) {
        int N = SZ(s);
        vector<int> z(N);
        z[0] = 0;
        int L = 0, R = 0;
        for (int i = 1; i < N; i++) {
                if (i <= R and z[i - L] < R - i + 1) {
                        z[i] = z[i - L];
                } else {
                        z[i] = max(0, R - i + 1);
                        while (i + z[i] < N and s[ z[i] ] == s[ i + z[i] ]) {
                                z[i]++;
                        }
                        if (i + z[i] - 1 > R) {
                                L = i;
                                R = i + z[i] - 1;
                        }
                }
        }
        return z;
}


void solution() {
        string S; cin >> S;
        int N = SZ(S);
        vector<int> z = z_function(S);
        vector<int> ans;
        for (int i = N-1; i >= 0; i--) {
                if (i + z[i] == N) ans.eb(z[i]);
        }
        printv(ans);
}

int main() {
        cin.tie(nullptr)->sync_with_stdio(false);
        solution();
        return 0;
}