#include <bits/stdc++.h>
using namespace std;
// Warning: Change mod and N according to question
const int mod = (1LL << 31)-1;
const int N = 1e6 + 3;
#define int long long
#define MP make_pair
#define F first
#define S second
#define sz(s) ((int)s.size())
int rand(int l, int r){
static std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());
std::uniform_int_distribution<int> ludo(l, r); return ludo(rng);
}
inline int add(int x, int y, int mod = ::mod) {
x += y;
if (x >= mod or x < 0) x %= mod;
if (x >= 0) return x;
return x + mod;
}
inline int mul(int x, int y, int mod = ::mod) {
if (x >= mod or x + mod < 0) x %= mod;
if (y >= mod or y + mod < 0) y %= mod;
x *= y;
if (x >= mod or x + mod < 0) x %= mod;
if (x >= 0) return x;
return x + mod;
}
inline int sub(int x, int y, int mod = ::mod) {
x -= y;
if (x + mod < 0 or x >= mod) {
x %= mod;
}
if (x >= 0) return x;
return x + mod;
}
char s[N];
struct Hash {
vector<pair<int,int>> H, pre;
Hash(const char *s, int N, int b1 = 41, int b2 = 53) :
H(N + 5), pre(N + 5) {
pre[0].F = 1, b1 = rand(37, 1 << 10);
pre[0].S = 1, b2 = rand(41, 1 << 9);
int cur1 = 0, cur2 = 0;
for (int i = 1; i <= N; ++i) {
pre[i].F = mul(pre[i-1].F, b1);
pre[i].S = mul(pre[i-1].S, b2);
cur1 = add(mul(cur1, b1), (s[i] - 'a' + 1));
cur2 = add(mul(cur2, b2), (s[i] - 'a' + 1));
H[i].F = cur1, H[i].S = cur2;
}
}
pair<int,int> get_hash(int l, int r) {
int rem1 = mul(pre[r-l+1].F, H[l-1].F);
int rem2 = mul(pre[r-l+1].S, H[l-1].S);
return MP(sub(H[r].F, rem1), sub(H[r].S, rem2));
}
};
signed main() {
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> (s + 1);
int n = strlen(s + 1);
Hash ins(s, n);
vector<int> answer;
answer.reserve(n);
for (int len = 1; len <= n; ++len) {
bool pos = true;
auto forLen = ins.get_hash(1, len);
for (int i = len + len; i <= n && pos; i += len) {
pos &= (forLen == ins.get_hash(i - len + 1, i));
}
int l = n / len * len;
if (l != n) {
int rem = n - l;
pos &= ins.get_hash(1, rem) == ins.get_hash(l + 1, n);
}
if (pos) answer.push_back(len);
}
for (int x: answer) cout << x << ' ';
return 0;
}
CiNpbmNsdWRlIDxiaXRzL3N0ZGMrKy5oPgogCnVzaW5nIG5hbWVzcGFjZSBzdGQ7CiAKIAovLyBXYXJuaW5nOiBDaGFuZ2UgbW9kIGFuZCBOIGFjY29yZGluZyB0byBxdWVzdGlvbgpjb25zdCBpbnQgbW9kID0gKDFMTCA8PCAzMSktMTsKY29uc3QgaW50IE4gPSAxZTYgKyAzOwogCiNkZWZpbmUgaW50IGxvbmcgbG9uZwojZGVmaW5lIE1QIG1ha2VfcGFpcgojZGVmaW5lIEYgZmlyc3QKI2RlZmluZSBTIHNlY29uZAojZGVmaW5lIHN6KHMpICgoaW50KXMuc2l6ZSgpKQogCmludCByYW5kKGludCBsLCBpbnQgcil7CiAgc3RhdGljIHN0ZDo6bXQxOTkzNyBybmcoc3RkOjpjaHJvbm86OnN0ZWFkeV9jbG9jazo6bm93KCkudGltZV9zaW5jZV9lcG9jaCgpLmNvdW50KCkpOwogIHN0ZDo6dW5pZm9ybV9pbnRfZGlzdHJpYnV0aW9uPGludD4gbHVkbyhsLCByKTsgcmV0dXJuIGx1ZG8ocm5nKTsKfQogCmlubGluZSBpbnQgYWRkKGludCB4LCBpbnQgeSwgaW50IG1vZCA9IDo6bW9kKSB7CiAgeCArPSB5OwogIGlmICh4ID49IG1vZCBvciB4IDwgMCkgeCAlPSBtb2Q7CiAgaWYgKHggPj0gMCkgcmV0dXJuIHg7CiAgcmV0dXJuIHggKyBtb2Q7Cn0gCmlubGluZSBpbnQgbXVsKGludCB4LCBpbnQgeSwgaW50IG1vZCA9IDo6bW9kKSB7CiAgaWYgKHggPj0gbW9kIG9yIHggKyBtb2QgPCAwKSB4ICU9IG1vZDsKICBpZiAoeSA+PSBtb2Qgb3IgeSArIG1vZCA8IDApIHkgJT0gbW9kOwogIHggKj0geTsKICBpZiAoeCA+PSBtb2Qgb3IgeCArIG1vZCA8IDApIHggJT0gbW9kOwogIGlmICh4ID49IDApIHJldHVybiB4OwogIHJldHVybiB4ICsgbW9kOwp9CmlubGluZSBpbnQgc3ViKGludCB4LCBpbnQgeSwgaW50IG1vZCA9IDo6bW9kKSB7CiAgeCAtPSB5OwogIGlmICh4ICsgbW9kIDwgMCBvciB4ID49IG1vZCkgewogICAgeCAlPSBtb2Q7CiAgfQogIGlmICh4ID49IDApIHJldHVybiB4OwogIHJldHVybiB4ICsgbW9kOwp9CiAKY2hhciBzW05dOwogCnN0cnVjdCBIYXNoIHsKICB2ZWN0b3I8cGFpcjxpbnQsaW50Pj4gSCwgcHJlOwogIEhhc2goY29uc3QgY2hhciAqcywgaW50IE4sIGludCBiMSA9IDQxLCBpbnQgYjIgPSA1MykgOgogICAgSChOICsgNSksIHByZShOICsgNSkgeyAgICAgICAKICAgIHByZVswXS5GID0gMSwgYjEgPSByYW5kKDM3LCAxIDw8IDEwKTsKICAgIHByZVswXS5TID0gMSwgYjIgPSByYW5kKDQxLCAxIDw8IDkpOwogICAgaW50IGN1cjEgPSAwLCBjdXIyID0gMDsKICAgIGZvciAoaW50IGkgPSAxOyBpIDw9IE47ICsraSkgewogICAgICBwcmVbaV0uRiA9IG11bChwcmVbaS0xXS5GLCBiMSk7CiAgICAgIHByZVtpXS5TID0gbXVsKHByZVtpLTFdLlMsIGIyKTsKICAgICAgY3VyMSA9IGFkZChtdWwoY3VyMSwgYjEpLCAoc1tpXSAtICdhJyArIDEpKTsKICAgICAgY3VyMiA9IGFkZChtdWwoY3VyMiwgYjIpLCAoc1tpXSAtICdhJyArIDEpKTsKICAgICAgSFtpXS5GID0gY3VyMSwgSFtpXS5TID0gY3VyMjsKICAgIH0gICAKICB9CiAgcGFpcjxpbnQsaW50PiBnZXRfaGFzaChpbnQgbCwgaW50IHIpIHsKICAgIGludCByZW0xID0gbXVsKHByZVtyLWwrMV0uRiwgSFtsLTFdLkYpOwogICAgaW50IHJlbTIgPSBtdWwocHJlW3ItbCsxXS5TLCBIW2wtMV0uUyk7CiAgICByZXR1cm4gTVAoc3ViKEhbcl0uRiwgcmVtMSksIHN1YihIW3JdLlMsIHJlbTIpKTsKICB9Cn07CiAKIApzaWduZWQgbWFpbigpIHsKICBpb3NfYmFzZTo6c3luY193aXRoX3N0ZGlvKDApOyBjaW4udGllKDApOyBjb3V0LnRpZSgwKTsKICBjaW4gPj4gKHMgKyAxKTsKICBpbnQgbiA9IHN0cmxlbihzICsgMSk7CiAgSGFzaCBpbnMocywgbik7CiAgdmVjdG9yPGludD4gYW5zd2VyOwogIGFuc3dlci5yZXNlcnZlKG4pOwogIGZvciAoaW50IGxlbiA9IDE7IGxlbiA8PSBuOyArK2xlbikgewogICAgYm9vbCBwb3MgPSB0cnVlOwogICAgYXV0byBmb3JMZW4gPSBpbnMuZ2V0X2hhc2goMSwgbGVuKTsKICAgIGZvciAoaW50IGkgPSBsZW4gKyBsZW47IGkgPD0gbiAmJiBwb3M7IGkgKz0gbGVuKSB7CiAgICAgIHBvcyAmPSAoZm9yTGVuID09IGlucy5nZXRfaGFzaChpIC0gbGVuICsgMSwgaSkpOyAgICAgIAogICAgfQogICAgaW50IGwgPSBuIC8gbGVuICogbGVuOwogICAgaWYgKGwgIT0gbikgewogICAgICBpbnQgcmVtID0gbiAtIGw7CiAgICAgIHBvcyAmPSBpbnMuZ2V0X2hhc2goMSwgcmVtKSA9PSBpbnMuZ2V0X2hhc2gobCArIDEsIG4pOwogICAgfQogICAgaWYgKHBvcykgYW5zd2VyLnB1c2hfYmFjayhsZW4pOwogIH0KICBmb3IgKGludCB4OiBhbnN3ZXIpIGNvdXQgPDwgeCA8PCAnICc7CiAgcmV0dXJuIDA7Cn0=