#include using namespace std; typedef long long ll; typedef vector vi; #define fst first #define snd second #define pb push_back const int maxn = 4e5; int L; typedef pair Pll; const ll b1 = 61; const ll b2 = 67; const ll p1 = 1e9 + 7; const ll p2 = p1 + 2; Pll dodaj_char(char c, Pll x) { ll val = c - 'a' + 1; x.fst = (x.fst * b1 + val) % p1; x.snd = (x.snd * b2 + val) % p2; return x; } Pll operator-(Pll lhs, Pll rhs) { lhs.fst -= rhs.fst; if(lhs.fst < 0) lhs.fst += p1; lhs.snd -= rhs.snd; if(lhs.snd < 0) lhs.snd += p2; return lhs; } ll B1[maxn]; ll B2[maxn]; Pll przesuj(int val, Pll x) { return {x.fst * B1[val] % p1, x.snd * B2[val] % p2}; } Pll H[maxn]; char buff[maxn]; char A[maxn]; set Dost[maxn]; vi vdost; int wynik[maxn]; struct Tree { vi V; int d; Tree(int x) { d = 1; while(d <= x) d *= 2; V.assign(2*d, 1000000000); } void add(int x, int pos) { pos += d; V[pos] = x; pos /= 2; while(pos != 0) { V[pos] = min(V[2*pos + 1], V[2 * pos]); pos /= 2; } } int query(int a, int b) { a += d; b += d; int res = min(V[a], V[b]); while(a / 2 != b / 2) { if((a & 1) == 0) res = min(res, V[a+1]); if((b & 1) != 0) res = min(res, V[b-1]); a /= 2; b /= 2; } return res; } }; int main() { scanf("%d", &L); scanf("%s", A); int len = strlen(A); B1[0] = B2[0] = 1; for(int i = 1; i <= len; ++i) { B1[i] = B1[i-1] * b1 % p1; B2[i] = B2[i-1] * b2 % p2; } for(int i = len - 1; i >= 0; --i) { H[i] = dodaj_char(A[i], H[i+1]); } set pom; for(int i = 0; i < L; ++i) { scanf("%s", buff); Pll res(0,0); int l2 = strlen(buff); pom.insert(l2); for(int j = l2-1; j >= 0; --j) { res = dodaj_char(buff[j], res); } Dost[l2].insert(res); } vdost = vi(pom.rbegin(), pom.rend()); Tree t(len+10); t.add(0,0); for(int i = 0; i < len; ++i) { for(int v : vdost) { if(i - v + 1 >= 0) { Pll hasz = H[i-v + 1] - przesuj(v, H[i+1]); if(Dost[v].count(hasz)) { //puts("TRAFIONY"); int res = t.query(i-v + 1, i); //printf("res = %d\n", res); t.add(res + 1, i+1); break; } } } } int r = t.query(len, len); if(r > 10000000) r = -1; printf("%d\n", r); }