// ﷽
// Contest: string (medium)
//
// Judge: Codeforces
// URL: https://c...content-available-to-author-only...s.com/group/o09Gu2FpOx/contest/559867/problem/C
// Memory Limit: 512
// Time Limit: 10000
// Start: Thu 08 May 2025 12:25:56 AM EEST
#include <bits/stdc++.h>
#ifdef ALGOAT
#include "debug.hpp"
#else
#define debug(...) 0
#define debug_itr(...) 0
#define debug_bits(...) 0
#endif
// 48-57 -> 0-9 65-90 -> A-Z 97-122 -> a-z
#define fastio() \
ios_base::sync_with_stdio(false); \
cin.tie(NULL);
#define int long long
#define F first
#define S second
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define rep(i, a, b) for (int i = (a); i < (b); ++i)
#define sz(x) (int)(x).size()
#define vi vector<int>
/*template <class T> using rpq = priority_queue<T, vector<T>, greater<T>>;*/
const int dx[8] = {1, 0, -1, 0, 1, 1, -1, -1},
dy[8] = {0, 1, 0, -1, -1, 1, -1, 1};
using namespace std;
constexpr int H = 2;
typedef array<long long, H> val;
vector<val> B;
const val M = {
1000000007, 1444444447,
// 998244353,
// 1000000009,
};
val tmp;
val operator*(const val &a, const val &b) {
for (int i = 0; i < H; i++)
tmp[i] = a[i] * b[i] % M[i];
return tmp;
}
val operator-(const val &a, const val &b) {
for (int i = 0; i < H; i++)
tmp[i] = (a[i] - b[i] + M[i]) % M[i];
return tmp;
}
val operator+(const val &a, const val &b) {
for (int i = 0; i < H; i++)
tmp[i] = (a[i] + b[i]) % M[i];
return tmp;
}
val getval(int x) {
for (int i = 0; i < H; i++)
tmp[i] = x % M[i];
return tmp;
}
void setB(int n) {
if (B.size() == 0) {
mt19937 rng(random_device{}());
B.assign(2, getval(1));
for (int i = 0; i < H; i++)
B.back()[i] = uniform_int_distribution<int>(1, M[i] - 1)(rng);
}
while ((int)B.size() <= n)
B.push_back(B.back() * B[1]);
}
struct Hash {
vector<val> h;
Hash(const string &s) : Hash(vector<int>(s.begin(), s.end())) {}
Hash(const vector<int> &s) {
vector<val> v;
for (auto x : s)
v.push_back(getval(x));
*this = Hash(v);
}
Hash(const vector<val> &s) : h(s.size() + 1) {
setB(s.size());
for (int i = 0; i < (int)s.size(); i++)
h[i + 1] = h[i] * B[1] + s[i];
}
val get(int l, int r) { return h[r + 1] - h[l] * B[r - l + 1]; }
};
struct ValHash {
size_t operator()(const val &v) const {
size_t h = 0;
for (int i = 0; i < H; ++i) {
h ^= std::hash<long long>()(v[i]) + 0x9e3779b9 + (h << 6) + (h >> 2);
}
return h;
}
};
void solve() {
int q;
cin >> q;
vector<string> words(q);
for (auto &w : words)
cin >> w;
unordered_map<int, unordered_set<val, ValHash>> dict;
set<int> word_lengths;
for (const auto &w : words) {
int len = w.size();
word_lengths.insert(len);
dict[len].insert(Hash(w).get(0, len - 1));
}
string s;
cin >> s;
int n = s.size();
Hash hs(s);
const int INF = INT_MAX / 2;
vector<int> dp(n + 2, INF);
dp[n + 1] = 0;
for (int i = n; i >= 1; --i) {
for (int len : word_lengths) {
if (i + len - 1 > n)
break;
val h = hs.get(i - 1, i + len - 2);
if (dict[len].count(h)) {
dp[i] = min(dp[i], dp[i + len] + 1);
}
}
}
cout << (dp[1] >= INF ? -1 : dp[1]) << "\n";
}
int32_t main() {
/*freopen("whereami.in", "r", stdin);*/
/*freopen("whereami.out", "w", stdout);*/
fastio();
int n = 1;
#ifdef MUTLI_CASE
cin >> n;
#endif
while (n--)
solve();
return 0;
}
Ly8g77e9Ci8vIENvbnRlc3Q6IHN0cmluZyAobWVkaXVtKQovLwovLyBKdWRnZTogQ29kZWZvcmNlcwovLyBVUkw6IGh0dHBzOi8vYy4uLmNvbnRlbnQtYXZhaWxhYmxlLXRvLWF1dGhvci1vbmx5Li4ucy5jb20vZ3JvdXAvbzA5R3UyRnBPeC9jb250ZXN0LzU1OTg2Ny9wcm9ibGVtL0MKLy8gTWVtb3J5IExpbWl0OiA1MTIKLy8gVGltZSBMaW1pdDogMTAwMDAKLy8gU3RhcnQ6IFRodSAwOCBNYXkgMjAyNSAxMjoyNTo1NiBBTSBFRVNUCiNpbmNsdWRlIDxiaXRzL3N0ZGMrKy5oPgoKI2lmZGVmIEFMR09BVAojaW5jbHVkZSAiZGVidWcuaHBwIgojZWxzZQojZGVmaW5lIGRlYnVnKC4uLikgMAojZGVmaW5lIGRlYnVnX2l0ciguLi4pIDAKI2RlZmluZSBkZWJ1Z19iaXRzKC4uLikgMAojZW5kaWYKCi8vIDQ4LTU3IC0+IDAtOSAgNjUtOTAgLT4gQS1aIDk3LTEyMiAtPiBhLXoKI2RlZmluZSBmYXN0aW8oKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICBpb3NfYmFzZTo6c3luY193aXRoX3N0ZGlvKGZhbHNlKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICBjaW4udGllKE5VTEwpOwoKI2RlZmluZSBpbnQgbG9uZyBsb25nCiNkZWZpbmUgRiBmaXJzdAojZGVmaW5lIFMgc2Vjb25kCiNkZWZpbmUgYWxsKGEpIChhKS5iZWdpbigpLCAoYSkuZW5kKCkKI2RlZmluZSByYWxsKGEpIChhKS5yYmVnaW4oKSwgKGEpLnJlbmQoKQojZGVmaW5lIHJlcChpLCBhLCBiKSBmb3IgKGludCBpID0gKGEpOyBpIDwgKGIpOyArK2kpCiNkZWZpbmUgc3ooeCkgKGludCkoeCkuc2l6ZSgpCiNkZWZpbmUgdmkgdmVjdG9yPGludD4KCi8qdGVtcGxhdGUgPGNsYXNzIFQ+IHVzaW5nIHJwcSA9IHByaW9yaXR5X3F1ZXVlPFQsIHZlY3RvcjxUPiwgZ3JlYXRlcjxUPj47Ki8KCmNvbnN0IGludCBkeFs4XSA9IHsxLCAwLCAtMSwgMCwgMSwgMSwgLTEsIC0xfSwKICAgICAgICAgIGR5WzhdID0gezAsIDEsIDAsIC0xLCAtMSwgMSwgLTEsIDF9OwoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKY29uc3RleHByIGludCBIID0gMjsKdHlwZWRlZiBhcnJheTxsb25nIGxvbmcsIEg+IHZhbDsKdmVjdG9yPHZhbD4gQjsKY29uc3QgdmFsIE0gPSB7CiAgICAxMDAwMDAwMDA3LCAxNDQ0NDQ0NDQ3LAogICAgLy8gOTk4MjQ0MzUzLAogICAgLy8gMTAwMDAwMDAwOSwKfTsKCnZhbCB0bXA7Cgp2YWwgb3BlcmF0b3IqKGNvbnN0IHZhbCAmYSwgY29uc3QgdmFsICZiKSB7CiAgZm9yIChpbnQgaSA9IDA7IGkgPCBIOyBpKyspCiAgICB0bXBbaV0gPSBhW2ldICogYltpXSAlIE1baV07CiAgcmV0dXJuIHRtcDsKfQoKdmFsIG9wZXJhdG9yLShjb25zdCB2YWwgJmEsIGNvbnN0IHZhbCAmYikgewogIGZvciAoaW50IGkgPSAwOyBpIDwgSDsgaSsrKQogICAgdG1wW2ldID0gKGFbaV0gLSBiW2ldICsgTVtpXSkgJSBNW2ldOwogIHJldHVybiB0bXA7Cn0KCnZhbCBvcGVyYXRvcisoY29uc3QgdmFsICZhLCBjb25zdCB2YWwgJmIpIHsKICBmb3IgKGludCBpID0gMDsgaSA8IEg7IGkrKykKICAgIHRtcFtpXSA9IChhW2ldICsgYltpXSkgJSBNW2ldOwogIHJldHVybiB0bXA7Cn0KCnZhbCBnZXR2YWwoaW50IHgpIHsKICBmb3IgKGludCBpID0gMDsgaSA8IEg7IGkrKykKICAgIHRtcFtpXSA9IHggJSBNW2ldOwogIHJldHVybiB0bXA7Cn0KCnZvaWQgc2V0QihpbnQgbikgewogIGlmIChCLnNpemUoKSA9PSAwKSB7CiAgICBtdDE5OTM3IHJuZyhyYW5kb21fZGV2aWNle30oKSk7CiAgICBCLmFzc2lnbigyLCBnZXR2YWwoMSkpOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBIOyBpKyspCiAgICAgIEIuYmFjaygpW2ldID0gdW5pZm9ybV9pbnRfZGlzdHJpYnV0aW9uPGludD4oMSwgTVtpXSAtIDEpKHJuZyk7CiAgfQogIHdoaWxlICgoaW50KUIuc2l6ZSgpIDw9IG4pCiAgICBCLnB1c2hfYmFjayhCLmJhY2soKSAqIEJbMV0pOwp9CgpzdHJ1Y3QgSGFzaCB7CiAgdmVjdG9yPHZhbD4gaDsKCiAgSGFzaChjb25zdCBzdHJpbmcgJnMpIDogSGFzaCh2ZWN0b3I8aW50PihzLmJlZ2luKCksIHMuZW5kKCkpKSB7fQoKICBIYXNoKGNvbnN0IHZlY3RvcjxpbnQ+ICZzKSB7CiAgICB2ZWN0b3I8dmFsPiB2OwogICAgZm9yIChhdXRvIHggOiBzKQogICAgICB2LnB1c2hfYmFjayhnZXR2YWwoeCkpOwogICAgKnRoaXMgPSBIYXNoKHYpOwogIH0KCiAgSGFzaChjb25zdCB2ZWN0b3I8dmFsPiAmcykgOiBoKHMuc2l6ZSgpICsgMSkgewogICAgc2V0QihzLnNpemUoKSk7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IChpbnQpcy5zaXplKCk7IGkrKykKICAgICAgaFtpICsgMV0gPSBoW2ldICogQlsxXSArIHNbaV07CiAgfQoKICB2YWwgZ2V0KGludCBsLCBpbnQgcikgeyByZXR1cm4gaFtyICsgMV0gLSBoW2xdICogQltyIC0gbCArIDFdOyB9Cn07CnN0cnVjdCBWYWxIYXNoIHsKICBzaXplX3Qgb3BlcmF0b3IoKShjb25zdCB2YWwgJnYpIGNvbnN0IHsKICAgIHNpemVfdCBoID0gMDsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgSDsgKytpKSB7CiAgICAgIGggXj0gc3RkOjpoYXNoPGxvbmcgbG9uZz4oKSh2W2ldKSArIDB4OWUzNzc5YjkgKyAoaCA8PCA2KSArIChoID4+IDIpOwogICAgfQogICAgcmV0dXJuIGg7CiAgfQp9OwoKdm9pZCBzb2x2ZSgpIHsKICBpbnQgcTsKICBjaW4gPj4gcTsKICB2ZWN0b3I8c3RyaW5nPiB3b3JkcyhxKTsKICBmb3IgKGF1dG8gJncgOiB3b3JkcykKICAgIGNpbiA+PiB3OwoKICB1bm9yZGVyZWRfbWFwPGludCwgdW5vcmRlcmVkX3NldDx2YWwsIFZhbEhhc2g+PiBkaWN0OwogIHNldDxpbnQ+IHdvcmRfbGVuZ3RoczsKICBmb3IgKGNvbnN0IGF1dG8gJncgOiB3b3JkcykgewogICAgaW50IGxlbiA9IHcuc2l6ZSgpOwogICAgd29yZF9sZW5ndGhzLmluc2VydChsZW4pOwogICAgZGljdFtsZW5dLmluc2VydChIYXNoKHcpLmdldCgwLCBsZW4gLSAxKSk7CiAgfQoKICBzdHJpbmcgczsKICBjaW4gPj4gczsKICBpbnQgbiA9IHMuc2l6ZSgpOwogIEhhc2ggaHMocyk7CgogIGNvbnN0IGludCBJTkYgPSBJTlRfTUFYIC8gMjsKICB2ZWN0b3I8aW50PiBkcChuICsgMiwgSU5GKTsKICBkcFtuICsgMV0gPSAwOwoKICBmb3IgKGludCBpID0gbjsgaSA+PSAxOyAtLWkpIHsKICAgIGZvciAoaW50IGxlbiA6IHdvcmRfbGVuZ3RocykgewogICAgICBpZiAoaSArIGxlbiAtIDEgPiBuKQogICAgICAgIGJyZWFrOwogICAgICB2YWwgaCA9IGhzLmdldChpIC0gMSwgaSArIGxlbiAtIDIpOwogICAgICBpZiAoZGljdFtsZW5dLmNvdW50KGgpKSB7CiAgICAgICAgZHBbaV0gPSBtaW4oZHBbaV0sIGRwW2kgKyBsZW5dICsgMSk7CiAgICAgIH0KICAgIH0KICB9CgogIGNvdXQgPDwgKGRwWzFdID49IElORiA/IC0xIDogZHBbMV0pIDw8ICJcbiI7Cn0KCmludDMyX3QgbWFpbigpIHsKICAvKmZyZW9wZW4oIndoZXJlYW1pLmluIiwgInIiLCBzdGRpbik7Ki8KICAvKmZyZW9wZW4oIndoZXJlYW1pLm91dCIsICJ3Iiwgc3Rkb3V0KTsqLwogIGZhc3RpbygpOwogIGludCBuID0gMTsKCiNpZmRlZiBNVVRMSV9DQVNFCiAgY2luID4+IG47CiNlbmRpZgogIHdoaWxlIChuLS0pCiAgICBzb2x2ZSgpOwogIHJldHVybiAwOwp9