#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ULL;
const int Lmax = 100000;
const int INF = numeric_limits<int>::max() / 2;
const ULL BASE = 137;
ULL base[Lmax];
struct Node
{
char key;
int priority;
int nr_nodes;
Node *st, *dr;
ULL codeHash;
Node(char k, int p, int n, Node *l, Node *r) : key(k), priority(p), nr_nodes(n), st(l), dr(r), codeHash(k) {
this->codeHash = static_cast<ULL>(this->key);
}
};
Node *root, *NIL;
void initBaseVector()
{
base[0] = 1;
for (int i = 1; i < Lmax; ++i)
base[i] = base[i - 1] * BASE;
}
void initTreap()
{
srand(time(nullptr));
NIL = new Node(0, 0, 0, nullptr, nullptr);
root = NIL;
}
void update(Node *&T)
{
T->nr_nodes = T->st->nr_nodes + T->dr->nr_nodes + 1;
ULL code = T->st->codeHash;
code = code * BASE + static_cast<ULL>(T->key);
code = code * base[T->dr->nr_nodes] + T->dr->codeHash;
T->codeHash = code;
}
void rotateRight(Node *&T)
{
Node *aux = T->st;
T->st = aux->dr;
aux->dr = T;
update(T);
update(aux);
T = aux;
}
void rotateLeft(Node *&T)
{
Node *aux = T->dr;
T->dr = aux->st;
aux->st = T;
update(T);
update(aux);
T = aux;
}
void balance(Node *&T)
{
if (T->st->priority > T->priority)
rotateRight(T);
if (T->dr->priority > T->priority)
rotateLeft(T);
update(T);
}
void insert(Node *&T, int pos, char key, int priority = 1 + rand() % (INF - 2))
{
if (T == NIL)
{
T = new Node(key, priority, 1, NIL, NIL);
}
else
{
if (pos <= T->st->nr_nodes + 1)
insert(T->st, pos, key, priority);
else
insert(T->dr, pos - T->st->nr_nodes - 1, key, priority);
balance(T);
}
}
void erase(Node *&T, int pos)
{
if (T == NIL) return;
if (T->st->nr_nodes + 1 == pos)
{
if (T->st == NIL && T->dr == NIL)
{
delete T;
T = NIL;
}
else
{
if (T->st->priority > T->dr->priority)
{
rotateRight(T);
erase(T->dr, pos - T->st->nr_nodes - 1);
}
else
{
rotateLeft(T);
erase(T->st, pos);
}
}
}
else
{
if (pos <= T->st->nr_nodes)
erase(T->st, pos);
else
erase(T->dr, pos - T->st->nr_nodes - 1);
}
if (T != NIL)
update(T);
}
char kth_element(Node *&T, int pos)
{
if (T->st->nr_nodes + 1 == pos)
return T->codeHash;
if (pos <= T->st->nr_nodes)
return kth_element(T->st, pos);
else
return kth_element(T->dr, pos - T->st->nr_nodes - 1);
}
void merge(Node *&root, Node *&L, Node *&R)
{
root = new Node(0, INF, 1, L, R);
update(root);
erase(root, root->st->nr_nodes + 1);
}
/// [0...pos-1] U [pos...sizeTreap]
void split(Node *&root, Node *&L, Node *&R, int pos)
{
insert(root, pos, 'a', INF);
L = root->st;
R = root->dr;
delete root;
root = NIL;
}
/// [x...y]
ULL getHash(int x, int y)
{
ULL code = 0;
Node *tmp, *T1, *T2, *T3;
split(root, tmp, T3, y + 1);
split(tmp, T1, T2, x);
code = T2->codeHash;
merge(tmp, T1, T2);
merge(root, tmp, T3);
return code;
}
void print(Node *&R = root)
{
if (R == NIL) return;
print(R->st);
cout << R->key;
print(R->dr);
}
void insert(int pos, char ch)
{
insert(root, pos, ch);
}
void erase(int pos)
{
erase(root, pos);
}
char kth_element(int pos)
{
return kth_element(root, pos);
}
ULL genHash(const string str)
{
ULL code = 0;
for (char c: str)
code = code * BASE + c;
return code;
}
int main()
{
ifstream in("strmatch.in");
ofstream out("strmatch.out");
initBaseVector();
initTreap();
string A, B;
in >> A >> B;
ULL codeHash = genHash(A);
const int N = A.size();
const int M = B.size();
for (int i = 0; i < M; ++i)
insert(i + 1, B[i]);
vector<int> sol;
for (int i = 1; i + N - 1 <= M; ++i)
{
if (getHash(i, i + N - 1) == codeHash)
sol.push_back(i - 1);
}
out << sol.size() << "\n";
for (int i = 0; i < min(1000, (int)sol.size()); ++i)
out << sol[i] << " ";
return 0;
}