#include<bits/stdc++.h>
using namespace std;

#define ff first
#define ss second
#define m_p make_pair
#define pb push_back
#define ppb pop_back
#define pf push_front
#define ppf pop_front
#define ll long long
#define l_b lower_bound
#define u_b upper_bound

int n;
string s;

const int maxN = 500010;// max length of total string,
int len;//length of the string of the suffix array
const static int maxNO = maxN; //multiple maximum number of string cancated in the suffixarray string
int slen[maxNO], start[maxNO]; //update these while taking input and concating
int nearest[maxN], belong[maxN];
void mapstring(int n, int term_char) //term_char = integer value of terminating character
{	//n = number of concated string
	n++;
	//cout << "enter mapstring\n";
	for (int i = len - 1, tt = len - 1; i >= 0; i--)
	{
		if (s[i] == term_char) tt = i, n--;
		nearest[i] = tt;
		belong[i] = n;
	}
	//cout << "end mapstring\n";
}
int ra[maxN], tra[maxN], sa[maxN], tmpsa[maxN], cnt[maxN];
void countSort(int k)
{
	int maxr = max(300, len);
	memset(cnt, 0, sizeof(cnt[0]) * (maxr + 5));

	for (int i = 0; i < len; i++) cnt[sa[i] + k < len ? ra[sa[i] + k] : 0]++;
	for (int i = 0, t, sum = 0; i < maxr; i++) t = cnt[i], cnt[i] = sum, sum += t;
	for (int i = 0; i < len; i++) tmpsa[cnt[sa[i] + k < len ? ra[sa[i] + k] : 0]++] = sa[i];
	for (int i = 0; i < len; i++) sa[i] = tmpsa[i];
}
void buildsa()
{
	for (int i = 0; i < len; i++) ra[i] = s[i], sa[i] = i;

	for (int k = 1; k < len; k <<= 1)
	{
		countSort(k);
		countSort(0);

		int r = 0;
		tra[sa[0]] = 0;
		for (int i = 1; i < len; i++)
		{
			int t1 = (sa[i] + k < len ? ra[sa[i] + k] : 0);
			int t2 = (sa[i - 1] + k < len ? ra[sa[i - 1] + k] : 0);
			tra[sa[i]] = (ra[sa[i]] == ra[sa[i - 1]] && t1 == t2 ) ? r : ++r;
		}
		for (int i = 0; i < len; i++) ra[i] = tra[i];
		if (ra[sa[len - 1]] == len - 1) break;
	}

	/*for (int i = 0; i < len; i++)
	{
		cout << i << " <suffixarray> " << sa[i] << " ";
		for (int j = sa[i]; j < len; j++) cout << s[j];
		cout << endl;
	}*/
}

int phi[maxN], LCP[maxN];
void computeLCP()
{
	phi[sa[0]] = -1;
	for (int i = 1; i < len; i++) phi[sa[i]] = sa[i - 1];
	int L = 0;
	for (int i = 0; i < len; i++)
	{
		if (phi[i] == -1)
		{
			LCP[ra[i]] = 0;
			continue;
		}
		while (L < len && s[i + L] == s[phi[i] + L]) L++;
		int TL = min(nearest[i] - i, L);
		LCP[ra[i]] = TL;
		L = max(L - 1, 0);
	}
	//for (int i = 0; i < len; i++)
	//cout << i << "  sa: " << sa[i] << " <LCP> " << LCP[i] << " bel:" << belong[sa[i]] << endl; //debug
}

int spt[maxN][25], spt2[maxN][25]; //default sparseTable array ( 25 > log2(10^7) )
int log2a[maxN];
void sptBuild(int spt[][25], int ara[], int n = maxN, bool mn = 1) // 0 indexing (0 to n-1)
{
	for (int j = 0; (1 << j) < n; j++)
	{
		for (int i = 0; i < n; i++)
		{
			if (j == 0) spt[i][j] = ara[i];
			//else if ((1<<j)+i >= n ) break;
			else if (mn)spt[i][j] = min(spt[i][j - 1], (i + (1 << j - 1) < n) ? spt[i + (1 << j - 1)][j - 1]  : 0 ) ;
			else spt[i][j] = max(spt[i][j - 1], (i + (1 << j - 1) < n) ? spt[i + (1 << j - 1)][j - 1]  : 0 ) ;

		}
	}

}
int sptQry(int spt[][25], int l, int r, bool mn = 1)
{
	if (l > r)
	{
		cout << "waht the fuck dude\n";
		exit(0);
	}
	int dis = log2a[r - l + 1]; //RMQ (minimum) using overlapping range
	if (mn) return min(spt[l][dis], spt[r - (1 << dis) + 1][dis]);
	return max(spt[l][dis], spt[r - (1 << dis) + 1][dis]);
}

int occ[maxNO], mxv[maxN], ans[maxN];
ll fans[maxN];

void qry(int n)//n: atleast n string has the LCS , prequisite:  computeLCP
{
	//cout << "came here" << endl;
	int distinct_cnt = 0, st = 0;
	for (int i = 0; i < len; i++)
	{
		distinct_cnt += !occ[belong[sa[i]]];
		occ[belong[sa[i]]]++;
		while (distinct_cnt == n)
		{
			mxv[st] = sptQry(spt, st + 1, i);
			occ[belong[sa[st]]]--;
			distinct_cnt -= !occ[belong[sa[st]]];
			st++;
		}
	}
	//cout << "came here 2" << endl;
	memset(occ, 0, sizeof(occ));
	sptBuild(spt2, mxv, len, 0);
	distinct_cnt = 0, st = 0;
	int lastout = -1;

	for (int i = 0; i < len; i++)
	{
		distinct_cnt += !occ[belong[sa[i]]];
		occ[belong[sa[i]]]++;
		ans[i] = sptQry(spt2, st, i, 0);
		while (distinct_cnt == n)
		{
			occ[belong[sa[st]]]--;
			distinct_cnt -= !occ[belong[sa[st]]];
			lastout = st;
			st++;
		}
		if (lastout != -1) ans[i] = max(ans[i], sptQry(spt, st , i));
	}
	//cout << "came here 3" << endl;
	for (int i = 0; i < len; i++) fans[belong[sa[i]]] += ans[i];

}
char ss[maxN];
int main()
{
	//freopen("inp.txt", "r", stdin);
	//freopen("mout.txt", "w", stdout);
	int n, k;
	scanf("%d %d", &n, &k);
	for (int i = 1; i <= n; i++)
	{
		scanf("%s", ss);
		slen[i] = strlen(ss);
		start[i] = len;
		s += ss;
		s += "&";
		len += slen[i] + 1;
		if (k == 1) cout << (slen[i] * ((ll)(slen[i] + 1)) / 2) << " ";
	}
	if (k == 1)
	{
		cout << endl;
		exit(0);
	}
	//cout << "pass 1" << endl;
	for (int i = 1; i <= len; i++) log2a[i] = log2(i);
	//cout << "calc the logs\n";
	mapstring(n, '&');
	//cout << "pass 2\n";
	buildsa();
	//cout<<"suffix array builded .. now time for lcp\n";
	computeLCP();
	//cout << "pass 3" << endl;
	sptBuild(spt, LCP, len);
	//cout << "pass 4" << endl;
	qry(k);

	for (int i = 1; i <= n; i++) printf("%I64d ", fans[i]);
	cout << endl;
}


#include<bits/stdc++.h>
using namespace std;

#define ff first
#define ss second
#define m_p make_pair
#define pb push_back
#define ppb pop_back
#define pf push_front
#define ppf pop_front
#define ll long long
#define l_b lower_bound
#define u_b upper_bound

int n;
string s;

const int maxN = 500010;// max length of total string,
int len;//length of the string of the suffix array
const static int maxNO = maxN; //multiple maximum number of string cancated in the suffixarray string
int slen[maxNO], start[maxNO]; //update these while taking input and concating
int nearest[maxN], belong[maxN];
void mapstring(int n, int term_char) //term_char = integer value of terminating character
{	//n = number of concated string
	n++;
	for (int i = len - 1, tt = len - 1; i >= 0; i--)
	{
		if (s[i] == term_char) tt = i, n--;
		nearest[i] = tt;
		belong[i] = n;
	}
}
int ra[maxN], tra[maxN], sa[maxN], tmpsa[maxN], cnt[maxN];
void countSort(int k)
{
	int maxr = max(300, len);
	memset(cnt, 0, sizeof(cnt[0]) * (maxr + 5));

	for (int i = 0; i < len; i++) cnt[sa[i] + k < len ? ra[sa[i] + k] : 0]++;
	for (int i = 0, t, sum = 0; i < maxr; i++) t = cnt[i], cnt[i] = sum, sum += t;
	for (int i = 0; i < len; i++) tmpsa[cnt[sa[i] + k < len ? ra[sa[i] + k] : 0]++] = sa[i];
	for (int i = 0; i < len; i++) sa[i] = tmpsa[i];
}
void buildsa()
{
	for (int i = 0; i < len; i++) ra[i] = s[i], sa[i] = i;

	for (int k = 1; k < len; k <<= 1)
	{
		countSort(k);
		countSort(0);

		int r = 0;
		tra[sa[0]] = 0;
		for (int i = 1; i < len; i++)
		{
			int t1 = (sa[i] + k < len ? ra[sa[i] + k] : 0);
			int t2 = (sa[i - 1] + k < len ? ra[sa[i - 1] + k] : 0);
			tra[sa[i]] = (ra[sa[i]] == ra[sa[i - 1]] && t1 == t2 ) ? r : ++r;
		}
		for (int i = 0; i < len; i++) ra[i] = tra[i];
		if (ra[sa[len - 1]] == len - 1) break;
	}

	/*for (int i = 0; i < len; i++)
	{
		cout << i << " <suffixarray> " << sa[i] << " ";
		for (int j = sa[i]; j < len; j++) cout << s[j];
		cout << endl;
	}*/
}

int phi[maxN], LCP[maxN];
void computeLCP()
{
	phi[sa[0]] = -1;
	for (int i = 1; i < len; i++) phi[sa[i]] = sa[i - 1];
	int L = 0;
	for (int i = 0; i < len; i++)
	{
		if (phi[i] == -1)
		{
			LCP[ra[i]] = 0;
			continue;
		}
		while (L < len && s[i + L] == s[phi[i] + L]) L++;
		L = min(nearest[i] - i, L);
		LCP[ra[i]] = L;
		L = max(L - 1, 0);
	}
	//for (int i = 0; i < len; i++)
	//cout << i << "  sa: " << sa[i] << " <LCP> " << LCP[i] << " bel:" << belong[sa[i]] << endl; //debug
}

int spt[maxN][25];//default sparseTable array ( 25 > log2(10^7) )
int log2a[maxN];
void sptBuild(int spt[][25], int ara[], int n = maxN) // 0 indexing (0 to n-1)
{
	for (int j = 0; (1 << j) < n; j++)
	{
		for (int i = 0; i < n; i++)
		{
			if (j == 0) spt[i][j] = ara[i];
			else spt[i][j] = min(spt[i][j - 1], (i + (1 << j - 1) < n) ? spt[i + (1 << j - 1)][j - 1]  : 0 ) ;
		}
	}
	for (int i = 1; i <= n; i++) log2a[i] = log2(i);
}
int sptQry(int spt[][25], int l, int r)
{
	int dis = log2a[r - l + 1]; //RMQ (minimum) using overlapping range
	return min(spt[l][dis], spt[r - (1 << dis) + 1][dis]);
}

ll occ[maxNO], mxv[maxN], ans[maxN], fans[maxN];

void qry(int n)//n: atleast n string has the LCS , prequisite:  computeLCP
{
	set<pair<ll, ll> >box;
	memset(occ, 0, sizeof(occ));
	int distinct_cnt = 0, mx = 0;
	for (int i = 0; i < len; i++)
	{
		distinct_cnt += !occ[belong[sa[i]]];
		occ[belong[sa[i]]]++;
		box.insert(make_pair(LCP[i], i));
		while (distinct_cnt == n)
		{
			int pos = i - box.size() + 1;
			box.erase(make_pair(LCP[pos], pos));
			mxv[pos] = max(mxv[pos], box.begin()->first);
			occ[belong[sa[pos]]]--;
			distinct_cnt -= !occ[belong[sa[pos]]];
		}
	}
	box.clear();
	memset(occ, 0, sizeof(occ));
	distinct_cnt = 0;
	int  lastout = -1;

	for (int i = 0; i < len; i++)
	{
		distinct_cnt += !occ[belong[sa[i]]];
		occ[belong[sa[i]]]++;
		box.insert(make_pair(-mxv[i], i));
		ans[i] = -box.begin()->first;
		while (distinct_cnt == n)
		{
			int pos = i - box.size() + 1;
			box.erase(make_pair(-mxv[pos], pos));
			occ[belong[sa[pos]]]--;
			distinct_cnt -= !occ[belong[sa[pos]]];
			lastout = pos;
		}
		if (lastout != -1) ans[i] = max(ans[i], (ll)sptQry(spt, lastout + 1, i));
	}
	for (int i = 0; i < len; i++) fans[belong[sa[i]]] += ans[i];

}

int main()
{
	string str;
	int n, k;
	cin >> n >> k;
	for (int i = 1; i <= n; i++)
	{
		cin >> str;
		slen[i] = str.size();
		start[i] = len;
		s += str;
		s += "&";
		len += str.size() + 1;
		if (k == 1) cout << (str.size() * ((ll)(str.size() + 1)) / 2) << " ";
	}
	if (k == 1)
	{
		cout << endl;
		exit(0);
	}
	mapstring(n, '&');
	buildsa();
	computeLCP();
	sptBuild(spt, LCP, len);
	qry(k);

	for (int i = 1; i <= n; i++) cout << fans[i] << " ";
	cout << endl;
}


#include<bits/stdc++.h>
using namespace std;

#define ff first
#define ss second
#define m_p make_pair
#define pb push_back
#define ppb pop_back
#define pf push_front
#define ppf pop_front
#define ll long long
#define l_b lower_bound
#define u_b upper_bound

int n;
string s;

const int maxN = 5000010;// max length of total string,
int len;//length of the string of the suffix array
const static int maxNO = maxN; //multiple maximum number of string cancated in the suffixarray string
int slen[maxNO], start[maxNO]; //update these while taking input and concating
int nearest[maxN], belong[maxN];
void mapstring(int n, int term_char) //term_char = integer value of terminating character
{	//n = number of concated string
	n++;
	for (int i = len - 1, tt = len - 1; i >= 0; i--)
	{
		if (s[i] == term_char) tt = i, n--;
		nearest[i] = tt;
		belong[i] = n;
	}
}
int ra[maxN], tra[maxN], sa[maxN], tmpsa[maxN], cnt[maxN];
void countSort(int k)
{
	int maxr = max(300, len);
	memset(cnt, 0, sizeof(cnt[0]) * (maxr + 5));

	for (int i = 0; i < len; i++) cnt[sa[i] + k < len ? ra[sa[i] + k] : 0]++;
	for (int i = 0, t, sum = 0; i < maxr; i++) t = cnt[i], cnt[i] = sum, sum += t;
	for (int i = 0; i < len; i++) tmpsa[cnt[sa[i] + k < len ? ra[sa[i] + k] : 0]++] = sa[i];
	for (int i = 0; i < len; i++) sa[i] = tmpsa[i];
}
void buildsa()
{
	for (int i = 0; i < len; i++) ra[i] = s[i], sa[i] = i;

	for (int k = 1; k < len; k <<= 1)
	{
		countSort(k);
		countSort(0);

		int r = 0;
		tra[sa[0]] = 0;
		for (int i = 1; i < len; i++)
		{
			int t1 = (sa[i] + k < len ? ra[sa[i] + k] : 0);
			int t2 = (sa[i - 1] + k < len ? ra[sa[i - 1] + k] : 0);
			tra[sa[i]] = (ra[sa[i]] == ra[sa[i - 1]] && t1 == t2 ) ? r : ++r;
		}
		for (int i = 0; i < len; i++) ra[i] = tra[i];
		if (ra[sa[len - 1]] == len - 1) break;
	}

	/*for (int i = 0; i < len; i++)
	{
		cout << i << " <suffixarray> " << sa[i] << " ";
		for (int j = sa[i]; j < len; j++) cout << s[j];
		cout << endl;
	}*/
}

