#include <bits/stdc++.h>
using namespace std;
/*
Para frecuencias
template<int E = 26> // E = Alfabeto
struct AhoCorasick {
int nodes;
vector<int> suf;
vector<int> freq;
vector<int> by_level;
vector<bool> terminal;
vector<array<int, E>> go;
AhoCorasick() {
add_node();
nodes = 1;
}
void add_node() {
terminal.emplace_back();
suf.emplace_back();
go.emplace_back();
freq.emplace_back();
}
void insert(string &s) {
int pos = 0;
for (char ch : s) {
int c = ch - 'a';
if (go[pos][c] == 0) {
go[pos][c] = nodes++;
add_node();
}
pos = go[pos][c];
}
terminal[pos] = true;
}
void build() {
queue<int> Q;
Q.emplace(0);
while (not Q.empty()) {
int u = Q.front(); Q.pop();
by_level.emplace_back(u);
for (int c = 0; c < E; ++c) {
if (go[u][c]) {
int v = go[u][c];
Q.emplace(v);
suf[v] = u == 0 ? 0 : go[suf[u]][c];
}
else {
go[u][c] = u == 0 ? 0 : go[suf[u]][c];
}
}
}
}
};*/
// Para existencia
template<int E = 26> // E = Alfabeto
struct AhoCorasick {
int nodes;
vector<int> suf;
vector<int> super;
vector<bool> terminal;
vector<array<int, E>> go;
AhoCorasick() {
add_node();
nodes = 1;
}
void add_node() {
terminal.emplace_back();
suf.emplace_back();
go.emplace_back();
super.emplace_back();
}
void insert(string &s) {
int pos = 0;
for (char ch : s) {
int c = ch - 'a';
if (go[pos][c] == 0) {
go[pos][c] = nodes++;
add_node();
}
pos = go[pos][c];
}
terminal[pos] = true;
}
void build() {
queue<int> Q;
Q.emplace(0);
while (not Q.empty()) {
int u = Q.front(); Q.pop();
super[u] = (suf[u] == 0 or terminal[suf[u]] ? suf[u] : super[suf[u]]);
for (int c = 0; c < E; ++c) {
if (go[u][c]) {
int v = go[u][c];
Q.emplace(v);
suf[v] = u == 0 ? 0 : go[suf[u]][c];
}
else {
go[u][c] = u == 0 ? 0 : go[suf[u]][c];
}
}
}
}
};
template<int E = 26>
void mark(int u, AhoCorasick<E> &AC) {
if (u == 0) return;
mark(AC.super[u], AC);
if (AC.terminal[u]) {
cout << "El nodo " << u << " ocurre como subcadena" << endl;
AC.terminal[u] = false;
}
AC.super[u] = 0;
}
int main() {
cin.tie(0) -> sync_with_stdio(false);
AhoCorasick<26> Solver;
vector<string> S = {"arco", "co", "barco", "oro", "toro"};
for (string s : S) {
Solver.insert(s);
}
Solver.build();
const string T = "coroparcotoro";
int p = 0;
for (char ch : T) {
int c = ch - 'a';
p = Solver.go[p][c];
mark(p, Solver);
}
/*
for (int i = (int)Solver.by_level.size() - 1; i > 0; --i) {
int x = Solver.by_level[i];
Solver.freq[Solver.suf[x]] += Solver.freq[x];
}
for (int i = 0; i < Solver.nodes; ++i) {
cout << "El nodo " << i << " ocurre " << Solver.freq[i] << " veces" << endl;
}*/
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgovKgpQYXJhIGZyZWN1ZW5jaWFzCnRlbXBsYXRlPGludCBFID0gMjY+IC8vIEUgPSBBbGZhYmV0bwpzdHJ1Y3QgQWhvQ29yYXNpY2sgewoJaW50IG5vZGVzOwoJdmVjdG9yPGludD4gc3VmOwoJdmVjdG9yPGludD4gZnJlcTsKCXZlY3RvcjxpbnQ+IGJ5X2xldmVsOwoJdmVjdG9yPGJvb2w+IHRlcm1pbmFsOwoJdmVjdG9yPGFycmF5PGludCwgRT4+IGdvOwoJCglBaG9Db3Jhc2ljaygpIHsKCQlhZGRfbm9kZSgpOwoJCW5vZGVzID0gMTsKCX0KCQoJdm9pZCBhZGRfbm9kZSgpIHsKCQl0ZXJtaW5hbC5lbXBsYWNlX2JhY2soKTsKCQlzdWYuZW1wbGFjZV9iYWNrKCk7CgkJZ28uZW1wbGFjZV9iYWNrKCk7CgkJZnJlcS5lbXBsYWNlX2JhY2soKTsKCX0KCQoJdm9pZCBpbnNlcnQoc3RyaW5nICZzKSB7CgkJaW50IHBvcyA9IDA7CgkJZm9yIChjaGFyIGNoIDogcykgewoJCQlpbnQgYyA9IGNoIC0gJ2EnOwoJCQlpZiAoZ29bcG9zXVtjXSA9PSAwKSB7CgkJCQlnb1twb3NdW2NdID0gbm9kZXMrKzsKCQkJCWFkZF9ub2RlKCk7CgkJCX0KCQkJcG9zID0gZ29bcG9zXVtjXTsKCQl9CgkJdGVybWluYWxbcG9zXSA9IHRydWU7Cgl9CgkKCXZvaWQgYnVpbGQoKSB7CgkJcXVldWU8aW50PiBROwoJCVEuZW1wbGFjZSgwKTsKCQl3aGlsZSAobm90IFEuZW1wdHkoKSkgewoJCQlpbnQgdSA9IFEuZnJvbnQoKTsgUS5wb3AoKTsKCQkJYnlfbGV2ZWwuZW1wbGFjZV9iYWNrKHUpOwoJCQlmb3IgKGludCBjID0gMDsgYyA8IEU7ICsrYykgewoJCQkJaWYgKGdvW3VdW2NdKSB7CgkJCQkJaW50IHYgPSBnb1t1XVtjXTsKCQkJCQlRLmVtcGxhY2Uodik7CgkJCQkJc3VmW3ZdID0gdSA9PSAwID8gMCA6IGdvW3N1Zlt1XV1bY107CgkJCQl9CgkJCQllbHNlIHsKCQkJCQlnb1t1XVtjXSA9IHUgPT0gMCA/IDAgOiBnb1tzdWZbdV1dW2NdOwoJCQkJfQoJCQl9CgkJfQoJfQp9OyovCgovLyBQYXJhIGV4aXN0ZW5jaWEKdGVtcGxhdGU8aW50IEUgPSAyNj4gLy8gRSA9IEFsZmFiZXRvCnN0cnVjdCBBaG9Db3Jhc2ljayB7CglpbnQgbm9kZXM7Cgl2ZWN0b3I8aW50PiBzdWY7Cgl2ZWN0b3I8aW50PiBzdXBlcjsKCXZlY3Rvcjxib29sPiB0ZXJtaW5hbDsKCXZlY3RvcjxhcnJheTxpbnQsIEU+PiBnbzsKCQoJQWhvQ29yYXNpY2soKSB7CgkJYWRkX25vZGUoKTsKCQlub2RlcyA9IDE7Cgl9CgkKCXZvaWQgYWRkX25vZGUoKSB7CgkJdGVybWluYWwuZW1wbGFjZV9iYWNrKCk7CgkJc3VmLmVtcGxhY2VfYmFjaygpOwoJCWdvLmVtcGxhY2VfYmFjaygpOwoJCXN1cGVyLmVtcGxhY2VfYmFjaygpOwoJfQoJCgl2b2lkIGluc2VydChzdHJpbmcgJnMpIHsKCQlpbnQgcG9zID0gMDsKCQlmb3IgKGNoYXIgY2ggOiBzKSB7CgkJCWludCBjID0gY2ggLSAnYSc7CgkJCWlmIChnb1twb3NdW2NdID09IDApIHsKCQkJCWdvW3Bvc11bY10gPSBub2RlcysrOwoJCQkJYWRkX25vZGUoKTsKCQkJfQoJCQlwb3MgPSBnb1twb3NdW2NdOwoJCX0KCQl0ZXJtaW5hbFtwb3NdID0gdHJ1ZTsKCX0KCQoJdm9pZCBidWlsZCgpIHsKCQlxdWV1ZTxpbnQ+IFE7CgkJUS5lbXBsYWNlKDApOwoJCXdoaWxlIChub3QgUS5lbXB0eSgpKSB7CgkJCWludCB1ID0gUS5mcm9udCgpOyBRLnBvcCgpOwoJCQlzdXBlclt1XSA9IChzdWZbdV0gPT0gMCBvciB0ZXJtaW5hbFtzdWZbdV1dID8gc3VmW3VdIDogc3VwZXJbc3VmW3VdXSk7CgkJCWZvciAoaW50IGMgPSAwOyBjIDwgRTsgKytjKSB7CgkJCQlpZiAoZ29bdV1bY10pIHsKCQkJCQlpbnQgdiA9IGdvW3VdW2NdOwoJCQkJCVEuZW1wbGFjZSh2KTsKCQkJCQlzdWZbdl0gPSB1ID09IDAgPyAwIDogZ29bc3VmW3VdXVtjXTsKCQkJCX0KCQkJCWVsc2UgewoJCQkJCWdvW3VdW2NdID0gdSA9PSAwID8gMCA6IGdvW3N1Zlt1XV1bY107CgkJCQl9CgkJCX0KCQl9Cgl9Cn07Cgp0ZW1wbGF0ZTxpbnQgRSA9IDI2Pgp2b2lkIG1hcmsoaW50IHUsIEFob0NvcmFzaWNrPEU+ICZBQykgewoJaWYgKHUgPT0gMCkgcmV0dXJuOwoJbWFyayhBQy5zdXBlclt1XSwgQUMpOwoJaWYgKEFDLnRlcm1pbmFsW3VdKSB7CgkJY291dCA8PCAiRWwgbm9kbyAiIDw8IHUgPDwgIiBvY3VycmUgY29tbyBzdWJjYWRlbmEiIDw8IGVuZGw7CgkJQUMudGVybWluYWxbdV0gPSBmYWxzZTsKCX0KCUFDLnN1cGVyW3VdID0gMDsKfQoKaW50IG1haW4oKSB7CgljaW4udGllKDApIC0+IHN5bmNfd2l0aF9zdGRpbyhmYWxzZSk7CglBaG9Db3Jhc2ljazwyNj4gU29sdmVyOwoJdmVjdG9yPHN0cmluZz4gUyA9IHsiYXJjbyIsICJjbyIsICJiYXJjbyIsICJvcm8iLCAidG9ybyJ9OwoJZm9yIChzdHJpbmcgcyA6IFMpIHsKCQlTb2x2ZXIuaW5zZXJ0KHMpOwoJfQoJU29sdmVyLmJ1aWxkKCk7Cgljb25zdCBzdHJpbmcgVCA9ICJjb3JvcGFyY290b3JvIjsKCWludCBwID0gMDsKCWZvciAoY2hhciBjaCA6IFQpIHsKCQlpbnQgYyA9IGNoIC0gJ2EnOwoJCXAgPSBTb2x2ZXIuZ29bcF1bY107CgkJbWFyayhwLCBTb2x2ZXIpOwoJfQoJLyoKCWZvciAoaW50IGkgPSAoaW50KVNvbHZlci5ieV9sZXZlbC5zaXplKCkgLSAxOyBpID4gMDsgLS1pKSB7CgkJaW50IHggPSBTb2x2ZXIuYnlfbGV2ZWxbaV07CgkJU29sdmVyLmZyZXFbU29sdmVyLnN1Zlt4XV0gKz0gU29sdmVyLmZyZXFbeF07Cgl9Cglmb3IgKGludCBpID0gMDsgaSA8IFNvbHZlci5ub2RlczsgKytpKSB7CgkJY291dCA8PCAiRWwgbm9kbyAiIDw8IGkgPDwgIiBvY3VycmUgIiA8PCBTb2x2ZXIuZnJlcVtpXSA8PCAiIHZlY2VzIiA8PCBlbmRsOwoJfSovCglyZXR1cm4gMDsKfQ==