1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #define MAXN 26 5 #define MOD 10330176681277348905LL 6 typedef unsigned long long LL; 7 using namespace std; 8 char str[MAXN]; 9 int size; 10 LL total, ans; 11 struct node { 12 int fail, next[MAXN]; 13 bool end; 14 void Init() { 15 end = false; 16 fail = 0; 17 memset(next, 0, sizeof(next)); 18 } 19 }; 20 struct Matrix { 21 LL mat[MAXN][MAXN]; 22 void Zero() { 23 memset(mat, 0, sizeof(mat)); 24 } 25 void Unit() { 26 int i; 27 for (i = 0; i <= size; i++) 28 mat[i][i] = 1; 29 } 30 }; 31 Matrix a, b; 32 node tree[MAXN]; 33 Matrix operator +(const Matrix &a, const Matrix &b) { 34 int i, j; 35 Matrix temp; 36 temp.Zero(); 37 for (i = 0; i <= size; i++) { 38 for (j = 0; j <= size; j++) 39 temp.mat[i][j] = a.mat[i][j] + b.mat[i][j]; 40 } 41 return temp; 42 } 43 Matrix operator *(const Matrix &a, const Matrix &b) { 44 int i, j, k; 45 Matrix temp; 46 temp.Zero(); 47 for (i = 0; i <= size; i++) { 48 for (j = 0; j <= size; j++) { 49 for (k = 0; k <= size; k++) 50 temp.mat[i][j] += a.mat[i][k] * b.mat[k][j]; 51 } 52 } 53 return temp; 54 } 55 Matrix operator ^(Matrix x, int k) { 56 Matrix temp; 57 temp.Zero(); 58 temp.Unit(); 59 for (; k; k >>= 1) { 60 if (k & 1) 61 temp = temp * x; 62 x = x * x; 63 } 64 return temp; 65 } 66 inline int GET(char ch) { 67 return ch - 'a'; 68 } 69 void Insert(char *s) { 70 int now, t; 71 for (now = 0; *s; s++) { 72 t = GET(*s); 73 if (!tree[now].next[t]) { 74 tree[++size].Init(); 75 tree[now].next[t] = size; 76 } 77 now = tree[now].next[t]; 78 } 79 tree[now].end = true; 80 } 81 void BFS() { 82 int now, i, p; 83 queue<int> q; 84 q.push(0); 85 while (!q.empty()) { 86 now = q.front(); 87 q.pop(); 88 for (i = 0; i < MAXN; i++) { 89 if (tree[now].next[i]) { 90 p = tree[now].next[i]; 91 if (now) 92 tree[p].fail = tree[tree[now].fail].next[i]; 93 tree[p].end |= tree[tree[p].fail].end; 94 q.push(p); 95 } else 96 tree[now].next[i] = tree[tree[now].fail].next[i]; 97 } 98 } 99 } 100 void GetTotal(int k) { 101 LL temp; 102 total = 1; 103 for (temp = 26; k; k >>= 1) { 104 if (k & 1) 105 total *= temp; 106 temp *= temp; 107 } 108 total = 26 * (total - 1) * MOD; 109 } 110 void Build() { 111 int i, j, p; 112 a.Zero(); 113 for (i = 0; i <= size; i++) { 114 if (!tree[i].end) { 115 for (j = 0; j < MAXN; j++) { 116 p = tree[i].next[j]; 117 if (p) { 118 if (!tree[p].end) 119 a.mat[i][p]++; 120 } else 121 a.mat[i][0]++; 122 } 123 } 124 } 125 } 126 Matrix DFS(int k) { 127 if (k == 1) 128 return a; 129 if (k & 1) 130 return DFS(k - 1) + (a ^ k); 131 else { 132 Matrix temp = DFS(k >> 1); 133 return temp + ((a ^ (k >> 1)) * temp); 134 } 135 } 136 int main() { 137 int n, m, i; 138 while (~scanf("%d%d", &n, &m)) { 139 GetTotal(m); 140 tree[0].Init(); 141 for (i = size = 0; i < n; i++) { 142 scanf(" %s", str); 143 Insert(str); 144 } 145 BFS(); 146 Build(); 147 b = DFS(m); 148 for (ans = i = 0; i <= size; i++) 149 ans += b.mat[0][i]; 150 printf("%I64u\n", total - ans); 151 } 152 return 0; 153 }