int phi[maxN], LCP[maxN];
void computeLCP()
{
	phi[sa[0]] = -1;
	for (int i = 1; i < len; i++) phi[sa[i]] = sa[i - 1];
	int L = 0;
	for (int i = 0; i < len; i++)
	{
		if (phi[i] == -1)
		{
			LCP[ra[i]] = 0;
			continue;
		}
		while (L < len && s[i + L] == s[phi[i] + L]) L++;
		L = min(nearest[i] - i, L);
		LCP[ra[i]] = L;
		L = max(L - 1, 0);
	}
	//for (int i = 0; i < len; i++)
		//cout << i << "  sa: " << sa[i] << " <LCP> " << LCP[i] << " bel:" << belong[sa[i]] << endl; //debug
}

int spt[maxN][25];//default sparseTable array ( 25 > log2(10^7) )
int log2a[maxN];
void sptBuild(int spt[][25], int ara[], int n = maxN) // 0 indexing (0 to n-1)
{
	for (int j = 0; (1 << j) < n; j++)
	{
		for (int i = 0; i < n; i++)
		{
			if (j == 0) spt[i][j] = ara[i];
			else spt[i][j] = min(spt[i][j - 1], (i + (1 << j - 1) < n) ? spt[i + (1 << j - 1)][j - 1]  : 0 ) ;
		}
	}
	for (int i = 1; i <= n; i++) log2a[i] = log2(i);
}
int sptQry(int spt[][25], int l, int r)
{
	int dis = log2a[r - l + 1]; //RMQ (minimum) using overlapping range
	return min(spt[l][dis], spt[r - (1 << dis) + 1][dis]);
}

ll occ[maxNO], mxv[maxN], ans[maxN], fans[maxN];
vector<int>v[maxN];
int getend(int pos, int val)
{
	int lo = pos+1, hi = len - 1, ans = pos;
	while (lo <= hi)
	{
		int mid = (lo + hi) / 2;
		if(mid<pos+1)
		{
			cout<<"bal"<<endl;
			exit(0);
		}
		int mm = sptQry(spt, pos + 1, mid);
		if (mm >= val) ans = max(ans, mid), lo = mid + 1;
		else hi = mid - 1;
	}
	return ans + 1;
}
void qry(int n)//n: atleast n string has the LCS , prequisite:  computeLCP
{
	set<pair<ll, ll> >box;
	memset(occ, 0, sizeof(occ));
	int distinct_cnt = 0, mx = 0;
	for (int i = 0; i < len; i++)
	{
		distinct_cnt += !occ[belong[sa[i]]];
		occ[belong[sa[i]]]++;
		box.insert(make_pair(LCP[i], i));
		while (distinct_cnt == n)
		{
			int pos = i - box.size() + 1;
			box.erase(make_pair(LCP[pos], pos));
			mxv[pos] = max(mxv[pos], box.begin()->first);
			v[getend(pos, mxv[pos])].pb(pos);
			occ[belong[sa[pos]]]--;
			distinct_cnt -= !occ[belong[sa[pos]]];
		}
	}
	box.clear();

	for (int i = 0; i < len; i++)
	{
		for (int j = 0; j < v[i].size(); j++) box.erase(m_p(-mxv[v[i][j]], v[i][j]));
		box.insert(make_pair(-mxv[i], i));
		ans[i] = -box.begin()->first;
	}
	for (int i = 0; i < len; i++) fans[belong[sa[i]]] += ans[i];

}

int main()
{
	string str;
	int n, k;
	cin >> n >> k;
	for (int i = 1; i <= n; i++)
	{
		cin >> str;
		slen[i] = str.size();
		start[i] = len;
		s += str;
		s += "&";
		len += str.size() + 1;
		if (k == 1) cout << (str.size() * ((ll)(str.size() + 1)) / 2) << " ";
	}
	if (k == 1)
	{
		cout << endl;
		exit(0);
	}
	mapstring(n, '&');
	buildsa();
	computeLCP();
	sptBuild(spt, LCP, len);
	qry(k);

	for (int i = 1; i <= n; i++) cout << fans[i] << " ";
	cout << endl;
}


#include<bits/stdc++.h>
using namespace std;

#define ff first
#define ss second
#define m_p make_pair
#define pb push_back
#define ppb pop_back
#define pf push_front
#define ppf pop_front
#define ll long long
#define l_b lower_bound
#define u_b upper_bound

int n;
string s;

const int maxN = 100010;// max length of total string,
int len;//length of the string of the suffix array
const static int maxNO = maxN; //multiple maximum number of string cancated in the suffixarray string
int slen[maxNO], start[maxNO]; //update these while taking input and concating
int nearest[maxN], belong[maxN];
void mapstring(int n, int term_char) //term_char = integer value of terminating character
{	//n = number of concated string
	n++;
	for (int i = len - 1, tt = len - 1; i >= 0; i--)
	{
		if (s[i] == term_char) tt = i, n--;
		nearest[i] = tt;
		belong[i] = n;
	}
}
int ra[maxN], tra[maxN], sa[maxN], tmpsa[maxN], cnt[maxN];
void countSort(int k)
{
	int maxr = max(300, len);
	memset(cnt, 0, sizeof(cnt[0]) * (maxr + 5));

	for (int i = 0; i < len; i++) cnt[sa[i] + k < len ? ra[sa[i] + k] : 0]++;
	for (int i = 0, t, sum = 0; i < maxr; i++) t = cnt[i], cnt[i] = sum, sum += t;
	for (int i = 0; i < len; i++) tmpsa[cnt[sa[i] + k < len ? ra[sa[i] + k] : 0]++] = sa[i];
	for (int i = 0; i < len; i++) sa[i] = tmpsa[i];
}
void buildsa()
{
	for (int i = 0; i < len; i++) ra[i] = s[i], sa[i] = i;

	for (int k = 1; k < len; k <<= 1)
	{
		countSort(k);
		countSort(0);

		int r = 0;
		tra[sa[0]] = 0;
		for (int i = 1; i < len; i++)
		{
			int t1 = (sa[i] + k < len ? ra[sa[i] + k] : 0);
			int t2 = (sa[i - 1] + k < len ? ra[sa[i - 1] + k] : 0);
			tra[sa[i]] = (ra[sa[i]] == ra[sa[i - 1]] && t1 == t2 ) ? r : ++r;
		}
		for (int i = 0; i < len; i++) ra[i] = tra[i];
		if (ra[sa[len - 1]] == len - 1) break;
	}

}

int phi[maxN], LCP[maxN];
void computeLCP()
{
	phi[sa[0]] = -1;
	for (int i = 1; i < len; i++) phi[sa[i]] = sa[i - 1];
	int L = 0;
	for (int i = 0; i < len; i++)
	{
		if (phi[i] == -1)
		{
			LCP[ra[i]] = 0;
			continue;
		}
		while (L < len && s[i + L] == s[phi[i] + L]) L++;
		L = min(nearest[i] - i, L);
		LCP[ra[i]] = L;
		L = max(L - 1, 0);
	}
	//for (int i = 0; i < len; i++)
		//cout << i << "  sa: " << sa[i] << " <LCP> " << LCP[i] << " bel:" << belong[sa[i]] << endl; //debug
}

int spt[maxN][25];//default sparseTable array ( 25 > log2(10^7) )
int log2a[maxN];
void sptBuild(int spt[][25], int ara[], int n = maxN) // 0 indexing (0 to n-1)
{
	for (int j = 0; (1 << j) < n; j++)
	{
		for (int i = 0; i < n; i++)
		{
			if (j == 0) spt[i][j] = ara[i];
			else spt[i][j] = min(spt[i][j - 1], (i + (1 << j - 1) < n) ? spt[i + (1 << j - 1)][j - 1]  : 0 ) ;
		}
	}
	for (int i = 1; i <= n; i++) log2a[i] = log2(i);
}
int sptQry(int spt[][25], int l, int r)
{
	int dis = log2a[r - l + 1]; //RMQ (minimum) using overlapping range
	return min(spt[l][dis], spt[r - (1 << dis) + 1][dis]);
}

ll occ[maxNO], mxv[maxN], ans[maxN], fans[maxN];
vector<int>v[maxN];
int getend(int pos, int val)
{
	int lo = pos, hi = len - 1, ans = pos;
	while (lo <= hi)
	{
		int mid = (lo + hi) / 2;
		int mm = sptQry(spt, pos + 1, mid);
		if (mm >= val) ans = max(ans, mid), lo = mid + 1;
		else hi = mid - 1;
	}
	return ans + 1;
}
void qry(int n)//n: atleast n string has the LCS , prequisite:  computeLCP
{
	set<pair<ll, ll> >box;
	memset(occ, 0, sizeof(occ));
	int distinct_cnt = 0, mx = 0;
	for (int i = 0; i < len; i++)
	{
		distinct_cnt += !occ[belong[sa[i]]];
		occ[belong[sa[i]]]++;
		box.insert(make_pair(LCP[i], i));
		while (distinct_cnt == n)
		{
			int pos = i - box.size() + 1;
			box.erase(make_pair(LCP[pos], pos));
			mxv[pos] = max(mxv[pos], box.begin()->first);
			v[getend(pos, mxv[pos])].pb(pos);
			occ[belong[sa[pos]]]--;
			distinct_cnt -= !occ[belong[sa[pos]]];
		}
	}
	box.clear();

	for (int i = 0; i < len; i++)
	{
		for (int j = 0; j < v[i].size(); j++) box.erase(m_p(-mxv[v[i][j]], v[i][j]));
		box.insert(make_pair(-mxv[i], i));
		ans[i] = -box.begin()->first;
	}
	for (int i = 0; i < len; i++) fans[belong[sa[i]]] += ans[i];
}

int main()
{
	string str;
	int n, k;
	cin >> n >> k;
	for (int i = 1; i <= n; i++)
	{
		cin >> str;
		slen[i] = str.size();
		start[i] = len;
		s += str;
		s += "&";
		len += str.size() + 1;
		if (k == 1) cout << (str.size() * ((ll)(str.size()+1)) / 2) << " ";
	}
	if (k == 1)
	{
		cout << endl;
		exit(0);
	}
	mapstring(n, '&');
	buildsa();
	computeLCP();
	sptBuild(spt, LCP, len);
	qry(k);

	for (int i = 1; i <= n; i++) cout << fans[i] << " ";
	cout << endl;
}


#include<bits/stdc++.h>
using namespace std;

#define ff first
#define ss second
#define m_p make_pair
#define pb push_back
#define ppb pop_back
#define pf push_front
#define ppf pop_front
#define ll long long
#define l_b lower_bound
#define u_b upper_bound

int n;
string s;

const int maxN = 500010;// max length of total string,
int len;//length of the string of the suffix array
const static int maxNO = maxN; //multiple maximum number of string cancated in the suffixarray string
int slen[maxNO], start[maxNO]; //update these while taking input and concating
int nearest[maxN], belong[maxN];
void mapstring(int n, int term_char) //term_char = integer value of terminating character
{	//n = number of concated string
	n++;
	for (int i = len - 1, tt = len - 1; i >= 0; i--)
	{
		if (s[i] == term_char) tt = i, n--;
		nearest[i] = tt;
		belong[i] = n;
	}
}
int ra[maxN], tra[maxN], sa[maxN], tmpsa[maxN], cnt[maxN];
void countSort(int k)
{
	int maxr = max(300, len);
	memset(cnt, 0, sizeof(cnt[0]) * (maxr + 5));

	for (int i = 0; i < len; i++) cnt[sa[i] + k < len ? ra[sa[i] + k] : 0]++;
	for (int i = 0, t, sum = 0; i < maxr; i++) t = cnt[i], cnt[i] = sum, sum += t;
	for (int i = 0; i < len; i++) tmpsa[cnt[sa[i] + k < len ? ra[sa[i] + k] : 0]++] = sa[i];
	for (int i = 0; i < len; i++) sa[i] = tmpsa[i];
}
void buildsa()
{
	for (int i = 0; i < len; i++) ra[i] = s[i], sa[i] = i;

	for (int k = 1; k < len; k <<= 1)
	{
		countSort(k);
		countSort(0);

		int r = 0;
		tra[sa[0]] = 0;
		for (int i = 1; i < len; i++)
		{
			int t1 = (sa[i] + k < len ? ra[sa[i] + k] : 0);
			int t2 = (sa[i - 1] + k < len ? ra[sa[i - 1] + k] : 0);
			tra[sa[i]] = (ra[sa[i]] == ra[sa[i - 1]] && t1 == t2 ) ? r : ++r;
		}
		for (int i = 0; i < len; i++) ra[i] = tra[i];
		if (ra[sa[len - 1]] == len - 1) break;
	}

	/*for (int i = 0; i < len; i++)
	{
		cout << i << " <suffixarray> " << sa[i] << " ";
		for (int j = sa[i]; j < len; j++) cout << s[j];
		cout << endl;
	}*/
}

int phi[maxN], LCP[maxN];
void computeLCP()
{
	phi[sa[0]] = -1;
	for (int i = 1; i < len; i++) phi[sa[i]] = sa[i - 1];
	int L = 0;
	for (int i = 0; i < len; i++)
	{
		if (phi[i] == -1)
		{
			LCP[ra[i]] = 0;
			continue;
		}
		while (L < len && s[i + L] == s[phi[i] + L]) L++;
		L = min(nearest[i] - i, L);
		LCP[ra[i]] = L;
		L = max(L - 1, 0);
	}
	//for (int i = 0; i < len; i++)
	//cout << i << "  sa: " << sa[i] << " <LCP> " << LCP[i] << " bel:" << belong[sa[i]] << endl; //debug
}

int spt[maxN][25];//default sparseTable array ( 25 > log2(10^7) )
int log2a[maxN];
void sptBuild(int spt[][25], int ara[], int n = maxN) // 0 indexing (0 to n-1)
{
	for (int j = 0; (1 << j) < n; j++)
	{
		for (int i = 0; i < n; i++)
		{
			if (j == 0) spt[i][j] = ara[i];
			else spt[i][j] = min(spt[i][j - 1], (i + (1 << j - 1) < n) ? spt[i + (1 << j - 1)][j - 1]  : 0 ) ;
		}
	}
	for (int i = 1; i <= n; i++) log2a[i] = log2(i);
}
int sptQry(int spt[][25], int l, int r)
{
	if (l > r)
	{
		cout << "waht the fuck dude\n";
		exit(0);
	}
	int dis = log2a[r - l + 1]; //RMQ (minimum) using overlapping range
	return min(spt[l][dis], spt[r - (1 << dis) + 1][dis]);
}

ll occ[maxNO], mxv[maxN], ans[maxN], fans[maxN];

void qry(int n)//n: atleast n string has the LCS , prequisite:  computeLCP
{
	set<pair<ll, ll> >box;
	memset(occ, 0, sizeof(occ));
	int distinct_cnt = 0, mx = 0;
	for (int i = 0; i < len; i++)
	{
		distinct_cnt += !occ[belong[sa[i]]];
		occ[belong[sa[i]]]++;
		box.insert(make_pair(LCP[i], i));
		while (distinct_cnt == n)
		{
			int pos = i - box.size() + 1;
			box.erase(make_pair(LCP[pos], pos));
			mxv[pos] = max(mxv[pos], box.begin()->first);
			occ[belong[sa[pos]]]--;
			distinct_cnt -= !occ[belong[sa[pos]]];
		}
	}
	box.clear();
	memset(occ, 0, sizeof(occ));
	distinct_cnt = 0;
	int  lastout = -1;

	for (int i = 0; i < len; i++)
	{
		distinct_cnt += !occ[belong[sa[i]]];
		occ[belong[sa[i]]]++;
		box.insert(make_pair(-mxv[i], i));
		ans[i] = -box.begin()->first;
		while (distinct_cnt == n)
		{
			int pos = i - box.size() + 1;
			box.erase(make_pair(-mxv[pos], pos));
			occ[belong[sa[pos]]]--;
			distinct_cnt -= !occ[belong[sa[pos]]];
			lastout = pos;
		}
		if (lastout != -1) ans[i] = max(ans[i], (ll)sptQry(spt, lastout + 1, i));
	}
	for (int i = 0; i < len; i++) fans[belong[sa[i]]] += ans[i];

}

