#include<string>
#include<iostream>
#include<algorithm>
const int inf=0x7fffffff;
const int N=2000,K=2001;
std::string s[N];
int n,k,lcp[N];
int f[3][K],cnt;
void dp(const int &l,const int &r,const int &id) {
	if(l==r) return;
	int mid=0;
	for(register int i=l+1;i<=r;i++) {
		if(lcp[i]<lcp[mid]) mid=i;
	}
	const int lid=cnt++,rid=cnt++;
	dp(l,mid-1,lid);
	dp(mid,r,rid);
	for(register int i=0;i<=k;i++) {
		if(i>mid-l) break;
		for(register int j=0;j<=k;j++) {
			if(j>r-mid+1) break;
			if(i+j<=k) f[id][i+j]=std::max(f[id][i+j],f[lid][i]+f[rid][j]+lcp[mid]*i*j);
		}
	}
}
int main() {
	std::ios_base::sync_with_stdio(false);
	std::cin.tie(NULL);
	std::cin>>n>>k;
	for(register int i=0;i<n;i++) {
		std::cin>>s[i];
	}
	std::sort(&s[0],&s[n]);
	lcp[0]=inf;
	for(register int i=1;i<n;i++) {
		lcp[i]=std::min(s[i].length(),s[i-1].length());
		for(register int j=0;j<lcp[i];j++) {
			if(s[i][j]!=s[i-1][j]) {
				lcp[i]=j;
			}
		}
	}
	dp(0,n-1,cnt++);
	std::cout<<f[0][k]<<std::endl;
	return 0;
}


#include<string>
#include<iostream>
#include<algorithm>
const int inf=0x7fffffff;
const int N=2000,K=2001;
std::string s[N];
int n,k,lcp[N];
int f[N<<1][K],cnt;
void dp(const int &l,const int &r,const int &id) {
	if(l==r) return;
	int mid=0;
	for(register int i=l+1;i<=r;i++) {
		if(lcp[i]<lcp[mid]) mid=i;
	}
	const int lid=cnt++,rid=cnt++;
	dp(l,mid-1,lid);
	dp(mid,r,rid);
	__builtin_memset(f[id],0,sizeof f[id]);
	for(register int i=0;i<=k;i++) {
		if(i>mid-l) break;
		for(register int j=0;j<=k;j++) {
			if(j>r-mid+1) break;
			if(i+j<=k) f[id][i+j]=std::max(f[id][i+j],f[lid][i]+f[rid][j]+lcp[mid]*i*j);
		}
	}
	cnt-=2;
}
int main() {
	std::ios_base::sync_with_stdio(false);
	std::cin.tie(NULL);
	std::cin>>n>>k;
	for(register int i=0;i<n;i++) {
		std::cin>>s[i];
	}
	std::sort(&s[0],&s[n]);
	lcp[0]=inf;
	for(register int i=1;i<n;i++) {
		lcp[i]=std::min(s[i].length(),s[i-1].length());
		for(register int j=0;j<lcp[i];j++) {
			if(s[i][j]!=s[i-1][j]) {
				lcp[i]=j;
			}
		}
	}
	dp(0,n-1,cnt++);
	std::cout<<f[0][k]<<std::endl;
	return 0;
}


#include<string>
#include<iostream>
#include<algorithm>
const int inf=0x7fffffff;
const int N=2000,K=2001;
std::string s[N];
int lcp[N];
int dp(const int &l,const int &r,const int &k) {
	if(l>=r||!k||k==1) return 0;
	//printf("%d %d %d\n",l,r,k);
	int mid;
	for(register int i=l+1,min=inf;i<=r;i++) {
		if(lcp[i]<min) {
			min=lcp[i];
			mid=i;
		}
	}
	int ret=0;
	for(register int i=std::max(k-r+mid-1,0);i<=std::min(k,mid-l);i++) {
		ret=std::max(ret,dp(l,mid-1,i)+dp(mid,r,k-i)+lcp[mid]*i*(k-i));
	}
	//printf("%d %d %d %d\n",l,r,k,ret);
	return ret;
}
int main() {
	std::ios_base::sync_with_stdio(false);
	std::cin.tie(NULL);
	int n,k;
	std::cin>>n>>k;
	for(register int i=0;i<n;i++) {
		std::cin>>s[i];
	}
	std::sort(&s[0],&s[n]);
	for(register int i=1;i<n;i++) {
		lcp[i]=std::min(s[i].length(),s[i-1].length());
		for(register int j=0;j<lcp[i];j++) {
			if(s[i][j]!=s[i-1][j]) {
				lcp[i]=j;
			}
		}
		//std::cout<<s[i-1]<<' '<<s[i]<<' '<<lcp[i]<<std::endl;
	}
	std::cout<<dp(0,n-1,k)<<std::endl;
	return 0;
}


#include<string>
#include<iostream>
#include<algorithm>
const int inf=0x7fffffff;
const int N=2000,K=2001;
std::string s[N];
int lcp[N];
int dp(const int &l,const int &r,const int &k) {
	if(l>=r) return 0;
	int mid;
	for(register int i=l+1,min=inf;i<=r;i++) {
		if(lcp[i]<min) {
			min=lcp[i];
			mid=i;
		}
	}
	int ret=0;
	for(register int i=0;i<=std::min(mid-l,k);i++) {
		ret=std::max(ret,dp(l,mid-1,i)+dp(mid,r,k-i)+lcp[mid]*i*(k-i));
	}
	return ret;
}
int main() {
	std::ios_base::sync_with_stdio(false);
	std::cin.tie(NULL);
	int n,k;
	std::cin>>n>>k;
	for(register int i=0;i<n;i++) {
		std::cin>>s[i];
	}
	std::sort(&s[0],&s[n]);
	for(register int i=1;i<n;i++) {
		lcp[i]=std::min(s[i].length(),s[i-1].length())-1;
		while(s[i][lcp[i]]!=s[i-1][lcp[i]]) lcp[i]--;
		lcp[i]++;
	}
	std::cout<<dp(0,n-1,k)<<std::endl;
	return 0;
}


#include<string>
#include<iostream>
#include<algorithm>
const int inf=0x7fffffff;
const int N=2000,K=2001;
std::string s[N];
int lcp[N];
int dp(const int &l,const int &r,const int &k) {
	if(l>=r) return 0;
	int mid;
	for(register int i=l+1,min=inf;i<=r;i++) {
		if(lcp[i]<min) {
			min=lcp[i];
			mid=i;
		}
	}
	int ret=0;
	for(register int i=std::max(k-r+mid-1,0);i<=std::min(k,mid-l);i++) {
		ret=std::max(ret,dp(l,mid-1,i)+dp(mid,r,k-i)+lcp[mid]*i*(k-i));
	}
	//printf("%d %d %d %d\n",l,r,k,ret);
	return ret;
}
int main() {
	std::ios_base::sync_with_stdio(false);
	std::cin.tie(NULL);
	int n,k;
	std::cin>>n>>k;
	for(register int i=0;i<n;i++) {
		std::cin>>s[i];
	}
	std::sort(&s[0],&s[n]);
	for(register int i=1;i<n;i++) {
		lcp[i]=std::min(s[i].length(),s[i-1].length())-1;
		while(s[i][lcp[i]]!=s[i-1][lcp[i]]) lcp[i]--;
		lcp[i]++;
	}
	std::cout<<dp(0,n-1,k)<<std::endl;
	return 0;
}


#include<string>
#include<iostream>
#include<algorithm>
const int inf=0x7fffffff;
const int N=200,K=2001;
std::string s[N];
int lcp[N];
int f[N][N][K];
int dp(const int &l,const int &r,const int &k) {
	if(l>=r) return 0;
	if(f[l][r][k]) return f[l][r][k];
	int mid;
	for(register int i=l+1,min=inf;i<=r;i++) {
		if(lcp[i]<min) {
			min=lcp[i];
			mid=i;
		}
	}
	for(register int i=0;i<=std::min(mid-l,k);i++) {
		f[l][r][k]=std::max(f[l][r][k],dp(l,mid-1,i)+dp(mid,r,k-i)+lcp[mid]*i*(k-i));
	}
	return f[l][r][k];
}
int main() {
	std::ios_base::sync_with_stdio(false);
	std::cin.tie(NULL);
	int n,k;
	std::cin>>n>>k;
	for(register int i=0;i<n;i++) {
		std::cin>>s[i];
	}
	std::sort(&s[0],&s[n]);
	for(register int i=1;i<n;i++) {
		lcp[i]=std::min(s[i].length(),s[i-1].length())-1;
		while(s[i][lcp[i]]!=s[i-1][lcp[i]]) lcp[i]--;
		lcp[i]++;
	}
	std::cout<<dp(0,n-1,k)<<std::endl;
	return 0;
}


#define _CRT_SECURE_NO_DEPRECATE
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <iostream>
#include <iterator>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <sstream>
#include <fstream>
#include <ctime>
#include <cstring>
#pragma comment(linker, "/STACK:66777216")
using namespace std;
#define pb push_back
#define ppb pop_back
#define pi 3.1415926535897932384626433832795028841971
#define mp make_pair
#define x first
#define y second
#define pii pair<int,int>
#define pdd pair<double,double>
#define INF 1000000000
#define FOR(i,a,b) for (int _n(b), i(a); i <= _n; i++)
#define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;i--)
#define all(c) (c).begin(), (c).end()
#define SORT(c) sort(all(c))
#define rep(i,n) FOR(i,1,(n))
#define rept(i,n) FOR(i,0,(n)-1)
#define L(s) (int)((s).size())
#define C(a) memset((a),0,sizeof(a))
#define VI vector <int>
#define ll long long

const int N = 1001002;
int a,b,c,d,i,j,n,m,k,tot,now,last;
int nx[N][26], sib[N], pr[N], fir[N];
int cnt[N], en[N], pcnt[N];
char str[502];
int num[2][N];
int dp[2][2002][2002];
VI lev[503];
int dfs(int v, int h = 0) {
	lev[h].pb(v);
	rept(i, 26) {
		if (nx[v][i] != -1) cnt[v] += dfs(nx[v][i], h + 1);
	}
	return cnt[v];
}
inline int g(int v, int c) {
	if (c < 0) return -INF;
	if (v == -1 && !c) return 0;
	if (v == -1) return -INF;
	if (c > pcnt[v]) return -INF;
	if (!c) return 0;
	return dp[last][num[last][v]][c];
}
inline int f(int v, int c) {
	if (c < 0) return -INF;
	if (v == -1 && !c) return 0;
	if (v == -1) return -INF;
	if (c > pcnt[v]) return -INF;
	if (!c) return 0;
	return dp[now][num[now][v]][c];
}
int rec(int v, int c) {
	if (c < 0) return -INF;
	if (v == -1 && !c) return 0;
	if (v == -1) return -INF;
	if (c > pcnt[v]) return -INF;
	if (!c) return 0;
	int ans = 0, fr = cnt[v] - en[v];
	FORD(i, min(cnt[v], c), 0) {
		int lf = c - i;
		if (lf && sib[v] == -1) break;

		int v1 = g(fir[v], min(fr, i));
		if (v1 < 0) continue;
		int v2 = f(sib[v], lf);
		if (v2 < 0) continue;
		ans = max(ans, i * (i - 1) / 2 + v1 + v2);
	}
	return dp[now][num[now][v]][c] = ans;
}

int main() {
	//freopen("input.txt","r",stdin);
	//freopen("output.txt","w",stdout);
	memset(nx, -1, sizeof(nx));
	pr[0] = -1;
	k = 1;
	scanf("%d%d", &n, &tot);
	rept(i, n) {
		scanf("%s", str);
		m = (int)strlen(str);
		a = 0;
		rept(i, m) {
			if (nx[a][str[i] - 'a'] == -1) {
				nx[a][str[i] - 'a'] = k++;
				pr[k - 1] = a;
			}
			a = nx[a][str[i] - 'a'];
		}
		++cnt[a]; ++en[a];
	}

	rept(i, k) {
		fir[i] = -1;
		FORD(j, 25, 0) {
			if (nx[i][j] == -1) continue;
			sib[nx[i][j]] = fir[i];
			fir[i] = nx[i][j];
		}
	}
	dfs(0);
	C(dp);
	now = 0, last = 1;
	FORD(h, 500, 1) {
		if (lev[h].empty()) continue;
		now ^= 1; last ^= 1;
		rept(i, L(lev[h])) num[now][lev[h][i]] = i;
		FORD(i, L(lev[h]) - 1, 0) {
			int v = lev[h][i];
			if (i == L(lev[h]) - 1) pcnt[v] = cnt[v]; else
			pcnt[v] = cnt[v] + pcnt[sib[v]];
		}
		FORD(i, L(lev[h]) - 1, 0) {
			int v = lev[h][i];
			rept(j, tot + 1) {
				if (j > pcnt[v]) break;
				rec(v, j);
			}
		}
	}
	int ans = dp[now][0][tot];
	printf("%d\n", ans);
}


#define _CRT_SECURE_NO_DEPRECATE
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <iostream>
#include <iterator>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <sstream>
#include <fstream>
#include <ctime>
#include <cstring>
#pragma comment(linker, "/STACK:66777216")
using namespace std;
#define pb push_back
#define ppb pop_back
#define pi 3.1415926535897932384626433832795028841971
#define mp make_pair
#define x first
#define y second
#define pii pair<int,int>
#define pdd pair<double,double>
#define INF 1000000000
#define FOR(i,a,b) for (int _n(b), i(a); i <= _n; i++)
#define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;i--)
#define all(c) (c).begin(), (c).end()
#define SORT(c) sort(all(c))
#define rep(i,n) FOR(i,1,(n))
#define rept(i,n) FOR(i,0,(n)-1)
#define L(s) (int)((s).size())
#define C(a) memset((a),0,sizeof(a))
#define VI vector <int>
#define ll long long

const int N = 1001002;
int a,b,c,d,i,j,n,m,k,tot,now,last,T;
int nx[N][26], sib[N], pr[N], fir[N];
int cnt[N], en[N], pcnt[2][N];
char str[502];
int num[N];
int dp[2][2002][2002];
VI lev[503];
int cfir[2002], ce[2002], ccnt[2002], csib[2002];
int dfs(int v, int h = 0) {
	lev[h].pb(v);
	rept(i, 26) {
		if (nx[v][i] != -1) cnt[v] += dfs(nx[v][i], h + 1);
	}
	return cnt[v];
}
inline int g(int v, int c) {
	if (c < 0) return -INF;
	if (v == -1 && !c) return 0;
	if (v == -1) return -INF;
	if (c > pcnt[last][v]) return -INF;
	if (!c) return 0;
	return dp[last][v][c];
}
inline int f(int v, int c) {
	if (c < 0) return -INF;
	if (v == -1 && !c) return 0;
	if (v == -1) return -INF;
	if (c > pcnt[now][v]) return -INF;
	if (!c) return 0;
	return dp[now][v][c];
}
int rec(int v, int c) {
	if (c < 0) return -INF;
	if (v == -1 && !c) return 0;
	if (v == -1) return -INF;
	if (c > pcnt[now][v]) return -INF;
	if (!c) return 0;
	int ans = 0, fr = ccnt[v] - ce[v];
	FORD(i, min(ccnt[v], c), 0) {
		int lf = c - i;
		if (lf && csib[v] == -1) break;

		int v1 = g(cfir[v], min(fr, i));
		if (v1 < 0) continue;
		int v2 = f(csib[v], lf);
		if (v2 < 0) continue;
		ans = max(ans, i * (i - 1) / 2 + v1 + v2);
	}
	return dp[now][v][c] = ans;
}

