int n, m; char s[30]; int ch[10005][30], fail[10005], val[10005], tot; int dp[1005][1005]; bool tag[100005];
inlinevoidinsert(char *str, int l){ int x = 0; for (int i = 1; i <= l; i++) { if (!ch[x][str[i] - 'A']) { ch[x][str[i] - 'A'] = ++tot; } x = ch[x][str[i] - 'A']; } tag[x] = 1; }
queue<int> q;
inlinevoidgetfail(){ for (int i = 0; i < 26; i++) if (ch[0][i]) q.push(ch[0][i]); while (!q.empty()) { int x = q.front(); q.pop(); for (int i = 0; i < 26; i++) { if (ch[x][i]) fail[ch[x][i]] = ch[fail[x]][i], q.push(ch[x][i]); else ch[x][i] = ch[fail[x]][i]; } } }
inlinevoidcalc(){ for (int i = 0; i <= tot; i++) { for (int j = i; j; j = fail[j]) { if (tag[j]) val[i]++; } } }
inlinevoidDP(){ memset(dp, -1, sizeof(dp)); dp[0][0] = 0; for (int i = 0; i < m; i++) { for (int j = 0; j <= tot; j++) { if (dp[i][j] == -1) continue; for (int k = 0; k < 26; k++) { dp[i+1][ch[j][k]] = max(dp[i+1][ch[j][k]], dp[i][j] + val[ch[j][k]]); } } } }
intmain(){ scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { scanf("%s", s+1); insert(s, strlen(s+1)); } getfail(); calc(); DP(); int ans = 0; for (int i = 0; i <= tot; i++) { ans = max(ans, dp[m][i]); } printf("%d\n", ans); return0; }