int main()
{
	string str;
	int n, k;
	cin >> n >> k;
	for (int i = 1; i <= n; i++)
	{
		cin >> str;
		slen[i] = str.size();
		start[i] = len;
		s += str;
		s += "&";
		len += str.size() + 1;
		if (k == 1) cout << (str.size() * ((ll)(str.size() + 1)) / 2) << " ";
	}
	if (k == 1)
	{
		cout << endl;
		exit(0);
	}
	mapstring(n, '&');
	buildsa();
	computeLCP();
	sptBuild(spt, LCP, len);
	qry(k);

	for (int i = 1; i <= n; i++) printf("%I64d ", fans[i]);
	cout << endl;
}


#include<bits/stdc++.h>
using namespace std;

#define ff first
#define ss second
#define m_p make_pair
#define pb push_back
#define ppb pop_back
#define pf push_front
#define ppf pop_front
#define ll long long
#define l_b lower_bound
#define u_b upper_bound

int n;
string s;

const int maxN = 100010;// max length of total string,
int len;//length of the string of the suffix array
const static int maxNO = maxN; //multiple maximum number of string cancated in the suffixarray string
int slen[maxNO], start[maxNO]; //update these while taking input and concating
int nearest[maxN], belong[maxN];
void mapstring(int n, int term_char) //term_char = integer value of terminating character
{	//n = number of concated string
	n++;
	for (int i = len - 1, tt = len - 1; i >= 0; i--)
	{
		if (s[i] == term_char) tt = i, n--;
		nearest[i] = tt;
		belong[i] = n;
	}
}
int ra[maxN], tra[maxN], sa[maxN], tmpsa[maxN], cnt[maxN];
void countSort(int k)
{
	int maxr = max(300, len);
	memset(cnt, 0, sizeof(cnt[0]) * (maxr + 5));

	for (int i = 0; i < len; i++) cnt[sa[i] + k < len ? ra[sa[i] + k] : 0]++;
	for (int i = 0, t, sum = 0; i < maxr; i++) t = cnt[i], cnt[i] = sum, sum += t;
	for (int i = 0; i < len; i++) tmpsa[cnt[sa[i] + k < len ? ra[sa[i] + k] : 0]++] = sa[i];
	for (int i = 0; i < len; i++) sa[i] = tmpsa[i];
}
void buildsa()
{
	for (int i = 0; i < len; i++) ra[i] = s[i], sa[i] = i;

	for (int k = 1; k < len; k <<= 1)
	{
		countSort(k);
		countSort(0);

		int r = 0;
		tra[sa[0]] = 0;
		for (int i = 1; i < len; i++)
		{
			int t1 = (sa[i] + k < len ? ra[sa[i] + k] : 0);
			int t2 = (sa[i - 1] + k < len ? ra[sa[i - 1] + k] : 0);
			tra[sa[i]] = (ra[sa[i]] == ra[sa[i - 1]] && t1 == t2 ) ? r : ++r;
		}
		for (int i = 0; i < len; i++) ra[i] = tra[i];
		if (ra[sa[len - 1]] == len - 1) break;
	}

	/*for (int i = 0; i < len; i++)
	{
		cout << i << " <suffixarray> " << sa[i] << " ";
		for (int j = sa[i]; j < len; j++) cout << s[j];
		cout << endl;
	}*/
}

int phi[maxN], LCP[maxN];
void computeLCP()
{
	phi[sa[0]] = -1;
	for (int i = 1; i < len; i++) phi[sa[i]] = sa[i - 1];
	int L = 0;
	for (int i = 0; i < len; i++)
	{
		if (phi[i] == -1)
		{
			LCP[ra[i]] = 0;
			continue;
		}
		while (L < len && s[i + L] == s[phi[i] + L]) L++;
		L = min(nearest[i] - i, L);
		LCP[ra[i]] = L;
		L = max(L - 1, 0);
	}
	//for (int i = 0; i < len; i++)
		//cout << i << "  sa: " << sa[i] << " <LCP> " << LCP[i] << " bel:" << belong[sa[i]] << endl; //debug
}

int spt[maxN][25];//default sparseTable array ( 25 > log2(10^7) )
int log2a[maxN];
void sptBuild(int spt[][25], int ara[], int n = maxN) // 0 indexing (0 to n-1)
{
	for (int j = 0; (1 << j) < n; j++)
	{
		for (int i = 0; i < n; i++)
		{
			if (j == 0) spt[i][j] = ara[i];
			else spt[i][j] = min(spt[i][j - 1], (i + (1 << j - 1) < n) ? spt[i + (1 << j - 1)][j - 1]  : 0 ) ;
		}
	}
	for (int i = 1; i <= n; i++) log2a[i] = log2(i);
}
int sptQry(int spt[][25], int l, int r)
{
	int dis = log2a[r - l + 1]; //RMQ (minimum) using overlapping range
	return min(spt[l][dis], spt[r - (1 << dis) + 1][dis]);
}

ll occ[maxNO], mxv[maxN], ans[maxN], fans[maxN];
vector<int>v[maxN];
int getend(int pos, int val)
{
	int lo = pos+1, hi = len - 1, ans = pos;
	while (lo <= hi)
	{
		int mid = (lo + hi) / 2;
		int mm = sptQry(spt, pos + 1, mid);
		if (mm >= val) ans = max(ans, mid), lo = mid + 1;
		else hi = mid - 1;
	}
	return ans + 1;
}
void qry(int n)//n: atleast n string has the LCS , prequisite:  computeLCP
{
	set<pair<ll, ll> >box;
	memset(occ, 0, sizeof(occ));
	int distinct_cnt = 0, mx = 0;
	for (int i = 0; i < len; i++)
	{
		distinct_cnt += !occ[belong[sa[i]]];
		occ[belong[sa[i]]]++;
		box.insert(make_pair(LCP[i], i));
		while (distinct_cnt == n)
		{
			int pos = i - box.size() + 1;
			box.erase(make_pair(LCP[pos], pos));
			mxv[pos] = max(mxv[pos], box.begin()->first);
			v[getend(pos, mxv[pos])].pb(pos);
			occ[belong[sa[pos]]]--;
			distinct_cnt -= !occ[belong[sa[pos]]];
		}
	}
	box.clear();

	for (int i = 0; i < len; i++)
	{
		for (int j = 0; j < v[i].size(); j++) box.erase(m_p(-mxv[v[i][j]], v[i][j]));
		box.insert(make_pair(-mxv[i], i));
		ans[i] = -box.begin()->first;
	}
	for (int i = 0; i < len; i++) fans[belong[sa[i]]] += ans[i];

}

int main()
{
	string str;
	int n, k;
	cin >> n >> k;
	for (int i = 1; i <= n; i++)
	{
		cin >> str;
		slen[i] = str.size();
		start[i] = len;
		s += str;
		s += "&";
		len += str.size() + 1;
		if (k == 1) cout << (str.size() * ((ll)(str.size() + 1)) / 2) << " ";
	}
	if (k == 1)
	{
		cout << endl;
		exit(0);
	}
	mapstring(n, '&');
	buildsa();
	computeLCP();
	sptBuild(spt, LCP, len);
	qry(k);

	for (int i = 1; i <= n; i++) cout << fans[i] << " ";
	cout << endl;
}


#include<bits/stdc++.h>
using namespace std;

#define ff first
#define ss second
#define m_p make_pair
#define pb push_back
#define ppb pop_back
#define pf push_front
#define ppf pop_front
#define ll long long
#define l_b lower_bound
#define u_b upper_bound

int n;
string s;

const int maxN = 500010;// max length of total string,
int len;//length of the string of the suffix array
const static int maxNO = maxN; //multiple maximum number of string cancated in the suffixarray string
int slen[maxNO], start[maxNO]; //update these while taking input and concating
int nearest[maxN], belong[maxN];
void mapstring(int n, int term_char) //term_char = integer value of terminating character
{	//n = number of concated string
	n++;
	for (int i = len - 1, tt = len - 1; i >= 0; i--)
	{
		if (s[i] == term_char) tt = i, n--;
		nearest[i] = tt;
		belong[i] = n;
	}
}
int ra[maxN], tra[maxN], sa[maxN], tmpsa[maxN], cnt[maxN];
void countSort(int k)
{
	int maxr = max(300, len);
	memset(cnt, 0, sizeof(cnt[0]) * (maxr + 5));

	for (int i = 0; i < len; i++) cnt[sa[i] + k < len ? ra[sa[i] + k] : 0]++;
	for (int i = 0, t, sum = 0; i < maxr; i++) t = cnt[i], cnt[i] = sum, sum += t;
	for (int i = 0; i < len; i++) tmpsa[cnt[sa[i] + k < len ? ra[sa[i] + k] : 0]++] = sa[i];
	for (int i = 0; i < len; i++) sa[i] = tmpsa[i];
}
void buildsa()
{
	for (int i = 0; i < len; i++) ra[i] = s[i], sa[i] = i;

	for (int k = 1; k < len; k <<= 1)
	{
		countSort(k);
		countSort(0);

		int r = 0;
		tra[sa[0]] = 0;
		for (int i = 1; i < len; i++)
		{
			int t1 = (sa[i] + k < len ? ra[sa[i] + k] : 0);
			int t2 = (sa[i - 1] + k < len ? ra[sa[i - 1] + k] : 0);
			tra[sa[i]] = (ra[sa[i]] == ra[sa[i - 1]] && t1 == t2 ) ? r : ++r;
		}
		for (int i = 0; i < len; i++) ra[i] = tra[i];
		if (ra[sa[len - 1]] == len - 1) break;
	}

	/*for (int i = 0; i < len; i++)
	{
		cout << i << " <suffixarray> " << sa[i] << " ";
		for (int j = sa[i]; j < len; j++) cout << s[j];
		cout << endl;
	}*/
}

int phi[maxN], LCP[maxN];
void computeLCP()
{
	phi[sa[0]] = -1;
	for (int i = 1; i < len; i++) phi[sa[i]] = sa[i - 1];
	int L = 0;
	for (int i = 0; i < len; i++)
	{
		if (phi[i] == -1)
		{
			LCP[ra[i]] = 0;
			continue;
		}
		while (L < len && s[i + L] == s[phi[i] + L]) L++;
		L = min(nearest[i] - i, L);
		LCP[ra[i]] = L;
		L = max(L - 1, 0);
	}
	//for (int i = 0; i < len; i++)
		//cout << i << "  sa: " << sa[i] << " <LCP> " << LCP[i] << " bel:" << belong[sa[i]] << endl; //debug
}

int spt[maxN][25];//default sparseTable array ( 25 > log2(10^7) )
int log2a[maxN];
void sptBuild(int spt[][25], int ara[], int n = maxN) // 0 indexing (0 to n-1)
{
	for (int j = 0; (1 << j) < n; j++)
	{
		for (int i = 0; i < n; i++)
		{
			if (j == 0) spt[i][j] = ara[i];
			else spt[i][j] = min(spt[i][j - 1], (i + (1 << j - 1) < n) ? spt[i + (1 << j - 1)][j - 1]  : 0 ) ;
		}
	}
	for (int i = 1; i <= n; i++) log2a[i] = log2(i);
}
int sptQry(int spt[][25], int l, int r)
{
	int dis = log2a[r - l + 1]; //RMQ (minimum) using overlapping range
	return min(spt[l][dis], spt[r - (1 << dis) + 1][dis]);
}

ll occ[maxNO], mxv[maxN], ans[maxN], fans[maxN];
vector<int>v[maxN];
int getend(int pos, int val)
{
	int lo = pos+1, hi = len - 1, ans = pos;
	while (lo <= hi)
	{
		int mid = (lo + hi) / 2;
		if(mid<pos+1)
		{
			cout<<"bal"<<endl;
			exit(0);
		}
		int mm = sptQry(spt, pos + 1, mid);
		if (mm >= val) ans = max(ans, mid), lo = mid + 1;
		else hi = mid - 1;
	}
	return ans + 1;
}
void qry(int n)//n: atleast n string has the LCS , prequisite:  computeLCP
{
	set<pair<ll, ll> >box;
	memset(occ, 0, sizeof(occ));
	int distinct_cnt = 0, mx = 0;
	for (int i = 0; i < len; i++)
	{
		distinct_cnt += !occ[belong[sa[i]]];
		occ[belong[sa[i]]]++;
		box.insert(make_pair(LCP[i], i));
		while (distinct_cnt == n)
		{
			int pos = i - box.size() + 1;
			box.erase(make_pair(LCP[pos], pos));
			mxv[pos] = max(mxv[pos], box.begin()->first);
			v[getend(pos, mxv[pos])].pb(pos);
			occ[belong[sa[pos]]]--;
			distinct_cnt -= !occ[belong[sa[pos]]];
		}
	}
	box.clear();

	for (int i = 0; i < len; i++)
	{
		for (int j = 0; j < v[i].size(); j++) box.erase(m_p(-mxv[v[i][j]], v[i][j]));
		box.insert(make_pair(-mxv[i], i));
		ans[i] = -box.begin()->first;
	}
	for (int i = 0; i < len; i++) fans[belong[sa[i]]] += ans[i];

}

int main()
{
	string str;
	int n, k;
	cin >> n >> k;
	for (int i = 1; i <= n; i++)
	{
		cin >> str;
		slen[i] = str.size();
		start[i] = len;
		s += str;
		s += "&";
		len += str.size() + 1;
		if (k == 1) cout << (str.size() * ((ll)(str.size() + 1)) / 2) << " ";
	}
	if (k == 1)
	{
		cout << endl;
		exit(0);
	}
	mapstring(n, '&');
	buildsa();
	computeLCP();
	sptBuild(spt, LCP, len);
	qry(k);

	for (int i = 1; i <= n; i++) cout << fans[i] << " ";
	cout << endl;
}


#include<bits/stdc++.h>
using namespace std;

#define ff first
#define ss second
#define m_p make_pair
#define pb push_back
#define ppb pop_back
#define pf push_front
#define ppf pop_front
#define ll long long
#define l_b lower_bound
#define u_b upper_bound

int n;
string s;

const int maxN = 500010;// max length of total string,
int len;//length of the string of the suffix array
const static int maxNO = maxN; //multiple maximum number of string cancated in the suffixarray string
int slen[maxNO], start[maxNO]; //update these while taking input and concating
int nearest[maxN], belong[maxN];
void mapstring(int n, int term_char) //term_char = integer value of terminating character
{	//n = number of concated string
	n++;
	//cout << "enter mapstring\n";
	for (int i = len - 1, tt = len - 1; i >= 0; i--)
	{
		if (s[i] == term_char) tt = i, n--;
		nearest[i] = tt;
		belong[i] = n;
	}
	//cout << "end mapstring\n";
}
int ra[maxN], tra[maxN], sa[maxN], tmpsa[maxN], cnt[maxN];
void countSort(int k)
{
	int maxr = max(300, len);
	memset(cnt, 0, sizeof(cnt[0]) * (maxr + 5));

	for (int i = 0; i < len; i++) cnt[sa[i] + k < len ? ra[sa[i] + k] : 0]++;
	for (int i = 0, t, sum = 0; i < maxr; i++) t = cnt[i], cnt[i] = sum, sum += t;
	for (int i = 0; i < len; i++) tmpsa[cnt[sa[i] + k < len ? ra[sa[i] + k] : 0]++] = sa[i];
	for (int i = 0; i < len; i++) sa[i] = tmpsa[i];
}
void buildsa()
{
	for (int i = 0; i < len; i++) ra[i] = s[i], sa[i] = i;

	for (int k = 1; k < len; k <<= 1)
	{
		countSort(k);
		countSort(0);

		int r = 0;
		tra[sa[0]] = 0;
		for (int i = 1; i < len; i++)
		{
			int t1 = (sa[i] + k < len ? ra[sa[i] + k] : 0);
			int t2 = (sa[i - 1] + k < len ? ra[sa[i - 1] + k] : 0);
			tra[sa[i]] = (ra[sa[i]] == ra[sa[i - 1]] && t1 == t2 ) ? r : ++r;
		}
		for (int i = 0; i < len; i++) ra[i] = tra[i];
		if (ra[sa[len - 1]] == len - 1) break;
	}
}

