#include <iostream>
#include <vector>
using namespace std;
int mod = 1000000007;
int l = 26;
char a = 'a';
long long exp(int b, int e){
long long a = 1;
long long x = b;
while(e){
if(e%2) a = (a*x)%mod;
x = (x*x)%mod;
e = e/2;
}
return a;
}
void push_back(long long &seed, int c){
seed = (26*seed + c%l)%mod;
}
void pop_front(long long &seed, int c, long long x){
x *= c%l;
x = mod - x%mod;
seed = (seed+x)%mod;
}
vector<int> match(const string &s, const string &w){
vector<int> p;
int n = w.size();
if(!n) return p;
int h_minus = exp(l,n-1);
long long h = 0;
for(char c: w) push_back(h,c-a);
cout<<"Hash value of the word: "<<h<<endl;
if(s.size()<n) return p;
int i=0;
long long x=0;
while(i<n) push_back(x,s[i++]-a);
if(h==x) p.push_back(i-n);
while(i<s.size()){
pop_front(x,s[i-n]-a,h_minus);
push_back(x,s[i++]-a);
if(h==x) p.push_back(i-n);
}
return p;
}
int main() {
string s;
string w;
cin>>s>>w;
vector<int> ans = match(s,w);
cout<<"The given word is matched in the string at following positions:"<<endl;
for(int x: ans) cout<<x<<' ';
cout<<endl;
cout<<s<<endl;
int j=0;
for(int i=0; i<s.size()&&j<ans.size(); i++){
if(i==ans[j]&&++j) cout<<'^';
else cout<<' ';
}
cout<<endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwppbnQgbW9kID0gMTAwMDAwMDAwNzsKaW50IGwgPSAyNjsKY2hhciBhID0gJ2EnOwpsb25nIGxvbmcgZXhwKGludCBiLCBpbnQgZSl7Cglsb25nIGxvbmcgYSA9IDE7Cglsb25nIGxvbmcgeCA9IGI7Cgl3aGlsZShlKXsKCQlpZihlJTIpCWEgPSAoYSp4KSVtb2Q7CgkJeCA9ICh4KngpJW1vZDsKCQllID0gZS8yOwoJfQoJcmV0dXJuIGE7Cn0Kdm9pZCBwdXNoX2JhY2sobG9uZyBsb25nICZzZWVkLCBpbnQgYyl7CglzZWVkID0gKDI2KnNlZWQgKyBjJWwpJW1vZDsKfQp2b2lkIHBvcF9mcm9udChsb25nIGxvbmcgJnNlZWQsIGludCBjLCBsb25nIGxvbmcgeCl7Cgl4ICo9IGMlbDsKCXggPSBtb2QgLSB4JW1vZDsKCXNlZWQgPSAoc2VlZCt4KSVtb2Q7Cn0KCnZlY3RvcjxpbnQ+IG1hdGNoKGNvbnN0IHN0cmluZyAmcywgY29uc3Qgc3RyaW5nICZ3KXsKCXZlY3RvcjxpbnQ+IHA7CgkKCWludCBuID0gdy5zaXplKCk7CglpZighbikJcmV0dXJuIHA7CgkKCWludCBoX21pbnVzID0gZXhwKGwsbi0xKTsKCQoJbG9uZyBsb25nIGggPSAwOwoJZm9yKGNoYXIgYzogdykJcHVzaF9iYWNrKGgsYy1hKTsKCWNvdXQ8PCJIYXNoIHZhbHVlIG9mIHRoZSB3b3JkOiAiPDxoPDxlbmRsOwoJCglpZihzLnNpemUoKTxuKQlyZXR1cm4gcDsKCWludCBpPTA7Cglsb25nIGxvbmcgeD0wOwoJd2hpbGUoaTxuKQlwdXNoX2JhY2soeCxzW2krK10tYSk7CglpZihoPT14KQlwLnB1c2hfYmFjayhpLW4pOwoJCgl3aGlsZShpPHMuc2l6ZSgpKXsKCQlwb3BfZnJvbnQoeCxzW2ktbl0tYSxoX21pbnVzKTsKCQlwdXNoX2JhY2soeCxzW2krK10tYSk7CgkJaWYoaD09eCkJcC5wdXNoX2JhY2soaS1uKTsKCX0KCXJldHVybiBwOwp9CmludCBtYWluKCkgewoJc3RyaW5nIHM7CglzdHJpbmcgdzsKCWNpbj4+cz4+dzsKCXZlY3RvcjxpbnQ+IGFucyA9IG1hdGNoKHMsdyk7Cgljb3V0PDwiVGhlIGdpdmVuIHdvcmQgaXMgbWF0Y2hlZCBpbiB0aGUgc3RyaW5nIGF0IGZvbGxvd2luZyBwb3NpdGlvbnM6Ijw8ZW5kbDsKCWZvcihpbnQgeDogYW5zKQljb3V0PDx4PDwnICc7Cgljb3V0PDxlbmRsOwoJY291dDw8czw8ZW5kbDsKCWludCBqPTA7Cglmb3IoaW50IGk9MDsgaTxzLnNpemUoKSYmajxhbnMuc2l6ZSgpOyBpKyspewoJCWlmKGk9PWFuc1tqXSYmKytqKQljb3V0PDwnXic7CgkJZWxzZQljb3V0PDwnICc7Cgl9Cgljb3V0PDxlbmRsOwoJcmV0dXJuIDA7Cn0=