int main() {
	//freopen("input.txt","r",stdin);
	//freopen("output.txt","w",stdout);
	memset(nx, -1, sizeof(nx));
	pr[0] = -1;
	k = 1;
	scanf("%d%d", &n, &tot);
	rept(i, n) {
		scanf("%s", str);
		m = (int)strlen(str);
		a = 0;
		rept(i, m) {
			if (nx[a][str[i] - 'a'] == -1) {
				nx[a][str[i] - 'a'] = k++;
				pr[k - 1] = a;
			}
			a = nx[a][str[i] - 'a'];
		}
		++cnt[a]; ++en[a];
	}

	rept(i, k) {
		fir[i] = -1;
		FORD(j, 25, 0) {
			if (nx[i][j] == -1) continue;
			sib[nx[i][j]] = fir[i];
			fir[i] = nx[i][j];
		}
	}
	dfs(0);
	C(dp);
	now = 0, last = 1;
	FORD(h, 500, 1) {
		if (lev[h].empty()) continue;
		now ^= 1; last ^= 1;
		rept(i, L(lev[h])) num[lev[h][i]] = i;
		T = L(lev[h]);
		FORD(i, L(lev[h]) - 1, 0) {
			int v = lev[h][i];
			if (sib[v] == -1) pcnt[now][i] = cnt[v]; else
			pcnt[now][i] = cnt[v] + pcnt[now][i + 1];

			if (fir[v] == -1) cfir[i] = -1; else
			cfir[i] = num[fir[v]];
			if (sib[v] == -1) csib[i] = -1; else
			csib[i] = i + 1;
			ce[i] = en[v];
			ccnt[i] = cnt[v];
		}
		FORD(i, L(lev[h]) - 1, 0) {
			int v = lev[h][i];
			rept(j, tot + 1) {
				if (j > pcnt[now][i]) break;
				rec(i, j);
			}
		}
	}
	int ans = dp[now][0][tot];
	printf("%d\n", ans);
}


#define _CRT_SECURE_NO_DEPRECATE
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <iostream>
#include <iterator>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <sstream>
#include <fstream>
#include <ctime>
#include <cstring>
#pragma comment(linker, "/STACK:66777216")
using namespace std;
#define pb push_back
#define ppb pop_back
#define pi 3.1415926535897932384626433832795028841971
#define mp make_pair
#define x first
#define y second
#define pii pair<int,int>
#define pdd pair<double,double>
#define INF 1000000000
#define FOR(i,a,b) for (int _n(b), i(a); i <= _n; i++)
#define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;i--)
#define all(c) (c).begin(), (c).end()
#define SORT(c) sort(all(c))
#define rep(i,n) FOR(i,1,(n))
#define rept(i,n) FOR(i,0,(n)-1)
#define L(s) (int)((s).size())
#define C(a) memset((a),0,sizeof(a))
#define VI vector <int>
#define ll long long

const int N = 1001002;
int a,b,c,d,i,j,n,m,k,tot,now,last,T;
int nx[N][26], sib[N], pr[N], fir[N];
int cnt[N], en[N], pcnt[2][N];
char str[502];
int num[N];
int dp[2][2002][2002], mlen[2][2002];
VI lev[503];
int cfir[2002], ce[2002], ccnt[2002], csib[2002];
int dfs(int v, int h = 0) {
	lev[h].pb(v);
	rept(i, 26) {
		if (nx[v][i] != -1) cnt[v] += dfs(nx[v][i], h + 1);
	}
	return cnt[v];
}
inline int g(int v, int c) {
	if (c < 0) return -INF;
	if (v == -1 && !c) return 0;
	if (v == -1) return -INF;
	if (c > pcnt[last][v]) return -INF;
	if (c <= 1) return 0;
	if (c > mlen[last][v]) return dp[last][v][mlen[last][v]]; else
	return dp[last][v][c];
}
inline int f(int v, int c) {
	if (c < 0) return -INF;
	if (v == -1 && !c) return 0;
	if (v == -1) return -INF;
	if (c > pcnt[now][v]) return -INF;
	if (c <= 1) return 0;
	if (c > mlen[now][v]) return dp[now][v][mlen[now][v]]; else
	return dp[now][v][c];
}
int rec(int v, int c) {
	if (c < 0) return -INF;
	if (v == -1 && !c) return 0;
	if (v == -1) return -INF;
	if (c > pcnt[now][v]) return -INF;
	if (c <= 1) return 0;
	int ans = 0, fr = ccnt[v] - ce[v];
	FORD(i, min(ccnt[v], c), 0) {
		int lf = c - i;
		if (lf && csib[v] == -1) break;

		int v2 = f(csib[v], lf);
		if (v2 < 0) continue;
		int v1 = g(cfir[v], min(fr, i));
		if (v1 < 0) continue;
		ans = max(ans, i * (i - 1) / 2 + v1 + v2);
	}
	return dp[now][v][c] = ans;
}

int main() {
	//freopen("input.txt","r",stdin);
	//freopen("output.txt","w",stdout);
	memset(nx, -1, sizeof(nx));
	pr[0] = -1;
	k = 1;
	scanf("%d%d", &n, &tot);
	rept(i, n) {
		scanf("%s", str);
		m = (int)strlen(str);
		a = 0;
		rept(i, m) {
			if (nx[a][str[i] - 'a'] == -1) {
				nx[a][str[i] - 'a'] = k++;
				pr[k - 1] = a;
			}
			a = nx[a][str[i] - 'a'];
		}
		++cnt[a]; ++en[a];
	}

	rept(i, k) {
		fir[i] = -1;
		FORD(j, 25, 0) {
			if (nx[i][j] == -1) continue;
			sib[nx[i][j]] = fir[i];
			fir[i] = nx[i][j];
		}
	}
	dfs(0);
	C(dp);
	now = 0, last = 1;
	memset(mlen, 63, sizeof(mlen));
	FORD(h, 500, 1) {
		if (lev[h].empty()) continue;
		now ^= 1; last ^= 1;
		rept(i, L(lev[h])) num[lev[h][i]] = i;
		T = L(lev[h]);
		FORD(i, L(lev[h]) - 1, 0) {
			int v = lev[h][i];
			if (sib[v] == -1) pcnt[now][i] = cnt[v]; else
			pcnt[now][i] = cnt[v] + pcnt[now][i + 1];

			if (fir[v] == -1) cfir[i] = -1; else
			cfir[i] = num[fir[v]];
			if (sib[v] == -1) csib[i] = -1; else
			csib[i] = i + 1;
			ce[i] = en[v];
			ccnt[i] = cnt[v];
		}
		FORD(i, L(lev[h]) - 1, 0) {
			int v = lev[h][i];
			mlen[now][i] = INF;
			rept(j, tot + 1) {
				if (j > pcnt[now][i]) break;
				rec(i, j);
				if (j >= 2 && dp[now][i][j] == dp[now][i][j - 1] && dp[now][i][j] == dp[now][i][j - 2]) {
					mlen[now][i] = j;
					break;
				}
			}
		}
	}
	if (tot > mlen[now][0]) tot = mlen[now][0];
	int ans = dp[now][0][tot];
	printf("%d\n", ans);
}


#define _CRT_SECURE_NO_DEPRECATE
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <iostream>
#include <iterator>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <sstream>
#include <fstream>
#include <ctime>
#include <cstring>
#pragma comment(linker, "/STACK:66777216")
using namespace std;
#define pb push_back
#define ppb pop_back
#define pi 3.1415926535897932384626433832795028841971
#define mp make_pair
#define x first
#define y second
#define pii pair<int,int>
#define pdd pair<double,double>
#define INF 1000000000
#define FOR(i,a,b) for (int _n(b), i(a); i <= _n; i++)
#define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;i--)
#define all(c) (c).begin(), (c).end()
#define SORT(c) sort(all(c))
#define rep(i,n) FOR(i,1,(n))
#define rept(i,n) FOR(i,0,(n)-1)
#define L(s) (int)((s).size())
#define C(a) memset((a),0,sizeof(a))
#define VI vector <int>
#define ll long long

const int N = 1000002;
int a,b,c,d,i,j,n,m,k,tot,now,last;
int nx[N][26], sib[N], pr[N], fir[N];
int cnt[N], en[N];
char str[502];
int num[2][N];
int dp[2][2001][2001];
VI lev[502];
int dfs(int v, int h = 0) {
	lev[h].pb(v);
	rept(i, 26) {
		if (nx[v][i] != -1) cnt[v] += dfs(nx[v][i], h + 1);
	}
	return cnt[v];
}
inline int g(int v, int c) {
	if (c < 0) return -INF;
	if (v == -1 && !c) return 0;
	if (v == -1) return -INF;
	if (!c) return 0;
	return dp[last][num[last][v]][c];
}
inline int f(int v, int c) {
	if (c < 0) return -INF;
	if (v == -1 && !c) return 0;
	if (v == -1) return -INF;
	if (!c) return 0;
	return dp[now][num[now][v]][c];
}
int rec(int v, int c) {
	if (c < 0) return -INF;
	if (v == -1 && !c) return 0;
	if (v == -1) return -INF;
	if (!c) return 0;
	int ans = 0, fr = cnt[v] - en[v];
	FORD(i, min(cnt[v], c), 0) {
		int lf = c - i;
		if (lf && sib[v] == -1) break;
		ans = max(ans, i * (i - 1) / 2 + g(fir[v], min(fr, i)) + f(sib[v], lf));
	}
	return dp[now][num[now][v]][c] = ans;
}

int main() {
	//freopen("input.txt","r",stdin);
	//freopen("output.txt","w",stdout);
	memset(nx, -1, sizeof(nx));
	pr[0] = -1;
	k = 1;
	scanf("%d%d", &n, &tot);
	rept(i, n) {
		scanf("%s", str);
		m = (int)strlen(str);
		a = 0;
		rept(i, m) {
			if (nx[a][str[i] - 'a'] == -1) {
				nx[a][str[i] - 'a'] = k++;
				pr[k - 1] = a;
			}
			a = nx[a][str[i] - 'a'];
		}
		++cnt[a]; ++en[a];
	}

	rept(i, k) {
		fir[i] = -1;
		FORD(j, 25, 0) {
			if (nx[i][j] == -1) continue;
			sib[nx[i][j]] = fir[i];
			fir[i] = nx[i][j];
		}
	}
	dfs(0);
	memset(dp, -1, sizeof(dp));
	now = 0, last = 1;
	FORD(h, 500, 1) {
		if (lev[h].empty()) continue;
		now ^= 1; last ^= 1;
		rept(i, L(lev[h])) num[now][lev[h][i]] = i;
		FORD(i, L(lev[h]) - 1, 0) {
			int v = lev[h][i], p = pr[v];
			rept(j, k + 1) {
				if (j > cnt[p]) break;
				rec(v, j);
			}
		}
	}
	int ans = dp[now][0][tot];
	printf("%d\n", ans);
}


#define _CRT_SECURE_NO_DEPRECATE
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <iostream>
#include <iterator>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <sstream>
#include <fstream>
#include <ctime>
#include <cstring>
#pragma comment(linker, "/STACK:66777216")
using namespace std;
#define pb push_back
#define ppb pop_back
#define pi 3.1415926535897932384626433832795028841971
#define mp make_pair
#define x first
#define y second
#define pii pair<int,int>
#define pdd pair<double,double>
#define INF 1000000000
#define FOR(i,a,b) for (int _n(b), i(a); i <= _n; i++)
#define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;i--)
#define all(c) (c).begin(), (c).end()
#define SORT(c) sort(all(c))
#define rep(i,n) FOR(i,1,(n))
#define rept(i,n) FOR(i,0,(n)-1)
#define L(s) (int)((s).size())
#define C(a) memset((a),0,sizeof(a))
#define VI vector <int>
#define ll long long

const int N = 1001002;
int a,b,c,d,i,j,n,m,k,tot,now,last;
int nx[N][26], sib[N], pr[N], fir[N];
int cnt[N], en[N];
char str[502];
int num[2][N];
int dp[2][2002][2002];
VI lev[503];
int dfs(int v, int h = 0) {
	lev[h].pb(v);
	rept(i, 26) {
		if (nx[v][i] != -1) cnt[v] += dfs(nx[v][i], h + 1);
	}
	return cnt[v];
}
inline int g(int v, int c) {
	if (c < 0) return -INF;
	if (v == -1 && !c) return 0;
	if (v == -1) return -INF;
	if (!c) return 0;
	return dp[last][num[last][v]][c];
}
inline int f(int v, int c) {
	if (c < 0) return -INF;
	if (v == -1 && !c) return 0;
	if (v == -1) return -INF;
	if (!c) return 0;
	return dp[now][num[now][v]][c];
}
int rec(int v, int c) {
	if (c < 0) return -INF;
	if (v == -1 && !c) return 0;
	if (v == -1) return -INF;
	if (!c) return 0;
	int ans = 0, fr = cnt[v] - en[v];
	FORD(i, min(cnt[v], c), 0) {
		int lf = c - i;
		if (lf && sib[v] == -1) break;

		int v1 = g(fir[v], min(fr, i));
		if (v1 < 0) continue;
		int v2 = f(sib[v], lf);
		if (v2 < 0) continue;
		ans = max(ans, i * (i - 1) / 2 + v1 + v2);
	}
	return dp[now][num[now][v]][c] = ans;
}

int main() {
	//freopen("input.txt","r",stdin);
	//freopen("output.txt","w",stdout);
	memset(nx, -1, sizeof(nx));
	pr[0] = -1;
	k = 1;
	scanf("%d%d", &n, &tot);
	rept(i, n) {
		scanf("%s", str);
		m = (int)strlen(str);
		a = 0;
		rept(i, m) {
			if (nx[a][str[i] - 'a'] == -1) {
				nx[a][str[i] - 'a'] = k++;
				pr[k - 1] = a;
			}
			a = nx[a][str[i] - 'a'];
		}
		++cnt[a]; ++en[a];
	}

	rept(i, k) {
		fir[i] = -1;
		FORD(j, 25, 0) {
			if (nx[i][j] == -1) continue;
			sib[nx[i][j]] = fir[i];
			fir[i] = nx[i][j];
		}
	}
	dfs(0);
	C(dp);
	now = 0, last = 1;
	FORD(h, 500, 1) {
		if (lev[h].empty()) continue;
		now ^= 1; last ^= 1;
		rept(i, L(lev[h])) num[now][lev[h][i]] = i;
		FORD(i, L(lev[h]) - 1, 0) {
			int v = lev[h][i], p = pr[v];
			rept(j, tot + 1) {
				if (j > cnt[p]) break;
				rec(v, j);
			}
		}
	}
	int ans = dp[now][0][tot];
	printf("%d\n", ans);
}


#define _CRT_SECURE_NO_DEPRECATE
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <iostream>
#include <iterator>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <sstream>
#include <fstream>
#include <ctime>
#include <cstring>
#pragma comment(linker, "/STACK:66777216")
using namespace std;
#define pb push_back
#define ppb pop_back
#define pi 3.1415926535897932384626433832795028841971
#define mp make_pair
#define x first
#define y second
#define pii pair<int,int>
#define pdd pair<double,double>
#define INF 1000000000
#define FOR(i,a,b) for (int _n(b), i(a); i <= _n; i++)
#define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;i--)
#define all(c) (c).begin(), (c).end()
#define SORT(c) sort(all(c))
#define rep(i,n) FOR(i,1,(n))
#define rept(i,n) FOR(i,0,(n)-1)
#define L(s) (int)((s).size())
#define C(a) memset((a),0,sizeof(a))
#define VI vector <int>
#define ll long long

const int N = 1001002;
int a,b,c,d,i,j,n,m,k,tot,now,last;
int nx[N][26], sib[N], pr[N], fir[N];
int cnt[N], en[N];
char str[502];
int num[2][N];
int dp[2][2002][2002];
VI lev[503];
int dfs(int v, int h = 0) {
	lev[h].pb(v);
	rept(i, 26) {
		if (nx[v][i] != -1) cnt[v] += dfs(nx[v][i], h + 1);
	}
	return cnt[v];
}
inline int g(int v, int c) {
	if (c < 0) return -INF;
	if (v == -1 && !c) return 0;
	if (v == -1) return -INF;
	if (!c) return 0;
	return dp[last][num[last][v]][c];
}
inline int f(int v, int c) {
	if (c < 0) return -INF;
	if (v == -1 && !c) return 0;
	if (v == -1) return -INF;
	if (!c) return 0;
	return dp[now][num[now][v]][c];
}
int rec(int v, int c) {
	if (c < 0) return -INF;
	if (v == -1 && !c) return 0;
	if (v == -1) return -INF;
	if (!c) return 0;
	int ans = 0, fr = cnt[v] - en[v];
	FORD(i, min(cnt[v], c), 0) {
		int lf = c - i;
		if (lf && sib[v] == -1) break;

		int v1 = g(fir[v], min(fr, i));
		if (v1 < 0) continue;
		int v2 = f(sib[v], lf);
		if (v2 < 0) continue;
		ans = max(ans, i * (i - 1) / 2 + v1 + v2);
	}
	return dp[now][num[now][v]][c] = ans;
}

