#include <algorithm>
#include <cstdio>
#include <fstream>
#include <string>
#include <vector>
#define R1 432314 // random 1 (este random ptc l am tastat eu random)
#define R2 130333
#define HASH_SIZE 65536 // cate valori are un unsigned short
unsigned short
powShort(unsigned b,
unsigned exp) { // pow care automat face modulo 2^16 cand da overflow
unsigned rez = 1;
while (exp) {
if (exp % 2)
rez *= b;
b *= b;
exp /= 2;
}
return (unsigned short)rez;
}
struct rhash {
const unsigned short putMax;
const int r;
rhash(int r, unsigned short k)
: putMax(powShort(r, k - 1)), r(r) {} // constructor
// precalculare r^k-1 , ca sa pot scoate ult element usor k = lungimea
// substringului
unsigned short hash(const std::string &a) {
unsigned short rez = 0;
for (int i = 0; i < a.size(); i++)
rez = (unsigned short)((long long)rez * r + a[i]);
return rez;
}
unsigned short roll(unsigned short hash, unsigned char oldChar,
unsigned char newChar) {
hash -= oldChar * putMax;
hash = hash * r + newChar;
return hash;
}
};
int main() {
FILE *fout;
std::ifstream fin("strmatch.in");
fout = fopen("strmatch.out", "w");
std::vector<int> rasp;
std::string a, b;
fin >> a >> b;
int i = a.size();
rhash h1(R1, a.size()),
h2(R2, a.size()); // doua functii hash, ca sa fie sansele mai mici sa dea
// 2 stringuri acelasi hash
int orHash = h1.hash(a), orHash2 = h2.hash(a); // hashurile lui a
int currentHash = h1.hash(b.substr(0, i)),
currentHash2 = h2.hash(b.substr(0, i));
if (currentHash == orHash && currentHash2 == orHash2)
rasp.push_back(i);
while (i < b.size()) {
currentHash = h1.roll(currentHash, b[i - a.size()], b[i]);
currentHash2 = h2.roll(currentHash2, b[i - a.size()], b[i]);
if (currentHash == orHash && currentHash2 == orHash2)
rasp.push_back(i - a.size() + 1);
i++;
}
fprintf(fout, "%d\n", (int)rasp.size());
for (int i = 0; i < std::min((int)rasp.size(), 1000); i++)
fprintf(fout, "%d ", rasp[i]);
return 0;
}