#include using namespace std; #define FOR(a, b, c) for(int a = (b); a < (c); a++) #define SZ(a) (int)((a).size()) #define SIZE(a) (int)((a).size()) #define ALL(a) (a).begin(), (a).end() using ll = long long; #define LL long long #define PB push_back template void _debug(const char* s, T x) { cerr << s << "=" << x << "\n"; } template void _debug(const char* s, T x, args... a) { while(*s != ',') cerr << *s++; cerr << "=" << x << ","; _debug(s + 1, a...); } template ostream& operator<< (ostream& os, vector& vec) { for(auto& v : vec) os << v << " "; return os; } #if 0 #define debug(...) _debug(#__VA_ARGS__, __VA_ARGS__) #define cerr cout #else #define debug(...) 1999 #define cerr if(0) cout #endif bitset<27> ban; int nr = 0; struct Aho { struct Vertex { int next[27]; int leaf = 0, count = -1; int p = -1; char pch; int link = -1; int go[27]; int numer = -1; Vertex(int p = -1, char ch = '$') : p(p), pch(ch) { fill(next, next + 27, -1); fill(go, go + 27, -1); } }; vector t; Aho() { t.push_back(Vertex()); } void numeruj(int v) { debug(v, t[v].leaf); if(t[v].leaf > 0) { return; } if(t[v].numer == -1) { t[v].numer = nr++; FOR(d, 0, 27) { if(t[v].next[d] != -1) { numeruj(t[v].next[d]); } } } } void add_string(string s) { int v = 0; for(char ch : s) { int c = ch - 'a'; if(t[v].next[c] == -1) { t[v].next[c] = t.size(); t.emplace_back(v, ch); } v = t[v].next[c]; } t[v].leaf++; } int calc(int v) { if(v == 0) return 0; if(t[v].count == -1) { t[v].count = t[v].leaf + calc(get_link(v)); } return t[v].count; } void calc() { t[0].count = 0; FOR(v, 1, SZ(t)) { calc(v); } } int get_link(int v) { if(t[v].link == -1) { if(v == 0 or t[v].p == 0) { t[v].link = 0; } else { t[v].link = go(get_link(t[v].p), t[v].pch); } } return t[v].link; } int go(int v, char ch) { debug(v, ch); int c = ch - 'a'; if(t[v].go[c] == -1) { if(t[v].next[c] != -1) { t[v].go[c] = t[v].next[c]; } else { t[v].go[c] = v == 0 ? 0 : go(get_link(v), ch); } } return t[v].go[c]; } }; const int MOD = 1e9 + 7; using T = long long; T add(T a, T b) { return (a + b) % MOD; } T mul(T a, T b) { return (a * b) % MOD; } struct Matrix { vector> a; int n, m; Matrix() {} Matrix(int n, int m) : n(n), m(m) { a.resize(n, vector(m, 0)); } Matrix operator+(const Matrix& o) { Matrix res(n, m); FOR(i, 0, n) { FOR(j, 0, m) { res.a[i][j] = add(a[i][j], o.a[i][j]); } } return res; } Matrix operator*(const Matrix& o) { Matrix res(n, o.m); FOR(i, 0, n) FOR(k, 0, o.m) FOR(j, 0, m) { res.a[i][k] = add(res.a[i][k], mul(a[i][j], o.a[j][k])); } return res; } Matrix operator^(ll k) { Matrix res(n, n), a{*this}; FOR(i, 0, n) res.a[i][i] = 1; for(; k ; k /= 2) { if(k & 1) res = res * a; a = a * a; } return res; } }; Aho ahoj; set zle; void cusiek(Matrix& mat, int v, int st) { auto& node = ahoj.t[v]; debug(v, st, node.numer); FOR(d, 0, 27) { int u = node.next[d]; if(u != -1) debug("G", v, u); if(u != -1 and ahoj.t[u].numer != -1 and not zle.count(d)) { mat.a[st][ahoj.t[u].numer]++; } else if(u != -1 and ahoj.t[u].numer == -1 and not zle.count(d)) { mat.a[st][0]--; zle.insert(d); } } if(node.link != -1) { cusiek(mat, node.link, st); } } int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); int n, q; cin >> n >> q; vector slowa; while(q--) { int d; string s; cin >> d >> s; slowa.PB(s); if(d == 1) { ban[s[0] - 'a'] = 1; } } FOR(i, 0, SZ(slowa)) { for(auto& j : slowa[i]) { if(ban[j - 'a']) { slowa.erase(slowa.begin() + i); i--; break; } } } debug(slowa); FOR(i, 0, SZ(slowa)) { FOR(j, 0, SZ(slowa)) if(i != j) { bool wyw = false; FOR(d, 0, SZ(slowa[j]) - SZ(slowa[i]) + 1) { if(slowa[i] == slowa[j].substr(d, SZ(slowa[i]))) { wyw = true; break; } } if(wyw) { slowa.erase(slowa.begin() + j); j--; } } } debug(slowa); for(auto& s : slowa) { debug("DOAJE"); ahoj.add_string(s); } ahoj.calc(); int alf = 26 - ban.count(); debug(alf); ahoj.numeruj(0); int roz = nr; debug(roz); Matrix mat(roz, roz); FOR(i, 0, SZ(ahoj.t)) { if(ahoj.t[i].numer != -1) { zle.clear(); cusiek(mat, i, ahoj.t[i].numer); } } FOR(i, 0, roz) { int temp = alf; FOR(j, 1, roz) { temp -= mat.a[i][j]; } debug(i, temp); mat.a[i][0] += temp; } FOR(i, 0, roz) { debug(mat.a[i]); } mat = mat ^ n; ll sum = 0; FOR(i, 0, roz) { sum += mat.a[0][i]; sum %= MOD; } cout << sum << "\n"; }