#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 { 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, char l) { node*& r = w->cache[l]; return r ? r : r = (w->son.count(l) ? 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) { auto e = p->son.find(*s); p = (e == p->son.end()) ? p->son[*s] = new node : e->se; } 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; 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; FOREACH(it,l[x]->son) { l.pb(it->se); w = l[x]->lnk; w = mv(w, it->fi); it->se->lnk = w; } } } vector < pii > searchAll (const char *s) { vector < pii > ans; node *p = &root, *r; for (int x = 0; s[x]; ++x) { p = mv(p, s[x]); 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()); addWord(s.c_str()); } } 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; }