int main() {
	//freopen("input.txt","r",stdin);
	//freopen("output.txt","w",stdout);
	memset(nx, -1, sizeof(nx));
	pr[0] = -1;
	k = 1;
	scanf("%d%d", &n, &tot);
	rept(i, n) {
		scanf("%s", str);
		m = (int)strlen(str);
		a = 0;
		rept(i, m) {
			if (nx[a][str[i] - 'a'] == -1) {
				nx[a][str[i] - 'a'] = k++;
				pr[k - 1] = a;
			}
			a = nx[a][str[i] - 'a'];
		}
		++cnt[a]; ++en[a];
	}

	rept(i, k) {
		fir[i] = -1;
		FORD(j, 25, 0) {
			if (nx[i][j] == -1) continue;
			sib[nx[i][j]] = fir[i];
			fir[i] = nx[i][j];
		}
	}
	dfs(0);
	C(dp);
	now = 0, last = 1;
	FORD(h, 500, 1) {
		if (lev[h].empty()) continue;
		now ^= 1; last ^= 1;
		rept(i, L(lev[h])) num[now][lev[h][i]] = i;
		FORD(i, L(lev[h]) - 1, 0) {
			int v = lev[h][i], p = pr[v];
			rept(j, k + 1) {
				if (j > cnt[p]) break;
				rec(v, j);
			}
		}
	}
	int ans = dp[now][0][tot];
	printf("%d\n", ans);
}


#define _CRT_SECURE_NO_DEPRECATE
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <iostream>
#include <iterator>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <sstream>
#include <fstream>
#include <ctime>
#include <cstring>
#pragma comment(linker, "/STACK:66777216")
using namespace std;
#define pb push_back
#define ppb pop_back
#define pi 3.1415926535897932384626433832795028841971
#define mp make_pair
#define x first
#define y second
#define pii pair<int,int>
#define pdd pair<double,double>
#define INF 1000000000
#define FOR(i,a,b) for (int _n(b), i(a); i <= _n; i++)
#define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;i--)
#define all(c) (c).begin(), (c).end()
#define SORT(c) sort(all(c))
#define rep(i,n) FOR(i,1,(n))
#define rept(i,n) FOR(i,0,(n)-1)
#define L(s) (int)((s).size())
#define C(a) memset((a),0,sizeof(a))
#define VI vector <int>
#define ll long long

const int N = 1001002;
int a,b,c,d,i,j,n,m,k,tot,now,last,T;
int nx[N][26], sib[N], pr[N], fir[N];
int cnt[N], en[N], pcnt[2][N];
char str[502];
int num[N];
int dp[2][2002][2002], mlen[2][2002];
VI lev[503];
int cfir[2002], ce[2002], ccnt[2002], csib[2002];
int dfs(int v, int h = 0) {
	lev[h].pb(v);
	rept(i, 26) {
		if (nx[v][i] != -1) cnt[v] += dfs(nx[v][i], h + 1);
	}
	return cnt[v];
}
inline int g(int v, int c) {
	if (c < 0) return -INF;
	if (v == -1 && !c) return 0;
	if (v == -1) return -INF;
	if (c > pcnt[last][v]) return -INF;
	if (c <= 1) return 0;
	if (c > mlen[last][v]) return dp[last][v][mlen[last][v]]; else
	return dp[last][v][c];
}
inline int f(int v, int c) {
	if (c < 0) return -INF;
	if (v == -1 && !c) return 0;
	if (v == -1) return -INF;
	if (c > pcnt[now][v]) return -INF;
	if (c <= 1) return 0;
	if (c > mlen[now][v]) return dp[now][v][mlen[now][v]]; else
	return dp[now][v][c];
}
int rec(int v, int c) {
	if (c < 0) return -INF;
	if (v == -1 && !c) return 0;
	if (v == -1) return -INF;
	if (c > pcnt[now][v]) return -INF;
	if (c <= 1) return 0;
	int ans = 0, fr = ccnt[v] - ce[v];
	FORD(i, min(ccnt[v], c), 0) {
		int lf = c - i;
		if (lf && csib[v] == -1) break;

		int v2 = f(csib[v], lf);
		if (v2 < 0) continue;
		int v1 = g(cfir[v], min(fr, i));
		if (v1 < 0) continue;
		ans = max(ans, i * (i - 1) / 2 + v1 + v2);
	}
	return dp[now][v][c] = ans;
}

int sub[26];
int main() {
	//freopen("input.txt","r",stdin);
	//freopen("output.txt","w",stdout);
	memset(nx, -1, sizeof(nx));
	pr[0] = -1;
	k = 1;
	rept(i, 26) sub[i] = i;
	srand(25091992);
	random_shuffle(sub, sub + 26);
	scanf("%d%d", &n, &tot);
	rept(i, n) {
		scanf("%s", str);
		m = (int)strlen(str);
		a = 0;
		rept(i, m) {
			str[i] = sub[str[i] - 'a'] + 'a';
			if (nx[a][str[i] - 'a'] == -1) {
				nx[a][str[i] - 'a'] = k++;
				pr[k - 1] = a;
			}
			a = nx[a][str[i] - 'a'];
		}
		++cnt[a]; ++en[a];
	}

	rept(i, k) {
		fir[i] = -1;
		FORD(j, 25, 0) {
			if (nx[i][j] == -1) continue;
			sib[nx[i][j]] = fir[i];
			fir[i] = nx[i][j];
		}
	}
	dfs(0);
	C(dp);
	now = 0, last = 1;
	memset(mlen, 63, sizeof(mlen));
	FORD(h, 500, 1) {
		if (lev[h].empty()) continue;
		now ^= 1; last ^= 1;
		rept(i, L(lev[h])) num[lev[h][i]] = i;
		T = L(lev[h]);
		FORD(i, L(lev[h]) - 1, 0) {
			int v = lev[h][i];
			if (sib[v] == -1) pcnt[now][i] = cnt[v]; else
			pcnt[now][i] = cnt[v] + pcnt[now][i + 1];

			if (fir[v] == -1) cfir[i] = -1; else
			cfir[i] = num[fir[v]];
			if (sib[v] == -1) csib[i] = -1; else
			csib[i] = i + 1;
			ce[i] = en[v];
			ccnt[i] = cnt[v];
		}
		FORD(i, L(lev[h]) - 1, 0) {
			int v = lev[h][i];
			mlen[now][i] = INF;
			rept(j, tot + 1) {
				if (j > pcnt[now][i]) break;
				rec(i, j);
				if (j >= 2 && dp[now][i][j] == dp[now][i][j - 1] && dp[now][i][j] == dp[now][i][j - 2]) {
					mlen[now][i] = j;
					break;
				}
			}
		}
	}
	if (tot > mlen[now][0]) tot = mlen[now][0];
	int ans = dp[now][0][tot];
	printf("%d\n", ans);
}


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#define N 2100
using namespace std;
int n,k,f[N][N],h[N],tot,i,l[N],j;
string s[N];
int dp(int l,int r){
	if(l==r)return 0;
	int X=++tot,i,j,mid=l+1,x,y;
	for(i=l+1;i<=r;++i)if(h[i]<h[mid])mid=i;
	x=dp(l,mid-1); y=dp(mid,r);
	for(i=0;i<=mid-l;++i)
		for(j=0;j<=r-mid+1;++j)f[X][i+j]=max(f[X][i+j],f[x][i]+f[y][j]+h[mid]*i*j);
	return X;
}
int main(){
	scanf("%d%d",&n,&k);
	for(i=1;i<=n;++i)cin>>s[i];
	sort(s+1,s+n+1);
	l[1]=s[1].length();
	for(i=2;i<=n;++i){
		l[i]=s[i].length();
		for(j=0;j<l[i-1] && j<l[i] && s[i-1][j]==s[i][j];++j);
		h[i]=j;
	}
	printf("%d\n",f[dp(1,n)][k]);
}


#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#define Maxn 2012
#define inf 1000002012

using namespace std;

int N, K;
string s[Maxn];
int f[2][Maxn][Maxn];
int Now, Max;
int h[Maxn];

inline void travel( int l, int r,int depth, int c )
{
	memset( f[c][depth], sizeof(f[c][depth]), 0 );
	if ( l > r ) return;
	if ( l == r ) { f[c][depth][2] = h[l]; return; }
	int Min = inf, id = 0;;

	for ( int i = l; i <= r; ++i )
	if ( Min > h[i] ) Min = h[i], id = i;

	travel( l, id - 1, depth + 1, 0 ); travel( id + 1, r, depth + 1, 1 );

	for ( int i = 0; i <= min(K,r-l+2); ++i )
	{
		f[c][depth][i] = 0;
		for ( int j = max(0,i-(r-id+1)); j <= min(i,id-l+1); ++j )
		f[c][depth][i] = max( f[c][depth][i], f[0][depth+1][j] + f[1][depth+1][i-j] + Min*(i-j)*j );
	}

}

int main()
{
	//freopen( "178F.in", "r", stdin );freopen( "178F.out", "w", stdout );

	scanf( "%d%d ", &N, &K );

	for ( int i = 0; i < N; ++i )
	getline(cin,s[i]);

	sort( s, s + N );

	int i, j = 0;
	for ( i = 0; i < N - 1; h[i++] = j )
	for ( j = 0; j < min(s[i].length(),s[i+1].length())&& s[i][j]==s[i+1][j]; ++j );

	travel( 0, N - 2, 0, 0 );
	printf( "%d", f[0][0][K] );

	//fclose( stdin ); fclose( stdout );
	return 0;
}


#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#define Maxn 2012
#define inf 1000002012

using namespace std;

int N, K;
string s[Maxn];
int f[2][Maxn][Maxn];
int Now, Max;
int h[Maxn];

inline void travel( int l, int r,int depth, int c )
{
	memset( f[c][depth], sizeof(f[c][depth]), 0 );
	if ( l > r ) return;
	if ( l == r ) { f[c][depth][2] = h[l]; return; }
	int Min = inf, id = 0;;

	for ( int i = l; i <= r; ++i )
	if ( Min > h[i] ) Min = h[i], id = i;

	travel( l, id - 1, depth + 1, 0 ); travel( id + 1, r, depth + 1, 1 );

	for ( int i = 0; i <= min(K,r-l+2); ++i )
	{
		f[c][depth][i] = 0;
		for ( int j = 0; j <= i; ++j )
		f[c][depth][i] = max( f[c][depth][i], f[0][depth+1][j] + f[1][depth+1][i-j] + Min*(i-j)*j );
	}

}

int main()
{
	//freopen( "178F.in", "r", stdin );freopen( "178F.out", "w", stdout );

	scanf( "%d%d ", &N, &K );

	for ( int i = 0; i < N; ++i )
	getline(cin,s[i]);

	sort( s, s + N );

	int i, j = 0;
	for ( i = 0; i < N - 1; h[i++] = j )
	for ( j = 0; j < min(s[i].length(),s[i+1].length())&& s[i][j]==s[i+1][j]; ++j );

	travel( 0, N - 2, 0, 0 );
	printf( "%d", f[0][0][K] );

	//fclose( stdin ); fclose( stdout );
	return 0;
}


