namespace ac { structTrie { int nxt[26], w, f; voidinit(){ fill(nxt, nxt + 26, -1); w = f = 0; } } L[N]; int sz;
voidinit() { sz = 0; L[sz++].init(); } inlineintnewnode() { L[sz].init(); return sz++; } voidins(char s[], int len) { int u = 0; for (int i = 0; i < len; ++i) { int v = s[i] - 'a'; if(L[u].nxt[v] == -1) L[u].nxt[v] = newnode(); u = L[u].nxt[v]; } L[u].w = 1; } voidbuild() { queue<int>Q; L[0].f = 0; for (int i = 0; i < 26; ++i) { int &v = L[0].nxt[i]; if(~v) { Q.push(v); L[v].f = 0; } else v = 0; } while (!Q.empty()) { int u = Q.front(); Q.pop(); int uf = L[u].f; L[u].w += L[uf].w; for (int i = 0; i < 26; ++i) { int &v = L[u].nxt[i]; if(~v) { Q.push(v); L[v].f = L[uf].nxt[i]; } else v = L[uf].nxt[i]; } } } } structMat { LL A[N][N]; voidzero(){ for (registerint i = 0; i < N; ++i) for (registerint j = 0; j < N; ++j) A[i][j] = -0x3f3f3f3f3f3f3f3f; } friend Mat operator *(const Mat &a, const Mat &b) { Mat ret; ret.zero(); for (registerint i = 0; i < N; ++i) { for (registerint k = 0; k < N; ++k) { for (registerint j = 0; j < N; ++j) { ret.A[i][j] = max(ret.A[i][j], a.A[i][k] + b.A[k][j]); } } } return ret; } friend Mat operator ^(Mat a, LL b) { Mat ret = a; --b; while (b) { if(b & 1) ret = ret * a; a = a * a; b >>= 1; } return ret; } } A; intmain(void) { registerint n, i, k; LL m; scanf("%d%lld", &n, &m); ac::init(); for (i = 0; i < n; ++i) { scanf("%s", s); ac::ins(s, strlen(s)); } ac::build(); A.zero(); for (i = 0; i < ac::sz; ++i) { for (k = 0; k < 26; ++k) { int v = ac::L[i].nxt[k]; A.A[i][v] = ac::L[v].w; } } A = A ^ m; LL ans = 0; for (int i = 0; i < ac::sz; ++i) ans = max(ans, A.A[0][i]); printf("%lld\n", ans); return0; }