#include<bits/stdc++.h>
using namespace std;
int n,m,q;
vector<int>adj[100005];
int col[100005],cnt=0,num[100005];
pair<int,int>dist[100005][2];
typedef long long ll;
vector<ll>numdis[100005],sumdist[100005];
vector<int>nodes[100005];
void dfs(int x,int p){
    col[x]=cnt;
    num[cnt]++;
    nodes[cnt].push_back(x);
    dist[x][0]=dist[x][1]={0,x};
    for(auto nxt:adj[x]){
        if(nxt==p)continue;
        dfs(nxt,x);
        auto d=dist[nxt][0];
        d.second=nxt;
        d.first++;
        if(d>dist[x][0])swap(d,dist[x][0]);
        if(d>dist[x][1])swap(d,dist[x][1]);
    }
}
ll sum[100005];
void dfs1(int x,int p){
    if(p!=-1){
        auto d=dist[p][0];
        if(d.second==x)d=dist[p][1];
        d.first++;d.second=p;
        if(d>dist[x][0])swap(d,dist[x][0]);
        if(d>dist[x][1])swap(d,dist[x][1]);
    }
    sum[col[x]]+=dist[x][0].first;
    for(auto nxt:adj[x]){
        if(nxt!=p)dfs1(nxt,x);
    }
}
int main()
{
    cin>>n>>m>>q;
    for(int i=0;i<m;++i){
        int u,v;
        scanf("%d%d",&u,&v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    for(int i=1;i<=n;++i){
        if(col[i])continue;
        ++cnt;
        dfs(i,-1);
        dfs1(i,-1);
        numdis[cnt].resize(num[cnt],0);
        for(auto x:nodes[cnt]){
            ++numdis[cnt][dist[x][0].first];
        }
        while(numdis[cnt].back()==0)numdis[cnt].pop_back();
        sumdist[cnt]=numdis[cnt];
        sumdist[cnt][0]=0;
        for(int j=1;j<numdis[cnt].size();++j){
            sumdist[cnt][j]=sumdist[cnt][j-1]+j*numdis[cnt][j];
            numdis[cnt][j]+=numdis[cnt][j-1];
        }
    }
    map<pair<int,int>,double>mp;
    while(q--){
        int u,v;
        scanf("%d%d",&u,&v);
        u=col[u];
        v=col[v];
        if(make_pair(numdis[u].size(),u)>make_pair(numdis[v].size(),v))swap(u,v);
        if(u==v){
            puts("-1");
            continue;
        }
        double ans;
        if(mp.count({u,v}))ans=mp[{u,v}];
        else{
            ll mx=max(numdis[u].size(),numdis[v].size())-1;
            long double tot=sum[v]*num[u]+sum[u]*num[v]+num[u]*num[v];
            //cout<<mx<<" "<<num[u]<<" "<<sum[u]<<" "<<num[v]<<" "<<sum[v]<<endl;
            for(int i=0;i<numdis[u].size();++i){
                //i+j<mx
                int j=mx-i-1;
                if(j<0)break;
                ll numu=numdis[u][i];
                if(i)numu-=numdis[u][i-1];
                //cout<<i<<" "<<j<<" "<<numu<<endl;
                tot-=numu*sumdist[v][j]+1.0*numu*i*numdis[v][j]+numu*numdis[v][j];
                tot+=1.0*numu*numdis[v][j]*mx;            }
            ans=tot/(1.0*num[u]*num[v]);
        }
        mp[{u,v}]=ans;
        printf("%.8f\n",ans);

    }
}


#include <stdio.h>
#include <algorithm>
#include <assert.h>
#include <cmath>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <time.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:336777216")
using namespace std;

#define mp make_pair
#define Fi first
#define Se second
#define pb(x) push_back(x)
#define szz(x) ((int)(x).size())
#define rep(i, n) for(int i=0;i<n;i++)
#define all(x) (x).begin(), (x).end()
#define ldb ldouble

typedef tuple<int, int, int> t3;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <ll, int> pli;
typedef pair <db, db> pdd;

int IT_MAX = 1 << 17;
const ll MOD = 1000000007;
const int INF = 0x3f3f3f3f;
const ll LL_INF = 1234567890123456789ll;
const db PI = acos(-1);
const db ERR = 1E-11;

class Node {
public:
	int mx, v;
	Node() { mx = 0, v = 0; }
};
Node indt[300050];
void update(int st, int en, int S, int E, int n, int v) {
	if (st > en) return;
	if (st == S && en == E) {
		indt[n].v += v;
		indt[n].mx += v;
		return;
	}

	int M = (S + E) / 2;
	update(st, min(en, M), S, M, 2 * n, v);
	update(max(M + 1, st), en, M + 1, E, 2 * n + 1, v);
	indt[n].mx = indt[n].v + max(indt[2 * n].mx, indt[2 * n + 1].mx);
}

vector <int> conn[100050];
vector <int> son[100050];
int G[100050];
int gsz[100050];
ll gv[100050];
int dis[100050];

int lr[100050][2];
bool dchk[100050];
int lrc = 0;
void DFS1(int n) {
	dchk[n] = true;
	lr[n][0] = ++lrc;
	for (auto it : conn[n]) {
		if (dchk[it]) continue;
		son[n].push_back(it);
		DFS1(it);
	}
	lr[n][1] = lrc;
}
void DFS2(int n, int g) {
	gv[g] += indt[1].mx;
	gsz[g]++;

	for (auto it : son[n]) {
		update(1, IT_MAX, 1, IT_MAX, 1, 1);
		update(lr[it][0], lr[it][1], 1, IT_MAX, 1, -2);
		DFS2(it, g);
		update(1, IT_MAX, 1, IT_MAX, 1, -1);
		update(lr[it][0], lr[it][1], 1, IT_MAX, 1, 2);
	}
}

int main() {
	int N, M, Q, i, j;
	scanf("%d %d %d", &N, &M, &Q);
	while (M--) {
		scanf("%d %d", &i, &j);
		conn[i].push_back(j);
		conn[j].push_back(i);
	}

	int gc = 0;
	for (i = 1; i <= N; i++) dis[i] = INF;
	for (i = 1; i <= N; i++) {
		if (G[i]) continue;
		G[i] = ++gc;
		vector <int> Vu;
		Vu.push_back(i);
		dis[i] = 0;
		for (j = 0; j < Vu.size(); j++) {
			for (auto it : conn[Vu[j]]) {
				if (G[it]) continue;
				G[it] = gc;
				dis[it] = dis[Vu[j]] + 1;
				Vu.push_back(it);
			}
		}
		lrc = 0;
		DFS1(i);

		for (IT_MAX = 2; IT_MAX < Vu.size(); IT_MAX *= 2);
		for (auto it : Vu) update(lr[it][0], lr[it][0], 1, IT_MAX, 1, dis[it]);
		DFS2(i, gc);
		for (j = 1; j <= 2 * IT_MAX; j++) indt[j].mx = indt[j].v = 0;
	}

	while (Q--) {
		scanf("%d %d", &i, &j);
		if (G[i] == G[j]) printf("-1\n");
		else printf("%.20lf\n", 1.0 * gv[G[i]] / gsz[G[i]] + 1.0 * gv[G[j]] / gsz[G[j]] + 1);
	}
	return 0;
}


#include <stdio.h>
#include <algorithm>
#include <assert.h>
#include <cmath>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <time.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:336777216")
using namespace std;

#define mp make_pair
#define Fi first
#define Se second
#define pb(x) push_back(x)
#define szz(x) ((int)(x).size())
#define rep(i, n) for(int i=0;i<n;i++)
#define all(x) (x).begin(), (x).end()
#define ldb ldouble

typedef tuple<int, int, int> t3;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <ll, int> pli;
typedef pair <db, db> pdd;

int IT_MAX = 1 << 17;
const ll MOD = 1000000007;
const int INF = 0x3f3f3f3f;
const ll LL_INF = 1234567890123456789ll;
const db PI = acos(-1);
const db ERR = 1E-11;

class Node {
public:
	int mx, v;
	Node() { mx = 0, v = 0; }
};
Node indt[300050];
void update(int st, int en, int S, int E, int n, int v) {
	if (st > en) return;
	if (st == S && en == E) {
		indt[n].v += v;
		indt[n].mx += v;
		return;
	}

	indt[2 * n].v += indt[n].v;
	indt[2 * n].mx += indt[n].v;
	indt[2 * n + 1].v += indt[n].v;
	indt[2 * n + 1].mx += indt[n].v;
	indt[n].v = 0;

	int M = (S + E) / 2;
	update(st, min(en, M), S, M, 2 * n, v);
	update(max(M + 1, st), en, M + 1, E, 2 * n + 1, v);
	indt[n].mx = max(indt[2 * n].mx, indt[2 * n + 1].mx);
}

vector <int> conn[100050];
vector <int> son[100050];
int G[100050];
int gsz[100050];
vector <ll> gv[100050];
vector <ll> gvs[100050];
int dis[100050];

int lr[100050][2];
bool dchk[100050];
int lrc = 0;
void DFS1(int n) {
	dchk[n] = true;
	lr[n][0] = ++lrc;
	for (auto it : conn[n]) {
		if (dchk[it]) continue;
		son[n].push_back(it);
		DFS1(it);
	}
	lr[n][1] = lrc;
}
void DFS2(int n, int g, int gs) {
	gv[g].push_back(indt[1].mx);
	gsz[g]++;

	for (auto it : son[n]) {
		update(1, gs, 1, IT_MAX, 1, 1);
		update(lr[it][0], lr[it][1], 1, IT_MAX, 1, -2);
		DFS2(it, g, gs);
		update(1, gs, 1, IT_MAX, 1, -1);
		update(lr[it][0], lr[it][1], 1, IT_MAX, 1, 2);
	}
}

int main() {
	int N, M, Q, i, j;
	scanf("%d %d %d", &N, &M, &Q);
	while (M--) {
		scanf("%d %d", &i, &j);
		conn[i].push_back(j);
		conn[j].push_back(i);
	}

	int gc = 0;
	for (i = 1; i <= N; i++) dis[i] = INF;
	for (i = 1; i <= N; i++) {
		if (G[i]) continue;
		G[i] = ++gc;
		vector <int> Vu;
		Vu.push_back(i);
		dis[i] = 0;
		for (j = 0; j < Vu.size(); j++) {
			for (auto it : conn[Vu[j]]) {
				if (G[it]) continue;
				G[it] = gc;
				dis[it] = dis[Vu[j]] + 1;
				Vu.push_back(it);
			}
		}
		lrc = 0;
		DFS1(i);

		for (IT_MAX = 2; IT_MAX < Vu.size(); IT_MAX *= 2);
		for (auto it : Vu) update(lr[it][0], lr[it][0], 1, IT_MAX, 1, dis[it]);
		DFS2(i, gc, Vu.size());
		for (j = 1; j <= 2 * IT_MAX; j++) indt[j].mx = indt[j].v = 0;
	}

	for (i = 1; i <= gc; i++) {
		sort(all(gv[i]));
		gvs[i].push_back(gv[i][0]);
		for (j = 1; j < gv[i].size(); j++) gvs[i].push_back(gvs[i].back() + gv[i][j]);
	}

	map <pii, db> Mx;
	while (Q--) {
		int t1, t2;
		scanf("%d %d", &t1, &t2);
		t1 = G[t1], t2 = G[t2];
		if (pii(gsz[t1], t1) > pii(gsz[t2], t2)) swap(t1, t2);
		if (t1 == t2) {
			printf("-1\n");
			continue;
		}
		if (Mx.count(pii(t1, t2))) {
			printf("%.20lf\n", Mx[pii(t1, t2)]);
			continue;
		}

		db s = 0;
		for (auto it : gv[t1]) {
			ll v = max(gv[t1].back(), gv[t2].back()) - it - 1;
			int p = lower_bound(all(gv[t2]), (int)v) - gv[t2].begin();

			s += (db)p * max(gv[t1].back(), gv[t2].back());
			s += gvs[t2].back() + (it+1) * (gv[t2].size() - p);
			if (p) s -= gvs[t2][p - 1];
		}
		s /= gv[t1].size();
		s /= gv[t2].size();
		Mx[pii(t1, t2)] = s;
		printf("%.20lf\n", s);
	}
	return 0;
}


#include <stdio.h>
#include <algorithm>
#include <assert.h>
#include <cmath>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <time.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:336777216")
using namespace std;

#define mp make_pair
#define Fi first
#define Se second
#define pb(x) push_back(x)
#define szz(x) ((int)(x).size())
#define rep(i, n) for(int i=0;i<n;i++)
#define all(x) (x).begin(), (x).end()
#define ldb ldouble

typedef tuple<int, int, int> t3;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <ll, int> pli;
typedef pair <db, db> pdd;

int IT_MAX = 1 << 17;
const ll MOD = 1000000007;
const int INF = 0x3f3f3f3f;
const ll LL_INF = 1234567890123456789ll;
const db PI = acos(-1);
const db ERR = 1E-11;

class Node {
public:
	int mx, v;
	Node() { mx = 0, v = 0; }
};
Node indt[300050];
void update(int st, int en, int S, int E, int n, int v) {
	if (st > en) return;
	if (st == S && en == E) {
		indt[n].v += v;
		indt[n].mx += v;
		return;
	}

	int M = (S + E) / 2;
	update(st, min(en, M), S, M, 2 * n, v);
	update(max(M + 1, st), en, M + 1, E, 2 * n + 1, v);
	indt[n].mx = indt[n].v + max(indt[2 * n].mx, indt[2 * n + 1].mx);
}

vector <int> conn[100050];
vector <int> son[100050];
int G[100050];
int gsz[100050];
ll gv[100050];
int dis[100050];

int lr[100050][2];
bool dchk[100050];
int lrc = 0;
void DFS1(int n) {
	dchk[n] = true;
	lr[n][0] = ++lrc;
	for (auto it : conn[n]) {
		if (dchk[it]) continue;
		son[n].push_back(it);
		DFS1(it);
	}
	lr[n][1] = lrc;
}
void DFS2(int n, int g, int gs) {
	gv[g] += indt[1].mx;
	gsz[g]++;

	for (auto it : son[n]) {
		update(1, gs, 1, IT_MAX, 1, 1);
		update(lr[it][0], lr[it][1], 1, IT_MAX, 1, -2);
		DFS2(it, g, gs);
		update(1, gs, 1, IT_MAX, 1, -1);
		update(lr[it][0], lr[it][1], 1, IT_MAX, 1, 2);
	}
}

int main() {
	int N, M, Q, i, j;
	scanf("%d %d %d", &N, &M, &Q);
	while (M--) {
		scanf("%d %d", &i, &j);
		conn[i].push_back(j);
		conn[j].push_back(i);
	}

	int gc = 0;
	for (i = 1; i <= N; i++) dis[i] = INF;
	for (i = 1; i <= N; i++) {
		if (G[i]) continue;
		G[i] = ++gc;
		vector <int> Vu;
		Vu.push_back(i);
		dis[i] = 0;
		for (j = 0; j < Vu.size(); j++) {
			for (auto it : conn[Vu[j]]) {
				if (G[it]) continue;
				G[it] = gc;
				dis[it] = dis[Vu[j]] + 1;
				Vu.push_back(it);
			}
		}
		lrc = 0;
		DFS1(i);

		for (IT_MAX = 2; IT_MAX < Vu.size(); IT_MAX *= 2);
		for (auto it : Vu) update(lr[it][0], lr[it][0], 1, IT_MAX, 1, dis[it]);
		DFS2(i, gc, Vu.size());
		for (j = 1; j <= 2 * IT_MAX; j++) indt[j].mx = indt[j].v = 0;
	}

	while (Q--) {
		scanf("%d %d", &i, &j);
		if (G[i] == G[j]) printf("-1\n");
		else printf("%.20lf\n", 1.0 * gv[G[i]] / gsz[G[i]] + 1.0 * gv[G[j]] / gsz[G[j]] + 1);
	}
	return 0;
}


#include <stdio.h>
#include <algorithm>
#include <assert.h>
#include <cmath>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <time.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:336777216")
using namespace std;

#define mp make_pair
#define Fi first
#define Se second
#define pb(x) push_back(x)
#define szz(x) ((int)(x).size())
#define rep(i, n) for(int i=0;i<n;i++)
#define all(x) (x).begin(), (x).end()
#define ldb ldouble

typedef tuple<int, int, int> t3;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <ll, int> pli;
typedef pair <db, db> pdd;

int IT_MAX = 1 << 17;
const ll MOD = 1000000007;
const int INF = 0x3f3f3f3f;
const ll LL_INF = 1234567890123456789ll;
const db PI = acos(-1);
const db ERR = 1E-11;

class Node {
public:
	int mx, v;
	Node() { mx = 0, v = 0; }
};
Node indt[300050];
void update(int st, int en, int S, int E, int n, int v) {
	if (st > en) return;
	if (st == S && en == E) {
		indt[n].v += v;
		indt[n].mx += v;
		return;
	}

	indt[2 * n].v += indt[n].v;
	indt[2 * n].mx += indt[n].v;
	indt[2 * n + 1].v += indt[n].v;
	indt[2 * n + 1].mx += indt[n].v;
	indt[n].v = 0;

	int M = (S + E) / 2;
	update(st, min(en, M), S, M, 2 * n, v);
	update(max(M + 1, st), en, M + 1, E, 2 * n + 1, v);
	indt[n].mx = max(indt[2 * n].mx, indt[2 * n + 1].mx);
}

vector <int> conn[100050];
vector <int> son[100050];
int G[100050];
int gsz[100050];
ll gv[100050];
int dis[100050];

int lr[100050][2];
bool dchk[100050];
int lrc = 0;
void DFS1(int n) {
	dchk[n] = true;
	lr[n][0] = ++lrc;
	for (auto it : conn[n]) {
		if (dchk[it]) continue;
		son[n].push_back(it);
		DFS1(it);
	}
	lr[n][1] = lrc;
}
void DFS2(int n, int g, int gs) {
	gv[g] += indt[1].mx;
	gsz[g]++;

	for (auto it : son[n]) {
		update(1, gs, 1, IT_MAX, 1, 1);
		update(lr[it][0], lr[it][1], 1, IT_MAX, 1, -2);
		DFS2(it, g, gs);
		update(1, gs, 1, IT_MAX, 1, -1);
		update(lr[it][0], lr[it][1], 1, IT_MAX, 1, 2);
	}
}

int main() {
	int N, M, Q, i, j;
	scanf("%d %d %d", &N, &M, &Q);
	while (M--) {
		scanf("%d %d", &i, &j);
		conn[i].push_back(j);
		conn[j].push_back(i);
	}

	int gc = 0;
	for (i = 1; i <= N; i++) dis[i] = INF;
	for (i = 1; i <= N; i++) {
		if (G[i]) continue;
		G[i] = ++gc;
		vector <int> Vu;
		Vu.push_back(i);
		dis[i] = 0;
		for (j = 0; j < Vu.size(); j++) {
			for (auto it : conn[Vu[j]]) {
				if (G[it]) continue;
				G[it] = gc;
				dis[it] = dis[Vu[j]] + 1;
				Vu.push_back(it);
			}
		}
		lrc = 0;
		DFS1(i);

		for (IT_MAX = 2; IT_MAX < Vu.size(); IT_MAX *= 2);
		for (auto it : Vu) update(lr[it][0], lr[it][0], 1, IT_MAX, 1, dis[it]);
		DFS2(i, gc, Vu.size());
		for (j = 1; j <= 2 * IT_MAX; j++) indt[j].mx = indt[j].v = 0;
	}

	while (Q--) {
		scanf("%d %d", &i, &j);
		if (G[i] == G[j]) printf("-1\n");
		else printf("%.20lf\n", 1.0 * gv[G[i]] / gsz[G[i]] + 1.0 * gv[G[j]] / gsz[G[j]] + 1);
	}
	return 0;
}


//Lasha Bukhnikashvili
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<string>
#define Pi 3.14159265358
#define mod9 %1000000009
#define INF 1000000000
#define mod7 %1000000009
#define LL  long long
#define time clock()/(double)CLOCKS_PER_SEC
using namespace std;
  int stop,n,k,x,i,ind,j,y[1000001],mini[2001][2001];
  int d[4001][2001];
  string s[2001];
  void f(int l,int r,int ind){
  	//cout<<l<<" "<<r<<endl;
  	  if (l>=r){
        return;
  	  }
  	  int p=mini[l][r-1];
  	  f(l,p,++ind);
  	  f(p+1,r,++ind);
  	  for (int i=0;i<=p-l+1;i++)
  	  	for (int j=0;j<=r-p;j++)
  	  		d[ind-2][i+j]=max(d[ind-1][i+j],d[2*ind][i]+d[ind][j]+i*j*y[p]);
  }
int main(){
 #ifndef ONLINE_JUDGE
   freopen("input.txt","r",stdin);
   freopen("output.txt","w",stdout);
 #endif
  cin>>n>>k;
  for (i=1;i<=n;i++)
  	cin>>s[i];
  sort(s+1,s+n+1);
  for (i=1;i<n;i++){
  	  y[i]=0;
  	  while (y[i]<min(s[i].length(),s[i+1].length()) && s[i][y[i]]==s[i+1][y[i]])  y[i]++;
  }
  y[0]=INF;

  for (i=1;i<=n-1;i++){
	 x=0;
  	for (j=i;j<n;j++){
  		if (y[x]>y[j])
		  x=j;
		  mini[i][j]=x;
	}
  };

  f(1,n,1);
  cout<<d[1][k]<<endl;
 return 0;
}


// --- hanhanW v1.1 ---
#include <cmath>
#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <string>
// Constest or Online Judge
#define MSET(x, y) memset(x, (y), sizeof(x))
#define REP(x,y,z) for(int x=(y); x<=(z); x++)
#define FORD(x,y,z) for(int x=(y); x>=(z); x--)
#define FLST(x,y,z) for(int x=(y); x; x=z[x])
#define PB push_back
#define SZ size()
#define F first
#define S second

typedef long long LL;
typedef unsigned long long uLL;
typedef long double LD;
typedef std::pair<int,int> MP;

/* ========== start ========== */

const int N = 2514;
const int Q =(int)1e6;

int n, K, vque[Q],vfr,vbk,dp[N],lenth[N];
std::string str[N];
std::vector<int> vc[Q];

int get_node(){
	int res=vque[vfr++];
	if (vfr>=Q) vfr-=Q;
	return res;
}
void release(int a){
	vc[a].clear();
	vque[vbk++]=a;
	if (vbk>=Q) vbk-=Q;
}
void uni(int m1, int m2, int idx, int d){
//	printf("#%d: ", idx);
//	printf("depth=%d\n", d);
//	printf("size 1 = %d\n", (int)vc[m1].SZ-1);
//	printf("size 2 = %d\n", (int)vc[m2].SZ-1);
	MSET(dp,0);
	REP(i,0,(int)vc[m1].SZ-1){
		if (i>K) break;
		REP(j,0,(int)vc[m2].SZ-1){
			if (i+j>K) break;
			dp[i+j]=std::max(dp[i+j], vc[m1][i]+vc[m2][j]+i*j*d);
		}
	}
//	puts("==");
	int ed=vc[m1].SZ+vc[m2].SZ-2;
	if (ed>K) ed=K;

	REP(i,0,ed){
		vc[idx].PB(dp[i]);
//		printf(" %d", dp[i]);
	}
//	puts("");
	release(m1); release(m2);
}
void dfs(int nL, int nR, int dep, int idx){
	if (nL==nR){
		vc[idx].PB(0); vc[idx].PB(0);
		return ;
	}
	if (dep >= lenth[nL]){
		int m1=get_node();
		int m2=get_node();
		vc[m1].PB(0); vc[m1].PB(0);
		dfs(nL+1, nR, dep, m2);
	//	printf("=== union (%d %d) ===\n", nL, nR);
		uni(m1,m2,idx,dep);
		return ;
	}
	int sign=1, m1, m2;
	REP(i,nL,nR-1){
		if (str[i][dep] != str[i+1][dep]){
			sign=0;
			m1=get_node();
			m2=get_node();
			dfs(nL,i,dep,m1);
			dfs(i+1,nR,dep,m2);
		//	printf("=== union (%d %d) ===", nL, nR);
			uni(m1,m2,idx,dep);
			return ;
		}
	}
	dfs(nL,nR,dep+1,idx);
}
void solve(){
	REP(i,0,n-1){
		char s[514];
		scanf("%s", s);
		str[i]=std::string(s);
	}
	std::sort(str,str+n);

	REP(i,0,n-1)
		lenth[i]=str[i].length();
	/*
	REP(i,0,n-1){
		char s[514];
		MSET(s,0);
		REP(j,0,(int)str[i].length())
			s[j]=str[i][j];
		printf("%s\n", s);
	}
	*/
	vfr=vbk=0;
	REP(i,0,Q-1)
		release(i);
	int st=get_node();
	dfs(0,n-1,0,st);
	//int mx=0;
	//if ((int)vc[st].SZ>=K)
	//	mx=vc[st][K];
	//REP(i,0,(int)vc[st].SZ-1)
	//	mx=std::max(mx,vc[st][i]);
	printf("%d\n", vc[st][vc[st].SZ-1]);
}

int main(){
	while (~scanf("%d%d", &n, &K))
		solve();
	return 0;
}


// .... .... .... !

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <cstring>

using namespace std;

#define rep(i, n) for (int i = 0, _n = (n); i < _n; i++)
#define fer(i, x, n) for (int i = (x), _n = (n); i < _n; i++)
#define rof(i, n, x) for (int i = (n), _x = (x); i-- > _x; )
#define fch(i, x) for (__typeof(x.begin()) i = x.begin(); i != x.end(); i++)
#define all(x) x.begin(), x.end()
#define sz(x) int((x).size())
#define cmx(a, b) (a = max(a,b))
#define cmn(a, b) (a = min(a,b))
#define pb push_back
#define mp make_pair
#define X first
#define Y second

typedef long long ll;
typedef pair <int, int> pii;
typedef vector <int> vi;

////////////////////////////////////////////////

const int INF = 1 << 30;
const int maxN = 2000 + 100;

int n, k;
string s[maxN];
int diff[maxN];

int main()
{
	cin >> n >> k;
	rep (i, n) cin >> s[i];
	sort (s, s + n);
	rep (i, n-1)
	{
		int &r = diff[i];
		while (r < sz (s[i]) && r < sz (s[i+1]) && s[i][r] == s[i+1][r])
			r++;
	}
	int cur = 0, ans = 0;
	rep (i, k-1)
	{
		int md = INF;
		fer (j, i, k-1)
		{
			cmn (md, diff[j]);
			cur += md;
		}
	}
	cmx (ans, cur);
	fer (i, k, n)
	{
		int md = INF;
		fer (j, i - k, i-1)
		{
			cmn (md, diff[j]);
			cur -= md;
		}
		md = INF;
		rof (j, i, i - k + 1)
		{
			cmn (md, diff[j]);
			cur += md;
		}
		cmx (ans, cur);
	}

	cout << ans << endl;

	{ int _; cin >> _; }
}


// .... .... .... !

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <cstring>

using namespace std;

#define rep(i, n) for (int i = 0, _n = (n); i < _n; i++)
#define fer(i, x, n) for (int i = (x), _n = (n); i < _n; i++)
#define rof(i, n, x) for (int i = (n), _x = (x); i-- > _x; )
#define fch(i, x) for (__typeof(x.begin()) i = x.begin(); i != x.end(); i++)
#define all(x) x.begin(), x.end()
#define sz(x) int((x).size())
#define cmx(a, b) (a = max(a,b))
#define cmn(a, b) (a = min(a,b))
#define pb push_back
#define mp make_pair
#define X first
#define Y second

typedef long long ll;
typedef pair <int, int> pii;
typedef vector <int> vi;

////////////////////////////////////////////////

const int INF = 1 << 30;
const int maxN = 2000 + 100;

int n, k;
string s[maxN];
int diff[maxN];

vi solve (int l, int r)
{
	if (r - l == 1)
		return vi (2, 0);
	int m = min_element (diff + l + 1, diff + r) - diff;
	vi a = solve (l, m), b = solve (m, r);
	vi res (r - l + 1, 0);
	rep (i, sz (a))
		rep (j, sz (b))
			cmx (res[i + j], a[i] + b[j] + i * j * diff[m]);
	return res;
}

int main()
{
	cin >> n >> k;
	rep (i, n) cin >> s[i];
	sort (s, s + n);
	rep (i, n-1)
		diff[i+1] = mismatch (all (s[i]), s[i+1].begin()).first - s[i].begin();

/**/rep (i, n) cerr << " ** " << diff[i] << ' ' << s[i] << endl;

	cout << solve (0, n) [k] << endl;

	{ int _; cin >> _; }
}


#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 <bits/stdc++.h>

using namespace std;

#define dbgs(x) cerr << (#x) << " --> " << (x) << ' '
#define dbg(x) cerr << (#x) << " --> " << (x) << endl

#define foreach(i,x) for(type(x)i=x.begin();i!=x.end();i++)
#define FOR(ii,aa,bb) for(int ii=aa;ii<=bb;ii++)
#define ROF(ii,aa,bb) for(int ii=aa;ii>=bb;ii--)

#define type(x) __typeof(x.begin())

#define orta (bas + son >> 1)
#define sag (k + k + 1)
#define sol (k + k)

#define pb push_back
#define mp make_pair

#define nd second
#define st first

#define endl '\n'

typedef pair < int ,int > pii;

typedef long long ll;

const long long linf = 1e18+5;
const int mod = (int) 1e9 + 7;
const int logN = 18;
const int inf = 1e9;
const int N = 2e3+5;

int n, m, x, y, lcp[N];
string str[N];

vector< int  > solve(int x, int y) {
    if(x >= y) {
        vector< int > v;
        v.resize(2, 0);
        return v;
    }
    int mid = min_element(lcp+x,lcp+y) - lcp, n = y - x + 1;
    vector< int > l = solve(x, mid),
                  r = solve(mid+1, y),
                  cur;
    int ls = mid - x + 1,
        rs = y - mid;
    cur.resize(min(ls+rs+1, m+1), 0);
    for(int m = 1; m <= min(::m, y-x+1); m++) {
        for(int i = max(m-rs, 0); i <= m && i <= ls; i++) {
            cur[m] = max(cur[m], l[i] + r[m-i] + i * (m-i) * lcp[mid]);
        }
    }
    return cur;
}

int main() {

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

    FOR(i, 1, n)
        cin >> str[i];

    sort(str + 1, str + n + 1);

    FOR(i, 1, n-1) {
        int lcp = 0;
        while(lcp < min(str[i].size(), str[i+1].size()) && str[i][lcp] == str[i+1][lcp])
            lcp++;
        ::lcp[i] = lcp;
    }

    cout << solve(1, n).back() << endl;

    return 0;
}


#include<cstdio>
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>

using namespace std;

struct node{
	int cnt;//the num of leaf of the node
	int sub;//the num of leaf in the subtree
	bool leaf;
	char ch;
	node* nxt[26];
	//int dp[2020];
	//int tmp[2020];
	vector<int> dp,tmp;
	bool visited;
	node()
	{
		leaf=false;
		ch='\0';
		cnt=0;
		sub=0;
		for(int i=0;i<26;i++)
		{
			nxt[i]=NULL;
		}
		visited=false;
	}
};

struct trie{
	node* root;
	trie()
	{
		root=new node();
	}
	void insert(string str)
	{
		node *p=root;
		int ln=str.size();
		for(int i=0;i<ln;i++)
		{
			int id=str[i]-'a';
			if((*p).nxt[id]==NULL)
			{
				p->nxt[id]=new node();
			}
			p->sub++;
			p=p->nxt[id];
			p->ch=str[i];
		}
		p->leaf=true;
		p->cnt++;
		p->sub++;
	}
	void rec(node* p)
	{
		if(p->visited) return;
		for(int i=0;i<26;i++) if(p->nxt[i]!=NULL) rec(p->nxt[i]);
		for(int i=0;i<=p->sub;i++) p->dp.push_back(0);
		for(int i=0;i<=p->sub;i++) p->tmp.push_back(0);
		int all=0;
		for(int i=0;i<=(p->sub);i++) p->tmp[i]=0;
		//if(p==root->nxt[0]) printf("%d %d\n",p->sub,p->cnt);
		for(int i=0;i<26;i++)
		{
			if(p->nxt[i]==NULL) continue;
			int now=(p->nxt[i])->sub;
			for(int a=0;a<=all+now;a++) p->tmp[a]=0;
			for(int n=0;n<=now;n++)
			{
				for(int a=0;a<=all;a++)
				{
					p->tmp[n+a]=max(p->tmp[n+a],p->dp[a]+(p->nxt[i])->dp[n]+n*(n-1)/2);
					//if(p==root->nxt[0]) printf("%d %d %d %d\n",n,a,(p->nxt[i])->dp[n],p->dp[a]);
				}
			}
			all+=now;
			for(int a=0;a<=all;a++) p->dp[a]=p->tmp[a];
		}
		for(int i=0;i<=all;i++) p->dp[i]=p->tmp[i];
		for(int i=0;i<=p->cnt;i++)
		{
			p->dp[all+i]=p->dp[all];
		}
		p->visited=true;
	}
};

string strs[2020];
int ln[2020];
int same[2020];

trie tr;

int main()
{
	int N,K;
	cin>>N>>K;
	for(int i=0;i<N;i++) cin>>strs[i];
	sort(strs,strs+N);
	for(int i=0;i<N;i++) ln[i]=strs[i].size();
	same[0]=ln[0],same[N-1]=ln[N-1];
	int dis=0;
	for(int i=1;i<N-1;i++)
	{
		bool flg=false;
		for(int j=0;j<ln[i];j++)
		{
			char pre=ln[i-1]<j+1?' ':strs[i-1][j];
			char nxt=ln[i+1]<j+1?' ':strs[i+1][j];
			if(strs[i][j]!=pre&&strs[i][j]!=nxt)
			{
				same[i]=j;
				flg=true;
				break;
			}
		}
		if(flg==false) same[i]=ln[i];
		if(same[i]==0) dis++;
	}
	for(int i=0;i<N;i++) strs[i]=strs[i].substr(0,same[i]);
	for(int i=0;i<N;i++) tr.insert(strs[i]);
	tr.rec(tr.root);
	if(N-dis<K) K=N-dis;
	cout<<(tr.root)->dp[K]<<"\n";
	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 <iostream>
#include <cstdio>
#include <cstdlib>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <cmath>
#include <cstring>
#include <queue>
#include <stack>
#include <algorithm>
#include <sstream>
using namespace std;

#define f first
#define s second
#define mp make_pair
#define sz(a) int((a).size())
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define forit(it,S) for(__typeof(S.begin()) it = S.begin(); it != S.end(); ++it)

typedef pair <int, int> pi;

char s[1111];
int to[111111][26];
int cnt[111111];
int dp[555][2222];
int vn, root, n, k;

void add() {
	int n = strlen(s);
	int u = root;
	for (int i = 0; i < n; ++i) {
		int &v = to[u][s[i] - 'a'];
		if (v == -1) {
			v = vn++;
		}
		++cnt[v];
		u = v;
	}
}

void calc(int u, int d) {

	for (int j = 0; j <= cnt[u]; ++j)
		dp[d][j] = -1;

	dp[d][0] = 0;

	int tt = cnt[u];
	for (int i = 0; i < 26; ++i) if (to[u][i] != -1) {
		int v = to[u][i];

		tt -= cnt[v];
		calc(v, d + 1);

		for (int j = cnt[u] - 1; j >= 0; --j) if (dp[d][j] != -1) {
			for (int k = 1; k <= cnt[v] && j + k <= cnt[u]; ++k) if (dp[d + 1][k] != -1) {
				dp[d][j + k] = max(dp[d][j + k], dp[d][j] + dp[d + 1][k]);
			}
		}
	}

	if (tt > 0) {
		for (int j = cnt[u] - tt; j >= 0; --j) if (dp[d][j] != -1) {
			for (int k = 1; k <= tt; ++k)
				dp[d][j + k] = max(dp[d][j + k], dp[d][j]);
		}
	}
	if (u != 0) {
		for (int k = 1; k <= cnt[u]; ++k) if (dp[d][k] != -1) {
			dp[d][k] += k * (k - 1) / 2;
		}
	}
}

int main() {
	memset(to, -1, sizeof(to));
	vn = 1;
	scanf("%d%d\n", &n, &k);
	for (int i = 0; i < n; ++i) {
		gets(s);
		add();
	}
	/*for (int i = 0; i < vn; ++i) {
		printf("%d %d\n", i, cnt[i]);
		for (int j = 0; j < 26; ++j) if (to[i][j] != -1)
			printf("(%d %d) ", j, to[i][j]);
		puts("");
	}*/

	cnt[0] = n;
	calc(0, 0);
	cout << dp[0][k] << endl;
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <cmath>
#include <cstring>
#include <queue>
#include <stack>
#include <algorithm>
#include <sstream>
using namespace std;

#define f first
#define s second
#define mp make_pair
#define sz(a) int((a).size())
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define forit(it,S) for(__typeof(S.begin()) it = S.begin(); it != S.end(); ++it)

typedef pair <int, int> pi;

char s[1111];
int to[1111111][26];
int cnt[1111111];
int dp[555][2222];
int vn, root, n, k;

void add() {
	int n = strlen(s);
	int u = root;
	for (int i = 0; i < n; ++i) {
		int &v = to[u][s[i] - 'a'];
		if (v == -1) {
			v = vn++;
		}
		++cnt[v];
		u = v;
	}
}

void calc(int u, int d) {

	for (int j = 0; j <= cnt[u]; ++j)
		dp[d][j] = -1;

	dp[d][0] = 0;

	int tt = cnt[u];
	for (int i = 0; i < 26; ++i) if (to[u][i] != -1) {
		int v = to[u][i];

		tt -= cnt[v];
		calc(v, d + 1);

		for (int j = cnt[u] - 1; j >= 0; --j) if (dp[d][j] != -1) {
			for (int k = 1; k <= cnt[v] && j + k <= cnt[u]; ++k) if (dp[d + 1][k] != -1) {
				dp[d][j + k] = max(dp[d][j + k], dp[d][j] + dp[d + 1][k]);
			}
		}
	}

	if (tt > 0) {
		for (int j = cnt[u] - tt; j >= 0; --j) if (dp[d][j] != -1) {
			for (int k = 1; k <= tt; ++k)
				dp[d][j + k] = max(dp[d][j + k], dp[d][j]);
		}
	}
	if (u != 0) {
		for (int k = 1; k <= cnt[u]; ++k) if (dp[d][k] != -1) {
			dp[d][k] += k * (k - 1) / 2;
		}
	}
}

int main() {
	memset(to, -1, sizeof(to));
	vn = 1;
	scanf("%d%d\n", &n, &k);
	for (int i = 0; i < n; ++i) {
		gets(s);
		add();
	}
	/*for (int i = 0; i < vn; ++i) {
		printf("%d %d\n", i, cnt[i]);
		for (int j = 0; j < 26; ++j) if (to[i][j] != -1)
			printf("(%d %d) ", j, to[i][j]);
		puts("");
	}*/

	cnt[0] = n;
	calc(0, 0);
	cout << dp[0][k] << endl;
	return 0;
}


#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string>
using namespace std;
int n,m,k,takoebi,lcp[10001],dp[4001][4001];
string s[2001];
long str(string t,string s) {
     long qrt=0;
     for (int k=0;k<t.size();++k){
         if (k>=s.size()) break;
         if (t[k]==s[k]) ++qrt;else break;
     }
     return qrt;
     }
     int kargistynai(int l,int r){
          if (l==r) return n;
          long ind=l,x,y;
          for (int k=l;k<r;++k) if (lcp[ind]>lcp[k]) ind=k;
          x=kargistynai(l,ind);  y=kargistynai(ind+1,r);
             ++takoebi;
             for (int i=0;i<=ind-l+1;++i)
               for (int j=0;j<=r-ind;++j) dp[takoebi][i+j]=max(dp[takoebi][i+j],dp[x][i]+dp[y][j]+i*j*lcp[ind]);
               return takoebi;
          }
int main() {
  //  freopen("input.txt","r",stdin);
 // freopen("output.txt","w",stdout);
	cin>>n>>m;
for (int k=1;k<=n;++k)
  cin>>s[k];
  sort(s+1,s+n+1);
  for (int k=1;k<=n-1;++k) {
      lcp[k]=str(s[k],s[k+1]);}
 long z=kargistynai(1,n);
 cout<<dp[z][m];
return 0;
}


#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string>
using namespace std;
int n,m,k,lcp[10001],dp[101][101][101];
string s[2001];
long str(string t,string s) {
     long qrt=0;
     for (int k=0;k<t.size();++k){
         if (k>=s.size()) break;
         if (t[k]==s[k]) ++qrt;else break;
     }
     return qrt;
     }
int main() {
  //  freopen("input.txt","r",stdin);
  //  freopen("output.txt","w",stdout);
	cin>>n>>m;
for (int k=1;k<=n;++k)
  cin>>s[k];
  sort(s+1,s+n+1);
  for (int k=1;k<=n-1;++k) {
      lcp[k]=str(s[k],s[k+1]);}
    dp[1][1][1]=0;dp[1][2][2]=lcp[1];int maxx=0;
    for (int k=n-1;k>=1;--k){
        for (int i=k+1;i<=n;++i){
            long ind=k;for (int j=k;j<=i-1;++j) if (lcp[j]<lcp[ind]) ind=j;
            for (int j=1;j<=m;++j){
        for (int q=0;q<=j;++q) { if (q>ind-k+1) continue;
        dp[k][i][j]=max(dp[k][ind][q]+dp[ind+1][i][j-q]+(j-q)*q*lcp[ind],dp[k][i][j]);}
        if (i-k+1<j) dp[k][i][j]=0;
            if (j==m) maxx=max(maxx,dp[k][i][j]);
             }
        }
    }
    cout<<maxx;
return 0;
}


#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string>
using namespace std;
int n,m,k,lcp[10001],dp[101][101][101];
string s[2001];
long str(string t,string s) {
     long qrt=0;
     for (int k=0;k<t.size();++k){
         if (k>=s.size()) break;
         if (t[k]==s[k]) ++qrt;else break;
     }
     return qrt;
     }
int main() {
  //  freopen("input.txt","r",stdin);
  //  freopen("output.txt","w",stdout);
	cin>>n>>m;
for (int k=1;k<=n;++k)
  cin>>s[k];
  sort(s+1,s+n+1);
  for (int k=1;k<=n-1;++k) {
      lcp[k]=str(s[k],s[k+1]);}
    dp[1][1][1]=0;dp[1][2][2]=lcp[1];int maxx=0;
    for (int k=n-1;k>=1;--k){
        for (int i=k+1;i<=n;++i){
            long ind=k;for (int j=k;j<=i-1;++j) if (lcp[j]<lcp[ind]) ind=j;
            for (int j=1;j<=m;++j){
        for (int q=0;q<=j;++q) { if (q>ind-k+1) continue;
        dp[k][i][j]=max(dp[k][ind][q]+dp[ind+1][i][j-q]+(j-q)*q*lcp[ind],dp[k][i][j]);}
        if (i-k+1<j) dp[k][i][j]=0;
            if (j==m) maxx=max(maxx,dp[k][i][j]);
             }
        }
    }
    cout<<dp[1][n][m];
return 0;
}


#include<cstdio>
#include<algorithm>
#include<string>
using namespace std;
#define rep(i,n) for (int i=0;i<n;i++)
#define N 2005
string a[N]; char s[N];
int f[N*2][N],h[N],n,m,k;
void dp(int l,int r,int x)
{
	if (l>=r) return; int L=++m,R=++m,mid=l;
	for (int i=l;i<r;i++) if (h[i]<h[mid]) mid=i; dp(l,mid,L),dp(mid+1,r,R);
	rep(i,mid-l+2) rep(j,r-mid+1) if (i+j<=k)
		f[x][i+j]=max(f[x][i+j],h[mid]*i*j+f[L][i]+f[R][j]);
}
int main()
{
	scanf("%d%d ",&n,&k); rep(i,n) gets(s),a[i]=s; sort(a,a+n);
	rep(i,n-1){
		h[i]=min(a[i].size(),a[i+1].size());
		rep(j,h[i])	if (a[i][j]!=a[i+1][j]) h[i]=j;
		}
	dp(0,n-1,0); printf("%d\n",f[0][k]); return 0;
}


#include <iostream>
#include <string>
#include <cstring>
#include <set>
#include <map>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cmath>
#include <queue>

using namespace std;

int n, k;
string s[2100];

struct node {
	node * p[27];
	vector <int> v;
	int cnt;

	node() {
		cnt = 0;
		for (int i = 0; i < 27; ++i) {
			p[i] = NULL;
		}
	}

	int isNull() {
		for (int i = 0; i < 26; ++i) {
			if (p[i]) return 1;
		}
		return 0;
	}
};

node * head;

void add(node * head, const string& s) {
	node * cur = head;
	for (int i = 0; i < s.length(); ++i) {
		if (cur->p[s[i] - 'a']) {
			++cur->cnt;
			cur = cur->p[s[i] - 'a'];
		} else {
			cur->p[s[i] - 'a'] = new node;
			++cur->cnt;
			cur = cur->p[s[i] - 'a'];
		}
	}
	++cur->cnt;
}

int cmp(node * a, node * b) {
	if (a == NULL) return 0;
	if (b == NULL) return 1;
	return a->cnt < b->cnt;
}

void dp(node * head) {
	if (head == NULL) return;
	if (!head->isNull()) {
		head->v.resize(head->cnt + 1);
		for (int i = 0; i <= head->cnt; ++i) {
			head->v[i] = (i * (i - 1)) / 2;
		}
		return;
	}

	for (int i = 0; i < 26; ++i) {
		dp(head->p[i]);
	}

	vector <int> d[2];
	head->p[26] = new node();
	int cnt = head->cnt;
	for (int i = 0; i < 26; ++i) {
		if (head->p[i]) {
			cnt -= head->p[i]->cnt;
		}
	}

	if (cnt > 0) {
		head->p[26]->v.assign(cnt + 1, 0);
		head->p[26]->cnt = cnt;
	} else {
		head->p[26] = NULL;
	}

	sort(head->p, head->p + 27, cmp);
	int u = 0, v = 1;
	d[u].push_back(0);

	for (int i = 0; i < 27; ++i) {
		if (head->p[i] == NULL) break;
		int cur = d[u].size();
		d[v].resize(min(k + 1, cur + head->p[i]->cnt));
		for (int j = 0; j <= k && j < cur + head->p[i]->cnt; ++j) {
			d[v][j] = 0;
			if (j <= head->p[i]->cnt) d[v][j] = head->p[i]->v[j];
			for (int l = min(head->p[i]->cnt, j); l >= 0 && j - l < d[u].size(); --l) {
				d[v][j] = max(d[v][j], d[u][j - l] + head->p[i]->v[l]);
			}
		}
		swap(u, v);
	}

	for (int i = 0; i < 27; ++i) {
		if (head->p[i]) head->p[i]->v.clear();
		delete head->p[i];
	}

	head->v.resize(min(k + 1, head->cnt + 1), 0);
	for (int i = 0; i <= min(k, head->cnt); ++i) {
		head->v[i] = d[u][i];
		head->v[i] += (i * (i - 1)) / 2;
	}
}

int main() {
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	cin >> n >> k;
	for (int i = 0; i < n; ++i) {
		cin >> s[i];
	}

	head = new node();
	for (int i = 0; i < n; ++i) {
		add(head, s[i]);
	}

	dp(head);
	cout << head->v[k] - (k * (k - 1)) / 2 << endl;

	return 0;
}


#include <iostream>
#include <string>
#include <cstring>
#include <set>
#include <map>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cmath>
#include <queue>

using namespace std;

int n, k;
string s[1000];

struct node {
	node * p[26];
	vector <int> v;
	int cnt;

	node() {
		cnt = 0;
		for (int i = 0; i < 26; ++i) {
			p[i] = NULL;
		}
	}

	int isNull() {
		for (int i = 0; i < 26; ++i) {
			if (p[i]) return 1;
		}
		return 0;
	}
};

node * head;

void add(node * head, const string& s) {
	node * cur = head;
	for (int i = 0; i < s.length(); ++i) {
		if (cur->p[s[i] - 'a']) {
			++cur->cnt;
			cur = cur->p[s[i] - 'a'];
		} else {
			cur->p[s[i] - 'a'] = new node;
			++cur->cnt;
			cur = cur->p[s[i] - 'a'];
		}
	}
	++cur->cnt;
}

int cmp(node * a, node * b) {
	if (a == NULL) return 0;
	if (b == NULL) return 1;
	return a->cnt < b->cnt;
}

void dp(node * head) {
	if (head == NULL) return;
	if (!head->isNull()) {
		head->v.resize(head->cnt + 1);
		for (int i = 0; i <= head->cnt; ++i) {
			head->v[i] = (i * (i - 1)) / 2;
		}
		return;
	}

	for (int i = 0; i < 26; ++i) {
		dp(head->p[i]);
	}

	vector <int> d[2];

	sort(head->p, head->p + 26, cmp);
	int u = 0, v = 1;
	d[u].push_back(0);

	for (int i = 0; i < 26; ++i) {
		if (head->p[i] == NULL) break;
		int cur = d[u].size();
		d[v].resize(min(k + 1, cur + head->p[i]->cnt));
		for (int j = 0; j <= k && j < cur + head->p[i]->cnt; ++j) {
			d[v][j] = 0;
			if (j <= head->p[i]->cnt) d[v][j] = head->p[i]->v[j];
			for (int l = 0; l <= head->p[i]->cnt && l <= j && j - l < d[u].size(); ++l) {
				d[v][j] = max(d[v][j], d[u][j - l] + head->p[i]->v[l]);
			}
		}
		swap(u, v);
	}

	for (int i = 0; i < 26; ++i) {
		if (head->p[i]) head->p[i]->v.clear();
	}

	head->v.resize(min(k + 1, head->cnt + 1), 0);
	for (int i = 0; i <= min(k, head->cnt); ++i) {
		head->v[i] = d[u][i];
		head->v[i] += (i * (i - 1)) / 2;
	}
}

int main() {
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	cin >> n >> k;
	for (int i = 0; i < n; ++i) {
		cin >> s[i];
	}

	head = new node();
	for (int i = 0; i < n; ++i) {
		add(head, s[i]);
	}

	dp(head);
	cout << head->v[k] - (k * (k - 1)) / 2 << endl;

	return 0;
}


#include <iostream>
#include <string>
#include <cstring>
#include <set>
#include <map>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cmath>
#include <queue>

using namespace std;

int n, k;
string s[1000];

struct node {
	node * p[27];
	vector <int> v;
	int cnt;

	node() {
		cnt = 0;
		for (int i = 0; i < 27; ++i) {
			p[i] = NULL;
		}
	}

	int isNull() {
		for (int i = 0; i < 26; ++i) {
			if (p[i]) return 1;
		}
		return 0;
	}
};

node * head;

void add(node * head, const string& s) {
	node * cur = head;
	for (int i = 0; i < s.length(); ++i) {
		if (cur->p[s[i] - 'a']) {
			++cur->cnt;
			cur = cur->p[s[i] - 'a'];
		} else {
			cur->p[s[i] - 'a'] = new node;
			++cur->cnt;
			cur = cur->p[s[i] - 'a'];
		}
	}
	++cur->cnt;
}

int cmp(node * a, node * b) {
	if (a == NULL) return 0;
	if (b == NULL) return 1;
	return a->cnt < b->cnt;
}

void dp(node * head) {
	if (head == NULL) return;
	if (!head->isNull()) {
		head->v.resize(head->cnt + 1);
		for (int i = 0; i <= head->cnt; ++i) {
			head->v[i] = (i * (i - 1)) / 2;
		}
		return;
	}

	for (int i = 0; i < 26; ++i) {
		dp(head->p[i]);
	}

	vector <int> d[2];
	head->p[26] = new node();
	int cnt = head->cnt;
	for (int i = 0; i < 26; ++i) {
		if (head->p[i]) {
			cnt -= head->p[i]->cnt;
		}
	}

	if (cnt > 0) {
		head->p[26]->v.assign(cnt + 1, 0);
		head->p[26]->cnt = cnt;
	} else {
		head->p[26] = NULL;
	}

	sort(head->p, head->p + 27, cmp);
	int u = 0, v = 1;
	d[u].push_back(0);

	for (int i = 0; i < 27; ++i) {
		if (head->p[i] == NULL) break;
		int cur = d[u].size();
		d[v].resize(min(k + 1, cur + head->p[i]->cnt));
		for (int j = 0; j <= k && j < cur + head->p[i]->cnt; ++j) {
			d[v][j] = 0;
			if (j <= head->p[i]->cnt) d[v][j] = head->p[i]->v[j];
			for (int l = 0; l <= head->p[i]->cnt && l <= j; ++l) {
				if (j - l < d[u].size()) d[v][j] = max(d[v][j], d[u][j - l] + head->p[i]->v[l]);
			}
		}
		swap(u, v);
	}

	for (int i = 0; i < 27; ++i) {
		if (head->p[i]) head->p[i] = NULL;
	}

	head->v.resize(min(k + 1, head->cnt + 1), 0);
	for (int i = 0; i <= min(k, head->cnt); ++i) {
		head->v[i] = d[u][i];
		head->v[i] += (i * (i - 1)) / 2;
	}
}

int main() {
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	cin >> n >> k;
	for (int i = 0; i < n; ++i) {
		cin >> s[i];
	}

	head = new node();
	for (int i = 0; i < n; ++i) {
		add(head, s[i]);
	}

	dp(head);
	cout << head->v[k] - (k * (k - 1)) / 2 << endl;

	return 0;
}


#include <iostream>
#include <string>
#include <cstring>
#include <set>
#include <map>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cmath>
#include <queue>

using namespace std;

int n, k;
string s[2100];

struct node {
	node * p[27];
	vector <int> v;
	int cnt;

	node() {
		cnt = 0;
		for (int i = 0; i < 27; ++i) {
			p[i] = NULL;
		}
	}

	int isNull() {
		for (int i = 0; i < 26; ++i) {
			if (p[i]) return 1;
		}
		return 0;
	}
};

node * head;

void add(node * head, const string& s) {
	node * cur = head;
	for (int i = 0; i < s.length(); ++i) {
		if (cur->p[s[i] - 'a']) {
			++cur->cnt;
			cur = cur->p[s[i] - 'a'];
		} else {
			cur->p[s[i] - 'a'] = new node;
			++cur->cnt;
			cur = cur->p[s[i] - 'a'];
		}
	}
	++cur->cnt;
}

int cmp(node * a, node * b) {
	if (a == NULL) return 0;
	if (b == NULL) return 1;
	return a->cnt < b->cnt;
}

void dp(node * head) {
	if (head == NULL) return;
	if (!head->isNull()) {
		head->v.resize(head->cnt + 1);
		for (int i = 0; i <= head->cnt; ++i) {
			head->v[i] = (i * (i - 1)) / 2;
		}
		return;
	}

	for (int i = 0; i < 26; ++i) {
		dp(head->p[i]);
	}

	vector <int> d[2];
	head->p[26] = new node();
	int cnt = head->cnt;
	for (int i = 0; i < 26; ++i) {
		if (head->p[i]) {
			cnt -= head->p[i]->cnt;
		}
	}

	if (cnt > 0) {
		head->p[26]->v.assign(cnt + 1, 0);
		head->p[26]->cnt = cnt;
	} else {
		head->p[26] = NULL;
	}

	sort(head->p, head->p + 27, cmp);
	int u = 0, v = 1;
	d[u].push_back(0);

	for (int i = 0; i < 27; ++i) {
		if (head->p[i] == NULL) break;
		int cur = d[u].size();
		d[v].resize(min(k + 1, cur + head->p[i]->cnt));
		for (int j = 0; j <= k && j < cur + head->p[i]->cnt; ++j) {
			d[v][j] = 0;
			if (j <= head->p[i]->cnt) d[v][j] = head->p[i]->v[j];
			for (int l = 0; l <= head->p[i]->cnt && l <= j; ++l) {
				if (j - l < d[u].size()) d[v][j] = max(d[v][j], d[u][j - l] + head->p[i]->v[l]);
			}
		}
		swap(u, v);
	}

	for (int i = 0; i < 27; ++i) {
		if (head->p[i]) head->p[i]->v.clear();
		delete head->p[i];
	}

	head->v.resize(min(k + 1, head->cnt + 1), 0);
	for (int i = 0; i <= min(k, head->cnt); ++i) {
		head->v[i] = d[u][i];
		head->v[i] += (i * (i - 1)) / 2;
	}
}

int main() {
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	cin >> n >> k;
	for (int i = 0; i < n; ++i) {
		cin >> s[i];
	}

	head = new node();
	for (int i = 0; i < n; ++i) {
		add(head, s[i]);
	}

	dp(head);
	cout << head->v[k] - (k * (k - 1)) / 2 << endl;

	return 0;
}


#include <iostream>
#include <string>
#include <cstring>
#include <set>
#include <map>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cmath>
#include <queue>

using namespace std;

int n, k;
string s[1000];

struct node {
	node * p[26];
	vector <int> v;
	int cnt;

	node() {
		cnt = 0;
		for (int i = 0; i < 26; ++i) {
			p[i] = NULL;
		}
	}

	int isNull() {
		for (int i = 0; i < 26; ++i) {
			if (p[i]) return 1;
		}
		return 0;
	}
};

node * head;

void add(node * head, const string& s) {
	node * cur = head;
	for (int i = 0; i < s.length(); ++i) {
		if (cur->p[s[i] - 'a']) {
			++cur->cnt;
			cur = cur->p[s[i] - 'a'];
		} else {
			cur->p[s[i] - 'a'] = new node;
			++cur->cnt;
			cur = cur->p[s[i] - 'a'];
		}
	}
	++cur->cnt;
}

int cmp(node * a, node * b) {
	if (a == NULL) return 0;
	if (b == NULL) return 1;
	return a->cnt < b->cnt;
}

void dp(node * head) {
	if (head == NULL) return;
	if (!head->isNull()) {
		head->v.resize(head->cnt + 1);
		for (int i = 0; i <= head->cnt; ++i) {
			head->v[i] = (i * (i - 1)) / 2;
		}
		return;
	}

	for (int i = 0; i < 26; ++i) {
		dp(head->p[i]);
	}

	vector <int> d[2];

	sort(head->p, head->p + 26, cmp);
	int u = 0, v = 1;

	for (int i = 0; i < 26; ++i) {
		if (head->p[i] == NULL) break;
		int cur = d[u].size();
		d[v].resize(min(k + 1, cur + head->p[i]->cnt + 1));
		for (int j = 0; j <= k && j <= cur + head->p[i]->cnt; ++j) {
			d[v][j] = 0;
			for (int l = 0; l <= head->p[i]->cnt && l <= j; ++l) {
				d[v][j] = max(d[v][j], d[u][j - l] + head->p[i]->v[l]);
			}
		}
		swap(u, v);
	}

	for (int i = 0; i < 26; ++i) {
		if (head->p[i]) head->p[i]->v.clear();
	}

	head->v.resize(head->cnt + 1);
	for (int i = 0; i <= head->cnt; ++i) {
		head->v[i] = d[u][i];
		head->v[i] += (i * (i - 1)) / 2;
	}
}

int main() {
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	cin >> n >> k;
	for (int i = 0; i < n; ++i) {
		cin >> s[i];
	}

	head = new node();
	for (int i = 0; i < n; ++i) {
		add(head, s[i]);
	}

	dp(head);
	cout << head->v[k] - (k * (k - 1)) / 2 << endl;

	return 0;
}


#include <iostream>
#include <string>
#include <cstring>
#include <set>
#include <map>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cmath>
#include <queue>

using namespace std;

int n, k;
string s[2100];

struct node {
	node * p[27];
	vector <int> v;
	int cnt;

	node() {
		cnt = 0;
		for (int i = 0; i < 27; ++i) {
			p[i] = NULL;
		}
	}

	int isNull() {
		for (int i = 0; i < 26; ++i) {
			if (p[i]) return 1;
		}
		return 0;
	}
};

node * head;

void add(node * head, const string& s) {
	node * cur = head;
	for (int i = 0; i < s.length(); ++i) {
		if (cur->p[s[i] - 'a']) {
			++cur->cnt;
			cur = cur->p[s[i] - 'a'];
		} else {
			cur->p[s[i] - 'a'] = new node;
			++cur->cnt;
			cur = cur->p[s[i] - 'a'];
		}
	}
	++cur->cnt;
}

int cmp(node * a, node * b) {
	if (a == NULL) return 0;
	if (b == NULL) return 1;
	return a->cnt < b->cnt;
}

void dp(node * head) {
	if (head == NULL) return;
	if (!head->isNull()) {
		head->v.resize(head->cnt + 1);
		for (int i = 0; i <= head->cnt; ++i) {
			head->v[i] = (i * (i - 1)) / 2;
		}
		return;
	}

	for (int i = 0; i < 26; ++i) {
		dp(head->p[i]);
	}

	vector <int> d[2];
	head->p[26] = new node();
	int cnt = head->cnt;
	for (int i = 0; i < 26; ++i) {
		if (head->p[i]) {
			cnt -= head->p[i]->cnt;
		}
	}

	if (cnt > 0) {
		head->p[26]->v.assign(cnt + 1, 0);
		head->p[26]->cnt = cnt;
	} else {
		head->p[26] = NULL;
	}

	sort(head->p, head->p + 27, cmp);
	int u = 0, v = 1;
	d[u].push_back(0);

	for (int i = 0; i < 27; ++i) {
		if (head->p[i] == NULL) break;
		int cur = d[u].size();
		d[v].resize(min(k + 1, cur + head->p[i]->cnt));
		for (int j = 0; j <= k && j < cur + head->p[i]->cnt; ++j) {
			d[v][j] = 0;
			if (j <= head->p[i]->cnt) d[v][j] = head->p[i]->v[j];
			for (int l = 0; l <= head->p[i]->cnt && l <= j; ++l) {
				if (j - l < d[u].size()) d[v][j] = max(d[v][j], d[u][j - l] + head->p[i]->v[l]);
			}
		}
		swap(u, v);
	}

	for (int i = 0; i < 27; ++i) {
		if (head->p[i]) head->p[i] = NULL;
	}

	head->v.resize(min(k + 1, head->cnt + 1), 0);
	for (int i = 0; i <= min(k, head->cnt); ++i) {
		head->v[i] = d[u][i];
		head->v[i] += (i * (i - 1)) / 2;
	}
}

int main() {
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	cin >> n >> k;
	for (int i = 0; i < n; ++i) {
		cin >> s[i];
	}

	head = new node();
	for (int i = 0; i < n; ++i) {
		add(head, s[i]);
	}

	dp(head);
	cout << head->v[k] - (k * (k - 1)) / 2 << endl;

	return 0;
}


#include <iostream>
#include <string>
#include <cstring>
#include <set>
#include <map>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cmath>
#include <queue>

using namespace std;

int n, k;
string s[1000];

struct node {
	node * p[27];
	vector <int> v;
	int cnt;

	node() {
		cnt = 0;
		for (int i = 0; i < 27; ++i) {
			p[i] = NULL;
		}
	}

	int isNull() {
		for (int i = 0; i < 26; ++i) {
			if (p[i]) return 1;
		}
		return 0;
	}
};

node * head;

void add(node * head, const string& s) {
	node * cur = head;
	for (int i = 0; i < s.length(); ++i) {
		if (cur->p[s[i] - 'a']) {
			++cur->cnt;
			cur = cur->p[s[i] - 'a'];
		} else {
			cur->p[s[i] - 'a'] = new node;
			++cur->cnt;
			cur = cur->p[s[i] - 'a'];
		}
	}
	++cur->cnt;
}

int cmp(node * a, node * b) {
	if (a == NULL) return 0;
	if (b == NULL) return 1;
	return a->cnt < b->cnt;
}

void dp(node * head) {
	if (head == NULL) return;
	if (!head->isNull()) {
		head->v.resize(head->cnt + 1);
		for (int i = 0; i <= head->cnt; ++i) {
			head->v[i] = (i * (i - 1)) / 2;
		}
		return;
	}

	for (int i = 0; i < 26; ++i) {
		dp(head->p[i]);
	}

	vector <int> d[2];
	head->p[26] = new node();
	int cnt = head->cnt;
	for (int i = 0; i < 26; ++i) {
		if (head->p[i]) {
			cnt -= head->p[i]->cnt;
		}
	}

	if (cnt > 0) {
		head->p[26]->v.assign(cnt + 1, 0);
		head->p[26]->cnt = cnt;
	} else {
		head->p[26] = NULL;
	}

	sort(head->p, head->p + 27, cmp);
	int u = 0, v = 1;
	d[u].push_back(0);

	for (int i = 0; i < 27; ++i) {
		if (head->p[i] == NULL) break;
		int cur = d[u].size();
		d[v].resize(min(k + 1, cur + head->p[i]->cnt));
		for (int j = 0; j <= k && j < cur + head->p[i]->cnt; ++j) {
			d[v][j] = 0;
			if (j <= head->p[i]->cnt) d[v][j] = head->p[i]->v[j];
			for (int l = 0; l <= head->p[i]->cnt && l <= j && j - l < d[u].size(); ++l) {
				d[v][j] = max(d[v][j], d[u][j - l] + head->p[i]->v[l]);
			}
		}
		swap(u, v);
	}

	for (int i = 0; i < 26; ++i) {
		if (head->p[i]) head->p[i] = NULL;
	}

	head->v.resize(min(k + 1, head->cnt + 1), 0);
	for (int i = 0; i <= min(k, head->cnt); ++i) {
		head->v[i] = d[u][i];
		head->v[i] += (i * (i - 1)) / 2;
	}
}

int main() {
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	cin >> n >> k;
	for (int i = 0; i < n; ++i) {
		cin >> s[i];
	}

	head = new node();
	for (int i = 0; i < n; ++i) {
		add(head, s[i]);
	}

	dp(head);
	cout << head->v[k] - (k * (k - 1)) / 2 << endl;

	return 0;
}


#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
int N,K,i,tot;
string S[2005];
int H[2005],len[2005];
int f[4005][2005];
int Work(int l,int r)
{
	int A,B,C,mid,i,j;
	A=tot++;
	if(l==r) return A;
	mid=l+1;
	for(i=l+2;i<=r;++i) if(H[i]<H[mid]) mid=i;
	B=Work(l,mid-1),C=Work(mid,r);
	for(i=0;i<=mid-l;++i)
		for(j=0;j<=r-mid+1&&i+j<=K;++j)
			if(f[B][i]+f[C][j]+i*j*H[mid]>f[A][i+j])
				f[A][i+j]=f[B][i]+f[C][j]+i*j*H[mid];
	return A;
}
int main()
{
	scanf("%d%d",&N,&K);
	for(i=0;i<N;++i) cin>>S[i];
	sort(S,S+N);
	for(i=0;i<N;++i) len[i]=S[i].length();
	for(i=1;i<N;++i) for(H[i]=0;H[i]<len[i]&&H[i]<len[i-1]&&S[i][H[i]]==S[i-1][H[i]];++H[i]);
	printf("%d\n",f[Work(0,N-1)][K]);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
int N,K,i,tot;
string S[2005];
int H[2005];
int f[2005][2005];
int Work(int l,int r)
{
	int A,B,C,mid,i,j;
	A=++tot;
	if(l==r) return A;
	mid=l+1;
	for(i=l+2;i<=r;++i) if(H[i]<H[mid]) mid=i;
	B=Work(l,mid-1),C=Work(mid,r);
	for(i=0;i<=mid-l;++i)
		for(j=0;j<=r-mid+1&&i+j<=K;++j)
			if(f[B][i]+f[C][j]+i*j*H[mid]>f[A][i+j])
				f[A][i+j]=f[B][i]+f[C][j]+i*j*H[mid];
	return A;
}
int main()
{
	scanf("%d%d",&N,&K);
	for(i=0;i<N;++i) scanf("%s",S[i]);
	sort(S,S+N);
	for(i=1;i<N;++i) for(H[i]=0;S[i][H[i]]==S[i-1][H[i]];++H[i]);
	printf("%d\n",f[Work(0,N-1)][K]);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
int N,K,i,tot;
string S[2005];
int H[2005];
int f[2005][2005];
int Work(int l,int r)
{
	int A,B,C,mid,i,j;
	A=++tot;
	if(l==r) return A;
	mid=l+1;
	for(i=l+2;i<=r;++i) if(H[i]<H[mid]) mid=i;
	B=Work(l,mid-1),C=Work(mid,r);
	for(i=0;i<=mid-l;++i)
		for(j=0;j<=r-mid+1&&i+j<=K;++j)
			if(f[B][i]+f[C][j]+i*j*H[mid]>f[A][i+j])
				f[A][i+j]=f[B][i]+f[C][j]+i*j*H[mid];
	return A;
}
int main()
{
	scanf("%d%d",&N,&K);
	for(i=0;i<N;++i) cin>>S[i];
	sort(S,S+N);
	for(i=1;i<N;++i) for(H[i]=0;S[i][H[i]]==S[i-1][H[i]];++H[i]);
	printf("%d\n",f[Work(0,N-1)][K]);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
int N,K,i,tot;
string S[2005];
int H[2005],len[2005];
int f[2005][2005];
int Work(int l,int r)
{
	int A,B,C,mid,i,j;
	A=tot++;
	if(l==r) return A;
	mid=l+1;
	for(i=l+2;i<=r;++i) if(H[i]<H[mid]) mid=i;
	B=Work(l,mid-1),C=Work(mid,r);
	for(i=0;i<=mid-l;++i)
		for(j=0;j<=r-mid+1&&i+j<=K;++j)
			if(f[B][i]+f[C][j]+i*j*H[mid]>f[A][i+j])
				f[A][i+j]=f[B][i]+f[C][j]+i*j*H[mid];
	return A;
}
int main()
{
	scanf("%d%d",&N,&K);
	for(i=0;i<N;++i) cin>>S[i];
	sort(S,S+N);
	for(i=0;i<N;++i) len[i]=S[i].length();
	for(i=1;i<N;++i) for(H[i]=0;H[i]<len[i]&&H[i]<len[i-1]&&S[i][H[i]]==S[i-1][H[i]];++H[i]);
	printf("%d\n",f[Work(0,N-1)][K]);
	return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<assert.h>
#include<stdarg.h>
#include<time.h>
#include<string>
#include<map>
#include<set>
#include<algorithm>
#include<vector>
using namespace std;
map<int,int> trie[1000100];
int cnt[1000100];
char tmp[1000];
int tc;
struct XD{
    int y,l;
    XD(int yy=-1,int ll=-1):y(yy),l(ll){}
};
vector<XD> ed[5000];
int nn;
int chn[5000];
inline void run(int np,int p){
    int i;
    map<int,int>::iterator it;
    for(it=trie[np].begin();it!=trie[np].end();it++){
        int cnt=0;
        int k=it->second,f=0;
        while(1){
            if(k<0){
                //cnt+=k;
                break;
            }
            if(trie[k].size()==0){
                cnt++;
                break;
            }
            if(trie[k].size()==1){
                cnt++;
                k=(trie[k].begin()->second);
            }else{
                cnt++;
                f=1;
                break;
            }
        }
        int pp=nn;
        nn++;
        ed[p].push_back(XD(pp,cnt));
        if(f){
            run(k,pp);
        }
    }
}
int dp[5010][5010];
inline int dpf(int np,int lp,int li){
    if(ed[np].size()==0){
        if(lp==1)return 0;
        else return -2;
    }
    int y=ed[np][li].y;
    int &d=dp[y][lp];
    if(d!=-1)return d;
    d=-2;
    // last one
    if(li+1==ed[np].size()){
        int r=dpf(y,lp,0);
        if(r==-2)d=-2;
        else d=r+ed[np][li].l*(lp*(lp-1)/2);
    }else{
        int k;
        int r;
        //select 0.
        r=dpf(np,lp,li+1);
        if(r!=-2)d=max(d,r);
        //select all
        if(chn[y]>=lp){
            r=dpf(y,lp,0);
            if(r!=-2)d=max(d,r+ed[np][li].l*(lp*(lp-1)/2));
        }
        //select some
        for(k=1;k<lp&&k<=chn[y];k++){
            int r1=dpf(y,k,0);
            if(r1==-2)break;
            int r2=dpf(np,lp-k,li+1);
            if(r2==-2)continue;
            d=max(d,r1+r2+ed[np][li].l*(k*(k-1)/2));
        }
    }
    //printf("np=%d lp=%d li=%d d=%d\n",np,lp,li,d);
    return d;
}
inline void cc(int np){
    chn[np]=1;
    for(int i=0;i<ed[np].size();i++){
        int y=ed[np][i].y;
        cc(y);
        chn[np]+=chn[y];
    }
}
int main(){
    int n,k,i,j;
    scanf("%d%d",&n,&k);
    tc=1;
    for(i=0;i<n;i++){
        scanf("%s",tmp);
        int np=0;
        map<int,int>::iterator it;
        for(j=0;tmp[j];j++){
            it=trie[np].find(tmp[j]-'a');
            int to;
            if(it==trie[np].end()){
                trie[np][tmp[j]-'a']=tc;
                to=tc;
                tc++;
            }else{
                to=it->second;
            }
            np=to;
        }
        trie[np][26+cnt[np]]=-1;
        cnt[np]++;
    }
    nn=1;
    run(0,0);
    cc(0);
    //printf("nn=%d\n",nn);
    //for(i=0;i<nn;i++)for(j=0;j<ed[i].size();j++)printf("%d -> %d (%d)\n",i,ed[i][j].y,ed[i][j].l);
    memset(dp,-1,sizeof(dp));
    printf("%d\n",dpf(0,k,0));
}


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<assert.h>
#include<stdarg.h>
#include<time.h>
#include<string>
#include<map>
#include<set>
#include<algorithm>
#include<vector>
using namespace std;
map<int,int> trie[1000100];
int cnt[1000100];
char tmp[1000];
int tc;
struct XD{
    int y,l;
    XD(int yy=-1,int ll=-1):y(yy),l(ll){}
};
vector<XD> ed[5000];
int nn;
inline void run(int np,int p){
    int i;
    map<int,int>::iterator it;
    for(it=trie[np].begin();it!=trie[np].end();it++){
        int cnt=0;
        int k=it->second,f=0;
        while(1){
            if(k<0){
                //cnt+=k;
                break;
            }
            if(trie[k].size()==0){
                cnt++;
                break;
            }
            if(trie[k].size()==1){
                cnt++;
                k=(trie[k].begin()->second);
            }else{
                cnt++;
                f=1;
                break;
            }
        }
        int pp=nn;
        nn++;
        ed[p].push_back(XD(pp,cnt));
        if(f){
            run(k,pp);
        }
    }
}
int dp[5010][5010];
inline int dpf(int np,int lp,int li){
    if(ed[np].size()==0){
        if(lp==1)return 0;
        else return -2;
    }
    int y=ed[np][li].y;
    int &d=dp[y][lp];
    if(d!=-1)return d;
    d=-2;
    // last one
    if(li+1==ed[np].size()){
        int r=dpf(y,lp,0);
        if(r==-2)d=-2;
        else d=r+ed[np][li].l*(lp*(lp-1)/2);
    }else{
        int k;
        int r;
        //select 0.
        r=dpf(np,lp,li+1);
        if(r!=-2)d=max(d,r);
        //select all
        r=dpf(y,lp,0);
        if(r!=-2)d=max(d,r+ed[np][li].l*(lp*(lp-1)/2));
        //select some
        for(k=1;k<lp;k++){
            int r1=dpf(y,k,0);
            if(r1==-2)continue;
            int r2=dpf(np,lp-k,li+1);
            if(r2==-2)continue;
            d=max(d,r1+r2+ed[np][li].l*(k*(k-1)/2));
        }
    }
    //printf("np=%d lp=%d li=%d d=%d\n",np,lp,li,d);
    return d;
}
int main(){
    int n,k,i,j;
    scanf("%d%d",&n,&k);
    tc=1;
    for(i=0;i<n;i++){
        scanf("%s",tmp);
        int np=0;
        map<int,int>::iterator it;
        for(j=0;tmp[j];j++){
            it=trie[np].find(tmp[j]-'a');
            int to;
            if(it==trie[np].end()){
                trie[np][tmp[j]-'a']=tc;
                to=tc;
                tc++;
            }else{
                to=it->second;
            }
            np=to;
        }
        trie[np][26+cnt[np]]=-1;
        cnt[np]++;
    }
    nn=1;
    run(0,0);
    //printf("nn=%d\n",nn);
    //for(i=0;i<nn;i++)for(j=0;j<ed[i].size();j++)printf("%d -> %d (%d)\n",i,ed[i][j].y,ed[i][j].l);
    memset(dp,-1,sizeof(dp));
    printf("%d\n",dpf(0,k,0));
}


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<assert.h>
#include<stdarg.h>
#include<time.h>
#include<string>
#include<map>
#include<set>
#include<algorithm>
#include<vector>
using namespace std;
map<int,int> trie[1000100];
int cnt[1000100];
char tmp[1000];
int tc;
struct XD{
    int y,l;
    XD(int yy=-1,int ll=-1):y(yy),l(ll){}
};
vector<XD> ed[5000];
int nn;
int chn[5000];
int sibchn[5000];
inline void run(int np,int p){
    int i;
    map<int,int>::iterator it;
    for(it=trie[np].begin();it!=trie[np].end();it++){
        int cnt=0;
        int k=it->second,f=0;
        while(1){
            if(k<0){
                //cnt+=k;
                break;
            }
            if(trie[k].size()==0){
                cnt++;
                break;
            }
            if(trie[k].size()==1){
                cnt++;
                k=(trie[k].begin()->second);
            }else{
                cnt++;
                f=1;
                break;
            }
        }
        int pp=nn;
        nn++;
        ed[p].push_back(XD(pp,cnt));
        if(f){
            run(k,pp);
        }
    }
}
int dp[5010][5010];
inline int dpf(int np,int lp,int li){
    if(ed[np].size()==0){
        if(lp==1)return 0;
        else return -2;
    }
    int y=ed[np][li].y;
    int &d=dp[y][lp];
    if(d!=-1)return d;
    d=-2;
    // last one
    if(li+1==ed[np].size()){
        int r=dpf(y,lp,0);
        if(r==-2)d=-2;
        else d=r+ed[np][li].l*(lp*(lp-1)/2);
    }else{
        int k;
        int r;
        int tmt=sibchn[ed[np][li+1].y];
        //select 0.
        if(tmt>=lp){
            r=dpf(np,lp,li+1);
            if(r!=-2)d=max(d,r);
        }
        //select all
        if(chn[y]>=lp){
            r=dpf(y,lp,0);
            if(r!=-2)d=max(d,r+ed[np][li].l*(lp*(lp-1)/2));
        }
        //select some
        for(k=max(1,lp-tmt);k<lp&&k<=chn[y];k++){
            int r1=dpf(y,k,0);
            if(r1==-2)break;
            int r2=dpf(np,lp-k,li+1);
            if(r2==-2)continue;
            d=max(d,r1+r2+ed[np][li].l*(k*(k-1)/2));
        }
    }
    //printf("np=%d lp=%d li=%d d=%d\n",np,lp,li,d);
    return d;
}
inline void cc(int np){
    chn[np]=1;
    for(int i=0;i<ed[np].size();i++){
        int y=ed[np][i].y;
        cc(y);
        chn[np]+=chn[y];
    }
    int s=0;
    for(int i=ed[np].size()-1;i>=0;i--){
        int y=ed[np][i].y;
        s+=chn[y];
        sibchn[y]=s;
    }
}
int main(){
    int n,k,i,j;
    scanf("%d%d",&n,&k);
    tc=1;
    for(i=0;i<n;i++){
        scanf("%s",tmp);
        int np=0;
        map<int,int>::iterator it;
        for(j=0;tmp[j];j++){
            it=trie[np].find(tmp[j]-'a');
            int to;
            if(it==trie[np].end()){
                trie[np][tmp[j]-'a']=tc;
                to=tc;
                tc++;
            }else{
                to=it->second;
            }
            np=to;
        }
        trie[np][26+cnt[np]]=-1;
        cnt[np]++;
    }
    nn=1;
    run(0,0);
    cc(0);
    //printf("nn=%d\n",nn);
    //for(i=0;i<nn;i++)for(j=0;j<ed[i].size();j++)printf("%d -> %d (%d)\n",i,ed[i][j].y,ed[i][j].l);
    memset(dp,-1,sizeof(dp));
    printf("%d\n",dpf(0,k,0));
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <utility>
#include <numeric>
#include <algorithm>
#include <bitset>
#include <complex>

using namespace std;

typedef unsigned uint;
typedef long long Int;
typedef vector<int> vint;
typedef pair<int,int> pint;
#define mp make_pair

template<class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cout << *i << " "; cout << endl; }
template<class T> void chmin(T &t, T f) { if (t > f) t = f; }
template<class T> void chmax(T &t, T f) { if (t < f) t = f; }
int in() { int x; scanf("%d", &x); return x; }

const int INF = 1001001001;

int lcp(const string &a, const string &b) {
	int m = a.size(), n = b.size();
	int i;
	for (i = 0; i < m && i < n; ++i) if (a[i] != b[i]) break;
	return i;
}

int N, K;
string S[2010];
int D[2010];

int poolPos;
int pool[4010][2010];

int *solve(int a, int b, int d) {
	int *dp = pool[poolPos++];
	if (a == b) {
		dp[0] = 0;
		dp[1] = 0;
	} else {
		int i, im = -1;
		pint sho = mp(INF, INF);
		for (i = a; i < b; ++i) {
			pint tmp = mp(D[i], max(i - a, b - (i + 1)));
			if (sho > tmp) {
				sho = tmp;
				im = i;
			}
		}
		int *dpL = solve(a, im, D[im]);
		int *dpR = solve(im + 1, b, D[im]);
		int k, kL, kR;
		for (k = 0; k <= b - a + 1 && k <= K; ++k) {
			dp[k] = -INF;
		}
		for (kL = 0; kL <= im - a + 1 && kL <= K; ++kL) {
			for (kR = 0; kR <= b - (im + 1) + 1 && kL + kR <= K; ++kR) {
				chmax(dp[kL + kR], dpL[kL] + dpR[kR]);
			}
		}
		for (k = 0; k <= b - a + 1 && k <= K; ++k) {
			dp[k] += (D[im] - d) * (k * (k - 1) / 2);
		}
	}
// cout<<a<<" "<<b<<" "<<d<<" : ";pv(dp,dp+min(b-a+1,K)+1);
	return dp;
}

char buf[1010];

int main() {
	int i;

	for (; ~scanf("%d%d", &N, &K); ) {
		for (i = 0; i < N; ++i) {
			scanf("%s", buf);
			S[i] = buf;
		}
		sort(S, S + N);
		for (i = 0; i < N - 1; ++i) {
			D[i] = lcp(S[i], S[i + 1]);
		}
// cout<<"D : ";pv(D,D+N-1);
		poolPos = 0;
		int *res = solve(0, N - 1, 0);
		printf("%d\n", res[K]);
	}

	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <utility>
#include <numeric>
#include <algorithm>
#include <bitset>
#include <complex>

using namespace std;

typedef unsigned uint;
typedef long long Int;
typedef vector<int> vint;
typedef pair<int,int> pint;
#define mp make_pair

template<class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cout << *i << " "; cout << endl; }
template<class T> void chmin(T &t, T f) { if (t > f) t = f; }
template<class T> void chmax(T &t, T f) { if (t < f) t = f; }
int in() { int x; scanf("%d", &x); return x; }

const int INF = 1001001001;

int lcp(const string &a, const string &b) {
	int m = a.size(), n = b.size();
	int i;
	for (i = 0; i < m && i < n; ++i) if (a[i] != b[i]) break;
	return i;
}

int N, K;
string S[2010];
int D[2010];

int poolPos;
int pool[2010][2010];

int *solve(int a, int b, int d) {
	int *dp = pool[poolPos++];
	if (a == b) {
		dp[0] = 0;
		dp[1] = 0;
	} else {
		int i, im = -1;
		pint sho = mp(INF, INF);
		for (i = a; i < b; ++i) {
			pint tmp = mp(D[i], max(i - a, b - (i + 1)));
			if (sho > tmp) {
				sho = tmp;
				im = i;
			}
		}
		int *dpL = solve(a, im, D[im]);
		int *dpR = solve(im + 1, b, D[im]);
		int k, kL, kR;
		for (k = 0; k <= b - a + 1 && k <= K; ++k) {
			dp[k] = -INF;
		}
		for (kL = 0; kL <= im - a + 1 && kL <= K; ++kL) {
			for (kR = 0; kR <= b - (im + 1) + 1 && kL + kR <= K; ++kR) {
				chmax(dp[kL + kR], dpL[kL] + dpR[kR]);
			}
		}
		for (k = 0; k <= b - a + 1 && k <= K; ++k) {
			dp[k] += (D[im] - d) * (k * (k - 1) / 2);
		}
	}
// cout<<a<<" "<<b<<" "<<d<<" : ";pv(dp,dp+min(b-a+1,K)+1);
	return dp;
}

int main() {
	int i;
	char buf[510];

	for (; ~scanf("%d%d", &N, &K); ) {
		for (i = 0; i < N; ++i) {
			scanf("%s", buf);
			S[i] = buf;
		}
		sort(S, S + N);
		for (i = 0; i < N - 1; ++i) {
			D[i] = lcp(S[i], S[i + 1]);
		}
// cout<<"D : ";pv(D,D+N-1);
		poolPos = 0;
		int *res = solve(0, N - 1, 0);
		printf("%d\n", res[K]);
	}

	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 <vector>
#include <cstdlib>
#include <cstring>
#define INFI 999999999
using namespace std;
struct box
{
  char str[505];
}s[2005];
int lcp[2005];
int comp(const void *p,const void *q)
{
  return strcmp((*(struct box*)p).str,(*(struct box*)q).str);
}
vector<int> solve(int l,int r)
{
  int i,m,j;
  vector<int> re(r-l+2,-INFI);
  if(l == r)
    {
      re[0] = 0;
      re[1] = 0;
      return re;
    }
  for(m=l,i=l;i<r;i++)
    if(lcp[i] < lcp[m])
      m = i;
  vector<int> veca = solve(l,m);
  vector<int> vecb = solve(m+1,r);
  for(i=0;i<veca.size();i++)
    for(j=0;j<vecb.size();j++)
      {
	int tmp = re[i+j];
	if(veca[i]+vecb[j]+lcp[m]*i*j > tmp)
	  re[i+j] = veca[i]+vecb[j]+lcp[m]*i*j;
      }
  return re;
}
int main()
{
  //freopen("f.in","r",stdin);
  //freopen("f.out","w",stdout);
  int i,n,k,j;
  scanf("%d%d",&n,&k);
  for(i=0;i<n;i++)
    scanf("%s",s[i].str);
  qsort(s,n,sizeof(s[0]),comp);
  for(i=0;i<n-1;i++)
    {
      for(j=0;s[i].str[j]!='\0'&&s[i+1].str[j]!='\0';j++)
	if(s[i].str[j] != s[i+1].str[j])
	  break;
      lcp[i] = j;
    }
  vector<int> vec = solve(0,n-1);
  printf("%d\n",vec[k]);
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;

#define N 4200
#define M N*500

int n,m,xb,tot,len,sss,sum[M],head[M],deep[M],top[M],t[N*100][30],size[M],f[N][N];
char s[N];
struct edge{int v,len,nxt;}e[M];

void add(int x,int y,int z){e[++tot].v=y; e[tot].len=z; e[tot].nxt=head[x]; head[x]=tot;}

void dfs(int x,int fa,int tt){
	top[x]=tt; deep[x]=deep[fa]+1;
	int flag=0;
	for (int i=1;i<=26;i++) if (t[x][i]) flag++;
	if (flag==0){add(top[x],x,deep[x]-deep[top[x]]); return;}
	if (flag>1 || sum[x]!=0){flag=2; add(top[x],x,deep[x]-deep[top[x]]);}
	for (int i=1;i<=26;i++)
		if (t[x][i])
			if (flag==1) dfs(t[x][i],x,top[x]); else dfs(t[x][i],x,x);
}

int C(int x){return x*(x-1)/2;}

int dp(int u,int fa,int len){
	int ret=++sss;
	size[u]=sum[u];
	for (int i=size[u];i>=1;i--) f[ret][i]=len*C(i);
	for (int i=head[u],v;i;i=e[i].nxt)
		if ((v=e[i].v)!=fa && v!=u){
			int tmp=dp(v,u,e[i].len); size[u]+=size[v];
			for (int j=size[u];j>=1;j--)
				for (int k=1;k<=size[v] && k<=j;k++)
					f[ret][j]=max(f[ret][j],f[ret][j-k]+f[tmp][k]+len*(j-k)*k+len*C(k));
		}
	return ret;
}

int main(){
	scanf("%d%d",&n,&m); xb=1;
	for (int i=1;i<=n;i++){
		scanf("%s",s+1);
		int w=1; int len=strlen(s+1);
		for (int j=1;j<=len;j++)
			if (!t[w][s[j]-'a'+1]) w=t[w][s[j]-'a'+1]=++xb;
			else w=t[w][s[j]-'a'+1];
		sum[w]++;
	}
	dfs(1,0,1); dp(1,0,0);
	printf("%d\n",f[1][m]);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;

#define N 2200
#define M N*500

int n,m,xb,tot,len,sss,sum[M],head[M],deep[M],top[M],t[M][30],size[M],f[N*2][N];
char s[N];
struct edge{int v,len,nxt;}e[M*2];

void add(int x,int y,int z){e[++tot].v=y; e[tot].len=z; e[tot].nxt=head[x]; head[x]=tot;}

void dfs(int x,int fa,int tt){
	top[x]=tt; deep[x]=deep[fa]+1;
	int flag=0;
	for (int i=1;i<=26;i++) if (t[x][i]) flag++;
	if (flag==0){add(top[x],x,deep[x]-deep[top[x]]); return;}
	if (flag>1 || sum[x]!=0){flag=2; add(top[x],x,deep[x]-deep[top[x]]);}
	for (int i=1;i<=26;i++)
		if (t[x][i])
			if (flag==1) dfs(t[x][i],x,top[x]); else dfs(t[x][i],x,x);
}

int C(int x){return x*(x-1)/2;}

int dp(int u,int fa,int len){
	int ret=++sss;
	size[u]=sum[u];
	for (int i=size[u];i>=1;i--) f[ret][i]=len*C(i);
	for (int i=head[u],v;i;i=e[i].nxt)
		if ((v=e[i].v)!=fa && v!=u){
			int tmp=dp(v,u,e[i].len); size[u]+=size[v];
			for (int j=size[u];j>=1;j--)
				for (int k=1;k<=size[v] && k<=j;k++)
					f[ret][j]=max(f[ret][j],f[ret][j-k]+f[tmp][k]+len*(j-k)*k+len*C(k));
		}
	return ret;
}

int main(){
	scanf("%d%d",&n,&m); xb=1;
	for (int i=1;i<=n;i++){
		scanf("%s",s+1);
		int w=1; int len=strlen(s+1);
		for (int j=1;j<=len;j++)
			if (!t[w][s[j]-'a'+1]) w=t[w][s[j]-'a'+1]=++xb;
			else w=t[w][s[j]-'a'+1];
		sum[w]++;
	}
	dfs(1,0,1); dp(1,0,0);
	printf("%d\n",f[1][m]);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;

#define N 2200
#define M N*500

int n,m,xb,tot,len,sss,sum[M],head[M],deep[M],top[M],t[M][30],size[M],f[N][N];
char s[N];
struct edge{int v,len,nxt;}e[M];

void add(int x,int y,int z){e[++tot].v=y; e[tot].len=z; e[tot].nxt=head[x]; head[x]=tot;}

void dfs(int x,int fa,int tt){
	top[x]=tt; deep[x]=deep[fa]+1;
	int flag=0;
	for (int i=1;i<=26;i++) if (t[x][i]) flag++;
	if (flag==0){add(top[x],x,deep[x]-deep[top[x]]); return;}
	if (flag>1 || sum[x]!=0){flag=2; add(top[x],x,deep[x]-deep[top[x]]);}
	for (int i=1;i<=26;i++)
		if (t[x][i])
			if (flag==1) dfs(t[x][i],x,top[x]); else dfs(t[x][i],x,x);
}

int C(int x){return x*(x-1)/2;}

int dp(int u,int fa,int len){
	int ret=++sss;
	size[u]=sum[u];
	for (int i=size[u];i>=1;i--) f[ret][i]=len*C(i);
	for (int i=head[u],v;i;i=e[i].nxt)
		if ((v=e[i].v)!=fa && v!=u){
			int tmp=dp(v,u,e[i].len); size[u]+=size[v];
			for (int j=size[u];j>=1;j--)
				for (int k=1;k<=size[v] && k<=j;k++)
					f[ret][j]=max(f[ret][j],f[ret][j-k]+f[tmp][k]+len*(j-k)*k+len*C(k));
		}
	return ret;
}

int main(){
	scanf("%d%d",&n,&m); xb=1;
	for (int i=1;i<=n;i++){
		scanf("%s",s+1);
		int w=1; int len=strlen(s+1);
		for (int j=1;j<=len;j++)
			if (!t[w][s[j]-'a'+1]) w=t[w][s[j]-'a'+1]=++xb;
			else w=t[w][s[j]-'a'+1];
		sum[w]++;
	}
	dfs(1,0,1); dp(1,0,0);
	printf("%d\n",f[1][m]);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;

#define N 2200
#define M N*800

int n,m,xb,tot,len,sss,sum[M],head[M],deep[M],top[M],t[M][30],size[M],f[N][N];
char s[N];
struct edge{int v,len,nxt;}e[M*2];

void add(int x,int y,int z){e[++tot].v=y; e[tot].len=z; e[tot].nxt=head[x]; head[x]=tot;}

void dfs(int x,int fa,int tt){
	top[x]=tt; deep[x]=deep[fa]+1;
	int flag=0;
	for (int i=1;i<=26;i++) if (t[x][i]) flag++;
	if (flag==0){add(top[x],x,deep[x]-deep[top[x]]); return;}
	if (flag>1 || sum[x]!=0){flag=2; add(top[x],x,deep[x]-deep[top[x]]);}
	for (int i=1;i<=26;i++)
		if (t[x][i])
			if (flag==1) dfs(t[x][i],x,top[x]); else dfs(t[x][i],x,x);
}

int C(int x){return x*(x-1)/2;}

int dp(int u,int fa,int len){
	int ret=++sss;
	size[u]=sum[u];
	for (int i=size[u];i>=1;i--) f[ret][i]=len*C(i);
	for (int i=head[u],v;i;i=e[i].nxt)
		if ((v=e[i].v)!=fa && v!=u){
			int tmp=dp(v,u,e[i].len); size[u]+=size[v];
			for (int j=size[u];j>=1;j--)
				for (int k=1;k<=size[v] && k<=j;k++)
					f[ret][j]=max(f[ret][j],f[ret][j-k]+f[tmp][k]+len*(j-k)*k+len*C(k));
		}
	return ret;
}

int main(){
	scanf("%d%d",&n,&m); xb=1;
	for (int i=1;i<=n;i++){
		scanf("%s",s+1);
		int w=1; int len=strlen(s+1);
		for (int j=1;j<=len;j++)
			if (!t[w][s[j]-'a'+1]) w=t[w][s[j]-'a'+1]=++xb;
			else w=t[w][s[j]-'a'+1];
		sum[w]++;
	}
	dfs(1,0,1); dp(1,0,0);
	printf("%d\n",f[1][m]);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;

#define N 2200
#define M N*500

int n,m,xb,tot,len,sss,sum[M],head[M],deep[M],top[M],t[M][30],size[M],f[N][N];
char s[N];
struct edge{int v,len,nxt;}e[M*2];

void add(int x,int y,int z){e[++tot].v=y; e[tot].len=z; e[tot].nxt=head[x]; head[x]=tot;}

void dfs(int x,int fa,int tt){
	top[x]=tt; deep[x]=deep[fa]+1;
	int flag=0;
	for (int i=1;i<=26;i++) if (t[x][i]) flag++;
	if (flag==0){add(top[x],x,deep[x]-deep[top[x]]); return;}
	if (flag>1 || sum[x]!=0){flag=2; add(top[x],x,deep[x]-deep[top[x]]);}
	for (int i=1;i<=26;i++)
		if (t[x][i])
			if (flag==1) dfs(t[x][i],x,top[x]); else dfs(t[x][i],x,x);
}

int C(int x){return x*(x-1)/2;}

int dp(int u,int fa,int len){
	int ret=++sss;
	size[u]=sum[u];
	for (int i=size[u];i>=1;i--) f[ret][i]=len*C(i);
	for (int i=head[u],v;i;i=e[i].nxt)
		if ((v=e[i].v)!=fa && v!=u){
			int tmp=dp(v,u,e[i].len); size[u]+=size[v];
			for (int j=size[u];j>=1;j--)
				for (int k=1;k<=size[v] && k<=j;k++)
					f[ret][j]=max(f[ret][j],f[ret][j-k]+f[tmp][k]+len*(j-k)*k+len*C(k));
		}
	return ret;
}

int main(){
	scanf("%d%d",&n,&m); xb=1;
	for (int i=1;i<=n;i++){
		scanf("%s",s+1);
		int w=1; int len=strlen(s+1);
		for (int j=1;j<=len;j++)
			if (!t[w][s[j]-'a'+1]) w=t[w][s[j]-'a'+1]=++xb;
			else w=t[w][s[j]-'a'+1];
		sum[w]++;
	}
	dfs(1,0,1); dp(1,0,0);
	printf("%d\n",f[1][m]);
	return 0;
}


#include<iostream>
#include<string>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 2010;
int sum = 0, w[N], f[N * 2][N];
string s[N];
bool compare(string a, string b)
{
    return(a < b);
}

int min(int a, int b)
{
    return(a < b ? a : b);
}

int work(int l, int r)
{
    int d = ++sum;
    if (l < r)
    {
        int i, j, left, right, b = l;
        for (i = l + 1; i < r; i++)
        if (w[i] < w[b])
        b = i;
        left = work(l, b);
        right = work(b + 1, r);
        for (i = 0; i <= b + 1 - l; i++)
        for (j = 0; j <= r - b; j++)
        if (f[d][i + j] < f[left][i] + f[right][j] + w[b] * i * j)
        f[d][i + j] = f[left][i] + f[right][j] + w[b] * i * j;
    }
    return(d);
}

int main()
{
    memset(f, 0, sizeof(f));
    int n, k, i, j, temp;
    cin >> n >> k;
    for (i = 1; i <= n; i++)
    cin >> s[i];
    sort(s + 1, s + n + 1, compare);
    for (i = 1; i < n; i++)
    {
        temp = min(s[i].size(), s[i + 1].size());
        w[i] = temp;
        for (j = 0; j < temp; j++)
        if (s[i][j] != s[i + 1][j])
        {
            w[i] = j;
            break;
        }
    }
    work(1, n);
    cout << f[1][k];
    return(0);
}


#include <algorithm>
#include <string>
#include <cstdio>
using namespace std;
#define rep(i,n) for (int i=0;i<n;i++)
int dp[2010][2010],h[2010],n,m,cnt;
char s[2010];string a[2010];
int calc(int l,int r) {
	if (l==r) return n;
	int md=min_element(h+l,h+r)-h,x=calc(l,md),y=calc(md+1,r),t=cnt++;
	rep(i,md-l+2) rep(j,r-md+1) dp[t][i+j]=max(dp[t][i+j],h[md]*i*j+dp[x][i]+dp[y][j]);
	return t;
}
int main() {
	scanf("%d%d ",&n,&m);
	rep(i,n) {gets(s);a[i]=s;}
	sort(a,a+n);
	rep(i,n-1) {h[i]=min(a[i].size(),a[i+1].size());rep(j,h[i]) if (a[i][j]!=a[i+1][j]) h[i]=j;}
	printf("%d\n",dp[calc(0,n-1)][m]);
}


#include <algorithm>
#include <string>
#include <cstdio>
using namespace std;
#define rep(i,n) for (int i=0;i<n;i++)
int dp[2010][2010],h[2010],n,m,cnt;
char s[2010];string a[2010];
int calc(int l,int r) {
	if (l==r) return n;
	int md=min_element(h+l,h+r)-h,x=calc(l,md),y=calc(md+1,r),t=cnt++;
	rep(i,md-l+2) rep(j,r-md+1) dp[t][i+j]=max(dp[t][i+j],h[md]*i*j+dp[x][i]+dp[y][j]);
	return t;
}
int main() {
	scanf("%d%d ",&n,&m);
	rep(i,n) {gets(s);a[i]=s;}
	sort(a,a+n);
	rep(i,n-1) rep(j,min(a[i].size(),a[i+1].size())+1)
		if (a[i][j]!=a[i+1][j]) {h[i]=j;break;}
	printf("%d\n",dp[calc(0,n-1)][m]);
}


#include <algorithm>
#include <string>
#include <cstdio>
using namespace std;
#define rep(i,n) for (int i=0;i<n;i++)
int dp[2010][2010],h[2010],n,m,cnt;
char s[2010];string a[2010];
int calc(int l,int r) {
	if (l==r) return n;
	int md=min_element(h+l,h+r)-h,x=calc(l,md),y=calc(md+1,r),t=cnt++;
	rep(i,md-l+2) rep(j,r-md+1) dp[t][i+j]=max(dp[t][i+j],h[md]*i*j+dp[x][i]+dp[y][j]);
	return t;
}
int main() {
	scanf("%d%d ",&n,&m);
	rep(i,n) {gets(s);a[i]=s;}
	sort(a,a+n);
	rep(i,n-1) rep(j,min(a[i].size(),a[i+1].size()))
		if (a[i][j]!=a[i+1][j]) {h[i]=j;break;}
	printf("%d\n",dp[calc(0,n-1)][m]);
}


#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <ctime>
#include <cmath>
#include <complex>
#include <numeric>
#include <vector>
#include <string>
#include <queue>
#include <map>
#include <set>

using namespace std;

#define all(a) (a).begin(), (a).end()
#define sz(a) int((a).size())
#define FOR(i, a, b) for(int i(a), _b(b); i < _b; ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORD(i, a, b) for(int i(a), _b(b); i >= _b; --i)
#define CL(a, v) memset(a, v, sizeof a)
#define pb push_back
#define X first
#define Y second

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;

const int INF = 1000000000;
const ll INF_LL = 1000000000000000000LL;

void smax(int &a, int b) { if(a < b) a = b; }

const int h = 2002;

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

vi f(int l, int r) {
  if (l + 1 == r) return vi(2, 0);
  vi x(r - l + 1, 0);
  int m = l;
  FOR(i, l, r-1) if(lcp[i] < lcp[m]) m = i;
  vi a = f(l, m+1);
  vi b = f(m+1, r);
  REP(i, sz(a)) REP(j, sz(b)) smax(x[i+j], a[i] + b[j] + lcp[m] * i * j);
  return x;
}

int main() {
#ifdef LocalHost
  freopen("input.txt", "r", stdin);
  //freopen("output.txt", "w", stdout);
#endif

  scanf("%d%d", &n, &k);
  char c[555];
  REP(i, n) {
    scanf("%s", c);
    s[i] = c;
  }
  sort(s, s+n);
  REP(i, n-1) {
    int j = 0;
    while (j<sz(s[i]) && j<sz(s[i+1]) && s[i][j]==s[i+1][j]) ++j;
    lcp[i] = j;
  }
  vi ans = f(0, n);
  printf("%d\n", ans[k]);

#ifdef LocalHost
  cout << endl << endl << "TIME: " << clock() << endl;
#endif
  return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int Max_N(2050);
const int Max_L(505);

int N, K, SA[Max_N], Height[Max_N], L[Max_N];
char S[Max_N][Max_L];

void init()
{
	scanf("%d%d", &N, &K);
	for (int i = 1;i <= N;++i)
		scanf("%s", S[i] + 1), L[i] = strlen(S[i] + 1);
}

inline bool comp(const int &a, const int &b)
{
	for (int i = 1;i <= min(L[a], L[b]);++i)
		if (S[a][i] != S[b][i])
			return S[a][i] < S[b][i];
	return L[a] < L[b];
}

struct edge
{
	int u, v, w;
	void give(const int &_u, const int &_v, const int &_w)
	{
		u = _u, v = _v, w = _w;
	}
};
edge E[Max_N];

inline bool operator<(const edge &a, const edge &b)
{
	return a.w > b.w;
}

void getSA()
{
	for (int i = 1;i <= N;++i)
		SA[i] = i;
	sort(SA + 1, SA + 1 + N, comp);
	for (int i = 2;i <= N;++i)
	{
		for (int j = 1;j <= min(L[SA[i - 1]], L[SA[i]]);++j)
			if (S[SA[i - 1]][j] == S[SA[i]][j])
				++Height[i];
			else
				break;
		E[i - 1].give(SA[i - 1], SA[i], Height[i]);
	}
}

int Father[Max_N], Size[Max_N], F[Max_N][Max_N], G[Max_N];

int Get_Father(const int &x)
{
	return Father[x] == x ? x : Father[x] = Get_Father(Father[x]);
}

inline void update(int &a, const int &b)
{
	a = max(a, b);
}

void work()
{
	for (int i = 1;i <= N;++i)
		Father[i] = i, Size[i] = 1, memset(F[i], -0X3F, sizeof(F[i])), F[i][0] = F[i][1] = 0;
	sort(E + 1, E + N);
	for (int i = 1, u, v, w;i <= N - 1;++i)
	{
		w = E[i].w, u = Get_Father(E[i].u), v = Get_Father(E[i].v);
		memset(G, -0X3F, sizeof(G)), G[0] = 0;
		for (int a = 0;a <= Size[u];++a)
			for (int b = 0;b <= Size[v];++b)
				update(G[a + b], F[u][a] + F[v][b] + a * b * w);
		for (int x = 0;x <= N;++x)
			F[u][x] = G[x];
		Size[u] += Size[v], Father[v] = u;
		if (i == N - 1)
			printf("%d", F[u][K]);
	}
	if (N == 1)
		printf("%d", 0);
}

int main()
{
	init();
	getSA();
	work();
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#define nn 202
#define len 502
#define ctu continue
using namespace std;

struct trie{
	int ch[27];
	int v;
}b[nn*len];
int n,k,ns,f[nn*len][nn],g[nn*len][nn],dep[nn*len];
char a[nn][len];

void insert(int i)
{
	int l=strlen(a[i]),d;
	int p=0;
	for(int j=0;j<l;++j)
	{
		d=a[i][j]-'a'+1;
		if(b[p].ch[d]==0) b[p].ch[d]=++ns;
		p=b[p].ch[d];
	}
	b[p].v++;
}

void init()
{
	ns=0;
	scanf("%d%d\n",&n,&k);
	for(int i=1;i<=n;++i)
	{
		scanf("%s\n",a[i]);
		insert(i);
	}
}

void dfs(int u)
{
	g[u][0]=1;
	int v;
	for(int i=1;i<=26;++i)
	{
		if(b[u].ch[i]==0) ctu;
		v=b[u].ch[i];
		dep[v]=dep[u]+1;
		dfs(v);
		for(int j=n;j>=1;--j)
		{
			for(int c=1;c<=j;++c)
			{
				if(g[v][c]&&g[u][j-c])
				{
					g[u][j]=1;
					f[u][j]=max(f[u][j],f[u][j-c]+f[v][c]+(j-c)*c*dep[u]);
				}
			}
		}
	}
	for(int j=n;j>=0;--j)
		if(g[u][j]&&b[u].v)
		{
			f[u][j+b[u].v]=max(f[u][j+b[u].v],f[u][j]+dep[u]*b[u].v*j+dep[u]*(b[u].v-1)*b[u].v/2);
			g[u][j+b[u].v]=1;
		}
	for(int j=1;j<=b[u].v;++j) g[u][j]=1;
}

void work()
{
	dep[0]=0;
	dfs(0);
	printf("%d",f[0][k]);
}

int main()
{

	init();
	work();

	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#define nn 2002
#define len 502
#define ctu continue
using namespace std;

struct trie{
	int ch[27];
	int v;
}b[nn];
int n,k,ns,f[nn][nn],g[nn][nn],dep[nn];
char a[nn][len];

void insert(int i)
{
	int l=strlen(a[i]),d;
	int p=0;
	for(int j=0;j<l;++j)
	{
		d=a[i][j]-'a'+1;
		if(b[p].ch[d]==0) b[p].ch[d]=++ns;
		p=b[p].ch[d];
	}
	b[p].v++;
}

void init()
{
	ns=0;
	scanf("%d%d\n",&n,&k);
	for(int i=1;i<=n;++i)
	{
		scanf("%s\n",a[i]);
		insert(i);
	}
}

void dfs(int u)
{
	g[u][0]=1;
	int v;
	for(int i=1;i<=26;++i)
	{
		if(b[u].ch[i]==0) ctu;
		v=b[u].ch[i];
		dep[v]=dep[u]+1;
		dfs(v);
		for(int j=n;j>=1;--j)
		{
			for(int c=1;c<=j;++c)
			{
				if(g[v][c]&&g[u][j-c])
				{
					g[u][j]=1;
					f[u][j]=max(f[u][j],f[u][j-c]+f[v][c]+(j-c)*c*dep[u]);
				}
			}
		}
	}
	for(int j=n;j>=0;--j)
		if(g[u][j]&&b[u].v)
		{
			f[u][j+b[u].v]=max(f[u][j+b[u].v],f[u][j]+dep[u]*b[u].v*j+dep[u]*(b[u].v-1)*b[u].v/2);
			g[u][j+b[u].v]=1;
		}
	for(int j=1;j<=b[u].v;++j) g[u][j]=1;
}

void work()
{
	dep[0]=0;
	dfs(0);
	printf("%d",f[0][k]);
}

int main()
{

	init();
	work();

	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#define nn 2002
#define len 502
#define ctu continue
using namespace std;

struct trie{
	int ch[27];
	int v;
}b[nn*len];
int n,k,ns,f[nn][nn],g[nn][nn],dep[nn];
char a[nn][len];

void insert(int i)
{
	int l=strlen(a[i]),d;
	int p=0;
	for(int j=0;j<l;++j)
	{
		d=a[i][j]-'a'+1;
		if(b[p].ch[d]==0) b[p].ch[d]=++ns;
		p=b[p].ch[d];
	}
	b[p].v++;
}

void init()
{
	ns=0;
	scanf("%d%d\n",&n,&k);
	for(int i=1;i<=n;++i)
	{
		scanf("%s\n",a[i]);
		insert(i);
	}
}

void dfs(int u)
{
	g[u][0]=1;
	int v;
	for(int i=1;i<=26;++i)
	{
		if(b[u].ch[i]==0) ctu;
		v=b[u].ch[i];
		dep[v]=dep[u]+1;
		dfs(v);
		for(int j=n;j>=1;--j)
		{
			for(int c=1;c<=j;++c)
			{
				if(g[v][c]&&g[u][j-c])
				{
					g[u][j]=1;
					f[u][j]=max(f[u][j],f[u][j-c]+f[v][c]+(j-c)*c*dep[u]);
				}
			}
		}
	}
	for(int j=n;j>=0;--j)
		if(g[u][j])
		for(int c=1;c<=b[u].v;++c)
		{
			f[u][j+c]=max(f[u][j+c],f[u][j]+dep[u]*c*j+dep[u]*(c-1)*c/2);
			g[u][j+c]=1;
		}
	for(int j=1;j<=b[u].v;++j) g[u][j]=1;
}

void work()
{
	dep[0]=0;
	dfs(0);
	printf("%d",f[0][k]);
}

int main()
{

	init();
	work();

	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#define nn 2002
#define len 502
#define ctu continue
using namespace std;

struct trie{
	int ch[27];
	int v;
}b[nn];
int n,k,ns,f[nn][nn],g[nn][nn],dep[nn];
char a[nn][len];

void insert(int i)
{
	int l=strlen(a[i]),d;
	int p=0;
	for(int j=0;j<l;++j)
	{
		d=a[i][j]-'a'+1;
		if(b[p].ch[d]==0) b[p].ch[d]=++ns;
		p=b[p].ch[d];
	}
	b[p].v++;
}

void init()
{
	ns=0;
	scanf("%d%d\n",&n,&k);
	for(int i=1;i<=n;++i)
	{
		scanf("%s\n",a[i]);
		insert(i);
	}
}

void dfs(int u)
{
	g[u][0]=1;
	int v;
	for(int i=1;i<=26;++i)
	{
		if(b[u].ch[i]==0) ctu;
		v=b[u].ch[i];
		dep[v]=dep[u]+1;
		dfs(v);
		for(int j=n;j>=1;--j)
		{
			for(int c=1;c<=j;++c)
			{
				if(g[v][c]&&g[u][j-c])
				{
					g[u][j]=1;
					f[u][j]=max(f[u][j],f[u][j-c]+f[v][c]+(j-c)*c*dep[u]);
				}
			}
		}
	}
	for(int j=n;j>=0;--j) if(g[u][j]) f[u][j+b[u].v]+=dep[u]*b[u].v*j,g[u][j+b[u].v]=1;
	for(int j=1;j<=b[u].v;++j) g[u][j]=1;
}

void work()
{
	dep[0]=0;
	dfs(0);
	printf("%d",f[0][k]);
}

int main()
{

	init();
	work();

	return 0;
}


#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define oo (int)1e+9
#define nn 2002
using namespace std;

int n,k,h[nn];
string a[nn];

int lcp(string x,string y)
{
	int s=0,l=x.size(),r=y.size();
	for(int i=0;i<l&&i<r;++i) if(x[i]==y[i]) s++;else break;
	return s;
}

void init()
{
	scanf("%d%d\n",&n,&k);
	for(int i=1;i<=n;++i) cin>>a[i];
	sort(a+1,a+n+1);
	for(int i=1;i<n;++i) h[i]=lcp(a[i],a[i+1]);
}

vector<int> merge(int l,int r)
{
	vector<int> res; res.clear();
	res.resize(r-l+2);
	if(l>=r) return res;
	int hs=oo,ni=0;
	for(int i=l;i<r;++i) if(hs>h[i]) hs=h[i],ni=i;
	vector<int> lef=merge(l,ni),rig=merge(ni+1,r);
	for(int i=0;i<(int)lef.size();++i)
		for(int j=0;j<(int)rig.size();++j)
			res[i+j]=max(res[i+j],lef[i]+rig[j]+i*j*hs);
	return res;
}

void work()
{
	vector<int> ans=merge(1,n);
	printf("%d",ans[k]);
}

int main()
{

	init();
	work();

	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#define nn 2002
#define len 502
#define ctu continue
using namespace std;

struct trie{
	int ch[27];
	int v;
}b[nn];
int n,k,ns,f[nn][nn],g[nn][nn],dep[nn];
char a[nn][len];

void insert(int i)
{
	int l=strlen(a[i]),d;
	int p=0;
	for(int j=0;j<l;++j)
	{
		d=a[i][j]-'a'+1;
		if(b[p].ch[d]==0) b[p].ch[d]=++ns;
		p=b[p].ch[d];
	}
	b[p].v++;
}

void init()
{
	ns=0;
	scanf("%d%d\n",&n,&k);
	for(int i=1;i<=n;++i)
	{
		scanf("%s\n",a[i]);
		insert(i);
	}
}

void dfs(int u)
{
	g[u][0]=1;
	int v;
	for(int i=1;i<=26;++i)
	{
		if(b[u].ch[i]==0) ctu;
		v=b[u].ch[i];
		dep[v]=dep[u]+1;
		dfs(v);
		for(int j=n;j>=1;--j)
		{
			for(int c=1;c<=j;++c)
			{
				if(g[v][c]&&g[u][j-c])
				{
					g[u][j]=1;
					f[u][j]=max(f[u][j],f[u][j-c]+f[v][c]+(j-c)*c*dep[u]);
				}
			}
		}
	}
	for(int j=0;j<=n;++j) if(g[u][j]) f[u][j+b[u].v]+=dep[u]*b[u].v*j;
	for(int j=1;j<=b[u].v;++j) g[u][j]=1;
}

void work()
{
	dep[0]=0;
	dfs(0);
	printf("%d",f[0][k]);
}

int main()
{

	init();
	work();

	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][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);
	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[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);
	__builtin_memset(f[id%3],0,sizeof f[id%3]);
	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%3][i+j]=std::max(f[id%3][i+j],f[lid%3][i]+f[rid%3][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);
	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 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=k-r+mid-1;i<=k&&i<=(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=2000,K=2001;
std::string s[N];
int n,k,lcp[N];
int f[N][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 n,k,lcp[N];
int f[N][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);
		}
	}
	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=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]++;
	}
	printf("%d\n",dp(0,n-1,k));
	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[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%3][i+j]=std::max(f[id%3][i+j],f[lid%3][i]+f[rid%3][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;
}