int phi[maxN], LCP[maxN];
void computeLCP()
{
	phi[sa[0]] = -1;
	for (int i = 1; i < len; i++) phi[sa[i]] = sa[i - 1];
	int L = 0;
	for (int i = 0; i < len; i++)
	{
		if (phi[i] == -1)
		{
			LCP[ra[i]] = 0;
			continue;
		}
		while (L < len && s[i + L] == s[phi[i] + L]) L++;
		int TL = min(nearest[i] - i, L);
		LCP[ra[i]] = TL;
		L = max(L - 1, 0);
	}
}

int occ[maxNO], mxv[maxN], ans[maxN];
ll fans[maxN];

void qry(int k)//n: atleast n string has the LCS , prequisite:  computeLCP
{
	set<pair<int, int> >box, box2;
	memset(occ, 0, sizeof(occ));
	int distinct_cnt = 0;
	for (int i = 0; i < len; i++)
	{
		distinct_cnt += !occ[belong[sa[i]]];
		occ[belong[sa[i]]]++;
		box.insert(m_p(LCP[i], i));
		while (distinct_cnt == k)
		{
			int pos = i - box.size() + 1;
			box.erase(m_p(LCP[pos], pos));
			mxv[pos] = box.begin()->first;
			occ[belong[sa[pos]]]--;
			distinct_cnt -= !occ[belong[sa[pos]]];
		}
	}
	box.clear();
	memset(occ, 0, sizeof(occ));
	distinct_cnt = 0;
	int lastout = -1;

	for (int i = 0; i < len; i++)
	{
		distinct_cnt += !occ[belong[sa[i]]];
		occ[belong[sa[i]]]++;
		box.insert(m_p(LCP[i], i));
		box2.insert(m_p(-mxv[i], i));
		ans[i] = -box2.begin()->first;
		while (distinct_cnt == k)
		{
			int pos = i - box.size() + 1;
			occ[belong[sa[pos]]]--;
			distinct_cnt -= !occ[belong[sa[pos]]];
			box.erase(m_p(LCP[pos], pos));
			box2.erase(m_p(-mxv[pos], pos));
			lastout = pos;
		}
		if(lastout!=-1) ans[i] = max(ans[i], box.begin()->first);
	}
	for (int i = 0; i < len; i++) fans[belong[sa[i]]] += ans[i];

}
char ss[maxN];
int main()
{
	int n, k;
	scanf("%d %d", &n, &k);
	for (int i = 1; i <= n; i++)
	{
		scanf("%s", ss);
		slen[i] = strlen(ss);
		start[i] = len;
		s += ss;
		s += "&";
		len += slen[i] + 1;
		if (k == 1) cout << (slen[i] * ((ll)(slen[i] + 1)) / 2) << " ";
	}
	if (k == 1)
	{
		cout << endl;
		exit(0);
	}
	mapstring(n, '&');
	buildsa();
	computeLCP();
	qry(k);

	for (int i = 1; i <= n; i++) printf("%I64d ", fans[i]);
	cout << endl;
}


#include<bits/stdc++.h>
using namespace std;

/// c vector< vector< int > > contains information about
/// rank. i th element in the k th vector contains information
/// about the substring of length 2^k at index i

vector< vector< int > >c;
vector<int>sort_cyclic_shifts(string const& s)
{
    int n = s.size();
    const int alphabet = 256;

    vector<int> p(n), cnt(alphabet, 0);

    c.clear();
    c.emplace_back();
    c[0].resize(n);

    for (int i = 0; i < n; i++)
        cnt[s[i]]++;
    for (int i = 1; i < alphabet; i++)
        cnt[i] += cnt[i-1];
    for (int i = 0; i < n; i++)
        p[--cnt[s[i]]] = i;
    c[0][p[0]] = 0;
    int classes = 1;
    for (int i = 1; i < n; i++) {
        if (s[p[i]] != s[p[i-1]])
            classes++;
        c[0][p[i]] = classes - 1;
    }

    vector<int> pn(n), cn(n);
    cnt.resize(n);

    for (int h = 0; (1 << h) < n; ++h) {
        for (int i = 0; i < n; i++) {
            pn[i] = p[i] - (1 << h);
            if (pn[i] < 0)
                pn[i] += n;
        }
        fill(cnt.begin(), cnt.end(), 0);

        /// radix sort
        for (int i = 0; i < n; i++)
            cnt[c[h][pn[i]]]++;
        for (int i = 1; i < classes; i++)
            cnt[i] += cnt[i-1];
        for (int i = n-1; i >= 0; i--)
            p[--cnt[c[h][pn[i]]]] = pn[i];

        cn[p[0]] = 0;
        classes = 1;
        for (int i = 1; i < n; i++) {
            pair<int, int> cur = {c[h][p[i]], c[h][(p[i] + (1 << h)) % n]};
            pair<int, int> prev = {c[h][p[i-1]], c[h][(p[i-1] + (1 << h)) % n]};
            if (cur != prev)
                ++classes;
            cn[p[i]] = classes - 1;
        }
        c.push_back(cn);
    }

    return p;
}

vector<int> suffix_array_construction(string s)
{
    s += "!";
    vector<int> sorted_shifts = sort_cyclic_shifts(s);
    sorted_shifts.erase(sorted_shifts.begin());
    return sorted_shifts;
}

/// compare two suffixes starting at i and j with length l
/// k = floor(log2(l))
/// n = string length

int compare(int i, int j, int n, int k)
{
    pair<int, int> a = {c[k][i], c[k][(i+1-(1 << k))%n]};
    pair<int, int> b = {c[k][j], c[k][(j+1-(1 << k))%n]};
    return a == b ? 0 : a < b ? -1 : 1;
}

int lcp(int i, int j)
{
    int log_n = c.size()-1;

    int ans = 0;
    for (int k = log_n; k >= 0; k--) {
        if (c[k][i] == c[k][j]) {
            ans += 1 << k;
            i += 1 << k;
            j += 1 << k;
        }
    }
    return ans;
}

/*
    We will compute the longest common prefix for each pair of
    adjacent suffixes in the sorted order. In other words we
    construct an array lcp[0…n−2], where lcp[i] is equal to
    the length of the longest common prefix of the suffixes
    starting at p[i] and p[i+1]. This array will give us an
    answer for any two adjacent suffixes of the string. Then
    the answer for arbitrary two suffixes, not necessarily
    neighboring ones, can be obtained from this array. In fact,
    let the request be to compute the LCP of the suffixes p[i]
    and p[j]. Then the answer to this query will be
    min{lcp[p[i]], lcp[p[i+1]], …, lcp[p[j−1]]}
*/

vector<int> lcp_construction(string const& s, vector<int> const& p)
{
    int n = s.size();
    vector<int> rank(n, 0);
    for (int i = 0; i < n; i++)
        rank[p[i]] = i;

    int k = 0;
    vector<int> lcp(n-1, 0);
    for (int i = 0; i < n; i++) {
        if (rank[i] == n - 1) {
            k = 0;
            continue;
        }
        int j = p[rank[i] + 1];
        while (i + k < n && j + k < n && s[i+k] == s[j+k])
            k++;
        lcp[rank[i]] = k;
        if (k)
            k--;
    }
    return lcp;
}

const int MAX = 200500;

int lg[MAX+5];

void pre()
{
    for (int i = 2; i <= MAX; i++) {
        lg[i] = lg[i-1];
        if (__builtin_popcount(i)==1) lg[i]++;
    }
}

struct RMQ{
    int N;
    vector< int >v[20];
    RMQ(const vector< int >&a) {
        N = a.size();
        v[0].resize(N);
        for (int i = 0; i < N; i++)
            v[0][i] = a[i];

        for (int k = 0; (1<<(k+1)) <= N; k++) {
            v[k+1].resize(N);
            for (int i = 0; i-1+(1<<(k+1)) < N; i++) {
                v[k+1][i] = min(v[k][i], v[k][i+(1<<k)]);
            }
        }
    }

    int findMin(int i, int j) {
        int k = j-i+1;
        k = lg[k];
        return min(v[k][i], v[k][j+1-(1<<k)]);
    }
};

int len[MAX];
int from[MAX];
int pos[MAX];

int cnt[MAX];

typedef long long LL;
typedef pair< int , int >PII;

vector< int >enter[MAX];
vector< int >eexit[MAX];

LL ans[MAX];
int vl[MAX];

int main()
{
    std::ios_base::sync_with_stdio(false);

    pre();
    int N, K;
    cin >> N >> K;

    string s;

    int sz = 0;
    for (int i = 0; i < N; i++) {
        string t;
        cin >> t;
        if (i) {
            s += "#";
            from[sz++] = -1;
        }
        s += t;
        len[i] = t.size();
        for (int j = 0; j < t.size(); j++) {
            from[sz] = i;
            pos[sz] = j;
            sz++;
        }
    }

    if (K==1) {
        for (int i = 0; i < N; i++) {
            LL x = len[i];
            x = (x*(x+1))/2;
            cout << x << " ";
        }
        cout << endl;
        return 0;
    }

//    cout << s << endl;

    vector< int >p = suffix_array_construction(s);
    vector< int >lcp = lcp_construction(s, p);
    RMQ lcprmq(lcp);

//    cout << "SA: ";
//    for (int x : p) cout << x << " ";
//    cout << endl;
//    cout << "SA: ";
//    for (int x : p) cout << from[x] << " ";
//    cout << endl;
//    cout << "LCP: ";
//    for (int x : lcp) cout << x << " ";
//    cout << endl;

    set< int >st;
    int L = 0;
    for (int R = 0; R < p.size(); R++) {
        if (from[p[R]]==-1) {
            L++;
            continue;
        }
        st.insert(from[p[R]]);
        cnt[from[p[R]]]++;

        if (st.size() > K) {
            while (L < R) {
                --cnt[from[p[L]]];
                if (cnt[from[p[L]]] == 0) {
                    st.erase(from[p[L]]);
                    L++;
                    break;
                }
                L++;
            }
        }

        while (L < R && cnt[from[p[L]]] > 1) {
            --cnt[from[p[L]]];
            L++;
        }

        if (st.size()==K) {
            assert(L < R);
            int x = lcprmq.findMin(L, R-1);
//            cout << "from " << L << " to " << R << " found " << x << endl;
            enter[L].push_back(x);
            eexit[R].push_back(x);
        }
    }

    multiset< int >mset;

    for (int i = 0; i < p.size(); i++) {
        int id = from[p[i]];
        if (id==-1) continue;

        for (int x : enter[i]) mset.insert(x);

        int x = 0;
        if (!mset.empty()) {
            auto it = mset.end();
            it--;
            x = *it;
        }
        x = min(x, len[id]-pos[p[i]]);

        vl[i] = x;

//        cout << i << " -> " << x << " for " << pos[p[i]] << " from " << from[p[i]] << endl;

        for (int x : eexit[i]) {
            auto it = mset.find(x);
            assert(it!=mset.end());
            mset.erase(it);
        }
    }

    for (int i = 0; i < p.size(); i++) {
        enter[i].clear();
        eexit[i].clear();
    }

    st.clear();
    memset(cnt, 0, sizeof cnt);
    int R = p.size()-1;
    for (int L = p.size()-1; L >= 0; L--) {
        if (from[p[R]]==-1) {
            break;
        }
        st.insert(from[p[L]]);
        cnt[from[p[L]]]++;

        if (st.size() > K) {
            while (L < R) {
                --cnt[from[p[R]]];
                if (cnt[from[p[R]]] == 0) {
                    st.erase(from[p[R]]);
                    R--;
                    break;
                }
                R--;
            }
        }

        while (L < R && cnt[from[p[R]]] > 1) {
            --cnt[from[p[R]]];
            R--;
        }

        if (st.size()==K) {
            assert(L < R);
            int x = lcprmq.findMin(L, R-1);
//            cout << "from " << L << " to " << R << " found " << x << endl;
            enter[R].push_back(x);
            eexit[L].push_back(x);
        }
    }

    mset.clear();

    for (int i = p.size()-1; i >= 0; i--) {
        int id = from[p[i]];
        if (id==-1) break;

        for (int x : enter[i]) mset.insert(x);

        int x = 0;
        if (!mset.empty()) {
            auto it = mset.end();
            it--;
            x = *it;
        }
        x = min(x, len[id]-pos[p[i]]);

        vl[i] = max(vl[i], x);
        ans[id] += vl[i];

//        cout << i << " -> " << x << " for " << pos[p[i]] << " from " << from[p[i]] << endl;

        for (int x : eexit[i]) {
            auto it = mset.find(x);
            assert(it!=mset.end());
            mset.erase(it);
        }
    }

    for (int i = 0; i < N; i++) cout << ans[i] << " ";
    cout << endl;

    return 0;
}


