#include using namespace std; typedef long long ll; const ll MOD = 1000000007; ll fact[200001]; ll gcd(ll a, ll b, ll &s, ll &t) { // a*s+b*t = g if (b==0) { t = 0; s = (a < 0) ? -1 : 1; return (a < 0) ? -a : a; } else { ll g = gcd(b, a%b, t, s); t -= a/b*s; return g; } } ll perm(int n, int r) { if (n == 0) return 1; ll s, t; gcd(fact[n-r], MOD, s, t); ll ans = (fact[n]*s) % MOD; if (ans < 0) ans += MOD; return ans; } struct trie_node { int next[26]; int index; trie_node() { fill(next, next+26, -1); index = -1; } }; int trie_n = 1; trie_node trie[1000000]; void trie_insert(string s, int index) { int root = 0; for (int i = 0; i < (int)s.length(); i++) { int next = trie[root].next[s[i]-'a']; if (next == -1) { next = trie[root].next[s[i]-'a'] = trie_n++; } root = next; } trie[root].index = index; } class FenwickTree{ // All entries must be >= 0 even after decrement public: // Every function is O(log n) FenwickTree(int n) : N(n), iBM(1), tree(n,0) { while (iBM < N) iBM *= 2; } // inc/dec the entry at position idx by val void incEntry(int idx, int val) { do tree[idx] += val; while(idx && (idx += (idx & (-idx))) < N); } // return the cumulative sum val[0] + val[1] + ... + val[idx] int cumulativeSum(int idx) const { int sum = tree[0]; for( ; idx > 0 ; idx &= idx-1) sum += tree[idx]; return sum; } // return the entry indexed by idx int getEntry(int idx) const { int val = tree[idx], par = idx & (idx-1); if (idx--) for( ; par != idx ; idx &= idx-1) val -= tree[idx]; return val; } // return the largest index such that the cumulative frequency is // what is given, or -1 if it is not found int getIndex(int sum) const { if ((sum -= tree[0]) < 0) return -1; int idx = 0; for(int bM = iBM ; bM != 0 && idx < N-1 ; bM >>= 1) if (sum >= tree[idx+bM]) sum -= tree[idx += bM]; return (sum != 0) ? -1 : min(N-1,idx); } private: int N, iBM; vector tree; }; int main() { int n, k; cin >> n >> k; fact[0] = 1; for (int i = 1; i <= n; i++) { fact[i] = (fact[i-1]*i) % MOD; } vector v(n); for (int i = 0; i < n; i++) { cin >> v[i]; } sort(v.begin(), v.end()); for (int i = 0; i < n; i++) { trie_insert(v[i], i); } string s; cin >> s; vector A; int node = 0; for (int i = 0; i < (int)s.length(); i++) { node = trie[node].next[s[i]-'a']; if (trie[node].index != -1) { A.push_back(trie[node].index); node = 0; } } FenwickTree ft(n); for (int i = 0; i < n; i++) { ft.incEntry(i, 1); } ll ans = 1; for (int i = 0; i < k; i++) { ans += (ft.cumulativeSum(A[i])-1) * perm(n-i-1, k-i-1) % MOD; ans %= MOD; ft.incEntry(A[i], -1); } cout << ans << endl; return 0; }