#include using namespace std; #define REP(i,a,b) for (int i = (a); i <= (b); ++i) #define FOR(i,n) REP(i,0,int(n)-1) #define mp make_pair #define pb push_back #define pii pair #define vi vector #define SZ(x) int((x).size()) #define FOREACH(i,t) for (auto i = t.begin(); i != t.end(); ++i) #define fi first #define se second struct node { node *son[26], *cache[26]; //int cnt; //map < char, node* > son, cache; node *lnk, *wo; int el; node () : el(-1) {} }; const int N = 3e5 + 7, INF = 1e9; vi len; node root; set < string > S; vector < int > D; vector < int > A[N]; int DP[N]; node* mv (node *w, int l) { node*& r = w->cache[l]; return r ? r : r = ((w->son[l] != nullptr) ? w->son[l] : w == &root ? w : mv(w->lnk, l)); } int addWord (const char *s) { int l = strlen(s); node *p = &root; for (; *s; ++s) { int letter = (int)(*s - 'a'); auto e = p->son[letter]; p = (e == nullptr) ? p->son[letter] = new node : e; } if (p->el == -1) { p->el = SZ(len); len.pb(l); } return p->el; } void calcLink () { vector < node* > l; node *w; root.lnk = root.wo = 0; for (int i = 0; i < 26; ++i) { if (root.son[i] == nullptr) continue; auto it = root.son[i]; l.pb(it); it->lnk = &root; } //FOREACH(it,root.son) { l.pb(it->se); it->se->lnk = &root; } FOR(x,SZ(l)) { l[x]->wo = (l[x]->lnk->el != -1) ? l[x]->lnk : l[x]->lnk->wo; for (int i = 0; i < 26; ++i) { if (l[x]->son[i] == nullptr) continue; auto it = l[x]->son[i]; l.pb(it); w = l[x]->lnk; w = mv(w, i); it->lnk = w; } } } vector < pii > searchAll (const char *s) { vector < pii > ans; node *p = &root, *r; for (int x = 0; s[x]; ++x) { int letter = (int)(s[x] - 'a'); p = mv(p, letter); for (r = p; r; r = r->wo) if (r->el != -1) ans.pb(mp(x - len[r->el] + 1, r->el)); } return ans; } int main () { ios_base::sync_with_stdio(false); int n; string text; cin >> n >> text; string s; for (int i = 0; i < n; ++i) { cin >> s; if (S.find(s) == S.end()) { S.insert(s); D.push_back(s.size()); auto sstr = s.c_str(); addWord(sstr); } } calcLink(); vector < pii > ans = searchAll(text.c_str()); for (int i = 0; i < ans.size(); ++i) A[ans[i].fi].push_back(D[ans[i].se]); //printf("%d %d\n", ans[i].fi, ans[i].se); int maxi = -1; for (auto d : A[0]) maxi = max(maxi, d); if (maxi == -1) { cout << "-1"; return 0; } int it = 1, result = 1; while (true) { if (maxi == text.size()) break; int nMaxi = -1; while (it <= maxi) { for (auto d : A[it]) nMaxi = max(nMaxi, it + d); ++it; } if (nMaxi == -1) break; ++result; maxi = nMaxi; } if (maxi < text.size()) cout << "-1"; else cout << result; return 0; }