#ifndef LOCAL #pragma GCC optimize("O3") #endif #include using namespace std; #define sim template muu & operator<<( #define ris return *this #define eni(r) sim> typename enable_if <1 r sizeof(dud(0)),muu&>::type operator<<(c g) { sim> struct rge {c b,e ;}; sim> rge range(c i, c j) {return rge{i, j};} sim> auto dud(c *r)-> decltype(cerr << *r); sim> char dud(...); struct muu { #ifdef LOCAL stringstream a; ~muu() {cerr << a.str() << endl;} eni(<) a << boolalpha << g; ris;} eni(==) ris << range(begin(g), end(g));} sim, class m mor pair r) {ris << "(" << r.first << ", " << r.second << ")";} sim mor rge u) { a << "["; for (c i = u.b; i != u.e; ++i) *this << ", " + 2 * (i == u.b) << *i; ris << "]"; } #else sim mor const c&) {ris;} #endif muu & operator()(){ris;} }; #define debug (muu() << __FUNCTION__ << "#" << __LINE__ << ": ") #define imie(r) "[" #r ": " << (r) << "] " #define imask(r) "[" #r ": " << bitset<8 * sizeof(r)>(r) << "] " #define arr(a, i) "[" #a imie(i) ": " << a[i] << "] " #define arr2(a, i, j) "[" #a imie(i) imie(j) ": " << a[i][j] << "] " const int nax = 3e5 + 11; unordered_set hashes[nax]; vector seen; char in[nax], curr[nax], rans[nax]; using ll = long long; ll pows[nax]; int jump[nax]; sim> void mini(c &a, c b) { if (a > b) a = b; } sim> void maxi(c &a, c b) { if (a < b) a = b; } const ll mod = 1e18 + 3, base = 12398173; int nn; ll mul(ll a, ll b) { return a * __int128(b) % mod; } void run(int len) { ll powe = pows[len]; ll hash = 0; for (int i = 0; i < len; ++i) hash = mul(hash, base) + rans[i]; hash %= mod; if (hashes[len].count(hash)) maxi(jump[0], len); for (int i = 0; i + len < nn; ++i) { hash = mul(hash, base) - mul(rans[i], powe) + rans[i + len]; hash %= mod; if (hash < 0) hash+=mod; if (hashes[len].count(hash)) maxi(jump[i + 1], i + len + 1); } } int main() { pows[0] = 1; for (int i = 1; i < nax; ++i) pows[i] = mul(pows[i - 1], base); int l; scanf("%d", &l); scanf("%s", rans); nn = strlen(rans); for (int i = 0; i < l; ++i) { scanf("%s", curr); int n = strlen(curr); ll hash = 0; for (int i = 0; i < n; ++i) hash = mul(hash, base) + curr[i]; hash %= mod; hashes[n].insert(hash); } for (int i = 0; i < nax; ++i) jump[i] = i; for (int i = 0; i < nax; ++i) if (hashes[i].size()) run(i); for (int i = 1; i <= nn; ++i) maxi(jump[i], jump[i - 1]); debug() << range(jump, jump + nn + 1); int where = 0; int ans = 0; while (where < nn) { int to = jump[where]; if (to == where) { ans = -1; break; } where = to; ans++; debug << imie(where); } printf("%d\n", ans); } /* * main#93: [2, 1, 2, 5, 4, 5] main#106: [where: 2] 2 abbab ab bbb */