#ifdef ONPC
#define _GLIBCXX_DEBUG
#endif
#include <bits/stdc++.h>
#define pii pair<int, int>
typedef long long ll;
#define int long long
using namespace std;
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
int modmul(int a, int b, int M)
{
return ((a % M) * (b % M)) % M;
}
ll modexp(ll a, ll e, ll mod)
{
ll res = 1 % mod;
a %= mod;
while (e > 0)
{
if (e & 1)
res = (res * a) % mod;
a = (a * a) % mod;
e >>= 1;
}
return res;
}
const long long mod = 1e9 + 7;
const long long P = 51;
void solve()
{
string in;
cin >> in;
string t;
cin >> t;
if (t.length() > in.length())
{
return;
}
vector<int> primesPow(in.length() + 5);
long long p = 51;
primesPow[0] = 1;
for (int i = 1; i < primesPow.size(); ++i)
{
primesPow[i] = modmul(p, primesPow[i - 1], mod);
}
ll invP = modexp(P, mod - 2, mod); // inverse of P mod MOD
vector<int> inv_pow(in.length() + 5);
inv_pow[0] = 1;
for (int i = 1; i <= in.length(); ++i)
inv_pow[i] = modmul(inv_pow[i - 1], invP, mod);
// polynomial hash of the string
vector<long long>
hashes(in.length() + 1);
hashes[0] = 0;
for (int i = 0; i < hashes.size() - 1; ++i)
{
hashes[i + 1] = (hashes[i] + ((in[i] - 'a' + 1) * primesPow[i])) % mod;
}
long long hashT = 0;
for (int i = 0; i < t.length(); ++i)
{
hashT = (hashT + ((t[i] - 'a' + 1) * primesPow[i])) % mod;
}
set<int> ans;
int sizeT = t.length();
for (int i = 0; i <= in.length() - t.length(); ++i)
{
long long newHash = (hashes[i + sizeT] + mod - hashes[i]) % mod;
newHash = modmul(newHash, inv_pow[i], mod);
if (newHash == hashT)
{
ans.insert(i);
}
}
for (auto i : ans)
{
cout << i << ' ';
}
cout << endl;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int t = 1;
#ifdef ONPC
freopen("input.txt", "r", stdin);
#endif
// cin >> t;
for (int i = 0; i < t; ++i)
{
solve();
}
#ifdef ONPC
cerr << endl
<< "finished in " << clock() * 1.0 / CLOCKS_PER_SEC << " sec" << endl;
#endif
return 0;
}
I2lmZGVmIE9OUEMKI2RlZmluZSBfR0xJQkNYWF9ERUJVRwojZW5kaWYKI2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CiNkZWZpbmUgcGlpIHBhaXI8aW50LCBpbnQ+CnR5cGVkZWYgbG9uZyBsb25nIGxsOwojZGVmaW5lIGludCBsb25nIGxvbmcKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCm10MTk5Mzcgcm5kKGNocm9ubzo6c3RlYWR5X2Nsb2NrOjpub3coKS50aW1lX3NpbmNlX2Vwb2NoKCkuY291bnQoKSk7CmludCBtb2RtdWwoaW50IGEsIGludCBiLCBpbnQgTSkKewoKICAgIHJldHVybiAoKGEgJSBNKSAqIChiICUgTSkpICUgTTsKfQoKbGwgbW9kZXhwKGxsIGEsIGxsIGUsIGxsIG1vZCkKewogICAgbGwgcmVzID0gMSAlIG1vZDsKICAgIGEgJT0gbW9kOwogICAgd2hpbGUgKGUgPiAwKQogICAgewogICAgICAgIGlmIChlICYgMSkKICAgICAgICAgICAgcmVzID0gKHJlcyAqIGEpICUgbW9kOwogICAgICAgIGEgPSAoYSAqIGEpICUgbW9kOwogICAgICAgIGUgPj49IDE7CiAgICB9CiAgICByZXR1cm4gcmVzOwp9Cgpjb25zdCBsb25nIGxvbmcgbW9kID0gMWU5ICsgNzsKY29uc3QgbG9uZyBsb25nIFAgPSA1MTsKdm9pZCBzb2x2ZSgpCnsKICAgIHN0cmluZyBpbjsKICAgIGNpbiA+PiBpbjsKICAgIHN0cmluZyB0OwogICAgY2luID4+IHQ7CiAgICBpZiAodC5sZW5ndGgoKSA+IGluLmxlbmd0aCgpKQogICAgewogICAgICAgIHJldHVybjsKICAgIH0KICAgIHZlY3RvcjxpbnQ+IHByaW1lc1Bvdyhpbi5sZW5ndGgoKSArIDUpOwogICAgbG9uZyBsb25nIHAgPSA1MTsKICAgIHByaW1lc1Bvd1swXSA9IDE7CiAgICBmb3IgKGludCBpID0gMTsgaSA8IHByaW1lc1Bvdy5zaXplKCk7ICsraSkKICAgIHsKICAgICAgICBwcmltZXNQb3dbaV0gPSBtb2RtdWwocCwgcHJpbWVzUG93W2kgLSAxXSwgbW9kKTsKICAgIH0KICAgIGxsIGludlAgPSBtb2RleHAoUCwgbW9kIC0gMiwgbW9kKTsgLy8gaW52ZXJzZSBvZiBQIG1vZCBNT0QKICAgIHZlY3RvcjxpbnQ+IGludl9wb3coaW4ubGVuZ3RoKCkgKyA1KTsKICAgIGludl9wb3dbMF0gPSAxOwogICAgZm9yIChpbnQgaSA9IDE7IGkgPD0gaW4ubGVuZ3RoKCk7ICsraSkKICAgICAgICBpbnZfcG93W2ldID0gbW9kbXVsKGludl9wb3dbaSAtIDFdLCBpbnZQLCBtb2QpOwogICAgLy8gcG9seW5vbWlhbCBoYXNoIG9mIHRoZSBzdHJpbmcKICAgIHZlY3Rvcjxsb25nIGxvbmc+CiAgICAgICAgaGFzaGVzKGluLmxlbmd0aCgpICsgMSk7CiAgICBoYXNoZXNbMF0gPSAwOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBoYXNoZXMuc2l6ZSgpIC0gMTsgKytpKQogICAgewogICAgICAgIGhhc2hlc1tpICsgMV0gPSAoaGFzaGVzW2ldICsgKChpbltpXSAtICdhJyArIDEpICogcHJpbWVzUG93W2ldKSkgJSBtb2Q7CiAgICB9CiAgICBsb25nIGxvbmcgaGFzaFQgPSAwOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0Lmxlbmd0aCgpOyArK2kpCiAgICB7CiAgICAgICAgaGFzaFQgPSAoaGFzaFQgKyAoKHRbaV0gLSAnYScgKyAxKSAqIHByaW1lc1Bvd1tpXSkpICUgbW9kOwogICAgfQogICAgc2V0PGludD4gYW5zOwogICAgaW50IHNpemVUID0gdC5sZW5ndGgoKTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDw9IGluLmxlbmd0aCgpIC0gdC5sZW5ndGgoKTsgKytpKQogICAgewogICAgICAgIGxvbmcgbG9uZyBuZXdIYXNoID0gKGhhc2hlc1tpICsgc2l6ZVRdICsgbW9kIC0gaGFzaGVzW2ldKSAlIG1vZDsKICAgICAgICBuZXdIYXNoID0gbW9kbXVsKG5ld0hhc2gsIGludl9wb3dbaV0sIG1vZCk7CiAgICAgICAgaWYgKG5ld0hhc2ggPT0gaGFzaFQpCiAgICAgICAgewogICAgICAgICAgICBhbnMuaW5zZXJ0KGkpOwogICAgICAgIH0KICAgIH0KICAgIGZvciAoYXV0byBpIDogYW5zKQogICAgewogICAgICAgIGNvdXQgPDwgaSA8PCAnICc7CiAgICB9CiAgICBjb3V0IDw8IGVuZGw7Cn0KCnNpZ25lZCBtYWluKCkKewogICAgaW9zOjpzeW5jX3dpdGhfc3RkaW8oMCk7CiAgICBjaW4udGllKDApOwogICAgaW50IHQgPSAxOwojaWZkZWYgT05QQwogICAgZnJlb3BlbigiaW5wdXQudHh0IiwgInIiLCBzdGRpbik7CiNlbmRpZgogICAgLy8gY2luID4+IHQ7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IHQ7ICsraSkKICAgIHsKICAgICAgICBzb2x2ZSgpOwogICAgfQojaWZkZWYgT05QQwogICAgY2VyciA8PCBlbmRsCiAgICAgICAgIDw8ICJmaW5pc2hlZCBpbiAiIDw8IGNsb2NrKCkgKiAxLjAgLyBDTE9DS1NfUEVSX1NFQyA8PCAiIHNlYyIgPDwgZW5kbDsKI2VuZGlmCiAgICByZXR1cm4gMDsKfQ==