#include <bits/stdc++.h>
#define ll long long
const int MAXN=2e5+10;
using namespace std;
typedef struct node{
    int l,r,sum;
}node;
node d[MAXN*25];
int cnt;
char str[MAXN];char str1[MAXN];
int sa[MAXN],txt[MAXN],rank1[MAXN],rank2[MAXN],td[MAXN],t1[MAXN],t2[MAXN];
int n,k;
bool cmp(int f[],int w,int m,int k){return f[w]==f[m]&&f[w+k]==f[m+k];}
void Sa(){
    int len=strlen(str);int m=128;
    int *td=t1;int *rank1=t2;
    for(int i=0;i<m;i++)txt[i]=0;
    for(int i=0;i<len;i++)rank1[i]=str[i],txt[str[i]]++;
    for(int i=1;i<m;i++)txt[i]+=txt[i-1];
    for(int i=len-1;i>=0;i--)sa[--txt[str[i]]]=i;
    for(int k=1;k<=len;k*=2){
	int p=0;
	for(int i=len-k;i<len;i++)td[p++]=i;
	for(int i=0;i<len;i++)if(sa[i]>=k)td[p++]=sa[i]-k;
	for(int i=0;i<m;i++)txt[i]=0;
	for(int i=0;i<len;i++)txt[rank1[i]]++;
	for(int i=1;i<m;i++)txt[i]+=txt[i-1];
	for(int i=len-1;i>=0;i--)sa[--txt[rank1[td[i]]]]=td[i];
	swap(rank1,td);rank1[sa[0]]=0;p=1;
	for(int i=1;i<len;i++)rank1[sa[i]]=cmp(td,sa[i],sa[i-1],k)?p-1:p++;
	if(p==len)return ;
	m=p;
    }
}
int h[MAXN],H[MAXN];
void hh(){
    int len=strlen(str);
    for(int i=0;i<len;i++)rank2[sa[i]]=i;
    memset(H,0,sizeof(H));
    for(int i=0;i<len;i++){
	if(rank2[i]==0)continue;
	int t=sa[rank2[i]-1];int w=i;int k;
	if(i==0||H[i-1]<=1)k=0;
	else k=H[i-1]-1,t+=k,w+=k;
	while(t<len&&w<len){
	    if(str[t]==str[w])k++;
	    else break;
	    t++;w++;
	}
	H[i]=k;h[rank2[i]]=k;
    }
}
int dp[MAXN][21],mu[21],ma[MAXN];
void st(int len){
    mu[0]=1;
    for(int i=1;i<21;i++)mu[i]=mu[i-1]<<1;
    ma[0]=-1;
    for(int i=1;i<len;i++){
	if((i&(i-1))==0)ma[i]=ma[i-1]+1;
	else ma[i]=ma[i-1];
    }
   // for(int i=1;i<len;i++)
    for(int i=1;i<len;i++)dp[i][0]=h[i];
    for(int j=1;mu[j]<=len;j++){
	for(int i=1;i+mu[j]<=len;i++){
	    dp[i][j]=min(dp[i][j-1],dp[i+mu[j-1]][j-1]);
	}
    }
}
int rmq(int l,int r){
    int k=ma[r-l+1];
  //  cout<<l<<" "<<r<<" "<<k<<" "<<dp[l][k]<<" "<<dp[r-mu[k]+1][k]<<endl;
    return min(dp[l][k],dp[r-mu[k]+1][k]);
}
void update(int &x,int y,int l,int r,int t,int vul){
    x=++cnt;d[x]=d[y];d[x].sum+=vul;
    if(l==r)return ;
    int mid=(l+r)>>1;
    if(t<=mid)update(d[x].l,d[y].l,l,mid,t,vul);
    else update(d[x].r,d[y].r,mid+1,r,t,vul);
}
int ans;
void querty(int x,int l,int r,int ql,int qr){
    if(ql<=l&&r<=qr){ans+=d[x].sum;return ;}
    int mid=(l+r)>>1;
    if(ql<=mid)querty(d[x].l,l,mid,ql,qr);
    if(qr>mid)querty(d[x].r,mid+1,r,ql,qr);
}
int vis[MAXN],length[MAXN],pos[MAXN],rt[MAXN];
ll sum[MAXN];
bool check(int t,int p,int len){
    int l=1;int r=p;int ans1=p+1;
    while(l<=r){
	int mid=(l+r)>>1;
//	cout<<mid<<" "<<p<<"====="<<rmq(mid,p)<<endl;
	if(rmq(mid,p)>=t)ans1=mid,r=mid-1;
	else l=mid+1;
    }
    //if(ans1!=p+1)ans1--;
    ans1--;
    //if(ans1<0)ans1=0;
    l=p+1;r=len-1;int ans2=p;
    while(l<=r){
	int mid=(l+r)>>1;
//	cout<<p+1<<"===="<<mid<<" "<<rmq(p+1,mid)<<endl;
	if(rmq(p+1,mid)>=t)ans2=mid,l=mid+1;
	else r=mid-1;
    }
  //  cout<<ans1<<"----===="<<ans2<<" "<<t<<endl;
    ans=0;querty(rt[ans2],1,len,ans1,ans2);
  //  cout<<ans<<endl;
    if(ans>=k)return true;
    return false;
}
void solve(){
    int len=strlen(str);
    for(int i=1;i<len;i++){
	if(!vis[sa[i]])continue;
	int t1=pos[sa[i]];int l=0;int r=length[vis[sa[i]]]-t1;
	int ans1=0;
//	cout<<i<<" "<<l<<" "<<r<<" "<<vis[sa[i]]<<endl;
	while(l<=r){
	    int mid=(l+r)>>1;
	    if(check(mid,i,len))ans1=mid,l=mid+1;
	    else r=mid-1;
	}
//	cout<<ans1<<endl;
	sum[vis[sa[i]]]+=1ll*ans1;
    }
}
int pre[MAXN];
int main(){
    scanf("%d%d",&n,&k);
    int len=0;
    for(int i=1;i<=n;i++){
	scanf("%s",str1);int len1=strlen(str1);length[i]=len1;
	for(int j=0;j<len1;j++)vis[len]=i,pos[len]=j,str[len++]=str1[j];
	vis[len]=0,pos[len]=0;str[len++]='$';
    }
    Sa();hh();st(len);
 //   cout<<len<<endl;
 //   cout<<str<<endl;
//    for(int i=1;i<len;i++)cout<<h[i]<<" ";
 //   cout<<endl;
    for(int i=1;i<len;i++){
	if(!vis[sa[i]]){rt[i]=rt[i-1];continue;}
//	cout<<pre[vis[sa[i]]]<<" ";
	update(rt[i],rt[i-1],1,len,i,1);
	if(pre[vis[sa[i]]])update(rt[i],rt[i],1,len,pre[vis[sa[i]]],-1);
	pre[vis[sa[i]]]=i;
    }
  //  cout<<endl;
    solve();
    for(int i=1;i<=n;i++)printf("%lld ",sum[i]);
    puts("");
}


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

typedef long long ll;

const int INF = 1000000000;

vector< vector<int> > st;
vector<int> pot;

void SuffixArray(vector<int> a, vector<int>& sa, vector<int>& lcp, int p)
{
    int n = a.size();
    vector< vector<int> > kmr(p + 1);
    vector< pair<int, int> > pod;
    for (int i = 0; i < n; ++i)
    {
        pod.push_back(make_pair(a[i], i));
        kmr[0].push_back(-1);
    }
    sort(pod.begin(), pod.end());
    int nr = 0;
    for (int i = 0; i < n; ++i)
    {
        if (i != 0 && pod[i].first != pod[i - 1].first)
            ++nr;
        kmr[0][pod[i].second] = nr;
    }
    for (int i = 1; i <= p; ++i)
    {
        vector< pair< pair<int, int>, int > > pod;
        for (int j = 0; j + (1 << i) - 1 < n; ++j)
        {
            pod.push_back(make_pair(make_pair(kmr[i - 1][j], kmr[i - 1][j + (1 << (i - 1))]), j));
            kmr[i].push_back(-1);
        }
        sort(pod.begin(), pod.end());
        int nr = 0;
        for (int j = 0; j < pod.size(); ++j)
        {
            if (j != 0 && (pod[j].first.first != pod[j - 1].first.first || pod[j].first.second != pod[j - 1].first.second))
                ++nr;
            kmr[i][pod[j].second] = nr;
        }
    }
    sa = kmr[p];
    n = sa.size();
    vector<int> gdzie(n);
    for (int i = 0; i < n; ++i)
        gdzie[sa[i]] = i;
    for (int i = 0; i < n; ++i)
    {
        if (sa[i] == n - 1)
            continue;
        int l = 0;
        if (i != 0 && sa[i - 1] != n - 1)
            l = max(0, lcp[sa[i - 1]] - 1);
        while (l < n && a[i + l] == a[gdzie[sa[i] + 1] + l])
            ++l;
        lcp[sa[i]] = l;
    }
}

void SparseTable(vector<int> a)
{
    int n = a.size();
    pot.push_back(-1);
    for (int i = 1; i <= n; ++i)
    {
        int p = 0;
        while ((1 << p) <= i)
            ++p;
        --p;
        pot.push_back(p);
    }
    vector<int> t;
    for (int i = 0; i <= pot[n]; ++i)
    {
        st.push_back(t);
        if (i == 0)
        {
            for (int j = 0; j < n; ++j)
                st[0].push_back(a[j]);
        }
        else
        {
            for (int j = 0; j + (1 << i) - 1 < n; ++j)
                st[i].push_back(min(st[i - 1][j], st[i - 1][j + (1 << (i - 1))]));
        }
    }
}

int Min(int l, int p)
{
    int dl = p - l + 1;
    return min(st[pot[dl]][l], st[pot[dl]][p - (1 << pot[dl]) + 1]);
}

int SzukajP(vector<int>& a, int l, int p, int x)
{
    int pocz = l;
    int s, r = -1;
    while (l <= p)
    {
        s = (l + p) / 2;
        if (Min(pocz, s) >= x)
        {
            r = s;
            l = s + 1;
        }
        else
            p = s - 1;
    }
    return r;
}

int SzukajL(vector<int>& a, int l, int p, int x)
{
    int kon = p;
    int s, r = -1;
    while (l <= p)
    {
        s = (l + p) / 2;
        if (Min(s, kon) >= x)
        {
            r = s;
            p = s - 1;
        }
        else
            l = s + 1;
    }
    return r;
}

bool Spr(vector<int>& lcp, int pos, vector<int>& pocz, int dl, int k, int pierwszy)
{
    if (dl == 0)
        return true;
    int ll = -1, lp = -1, pl = -1, pp = -1;
    pl = pos;
    pp = SzukajP(lcp, pl, lcp.size() - 1, dl);
    if (pos > 0)
    {
        lp = pos - 1;
        ll = SzukajL(lcp, 0, lp, dl);
    }
    int L = -1, P = -1;
    if (ll != -1)
        L = ll, P = lp;
    if (pp != -1)
    {
        if (L == -1)
            L = pl;
        P = pp;
    }
    if (L == -1)
        return k == 1;
    else
        return (pierwszy != -1 && P + 1 >= pierwszy && L <= pocz[P + 1]);
}

int main()
{
    ios_base::sync_with_stdio(0);
    int n, k;
    cin >> n >> k;
    vector<int> a;
    a.push_back(30);
    for (int i = 0; i < n; ++i)
    {
        string x;
        cin >> x;
        for (int j = 0; j < x.size(); ++j)
            a.push_back(x[j] - 'a');
        a.push_back(31 + i);
    }
    int N = a.size();
    vector<int> sa(N), lcp(N - 1);
    int p = 0;
    while ((1 << p) < N)
        ++p;
    for (int i = 0; i < (1 << p) - 1; ++i)
        a.push_back(INF);
    SuffixArray(a, sa, lcp, p);
    SparseTable(lcp);
    vector<int> ktoreSlowo(N);
    int nrSlowa = -1;
    for (int i = 0; i < N; ++i)
    {
        if (a[i] >= 30)
        {
            ++nrSlowa;
            ktoreSlowo[sa[i]] = n;
        }
        else
            ktoreSlowo[sa[i]] = nrSlowa;
    }
    vector<int> pocz(N);
    vector<int> wyst(n + 1, 0);
    int il = 0, pierwszy = -1;
    pocz[0] = 0;
    wyst[ktoreSlowo[0]] = 1;
    il = 1;
    if (il == k)
        pierwszy = 0;
    for (int i = 1; i < N; ++i)
    {
        ++wyst[ktoreSlowo[i]];
        if (wyst[ktoreSlowo[i]] == 1)
            ++il;
        if (il == k && pierwszy == -1)
            pierwszy = i;
        pocz[i] = pocz[i - 1];
        if (il >= k)
        {
            while (il >= k)
            {
                --wyst[ktoreSlowo[pocz[i]]];
                if (wyst[ktoreSlowo[pocz[i]]] == 0)
                    --il;
                ++pocz[i];
            }
            --pocz[i];
            ++wyst[ktoreSlowo[pocz[i]]];
            ++il;
        }
    }
    vector<ll> odp(n, 0);
    nrSlowa = n;
    int dlSuf;
    for (int i = N - 1; i >= 0; --i)
    {
        if (a[i] >= 30)
        {
            --nrSlowa;
            dlSuf = 0;
            continue;
        }
        ++dlSuf;
        int l = 0, p = dlSuf, s, r = -1;
        while (l <= p)
        {
            s = (l + p) / 2;
            if (Spr(lcp, sa[i], pocz, s, k, pierwszy))
            {
                r = s;
                l = s + 1;
            }
            else
                p = s - 1;
        }
        odp[nrSlowa] += r;
    }
    for (int i = 0; i < n; ++i)
        cout << odp[i] << " ";
    return 0;
}


