#include<iomanip>
#include<limits>
#include<thread>
#include<utility>
#include<iostream>
#include<string>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<numeric>
#include<cassert>
#include<random>
#include<chrono>
#include<unordered_map>
#include<fstream>
#include<list>
#include<functional>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll,ll> pll;
typedef pair<int,int> pi;
typedef pair<double,double> pd;
typedef pair<double,ll> pdl;
#define F first
#define S second
const ll E=1e18+7;
const ll MOD=1000000007;


class string_hash{
private:
    typedef long long int ll;
    typedef unsigned long long int ull;
    typedef unsigned long ul;
    typedef vector<ull> Hash;
    
    const ull mod;
    const ull roll;
    Hash H;
    string W;
    
    ull mod_pow(ull a,ull x){
        a%=mod;
        ll ans=1;
        while(x>0){
            if(x&1){ans*=a; ans%=mod;}
            a*=a; a%=mod;
            x>>=1;
        }
        return ans;
    }
    
    pll Ex_gcd(ll a,ll b){
        if(b==0){return {1,0};}
        pll ret=Ex_gcd(b,a%b);
        ret.F-=a/b*ret.S;
        return {ret.S,ret.F};
    }
    
    ull R(ull a){
        ll ret=Ex_gcd(a,mod).F;
        ret%=mod;
        if(ret<0){ret+=mod;}
        return ret;
    }
    
    void mk_hash(){
        H[0]=W[0];
        for(int i=1;i<H.size();i++){
            H[i]=H[i-1]*roll%mod+W[i];
            H[i]%=mod;
        }
    }
    
public:
    string_hash(const string &W={},ull mod=1000000007,ull roll=65537):W(W),mod(mod),roll(roll),H(W.size()){
        mk_hash();
    }
    
    void push_back(const string &A){
        ull d=H.size();
        H.resize(d+A.size());
        W.resize(d+A.size());
        for(ull i=d;i<H.size();i++){
            W[i]=A[i-d];
            H[i]=W[i];
            if(i!=0){
                H[i]+=H[i-1]*roll%mod;
            }
            H[i]%=mod;
        }
    }
    
    void push_back(char c){
        W.push_back(c);
        H.push_back(c);
        if(H.size()==1){return;}
        H[H.size()-1]+=H[H.size()-2]*roll%mod;
        H[H.size()-1]%=mod;
    }
    
    void find(const string_hash &S){
        
    }
    
    unsigned long size() const {return W.size();}
    
    const ull & MOD() const {return mod;}
    
    const ull & ROLL() const {return roll;}
    
    ull & operator [] (const ul &s){
        assert(s<H.size());
        return H[s];
    }
    
    bool operator == (string_hash &S) const {
        return S.size()==H.size() && H[H.size()-1]==S[H.size()-1];
    }
    
    //共通の長さ、初めて違う文字のインデックス
    unsigned long same(string_hash &W) const {
        ul r=min(H.size(),W.size())-1;
        if(H[r]==W[r]){return r+1;}
        ul l=0;
        while(r-l>3){
            ul m=l+(r-l)/2;
            if(W[m]!=H[m]){r=m;}
            else{l=m+1;}
        }
        for(ul i=l;i<r;i++){
            if(W[i]!=H[i]){return i;}
        }
        return r;
    }
    
    //[l,r)
    ull hash(ul l,ul r){
        assert(l<r && r<=H.size());
        if(l==0){return H[r-1];}
        return (mod+H[r-1]-H[l-1]*mod_pow(roll,r-l)%mod)%mod;
    }
    
    ull merge_hash(ull hash,ul Long){
        return (H[H.size()-1]*mod_pow(roll,Long)%mod+hash)%mod;
    }
};




int main(){
    string t,p;
    cin>>t>>p;
    string_hash T(t),P(p);
    string_hash A(t,1000037123),B(p,1000037123);
    for(ll i=0;i+P.size()<=T.size();i++){
        if(T.hash(i,i+P.size())==P[P.size()-1] && A.hash(i,i+B.size())==B[B.size()-1]){
            printf("%d\n",i);
        }
    }
    
    
    
    return 0;
}



Measured memory_bytes: 21660