#include <stdio.h>
#include <string.h>
#define MAX_LENGHT 2000000
#define HASH_SIZE_1 65536
#define HASH_SIZE_2 131072
#define FACTOR1 15
#define FACTOR2 34
using namespace std;
char word[MAX_LENGHT + 1];
char s[MAX_LENGHT + 1];
int pozApperances[1000];
int nrApperances, s_lenght, word_lenght;
int pwr_max_hash1, pwr_max_hash2, res_word_hash1, res_word_hash2, res_seq_hash1, res_seq_hash2;
int calcHash(char seq[], int lenght, int factor, int hash_s) {
int result, i;
result = 0;
for ( i = 0; i < lenght; i++ ) {
result = ((long long) result * factor + seq[i]) % hash_s;
}
return result;
}
int pwr(int n, int p, int hash_s) {
int result;
result = 1;
while ( p ) {
if ( p % 2 == 1 ) {
result = ((long long) result * n) % hash_s;
}
n = ((long long) n * n) % hash_s;
p /= 2;
}
return result;
}
bool compareResults() {
return res_word_hash1 == res_seq_hash1 && res_word_hash2 == res_seq_hash2;
}
int eraseNr(int nr, int p, int result, int hash_s) {
result = result - ((long long) nr * p) % hash_s;
if ( result < 0 )
result += hash_s;
return result;
}
int addNr(int nr, int p, int result, int hash_s) {
result = ((long long) result * p + nr) % hash_s;
return result;
}
void getResult(int poz) {
res_seq_hash1 = eraseNr(s[poz - word_lenght], pwr_max_hash1, res_seq_hash1, HASH_SIZE_1);
res_seq_hash2 = eraseNr(s[poz - word_lenght], pwr_max_hash2, res_seq_hash2, HASH_SIZE_2);
res_seq_hash1 = addNr(s[poz], FACTOR1, res_seq_hash1, HASH_SIZE_1);
res_seq_hash2 = addNr(s[poz], FACTOR2, res_seq_hash2, HASH_SIZE_2);
if ( compareResults() ) {
if ( nrApperances < 1000 )
pozApperances[nrApperances] = poz - word_lenght + 1;
nrApperances++;
}
}
bool alphabeth(char ch) {
return (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
}
int main() {
FILE *fin, *fout;
fin = fopen("strmatch.in", "r");
fout = fopen("strmatch.out", "w");
int i;
fgets(word, MAX_LENGHT + 1, fin);
fgets(s, MAX_LENGHT + 1, fin);
s_lenght = strlen(s);
while ( !alphabeth(s[s_lenght]) ) {
s_lenght--;
}
s_lenght++;
word_lenght = strlen(word);
while ( !alphabeth(word[word_lenght]) ) {
word_lenght--;
}
word_lenght++;
nrApperances = 0;
pwr_max_hash1 = pwr(FACTOR1, word_lenght - 1, HASH_SIZE_1);
pwr_max_hash2 = pwr(FACTOR2, word_lenght - 1, HASH_SIZE_2);
res_word_hash1 = calcHash(word, word_lenght, FACTOR1, HASH_SIZE_1);
res_word_hash2 = calcHash(word, word_lenght, FACTOR2, HASH_SIZE_2);
res_seq_hash1 = calcHash(s, word_lenght, FACTOR1, HASH_SIZE_1);
res_seq_hash2 = calcHash(s, word_lenght, FACTOR2, HASH_SIZE_2);
i = word_lenght;
if ( compareResults() ) {
pozApperances[nrApperances] = i - word_lenght;
nrApperances++;
}
while ( i < s_lenght ) {
getResult(i);
i++;
}
fprintf(fout, "%d\n", nrApperances);
for ( i = 0; i < nrApperances && i < 1000; i++ ) {
fprintf(fout, "%d ", pozApperances[i]);
}
fprintf(fout, "\n");
fclose(fin);
fclose(fout);
return 0;
}