#include<iostream>
#include<algorithm>
using namespace std;
string s[2010];
int f[2010][2010],h[2010],n,m,tot,i;
int dp(int l,int r)
{
	if(l==r) return n;
	int mid=min_element(h+l,h+r)-h,x=dp(l,mid),y=dp(mid+1,r),z=++tot,i,j;
	for(i=0;i<=mid-l+1;i++)
		for(j=0;j<=r-mid;j++) f[z][i+j]=max(f[z][i+j],f[x][i]+f[y][j]+h[mid]*i*j);
	return z;
}
int main()
{
	cin>>n>>m;
	for(i=1;i<=n;i++) cin>>s[i];
	sort(s+1,s+n+1);
	for(i=1;i<n;i++)
		for(;h[i]<min(s[i].length(),s[i+1].length())&&s[i][h[i]]==s[i+1][h[i]];h[i]++);
	cout<<f[dp(1,n)][m]<<endl;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>
#include <algorithm>
#include <string>
#include <vector>

using namespace std;

#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define pb push_back
#define mp make_pair
#define sz(x) ((int)(x).size())

typedef long long ll;
typedef vector<ll> vll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef pair<int, int> pii;

char buf[1000];

struct Node {
  int ne[26];
  int ecnt;
  Node() { memset(ne, -1, sizeof ne); ecnt = 0; }
  int& operator[](int x) { return ne[x]; }
};

const int INF = 2e9 + 2e6;

int main() {
  #ifdef DEBUG
  freopen("std.in", "r", stdin);
  freopen("std.out", "w", stdout);
  #endif

  int n, k;
  while (scanf("%d%d", &n, &k) >= 1) {
    vector<string> ss(n);
    for (int i = 0; i < n; i++) {
      scanf("%s", buf);
      ss[i] = buf;
    }
    sort(ss.begin(), ss.end());

    vi lcp0(n - 1);
    for (int i = 0; i + 1 < n; i++) {
      int k = 0;
      while (ss[i][k] && ss[i][k] == ss[i + 1][k]) k++;
      lcp0[i] = k;
    }

    vvi lcp(n, vi(n, 0));
    for (int a = 0; a + 1 < n; a++) {
      int k = lcp0[a];
      for (int b = a + 1; b < n; b++) {
        k = min(k, lcp0[b - 1]);
        lcp[a][b] = lcp[b][a] = k;
      }
    }

    vector<Node> ns(1);
    for (int i = 0; i < n; i++) {
      int v = 0;
      for (int i2 = 0; ss[i][i2]; i2++) {
        int c = ss[i][i2] - 'a';

        if (ns[v][c] < 0) {
          ns.pb(Node());
          ns[v][c] = sz(ns) -1;
        }
        v = ns[v][c];
      }
      ns[v].ecnt++;
    }

    vi nextInt(sz(ns), -1), nextLen(sz(ns), 1);
    for (int i = sz(ns) - 1; i >= 0; i--) {
      nextInt[i] = i;
      if (ns[i].ecnt) continue;

      for (int i2 = 0; i2 < 26; i2++)
        if (ns[i][i2] >= 0) {
          if (nextInt[i] != i) {
            nextInt[i] = i;
            nextLen[i] = 1;
            break;
          }
          nextInt[i] = nextInt[ns[i][i2]];
          nextLen[i] = 1 + nextLen[ns[i][i2]];
        }
    }
    nextInt[0] = 0; nextLen[0] = 1;

    vi prLen(sz(ns), 1);
    for (int i = 0; i < sz(ns); i++)
      if (nextInt[i] == i) {
        for (int i2 = 0; i2 < 26; i2++) if (ns[i][i2] >= 0) {
          prLen[nextInt[ns[i][i2]]] = nextLen[ns[i][i2]];
        }
      }

    vvi dyn(sz(ns));
    for (int i = 0; i < sz(ns); i++) if (nextInt[i] == i) dyn[i] = vi(k + 1, -INF);

    for (int v = sz(ns) - 1; v >= 0; v--) if (nextInt[v] == v) {
      vvi dc(27, vi(k + 1, -INF));
      for (int ccnt = 0; ccnt <= ns[v].ecnt; ccnt++)
        dc[0][ccnt] = 0;

      for (int i = 0; i < 26; i++) {
        int b = ns[v][i];
        if (b < 0) {
          dc[i + 1] = dc[i];
          continue;
        }
        b = nextInt[b];

        assert(v <= b);
        for (int wcnt = 0; wcnt <= k; wcnt++) if (dc[i][wcnt] >= 0)
        for (int ccnt = 0; wcnt + ccnt <= k; ccnt++) {
          dc[i + 1][wcnt + ccnt] = max(dc[i + 1][wcnt + ccnt], dc[i][wcnt] + dyn[b][ccnt]);
        }
      }
      for (int ccnt = 0; ccnt <= k; ccnt++)
        if (dc[26][ccnt] >= 0) {
          dyn[v][ccnt] = dc[26][ccnt] + prLen[v] * ccnt * (ccnt - 1) / 2;
        }
    }
    printf("%d\n", dyn[nextInt[0]][k] - k * (k - 1) / 2);
  }
  return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>
#include <algorithm>
#include <string>
#include <vector>

using namespace std;

#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define pb push_back
#define mp make_pair
#define sz(x) ((int)(x).size())

typedef long long ll;
typedef vector<ll> vll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef pair<int, int> pii;

char buf[1000];

struct Node {
  int ne[26];
  int ecnt;
  Node() { memset(ne, -1, sizeof ne); ecnt = 0; }
  int& operator[](int x) { return ne[x]; }
};

const int INF = 2e9 + 2e6;

int main() {
  #ifdef DEBUG
  freopen("std.in", "r", stdin);
  freopen("std.out", "w", stdout);
  #endif

  int n, k;
  while (scanf("%d%d", &n, &k) >= 1) {
    vector<string> ss(n);
    for (int i = 0; i < n; i++) {
      scanf("%s", buf);
      ss[i] = buf;
    }
    sort(ss.begin(), ss.end());

    vi lcp0(n - 1);
    for (int i = 0; i + 1 < n; i++) {
      int k = 0;
      while (ss[i][k] && ss[i][k] == ss[i + 1][k]) k++;
      lcp0[i] = k;
    }

    vvi lcp(n, vi(n, 0));
    for (int a = 0; a + 1 < n; a++) {
      int k = lcp0[a];
      for (int b = a + 1; b < n; b++) {
        k = min(k, lcp0[b - 1]);
        lcp[a][b] = lcp[b][a] = k;
      }
    }

    vector<Node> ns(1);
    for (int i = 0; i < n; i++) {
      int v = 0;
      for (int i2 = 0; ss[i][i2]; i2++) {
        int c = ss[i][i2] - 'a';

        if (ns[v][c] < 0) {
          ns.pb(Node());
          ns[v][c] = sz(ns) -1;
        }
        v = ns[v][c];
      }
      ns[v].ecnt++;
    }

    vi nextInt(sz(ns), -1), nextLen(sz(ns), 1);
    for (int i = sz(ns) - 1; i >= 0; i--) {
      nextInt[i] = i;
      if (ns[i].ecnt) continue;

      for (int i2 = 0; i2 < 26; i2++)
        if (ns[i][i2] >= 0) {
          if (nextInt[i] != i) {
            nextInt[i] = i;
            nextLen[i] = 1;
            break;
          }
          nextInt[i] = nextInt[ns[i][i2]];
          nextLen[i] = 1 + nextLen[ns[i][i2]];
        }
    }
    nextInt[0] = 0; nextLen[0] = 1;

    vi prLen(sz(ns), 1);
    for (int i = 0; i < sz(ns); i++)
      if (nextInt[i] == i) {
        for (int i2 = 0; i2 < 26; i2++) if (ns[i][i2] >= 0) {
          prLen[nextInt[ns[i][i2]]] = nextLen[ns[i][i2]];
        }
      }

    vvi dyn(sz(ns));
    for (int i = 0; i < sz(ns); i++) if (nextInt[i] == i) dyn[i] = vi(k + 1, -INF);

    for (int v = sz(ns) - 1; v >= 0; v--) if (nextInt[v] == v) {
      vvi dc(27, vi(k + 1, -INF));
      for (int ccnt = 0; ccnt <= ns[v].ecnt; ccnt++)
        dc[0][ccnt] = 0;

      for (int i = 0; i < 26; i++) {
        int b = ns[v][i];
        if (b < 0) {
          dc[i + 1] = dc[i];
          continue;
        }
        b = nextInt[b];

        assert(v <= b);
        for (int wcnt = 0; wcnt <= k; wcnt++) {
          if (dc[i][wcnt] < 0) break;
          for (int ccnt = 0; wcnt + ccnt <= k; ccnt++) {
            if (dyn[b][ccnt] < 0) break;
            dc[i + 1][wcnt + ccnt] = max(dc[i + 1][wcnt + ccnt], dc[i][wcnt] + dyn[b][ccnt]);
          }
        }
      }

      for (int ccnt = 0; ccnt <= k; ccnt++)
        if (dc[26][ccnt] >= 0) {
          dyn[v][ccnt] = dc[26][ccnt] + prLen[v] * ccnt * (ccnt - 1) / 2;
        }
    }
    printf("%d\n", dyn[nextInt[0]][k] - k * (k - 1) / 2);
  }
  return 0;
}


#include<iostream>
#include<algorithm>
using namespace std;
string s[2010];
int f[2010][2010],h[2010],n,m,tot,i;
int dp(int l,int r)
{
    if(l==r) return n;
    int mid=min_element(h+l,h+r)-h,x=dp(l,mid),y=dp(mid+1,r),z=++tot,i,j;
    for(i=0;i<=mid-l+1;i++)
        for(j=0;j<=r-mid;j++) f[z][i+j]=max(f[z][i+j],f[x][i]+f[y][j]+h[mid]*i*j);
    return z;
}
int main()
{
    cin>>n>>m;
    for(i=1;i<=n;i++) cin>>s[i];
    sort(s+1,s+n+1);
    for(i=1;i<n;i++)
        for(;h[i]<min(s[i].length(),s[i+1].length())&&s[i][h[i]]==s[i+1][h[i]];h[i]++);
    cout<<f[dp(1,n)][m]<<endl;
}


#include<bits/stdc++.h>
#define ll int
#define pb push_back
#define mp make_pair
#define ld long double
#define F first
#define S second

using namespace :: std;

const ll maxn=2100*500;
const ll maxm=2100;
const ll mod=1e9+7;
const ll inf=1e9+500;

vector<pair<char,pair<ll,ll > > > bach[maxn];
ll cn=2;

ll en[maxn];

ll trii[maxm*2][26];
ll vazn[maxm*2][26];
ll enn[maxm*2];
ll sz[maxn*2];
ll cnn=1;

ll k;
ll dp[maxm][2100];

void add(string s){
	ll p=1;
	for(ll i=0;i<s.size();i++){
		s[i]-='a';
		char c=s[i];

		bool peyda=0;
		for(ll j=0;j<bach[p].size();j++){
			if(bach[p][j].F==c){
				peyda=1;
				p=bach[p][j].S.F;
				break;
			}
		}
		if(!peyda){
			bach[p].pb(mp(c,mp(cn,1)));
			p=cn;
			cn++;
		}
	}
	en[p]++;
}
ll compp(ll p){
	ll kh=cnn;
	cnn++;
	for(ll i=0;i<bach[p].size();i++){
		ll v=compp(bach[p][i].S.F);
		trii[kh][bach[p][i].F]=v;
		vazn[kh][bach[p][i].F]=bach[p][i].S.S;
	}
	enn[kh]=en[p];
	return kh;
}
void  comp(ll p){
	for(ll i=0;i<bach[p].size();i++){
		comp(bach[p][i].S.F);
	}
	for(ll i=0;i<bach[p].size();i++){
		char c=bach[p][i].F;
		ll v=bach[p][i].S.F;
		if(bach[v].size()==1 && en[v]==0){
			bach[p][i].S.S+=bach[v][0].S.S;
			bach[p][i].S.F=bach[v][0].S.F;
		}
	}
}
void dfs(ll a){

	sz[a]=enn[a];
	for(ll i=0;i<=sz[a];i++){
		dp[a][i]=0;
	}
	for(ll i=0;i<26;i++){
		ll v=trii[a][i];
		if(v!=0){
			dfs(v);
			for(ll p=sz[a]+sz[v];p>=0;p--){
				for(ll k=0;k<=sz[v];k++){
					ll j=p-k;
					if(j<0 || j>sz[a]){
						continue;
					}
					dp[a][p]=max(dp[a][p],dp[a][j]+dp[v][k]+vazn[a][i]*k*(k-1)/2);
				}
			}
			sz[a]+=sz[v];
		}
	}
}
int main(){

	for(ll i=0;i<maxm;i++){
		for(ll j=0;j<2100;j++){
			dp[i][j]=-inf;
		}
	}
	ll n;
	cin>>n>>k;
	for(ll i=0;i<n;i++){
		string s;
		cin>>s;
		add(s);
	}
	comp(1);
	compp(1);
	dfs(1);
	cout<<dp[1][k];

}

/*
	  .      _______    __    ___     ________      ________       _________     _________   ________
	  .     /       \  |  |  /  /    /        \    |        \     /         \   |        |  |   __   \
	  .    /   _____/  |  | /  /    /    ___   \   |   ___   \   |   _______/   |  ______|  |  |  \   \
	  .   /   /        |  |/  /    /    /   \   \  |  |   \   \  |  (______     |  |_____   |  |__/   /
	  .   |  |         |     /     |   /     \  |  |  |    |  |   \        \    |        |  |      __/
	  .   |  |         |     \     |   \     /  |  |  |    |  |    \______  \   |  ______|  |      \
	  .   \   \_____   |  |\  \    \    \___/   /  |  |___/   /    _______) |   |  |_____   |   |\  \
	  .    \        \  |  | \  \    \          /   |         /    /         /   |        |  |   | \  \
	  .     \_______/  |__|  \__\    \________/    |________/     \________/    |________|  |___|  \__\
 */


#include<bits/stdc++.h>
#define ll int
#define pb push_back
#define mp make_pair
#define ld long double
#define F first
#define S second

using namespace :: std;

const ll maxn=2100*500;
const ll maxm=2100;
const ll mod=1e9+7;
const ll inf=1e9+500;

vector<pair<char,pair<ll,ll > > > bach[maxn];
ll cn=2;

ll en[maxn];

ll trii[maxm*2][26];
ll vazn[maxm*2][26];
ll enn[maxm*2];
ll sz[maxn*2];
ll cnn=1;

ll k;
ll dp[maxm][2100];

void add(string s){
	ll p=1;
	for(ll i=0;i<s.size();i++){
		s[i]-='a';
		char c=s[i];

		bool peyda=0;
		for(ll j=0;j<bach[p].size();j++){
			if(bach[p][j].F==c){
				peyda=1;
				p=bach[p][j].S.F;
				break;
			}
		}
		if(!peyda){
			bach[p].pb(mp(c,mp(cn,1)));
			p=cn;
			cn++;
		}
	}
	en[p]++;
}
ll compp(ll p){
	ll kh=cnn;
	cnn++;
	for(ll i=0;i<bach[p].size();i++){
		ll v=compp(bach[p][i].S.F);
		trii[kh][i]=v;
		vazn[kh][i]=bach[p][i].S.S;
	}
	enn[kh]=en[p];
	return kh;
}
void  comp(ll p){
	for(ll i=0;i<bach[p].size();i++){
		comp(bach[p][i].S.F);
	}
	for(ll i=0;i<bach[p].size();i++){
		char c=bach[p][i].F;
		ll v=bach[p][i].S.F;
		if(bach[v].size()==1 && en[v]==0){
			bach[p][i].S.S+=bach[v][0].S.S;
			bach[p][i].S.F=bach[v][0].S.F;
		}
	}
}
void dfs(ll a){

	sz[a]=enn[a];
	for(ll i=0;i<=sz[a];i++){
		dp[a][i]=0;
	}
	for(ll i=0;i<26;i++){
		ll v=trii[a][i];
		if(v!=0){
			dfs(v);
			for(ll j=0;j<=sz[a];j++){
				for(ll k=0;k<=sz[v];k++){
					dp[a][j+k]=max(dp[a][j+k],dp[a][j]+dp[v][k]+vazn[a][i]*k*(k-1)/2);
				}
			}
			sz[a]+=sz[v];
		}
	}
}
int main(){

	for(ll i=0;i<maxm;i++){
		for(ll j=0;j<2100;j++){
			dp[i][j]=-inf;
		}
	}
	ll n;
	cin>>n>>k;
	for(ll i=0;i<n;i++){
		string s;
		cin>>s;
		add(s);
	}
	comp(1);
	compp(1);
	dfs(1);
	cout<<dp[1][k];

}

/*
	  .      _______    __    ___     ________      ________       _________     _________   ________
	  .     /       \  |  |  /  /    /        \    |        \     /         \   |        |  |   __   \
	  .    /   _____/  |  | /  /    /    ___   \   |   ___   \   |   _______/   |  ______|  |  |  \   \
	  .   /   /        |  |/  /    /    /   \   \  |  |   \   \  |  (______     |  |_____   |  |__/   /
	  .   |  |         |     /     |   /     \  |  |  |    |  |   \        \    |        |  |      __/
	  .   |  |         |     \     |   \     /  |  |  |    |  |    \______  \   |  ______|  |      \
	  .   \   \_____   |  |\  \    \    \___/   /  |  |___/   /    _______) |   |  |_____   |   |\  \
	  .    \        \  |  | \  \    \          /   |         /    /         /   |        |  |   | \  \
	  .     \_______/  |__|  \__\    \________/    |________/     \________/    |________|  |___|  \__\
 */


#include<bits/stdc++.h>
#define ll int
#define pb push_back
#define mp make_pair
#define ld long double
#define F first
#define S second

using namespace :: std;

const ll maxn=2100*500;
const ll maxm=4100;
const ll mod=1e9+7;
const ll inf=1e9+500;

vector<pair<char,pair<ll,ll > > > bach[maxn];
ll cn=2;

ll en[maxn];

ll trii[maxm][26];
ll vazn[maxm][26];
ll enn[maxm];
ll sz[maxn];
ll cnn=1;

ll k;
ll dp[maxm][2100];

void add(string s){
	ll p=1;
	for(ll i=0;i<s.size();i++){
		s[i]-='a';
		char c=s[i];

		bool peyda=0;
		for(ll j=0;j<bach[p].size();j++){
			if(bach[p][j].F==c){
				peyda=1;
				p=bach[p][j].S.F;
				break;
			}
		}
		if(!peyda){
			bach[p].pb(mp(c,mp(cn,1)));
			p=cn;
			cn++;
		}
	}
	en[p]++;
}
ll compp(ll p){
	ll kh=cnn;
	cnn++;
	for(ll i=0;i<bach[p].size();i++){
		ll v=compp(bach[p][i].S.F);
		trii[kh][bach[p][i].F]=v;
		vazn[kh][bach[p][i].F]=bach[p][i].S.S;
	}
	enn[kh]=en[p];
	return kh;
}
void  comp(ll p){
	for(ll i=0;i<bach[p].size();i++){
		comp(bach[p][i].S.F);
	}
	for(ll i=0;i<bach[p].size();i++){
		char c=bach[p][i].F;
		ll v=bach[p][i].S.F;
		if(bach[v].size()==1 && en[v]==0){
			bach[p][i].S.S+=bach[v][0].S.S;
			bach[p][i].S.F=bach[v][0].S.F;
		}
	}
}
void dfs(ll a){

	sz[a]=enn[a];
	for(ll i=0;i<=sz[a];i++){
		dp[a][i]=0;
	}
	for(ll i=0;i<26;i++){
		ll v=trii[a][i];
		if(v!=0){
			dfs(v);
			for(ll p=sz[a]+sz[v];p>=0;p--){
				for(ll k=0;k<=sz[v];k++){
					ll j=p-k;
					if(j<0 || j>sz[a]){
						continue;
					}
					dp[a][p]=max(dp[a][p],dp[a][j]+dp[v][k]+vazn[a][i]*k*(k-1)/2);
				}
			}
			sz[a]+=sz[v];
		}
	}
}
int main(){

	for(ll i=0;i<maxm;i++){
		for(ll j=0;j<2100;j++){
			dp[i][j]=-inf;
		}
	}
	ll n;
	cin>>n>>k;
	for(ll i=0;i<n;i++){
		string s;
		cin>>s;
		add(s);
	}
	comp(1);
	compp(1);
	dfs(1);
	cout<<dp[1][k];

}

/*
	  .      _______    __    ___     ________      ________       _________     _________   ________
	  .     /       \  |  |  /  /    /        \    |        \     /         \   |        |  |   __   \
	  .    /   _____/  |  | /  /    /    ___   \   |   ___   \   |   _______/   |  ______|  |  |  \   \
	  .   /   /        |  |/  /    /    /   \   \  |  |   \   \  |  (______     |  |_____   |  |__/   /
	  .   |  |         |     /     |   /     \  |  |  |    |  |   \        \    |        |  |      __/
	  .   |  |         |     \     |   \     /  |  |  |    |  |    \______  \   |  ______|  |      \
	  .   \   \_____   |  |\  \    \    \___/   /  |  |___/   /    _______) |   |  |_____   |   |\  \
	  .    \        \  |  | \  \    \          /   |         /    /         /   |        |  |   | \  \
	  .     \_______/  |__|  \__\    \________/    |________/     \________/    |________|  |___|  \__\
 */


#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define mp make_pair
#define ld long double
#define F first
#define S second

using namespace :: std;

const ll maxn=2100*500;
const ll maxm=2100;
const ll mod=1e9+7;
const ll inf=1e9+500;

ll tri[maxm][26];
ll en [maxn];
ll vaz[maxn][26];
vector<char> bach[maxn];
ll cn=2;

ll trii[maxm][26];
ll vazn[maxm][26];
ll enn[maxm];
ll sz[maxn];
ll cnn=1;

ll k;
ll dp[maxm][2100];

void add(string s){
	ll p=1;
	for(ll i=0;i<s.size();i++){
		s[i]-='a';
		char c=s[i];
		if(tri[p][c]==0){
			tri[p][c]=cn;
			bach[p].pb(c);
			cn++;
		}
		p=tri[p][c];
	}
	en[p]++;
}
ll compp(ll p){
	ll kh=cnn;
	cnn++;
	for(ll i=0;i<26;i++){
		if(tri[p][i]!=0){
			ll v=compp(tri[p][i]);
			trii[kh][i]=v;
			vazn[kh][i]=vaz[p][i];
		}
	}
	enn[kh]=en[p];
	return kh;
}
void  comp(ll p){
	for(ll i=0;i<bach[p].size();i++){
		comp(tri[p][bach[p][i]]);
		vaz[p][bach[p][i]]=1;
	}
	for(ll i=0;i<bach[p].size();i++){
		char c=bach[p][i];
		ll v=tri[p][c];
		if(bach[v].size()==1 && en[v]==0){
			char cc=bach[v][0];
			tri[p][c]=tri[v][cc];
			vaz[p][c]+=vaz[v][cc];
		}
	}
}
void dfs(ll a){

	sz[a]=enn[a];
	for(ll i=0;i<=sz[a];i++){
		dp[a][i]=0;
	}
	for(ll i=0;i<26;i++){
		ll v=trii[a][i];
		if(v!=0){
			dfs(v);
			for(ll j=0;j<=sz[a];j++){
				for(ll k=0;k<=sz[v];k++){
					dp[a][j+k]=max(dp[a][j+k],dp[a][j]+dp[v][k]+vazn[a][i]*k*(k-1)/2);
				}
			}
			sz[a]+=sz[v];
		}
	}
}
int main(){

	for(ll i=0;i<maxm;i++){
		for(ll j=0;j<2100;j++){
			dp[i][j]=-inf;
		}
	}
	ll n;
	cin>>n>>k;
	for(ll i=0;i<n;i++){
		string s;
		cin>>s;
		add(s);
	}
	comp(1);
	compp(1);
	dfs(1);
	cout<<dp[1][k];

}

/*
	  .      _______    __    ___     ________      ________       _________     _________   ________
	  .     /       \  |  |  /  /    /        \    |        \     /         \   |        |  |   __   \
	  .    /   _____/  |  | /  /    /    ___   \   |   ___   \   |   _______/   |  ______|  |  |  \   \
	  .   /   /        |  |/  /    /    /   \   \  |  |   \   \  |  (______     |  |_____   |  |__/   /
	  .   |  |         |     /     |   /     \  |  |  |    |  |   \        \    |        |  |      __/
	  .   |  |         |     \     |   \     /  |  |  |    |  |    \______  \   |  ______|  |      \
	  .   \   \_____   |  |\  \    \    \___/   /  |  |___/   /    _______) |   |  |_____   |   |\  \
	  .    \        \  |  | \  \    \          /   |         /    /         /   |        |  |   | \  \
	  .     \_______/  |__|  \__\    \________/    |________/     \________/    |________|  |___|  \__\
 */


//let's do it
 #include <iostream>
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define inf 10000000
#define mod 1000000007
#define pb push_back
#define mp make_pair
#define all(v) v.begin(),v.end()
#define S second
#define F first
#define boost1 ios::sync_with_stdio(false);
#define boost2 cin.tie(0);
#define mem(a,val) memset(a,val,sizeof a)
#define endl "\n"
#define maxn 100001

int n,k,lcp[2005];
string s[2005];

int get(string s1,string s2)
{
	int got=0;
	for(int i=0;i<min(s1.length(),s2.length());i++)
	{
		if(s1[i]!=s2[i])
		break;
		got++;
	}
	return got;
}
vector<int>solve(int l,int r)
{
	if(r<=l)
	return vector<int>(k+1,0);
	int mini=inf;
	int pos=-1;
	for(int i=l;i<r;i++)
	{
		if(lcp[i]<mini)
		{
			mini=lcp[i];
			pos=i;
		}
	}
	vector<int>lft=solve(l,pos);
	vector<int>rght=solve(pos+1,r);
	vector<int>ans(k+1,0);
	for(int i=0;i<=min(k,pos-l+1);i++)
	{
		for(int j=0;j<=r-pos && i+j<=k;j++)
		ans[i+j]=max(ans[i+j],lft[i]+rght[j]+mini*i*j);
	}
	return ans;
}
int main()
{
	boost1;boost2;
	int i;
	cin>>n>>k;
	for(i=1;i<=n;i++)
	cin>>s[i];
	sort(s+1,s+n+1);
	for(i=1;i<n;i++)
	lcp[i]=get(s[i],s[i+1]);
	/*for(i=1;i<n;i++)
	cout<<lcp[i]<<" ";
	cout<<endl;*/
	vector<int>ans=solve(1,n);
	cout<<ans[k];
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long lint;
typedef pair<int, int> pi;
const int MAXN = 2005;
const int MAXT = 1000005;
const int mod = 1e9 + 7;

int n, k;
int trie[MAXT][26], term[MAXT], cnt;
int dfn[MAXT], dout[MAXT], par[MAXT], dep[MAXT], piv;
vector<int> v;

bool in(int s, int t){
	return dfn[s] <= dfn[t] && dout[t] <= dout[s];
}

void dfs(int x){
	dfn[x] = ++piv;
	if(term[x]) v.push_back(x);
	for(int i=0; i<26; i++){
		if(trie[x][i]) dfs(trie[x][i]);
	}
	dout[x] = piv;
}

int lca(int x, int y){
	while(dep[x] < dep[y]) y = par[y];
	while(dep[x] > dep[y]) x = par[x];
	while(x != y){
		x = par[x];
		y = par[y];
	}
	return x;
}

vector<pi> gph[2 * MAXN];
lint dp[2 * MAXN][2 * MAXN];
int sz[2 * MAXN];

void dfs2(int x){
	sz[x] = term[v[x]];
	for(auto &i : gph[x]){
		dep[i.second] = dep[x] + i.first;
		dfs2(i.second);
		sz[x] += sz[i.second];
	}
}

int main(){
	char buf[505];
	scanf("%d %d",&n,&k);
	for(int i=0; i<n; i++){
		scanf("%s", buf);
		int p = 0;
		for(int j=0; buf[j]; j++){
			if(!trie[p][buf[j] - 'a']){
				trie[p][buf[j] - 'a'] = ++cnt;
				par[cnt] = p;
				dep[cnt] = dep[p] + 1;
			}
			p = trie[p][buf[j] - 'a'];
		}
		term[p]++;
	}
	dfs(0);
	sort(v.begin(), v.end(), [&](const int &a, const int &b){
		return dfn[a] < dfn[b];
	});
	v.push_back(0);
	{
		int sz = v.size();
		for(int i=0; i+1<sz; i++){
			v.push_back(lca(v[i], v[i+1]));
		}
	}
	sort(v.begin(), v.end(), [&](const int &a, const int &b){
		return dfn[a] < dfn[b];
	});
	v.resize(unique(v.begin(), v.end()) - v.begin());
	stack<int> stk;
	for(int i=0; i<v.size(); i++){
		while(!stk.empty() && !in(v[stk.top()], v[i])) stk.pop();
		if(i > 0) gph[stk.top()].push_back(pi(dep[v[i]] - dep[v[stk.top()]], i));
		stk.push(i);
	}
	dfs2(0);
	for(int i=v.size() - 1; i>=0; i--){
		for(int j=0; j<=term[v[i]]; j++) dp[i][j] = 1ll * j * (j-1) / 2 * dep[i];
		int cur = term[v[i]];
		for(auto &j : gph[i]){
			lint nxt[2 * MAXN] = {};
			for(int k=0; k<=sz[j.second]; k++){
				for(int l=0; l<=cur; l++){
					nxt[k + l] = max(nxt[k + l], dp[j.second][k] + dp[i][l] + 1ll * k * l * dep[i]);
				}
			}
			memcpy(dp[i], nxt, sizeof(nxt));
			cur += sz[j.second];
		}
	}
	cout << dp[0][k];
}


// 6:17
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <limits>
#include <memory>
#include <queue>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

#define all(a) (a).begin(), (a).end()
#define sz(a) static_cast<int>((a).size())
#define fillchar(a, x) memset(a, x, sizeof(a))
#define rep(i, a, b) for(int i=int(a); i<=int(b); ++i)
#define irep(i, a, b) for(int i=int(a); i>=int(b); --i)
#define replr(i, a, b) rep(i, a, (b)-1)
#define reprl(i, a, b) irep(i, (b)-1, a)
#define repn(i, n) rep(i, 0, (n)-1)
#define irepn(i, n) irep(i, (n)-1, 0)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
typedef long long LL;
typedef pair<LL,LL> PLL;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
typedef vector<LL> VL;
typedef vector<int> VI;
typedef vector<PII> VPI;
typedef vector<string> VS;
template<class T, class S> ostream& operator<<(ostream& os, const pair<T, S>& v) { return os<<"("<<v.first<<", "<<v.second<<")"; }
template<class T> ostream& operator<<(ostream& os, const vector<T>& v) { os<<"["; repn(i, sz(v)) { if(i) os<<", "; os<<v[i]; } return os<<"]"; }
template<class T> bool setmax(T &_a, T _b) { if(_b>_a) { _a=_b; return true; } return false; }
template<class T> bool setmin(T &_a, T _b) { if(_b<_a) { _a=_b; return true; } return false; }
template<class T> T gcd(T _a, T _b) { return _b==0?_a:gcd(_b,_a%_b); }

struct Node {
    vector<Node*> ys;
    int h=-1;
};

int main() {
    int n, k;
    cin>>n>>k;
    VS ss(n);
    repn(i, n) cin>>ss[i];
    sort(all(ss));
    VI height(n-1);
    repn(i, n-1) {
        int j=0;
        while(j<sz(ss[i]) && j<sz(ss[i+1]) && ss[i][j]==ss[i+1][j]) {
            ++j;
        }
        height[i]=j;
    }

    const function<Node*(int, int)> build=[&](int l, int r) {
        Node* x=new Node();
        if(l+1==r) return x;
        int h=*min_element(height.begin()+l, height.begin()+r-1);
        x->h=h;
        int i=l;
        replr(j, l, r) {
            if(j==r-1 || height[j]==h) {
                x->ys.pb(build(i, j+1));
                i=j+1;
            }
        }
        return x;
    };
    Node* root=build(0, n);

    const function<VI(Node*)> solve=[&](Node* x) {
        if(x->h<0) return VI{0, 0};
        VI ans{0};
        for(Node* y: x->ys) {
            VI tmp=solve(y);
            VI r(sz(ans)+sz(tmp)-1);
            repn(i, sz(ans)) repn(j, sz(tmp)) {
                setmax(r[i+j], ans[i]+tmp[j]+i*j*x->h);
            }
            ans=r;
        }
        if(sz(ans)>k+1) ans.resize(k+1);
        return ans;
    };
    VI ans=solve(root);
    if(k<sz(ans)) {
        cout<<ans[k]<<endl;
    } else {
        cout<<0<<endl;
    }

    return 0;
}


/*

*/
#include <bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
#define pb push_back
#define ll long long
typedef pair<int,int> pii;
const int maxn=2010;
const int maxlen=510;
const int mxnode=maxlen*maxn;
vector<int>dp[maxn*maxlen];
int cnt,val[maxn*maxlen],sz[mxnode],n,k,pos[mxnode];
vector<int>vect[maxn*maxlen];
string s[maxn];
int rek(int lvl,int l,int r){

    ++cnt;
    int node=cnt;

    while(l<=r && lvl==s[l].size()){l++;val[node]++;}

    if(l>r)return node;

    int l2=l,r2=l;

    while(1){

        while(r2+1<=r && s[r2+1][lvl]==s[r2][lvl])r2++;

        vect[node].pb(rek(lvl+1,l2,r2));

        l2=r2+1;
        r2=l2;

        if(l2>r)break;
    }

    return node;
}
void getsz(int x){

    sz[x]=val[x];
    for(int i=0;i<vect[x].size();i++){
        int id=vect[x][i];

        getsz(id);
        sz[x]+=sz[id];
    }
}
void build_tree(){
    rek(0,1,n);
    getsz(1);
}
int go(int x,int k){

    ///printf("%d X\n",x);

    if(pos[x]){
        if(k>sz[x])return 0;
        return dp[x][k];
    }

    ///printf("%d X\n",x);

    pos[x]=1;
    dp[x].resize(sz[x]+1);
    for(int i=1;i<dp[x].size();i++)dp[x][i]=-1;

    for(int i=0;i<vect[x].size();i++){
        int id=vect[x][i];

        int up;
        for(int j=0;j<dp[x].size();j++){
            if(dp[x][j]!=-1)up=j;
            else break;
        }

        for(int j=up;j>=0;j--){
            if(dp[x][j]==-1)break;

            int pom=dp[x][j];
            for(int p=1;p<=sz[id];p++){
                int sum=pom+j*p+(p*(p-1))/2+go(id,p);

                dp[x][j+p]=max(dp[x][j+p],sum);
            }
        }

    }
    ///printf("%d X\n",x);

    int up;
    for(int j=0;j<dp[x].size();j++){
        if(dp[x][j]!=-1)up=j;
        else break;
    }

    ///printf("%d X\n",x);

    for(int j=up;j>=0;j--){

        int pom=dp[x][j];
        for(int i=1;i<=val[x];i++){
            int sum=pom+j*i+(i*(i-1))/2;

            ///printf("%d | %d %d %d\n",x,j,i,sum);
            dp[x][j+i]=max(dp[x][j+i],sum);
            ///printf("%d DP\n",dp[x][j+i]);
        }
    }

    ///printf("%d X\n",x);

    return dp[x][k];
}
int main(){

    ///freopen("test.txt","r",stdin);

    scanf("%d %d",&n,&k);

    for(int i=1;i<=n;i++)cin>>s[i];
    sort(s+1,s+n+1);

    build_tree();

    printf("%d\n",go(1,k)-(k*(k-1))/2);

    ///for(int i=0;i<=2;i++)printf("%d %d AD\n",go(3,i),sz[3]);

	return 0;
}


/*input
4 3
aaa
abba
abbc
abbd
*/
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
#define REP(i,j,k)     for(int i = j ; i < k ; ++i)
#define RREP(i,j,k)    for(int i = j ; i >=k ; --i)
#define A    first
#define B    second
#define mp   make_pair
#define pb   emplace_back
#define PII pair<int , int>
#define MEM(i,j)   memset(i , j , sizeof i)
#define ALL(i)     i.begin() , i.end()
#define DBGG(i,j)     cout << i << " " << j << endl
#define DB4(i,j,k,l)  cout << i << " " << j << " " << k << " " << l << endl
#define IOS cin.tie(0) , cout.sync_with_stdio(0)
#define endl "\n"
///------------------------------------------------------------
#define MAX 2020
#define INF 0x3f3f3f3f
#define AC  10430579
#define mod 1000000007LL

int n , m , lcp[MAX];
string s[MAX];
map<int , int> dp;
int trs(int a , int b , int c){
    return ((1LL * a * 10430579 + b) % mod * AC + c) % mod;
    // return mp(a , mp(b , c));
}
int DP(int take , int l , int r){
    if(dp.find(trs(take , l , r)) != dp.end()) return dp[trs(take , l , r)];
    if(l == r) return dp[trs(take , l , r)] = 0;
    else {
        int sml = INF , idx , val = 0;
        REP(i , l + 1 , r + 1) if(lcp[i] < sml) sml = lcp[i] , idx = i;
        REP(i , 0 , take + 1){
            int v1 = i , v2 = take - i;
            int base = v1 * v2 * sml;
            if(v1 <= idx - l && v2 <= r - idx + 1){
                val = max(val , DP(v1 , l , idx - 1) + DP(v2 , idx , r) + base);
            }
        }
        return dp[trs(take , l , r)] = val;
    }
}
int32_t main(){
    IOS;
    cin >> n >> m;
    REP(i , 1 , n + 1) cin >> s[i];
    sort(s + 1 , s + 1 + n);
    REP(i , 2 , n + 1){
        lcp[i] = 0;
        while(lcp[i] < s[i - 1].size() && lcp[i] < s[i].size() && s[i - 1][lcp[i]] == s[i][lcp[i]]) lcp[i]++;
    }
    cout << DP(m , 1 , n)<< endl;
    return 0;
}


/*input
4 3
aaa
abba
abbc
abbd
*/
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
#define REP(i,j,k)     for(int i = j ; i < k ; ++i)
#define RREP(i,j,k)    for(int i = j ; i >=k ; --i)
#define A    first
#define B    second
#define mp   make_pair
#define pb   emplace_back
#define PII pair<int , int>
#define MEM(i,j)   memset(i , j , sizeof i)
#define ALL(i)     i.begin() , i.end()
#define DBGG(i,j)     cout << i << " " << j << endl
#define DB4(i,j,k,l)  cout << i << " " << j << " " << k << " " << l << endl
#define IOS cin.tie(0) , cout.sync_with_stdio(0)
#define endl "\n"
///------------------------------------------------------------
#define MAX 2020
#define INF 0x3f3f3f3f
#define AC  10430579
#define mod 1000000007LL

int n , m , lcp[MAX] , dp[MAX][MAX] , idx[MAX][MAX] , idxpo = 0;
string s[MAX];

int DP(int take , int l , int r){
    if(idx[l][r] == 0) idx[l][r] = ++idxpo;
    assert(idxpo < n + 10);

    if(dp[take][idx[l][r]] != -1) return dp[take][idx[l][r]];
    if(l == r) return dp[take][idx[l][r]] = 0;
    else {
        int sml = INF , tmp , val = 0;
        REP(i , l + 1 , r + 1) if(lcp[i] < sml) sml = lcp[i] , tmp = i;
        REP(i , 0 , take + 1){
            int v1 = i , v2 = take - i;
            int base = v1 * v2 * sml;
            if(v1 <= tmp - l && v2 <= r - tmp + 1){
                val = max(val , DP(v1 , l , tmp - 1) + DP(v2 , tmp , r) + base);
            }
        }
        return dp[take][idx[l][r]] = val;
    }
}
int32_t main(){
    IOS;
    cin >> n >> m;
    REP(i , 1 , n + 1) cin >> s[i];
    sort(s + 1 , s + 1 + n);
    MEM(dp , -1);
    REP(i , 2 , n + 1){
        lcp[i] = 0;
        while(lcp[i] < s[i - 1].size() && lcp[i] < s[i].size() && s[i - 1][lcp[i]] == s[i][lcp[i]]) lcp[i]++;
    }
    cout << DP(m , 1 , n)<< endl;
    return 0;
}


/*input
4 3
aaa
abba
abbc
abbd
*/
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
#define REP(i,j,k)     for(int i = j ; i < k ; ++i)
#define RREP(i,j,k)    for(int i = j ; i >=k ; --i)
#define A    first
#define B    second
#define mp   make_pair
#define pb   emplace_back
#define PII pair<int , int>
#define MEM(i,j)   memset(i , j , sizeof i)
#define ALL(i)     i.begin() , i.end()
#define DBGG(i,j)     cout << i << " " << j << endl
#define DB4(i,j,k,l)  cout << i << " " << j << " " << k << " " << l << endl
#define IOS cin.tie(0) , cout.sync_with_stdio(0)
#define endl "\n"
///------------------------------------------------------------
#define MAX 2020
#define INF 0x3f3f3f3f
#define AC  10430579
#define mod 1000000007LL

int n , m , lcp[MAX];
string s[MAX];
cc_hash_table<int , int> dp;
int trs(int a , int b , int c){
    return ((1LL * a * 10430579 + b) % mod * AC + c) % mod;
    // return mp(a , mp(b , c));
}
int DP(int take , int l , int r){
    if(dp.find(trs(take , l , r)) != dp.end()) return dp[trs(take , l , r)];
    if(l == r) return dp[trs(take , l , r)] = 0;
    else {
        int sml = INF , idx , val = 0;
        REP(i , l + 1 , r + 1) if(lcp[i] < sml) sml = lcp[i] , idx = i;
        REP(i , 0 , take + 1){
            int v1 = i , v2 = take - i;
            int base = v1 * v2 * sml;
            if(v1 <= idx - l && v2 <= r - idx + 1){
                val = max(val , DP(v1 , l , idx - 1) + DP(v2 , idx , r) + base);
            }
        }
        return dp[trs(take , l , r)] = val;
    }
}
int32_t main(){
    IOS;
    cin >> n >> m;
    REP(i , 1 , n + 1) cin >> s[i];
    sort(s + 1 , s + 1 + n);
    REP(i , 2 , n + 1){
        lcp[i] = 0;
        while(lcp[i] < s[i - 1].size() && lcp[i] < s[i].size() && s[i - 1][lcp[i]] == s[i][lcp[i]]) lcp[i]++;
    }
    cout << DP(m , 1 , n)<< endl;
    return 0;
}


/*input
20 10
commonprefixhello
commonprefixhow
commonprefixdo
commonprefixyou
commonprefixdo
commonprefixaaabd
commonprefixaaab
commonprefixabddef
commonprefixbaaaae
commonprefixbaae
commonprefixbaaade
commonprefixaedbed
commonprefixaeeee
commonprefixbbbbb
commonprefixbebe
commonprefixbebeb
commonprefixbye
commonprefixsee
commonprefixyou
commonprefixlater
*/
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
#define REP(i,j,k)     for(int i = j ; i < k ; ++i)
#define RREP(i,j,k)    for(int i = j ; i >=k ; --i)
#define A    first
#define B    second
#define mp   make_pair
#define pb   emplace_back
#define PII pair<int , int>
#define MEM(i,j)   memset(i , j , sizeof i)
#define ALL(i)     i.begin() , i.end()
#define DBGG(i,j)     cout << i << " " << j << endl
#define DB4(i,j,k,l)  cout << i << " " << j << " " << k << " " << l << endl
#define IOS cin.tie(0) , cout.sync_with_stdio(0)
#define endl "\n"
///------------------------------------------------------------
#define MAX 4020
#define INF 0x3f3f3f3f
#define AC  10430579
#define mod 1000000007LL

int n , m , lcp[MAX] , dp[MAX][MAX] , idx[MAX][MAX] , idxpo = 0;
string s[MAX];

int DP(int take , int l , int r){
    // if(idx[l][r] == 0) DBGG(l , r);
    if(idx[l][r] == 0) idx[l][r] = ++idxpo;
    assert(idxpo < n + n + 10);

    if(dp[take][idx[l][r]] != -1) return dp[take][idx[l][r]];
    if(l == r) return dp[take][idx[l][r]] = 0;
    else {
        int sml = INF , tmp , val = 0;
        REP(i , l + 1 , r + 1) if(lcp[i] < sml) sml = lcp[i] , tmp = i;
        REP(i , 0 , take + 1){
            int v1 = i , v2 = take - i;
            int base = v1 * v2 * sml;
            if(v1 <= tmp - l && v2 <= r - tmp + 1){
                val = max(val , DP(v1 , l , tmp - 1) + DP(v2 , tmp , r) + base);
            }
        }
        return dp[take][idx[l][r]] = val;
    }
}
int32_t main(){
    IOS;
    cin >> n >> m;
    REP(i , 1 , n + 1) cin >> s[i];
    sort(s + 1 , s + 1 + n);
    MEM(dp , -1);
    REP(i , 2 , n + 1){
        lcp[i] = 0;
        while(lcp[i] < s[i - 1].size() && lcp[i] < s[i].size() && s[i - 1][lcp[i]] == s[i][lcp[i]]) lcp[i]++;
    }
    cout << DP(m , 1 , n)<< endl;
    return 0;
}


/*input
4 3
aaa
abba
abbc
abbd
*/
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
#define REP(i,j,k)     for(int i = j ; i < k ; ++i)
#define RREP(i,j,k)    for(int i = j ; i >=k ; --i)
#define A    first
#define B    second
#define mp   make_pair
#define pb   emplace_back
#define PII pair<int , int>
#define MEM(i,j)   memset(i , j , sizeof i)
#define ALL(i)     i.begin() , i.end()
#define DBGG(i,j)     cout << i << " " << j << endl
#define DB4(i,j,k,l)  cout << i << " " << j << " " << k << " " << l << endl
#define IOS cin.tie(0) , cout.sync_with_stdio(0)
#define endl "\n"
///------------------------------------------------------------
#define MAX 2020
#define INF 0x3f3f3f3f
#define AC  10430579
#define mod 1000000007LL

int n , m , lcp[MAX] , dp[MAX][MAX] , idx[MAX][MAX] , idxpo = 0;
string s[MAX];

int DP(int take , int l , int r){
    if(idx[l][r] == 0) idx[l][r] = ++idxpo;

    if(dp[take][idx[l][r]] != -1) return dp[take][idx[l][r]];
    if(l == r) return dp[take][idx[l][r]] = 0;
    else {
        int sml = INF , tmp , val = 0;
        REP(i , l + 1 , r + 1) if(lcp[i] < sml) sml = lcp[i] , tmp = i;
        REP(i , 0 , take + 1){
            int v1 = i , v2 = take - i;
            int base = v1 * v2 * sml;
            if(v1 <= tmp - l && v2 <= r - tmp + 1){
                val = max(val , DP(v1 , l , tmp - 1) + DP(v2 , tmp , r) + base);
            }
        }
        return dp[take][idx[l][r]] = val;
    }
}
int32_t main(){
    IOS;
    cin >> n >> m;
    REP(i , 1 , n + 1) cin >> s[i];
    sort(s + 1 , s + 1 + n);
    MEM(dp , -1);
    REP(i , 2 , n + 1){
        lcp[i] = 0;
        while(lcp[i] < s[i - 1].size() && lcp[i] < s[i].size() && s[i - 1][lcp[i]] == s[i][lcp[i]]) lcp[i]++;
    }
    cout << DP(m , 1 , n)<< endl;
    return 0;
}


/*input
4 3
aaa
abba
abbc
abbd
*/
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
#define REP(i,j,k)     for(int i = j ; i < k ; ++i)
#define RREP(i,j,k)    for(int i = j ; i >=k ; --i)
#define A    first
#define B    second
#define mp   make_pair
#define pb   emplace_back
#define PII pair<int , int>
#define MEM(i,j)   memset(i , j , sizeof i)
#define ALL(i)     i.begin() , i.end()
#define DBGG(i,j)     cout << i << " " << j << endl
#define DB4(i,j,k,l)  cout << i << " " << j << " " << k << " " << l << endl
#define IOS cin.tie(0) , cout.sync_with_stdio(0)
#define endl "\n"
///------------------------------------------------------------
#define MAX 2020
#define INF 0x3f3f3f3f

int n , m , lcp[MAX];
string s[MAX];
map<pair<int , pair<int , int>> , int> dp;
pair<int , pair<int , int>> trs(int a , int b , int c){
    return mp(a , mp(b , c));
}
int DP(int take , int l , int r){
    if(dp.find(trs(take , l , r)) != dp.end()) return dp[trs(take , l , r)];
    if(l == r) return dp[trs(take , l , r)] = 0;
    else {
        int sml = INF , idx , val = 0;
        REP(i , l + 1 , r + 1) if(lcp[i] < sml) sml = lcp[i] , idx = i;
        REP(i , 0 , take + 1){
            int v1 = i , v2 = take - i;
            int base = v1 * v2 * sml;
            if(v1 <= idx - l && v2 <= r - idx + 1){
                val = max(val , DP(v1 , l , idx - 1) + DP(v2 , idx , r) + base);
            }
        }
        return dp[trs(take , l , r)] = val;
    }
}
int32_t main(){
    IOS;
    cin >> n >> m;
    REP(i , 1 , n + 1) cin >> s[i];
    sort(s + 1 , s + 1 + n);
    REP(i , 2 , n + 1){
        lcp[i] = 0;
        while(lcp[i] < s[i - 1].size() && lcp[i] < s[i].size() && s[i - 1][lcp[i]] == s[i][lcp[i]]) lcp[i]++;
    }
    cout << DP(m , 1 , n)<< endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
struct node
{char s[505];
int len;
}t[2005];
int hgt[2005],cnt=0,n,k;
int dp[2005][2005];
inline bool cmp(node a,node b)
{for (int i=1;i<=a.len&&i<=b.len;i++)
{if (a.s[i]!=b.s[i]) return a.s[i]<b.s[i];
}
return a.len<b.len;
}
inline int min(int a,int b)
{return a<b?a:b;}
inline int max(int a,int b)
{return a>b?a:b;}
int cal(int l,int r)
{int id=++cnt,i,j;
if (l==r) return id;
int minn=666,pos=-1;
for (i=l;i<r;i++)
{if (hgt[i]<minn) {minn=hgt[i];pos=i;}
}
int lc=cal(l,pos),rc=cal(pos+1,r);
for (i=1;i<=k&&i<=r-l+1;i++)
{for (j=max(0,i-min(k,r-pos));j<=min(i,pos-l+1);j++)
{dp[id][i]=max(dp[id][i],dp[lc][j]+dp[rc][i-j]+minn*j*(i-j));}
}
return id;
}
int main (){
	int i,j,l;
	scanf ("%d%d",&n,&k);
	for (i=1;i<=n;i++)
	{scanf ("%s",t[i].s+1);
	t[i].len=strlen(t[i].s+1);
	}
	sort(t+1,t+n+1,cmp);
	for (i=1;i<n;i++)
	{hgt[i]=min(t[i].len,t[i+1].len);
	for (j=1;j<=t[i].len&&j<=t[i+1].len;j++)
	{if (t[i].s[j]!=t[i+1].s[j])
	{hgt[i]=j-1;break;}
	}
	}
	int o=cal(1,n);
	printf ("%d\n",dp[o][k]);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
struct node
{char s[505];
int len;
}t[2005];
int hgt[2005],cnt=0,n,k;
int dp[4005][2005];
inline bool cmp(node a,node b)
{for (int i=1;i<=a.len&&i<=b.len;i++)
{if (a.s[i]!=b.s[i]) return a.s[i]<b.s[i];
}
return a.len<b.len;
}
inline int min(int a,int b)
{return a<b?a:b;}
inline int max(int a,int b)
{return a>b?a:b;}
int cal(int l,int r)
{int id=++cnt,i,j;
if (l==r) return id;
int minn=666,pos=-1;
for (i=l;i<r;i++)
{if (hgt[i]<minn) {minn=hgt[i];pos=i;}
}
int lc=cal(l,pos),rc=cal(pos+1,r);
for (i=1;i<=k&&i<=r-l+1;i++)
{for (j=max(0,i-min(k,r-pos));j<=min(i,pos-l+1);j++)
{dp[id][i]=max(dp[id][i],dp[lc][j]+dp[rc][i-j]+minn*j*(i-j));}
}
return id;
}
int main (){
	int i,j,l;
	scanf ("%d%d",&n,&k);
	for (i=1;i<=n;i++)
	{scanf ("%s",t[i].s+1);
	t[i].len=strlen(t[i].s+1);
	}
	sort(t+1,t+n+1,cmp);
	for (i=1;i<n;i++)
	{hgt[i]=min(t[i].len,t[i+1].len);
	for (j=1;j<=t[i].len&&j<=t[i+1].len;j++)
	{if (t[i].s[j]!=t[i+1].s[j])
	{hgt[i]=j-1;break;}
	}
	}
	int o=cal(1,n);
	printf ("%d\n",dp[o][k]);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
struct node
{char s[505];
int len;
}t[2005];
int hgt[2005],cnt=0,n,k;
int dp[2005][2005];
inline bool cmp(node a,node b)
{for (int i=1;i<=a.len&&i<=b.len;i++)
{if (a.s[i]!=b.s[i]) return a.s[i]<b.s[i];
}
return a.len<b.len;
}
inline int min(int a,int b)
{return a<b?a:b;}
inline int max(int a,int b)
{return a>b?a:b;}
int cal(int l,int r)
{int id=++cnt,i,j;
if (l==r) return id;
int minn=666,pos=-1;
for (i=l;i<r;i++)
{if (hgt[i]<minn) {minn=hgt[i];pos=i;}
}
int lc=cal(l,pos),rc=cal(pos+1,r);
for (i=1;i<=k&&i<=r-l+1;i++)
{for (j=i-min(k,r-pos);j<=min(i,pos-l+1);j++)
{dp[id][i]=max(dp[id][i],dp[lc][j]+dp[rc][i-j]+minn*j*(i-j));}
}
return id;
}
int main (){
	int i,j,l;
	scanf ("%d%d",&n,&k);
	for (i=1;i<=n;i++)
	{scanf ("%s",t[i].s+1);
	t[i].len=strlen(t[i].s+1);
	}
	sort(t+1,t+n+1,cmp);
	for (i=1;i<n;i++)
	{hgt[i]=min(t[i].len,t[i+1].len);
	for (j=1;j<=t[i].len&&j<=t[i+1].len;j++)
	{if (t[i].s[j]!=t[i+1].s[j])
	{hgt[i]=j-1;break;}
	}
	}
	int o=cal(1,n);
	printf ("%d\n",dp[o][k]);
	return 0;
}


/*
    Author: Nguyen Tan Bao

    Idea:
*/

#include <bits/stdc++.h>
#define FI first
#define SE second
#define EPS 1e-9
#define ALL(a) a.begin(),a.end()
#define SZ(a) int((a).size())
#define MS(s, n) memset(s, n, sizeof(s))
#define FOR(i,a,b) for (int i = (a); i <= (b); i++)
#define FORE(i,a,b) for (int i = (a); i >= (b); i--)
#define FORALL(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define WHATIS(x) cout << #x << " is " << x << endl;
#define ERROR(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); }
//__builtin_ffs(x) return 1 + index of least significant 1-bit of x
//__builtin_clz(x) return number of leading zeros of x
//__builtin_ctz(x) return number of trailing zeros of x

using namespace std;
using ll = long long;
using ld = double;
typedef pair<int, int> II;
typedef pair<II, int> III;
typedef complex<ld> cd;
typedef vector<cd> vcd;

void err(istream_iterator<string> it) {}
template<typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
    cout << *it << " = " << a << endl;
    err(++it, args...);
}

const ll MODBASE = 1000000007LL;
const int MAXN = 2010;
const int MAXM = 200010;
const int MAXK = 110;
const int MAXQ = 200010;

int n, K;
ll dp[MAXN * 2][MAXN], tmp[MAXN];

struct TrieNode {
    TrieNode *children[27];
    int depth, cnt;
};

TrieNode *getNode() {
    TrieNode *pNode =  new TrieNode;
    pNode->depth = 0;
    pNode->cnt = 0;
    FOR(i,0,26) pNode->children[i] = nullptr;
    return pNode;
}

void insert(TrieNode *root, string &key) {
    root->cnt++;
    TrieNode *pCrawl = root;
    FOR(i,0,SZ(key)-1) {
        int index = key[i] - 'a';
        if (key[i] == '$') index = 26;
        if (!pCrawl->children[index]) {
            pCrawl->children[index] = getNode();
            pCrawl->children[index]->depth = pCrawl->depth + 1;
        }
        pCrawl = pCrawl->children[index];
        pCrawl->cnt++;
    }
}

int nowId = 0;

int getId() {
    return nowId++;
}

int calc(TrieNode *root) {
    int nodeId = -1;
    int posChild = -1, cntChild = 0;
    FOR(i,0,26)
        if (root->children[i] != nullptr) {
            cntChild++;
            posChild = i;
        }

    // leaf of tree
    if (posChild == -1) {
        nodeId = getId();
        FOR(i,0,min(root->cnt,K)) dp[nodeId][i] = (ll) root->depth * i * (i - 1) / 2;
        return nodeId;
    }
    // if this node has only one children, go directly to it
    if (cntChild == 1) return calc(root->children[posChild]);

    // otherwise, use dp for each child
    nodeId = getId();
    FOR(i,0,K) dp[nodeId][i] = 0;
    int numOfString = 0;
    FOR(i,0,26)
        if (root->children[i] != nullptr) {
            int childNodeId = calc(root->children[i]);
            int numStringAtChild = root->children[i]->cnt;

            FOR(j,0,K) tmp[j] = 0;

            FOR(j,0,min(K,numOfString))
                FOR(k,0,min(K,numStringAtChild)) {
                    if (j + k <= K) tmp[j+k] = max(tmp[j+k], (ll) dp[nodeId][j] + dp[childNodeId][k] + (ll) j * k * root->depth);
                    else break;
                }

            FOR(j,0,K) dp[nodeId][j] = tmp[j];
            numOfString += numStringAtChild;

        }
    return nodeId;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(nullptr);
    cin >> n >> K;
    TrieNode *root = getNode();
    FOR(i,0,n-1) {
        string t;
        cin >> t;
        t = t + "$";
        insert(root, t);
    }
    int nodeId = calc(root);
    cout << dp[nodeId][K];
    return 0;
}


/*
    Author: Nguyen Tan Bao

    Idea:
*/

#include <bits/stdc++.h>
#define FI first
#define SE second
#define EPS 1e-9
#define ALL(a) a.begin(),a.end()
#define SZ(a) int((a).size())
#define MS(s, n) memset(s, n, sizeof(s))
#define FOR(i,a,b) for (int i = (a); i <= (b); i++)
#define FORE(i,a,b) for (int i = (a); i >= (b); i--)
#define FORALL(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define WHATIS(x) cout << #x << " is " << x << endl;
#define ERROR(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); }
//__builtin_ffs(x) return 1 + index of least significant 1-bit of x
//__builtin_clz(x) return number of leading zeros of x
//__builtin_ctz(x) return number of trailing zeros of x

using namespace std;
using ll = long long;
using ld = double;
typedef pair<int, int> II;
typedef pair<II, int> III;
typedef complex<ld> cd;
typedef vector<cd> vcd;

void err(istream_iterator<string> it) {}
template<typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
    cout << *it << " = " << a << endl;
    err(++it, args...);
}

const ll MODBASE = 1000000007LL;
const int MAXN = 2010;
const int MAXM = 200010;
const int MAXK = 110;
const int MAXQ = 200010;

int n, K, f[MAXN][MAXN], preF[MAXN][MAXN], cnt[26], numOfFirstChar[26];
vector<string> s;
ll group[MAXN][MAXN], g[26][MAXN], dp[30][MAXN];

int main() {
    ios::sync_with_stdio(0);
    cin.tie(nullptr);
    cin >> n >> K;
    FOR(i,0,n-1) {
        string t;
        cin >> t;
        s.emplace_back(t);
    }
    sort(ALL(s));
    FOR(i,0,n-1) {
        int l = i, r = n-1;
        FOR(j,0,SZ(s[i])-1) {
            char ch = s[i][j];
            int dau = l, cuoi = r, mid;
            while (dau <= cuoi) {
                mid = (dau + cuoi) >> 1;
                if (j >= SZ(s[mid])) {
                    cuoi = mid-1;
                    continue;
                }
                if (s[mid][j] > s[i][j]) cuoi = mid-1;
                else dau = mid+1;
            }
            // cout << i << ' ' << j << ' ' << cuoi << endl;
            // from i + 1 to cuoi
            if (i < cuoi && cuoi < n) {
                f[i][i+1]++;
                f[i][cuoi+1]--;
            }
            else break;
        }
        FOR(j,i+1,n-1) f[i][j] += f[i][j-1];
    }

    // FOR(i,0,n-1) cout << s[i] << endl;

    // FOR(i,0,n-1) {
    //     FOR(j,0,n-1) cout << f[i][j] << ' ';
    //     cout << endl;
    // }

    FOR(j,0,n-1) {
        FOR(i,0,n-1) {
            if (i == 0) preF[i][j] = f[i][j];
            else preF[i][j] = preF[i-1][j] + f[i][j];
        }
    }

    FOR(i,0,n-1)
        FOR(j,i+1,n-1)
            if (j == i + 1) group[i][j] = f[i][j];
            else {
                // group[i][j] = group[i][j-1] + f[k][j]; k from i to j - 1
                group[i][j] = group[i][j-1] + preF[j-1][j];
                if (i > 0) group[i][j] = group[i][j] - preF[i-1][j];
            }

    // FOR(i,0,n-1) {
    //     FOR(j,0,n-1) cout << group[i][j] << ' ';
    //     cout << endl;
    // }

    FOR(i,0,n-1) cnt[s[i][0]-'a']++;

    int now = 0;
    FOR(i,0,25) {
        int nex = now + cnt[i];
        int num = nex - now;
        numOfFirstChar[i] = num;
        FOR(j,1,num) {
            g[i][j] = 0;
            FOR(k,now,nex-1) {
                if (k + j - 1 >= nex) break;
                int l = k, r = k + j - 1;
                g[i][j] = max(g[i][j], group[l][r]);
            }
        }
        now = nex;
    }

    // FOR(i,0,25) cout << numOfFirstChar[i] << ' ';
    // cout << endl;

    FOR(i,0,26)
        FOR(j,0,K) dp[i][j] = -1e18;
    dp[0][0] = 0;
    FOR(i,0,25)
        FOR(j,0,K) {
            FOR(k,0,numOfFirstChar[i]) {
                if (j + k <= K) dp[i+1][j+k] = max(dp[i+1][j+k], dp[i][j] + g[i][k]);
            }
        }
    ll res = 0;
    FOR(j,0,K) res = max(res, dp[26][j]);
    cout << res;
    return 0;
}


#include <cstdio>
#define NE(x, y, z) ++nes, e[nes]=y, h[nes]=s[x], s[x]=nes, c[nes]=z
#define key(w) d[a[w]]
using namespace std;

int n, m, nes = 0, s[100001], e[200001], h[200001], c[200001], d[100001],
    t[100005], ts[100005];
struct heap {
    int size, a[100001], pos[100001];
    inline void Adj_down(int w) {
        int x = a[w], targ = w << 1, xKey = key(w);
        for (; targ <= size; targ = w << 1) {
            if ((targ < size) && (key(targ + 1) < key (targ)))
                ++targ;
            if (key(targ) < xKey) {
                a[w] = a[targ], pos[a[w]] = w;
                w = targ;
            } else
                break;
        }
        a[w] = x, pos[x] = w;
    }
    inline void Adj_up(int w) {
        int x = a[w], xKey = key(w);
        for (; (w > 1) && (key(w >> 1) > xKey); w >>= 1)
            a[w] = a[w >> 1], pos[a[w]] = w;
        a[w] = x, pos[x] = w;
    }
    inline void build() {
        size = n;
        for (int i=1; i<=size; ++i)
            a[i] = i, pos[i] = i;
    }
    inline void pop() {
        a[1] = a[size--];
        pos[a[1]] = 1, Adj_down(1);
    }
} H;
inline int d2f(int s, int e, int x) {
    int mid;
    while (s <= e) {
        mid = (s + e) >> 1;
        if (t[mid] == x) return mid; else
        if (t[mid] < x) s = mid + 1; else
            e = mid - 1;
    }
    return 0;
}
inline int AT(int x, int T) {
    int w = d2f(ts[x], ts[x+1]-1, T);
    for (; w < ts[x + 1] && t[w] == T; ++T, ++w);
    return T;
}
int main() {
    scanf("%d%d", &n, &m);
    int x, y, z, k;
    for (int i=1; i<=m; ++i) {
        scanf("%d%d%d", &x, &y, &z);
        NE(x, y ,z);
        NE(y, x, z);
    }
    ts[1] = 1;
    for (int i=1; i<=n; ++i) {
        scanf("%d", &k);
        for (int j=0; j<k; ++j)
            scanf("%d", &t[ts[i] + j]);
        ts[i+1] = ts[i] + k;
    }
    for (int i=1; i<=n; ++i) d[i] = (1 << 30) - 1;
    d[1] = 0;
    H.build();
    while (H.size) {
        x = H.a[1];
        for (int w=s[x]; w; w=h[w])
            if (d[x] + c[w] < d[e[w]]) {
                d[e[w]] = AT(e[w], d[x] + c[w]);
                H.Adj_up(H.pos[e[w]]);
            }
        H.pop();
    }
    if (d[n] < (1 << 30)-1)
        printf("%d\n", d[n]); else
        printf("-1\n");
    return 0;
}


#include <cstdio>
#define NE(x, y, z) ++nes, e[nes]=y, h[nes]=s[x], s[x]=nes, c[nes]=z
#define key(w) d[a[w]]
using namespace std;

const int inf = (1 << 30) - 1;
int n, m, nes = 0, s[200005], e[200005], h[200005], c[200005], d[200005],
    t[200005], ts[200005];
struct heap {
    int size, a[200005], pos[200005];
    inline void Adj_down(int w) {
        int x = a[w], targ = w << 1, xKey = key(w);
        for (; targ <= size; targ = w << 1) {
            if ((targ < size) && (key(targ + 1) < key (targ)))
                ++targ;
            if (key(targ) < xKey) {
                a[w] = a[targ], pos[a[w]] = w;
                w = targ;
            } else
                break;
        }
        a[w] = x, pos[x] = w;
    }
    inline void Adj_up(int w) {
        int x = a[w], xKey = key(w);
        for (; (w > 1) && (key(w >> 1) > xKey); w >>= 1)
            a[w] = a[w >> 1], pos[a[w]] = w;
        a[w] = x, pos[x] = w;
    }
    inline void build() {
        size = n;
        for (int i=1; i<=size; ++i)
            a[i] = i, pos[i] = i;
    }
    inline void pop() {
        a[1] = a[size--];
        pos[a[1]] = 1, Adj_down(1);
    }
} H;
inline int d2f(int s, int e, int x) {
    int mid;
    while (s <= e) {
        mid = (s + e) >> 1;
        if (t[mid] == x) return mid; else
        if (t[mid] < x) s = mid + 1; else
            e = mid - 1;
    }
    return 0;
}
inline int AT(int x, int T) {
    int w = d2f(ts[x], ts[x+1]-1, T);
    for (; w < ts[x + 1] && t[w] == T; ++T, ++w);
    return T;
}
int main() {
    scanf("%d%d", &n, &m);
    int x, y, z, k, t2;
    for (int i=1; i<=m; ++i) {
        scanf("%d%d%d", &x, &y, &z);
        NE(x, y ,z);
        NE(y, x, z);
    }
    ts[1] = 1, t[0] = -1;
    for (int i=1; i<=n; ++i) {
        scanf("%d", &k);
        for (int j=0; j<k; ++j)
            scanf("%d", &t[ts[i] + j]);
        ts[i+1] = ts[i] + k;
    }
    for (int i=1; i<=n; ++i) d[i] = inf;
    d[1] = 0;
    H.build();
    while (H.size) {
        x = H.a[1];
        for (int w=s[x]; w; w=h[w])
            if ((t2 = AT(e[w], d[x] + c[w])) < d[e[w]]) {
                d[e[w]] = t2;
                H.Adj_up(H.pos[e[w]]);
            }
        H.pop();
    }
    if (d[n] < inf)
        printf("%d\n", d[n]); else
        printf("-1\n");
    return 0;
}


#include<cstdio>
#include<queue>
#include<vector>
#include<algorithm>
#include<cstring>

using namespace std;

const int MAXN = 100100;

struct edge {
    int to, time;

    bool operator < ( const edge & p ) const {
        if ( time < p.time ) return 1;
        return 0;
    }

    edge ( int to_ = 0, int time_ = 0 ) {
        to = to_;
        time = time_;
    }

};

int n, m;
vector < edge > v[MAXN];
vector < int > arr[MAXN];
priority_queue < edge > q;
unsigned int d[MAXN];

void read() {
    int i, j, x, y, z, k;

    scanf ( "%d %d", &n, &m );

    for ( i = 0; i < m; ++ i ) {
        scanf ( "%d %d %d", &x, &y, &z );

        v[x].push_back ( edge ( y, z ) );
        v[y].push_back ( edge ( x, z ) );
    }

    for ( i = 1; i <= n; ++ i ) {
        scanf ( "%d", &k );

        for ( j = 0; j < k; ++ j ) {
            scanf ( "%d", &x );
            arr[i].push_back ( x );
        }
    }

}

int find_next_time ( int idx, int ll, int num ) {
    int l = 0, r = ( int ) arr[idx].size() - 1, mid, best;
    best = r;

    while ( r - l >= 0 ) {
        mid = ( l + r ) / 2;

        if ( num - arr[idx][mid] - num <= mid - ll ) {
            l = mid + 1;
        }
        else if ( num - arr[idx][mid] > mid - ll ) {
            r = mid - 1;
            best = r;
        }

    }

    return arr[idx][best] + 1;

}

int find_time ( int idx, int num ) {
    int l = 0, r = ( int ) arr[idx].size() - 1, mid;

    if ( r == ( int ) arr[idx].size() ) return num;

    while ( r - l >= 0 ) {
        mid = ( l + r ) / 2;

        if ( arr[idx][mid] == num ) {
            return find_next_time ( idx, mid, num );
        }

        if ( arr[idx][mid] < num ) {
            l = mid + 1;
        }
        else {
            r = mid - 1;
        }

    }

    return num;

}

void solve ( int start, int end ) {
    int i;
    edge tc;

    memset ( d, ( 0 - 1 ), sizeof d );

    int cur = find_time ( start, 0 );

    d[start] = cur;

    q.push ( edge ( start, cur ) );

    while ( !q.empty () ) {
        tc = q.top();
        q.pop();

        if ( tc.time <= d[tc.to] ) {
            int sz = ( int ) v[tc.to].size();
            int cur = find_time ( tc.to, tc.time );
            cur -= tc.time;

            for ( i = 0; i < sz; ++ i ) {
                if ( d[ v[tc.to][i].to ] > tc.time + v[tc.to][i].time + cur ) {
                    d[ v[tc.to][i].to ] = v[tc.to][i].time + tc.time + cur;
                    q.push ( edge ( v[tc.to][i].to, d[ v[tc.to][i].to ] ) );
                }
            }
        }
    }

    if ( d[end] == ( unsigned int ) ( 0 - 1 ) ) printf ( "-1\n" );
    else printf ( "%d\n", d[end] );

}

int main() {
    read();
    solve ( 1, n );

    return 0;

}


#include<cstdio>
#include<queue>
#include<vector>
#include<algorithm>
#include<cstring>

using namespace std;

const int MAXN = 100100;

struct edge {
    int to, time;

    bool operator < ( const edge & p ) const {
        if ( time < p.time ) return 1;
        if ( time == p.time ) return to < p.to;
        return 0;
    }

    edge ( int to_ = 0, int time_ = 0 ) {
        to = to_;
        time = time_;
    }

};

int n, m;
vector < edge > v[MAXN];
vector < int > arr[MAXN];
priority_queue < edge > q;
unsigned int d[MAXN];

void read() {
    int i, j, x, y, z, k;

    scanf ( "%d %d", &n, &m );

    for ( i = 0; i < m; ++ i ) {
        scanf ( "%d %d %d", &x, &y, &z );

        v[x].push_back ( edge ( y, z ) );
        v[y].push_back ( edge ( x, z ) );
    }

    for ( i = 1; i <= n; ++ i ) {
        scanf ( "%d", &k );

        for ( j = 0; j < k; ++ j ) {
            scanf ( "%d", &x );
            arr[i].push_back ( x );
        }
    }

}

int find_next_time ( int idx, int ll, int num ) {
    int l = ll, r = ( int ) arr[idx].size(), mid;

    while ( r - l > 0 ) {
        mid = ( l + r ) / 2;

        if ( arr[idx][mid] - num <= mid - ll ) {
            l = mid + 1;
        }
        else if ( arr[idx][mid] - num > mid - ll ) {
            r = mid;
        }

    }
//printf ( "fail %d\n", l );
    return arr[idx][l - 1] + 1;

}

int find_time ( int idx, int num ) {
    int l = 0, r = ( int ) arr[idx].size(), mid;

    if ( r == 0 ) return 0;

    while ( r - l >= 0 ) {
        mid = ( l + r ) / 2;

        if ( arr[idx][mid] == num ) {
            return find_next_time ( idx, mid, num );
        }

        if ( arr[idx][mid] < num ) {
            l = mid + 1;
        }
        else {
            r = mid - 1;
        }

    }

    return 0;

}

int solve ( int start, int end ) {
    int i;
    edge tc;

    memset ( d, 0 - 1, sizeof d );

    int cur = find_time ( start, 0 );

    d[start] = cur;

    q.push ( edge ( start, cur ) );

    while ( !q.empty () ) {
        tc = q.top(), q.pop();

        if ( tc.time >= d[tc.to] ) {
            int sz = ( int ) v[tc.to].size();
            int cur = find_time ( tc.to, tc.time );

            for ( i = 0; i < sz; ++ i ) {

                //printf ( "%d %d %d\n", tc.to, tc.time, cur );

                if ( d[ v[tc.to][i].to ] > tc.time + v[tc.to][i].time + cur ) {
                    d[ v[tc.to][i].to ] = v[tc.to][i].time + tc.time + cur;

                    q.push ( edge ( v[tc.to][i].to, d[ v[tc.to][i].to ] ) );
                }
            }
        }
    }

    if ( d[end] == ( unsigned int ) ( 0 - 1 ) ) printf ( "-1\n" );
    else printf ( "%d\n", d[end] );

}

int main() {
    read();
    solve ( 1, n );

    return 0;

}


#include<cstdio>
#include<queue>
#include<vector>
#include<algorithm>
#include<cstring>

using namespace std;

const int MAXN = 100100;

struct edge {
    int to, time;

    bool operator < ( const edge & p ) const {
        if ( time > p.time ) return 1;
        if ( time == p.time ) return to < p.to;
        return 0;
    }

    edge ( int to_ = 0, int time_ = 0 ) {
        to = to_;
        time = time_;
    }

};

int n, m;
vector < edge > v[MAXN];
vector < int > arr[MAXN];
priority_queue < edge > q;
unsigned int d[MAXN];

void read() {
    int i, j, x, y, z, k;

    scanf ( "%d %d", &n, &m );

    for ( i = 0; i < m; ++ i ) {
        scanf ( "%d %d %d", &x, &y, &z );

        v[x].push_back ( edge ( y, z ) );
        v[y].push_back ( edge ( x, z ) );
    }

    for ( i = 1; i <= n; ++ i ) {
        scanf ( "%d", &k );

        for ( j = 0; j < k; ++ j ) {
            scanf ( "%d", &x );
            arr[i].push_back ( x );
        }
    }

}

bool find_time ( int idx, int num ) {
    int l = 0, r = ( int ) arr[idx].size() - 1, mid;

    if ( arr[idx].size() == 0 ) return 0;

    while ( r - l >= 0 ) {
        mid = ( l + r ) / 2;

        if ( arr[idx][mid] == num ) {
            return 1;
        }

        if ( arr[idx][mid] < num ) {
            l = mid + 1;
        }
        else {
            r = mid - 1;
        }

    }

    return 0;

}

int solve ( int start, int end ) {
    int i;
    edge tc;

    memset ( d, 0 - 1, sizeof d );

    int cur = find_time ( start, 0 );

    d[start] = cur;

    q.push ( edge ( start, cur ) );

    while ( !q.empty () ) {
        tc = q.top(), q.pop();

        if ( tc.time >= d[tc.to] ) {
            int sz = ( int ) v[tc.to].size();

            int cur = tc.time;

            while ( find_time ( tc.to, cur ) ) {
                cur ++;
            }

            cur -= tc.time;

            for ( i = 0; i < sz; ++ i ) {

                if ( d[ v[tc.to][i].to ] > tc.time + v[tc.to][i].time + cur ) {
                    d[ v[tc.to][i].to ] = v[tc.to][i].time + tc.time + cur;

                    q.push ( edge ( v[tc.to][i].to, d[ v[tc.to][i].to ] ) );
                }
            }
        }
    }

    if ( d[end] == ( unsigned int ) ( 0 - 1 ) ) printf ( "-1\n" );
    else printf ( "%d\n", d[end] );

}

int main() {
    read();
    solve ( 1, n );

    return 0;

}


#include<cstdio>
#include<queue>
#include<vector>
#include<algorithm>
#include<cstring>

using namespace std;

const int MAXN = 100100;

struct edge {
    int to, time;

    bool operator < ( const edge & p ) const {
        if ( time < p.time ) return 1;
        return 0;
    }

    edge ( int to_ = 0, int time_ = 0 ) {
        to = to_;
        time = time_;
    }

};

int n, m;
vector < edge > v[MAXN];
vector < int > arr[MAXN];
priority_queue < edge > q;
unsigned int d[MAXN];

void read() {
    int i, j, x, y, z, k;

    scanf ( "%d %d", &n, &m );

    for ( i = 0; i < m; ++ i ) {
        scanf ( "%d %d %d", &x, &y, &z );

        v[x].push_back ( edge ( y, z ) );
        v[y].push_back ( edge ( x, z ) );
    }

    for ( i = 1; i <= n; ++ i ) {
        scanf ( "%d", &k );

        for ( j = 0; j < k; ++ j ) {
            scanf ( "%d", &x );
            arr[i].push_back ( x );
        }
    }

}

int find_next_time ( int idx, int ll, int num ) {
    int l = 0, r = ( int ) arr[idx].size() - 1, mid, best;
    best = r;

    while ( r - l >= 0 ) {
        mid = ( l + r ) / 2;

        if ( num - arr[idx][mid] - num <= mid - ll ) {
            l = mid + 1;
        }
        else if ( num - arr[idx][mid] > mid - ll ) {
            r = mid - 1;
            best = r;
        }

    }
//printf ( "%d %d\n", best, arr[idx][best] + 1 );
    return arr[idx][best] + 1;

}

int find_time ( int idx, int num ) {
    int l = 0, r = ( int ) arr[idx].size() - 1, mid;

    if ( r == ( int ) arr[idx].size() ) return num;

    while ( r - l >= 0 ) {
        mid = ( l + r ) / 2;

        if ( arr[idx][mid] == num ) {
            return find_next_time ( idx, mid, num );
        }

        if ( arr[idx][mid] < num ) {
            l = mid + 1;
        }
        else {
            r = mid - 1;
        }

    }

    return num;

}

void solve ( int start, int end ) {
    int i;
    edge tc;

    memset ( d, 0 - 1, sizeof d );

    int cur = find_time ( start, 0 );

    d[start] = cur;
//printf ( "%d\n", cur );
    q.push ( edge ( start, cur ) );

    while ( !q.empty () ) {
        tc = q.top(), q.pop();

        if ( tc.time <= d[tc.to] ) {
            int sz = ( int ) v[tc.to].size();
            int cur = find_time ( tc.to, tc.time );
            cur -= tc.time;

            for ( i = 0; i < sz; ++ i ) {
                //if ( tc.to == 2 ) printf ( "%d %d\n", v[tc.to][i].to, tc.time + v[tc.to][i].time + cur );
                //printf ( "%d %d %d\n", tc.to, tc.time, cur );
                if ( d[ v[tc.to][i].to ] > tc.time + v[tc.to][i].time + cur ) {
                    d[ v[tc.to][i].to ] = v[tc.to][i].time + tc.time + cur;

                    q.push ( edge ( v[tc.to][i].to, d[ v[tc.to][i].to ] ) );
                }
            }
        }
    }

    if ( d[end] == ( unsigned int ) ( 0 - 1 ) ) printf ( "-1\n" );
    else printf ( "%d\n", d[end] );

}

int main() {
    read();
    solve ( 1, n );

    return 0;

}


#include<cstdio>
#include<queue>
#include<vector>
#include<algorithm>
#include<cstring>

using namespace std;

const int MAXN = 100100;

struct edge {
    int to, time;

    bool operator < ( const edge & p ) const {
        if ( time < p.time ) return 1;
        return 0;
    }

    edge ( int to_ = 0, int time_ = 0 ) {
        to = to_;
        time = time_;
    }

};

int n, m;
vector < edge > v[MAXN];
vector < int > arr[MAXN];
priority_queue < edge > q;
int lv[MAXN];
unsigned int d[MAXN];

void read() {
    int i, j, x, y, z, k;

    scanf ( "%d %d", &n, &m );

    for ( i = 0; i < m; ++ i ) {
        scanf ( "%d %d %d", &x, &y, &z );
lv[x] ++;
lv[y] ++;
        v[x].push_back ( edge ( y, z ) );
        v[y].push_back ( edge ( x, z ) );
    }

    for ( i = 1; i <= n; ++ i ) {
        scanf ( "%d", &k );

        for ( j = 0; j < k; ++ j ) {
            scanf ( "%d", &x );
            arr[i].push_back ( x );
        }
    }

}

int find_next_time ( int idx, int ll, int num ) {
    int l = 0, r = ( int ) arr[idx].size() - 1, mid, best;
    best = r;

    while ( r - l >= 0 ) {
        mid = ( l + r ) / 2;

        if ( num - arr[idx][mid] - num <= mid - ll ) {
            l = mid + 1;
        }
        else if ( num - arr[idx][mid] > mid - ll ) {
            r = mid - 1;
            best = r;
        }

    }
//printf ( "%d %d\n", best, arr[idx][best] + 1 );
    return arr[idx][best] + 1;

}

int find_time ( int idx, int num ) {
    int l = 0, r = ( int ) arr[idx].size() - 1, mid;

    if ( r == ( int ) arr[idx].size() ) return num;

    while ( r - l >= 0 ) {
        mid = ( l + r ) / 2;

        if ( arr[idx][mid] == num ) {
            return find_next_time ( idx, mid, num );
        }

        if ( arr[idx][mid] < num ) {
            l = mid + 1;
        }
        else {
            r = mid - 1;
        }

    }

    return num;

}

void solve ( int start, int end ) {
    int i;
    edge tc;

    memset ( d, 0 - 1, sizeof d );

    int cur = find_time ( start, 0 );

    d[start] = cur;
//printf ( "%d\n", cur );
    q.push ( edge ( start, cur ) );

    while ( !q.empty () ) {
        tc = q.top(), q.pop();
if ( !lv [ tc.to] ) continue;
        if ( tc.time <= d[tc.to] ) {
            int sz = ( int ) v[tc.to].size();
            int cur = find_time ( tc.to, tc.time );
            cur -= tc.time;

            for ( i = 0; i < sz; ++ i ) {
                //if ( tc.to == 2 ) printf ( "%d %d\n", v[tc.to][i].to, tc.time + v[tc.to][i].time + cur );
                //printf ( "%d %d %d\n", tc.to, tc.time, cur );
                if ( d[ v[tc.to][i].to ] > tc.time + v[tc.to][i].time + cur && lv[ v[tc.to][i].to ] ) {
                    d[ v[tc.to][i].to ] = v[tc.to][i].time + tc.time + cur;
lv[ v[tc.to][i].to ] --;
                    q.push ( edge ( v[tc.to][i].to, d[ v[tc.to][i].to ] ) );
                }
            }
        }
    }

    if ( d[end] == ( unsigned int ) ( 0 - 1 ) ) printf ( "-1\n" );
    else printf ( "%d\n", d[end] );

}

int main() {
    read();
    solve ( 1, n );

    return 0;

}