#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=400010;
int N,K,L,times; string s[maxn];
struct SAM
{
    int np,p,nq,q,Last,cnt,cur[maxn],sum[maxn];
    int maxlen[maxn],fa[maxn],ch[maxn][26];
    SAM(){ Last=cnt=1; }
    void add(int x){
        np=++cnt; p=Last; Last=np; maxlen[np]=maxlen[p]+1;
        while(p&&!ch[p][x]) ch[p][x]=np,p=fa[p];
        if(!p) fa[np]=1;
        else{
            q=ch[p][x];
            if(maxlen[q]==maxlen[p]+1) fa[np]=q;
            else{
                nq=++cnt;
                memcpy(ch[nq],ch[q],sizeof(ch[nq]));
                cur[nq]=cur[q]; sum[nq]=sum[q];
                fa[nq]=fa[q];  fa[np]=fa[q]=nq;maxlen[nq]=maxlen[p]+1;
                while(p&&ch[p][x]==q) ch[p][x]=nq,p=fa[p];
            }
        }
        while(np){
            if(cur[np]==times||sum[np]>=K)  break;
            sum[np]++; cur[np]=times; np=fa[np];
        }
    }
    void sort()
    {

    }
    void solve(int now)
    {
        int tp=1;long long ans=0; L=s[now].length();
        for(int i=0;i<L;i++) {
            tp=ch[tp][s[now][i]-'a'];
            int kkk=tp;
            while(kkk>1){
               if(sum[kkk]>=K){ ans+=maxlen[kkk]; break; }
               kkk=fa[kkk];
            }
        }
        printf("%lld ",ans);
    }
}sam;
int main()
{
    scanf("%d%d",&N,&K);
    for(int i=1;i<=N;i++){
        cin>>s[i];
        L=s[i].length(); sam.Last=1; times=i;
        for(int j=0;j<L;j++) sam.add(s[i][j]-'a');
    }
    if(K>N){
        for(int i=1;i<=N;i++) printf("0 ");
        return 0;
    }
    sam.sort();
    for(int i=1;i<=N;i++) sam.solve(i);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 220000;
int wa[N], wb[N], wc[N], wd[N], sa[N], rnk[N], lcp[N], dp[N][22], pw2[22], rem[N], pos[N], nxt[N];
bool is_equal(int *r, int a, int b, int l, int n) {
	int la = r[a], lb = r[b], ra, rb;
	ra = a + l < n ? r[a + l] : -1;
	rb = b + l < n ? r[b + l] : -1;
	return (la == lb) && (ra == rb);
}

void build_suffix_array(string r, int *sa, int n, int m) {
	int *x = wa, *y = wb;
	int i, tot, p;
	memset(wc, 0, sizeof(int) * m);
	for (i = 0; i < n; i++) wc[x[i] = r[i]]++;
	for (i = 1; i < m; i++) wc[i] += wc[i - 1];
	for (i = n - 1; i >= 0; i--) sa[--wc[x[i]]] = i;
	for (tot = 0, p = 1; tot + 1 < n; p <<= 1, m = tot + 1) {
		for (tot = 0, i = n - p; i < n; i++) y[tot++] = i;
		for (i = 0; i < n; i++) if (sa[i] >= p) y[tot++] = sa[i] - p;
		for (i = 0; i < n; i++) wd[i] = x[y[i]];
		memset(wc, 0, sizeof(int) * m);
		for (i = 0; i < n; i++) wc[wd[i]]++;
		for (i = 1; i < m; i++) wc[i] += wc[i - 1];
		for (i = n - 1; i >= 0; i--) sa[--wc[wd[i]]] = y[i];
		swap(x, y);
		x[sa[0]] = tot = 0;
		for (i = 1; i < n; i++) x[sa[i]] = is_equal(y, sa[i - 1], sa[i], p, n) ? tot : ++tot;
	}
}
void build_lcp(string r, int *sa, int *lcp, int n) {
	int i;
	for (i = 0; i < n; i++) rnk[sa[i]] = i;
	for (lcp[0] = i = 0; i < n; i++) if (rnk[i]) {
		lcp[rnk[i]] = (i == 0) ? 0 : max(0, lcp[rnk[i - 1]] - 1);
		for ( ; r[i + lcp[rnk[i]]] == r[sa[rnk[i] - 1] + lcp[rnk[i]]];
		lcp[rnk[i]]++);
	}
	for (int i = 1; i < n; i++) dp[i][0] = lcp[i];
	pw2[0] = 1;
	for (int j = 1; j < 22; j++) {
		pw2[j] = pw2[j - 1] * 2;
		for (int i = 1; i + pw2[j] - 1 < n; i++) dp[i][j] = min(dp[i][j - 1], dp[i + pw2[j - 1]][j - 1]);
	}
}

int get_lcp(int i, int j) {
	int ri = i, rj = j;
	int lim = min(rem[sa[i]], rem[sa[j]]);
	if (ri == rj) return lim;
	if (ri > rj) swap(ri, rj);
	ri++;
	int p = 31 - __builtin_clz(rj - ri + 1);
	return min(lim, min(dp[ri][p], dp[rj - pw2[p] + 1][p]));
}
int find1(int p, int lo, int hi, int len_c) {
	int mid;
	while (lo < hi) {
		mid = lo + hi >> 1;
		if (get_lcp(p, mid) >= len_c) hi = mid;
		else lo = mid + 1;
	}
	return hi;
}
int find2(int p, int lo, int hi, int len_c) {
	int mid;
	while (lo < hi) {
		mid = lo + hi + 1 >> 1;
		if (get_lcp(p, mid) >= len_c) lo = mid;
		else hi = mid - 1;
	}
	return lo;
}

string s[N], T;
int a[N], sum[N], len[N], cnt[N];
int main() {
	//freopen("in.txt", "r", stdin);
	int n, k; scanf("%d%d", &n, &k);
	for (int i = 1; i <= n; i++) {
		cin>>s[i];
		s[i].push_back('$');
		len[i] = s[i].length();
		sum[i] = sum[i - 1] + len[i];
		T += s[i];
	}
	int cur = 0;
	for (int i = 1; i <= n; i++) {
		for (int j = cur; j < cur + len[i]; j++) pos[j] = i, rem[j] = len[i] - (j - cur);
		cur += len[i];
	}
	int len_T = T.length();
	build_suffix_array(T, sa, len_T, 256);
	build_lcp(T, sa, lcp, len_T);
	for (int i = 0; i < len_T; i++) {
		int cur = sa[i];
		a[i] = pos[cur];
	}
	cur = 1;
	cnt[a[0]]++;
	for (int i = 0, j = 0; i < len_T; i++) {
		if (j == len_T) {
			nxt[i] = j;
			continue;
		}

		if (i) {
			cnt[a[i - 1]]--;
			if (!cnt[a[i - 1]]) cur--;
		}
		for (j++; j <= len_T; j++) {
			if (cur == k) break;
			cnt[a[j]]++;
			if (cnt[a[j]] == 1) cur++;
		}
		j--;
		nxt[i] = j;
	}
	for (int i = 1; i <= n; i++) {
		long long ans = 0;
		for (int j = 0, k = 0; j < len[i] - 1; j++) {
			k = max(j, k);
			for (; k < len[i] - 1; k++) {
				int p = rnk[sum[i - 1] + j];
				int lo = find1(p, 0, p, k - j + 1);
				int hi = find2(p, p, len_T - 1, k - j + 1);
				if (nxt[lo] > hi) break;
			}
			k--;
			ans += (k - j + 1);
		}
		printf("%d ", ans);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 110000;
int wa[N], wb[N], wc[N], wd[N], sa[N], rnk[N], lcp[N], dp[N][22], pw2[22], rem[N], pos[N], nxt[N];
bool is_equal(int *r, int a, int b, int l, int n) {
	int la = r[a], lb = r[b], ra, rb;
	ra = a + l < n ? r[a + l] : -1;
	rb = b + l < n ? r[b + l] : -1;
	return (la == lb) && (ra == rb);
}

void build_suffix_array(string r, int *sa, int n, int m) {
	int *x = wa, *y = wb;
	int i, tot, p;
	memset(wc, 0, sizeof(int) * m);
	for (i = 0; i < n; i++) wc[x[i] = r[i]]++;
	for (i = 1; i < m; i++) wc[i] += wc[i - 1];
	for (i = n - 1; i >= 0; i--) sa[--wc[x[i]]] = i;
	for (tot = 0, p = 1; tot + 1 < n; p <<= 1, m = tot + 1) {
		for (tot = 0, i = n - p; i < n; i++) y[tot++] = i;
		for (i = 0; i < n; i++) if (sa[i] >= p) y[tot++] = sa[i] - p;
		for (i = 0; i < n; i++) wd[i] = x[y[i]];
		memset(wc, 0, sizeof(int) * m);
		for (i = 0; i < n; i++) wc[wd[i]]++;
		for (i = 1; i < m; i++) wc[i] += wc[i - 1];
		for (i = n - 1; i >= 0; i--) sa[--wc[wd[i]]] = y[i];
		swap(x, y);
		x[sa[0]] = tot = 0;
		for (i = 1; i < n; i++) x[sa[i]] = is_equal(y, sa[i - 1], sa[i], p, n) ? tot : ++tot;
	}
}
void build_lcp(string r, int *sa, int *lcp, int n) {
	int i;
	for (i = 0; i < n; i++) rnk[sa[i]] = i;
	for (lcp[0] = i = 0; i < n; i++) if (rnk[i]) {
		lcp[rnk[i]] = (i == 0) ? 0 : max(0, lcp[rnk[i - 1]] - 1);
		for ( ; r[i + lcp[rnk[i]]] == r[sa[rnk[i] - 1] + lcp[rnk[i]]];
		lcp[rnk[i]]++);
	}
	for (int i = 1; i < n; i++) dp[i][0] = lcp[i];
	pw2[0] = 1;
	for (int j = 1; j < 22; j++) {
		pw2[j] = pw2[j - 1] * 2;
		for (int i = 1; i + pw2[j] - 1 < n; i++) dp[i][j] = min(dp[i][j - 1], dp[i + pw2[j - 1]][j - 1]);
	}
}

int get_lcp(int i, int j) {
	int ri = i, rj = j;
	int lim = min(rem[sa[i]], rem[sa[j]]);
	if (ri == rj) return lim;
	if (ri > rj) swap(ri, rj);
	ri++;
	int p = 31 - __builtin_clz(rj - ri + 1);
	return min(lim, min(dp[ri][p], dp[rj - pw2[p] + 1][p]));
}
int find1(int p, int lo, int hi, int len_c) {
	int mid;
	while (lo < hi) {
		mid = lo + hi >> 1;
		if (get_lcp(p, mid) >= len_c) hi = mid;
		else lo = mid + 1;
	}
	return hi;
}
int find2(int p, int lo, int hi, int len_c) {
	int mid;
	while (lo < hi) {
		mid = lo + hi + 1 >> 1;
		if (get_lcp(p, mid) >= len_c) lo = mid;
		else hi = mid - 1;
	}
	return lo;
}

string s[N], T;
int a[N], sum[N], len[N], cnt[N];
int main() {
	int n, k; scanf("%d%d", &n, &k);
	for (int i = 1; i <= n; i++) {
		cin>>s[i];
		s[i].push_back('$');
		len[i] = s[i].length();
		sum[i] = sum[i - 1] + len[i];
		T += s[i];
	}
	int cur = 0;
	for (int i = 1; i <= n; i++) {
		for (int j = cur; j < cur + len[i]; j++) pos[j] = i, rem[j] = len[i] - (j - cur);
		cur += len[i];
	}
	int len_T = T.length();
	build_suffix_array(T, sa, len_T, 256);
	build_lcp(T, sa, lcp, len_T);
	for (int i = 0; i < len_T; i++) {
		int cur = sa[i];
		a[i] = pos[cur];
	}
	cnt[a[0]]++;
	cur = 1;
	for (int i = 0, j = 0; i < len_T; i++) {
		if (j == len_T) {
			nxt[i] = j;
			continue;
		}
		if (i) {
			cnt[a[i - 1]]--;
			if (!cnt[a[i - 1]]) cur--;
		}

		for (j++; j < len_T; j++) {
			if (cur == k) break;
			cnt[a[j]]++;
			if (cnt[a[j]] == 1) cur++;
		}
		j--;
		nxt[i] = j;
	}
	for (int i = 1; i <= n; i++) {
		long long ans = 0;
		for (int j = 0, k = 0; j < len[i] - 1; j++) {
			k = max(j, k);
			for (; k < len[i] - 1; k++) {
				int p = rnk[sum[i - 1] + j];
				int lo = find1(p, 0, p, k - j + 1);
				int hi = find2(p, p, len_T - 1, k - j + 1);
				if (nxt[lo] > hi) break;
			}
			k--;
			ans += (k - j + 1);
		}
		printf("%d ", ans);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 110000;
int wa[N], wb[N], wc[N], wd[N], sa[N], rnk[N], lcp[N], dp[N][22], pw2[22], rem[N], pos[N], nxt[N];
bool is_equal(int *r, int a, int b, int l, int n) {
	int la = r[a], lb = r[b], ra, rb;
	ra = a + l < n ? r[a + l] : -1;
	rb = b + l < n ? r[b + l] : -1;
	return (la == lb) && (ra == rb);
}

void build_suffix_array(string r, int *sa, int n, int m) {
	int *x = wa, *y = wb;
	int i, tot, p;
	memset(wc, 0, sizeof(int) * m);
	for (i = 0; i < n; i++) wc[x[i] = r[i]]++;
	for (i = 1; i < m; i++) wc[i] += wc[i - 1];
	for (i = n - 1; i >= 0; i--) sa[--wc[x[i]]] = i;
	for (tot = 0, p = 1; tot + 1 < n; p <<= 1, m = tot + 1) {
		for (tot = 0, i = n - p; i < n; i++) y[tot++] = i;
		for (i = 0; i < n; i++) if (sa[i] >= p) y[tot++] = sa[i] - p;
		for (i = 0; i < n; i++) wd[i] = x[y[i]];
		memset(wc, 0, sizeof(int) * m);
		for (i = 0; i < n; i++) wc[wd[i]]++;
		for (i = 1; i < m; i++) wc[i] += wc[i - 1];
		for (i = n - 1; i >= 0; i--) sa[--wc[wd[i]]] = y[i];
		swap(x, y);
		x[sa[0]] = tot = 0;
		for (i = 1; i < n; i++) x[sa[i]] = is_equal(y, sa[i - 1], sa[i], p, n) ? tot : ++tot;
	}
}
void build_lcp(string r, int *sa, int *lcp, int n) {
	int i;
	for (i = 0; i < n; i++) rnk[sa[i]] = i;
	for (lcp[0] = i = 0; i < n; i++) if (rnk[i]) {
		lcp[rnk[i]] = (i == 0) ? 0 : max(0, lcp[rnk[i - 1]] - 1);
		for ( ; r[i + lcp[rnk[i]]] == r[sa[rnk[i] - 1] + lcp[rnk[i]]];
		lcp[rnk[i]]++);
	}
	for (int i = 1; i < n; i++) dp[i][0] = lcp[i];
	pw2[0] = 1;
	for (int j = 1; j < 22; j++) {
		pw2[j] = pw2[j - 1] * 2;
		for (int i = 1; i + pw2[j] - 1 < n; i++) dp[i][j] = min(dp[i][j - 1], dp[i + pw2[j - 1]][j - 1]);
	}
}

int get_lcp(int i, int j) {
	int ri = i, rj = j;
	int lim = min(rem[sa[i]], rem[sa[j]]);
	if (ri == rj) return lim;
	if (ri > rj) swap(ri, rj);
	ri++;
	int p = 31 - __builtin_clz(rj - ri + 1);
	return min(lim, min(dp[ri][p], dp[rj - pw2[p] + 1][p]));
}
int find1(int p, int lo, int hi, int len_c) {
	int mid;
	while (lo < hi) {
		mid = lo + hi >> 1;
		if (get_lcp(p, mid) >= len_c) hi = mid;
		else lo = mid + 1;
	}
	return hi;
}
int find2(int p, int lo, int hi, int len_c) {
	int mid;
	while (lo < hi) {
		mid = lo + hi + 1 >> 1;
		if (get_lcp(p, mid) >= len_c) lo = mid;
		else hi = mid - 1;
	}
	return lo;
}

string s[N], T;
int a[N], sum[N], len[N], cnt[N];
int main() {
	//freopen("in.txt", "r", stdin);
	int n, k; scanf("%d%d", &n, &k);
	for (int i = 1; i <= n; i++) {
		cin>>s[i];
		s[i].push_back('$');
		len[i] = s[i].length();
		sum[i] = sum[i - 1] + len[i];
		T += s[i];
	}
	int cur = 0;
	for (int i = 1; i <= n; i++) {
		for (int j = cur; j < cur + len[i]; j++) pos[j] = i, rem[j] = len[i] - (j - cur);
		cur += len[i];
	}
	int len_T = T.length();
	build_suffix_array(T, sa, len_T, 256);
	build_lcp(T, sa, lcp, len_T);
	for (int i = 0; i < len_T; i++) {
		int cur = sa[i];
		a[i] = pos[cur];
	}
	cnt[a[0]]++;
	cur = 1;
	for (int i = 0, j = 0; i < len_T; i++) {
		if (i) cnt[a[i - 1]]--;
		if (!cnt[a[i - 1]]) cur--;
		for (; j < len_T; j++) {
			if (cur == k) break;
			cnt[a[j]]++;
			if (cnt[a[j]] == 1) cur++;
		}
		nxt[i] = j;
	}
	for (int i = 1; i <= n; i++) {
		long long ans = 0;
		for (int j = 0, k = 0; j < len[i] - 1; j++) {
			k = max(j, k);
			for (; k < len[i] - 1; k++) {
				int p = rnk[sum[i - 1] + j];
				int lo = find1(p, 0, p, k - j + 1);
				int hi = find2(p, p, len_T - 1, k - j + 1);
				if (nxt[lo] > hi) break;
			}
			k--;
			ans += (k - j + 1);
		}
		printf("%d ", ans);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 220000;
int wa[N], wb[N], wc[N], wd[N], sa[N], rnk[N], lcp[N], dp[N][22], pw2[22], rem[N], pos[N], nxt[N];
bool is_equal(int *r, int a, int b, int l, int n) {
	int la = r[a], lb = r[b], ra, rb;
	ra = a + l < n ? r[a + l] : -1;
	rb = b + l < n ? r[b + l] : -1;
	return (la == lb) && (ra == rb);
}

void build_suffix_array(string r, int *sa, int n, int m) {
	int *x = wa, *y = wb;
	int i, tot, p;
	memset(wc, 0, sizeof(int) * m);
	for (i = 0; i < n; i++) wc[x[i] = r[i]]++;
	for (i = 1; i < m; i++) wc[i] += wc[i - 1];
	for (i = n - 1; i >= 0; i--) sa[--wc[x[i]]] = i;
	for (tot = 0, p = 1; tot + 1 < n; p <<= 1, m = tot + 1) {
		for (tot = 0, i = n - p; i < n; i++) y[tot++] = i;
		for (i = 0; i < n; i++) if (sa[i] >= p) y[tot++] = sa[i] - p;
		for (i = 0; i < n; i++) wd[i] = x[y[i]];
		memset(wc, 0, sizeof(int) * m);
		for (i = 0; i < n; i++) wc[wd[i]]++;
		for (i = 1; i < m; i++) wc[i] += wc[i - 1];
		for (i = n - 1; i >= 0; i--) sa[--wc[wd[i]]] = y[i];
		swap(x, y);
		x[sa[0]] = tot = 0;
		for (i = 1; i < n; i++) x[sa[i]] = is_equal(y, sa[i - 1], sa[i], p, n) ? tot : ++tot;
	}
}
void build_lcp(string r, int *sa, int *lcp, int n) {
	int i;
	for (i = 0; i < n; i++) rnk[sa[i]] = i;
	for (lcp[0] = i = 0; i < n; i++) if (rnk[i]) {
		lcp[rnk[i]] = (i == 0) ? 0 : max(0, lcp[rnk[i - 1]] - 1);
		for ( ; r[i + lcp[rnk[i]]] == r[sa[rnk[i] - 1] + lcp[rnk[i]]];
		lcp[rnk[i]]++);
	}
	for (int i = 1; i < n; i++) dp[i][0] = lcp[i];
	pw2[0] = 1;
	for (int j = 1; j < 22; j++) {
		pw2[j] = pw2[j - 1] * 2;
		for (int i = 1; i + pw2[j] - 1 < n; i++) dp[i][j] = min(dp[i][j - 1], dp[i + pw2[j - 1]][j - 1]);
	}
}

int get_lcp(int i, int j) {
	int ri = i, rj = j;
	int lim = min(rem[sa[i]], rem[sa[j]]);
	if (ri == rj) return lim;
	if (ri > rj) swap(ri, rj);
	ri++;
	int p = 31 - __builtin_clz(rj - ri + 1);
	return min(lim, min(dp[ri][p], dp[rj - pw2[p] + 1][p]));
}
int find1(int p, int lo, int hi, int len_c) {
	int mid;
	while (lo < hi) {
		mid = lo + hi >> 1;
		if (get_lcp(p, mid) >= len_c) hi = mid;
		else lo = mid + 1;
	}
	return hi;
}
int find2(int p, int lo, int hi, int len_c) {
	int mid;
	while (lo < hi) {
		mid = lo + hi + 1 >> 1;
		if (get_lcp(p, mid) >= len_c) lo = mid;
		else hi = mid - 1;
	}
	return lo;
}

string s[N], T;
int a[N], sum[N], len[N], cnt[N];
int main() {
	//freopen("in.txt", "r", stdin);
	int n, k; scanf("%d%d", &n, &k);
	for (int i = 1; i <= n; i++) {
		cin>>s[i];
		s[i].push_back('$');
		len[i] = s[i].length();
		sum[i] = sum[i - 1] + len[i];
		T += s[i];
	}
	int cur = 0;
	for (int i = 1; i <= n; i++) {
		for (int j = cur; j < cur + len[i]; j++) pos[j] = i, rem[j] = len[i] - (j - cur);
		cur += len[i];
	}
	int len_T = T.length();
	build_suffix_array(T, sa, len_T, 256);
	build_lcp(T, sa, lcp, len_T);
	for (int i = 0; i < len_T; i++) {
		int cur = sa[i];
		a[i] = pos[cur];
	}
	cur = 1;
	cnt[a[0]]++;
	for (int i = 0, j = 0; i < len_T; i++) {
		if (j == len_T) {
			nxt[i] = j;
			continue;
		}

		if (i) {
			cnt[a[i - 1]]--;
			if (!cnt[a[i - 1]]) cur--;
		}
		for (j++; j <= len_T; j++) {
			if (cur == k) break;
			cnt[a[j]]++;
			if (cnt[a[j]] == 1) cur++;
		}
		j--;
		nxt[i] = j;
	}
	for (int i = 1; i <= n; i++) {
		long long ans = 0;
		for (int j = 0, k = 0; j < len[i] - 1; j++) {
			k = max(j, k);
			for (; k < len[i] - 1; k++) {
				int p = rnk[sum[i - 1] + j];
				int lo = find1(p, 0, p, k - j + 1);
				int hi = find2(p, p, len_T - 1, k - j + 1);
				if (nxt[lo] > hi) break;
			}
			k--;
			ans += (k - j + 1);
		}
		printf("%lld ", ans);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 110000;
int wa[N], wb[N], wc[N], wd[N], sa[N], rnk[N], lcp[N], dp[N][22], pw2[22], rem[N], pos[N], nxt[N];
bool is_equal(int *r, int a, int b, int l, int n) {
	int la = r[a], lb = r[b], ra, rb;
	ra = a + l < n ? r[a + l] : -1;
	rb = b + l < n ? r[b + l] : -1;
	return (la == lb) && (ra == rb);
}

void build_suffix_array(string r, int *sa, int n, int m) {
	int *x = wa, *y = wb;
	int i, tot, p;
	memset(wc, 0, sizeof(int) * m);
	for (i = 0; i < n; i++) wc[x[i] = r[i]]++;
	for (i = 1; i < m; i++) wc[i] += wc[i - 1];
	for (i = n - 1; i >= 0; i--) sa[--wc[x[i]]] = i;
	for (tot = 0, p = 1; tot + 1 < n; p <<= 1, m = tot + 1) {
		for (tot = 0, i = n - p; i < n; i++) y[tot++] = i;
		for (i = 0; i < n; i++) if (sa[i] >= p) y[tot++] = sa[i] - p;
		for (i = 0; i < n; i++) wd[i] = x[y[i]];
		memset(wc, 0, sizeof(int) * m);
		for (i = 0; i < n; i++) wc[wd[i]]++;
		for (i = 1; i < m; i++) wc[i] += wc[i - 1];
		for (i = n - 1; i >= 0; i--) sa[--wc[wd[i]]] = y[i];
		swap(x, y);
		x[sa[0]] = tot = 0;
		for (i = 1; i < n; i++) x[sa[i]] = is_equal(y, sa[i - 1], sa[i], p, n) ? tot : ++tot;
	}
}
void build_lcp(string r, int *sa, int *lcp, int n) {
	int i;
	for (i = 0; i < n; i++) rnk[sa[i]] = i;
	for (lcp[0] = i = 0; i < n; i++) if (rnk[i]) {
		lcp[rnk[i]] = (i == 0) ? 0 : max(0, lcp[rnk[i - 1]] - 1);
		for ( ; r[i + lcp[rnk[i]]] == r[sa[rnk[i] - 1] + lcp[rnk[i]]];
		lcp[rnk[i]]++);
	}
	for (int i = 1; i < n; i++) dp[i][0] = lcp[i];
	pw2[0] = 1;
	for (int j = 1; j < 22; j++) {
		pw2[j] = pw2[j - 1] * 2;
		for (int i = 1; i + pw2[j] - 1 < n; i++) dp[i][j] = min(dp[i][j - 1], dp[i + pw2[j - 1]][j - 1]);
	}
}

int get_lcp(int i, int j) {
	int ri = i, rj = j;
	int lim = min(rem[sa[i]], rem[sa[j]]);
	if (ri == rj) return lim;
	if (ri > rj) swap(ri, rj);
	ri++;
	int p = 31 - __builtin_clz(rj - ri + 1);
	return min(lim, min(dp[ri][p], dp[rj - pw2[p] + 1][p]));
}
int find1(int p, int lo, int hi, int len_c) {
	int mid;
	while (lo < hi) {
		mid = lo + hi >> 1;
		if (get_lcp(p, mid) >= len_c) hi = mid;
		else lo = mid + 1;
	}
	return hi;
}
int find2(int p, int lo, int hi, int len_c) {
	int mid;
	while (lo < hi) {
		mid = lo + hi + 1 >> 1;
		if (get_lcp(p, mid) >= len_c) lo = mid;
		else hi = mid - 1;
	}
	return lo;
}

string s[N], T;
int a[N], sum[N], len[N], cnt[N];
int main() {
	//freopen("in.txt", "r", stdin);
	int n, k; scanf("%d%d", &n, &k);
	for (int i = 1; i <= n; i++) {
		cin>>s[i];
		s[i].push_back('$');
		len[i] = s[i].length();
		sum[i] = sum[i - 1] + len[i];
		T += s[i];
	}
	int cur = 0;
	for (int i = 1; i <= n; i++) {
		for (int j = cur; j < cur + len[i]; j++) pos[j] = i, rem[j] = len[i] - (j - cur);
		cur += len[i];
	}
	int len_T = T.length();
	build_suffix_array(T, sa, len_T, 256);
	build_lcp(T, sa, lcp, len_T);
	for (int i = 0; i < len_T; i++) {
		int cur = sa[i];
		a[i] = pos[cur];
	}
	cur = 1;
	cnt[a[0]]++;
	for (int i = 0, j = 0; i < len_T; i++) {
		if (j == len_T) {
			nxt[i] = j;
			continue;
		}

		if (i) {
			cnt[a[i - 1]]--;
			if (!cnt[a[i - 1]]) cur--;
		}
		for (j++; j <= len_T; j++) {
			if (cur == k) break;
			cnt[a[j]]++;
			if (cnt[a[j]] == 1) cur++;
		}
		j--;
		nxt[i] = j;
	}
	for (int i = 1; i <= n; i++) {
		long long ans = 0;
		for (int j = 0, k = 0; j < len[i] - 1; j++) {
			k = max(j, k);
			for (; k < len[i] - 1; k++) {
				int p = rnk[sum[i - 1] + j];
				int lo = find1(p, 0, p, k - j + 1);
				int hi = find2(p, p, len_T - 1, k - j + 1);
				if (nxt[lo] > hi) break;
			}
			k--;
			ans += (k - j + 1);
		}
		printf("%d ", ans);
	}
	return 0;
}


#include <iostream>
#include <cstring>
#include <cstdio>
#include <map>
#include <cmath>
using namespace std;

#define FOR(i, l, r) for (int i = (l); i <= (r); ++i)

const int maxn = 200005;

/* Suffix Array */
template<int N>
struct SA {
    int s[N];
    /* s: [1, n] ( not [0, 0) ) */

    int n, sa[N], rk[N], ht[N];
    /* sa : sorted index of suffix */
    /* rk[i] : rank of suffix i in sa, i.e. sa[rk[i]] == i */
    /* ht[i] : lcp{ sa[i-1], sa[i] } */

    // aux arrays
    int oldrk[N << 1], id[N], px[N], cnt[N];

    bool cmp(int x, int y, int w) {
        return oldrk[x] == oldrk[y] && oldrk[x + w] == oldrk[y + w];
    }

    void build_sa(int n /*the length of s*/, int m /* the domain of s */) {
        int i, k, p, w;

        this -> n = n;
        for (i = 1; i <= n; ++i) ++cnt[rk[i] = s[i]];
        for (i = 1; i <= m; ++i) cnt[i] += cnt[i - 1];
        for (i = n; i >= 1; --i) sa[cnt[rk[i]]--] = i;

        for (w = 1; w < n; w <<= 1, m = p) {  // m=p 就是优化计数排序值域
            for (p = 0, i = n; i > n - w; --i) id[++p] = i;
            for (i = 1; i <= n; ++i)
                if (sa[i] > w) id[++p] = sa[i] - w;
            memset(cnt, 0, sizeof(cnt));
            for (i = 1; i <= n; ++i) ++cnt[px[i] = rk[id[i]]];
            for (i = 1; i <= m; ++i) cnt[i] += cnt[i - 1];
            for (i = n; i >= 1; --i) sa[cnt[px[i]]--] = id[i];
            memcpy(oldrk, rk, sizeof(rk));
            for (p = 0, i = 1; i <= n; ++i)
                rk[sa[i]] = cmp(sa[i], sa[i - 1], w) ? p : ++p;
        }

        // calc height
        for (i = 1, k = 0; i <= n; ++i) {
            if (k) --k;
            while (s[i + k] == s[sa[rk[i] - 1] + k]) ++k;
            ht[rk[i]] = k;  // height太长了缩写为ht
        } ht[1] = 0;
    }

};

int n, k;
SA<maxn> Sa;
int at[maxn]; // which string is this char in

int L[maxn];
void calcL() {
    map<int, int> mp; mp.clear();
    int r, cnt = 0;
    for (r = 1; r <= Sa.n; ++r) {
        if (!mp.count(at[Sa.sa[r]])) {
            ++cnt;
            mp[at[Sa.sa[r]]] = 0;
        }
        ++ mp[at[Sa.sa[r]]];
        L[r] = -1;
        if (cnt == k) break;
    }
    int l = 1;
    while (l <= r && cnt >= k) {
        -- mp[at[Sa.sa[l]]];
        if (mp[at[Sa.sa[l]]] == 0) --cnt;
        ++l;
    } --l; cnt = k; ++mp[at[Sa.sa[l]]];
    L[r] = l;
    for (++r ; r <= Sa.n; ++r) {
        if (!mp.count(at[Sa.sa[r]])) {
            mp[at[Sa.sa[r]]] = 0;
        }
        if (mp[at[Sa.sa[r]]] == 0) ++ cnt;
        ++ mp[at[Sa.sa[r]]];
        while (l <= r && cnt >= k) {
            -- mp[at[Sa.sa[l]]];
            if (mp[at[Sa.sa[l]]] == 0) --cnt;
            ++l;
        } --l; cnt = k; ++mp[at[Sa.sa[l]]];
        L[r] = l;
    }
}

int st_table[20][maxn];
void build_ST() {
    for (int i = 1; i <= Sa.n; ++i) st_table[0][i] = Sa.ht[i];
    for (int i = 1; i < 20; ++i)
        for (int j = 1; j + (1 << i) - 1 <= Sa.n; ++j) {
            st_table[i][j] = min(st_table[i-1][j], st_table[i-1][j + (1 << (i-1))]);
        }
}

int Logn[maxn];
void pre() {
    Logn[1] = 0;
    Logn[2] = 1;
    for (int i = 3; i < maxn; i++) {
        Logn[i] = Logn[i / 2] + 1;
    }
}

int st_query(int l, int r) {
    if (l > r) return 0x3f3f3f3f;
    int k = Logn[r - l + 1];
    return min(st_table[k][l], st_table[k][r - (1 << k) + 1]);
}

bool check(int x, int len) {
    int A, B;
    if (Sa.ht[x+1] < len) B = x;
    else {
        int l = x + 1, r = Sa.n;
        while(l + 1 < r) {
            int mid = l + ((r - l) >> 1);
            if (st_query(x+1, mid) >= len) l = mid;
            else r = mid;
            B = l;
        }
    }
    if (Sa.ht[x] < len) A = x;
    else {
        int l = 1, r = x - 1;
        while (l + 1 < r) {
            int mid = l + ((r - l) >> 1);
            if (st_query(mid+1, x) >= len) r = mid;
            else l = mid;
        }
        A = r;
    }
    return A <= L[B];
    /*
    int l = x, r = x;
    if (Sa.ht[x] < len && Sa.ht[x + 1] < len) return false;
    while(l > 1 && Sa.ht[l] >= len) --l;
    while(r < Sa.n && Sa.ht[r + 1] >= len) ++ r;
    //printf("%d %d %d %d %d %d\n", x, len, A, B, l, r);
    //printf("%d\n", Sa.ht[2]);
    //assert(A == l && B == r);
    //if (x == 31 && len == 1) printf("%d %d %d %d\n", x, len, l, r);
    return l <= L[r];
    */
}

int ml[maxn];
int ans[maxn];
int ansp[maxn];
void getAns() {
    for (int i = 1; i <= Sa.n; ++i) {
        int l = 0, r = ml[Sa.sa[i]] + 1;
        while (l + 1 < r) {
            int mid = l + ((r - l) >> 1);
            if (check(i, mid)) l = mid;
            else r = mid;
        }
        ans[at[Sa.sa[i]]] += l;
        ansp[i] = l;
    }
    for (int i = 1; i <= n; ++i) {
        printf("%d ", ans[i]);
    }
    puts("");
}

void log() {
    for (int i = 1; i <= Sa.n; ++i) {
        //if (at[Sa.sa[i]] == 3) {
            printf("%3d ", i);
            for (int j = Sa.sa[i]; j <= Sa.n; ++j) {
                if (Sa.s[j] >= 0 && Sa.s[j] < 26) printf("%c", Sa.s[j] + 'a');
                else printf("#");
            }
            printf(" %d %d %d %d %d", at[Sa.sa[i]], L[i], ml[Sa.sa[i]], ansp[i], Sa.ht[i]);
            puts("");
            //}
    }
}

int main() {
#ifdef __APPLE__
    freopen("main.in", "r", stdin);
#endif
    scanf(" %d%d", &n, &k);
    if (k == 1) {
        for (int i = 1; i <= n; ++i){
            string s; cin >> s;
            int l = s.length();
            cout << l * (l - 1) / 2 + l << " ";
        }
        puts("");
        return 0;
    }
    int p = 0;
    for (int i = 1; i <= n; ++i) {
        string s; cin >> s;
        for (int j = 0; j < s.length(); ++j) {
            Sa.s[++p] = s[j] - 'a';
            at[p] = i;
            ml[p] = s.length() - j;
        }
        Sa.s[++p] = 'z' - 'a' + i;
    }
    Sa.build_sa(p, n + 'z' - 'a');
    calcL();
    build_ST();
    pre();
    getAns();
    //log();
    return 0;
}


#include <iostream>
#include <cstring>
#include <cstdio>
#include <map>
#include <cmath>
using namespace std;

#define FOR(i, l, r) for (int i = (l); i <= (r); ++i)

const int maxn = 200005;

/* Suffix Array */
template<int N>
struct SA {
    int s[N];
    /* s: [1, n] ( not [0, 0) ) */

    int n, sa[N], rk[N], ht[N];
    /* sa : sorted index of suffix */
    /* rk[i] : rank of suffix i in sa, i.e. sa[rk[i]] == i */
    /* ht[i] : lcp{ sa[i-1], sa[i] } */

    // aux arrays
    int oldrk[N << 1], id[N], px[N], cnt[N];

    bool cmp(int x, int y, int w) {
        return oldrk[x] == oldrk[y] && oldrk[x + w] == oldrk[y + w];
    }

    void build_sa(int n /*the length of s*/, int m /* the domain of s */) {
        int i, k, p, w;

        this -> n = n;
        for (i = 1; i <= n; ++i) ++cnt[rk[i] = s[i]];
        for (i = 1; i <= m; ++i) cnt[i] += cnt[i - 1];
        for (i = n; i >= 1; --i) sa[cnt[rk[i]]--] = i;

        for (w = 1; w < n; w <<= 1, m = p) {  // m=p 就是优化计数排序值域
            for (p = 0, i = n; i > n - w; --i) id[++p] = i;
            for (i = 1; i <= n; ++i)
                if (sa[i] > w) id[++p] = sa[i] - w;
            memset(cnt, 0, sizeof(cnt));
            for (i = 1; i <= n; ++i) ++cnt[px[i] = rk[id[i]]];
            for (i = 1; i <= m; ++i) cnt[i] += cnt[i - 1];
            for (i = n; i >= 1; --i) sa[cnt[px[i]]--] = id[i];
            memcpy(oldrk, rk, sizeof(rk));
            for (p = 0, i = 1; i <= n; ++i)
                rk[sa[i]] = cmp(sa[i], sa[i - 1], w) ? p : ++p;
        }

        // calc height
        for (i = 1, k = 0; i <= n; ++i) {
            if (k) --k;
            while (s[i + k] == s[sa[rk[i] - 1] + k]) ++k;
            ht[rk[i]] = k;  // height太长了缩写为ht
        } ht[1] = 0;
    }

};

int n, k;
SA<maxn> Sa;
int at[maxn]; // which string is this char in

int L[maxn];
void calcL() {
    map<int, int> mp; mp.clear();
    int r, cnt = 0;
    for (r = 1; r <= Sa.n; ++r) {
        if (!mp.count(at[Sa.sa[r]])) {
            ++cnt;
            mp[at[Sa.sa[r]]] = 0;
        }
        ++ mp[at[Sa.sa[r]]];
        L[r] = -1;
        if (cnt == k) break;
    }
    int l = 1;
    while (l <= r && cnt >= k) {
        -- mp[at[Sa.sa[l]]];
        if (mp[at[Sa.sa[l]]] == 0) --cnt;
        ++l;
    } --l; cnt = k; ++mp[at[Sa.sa[l]]];
    L[r] = l;
    for (++r ; r <= Sa.n; ++r) {
        if (!mp.count(at[Sa.sa[r]])) {
            mp[at[Sa.sa[r]]] = 0;
        }
        if (mp[at[Sa.sa[r]]] == 0) ++ cnt;
        ++ mp[at[Sa.sa[r]]];
        while (l <= r && cnt >= k) {
            -- mp[at[Sa.sa[l]]];
            if (mp[at[Sa.sa[l]]] == 0) --cnt;
            ++l;
        } --l; cnt = k; ++mp[at[Sa.sa[l]]];
        L[r] = l;
    }
}

int st_table[20][maxn];
void build_ST() {
    for (int i = 1; i <= Sa.n; ++i) st_table[0][i] = Sa.ht[i];
    for (int i = 1; i < 20; ++i)
        for (int j = 1; j + (1 << i) - 1 <= Sa.n; ++j) {
            st_table[i][j] = min(st_table[i-1][j], st_table[i-1][j + (1 << (i-1))]);
        }
}

int Logn[maxn];
void pre() {
    Logn[1] = 0;
    Logn[2] = 1;
    for (int i = 3; i < maxn; i++) {
        Logn[i] = Logn[i / 2] + 1;
    }
}

int st_query(int l, int r) {
    if (l > r) return 0x3f3f3f3f;
    int k = Logn[r - l + 1];
    return min(st_table[k][l], st_table[k][r - (1 << k) + 1]);
}

bool check(int x, int len) {
    int A, B;
    if (Sa.ht[x+1] < len) B = x;
    else {
        int l = x + 1, r = Sa.n;
        while(l + 1 < r) {
            int mid = l + ((r - l) >> 1);
            if (st_query(x+1, mid) >= len) l = mid;
            else r = mid;
            B = l;
        }
    }
    if (Sa.ht[x] < len) A = x;
    else {
        int l = 1, r = x - 1;
        while (l + 1 < r) {
            int mid = l + ((r - l) >> 1);
            if (st_query(mid+1, x) >= len) r = mid;
            else l = mid;
        }
        A = r;
    }
    return A <= L[B];
    /*
    int l = x, r = x;
    if (Sa.ht[x] < len && Sa.ht[x + 1] < len) return false;
    while(l > 1 && Sa.ht[l] >= len) --l;
    while(r < Sa.n && Sa.ht[r + 1] >= len) ++ r;
    //printf("%d %d %d %d %d %d\n", x, len, A, B, l, r);
    //printf("%d\n", Sa.ht[2]);
    //assert(A == l && B == r);
    //if (x == 31 && len == 1) printf("%d %d %d %d\n", x, len, l, r);
    return l <= L[r];
    */
}

int ml[maxn];
long long ans[maxn];
int ansp[maxn];
void getAns() {
    for (int i = 1; i <= Sa.n; ++i) {
        int l = 0, r = ml[Sa.sa[i]] + 1;
        while (l + 1 < r) {
            int mid = l + ((r - l) >> 1);
            if (check(i, mid)) l = mid;
            else r = mid;
        }
        ans[at[Sa.sa[i]]] += l;
        ansp[i] = l;
    }
    for (int i = 1; i <= n; ++i) {
        //printf("%lld ", ans[i]);
        cout << ans[i] << endl;
    }
    puts("");
}

void log() {
    for (int i = 1; i <= Sa.n; ++i) {
        //if (at[Sa.sa[i]] == 3) {
            printf("%3d ", i);
            for (int j = Sa.sa[i]; j <= Sa.n; ++j) {
                if (Sa.s[j] >= 0 && Sa.s[j] < 26) printf("%c", Sa.s[j] + 'a');
                else printf("#");
            }
            printf(" %d %d %d %d %d", at[Sa.sa[i]], L[i], ml[Sa.sa[i]], ansp[i], Sa.ht[i]);
            puts("");
            //}
    }
}

int main() {
#ifdef __APPLE__
    freopen("main.in", "r", stdin);
#endif
    scanf(" %d%d", &n, &k);
    if (k == 1) {
        for (int i = 1; i <= n; ++i){
            string s; cin >> s;
            long long l = s.length();
            cout << l * (l - 1) / 2 + l << " ";
        }
        puts("");
        return 0;
    }
    int p = 0;
    for (int i = 1; i <= n; ++i) {
        string s; cin >> s;
        for (int j = 0; j < s.length(); ++j) {
            Sa.s[++p] = s[j] - 'a';
            at[p] = i;
            ml[p] = s.length() - j;
        }
        Sa.s[++p] = 'z' - 'a' + i;
    }
    Sa.build_sa(p, n + 'z' - 'a');
    calcL();
    build_ST();
    pre();
    getAns();
    //log();
    return 0;
}


#include <iostream>
#include <cstring>
#include <cstdio>
#include <map>
#include <cmath>
using namespace std;

#define FOR(i, l, r) for (int i = (l); i <= (r); ++i)

const int maxn = 200005;

/* Suffix Array */
template<int N>
struct SA {
    int s[N];
    /* s: [1, n] ( not [0, 0) ) */

    int n, sa[N], rk[N], ht[N];
    /* sa : sorted index of suffix */
    /* rk[i] : rank of suffix i in sa, i.e. sa[rk[i]] == i */
    /* ht[i] : lcp{ sa[i-1], sa[i] } */

    // aux arrays
    int oldrk[N << 1], id[N], px[N], cnt[N];

    bool cmp(int x, int y, int w) {
        return oldrk[x] == oldrk[y] && oldrk[x + w] == oldrk[y + w];
    }

    void build_sa(int n /*the length of s*/, int m /* the domain of s */) {
        int i, k, p, w;

        this -> n = n;
        for (i = 1; i <= n; ++i) ++cnt[rk[i] = s[i]];
        for (i = 1; i <= m; ++i) cnt[i] += cnt[i - 1];
        for (i = n; i >= 1; --i) sa[cnt[rk[i]]--] = i;

        for (w = 1; w < n; w <<= 1, m = p) {  // m=p 就是优化计数排序值域
            for (p = 0, i = n; i > n - w; --i) id[++p] = i;
            for (i = 1; i <= n; ++i)
                if (sa[i] > w) id[++p] = sa[i] - w;
            memset(cnt, 0, sizeof(cnt));
            for (i = 1; i <= n; ++i) ++cnt[px[i] = rk[id[i]]];
            for (i = 1; i <= m; ++i) cnt[i] += cnt[i - 1];
            for (i = n; i >= 1; --i) sa[cnt[px[i]]--] = id[i];
            memcpy(oldrk, rk, sizeof(rk));
            for (p = 0, i = 1; i <= n; ++i)
                rk[sa[i]] = cmp(sa[i], sa[i - 1], w) ? p : ++p;
        }

        // calc height
        for (i = 1, k = 0; i <= n; ++i) {
            if (k) --k;
            while (s[i + k] == s[sa[rk[i] - 1] + k]) ++k;
            ht[rk[i]] = k;  // height太长了缩写为ht
        } ht[1] = 0;
    }

};

int n, k;
SA<maxn> Sa;
int at[maxn]; // which string is this char in

int L[maxn];
void calcL() {
    map<int, int> mp; mp.clear();
    int r, cnt = 0;
    for (r = 1; r <= Sa.n; ++r) {
        if (!mp.count(at[Sa.sa[r]])) {
            ++cnt;
            mp[at[Sa.sa[r]]] = 0;
        }
        ++ mp[at[Sa.sa[r]]];
        L[r] = -1;
        if (cnt == k) break;
    }
    int l = 1;
    while (l <= r && cnt >= k) {
        -- mp[at[Sa.sa[l]]];
        if (mp[at[Sa.sa[l]]] == 0) --cnt;
        ++l;
    } --l; cnt = k; ++mp[at[Sa.sa[l]]];
    L[r] = l;
    for (++r ; r <= Sa.n; ++r) {
        if (!mp.count(at[Sa.sa[r]])) {
            mp[at[Sa.sa[r]]] = 0;
        }
        if (mp[at[Sa.sa[r]]] == 0) ++ cnt;
        ++ mp[at[Sa.sa[r]]];
        while (l <= r && cnt >= k) {
            -- mp[at[Sa.sa[l]]];
            if (mp[at[Sa.sa[l]]] == 0) --cnt;
            ++l;
        } --l; cnt = k; ++mp[at[Sa.sa[l]]];
        L[r] = l;
    }
}

int st_table[20][maxn];
void build_ST() {
    for (int i = 1; i <= Sa.n; ++i) st_table[0][i] = Sa.ht[i];
    for (int i = 1; i < 20; ++i)
        for (int j = 1; j + (1 << i) - 1 <= Sa.n; ++j) {
            st_table[i][j] = min(st_table[i-1][j], st_table[i-1][j + (1 << (i-1))]);
        }
}

int Logn[maxn];
void pre() {
    Logn[1] = 0;
    Logn[2] = 1;
    for (int i = 3; i < maxn; i++) {
        Logn[i] = Logn[i / 2] + 1;
    }
}

int st_query(int l, int r) {
    if (l > r) return 0x3f3f3f3f;
    int k = Logn[r - l + 1];
    return min(st_table[k][l], st_table[k][r - (1 << k) + 1]);
}

bool check(int x, int len) {
    int A, B;
    if (Sa.ht[x+1] < len) B = x;
    else {
        int l = x + 1, r = Sa.n + 1;
        while(l + 1 < r) {
            int mid = l + ((r - l) >> 1);
            if (st_query(x+1, mid) >= len) l = mid;
            else r = mid;
            B = l;
        }
    }
    if (Sa.ht[x] < len) A = x;
    else {
        int l = 0, r = x - 1;
        while (l + 1 < r) {
            int mid = l + ((r - l) >> 1);
            if (st_query(mid+1, x) >= len) r = mid;
            else l = mid;
        }
        A = r;
    }
    //cout << A << " " << B << endl;
    return A <= L[B];
    /*
    int l = x, r = x;
    if (Sa.ht[x] < len && Sa.ht[x + 1] < len) return false;
    while(l > 1 && Sa.ht[l] >= len) --l;
    while(r < Sa.n && Sa.ht[r + 1] >= len) ++ r;
    //printf("%d %d %d %d %d %d\n", x, len, A, B, l, r);
    //printf("%d\n", Sa.ht[2]);
    //assert(A == l && B == r);
    //if (x == 31 && len == 1) printf("%d %d %d %d\n", x, len, l, r);
    return l <= L[r];
    */
}

int ml[maxn];
long long ans[maxn];
int ansp[maxn];
void getAns() {
    //cout << check(3, 3) << endl;
    for (int i = 1; i <= Sa.n; ++i) {
        int l = 0, r = ml[Sa.sa[i]] + 1;
        while (l + 1 < r) {
            int mid = l + ((r - l) >> 1);
            if (check(i, mid)) l = mid;
            else r = mid;
        }
        ans[at[Sa.sa[i]]] += l;
        ansp[i] = l;
    }
    for (int i = 1; i <= n; ++i) {
        //printf("%lld ", ans[i]);
        cout << ans[i] << endl;
    }
    puts("");
}

void log() {
    for (int i = 1; i <= Sa.n; ++i) {
        //if (at[Sa.sa[i]] == 3) {
            printf("%3d ", i);
            for (int j = Sa.sa[i]; j <= Sa.n; ++j) {
                if (Sa.s[j] >= 0 && Sa.s[j] < 26) printf("%c", Sa.s[j] + 'a');
                else printf("#");
            }
            printf(" %d %d %d %d %d", at[Sa.sa[i]], L[i], ml[Sa.sa[i]], ansp[i], Sa.ht[i]);
            puts("");
            //}
    }
}

int main() {
#ifdef __APPLE__
    freopen("main.in", "r", stdin);
#endif
    scanf(" %d%d", &n, &k);
    if (k == 1) {
        for (int i = 1; i <= n; ++i){
            string s; cin >> s;
            long long l = s.length();
            cout << l * (l - 1) / 2 + l << " ";
        }
        puts("");
        return 0;
    }
    int p = 0;
    for (int i = 1; i <= n; ++i) {
        string s; cin >> s;
        for (int j = 0; j < s.length(); ++j) {
            Sa.s[++p] = s[j] - 'a';
            at[p] = i;
            ml[p] = s.length() - j;
        }
        Sa.s[++p] = 'z' - 'a' + i;
    }
    Sa.build_sa(p, n + 'z' - 'a');
    calcL();
    build_ST();
    pre();
    getAns();
    //log();
    return 0;
}