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

const int MAXN = 250001;

int n,k;
string temp;
int str[MAXN],pos[MAXN],lcp[MAXN],sa[MAXN],gap,tmp[MAXN];
int owner[MAXN],base;
long long ans[MAXN];
int parent[MAXN];
long long len[MAXN];
int sz[MAXN];
set<int> stk[MAXN];
vector<int> p[MAXN];
long long sp[MAXN];
int chk[MAXN];
void init(){
    for(int i=0;i<MAXN;i++)parent[i]=i,p[i].push_back(i);
}

int find(int u){
    return u == parent[u] ? u : parent[u] = find(parent[u]);
}
void mrg(int u,int v){
    u=find(u) , v=find(v);
    if(p[u].size() > p[v].size()){
        swap(u,v);
    }
    set<int> :: iterator it;
    for(it = stk[u].begin();it!=stk[u].end();it++){
        stk[v].insert(*it);
    }
    vector<int> ::iterator jt;
    for(jt = p[u].begin();jt!=p[u].end();jt++){
        p[v].push_back(*jt);
    }

    parent[u]=v;
    stk[u].clear();
    p[u].clear();
}
bool cmp(int i,int j){
    return pos[i]!=pos[j] ? pos[i] < pos[j] : pos[i+gap]<pos[j+gap];
}
void build_sa(){
    int N = temp.size();
    for(int i=0;i<N;i++)sa[i]=i,pos[i]=str[i];
    pos[N] = -1;
    for(gap=1;;gap*=2){
        sort(sa,sa+N,cmp);
        for(int i=1;i<N;i++) tmp[i] = tmp[i-1] + cmp(sa[i-1],sa[i]);
        for(int i=0;i<N;i++) pos[sa[i]] = tmp[i];
        if(tmp[N-1] == N-1)break;
    }
}
void build_lcp(){
    int N =temp.size();
    for(int i=0,k=0;i<N;i++){
        if(pos[i] == N-1)continue;
        for(int j = sa[pos[i]+1];str[i+k] == str[j+k];){
            k++;
        }
        lcp[pos[i]] = k;
        if(k)k--;
    }
}
vector<pair<int,int> > vx[MAXN];
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>k;
    int cur = -2;
    init();
    for(int i=1;i<=n;i++){
        string ttt; cin>>ttt;
        sp[i] = ttt.size();
        temp+=ttt;
        for(int j = cur+2 ;j<temp.size();j++){
            owner[j] = i;
            cur = j;
        }

        temp+="#";
    }
    if(k>n){
        for(int i=1;i<=n;i++){
            cout<<0<<' ';
        }
        exit(0);
    }
    if(k==1){
        for(int i=1;i<=n;i++){
            cout<<1LL * sp[i] *(sp[i]+1)/2<<' ';
        }
        exit(0);
    }
    int cnt=100;
    for(int i=0;i<temp.size();i++){
        if(temp[i]>='a' && temp[i] <='z'){
            str[i] = temp[i]-'a';
        }
        else str[i] = ++cnt;
    }
    build_sa();
    build_lcp();
    for(int i=0;i<(int)temp.size()-1;i++){
        vx[lcp[i]].push_back(make_pair(i,i+1));
    }
    for(int i=0;i<temp.size();i++){
        stk[i].insert(owner[i]);
    }
    for(int i=temp.size()-1;i >= 1;i--){
        for(int j=0;j<vx[i].size();j++){
            int x = sa[vx[i][j].first];
            int y = sa[vx[i][j].second];
            mrg(x,y);
        }
        for(int j=0;j<vx[i].size();j++){
            int x = sa[vx[i][j].first];
            int y = sa[vx[i][j].second];
            int root = find(x);
            if(stk[root].size() >=k){
                vector<int>::iterator it;
                set<int>::iterator jt;
                for(it = p[root].begin();it!=p[root].end();it++){
                    ans[owner[*it]]+=i;
                }
                p[root].clear();
            }
        }
    }
    for(int i=1;i<=n;i++){
        cout<<ans[i]<<' ';
    }
    return 0;
}


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

const int MAXN = 400001;

int n,k;
string temp;
int str[MAXN],pos[MAXN],lcp[MAXN],sa[MAXN],gap,tmp[MAXN];
int owner[MAXN],base;
long long ans[MAXN];
int parent[MAXN];
long long len[MAXN];
int sz[MAXN];
set<int> stk[MAXN];
vector<int> p[MAXN];
long long sp[MAXN];
int chk[MAXN];
void init(){
    for(int i=0;i<MAXN;i++)parent[i]=i,p[i].push_back(i);
}

int find(int u){
    return u == parent[u] ? u : parent[u] = find(parent[u]);
}
void mrg(int u,int v){
    u=find(u) , v=find(v);
    if(p[u].size() > p[v].size()){
        swap(u,v);
    }
    set<int> :: iterator it;
    for(it = stk[u].begin();it!=stk[u].end();it++){
        stk[v].insert(*it);
    }
    vector<int> ::iterator jt;
    for(jt = p[u].begin();jt!=p[u].end();jt++){
        p[v].push_back(*jt);
    }

    parent[u]=v;
    stk[u].clear();
    p[u].clear();
}
bool cmp(int i,int j){
    return pos[i]!=pos[j] ? pos[i] < pos[j] : pos[i+gap]<pos[j+gap];
}
void build_sa(){
    int N = temp.size();
    for(int i=0;i<N;i++)sa[i]=i,pos[i]=str[i];
    pos[N] = -1;
    for(gap=1;;gap*=2){
        sort(sa,sa+N,cmp);
        for(int i=1;i<N;i++) tmp[i] = tmp[i-1] + cmp(sa[i-1],sa[i]);
        for(int i=0;i<N;i++) pos[sa[i]] = tmp[i];
        if(tmp[N-1] == N-1)break;
    }
}
void build_lcp(){
    int N =temp.size();
    for(int i=0,k=0;i<N;i++){
        if(pos[i] == N-1)continue;
        for(int j = sa[pos[i]+1];str[i+k] == str[j+k];){
            k++;
        }
        lcp[pos[i]] = k;
        if(k)k--;
    }
}
vector<pair<int,int> > vx[MAXN];
int main(){
    //freopen("input.txt","r",stdin);
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>k;
    int cur = -2;
    init();
    for(int i=1;i<=n;i++){
        string ttt; cin>>ttt;
        sp[i] = ttt.size();
        temp+=ttt;
        for(int j = cur+2 ;j<temp.size();j++){
            owner[j] = i;
            cur = j;
        }

        temp+="#";
    }
    if(k>n){
        for(int i=1;i<=n;i++){
            cout<<0<<' ';
        }
        exit(0);
    }
    if(k==1){
        for(int i=1;i<=n;i++){
            cout<<1LL * sp[i] *(sp[i]+1)/2<<' ';
        }
        exit(0);
    }
    int cnt=100;
    for(int i=0;i<temp.size();i++){
        if(temp[i]>='a' && temp[i] <='z'){
            str[i] = temp[i]-'a';
        }
        else str[i] = ++cnt;
    }
    build_sa();
    build_lcp();
    for(int i=0;i<(int)temp.size()-1;i++){
        vx[lcp[i]].push_back(make_pair(i,i+1));
    }
    for(int i=0;i<temp.size();i++){
        stk[i].insert(owner[i]);
    }
    for(int i=temp.size()-1;i >= 1;i--){
        for(int j=0;j<vx[i].size();j++){
            int x = sa[vx[i][j].first];
            int y = sa[vx[i][j].second];
            mrg(x,y);
        }
        for(int j=0;j<vx[i].size();j++){
            int x = sa[vx[i][j].first];
            int y = sa[vx[i][j].second];
            int root = find(x);
            if(stk[root].size() >=k){
                vector<int>::iterator it;
                set<int>::iterator jt;
                for(it = p[root].begin();it!=p[root].end();it++){
                    ans[owner[*it]]+=i;
                }
                p[root].clear();
            }
        }
    }
    for(int i=1;i<=n;i++){
        cout<<ans[i]<<' ';
    }
    return 0;
}


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

const int MAXN = 400001;

int n,k;
string temp;
int str[MAXN],pos[MAXN],lcp[MAXN],sa[MAXN],gap,tmp[MAXN];
int owner[MAXN],base;
long long ans[MAXN];
int parent[MAXN];
long long len[MAXN];
int sz[MAXN];
set<int> stk[MAXN],p[MAXN];
long long sp[MAXN];
int chk[MAXN];
void init(){
    for(int i=0;i<MAXN;i++)parent[i]=i,p[i].insert(i);
}

int find(int u){
    return u == parent[u] ? u : parent[u] = find(parent[u]);
}
void mrg(int u,int v){
    u=find(u) , v=find(v);
    if(p[u].size() > p[v].size()){
        swap(u,v);
    }
    set<int> :: iterator it;
    for(it = stk[u].begin();it!=stk[u].end();it++){
        stk[v].insert(*it);
    }

    for(it = p[u].begin();it!=p[u].end();it++){
        p[v].insert(*it);
    }

    parent[u]=v;
    stk[u].clear();
    p[u].clear();
}
bool cmp(int i,int j){
    return pos[i]!=pos[j] ? pos[i] < pos[j] : pos[i+gap]<pos[j+gap];
}
void build_sa(){
    int N = temp.size();
    for(int i=0;i<N;i++)sa[i]=i,pos[i]=str[i];
    pos[N] = -1;
    for(gap=1;;gap*=2){
        sort(sa,sa+N,cmp);
        for(int i=1;i<N;i++) tmp[i] = tmp[i-1] + cmp(sa[i-1],sa[i]);
        for(int i=0;i<N;i++) pos[sa[i]] = tmp[i];
        if(tmp[N-1] == N-1)break;
    }
}
void build_lcp(){
    int N =temp.size();
    for(int i=0,k=0;i<N;i++){
        if(pos[i] == N-1)continue;
        for(int j = sa[pos[i]+1];str[i+k] == str[j+k];){
            k++;
        }
        lcp[pos[i]] = k;
        if(k)k--;
    }
}
vector<pair<int,int> > vx[MAXN];
int main(){
    //freopen("input.txt","r",stdin);
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>k;
    int cur = -2;
    init();
    for(int i=1;i<=n;i++){
        string ttt; cin>>ttt;
        sp[i] = ttt.size();
        temp+=ttt;
        for(int j = cur+2 ;j<temp.size();j++){
            owner[j] = i;
            cur = j;
        }

        temp+="#";
    }
    if(k>n){
        for(int i=1;i<=n;i++){
            cout<<0<<' ';
        }
        exit(0);
    }
    if(k==1){
        for(int i=1;i<=n;i++){
            cout<<1LL * sp[i] *(sp[i]+1)/2<<' ';
        }
        exit(0);
    }
    int cnt=100;
    for(int i=0;i<temp.size();i++){
        if(temp[i]>='a' && temp[i] <='z'){
            str[i] = temp[i]-'a';
        }
        else str[i] = ++cnt;
    }
    build_sa();
    build_lcp();
    for(int i=0;i<(int)temp.size()-1;i++){
        vx[lcp[i]].push_back(make_pair(i,i+1));
    }
    for(int i=0;i<temp.size();i++){
        stk[i].insert(owner[i]);
    }
    for(int i=temp.size()-1;i >= 1;i--){
        for(int j=0;j<vx[i].size();j++){
            int x = sa[vx[i][j].first];
            int y = sa[vx[i][j].second];
            mrg(x,y);
        }
        for(int j=0;j<vx[i].size();j++){
            int x = sa[vx[i][j].first];
            int y = sa[vx[i][j].second];
            int root = find(x);
            if(stk[root].size() >=k){
                set<int>::iterator it;
                set<int>::iterator jt;
                for(it = p[root].begin();it!=p[root].end();it++){
                    ans[owner[*it]]+=i;
                }
                p[root].clear();
            }

        }
    }
    for(int i=1;i<=n;i++){
        cout<<ans[i]<<' ';
    }
    return 0;
}


//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <cassert>
#include <stack>
#include <bitset>
#define mkp make_pair
using namespace std;
const double EPS=1e-8;
typedef long long lon;
const lon SZ=200010,SSZ=0,APB=26,INF=0x7FFFFFFFFFFFFFF,mod=1000000007;
int n,m,maxlen[SZ],nex[SZ][APB],cnt,slink[SZ];
int minlen[SZ],in[SZ],ans[SZ];
char ch[SZ];
set<int> st[SZ];
bool green[SZ];
int endpos[SZ];
string str[SZ];

//int add(int pre,int cur,int sz,int stc)
//{
//	int &tmp=nex[pre][cur];
//	if(tmp&&maxlen[tmp]==sz)
//	{
//		st[tmp].insert(stc);
//		return tmp;
//	}
//	else
//	{
//		int z=++cnt;
//		st[z].insert(stc);
//		int u=pre;
//		for(;u!=-1&&!nex[u][cur];u=slink[u])nex[u][cur]=z;
//		if(u==-1)
//		{
//			maxlen[z]=maxlen[pre]+1;
//			minlen[z]=1;
//			slink[z]=0;
//			return z;
//		}
//		else
//		{
//			int x=nex[u][cur];
//			if(maxlen[x]==maxlen[u]+1)
//			{
//				maxlen[z]=maxlen[pre]+1;
//				minlen[z]=maxlen[x]+1;
//				slink[z]=x;
//				return z;
//			}
//			else
//			{
//				int v=++cnt;
//				memcpy(nex[v],nex[x],sizeof(nex[x]));
//				maxlen[v]=maxlen[u]+1;
//				slink[v]=slink[x];
//				minlen[v]=maxlen[slink[x]]+1;
//				slink[x]=slink[z]=v;
//				minlen[x]=maxlen[v]+1;
//				maxlen[z]=maxlen[pre]+1;
//				minlen[z]=maxlen[v]+1;
//				for(;u!=-1&&nex[u][cur]==x;u=slink[u])nex[u][cur]=v;
//				return z;
//			}
//		}
//	}
//}

int add(int pre,int cur,int sz,int stc)
{
	int &tmp=nex[pre][cur];
	if(tmp&&maxlen[tmp]==sz)
	{
		st[tmp].insert(stc);
		return tmp;
	}
	else
	{
		int z=++cnt;
		green[z]=1;
		st[z].insert(stc);
		int u=pre;
		for(;u!=-1&&!nex[u][cur];u=slink[u])nex[u][cur]=z;
		if(u==-1)
		{
			maxlen[z]=maxlen[pre]+1;
			minlen[z]=1;
			slink[z]=0;
			return z;
		}
		else
		{
			int x=nex[u][cur];
			if(maxlen[x]==maxlen[u]+1)
			{
				maxlen[z]=maxlen[pre]+1;
				slink[z]=x;
				minlen[z]=maxlen[x]+1;
				return z;
			}
			else
			{
				int v=++cnt;
				memcpy(nex[v],nex[x],sizeof(nex[x]));
				slink[v]=slink[x];
				minlen[v]=maxlen[slink[v]]+1;
				maxlen[v]=maxlen[u]+1;
				slink[x]=slink[z]=v;
				minlen[x]=maxlen[v]+1;
				minlen[z]=maxlen[v]+1;
				maxlen[z]=maxlen[pre]+1;
				for(;u!=-1&&nex[u][cur]==x;u=slink[u])nex[u][cur]=v;
				return z;
			}
		}
	}
}

void topo()
{
	for(int i=1;i<=cnt;++i)++in[slink[i]];
	stack<int> stk;
	for(int i=1;i<=cnt;++i)
	{
		if(!in[i])
		{
			stk.push(i);
			endpos[i]=1;
		}
	}
	for(;stk.size();)
	{
		int top=stk.top();
		stk.pop();
		int sl=slink[top];
		endpos[sl]+=endpos[top];
		set<int>::iterator it;
		for(it=st[top].begin();it!=st[top].end();++it)
		{
			st[sl].insert(*it);
		}
		--in[slink[top]];
		if(slink[top]&&!in[slink[top]])
		{
			if(green[sl])++endpos[sl];
			stk.push(slink[top]);
		}
	}
}

void init()
{
	cin>>n>>m;
	slink[0]=-1;
	for(int i=1;i<=n;++i)
	{
		scanf(" %s",ch+1);
		str[i]=string(ch+1);
		int pre=0,sz=0;
		for(int j=1;ch[j];++j)
		{
			pre=add(pre,ch[j]-'a',++sz,i);
		}
	}
	topo();
}

void calc(string &x,int pos)
{
	int cur=0;
	for(int i=0;i<x.size();++i)
	{
		cur=nex[cur][x[i]-'a'];
		int u=cur;
		for(;u!=0&&st[u].size()<m;u=slink[u]);
		for(;u!=0&&st[u].size()>=m;u=slink[u])
		{
			ans[pos]+=maxlen[u]-minlen[u]+1;
		}
	}
}

void work()
{
	for(int i=1;i<=n;++i)
	{
		calc(str[i],i);
	}
	for(int i=1;i<=n;++i)
	{
		if(i!=1)printf(" ");
		printf("%d",ans[i]);
	}
}

int main()
{
	//std::ios::sync_with_stdio(0);
	//freopen("d:\\1.txt","r",stdin);
	lon casenum;
	//cin>>casenum;
	//cout<<casenum<<endl;
	//for(int tim=1;tim<=casenum;++tim)
	//for(lon time=1;cin>>n>>len>>wid;++time)
	{
		init();
		work();
	}
	return 0;
}


//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <cassert>
#include <stack>
#include <bitset>
#define mkp make_pair
using namespace std;
const double EPS=1e-8;
typedef long long lon;
const lon SZ=200010,SSZ=0,APB=26,INF=0x7FFFFFFFFFFFFFF,mod=1000000007;
int n,m,maxlen[SZ],nex[SZ][APB],cnt,slink[SZ];
int minlen[SZ],in[SZ],ans[SZ];
char ch[SZ];
set<int> st[SZ];
bool green[SZ];
int endpos[SZ];
string str[SZ];

//int add(int pre,int cur,int sz,int stc)
//{
//	int &tmp=nex[pre][cur];
//	if(tmp&&maxlen[tmp]==sz)
//	{
//		st[tmp].insert(stc);
//		return tmp;
//	}
//	else
//	{
//		int z=++cnt;
//		st[z].insert(stc);
//		int u=pre;
//		for(;u!=-1&&!nex[u][cur];u=slink[u])nex[u][cur]=z;
//		if(u==-1)
//		{
//			maxlen[z]=maxlen[pre]+1;
//			minlen[z]=1;
//			slink[z]=0;
//			return z;
//		}
//		else
//		{
//			int x=nex[u][cur];
//			if(maxlen[x]==maxlen[u]+1)
//			{
//				maxlen[z]=maxlen[pre]+1;
//				minlen[z]=maxlen[x]+1;
//				slink[z]=x;
//				return z;
//			}
//			else
//			{
//				int v=++cnt;
//				memcpy(nex[v],nex[x],sizeof(nex[x]));
//				maxlen[v]=maxlen[u]+1;
//				slink[v]=slink[x];
//				minlen[v]=maxlen[slink[x]]+1;
//				slink[x]=slink[z]=v;
//				minlen[x]=maxlen[v]+1;
//				maxlen[z]=maxlen[pre]+1;
//				minlen[z]=maxlen[v]+1;
//				for(;u!=-1&&nex[u][cur]==x;u=slink[u])nex[u][cur]=v;
//				return z;
//			}
//		}
//	}
//}

int add(int pre,int cur,int sz,int stc)
{
	int &tmp=nex[pre][cur];
	if(tmp&&maxlen[tmp]==sz)
	{
		st[tmp].insert(stc);
		return tmp;
	}
	else
	{
		int z=++cnt;
		green[z]=1;
		st[z].insert(stc);
		int u=pre;
		for(;u!=-1&&!nex[u][cur];u=slink[u])nex[u][cur]=z;
		if(u==-1)
		{
			maxlen[z]=maxlen[pre]+1;
			minlen[z]=1;
			slink[z]=0;
			return z;
		}
		else
		{
			int x=nex[u][cur];
			if(maxlen[x]==maxlen[u]+1)
			{
				maxlen[z]=maxlen[pre]+1;
				slink[z]=x;
				minlen[z]=maxlen[x]+1;
				return z;
			}
			else
			{
				int v=++cnt;
				//st[v]=st[x];
				memcpy(nex[v],nex[x],sizeof(nex[x]));
				slink[v]=slink[x];
				minlen[v]=maxlen[slink[v]]+1;
				maxlen[v]=maxlen[u]+1;
				slink[x]=slink[z]=v;
				minlen[x]=maxlen[v]+1;
				minlen[z]=maxlen[v]+1;
				maxlen[z]=maxlen[pre]+1;
				for(;u!=-1&&nex[u][cur]==x;u=slink[u])nex[u][cur]=v;
				return z;
			}
		}
	}
}

void topo()
{
	for(int i=1;i<=cnt;++i)++in[slink[i]];
	stack<int> stk;
	for(int i=1;i<=cnt;++i)
	{
		if(!in[i])
		{
			stk.push(i);
			endpos[i]=1;
		}
	}
	for(;stk.size();)
	{
		int top=stk.top();
		stk.pop();
		int sl=slink[top];
		endpos[sl]+=endpos[top];
		set<int>::iterator it;
		for(it=st[top].begin();it!=st[top].end();++it)
		{
			st[sl].insert(*it);
		}
		--in[slink[top]];
		if(slink[top]&&!in[slink[top]])
		{
			if(green[sl])++endpos[sl];
			stk.push(slink[top]);
		}
	}
}

void init()
{
	cin>>n>>m;
	slink[0]=-1;
	for(int i=1;i<=n;++i)
	{
		scanf(" %s",ch+1);
		str[i]=string(ch+1);
		int pre=0,sz=0;
		for(int j=1;ch[j];++j)
		{
			pre=add(pre,ch[j]-'a',++sz,i);
		}
	}
	topo();
}

void calc(string &x,int pos)
{
	int cur=0;
	for(int i=0;i<x.size();++i)
	{
		cur=nex[cur][x[i]-'a'];
		//if(pos==1)cout<<cur<<" "<<st[cur].size()<<endl;
		int u=cur;
		//for(;u!=0&&st[u].size()<m;u=slink[u]);
		for(;u!=0;u=slink[u])
		{
//			if(pos==1)
//			{
//				cout<<st[u].size()<<" "<<u<<" "<<maxlen[u]<<endl;
//			}
			if(st[u].size()<m)continue;
			ans[pos]+=maxlen[u];
			break;
			//ans[pos]+=maxlen[u]-minlen[u]+1;
		}

	}
}

void work()
{
	if(m<=n)
	for(int i=1;i<=n;++i)
	{
		calc(str[i],i);
	}
	for(int i=1;i<=n;++i)
	{
		if(i!=1)printf(" ");
		printf("%d",ans[i]);
	}
}

int main()
{
	//std::ios::sync_with_stdio(0);
	//freopen("d:\\1.txt","r",stdin);
	lon casenum;
	//cin>>casenum;
	//cout<<casenum<<endl;
	//for(int tim=1;tim<=casenum;++tim)
	//for(lon time=1;cin>>n>>len>>wid;++time)
	{
		init();
		work();
	}
	return 0;
}


//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <cassert>
#include <stack>
#include <bitset>
#define mkp make_pair
using namespace std;
const double EPS=1e-8;
typedef long long lon;
const lon SZ=200010,SSZ=0,APB=26,INF=0x7FFFFFFFFFFFFFF,mod=1000000007;
int n,m,maxlen[SZ],nex[SZ][APB],cnt,slink[SZ];
int minlen[SZ],in[SZ],ans[SZ];
char ch[SZ];
set<int> st[SZ];
bool green[SZ];
int endpos[SZ];
string str[SZ];

//int add(int pre,int cur,int sz,int stc)
//{
//	int &tmp=nex[pre][cur];
//	if(tmp&&maxlen[tmp]==sz)
//	{
//		st[tmp].insert(stc);
//		return tmp;
//	}
//	else
//	{
//		int z=++cnt;
//		st[z].insert(stc);
//		int u=pre;
//		for(;u!=-1&&!nex[u][cur];u=slink[u])nex[u][cur]=z;
//		if(u==-1)
//		{
//			maxlen[z]=maxlen[pre]+1;
//			minlen[z]=1;
//			slink[z]=0;
//			return z;
//		}
//		else
//		{
//			int x=nex[u][cur];
//			if(maxlen[x]==maxlen[u]+1)
//			{
//				maxlen[z]=maxlen[pre]+1;
//				minlen[z]=maxlen[x]+1;
//				slink[z]=x;
//				return z;
//			}
//			else
//			{
//				int v=++cnt;
//				memcpy(nex[v],nex[x],sizeof(nex[x]));
//				maxlen[v]=maxlen[u]+1;
//				slink[v]=slink[x];
//				minlen[v]=maxlen[slink[x]]+1;
//				slink[x]=slink[z]=v;
//				minlen[x]=maxlen[v]+1;
//				maxlen[z]=maxlen[pre]+1;
//				minlen[z]=maxlen[v]+1;
//				for(;u!=-1&&nex[u][cur]==x;u=slink[u])nex[u][cur]=v;
//				return z;
//			}
//		}
//	}
//}

int add(int pre,int cur,int sz,int stc)
{
	int &tmp=nex[pre][cur];
	if(tmp&&maxlen[tmp]==sz)
	{
		st[tmp].insert(stc);
		return tmp;
	}
	else
	{
		int z=++cnt;
		green[z]=1;
		st[z].insert(stc);
		int u=pre;
		for(;u!=-1&&!nex[u][cur];u=slink[u])nex[u][cur]=z;
		if(u==-1)
		{
			maxlen[z]=maxlen[pre]+1;
			minlen[z]=1;
			slink[z]=0;
			return z;
		}
		else
		{
			int x=nex[u][cur];
			if(maxlen[x]==maxlen[u]+1)
			{
				maxlen[z]=maxlen[pre]+1;
				slink[z]=x;
				minlen[z]=maxlen[x]+1;
				return z;
			}
			else
			{
				int v=++cnt;
				memcpy(nex[v],nex[x],sizeof(nex[x]));
				slink[v]=slink[x];
				minlen[v]=maxlen[slink[v]]+1;
				maxlen[v]=maxlen[u]+1;
				slink[x]=slink[z]=v;
				minlen[x]=maxlen[v]+1;
				minlen[z]=maxlen[v]+1;
				maxlen[z]=maxlen[pre]+1;
				for(;u!=-1&&nex[u][cur]==x;u=slink[u])nex[u][cur]=v;
				return z;
			}
		}
	}
}

void topo()
{
	for(int i=1;i<=cnt;++i)++in[slink[i]];
	stack<int> stk;
	for(int i=1;i<=cnt;++i)
	{
		if(!in[i])
		{
			stk.push(i);
			endpos[i]=1;
		}
	}
	for(;stk.size();)
	{
		int top=stk.top();
		stk.pop();
		int sl=slink[top];
		endpos[sl]+=endpos[top];
		set<int>::iterator it;
		for(it=st[top].begin();it!=st[top].end();++it)
		{
			st[sl].insert(*it);
		}
		--in[slink[top]];
		if(slink[top]&&!in[slink[top]])
		{
			if(green[sl])++endpos[sl];
			stk.push(slink[top]);
		}
	}
}

void init()
{
	cin>>n>>m;
	slink[0]=-1;
	for(int i=1;i<=n;++i)
	{
		scanf(" %s",ch+1);
		str[i]=string(ch+1);
		int pre=0,sz=0;
		for(int j=1;ch[j];++j)
		{
			pre=add(pre,ch[j]-'a',++sz,i);
		}
	}
	topo();
}

void calc(string &x,int pos)
{
	int cur=0;
	for(int i=0;i<x.size();++i)
	{
		cur=nex[cur][x[i]-'a'];
		int u=cur;
		for(;u!=0&&st[u].size()<m;u=slink[u]);
		for(;u!=0&&st[u].size()>=m;u=slink[u])
		{
			ans[pos]+=maxlen[u]-minlen[u]+1;
		}
	}
}

void work()
{
	for(int i=1;i<=n;++i)
	{
		calc(str[i],i);
	}
	for(int i=1;i<=n;++i)
	{
		if(i!=1)cout<<" ";
		cout<<ans[i];
	}
}

int main()
{
	//std::ios::sync_with_stdio(0);
	//freopen("d:\\1.txt","r",stdin);
	lon casenum;
	//cin>>casenum;
	//cout<<casenum<<endl;
	//for(int tim=1;tim<=casenum;++tim)
	//for(lon time=1;cin>>n>>len>>wid;++time)
	{
		init();
		work();
	}
	return 0;
}


//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <cassert>
#include <stack>
#include <bitset>
#define mkp make_pair
using namespace std;
const double EPS=1e-8;
typedef long long lon;
const lon SZ=200010,SSZ=0,APB=26,INF=0x7FFFFFFFFFFFFFF,mod=1000000007;
lon n,m,maxlen[SZ],nex[SZ][APB],cnt,slink[SZ];
lon minlen[SZ],in[SZ],ans[SZ];
char ch[SZ];
set<lon> st[SZ];
bool green[SZ];
lon endpos[SZ];
string str[SZ];

//lon add(lon pre,lon cur,lon sz,lon stc)
//{
//	lon &tmp=nex[pre][cur];
//	if(tmp&&maxlen[tmp]==sz)
//	{
//		st[tmp].insert(stc);
//		return tmp;
//	}
//	else
//	{
//		lon z=++cnt;
//		st[z].insert(stc);
//		lon u=pre;
//		for(;u!=-1&&!nex[u][cur];u=slink[u])nex[u][cur]=z;
//		if(u==-1)
//		{
//			maxlen[z]=maxlen[pre]+1;
//			minlen[z]=1;
//			slink[z]=0;
//			return z;
//		}
//		else
//		{
//			lon x=nex[u][cur];
//			if(maxlen[x]==maxlen[u]+1)
//			{
//				maxlen[z]=maxlen[pre]+1;
//				minlen[z]=maxlen[x]+1;
//				slink[z]=x;
//				return z;
//			}
//			else
//			{
//				lon v=++cnt;
//				memcpy(nex[v],nex[x],sizeof(nex[x]));
//				maxlen[v]=maxlen[u]+1;
//				slink[v]=slink[x];
//				minlen[v]=maxlen[slink[x]]+1;
//				slink[x]=slink[z]=v;
//				minlen[x]=maxlen[v]+1;
//				maxlen[z]=maxlen[pre]+1;
//				minlen[z]=maxlen[v]+1;
//				for(;u!=-1&&nex[u][cur]==x;u=slink[u])nex[u][cur]=v;
//				return z;
//			}
//		}
//	}
//}

lon add(lon pre,lon cur,lon sz,lon stc)
{
	lon &tmp=nex[pre][cur];
	if(tmp&&maxlen[tmp]==sz)
	{
		st[tmp].insert(stc);
		return tmp;
	}
	else
	{
		lon z=++cnt;
		green[z]=1;
		st[z].insert(stc);
		lon u=pre;
		for(;u!=-1&&!nex[u][cur];u=slink[u])nex[u][cur]=z;
		if(u==-1)
		{
			maxlen[z]=maxlen[pre]+1;
			minlen[z]=1;
			slink[z]=0;
			return z;
		}
		else
		{
			lon x=nex[u][cur];
			if(maxlen[x]==maxlen[u]+1)
			{
				maxlen[z]=maxlen[pre]+1;
				slink[z]=x;
				minlen[z]=maxlen[x]+1;
				return z;
			}
			else
			{
				lon v=++cnt;
				//st[v]=st[x];
				memcpy(nex[v],nex[x],sizeof(nex[x]));
				slink[v]=slink[x];
				minlen[v]=maxlen[slink[v]]+1;
				maxlen[v]=maxlen[u]+1;
				slink[x]=slink[z]=v;
				minlen[x]=maxlen[v]+1;
				minlen[z]=maxlen[v]+1;
				maxlen[z]=maxlen[pre]+1;
				for(;u!=-1&&nex[u][cur]==x;u=slink[u])nex[u][cur]=v;
				return z;
			}
		}
	}
}

void topo()
{
	for(lon i=1;i<=cnt;++i)++in[slink[i]];
	stack<lon> stk;
	for(lon i=1;i<=cnt;++i)
	{
		if(!in[i])
		{
			stk.push(i);
			endpos[i]=1;
		}
	}
	for(;stk.size();)
	{
		lon top=stk.top();
		stk.pop();
		lon sl=slink[top];
		endpos[sl]+=endpos[top];
		set<lon>::iterator it;
		for(it=st[top].begin();it!=st[top].end();++it)
		{
			st[sl].insert(*it);
		}
		--in[slink[top]];
		if(slink[top]&&!in[slink[top]])
		{
			if(green[sl])++endpos[sl];
			stk.push(slink[top]);
		}
	}
}

void init()
{
	cin>>n>>m;
	slink[0]=-1;
	for(lon i=1;i<=n;++i)
	{
		scanf(" %s",ch+1);
		str[i]=string(ch+1);
		lon pre=0,sz=0;
		for(lon j=1;ch[j];++j)
		{
			pre=add(pre,ch[j]-'a',++sz,i);
		}
	}
	topo();
}

void calc(string &x,lon pos)
{
	lon cur=0;
	for(lon i=0;i<x.size();++i)
	{
		cur=nex[cur][x[i]-'a'];
		//if(pos==1)cout<<cur<<" "<<st[cur].size()<<endl;
		lon u=cur;
		//for(;u!=0&&st[u].size()<m;u=slink[u]);
		for(;u!=0;u=slink[u])
		{
//			if(pos==1)
//			{
//				cout<<st[u].size()<<" "<<u<<" "<<maxlen[u]<<endl;
//			}
			if(st[u].size()<m)continue;
			ans[pos]+=maxlen[u];
			break;
			//ans[pos]+=maxlen[u]-minlen[u]+1;
		}

	}
}

void work()
{
	if(m<=n)
	for(lon i=1;i<=n;++i)
	{
		calc(str[i],i);
	}
	for(lon i=1;i<=n;++i)
	{
		if(i!=1)printf(" ");
		printf("%lld",ans[i]);
	}
}

int main()
{
	//std::ios::sync_with_stdio(0);
	//freopen("d:\\1.txt","r",stdin);
	lon casenum;
	//cin>>casenum;
	//cout<<casenum<<endl;
	//for(int tim=1;tim<=casenum;++tim)
	//for(lon time=1;cin>>n>>len>>wid;++time)
	{
		init();
		work();
	}
	return 0;
}


///Chefer

#include<bits/stdc++.h>
//#pragma GCC optimize("O2")
#define int long long int
#define f first
#define s second
#define rand() rand()*rand()

using namespace std;

typedef pair<int,int> pii;
typedef pair<pii,int> pip;
const int maxn=1e5+6,base=32;
int rnk[maxn];
string a[maxn];
int ans[maxn];
int b[maxn];
pii p[maxn];
int cnt;
pip tmp[maxn];
pii suf[maxn];
vector<int> h[maxn];
int po[maxn];
int spars[20][maxn];
int nxt[maxn];
int check[maxn];
int lg[maxn];
int get(int x,int y,int len)
{
	return h[x][y]-h[x][y+len]*po[len];
}
int say(int l,int r)
{
	int len=(r-l+1);
	int t=lg[len];
	int ret=spars[t][l];
	len-=(1<<t);
	ret=min(ret,spars[t][l+len]);
	return ret;
}
int found(int x,int len)
{
	int r=x,l=-1,mid;
	while(l+1<r)
	{
		mid=(l+r)/2;
		//cerr<<"MID & X : "<<mid<<" "<<x-1<<" "<<say(mid,x-1)<<endl;
		if(say(mid,x-1)>=len)
			r=mid;
		else
			l=mid;
	}
	return r;
}
main()
{
	ios_base::sync_with_stdio(false);
	lg[0]=0;
	for(int i=1;i<maxn;i++)
	{
		if((1<<lg[i-1])*2==i)
			lg[i]=lg[i-1]+1;
		else
			lg[i]=lg[i-1];
	}
	po[0]=1;
	for(int i=1;i<maxn;i++)
		po[i]=po[i-1]*base;
	int n,k;
	cin>>n>>k;
	for(int i=0;i<n;i++)
	{
		cin>>a[i];
		for(int j=0;j<a[i].size();j++)
		{
			h[i].push_back(0);
			h[i].push_back(0);
			p[cnt]=pii(i,j);
			cnt++;
		}
		h[i][a[i].size()-1]=a[i].back()-'a'+1;
		if(a[i].size()==1)
			continue;
		for(int j=a[i].size()-2;j>=0;j--)
			h[i][j]=h[i][j+1]*base+a[i][j]-'a'+1;
	}
	if(k==1)
	{
		for(int i=0;i<n;i++)
			cout<<((int)a[i].size()*a[i].size()+a[i].size())/2<<" ";
		return 0;
	}
	for(int i=0;i<cnt;i++)
		rnk[i]=a[p[i].f][p[i].s]-'a';
	for(int i=1;i<=20;i++)
	{
		for(int j=0;j<cnt;j++)
		{
			if((1<<(i-1))+p[j].s>=a[p[j].f].size())
				tmp[j]=pip(pii(rnk[j],-1),j);
			else
				tmp[j]=pip(pii(rnk[j],rnk[j+(1<<(i-1))]),j);
		}
		sort(tmp,tmp+cnt);
		rnk[tmp[0].s]=0;
		for(int j=1;j<cnt;j++)
		{
			if(tmp[j].f.f!=tmp[j-1].f.f||tmp[j].f.s!=tmp[j-1].f.s)
				rnk[tmp[j].s]=j;
			else
				rnk[tmp[j].s]=rnk[tmp[j-1].s];
		}
	}
	for(int i=0;i<cnt;i++)
		suf[i]=p[tmp[i].s];//,cerr<<suf[i].f<<" "<<suf[i].s<<endl;
	//cerr<<endl;
	for(int j=0;j<cnt-1;j++)
	{
		int x=suf[j].f,y=suf[j+1].f,c1=suf[j].s,c2=suf[j+1].s;
		int l=0,r=min(a[x].size()-c1,a[y].size()-c2)+1,mid;
		while(l+1<r)
		{
			mid=(l+r)/2;
			if(get(x,c1,mid)==get(y,c2,mid))
				l=mid;
			else
				r=mid;
		}
		b[j]=l;
		//cerr<<"J : "<<j<<" "<<b[j]<<endl;
		spars[0][j]=b[j];
	}
	for(int i=1;i<20;i++)
	{
		for(int j=0;j<cnt-1;j++)
		{
			if(j+(1<<(i-1))>=cnt-1)
				spars[i][j]=spars[i-1][j];
			else
				spars[i][j]=min(spars[i-1][j],spars[i-1][j+(1<<(i-1))]);
			//cerr<<"I&J : "<<i<<" "<<j<<" "<<spars[i][j]<<endl;
		}
	}
	//cerr<<"DAMN : "<<say(0,2)<<endl;
	int p2=0,tp=1;
	check[suf[0].f]=1;
	for(int i=0;i<cnt;i++)
	{
		while(tp<k&&p2<cnt)
		{
			p2++;
			if(p2==cnt)
				break;
			check[suf[p2].f]++;
			if(check[suf[p2].f]==1)
				tp++;
		}
		nxt[i]=p2;
		check[suf[i].f]--;
		if(check[suf[i].f]==0)
			tp--;
		//cerr<<"NXTI : "<<i<<" "<<nxt[i]<<endl;
	}
	for(int i=0;i<cnt;i++)
	{
		//cerr<<"I : "<<i<<endl;
		int x=suf[i].f,y=suf[i].s;
		int l=0,r=a[x].size()-y+1,mid;
		//cerr<<"L & R : "<<l<<" "<<r<<endl;
		while(l+1<r)
		{
			mid=(l+r)/2;
			p2=found(i,mid);
			//cerr<<"MID : "<<mid<<" "<<p2<<endl;
			if(nxt[p2]==cnt)
			{
				r=mid;
				continue;
			}
			if(nxt[p2]<=i)
			{
				l=mid;
				continue;
			}
			if(say(p2,nxt[p2]-1)>=mid)
				l=mid;
			else
				r=mid;
		}
		//cerr<<"I & L : "<<i<<" "<<l<<endl;
		ans[x]+=l;
	}
	for(int i=0;i<n;i++)
		cout<<ans[i]<<" ";
	return 0;
}


///Chefer

#include<bits/stdc++.h>
//#pragma GCC optimize("O2")
#define int long long int
#define f first
#define s second
#define rand() rand()*rand()

using namespace std;

typedef pair<int,int> pii;
typedef pair<pii,int> pip;
const int maxn=1e5+6,base=32,mod=1e9+7;
int rnk[maxn];
string a[maxn];
int ans[maxn];
int b[maxn];
pii p[maxn];
int cnt;
pip tmp[maxn];
pii suf[maxn];
vector<int> h[maxn],h2[maxn];
int po[maxn],po2[maxn];
int spars[20][maxn];
int nxt[maxn];
int check[maxn];
int lg[maxn];
int get(int x,int y,int len)
{
	return h[x][y]-h[x][y+len]*po[len];
}
int get2(int x,int y,int len)
{
	return ((h2[x][y]-h2[x][y+len]*po2[len])%mod+mod)%mod;
}

int say(int l,int r)
{
	int len=(r-l+1);
	int t=lg[len];
	int ret=spars[t][l];
	len-=(1<<t);
	ret=min(ret,spars[t][l+len]);
	return ret;
}
int found(int x,int len)
{
	int r=x,l=-1,mid;
	while(l+1<r)
	{
		mid=(l+r)/2;
		//cerr<<"MID & X : "<<mid<<" "<<x-1<<" "<<say(mid,x-1)<<endl;
		if(say(mid,x-1)>=len)
			r=mid;
		else
			l=mid;
	}
	return r;
}
main()
{
	ios_base::sync_with_stdio(false);
	lg[0]=0;
	for(int i=1;i<maxn;i++)
	{
		if((1<<lg[i-1])*2==i)
			lg[i]=lg[i-1]+1;
		else
			lg[i]=lg[i-1];
	}
	po[0]=1;
	po2[0]=1;
	for(int i=1;i<maxn;i++)
		po[i]=po[i-1]*base,po2[i]=(po2[i-1]*base)%mod;
	int n,k;
	cin>>n>>k;
	for(int i=0;i<n;i++)
	{
		cin>>a[i];
		for(int j=0;j<a[i].size();j++)
		{
			h[i].push_back(0);
			h[i].push_back(0);
			h2[i].push_back(0);
			h2[i].push_back(0);

			p[cnt]=pii(i,j);
			cnt++;
		}
		h[i][a[i].size()-1]=a[i].back()-'a'+1;
		h2[i][a[i].size()-1]=a[i].back()-'a'+1;
		if(a[i].size()==1)
			continue;
		for(int j=a[i].size()-2;j>=0;j--)
		{
			h[i][j]=h[i][j+1]*base+a[i][j]-'a'+1;
			h2[i][j]=(h2[i][j+1]*base+a[i][j]-'a'+1)%mod;
		}
	}
	if(k==1)
	{
		for(int i=0;i<n;i++)
			cout<<((int)a[i].size()*a[i].size()+a[i].size())/2<<" ";
		return 0;
	}
	for(int i=0;i<cnt;i++)
		rnk[i]=a[p[i].f][p[i].s]-'a';
	for(int i=1;i<=20;i++)
	{
		for(int j=0;j<cnt;j++)
		{
			if((1<<(i-1))+p[j].s>=a[p[j].f].size())
				tmp[j]=pip(pii(rnk[j],-1),j);
			else
				tmp[j]=pip(pii(rnk[j],rnk[j+(1<<(i-1))]),j);
		}
		sort(tmp,tmp+cnt);
		rnk[tmp[0].s]=0;
		for(int j=1;j<cnt;j++)
		{
			if(tmp[j].f.f!=tmp[j-1].f.f||tmp[j].f.s!=tmp[j-1].f.s)
				rnk[tmp[j].s]=j;
			else
				rnk[tmp[j].s]=rnk[tmp[j-1].s];
		}
	}
	for(int i=0;i<cnt;i++)
		suf[i]=p[tmp[i].s];//,cerr<<suf[i].f<<" "<<suf[i].s<<endl;
	//cerr<<endl;
	for(int j=0;j<cnt-1;j++)
	{
		int x=suf[j].f,y=suf[j+1].f,c1=suf[j].s,c2=suf[j+1].s;
		int l=0,r=min(a[x].size()-c1,a[y].size()-c2)+1,mid;
		while(l+1<r)
		{
			mid=(l+r)/2;
			if(get(x,c1,mid)==get(y,c2,mid)&&get2(x,c1,mid)==get2(y,c2,mid))
				l=mid;
			else
				r=mid;
		}
		b[j]=l;
		//cerr<<"J : "<<j<<" "<<b[j]<<endl;
		spars[0][j]=b[j];
	}
	for(int i=1;i<20;i++)
	{
		for(int j=0;j<cnt-1;j++)
		{
			if(j+(1<<(i-1))>=cnt-1)
				spars[i][j]=spars[i-1][j];
			else
				spars[i][j]=min(spars[i-1][j],spars[i-1][j+(1<<(i-1))]);
			//cerr<<"I&J : "<<i<<" "<<j<<" "<<spars[i][j]<<endl;
		}
	}
	//cerr<<"DAMN : "<<say(0,2)<<endl;
	int p2=0,tp=1;
	check[suf[0].f]=1;
	for(int i=0;i<cnt;i++)
	{
		while(tp<k&&p2<cnt)
		{
			p2++;
			if(p2==cnt)
				break;
			check[suf[p2].f]++;
			if(check[suf[p2].f]==1)
				tp++;
		}
		nxt[i]=p2;
		check[suf[i].f]--;
		if(check[suf[i].f]==0)
			tp--;
		//cerr<<"NXTI : "<<i<<" "<<nxt[i]<<endl;
	}
	for(int i=0;i<cnt;i++)
	{
		//cerr<<"I : "<<i<<endl;
		int x=suf[i].f,y=suf[i].s;
		int l=0,r=a[x].size()-y+1,mid;
		//cerr<<"L & R : "<<l<<" "<<r<<endl;
		while(l+1<r)
		{
			mid=(l+r)/2;
			p2=found(i,mid);
			//cerr<<"MID : "<<mid<<" "<<p2<<endl;
			if(nxt[p2]==cnt)
			{
				r=mid;
				continue;
			}
			if(nxt[p2]<=i)
			{
				l=mid;
				continue;
			}
			if(say(p2,nxt[p2]-1)>=mid)
				l=mid;
			else
				r=mid;
		}
		//cerr<<"I & L : "<<i<<" "<<l<<endl;
		ans[x]+=l;
	}
	for(int i=0;i<n;i++)
		cout<<ans[i]<<" ";
	return 0;
}


///Chefer

#include<bits/stdc++.h>
#define int long long int
#define f first
#define s second
#define rand() rand()*rand()

using namespace std;

typedef pair<int,int> pii;
typedef pair<pii,int> pip;
const int maxn=1e5+6,base=32;
int rnk[maxn];
string a[maxn];
int ans[maxn];
int b[maxn];
pii p[maxn];
int cnt;
pip tmp[maxn];
pii suf[maxn];
vector<int> h[maxn];
int po[maxn];
int spars[20][maxn];
int nxt[maxn];
int check[maxn];
int lg[maxn];
int get(int x,int y,int len)
{
	return h[x][y]-h[x][y+len]*po[len];
}
int say(int l,int r)
{
	int len=(r-l+1);
	int t=lg[len];
	int ret=spars[t][l];
	len-=(1<<t);
	ret=min(ret,spars[t][l+len]);
	return ret;
}
int found(int x,int len)
{
	int r=x,l=-1,mid;
	while(l+1<r)
	{
		mid=(l+r)/2;
		//cerr<<"MID & X : "<<mid<<" "<<x-1<<" "<<say(mid,x-1)<<endl;
		if(say(mid,x-1)>=len)
			r=mid;
		else
			l=mid;
	}
	return r;
}
main()
{
	ios_base::sync_with_stdio(false);
	lg[0]=0;
	for(int i=1;i<maxn;i++)
	{
		if((1<<lg[i-1])*2==i)
			lg[i]=lg[i-1]+1;
		else
			lg[i]=lg[i-1];
	}
	po[0]=1;
	for(int i=1;i<maxn;i++)
		po[i]=po[i-1]*base;
	int n,k;
	cin>>n>>k;
	for(int i=0;i<n;i++)
	{
		cin>>a[i];
		for(int j=0;j<a[i].size();j++)
		{
			h[i].push_back(0);
			p[cnt]=pii(i,j);
			cnt++;
		}
		h[i][a[i].size()-1]=a[i].back()-'a'+1;
		if(a[i].size()==1)
			continue;
		for(int j=a[i].size()-2;j>=0;j--)
			h[i][j]=h[i][j+1]*base+a[i][j]-'a'+1;
	}
	if(k==1)
	{
		for(int i=0;i<n;i++)
			cout<<((int)a[i].size()*a[i].size()+a[i].size())/2<<" ";
		return 0;
	}
	for(int i=0;i<cnt;i++)
		rnk[i]=a[p[i].f][p[i].s]-'a';
	for(int i=1;i<=20;i++)
	{
		for(int j=0;j<cnt;j++)
		{
			if((1<<(i-1))+p[j].s>=a[p[j].f].size())
				tmp[j]=pip(pii(rnk[j],-1),j);
			else
				tmp[j]=pip(pii(rnk[j],rnk[j+(1<<(i-1))]),j);
		}
		sort(tmp,tmp+cnt);
		rnk[tmp[0].s]=0;
		for(int j=1;j<cnt;j++)
		{
			if(tmp[j].f.f!=tmp[j-1].f.f||tmp[j].f.s!=tmp[j-1].f.s)
				rnk[tmp[j].s]=j;
			else
				rnk[tmp[j].s]=rnk[tmp[j-1].s];
		}
	}
	for(int i=0;i<cnt;i++)
		suf[i]=p[tmp[i].s];//,cerr<<suf[i].f<<" "<<suf[i].s<<endl;
	//cerr<<endl;
	for(int j=0;j<cnt-1;j++)
	{
		int x=suf[j].f,y=suf[j+1].f,c1=suf[j].s,c2=suf[j+1].s;
		int l=0,r=min(a[x].size()-c1,a[y].size()-c2)+1,mid;
		while(l+1<r)
		{
			mid=(l+r)/2;
			if(get(x,c1,mid)==get(y,c2,mid))
				l=mid;
			else
				r=mid;
		}
		b[j]=l;
		//cerr<<"J : "<<j<<" "<<b[j]<<endl;
		spars[0][j]=b[j];
	}
	for(int i=1;i<5;i++)
	{
		for(int j=0;j<cnt-1;j++)
		{
			if(j+(1<<(i-1))>=cnt-1)
				spars[i][j]=spars[i-1][j];
			else
				spars[i][j]=min(spars[i-1][j],spars[i-1][j+(1<<(i-1))]);
			//cerr<<"I&J : "<<i<<" "<<j<<" "<<spars[i][j]<<endl;
		}
	}
	//cerr<<"DAMN : "<<say(0,2)<<endl;
	int p2=0,tp=1;
	check[suf[0].f]=1;
	for(int i=0;i<cnt;i++)
	{
		while(tp<k&&p2<cnt)
		{
			p2++;
			if(p2==cnt)
				break;
			check[suf[p2].f]++;
			if(check[suf[p2].f]==1)
				tp++;
		}
		nxt[i]=p2;
		check[suf[i].f]--;
		if(check[suf[i].f]==0)
			tp--;
		//cerr<<"NXTI : "<<i<<" "<<nxt[i]<<endl;
	}
	for(int i=0;i<cnt;i++)
	{
		//cerr<<"I : "<<i<<endl;
		int x=suf[i].f,y=suf[i].s;
		int l=0,r=a[x].size()-y+1,mid;
		//cerr<<"L & R : "<<l<<" "<<r<<endl;
		while(l+1<r)
		{
			mid=(l+r)/2;
			p2=found(i,mid);
			//cerr<<"MID : "<<mid<<" "<<p2<<endl;
			if(nxt[p2]==cnt)
			{
				r=mid;
				continue;
			}
			if(nxt[p2]<=i)
			{
				l=mid;
				continue;
			}
			if(say(p2,nxt[p2]-1)>=mid)
				l=mid;
			else
				r=mid;
		}
		//cerr<<"I & L : "<<i<<" "<<l<<endl;
		ans[x]+=l;
	}
	for(int i=0;i<n;i++)
		cout<<ans[i]<<" ";
	return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<set>
#define pb push_back
using namespace std;
const int maxv=2e5;
int n,k,br,ind[maxv+10],niz[maxv+10],p[maxv+10],cnt[maxv+10],pm[maxv+10],pniz[maxv+10],rnk[maxv+10],lcp[maxv+10],ss[maxv+10],uk,brojac[maxv+10],lseg[2*maxv+10],rseg[2*maxv+10],brs;
int dp[20][maxv+10],len[maxv+10],lr[maxv+10],rl[maxv+10],rez[maxv+10];
long long sol[maxv+10];
vector<int>vect[maxv+10],vect2[maxv+10];
int get(int x){
return x-'a'+1+n;
}
bool srt(int x,int y){
   return niz[x]<niz[y];
}
void prek(){
  for(int i=0;i<br;i++)dp[0][i]=lcp[i];
  int h=log2(br);
  for(int i=1;i<=h;i++)
  for(int j=0;j<br;j++){
    if(j+(1<<i)-1>=br)break;
    dp[i][j]=min(dp[i-1][j],dp[i-1][j+(1<<(i-1))]);
  }
}
int query(int l,int r){
   if(l==r){
     int id=p[l];
     return len[id];
   }
   r--;
   int h=log2(r-l+1);
   return min(dp[h][l],dp[h][r-(1<<h)+1]);
}
struct op{
   bool operator()(int x,int y){
     return x>y;
   }
};
int main(){

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

    /// shiftujem aflabet za n+1
    int curr=0;
    for(int i=1;i<=n;i++){
      string a;
      cin>>a;
      curr++;
      for(int j=br;j<=br+a.size();j++){
        niz[j]=get(a[j-br]);
        ind[j]=i;
        ss[j]=niz[j];
        len[j]=br+a.size()-j;
      }
      br+=a.size();
      niz[br++]=curr;
      ss[br-1]=niz[br-1];
      ind[br-1]=i;
    }

    for(int i=0;i<br;i++)p[i]=i;
    sort(p,p+br,srt);

    for(int i=1;(1<<(i-1))<br;i++){

        for(int j=0;j<br;j++)p[j]=(p[j]-(1<<(i-1))+br)%br;

        memset(cnt,0,sizeof(cnt));
        for(int j=0;j<br;j++)cnt[niz[j]]++;
        for(int j=1;j<=maxv;j++)cnt[j]+=cnt[j-1];
        for(int j=br-1;j>=0;j--)pm[--cnt[ niz[p[j]] ] ]=p[j];
        for(int j=0;j<br;j++)p[j]=pm[j];

        pniz[p[0]]=1;
        for(int j=1;j<br;j++){

            int id=p[j];
            int id2=p[j-1];

            if(niz[id]==niz[id2] && niz[(id+(1<<(i-1)))%br]==niz[(id2+(1<<(i-1)))%br])pniz[p[j]]=pniz[p[j-1]];
            else pniz[p[j]]=pniz[p[j-1]]+1;
        }

        for(int j=0;j<br;j++)niz[j]=pniz[j];

    }

    for(int i=0;i<br;i++)rnk[p[i]]=i;

    int clcp=0;
    for(int i=0;i<br;i++){

        if(rnk[i]==br-1){
            lcp[rnk[i]]=0;
            clcp=0;
            continue;
        }

        int j=p[rnk[i]+1];
        while(j+clcp<br && i+clcp<br && ss[i+clcp]==ss[j+clcp])clcp++;
        lcp[rnk[i]]=clcp;

        if(clcp)clcp--;
    }

    ///for(int i=0;i<br;i++)printf("%d %d\n",p[i],len[p[i]]);

    int l=n;
    int r=l;

    uk=0;

    while(r<br){

        while(r<br && uk<k){
            if(brojac[ind[p[r]]]==0)uk++;
            brojac[ind[p[r]]]++;
            r++;
        }
        if(uk<k)break;

        while(uk>=k){
            lseg[++brs]=l;
            rseg[brs]=r-1;
            brojac[ind[p[l]]]--;
            if(brojac[ind[p[l]]]==0)uk--;
            l++;
        }
    }

    ///for(int i=1;i<=brs;i++)printf("%d %d  segments\n",lseg[i],rseg[i]);

    prek();

    for(int i=1;i<=brs;i++){
       vect[lseg[i]].pb(query(lseg[i],rseg[i]));
       vect2[rseg[i]+1].pb(query(lseg[i],rseg[i]));

       lr[rseg[i]]=max(lr[rseg[i]],lseg[i]);
       rl[lseg[i]]=min(rl[lseg[i]],rseg[i]);
    }

    /// left-right
    curr=0;
    for(int i=n;i<br;i++){
        if(lr[i]!=0)curr=max(curr,lr[i]);
        rez[i]=max(rez[i],query(curr,i));
    }

    /// right-left
    curr=0;
    for(int i=br-1;i>=n;i--){
        if(rl[i]!=0)curr=min(curr,rl[i]);
        if(curr!=0)rez[i]=max(rez[i],query(i,curr));
    }

    multiset<int,op>kek;
    for(int i=n;i<br;i++){
       for(int j=0;j<vect2[i].size();j++)kek.erase(vect2[i][j]);
       for(int j=0;j<vect[i].size();j++)kek.insert(vect[i][j]);

       rez[i]=max(rez[i],*(kek.begin()));
    }

    for(int j=n;j<br;j++){
        ///printf("%d\n",rez[j]);
        sol[ind[p[j]]]+=(long long)rez[j];
    }
    for(int j=1;j<=n;j++)printf("%lld ",sol[j]);

return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
#include<set>
#define pb push_back
using namespace std;
const int maxv=4e5;
const int K=28;
int tp,ts,tv,r[maxv],l[maxv],s[maxv],p[maxv],t[maxv][K],cl,niz[maxv],br,ind[maxv],cnt[maxv],k,len[maxv],n;
long long sol[maxv];
set<int>st[maxv];
void extend(int x){
   suff:;
   if(tp>r[tv]){
    if(t[tv][x]==-1){t[tv][x]=ts;l[ts]=cl;p[ts++]=tv;tv=s[tv];tp=r[tv]+1;goto suff;}
    tv=t[tv][x];
    tp=l[tv];
   }
   if(tp==-1 || niz[tp]==x)tp++;
   else{
    p[ts]=p[tv];l[ts]=l[tv];r[ts]=tp-1;t[ts][x]=ts+1;t[ts][niz[tp]]=tv;
    l[tv]=tp;p[tv]=ts;l[ts+1]=cl;p[ts+1]=ts;t[p[ts]][niz[l[ts]]]=ts;ts+=2;
    tv=s[p[ts-2]];tp=l[ts-2];
    while(tp<=r[ts-2]){tv=t[tv][niz[tp]];tp+=r[tv]-l[tv]+1;}
    if(tp==r[ts-2]+1)s[ts-2]=tv;
    else s[ts-2]=ts;
    tp=r[tv]-(tp-r[ts-2])+2;
    goto suff;
   }
}
void make_suff(){

   fill(r,r+maxv,br-1);
   ts=2;
   tv=0;
   tp=0;
   s[0]=1;
   l[0]=l[1]=r[0]=r[1]=-1;
   memset(t,-1,sizeof(t));
   for(int i=0;i<K;i++)t[1][i]=0;

   for(cl=0;cl<br;cl++)
    extend(niz[cl]);
}
void transfer(int x,int y){
   for(set<int>::iterator it=st[y].begin();it!=st[y].end();it++)
    st[x].insert(*it);
   st[y].clear();
}
void enumerate(int x,int currlen){

    currlen+=r[x]-l[x]+1;
    if(x==0)currlen--;

    int child=0;
    for(int i=0;i<K;i++){
       int id=t[x][i];
       if(t[x][i]==-1)continue;
       child++;
       enumerate(t[x][i],currlen);
       if(st[x].size()<st[id].size())swap(st[x],st[id]);
       transfer(x,id);
    }
    if(child==0)st[x].insert(ind[br-currlen]);
    cnt[x]=st[x].size();
}
void calc(int x,int currlen,int aclen){

   if(cnt[x]>=k)currlen+=r[x]-l[x]+1;
   aclen+=r[x]-l[x]+1;
   if(x==0){
    aclen--;
    currlen--;
   }
   int child=0;
   for(int i=0;i<K;i++){
       int id=t[x][i];
       if(t[x][i]==-1)continue;
       child++;
       calc(t[x][i],currlen,aclen);
    }
    if(child==0)sol[ind[br-aclen]]+=(long long)min(len[br-aclen],currlen);
}
int main(){

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

    int curr=0;
    for(int i=1;i<=n;i++){
      string a;
      cin>>a;
      curr++;
      for(int j=br;j<=br+a.size();j++){
        niz[j]=a[j-br]-'a';
        ind[j]=i;
        len[j]=br+a.size()-j;
      }
      br+=a.size();
      niz[br++]=26;
      ind[br-1]=0;
    }
    niz[br-1]=27;

    make_suff();

    enumerate(0,0);
    calc(0,0,0);

    for(int i=1;i<=n;i++)printf("%lld ",sol[i]);

return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#define pb push_back
using namespace std;
const int maxv=2e5;
int n,k,br,ind[maxv+10],niz[maxv+10],p[maxv+10],cnt[maxv+10],pm[maxv+10],pniz[maxv+10],rnk[maxv+10],lcp[maxv+10],ss[maxv+10],uk,brojac[maxv+10],lseg[2*maxv+10],rseg[2*maxv+10],brs;
int dp[20][maxv+10],len[maxv+10],lr[maxv+10],rl[maxv+10],rez[maxv+10];
long long sol[maxv+10];
vector<int>vect[maxv+10],vect2[maxv+10];
int get(int x){
return x-'a'+1+n;
}
bool srt(int x,int y){
   return niz[x]<niz[y];
}
void prek(){
  for(int i=0;i<br;i++)dp[0][i]=lcp[i];
  int h=log2(br);
  for(int i=1;i<=h;i++)
  for(int j=0;j<br;j++){
    if(j+(1<<i)-1>=br)break;
    dp[i][j]=min(dp[i-1][j],dp[i-1][j+(1<<(i-1))]);
  }
}
int query(int l,int r){
   if(l==r){
     int id=p[l];
     return len[id];
   }
   r--;
   int h=log2(r-l+1);
   return min(dp[h][l],dp[h][r-(1<<h)+1]);
}
struct op{
   bool operator()(int x,int y){
     return x>y;
   }
};
int main(){

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

    /// shiftujem aflabet za n+1
    int curr=0;
    for(int i=1;i<=n;i++){
      string a;
      cin>>a;
      curr++;
      for(int j=br;j<=br+a.size();j++){
        niz[j]=get(a[j-br]);
        ind[j]=i;
        ss[j]=niz[j];
        len[j]=br+a.size()-j;
      }
      br+=a.size();
      niz[br++]=curr;
      ss[br-1]=niz[br-1];
      ind[br-1]=i;
    }

    for(int i=0;i<br;i++)p[i]=i;
    sort(p,p+br,srt);

    for(int i=1;(1<<(i-1))<br;i++){

        for(int j=0;j<br;j++)p[j]=(p[j]-(1<<(i-1))+br)%br;

        memset(cnt,0,sizeof(cnt));
        for(int j=0;j<br;j++)cnt[niz[j]]++;
        for(int j=1;j<=maxv;j++)cnt[j]+=cnt[j-1];
        for(int j=br-1;j>=0;j--)pm[--cnt[ niz[p[j]] ] ]=p[j];
        for(int j=0;j<br;j++)p[j]=pm[j];

        pniz[p[0]]=1;
        for(int j=1;j<br;j++){

            int id=p[j];
            int id2=p[j-1];

            if(niz[id]==niz[id2] && niz[(id+(1<<(i-1)))%br]==niz[(id2+(1<<(i-1)))%br])pniz[p[j]]=pniz[p[j-1]];
            else pniz[p[j]]=pniz[p[j-1]]+1;
        }

        for(int j=0;j<br;j++)niz[j]=pniz[j];

    }

    for(int i=0;i<br;i++)rnk[p[i]]=i;

    int clcp=0;
    for(int i=0;i<br;i++){

        if(rnk[i]==br-1){
            lcp[rnk[i]]=0;
            clcp=0;
            continue;
        }

        int j=p[rnk[i]+1];
        while(j+clcp<br && i+clcp<br && ss[i+clcp]==ss[j+clcp])clcp++;
        lcp[rnk[i]]=clcp;

        if(clcp)clcp--;
    }

    ///for(int i=0;i<br;i++)printf("%d %d\n",p[i],len[p[i]]);

    int l=n;
    int r=l;

    uk=0;

    while(r<br){

        while(r<br && uk<k){
            if(brojac[ind[p[r]]]==0)uk++;
            brojac[ind[p[r]]]++;
            r++;
        }
        if(uk<k)break;

        while(uk>=k){
            lseg[++brs]=l;
            rseg[brs]=r-1;
            brojac[ind[p[l]]]--;
            if(brojac[ind[p[l]]]==0)uk--;
            l++;
        }
    }

    ///for(int i=1;i<=brs;i++)printf("%d %d  segments\n",lseg[i],rseg[i]);

    prek();

    for(int i=1;i<=brs;i++){
       vect[lseg[i]].pb(query(lseg[i],rseg[i]));
       vect2[rseg[i]+1].pb(query(lseg[i],rseg[i]));

       lr[rseg[i]]=max(lr[rseg[i]],lseg[i]);
       rl[lseg[i]]=min(rl[lseg[i]],rseg[i]);
    }

    /// left-right
    curr=0;
    for(int i=n;i<br;i++){
        if(lr[i]!=0)curr=max(curr,lr[i]);
        rez[i]=max(rez[i],query(curr,i));
    }

    /// right-left
    curr=0;
    for(int i=br-1;i>=n;i--){
        if(rl[i]!=0)curr=min(curr,rl[i]);
        if(curr!=0)rez[i]=max(rez[i],query(i,curr));
    }

    multiset<int,op>kek;
    for(int i=n;i<br;i++){
       for(int j=0;j<vect2[i].size();j++)kek.erase(vect2[i][j]);
       for(int j=0;j<vect[i].size();j++)kek.insert(vect[i][j]);

       rez[i]=max(rez[i],*(kek.begin()));
    }

    for(int j=n;j<br;j++){
        ///printf("%d\n",rez[j]);
        sol[ind[p[j]]]+=(long long)rez[j];
    }
    for(int j=1;j<=n;j++)printf("%lld ",sol[j]);

return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
#include<set>
#define pb push_back
using namespace std;
const int maxv=2e5;
int n,k,br,ind[maxv+10],niz[maxv+10],p[maxv+10],cnt[maxv+10],pm[maxv+10],pniz[maxv+10],rnk[maxv+10],lcp[maxv+10],ss[maxv+10],uk,brojac[maxv+10],lseg[2*maxv+10],rseg[2*maxv+10],brs;
int dp[20][maxv+10],len[maxv+10],lr[maxv+10],rl[maxv+10],rez[maxv+10];
long long sol[maxv+10];
vector<int>vect[maxv+10],vect2[maxv+10];
int get(int x){
return x-'a'+1+n;
}
bool srt(int x,int y){
   return niz[x]<niz[y];
}
void prek(){
  for(int i=0;i<br;i++)dp[0][i]=lcp[i];
  int h=log2(br);
  for(int i=1;i<=h;i++)
  for(int j=0;j<br;j++){
    if(j+(1<<i)-1>=br)break;
    dp[i][j]=min(dp[i-1][j],dp[i-1][j+(1<<(i-1))]);
  }
}
int query(int l,int r){
   if(l==r){
     int id=p[l];
     return len[id];
   }
   r--;
   int h=log2(r-l+1);
   return min(dp[h][l],dp[h][r-(1<<h)+1]);
}
struct op{
   bool operator()(int x,int y){
     return x>y;
   }
};
int main(){

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

    /// shiftujem aflabet za n+1
    int curr=0;
    for(int i=1;i<=n;i++){
      string a;
      cin>>a;
      curr++;
      for(int j=br;j<=br+a.size();j++){
        niz[j]=get(a[j-br]);
        ind[j]=i;
        ss[j]=niz[j];
        len[j]=br+a.size()-j;
      }
      br+=a.size();
      niz[br++]=curr;
      ss[br-1]=niz[br-1];
      ind[br-1]=i;
    }

    for(int i=0;i<br;i++)p[i]=i;
    sort(p,p+br,srt);

    for(int i=1;(1<<(i-1))<br;i++){

        for(int j=0;j<br;j++)p[j]=(p[j]-(1<<(i-1))+br)%br;

        memset(cnt,0,sizeof(cnt));
        for(int j=0;j<br;j++)cnt[niz[j]]++;
        for(int j=1;j<=maxv;j++)cnt[j]+=cnt[j-1];
        for(int j=br-1;j>=0;j--)pm[--cnt[ niz[p[j]] ] ]=p[j];
        for(int j=0;j<br;j++)p[j]=pm[j];

        pniz[p[0]]=1;
        for(int j=1;j<br;j++){

            int id=p[j];
            int id2=p[j-1];

            if(niz[id]==niz[id2] && niz[(id+(1<<(i-1)))%br]==niz[(id2+(1<<(i-1)))%br])pniz[p[j]]=pniz[p[j-1]];
            else pniz[p[j]]=pniz[p[j-1]]+1;
        }

        for(int j=0;j<br;j++)niz[j]=pniz[j];

    }

    for(int i=0;i<br;i++)rnk[p[i]]=i;

    int clcp=0;
    for(int i=0;i<br;i++){

        if(rnk[i]==br-1){
            lcp[rnk[i]]=0;
            clcp=0;
            continue;
        }

        int j=p[rnk[i]+1];
        while(j+clcp<br && i+clcp<br && ss[i+clcp]==ss[j+clcp])clcp++;
        lcp[rnk[i]]=clcp;

        if(clcp)clcp--;
    }

    ///for(int i=0;i<br;i++)printf("%d %d\n",p[i],len[p[i]]);

    int l=n;
    int r=l;

    uk=0;

    while(r<br){

        while(r<br && uk<k){
            if(brojac[ind[p[r]]]==0)uk++;
            brojac[ind[p[r]]]++;
            r++;
        }
        if(uk<k)break;

        while(uk>=k){
            lseg[++brs]=l;
            rseg[brs]=r-1;
            brojac[ind[p[l]]]--;
            if(brojac[ind[p[l]]]==0)uk--;
            l++;
        }
    }

    ///for(int i=1;i<=brs;i++)printf("%d %d  segments\n",lseg[i],rseg[i]);

    prek();

    for(int i=1;i<=brs;i++){
       vect[lseg[i]].pb(query(lseg[i],rseg[i]));
       vect2[rseg[i]+1].pb(query(lseg[i],rseg[i]));

       lr[rseg[i]]=max(lr[rseg[i]],lseg[i]);
       rl[lseg[i]]=min(rl[lseg[i]],rseg[i]);
    }

    /// left-right
    curr=0;
    for(int i=n;i<br;i++){
        if(lr[i]!=0)curr=max(curr,lr[i]);
        rez[i]=max(rez[i],query(curr,i));
    }

    /// right-left
    curr=0;
    for(int i=br-1;i>=n;i--){
        if(rl[i]!=0)curr=min(curr,rl[i]);
        if(curr!=0)rez[i]=max(rez[i],query(i,curr));
    }

    multiset<int,op>kek;
    for(int i=n;i<br;i++){
       for(int j=0;j<vect2[i].size();j++)kek.erase(vect2[i][j]);
       for(int j=0;j<vect[i].size();j++)kek.insert(vect[i][j]);

       rez[i]=max(rez[i],*(kek.begin()));
    }

    for(int j=n;j<br;j++){
        ///printf("%d\n",rez[j]);
        sol[ind[p[j]]]+=(long long)rez[j];
    }
    for(int j=1;j<=n;j++)printf("%lld ",sol[j]);

return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
#include<set>
#define pb push_back
using namespace std;
const int maxv=4e5;
const int K=28;
int tp,ts,tv,r[maxv],l[maxv],s[maxv],p[maxv],t[maxv][K],cl,niz[maxv],br,ind[maxv],cnt[maxv],k,len[maxv],n;
long long sol[maxv];
set<int>st[maxv];
void extend(int x){
   suff:;
   if(tp>r[tv]){
    if(t[tv][x]==-1){t[tv][x]=ts;l[ts]=cl;p[ts++]=tv;tv=s[tv];tp=r[tv]+1;goto suff;}
    tv=t[tv][x];
    tp=l[tv];
   }
   if(tp==-1 || niz[tp]==x)tp++;
   else{
    p[ts]=p[tv];l[ts]=l[tv];r[ts]=tp-1;t[ts][x]=ts+1;t[ts][niz[tp]]=tv;
    l[tv]=tp;p[tv]=ts;l[ts+1]=cl;p[ts+1]=ts;t[p[ts]][niz[l[ts]]]=ts;ts+=2;
    tv=s[p[ts-2]];tp=l[ts-2];
    while(tp<=r[ts-2]){tv=t[tv][niz[tp]];tp+=r[tv]-l[tv]+1;}
    if(tp==r[ts-2]+1)s[ts-2]=tv;
    else s[ts-2]=ts;
    tp=r[tv]-(tp-r[ts-2])+2;
    goto suff;
   }
}
void make_suff(){

   fill(r,r+maxv,br-1);
   ts=2;
   tv=0;
   tp=0;
   s[0]=1;
   l[0]=l[1]=r[0]=r[1]=-1;
   memset(t,-1,sizeof(t));
   for(int i=0;i<K;i++)t[1][i]=0;

   for(cl=0;cl<br;cl++)
    extend(niz[cl]);
}
void transfer(int x,int y){
   for(set<int>::iterator it=st[y].begin();it!=st[y].end();it++)
    st[x].insert(*it);
   st[y].clear();
}
void enumerate(int x,int currlen){

    currlen+=r[x]-l[x]+1;
    if(x==0)currlen--;

    int child=0;
    for(int i=0;i<K;i++){
       int id=t[x][i];
       if(t[x][i]==-1)continue;
       child++;
       enumerate(t[x][i],currlen);
       if(st[x].size()<st[id].size())swap(st[x],st[id]);
       transfer(x,id);
    }
    if(child==0)st[x].insert(ind[br-currlen]);
    cnt[x]=st[x].size();
}
void calc(int x,int currlen,int aclen){

   if(cnt[x]>=k)currlen+=r[x]-l[x]+1;
   aclen+=r[x]-l[x]+1;
   if(x==0){
    aclen--;
    if(cnt[x]>=k)currlen--;
   }
   int child=0;
   for(int i=0;i<K;i++){
       int id=t[x][i];
       if(t[x][i]==-1)continue;
       child++;
       calc(t[x][i],currlen,aclen);
    }
    if(child==0)sol[ind[br-aclen]]+=(long long)min(len[br-aclen],currlen);
}
int main(){

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

    int curr=0;
    for(int i=1;i<=n;i++){
      string a;
      cin>>a;
      curr++;
      for(int j=br;j<=br+a.size();j++){
        niz[j]=a[j-br]-'a';
        ind[j]=i;
        len[j]=br+a.size()-j;
      }
      br+=a.size();
      niz[br++]=26;
      ind[br-1]=0;
    }
    niz[br-1]=27;

    make_suff();

    enumerate(0,0);
    calc(0,0,0);

    for(int i=1;i<=n;i++)printf("%lld ",sol[i]);

return 0;
}


#include<string>
#include<cstring>
#include<vector>
#include<algorithm>
#include<map>
#include<set>
#include<deque>
#include<iomanip>
#include<sstream>
#include<stack>
#include<iostream>
#include<limits>
#include<bitset>
#include<list>
#include<queue>
#include<memory>
#include<functional>
#include<unordered_map>

#define For(n) for(int i=0;i<n;++i)
using namespace std;
const int N = 200010;
struct EXSAM_node
{
	EXSAM_node *next[26],*pre;
	//bitset<10> part;//属于哪个主串
	int step;
	int bel;
	int size;
	int visit;
	int cnt[3];
	unordered_map<int, int> cnt2;
	void clear()
	{
		pre = NULL;
		step = 0;
		size = 0;
		visit = 0;
		memset(next, 0, sizeof(next));
		memset(cnt, 0, sizeof(cnt));
	}
};
EXSAM_node EXSAM_Pool[N * 2];
EXSAM_node *EXpool[N * 2];
long d[N * 2];
struct EXSAM
{
	EXSAM_node *root, *last;
	EXSAM_node  *cur;
	void init()
	{
		cur = EXSAM_Pool;  //cur=当前弧
		root = last = cur++;
		root->clear();
		root->visit = 0;
	}
	void Insert(int w,int i)//第i个子串的字符,每插入新串时last应设置为root
	{
		EXSAM_node *p = last;
		if (p->next[w] && p->next[w]->step == p->step + 1)
		{
			last = p->next[w];
			last->cnt2[i] = 1;
			//last->cnt[i]++;
			return;
		}
		EXSAM_node *np = cur++;
		np->clear();
		np->step = p->step + 1;
			while (p && !p->next[w])
			{
				p->next[w] = np, p = p->pre;
			}
			if (p == 0)
				np->pre = root;
			else
			{
				EXSAM_node *q = p->next[w];
				if (p->step + 1 == q->step)
					np->pre = q;
				else
				{
					EXSAM_node *nq = cur++;
					nq->clear();
					nq->step = p->step + 1;
					memcpy(nq->next, q->next, sizeof(q->next));
					nq->pre = q->pre;
					q->pre = nq;
					np->pre = nq;
					while (p&&p->next[w] == q)
					{
						p->next[w] = nq, p = p->pre;
					}
				}
			}
		last = np;
		last->cnt2[i] = 1;
		//last->cnt[i] = 1;
	}
	void topo()
	{
		// 求出parent树的拓扑序
		int cnt = cur - EXSAM_Pool;
		int maxVal = 0;
		memset(d, 0, sizeof(d));
		for (int i = 1; i < cnt; i++)
		{
			maxVal = max(maxVal, EXSAM_Pool[i].step), d[EXSAM_Pool[i].step]++;
		}
		for (int i = 1; i <= maxVal; i++)
			d[i] += d[i - 1];
		for (int i = 1; i < cnt; i++)
			EXpool[d[EXSAM_Pool[i].step]--] = &EXSAM_Pool[i];
		EXpool[0] = root;
	}
};
long long ans[110000];
int main()
{
	ios::sync_with_stdio(false);
	EXSAM part;
	cin.tie(0);
	cout.tie(0);
	int P, K;
	cin >> P >> K;
	string a, b, c;
	cin.tie(0);
	cout.tie(0);
	part.init();
	memset(ans, 0, sizeof(ans));
	for(int i=0;i<P;++i)
	{
		cin >> a;
		for (auto &s : a)
			part.Insert(s - 'a', i);
		part.last = part.root;
	}
	part.topo();
	int cnt = part.cur - EXSAM_Pool;
	for (int i = cnt-1; i >= 1; i--)
		for (auto &s : EXpool[i]->cnt2)
			EXpool[i]->pre->cnt2[s.first] += s.second;
	for (int i = cnt - 1; i >= 1; i--)
	{
		if (EXpool[i]->cnt2.size() >= K)
			for (auto &s : EXpool[i]->cnt2)
				ans[s.first] += (EXpool[i]->step - EXpool[i]->pre->step)*s.second;
	}
	for (int i = 0; i < P; ++i)
		cout << ans[i] << " ";
		return 0;
}


#include<string>
#include<cstring>
#include<vector>
#include<algorithm>
#include<map>
#include<set>
#include<deque>
#include<iomanip>
#include<sstream>
#include<stack>
#include<iostream>
#include<limits>
#include<bitset>
#include<list>
#include<queue>
#include<memory>
#include<functional>

#define For(n) for(int i=0;i<n;++i)
using namespace std;
const int N = 200010;
struct EXSAM_node
{
	EXSAM_node *next[26],*pre;
	//bitset<10> part;//属于哪个主串
	int step;
	int bel;
	int size;
	int visit;
	int cnt[3];
	map<int, int> cnt2;
	void clear()
	{
		pre = NULL;
		step = 0;
		size = 0;
		visit = 0;
		memset(next, 0, sizeof(next));
		memset(cnt, 0, sizeof(cnt));
	}
};
EXSAM_node EXSAM_Pool[N * 2];
EXSAM_node *EXpool[N * 2];
long d[N * 2];
struct EXSAM
{
	EXSAM_node *root, *last;
	EXSAM_node  *cur;
	void init()
	{
		cur = EXSAM_Pool;  //cur=当前弧
		root = last = cur++;
		root->clear();
		root->visit = 0;
	}
	void Insert(int w,int i)//第i个子串的字符,每插入新串时last应设置为root
	{
		EXSAM_node *p = last;
		if (p->next[w] && p->next[w]->step == p->step + 1)
		{
			last = p->next[w];
			last->cnt2[i] = 1;
			//last->cnt[i]++;
			return;
		}
		EXSAM_node *np = cur++;
		np->clear();
		np->step = p->step + 1;
			while (p && !p->next[w])
			{
				p->next[w] = np, p = p->pre;
			}
			if (p == 0)
				np->pre = root;
			else
			{
				EXSAM_node *q = p->next[w];
				if (p->step + 1 == q->step)
					np->pre = q;
				else
				{
					EXSAM_node *nq = cur++;
					nq->clear();
					nq->step = p->step + 1;
					memcpy(nq->next, q->next, sizeof(q->next));
					nq->pre = q->pre;
					q->pre = nq;
					np->pre = nq;
					while (p&&p->next[w] == q)
					{
						p->next[w] = nq, p = p->pre;
					}
				}
			}
		last = np;
		last->cnt2[i] = 1;
		//last->cnt[i] = 1;
	}
	void topo()
	{
		// 求出parent树的拓扑序
		int cnt = cur - EXSAM_Pool;
		int maxVal = 0;
		memset(d, 0, sizeof(d));
		for (int i = 1; i < cnt; i++)
		{
			maxVal = max(maxVal, EXSAM_Pool[i].step), d[EXSAM_Pool[i].step]++;
		}
		for (int i = 1; i <= maxVal; i++)
			d[i] += d[i - 1];
		for (int i = 1; i < cnt; i++)
			EXpool[d[EXSAM_Pool[i].step]--] = &EXSAM_Pool[i];
		EXpool[0] = root;
	}
};
long long ans[110000];
int main()
{
	ios::sync_with_stdio(false);
	EXSAM part;
	int P, K;
	cin >> P >> K;
	string a, b, c;
	cin.tie(0);
	cout.tie(0);
	part.init();
	memset(ans, 0, sizeof(ans));
	for(int i=0;i<P;++i)
	{
		cin >> a;
		for (auto &s : a)
			part.Insert(s - 'a', i);
		part.last = part.root;
	}
	part.topo();
	int cnt = part.cur - EXSAM_Pool;
	for (int i = cnt-1; i >= 1; i--)
		for (auto &s : EXpool[i]->cnt2)
			EXpool[i]->pre->cnt2[s.first] += s.second;
	for (int i = cnt - 1; i >= 1; i--)
	{
		if (EXpool[i]->cnt2.size() >= K)
			for (auto &s : EXpool[i]->cnt2)
				ans[s.first] += (EXpool[i]->step - EXpool[i]->pre->step)*s.second;
	}
	for (int i = 0; i < P; ++i)
		cout << ans[i] << " ";
		return 0;
}


#include<bits/stdc++.h>
#define g0(a) memset(a,0,sizeof(a))
#define gc(a,b) memcpy(a,b,sizeof(a))
#define o 1000005
#define ll long long
#define FOR(i,a,b) for(ll i=a;i<=b;i++)
#define REP(i,a,b) for(ll i=a;i>=b;i--)
#define pa pair<ll,ll>
#define mpp make_pair
#define fi first
#define se second
using namespace std;
inline ll read()
{
	register ll data=0,w=1;
	char ch=0;
	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
	if(ch=='-')w=-1,ch=getchar();
	while(ch>='0'&&ch<='9')data=(data<<1)+(data<<3)+(ch^48),ch=getchar();
	return data*w;
}
int n,ch[200005][27],len[o],pr[o],K,last=1,tot=1;
string s[o];
void insert(int x)
{
	int p=last,np=++tot,tmp=0,q=0,nq=0;len[np]=len[p]+1;
	if(len[ch[p][x]]==len[p]+1)return last=ch[p][x],void();
	while(p&&!ch[p][x])ch[p][x]=np,p=pr[p];
	if(!p)pr[np]=1;
	else
	{
		q=ch[p][x];
		if(len[q]==len[p]+1)pr[np]=q;
		else
		{
			nq=++tot;len[nq]=len[p]+1;
			pr[nq]=pr[q];pr[np]=pr[q]=nq;
			tmp=p;
			gc(ch[nq],ch[q]);
			while(ch[p][x]==q)ch[p][x]=nq,p=pr[p];
		}
	}
	if(tmp==last)last=nq;
	else last=np;
}
vector<int> v[200005];
struct node
{
	int to,next;
}w[o];
int h[o],cnt;
void add(int x,int y){++cnt;w[cnt].to=y;w[cnt].next=h[x];h[x]=cnt;}
int sum[o],ans,L[o];
void add(int v){ans+=(++sum[v]==1);}
void del(int v){ans-=(--sum[v]==0);}
void dsu(int x,int tp)
{
	for(auto y:v[x])(tp==1)?add(y):del(y);
	for(int i=h[x];i;i=w[i].next)
		dsu(w[i].to,tp);
}
int size[o],son[o];
void dfsp(int x)
{
	size[x]=1;
	for(int i=h[x];i;i=w[i].next)
	{
		dfsp(w[i].to);
		size[x]+=size[w[i].to];
		if(size[w[i].to]>size[son[x]])son[x]=w[i].to;
	}
}
int t[o];
void dfs(int x,int tp)
{
	for(int i=h[x];i;i=w[i].next)if(w[i].to!=son[x])dfs(w[i].to,0);
	if(son[x])dfs(son[x],1);
	for(auto y:v[x])add(y);
	for(int i=h[x];i;i=w[i].next)
	{
		int y=w[i].to;
		if(y!=son[x])dsu(y,1);
	}
	t[x]=(ans>=K);
	if(!tp)dsu(x,0);
}
int d[o];
void dfs2(int x)
{
	d[x]+=d[pr[x]]+t[x]*(len[x]-len[pr[x]]);
	for(int i=h[x];i;i=w[i].next)dfs2(w[i].to);
}
int main()
{
	n=read(),K=read();
	FOR(i,1,n)cin>>s[i],L[i]=s[i].length(),s[i]=' '+s[i];
	FOR(i,1,n)
	{
		last=1;
		FOR(j,1,L[i])insert(s[i][j]-'a'),v[last].push_back(i);
	}
	FOR(i,1,tot)if(pr[i])add(pr[i],i);
	dfsp(1);
	dfs(1,1);
	dfs2(1);
	FOR(i,1,n)
	{
		int x=1;
		ll ans=0;
		FOR(j,1,L[i])x=ch[x][s[i][j]-'a'],ans+=d[x];
		cout<<ans<<' ';
	}
	return 0;
}


#include <cstdio>
#include <cstring>
#include <map>

using namespace std;

typedef long long ll;
const int maxLen = 2e5 + 5, maxNode = maxLen << 1, inf = 1e8;
int strNum, common;
struct SuffixTree {
	int curLen, actLen, now, tail;
	map<int, int> ch[maxNode];
	int link[maxNode], curStr[maxLen], start[maxNode], len[maxNode], tag[maxNode], end[maxNode];
	SuffixTree() {
		curLen = actLen = 0;
		now = tail = 1;
		len[0] = inf;
	}
	int NewNode(int st, int le, int flag, int ed) {
		link[++tail] = 1;
		start[tail] = st;
		len[tail] = le;
		tag[tail] = flag;
		end[tail] = ed;
		return tail;
	}
	void Extend(int ins, int flag, int ed) {
		curStr[++curLen] = ins;
		++actLen;
		for (int last = 1; actLen; ) {
			while (actLen > len[ch[now][curStr[curLen - actLen + 1]]])
				actLen -= len[now = ch[now][curStr[curLen - actLen + 1]]];
			int &son = ch[now][curStr[curLen - actLen + 1]], val = curStr[start[son] + actLen - 1];
			if (!son || val == ins) {
				link[last] = now;
				last = now;
				if (!son)
					son = NewNode(curLen - actLen + 1, inf, flag, ed);
				else
					break ;
			} else {
				int split = NewNode(start[son], actLen - 1, 0, inf);
				ch[split][val] = son;
				ch[split][ins] = NewNode(curLen, inf, flag, ed);
				start[son] += actLen - 1;
				len[son] -= actLen - 1;
				link[last] = son = split;
				last = split;
			}
			if (now == 1)
				--actLen;
			else
				now = link[now];
		}
	}
	void Check() {
		for (int pos = 1; pos <= curLen; ++pos)
			printf("%c", curStr[pos] + 'a');
		printf("\n");
		for (int id = 1; id <= tail; ++id) {
			printf("id : %d end : %d start : %d len : %d\n", id, end[id], start[id], len[id]);
			for (auto son : ch[id]) {
				printf("	to : %d\n", son.second);
			}
		}
	}
} sft;
char str[maxLen];
struct SegmentTree {
	int tail;
	int ch[maxNode << 5][2], kind[maxNode << 5];
	void PushUp(int now) {
		if (ch[now][0] || ch[now][1])
			kind[now] = kind[ch[now][0]] + kind[ch[now][1]];
		else
			kind[now] = 1;
	}
	void Insert(int &now, int lEP, int rEP, int val) {
		if (!now)
			now = ++tail;
		if (lEP == rEP) {
			kind[now] = 1;
			return ;
		}
		int mid = (lEP + rEP) >> 1;
		if (val <= mid)
			Insert(ch[now][0], lEP, mid, val);
		else
			Insert(ch[now][1], mid + 1, rEP, val);
		PushUp(now);
	}
	void Merge(int &to, int from) {
		if (!to || !from) {
			to |= from;
			return ;
		}
		Merge(ch[to][0], ch[from][0]);
		Merge(ch[to][1], ch[from][1]);
		PushUp(to); //因为这里不一定不更新叶子节点，所以 PushUp的时候要小心
	}
	void dfs(int now) {
		if (!now)
			return ;
		printf("********* now : %d ls : %d rs : %d\n", now, ch[now][0], ch[now][1]);
		dfs(ch[now][0]);
		dfs(ch[now][1]);
	}
} seg;
int can[maxNode], rt[maxNode], sum[maxNode];
ll ans[maxNode];
void dfs1(int now) {
	if (!now)
		return ;
	sft.len[now] = min(sft.len[now], sft.end[now] - sft.start[now]);
	for (auto son : sft.ch[now]) {
		int to = son.second, charac = son.first;
		dfs1(to);
		seg.Merge(rt[now], rt[to]);
	}
	if (sft.tag[now]) {
		seg.Insert(rt[now], 1, strNum, sft.tag[now]);
	}
	if (seg.kind[rt[now]] >= common) {
		can[now] = 1;
	}
}
void dfs2(int now) {
	if (!now)
		return ;
	if (can[now])
		sum[now] += sft.len[now];
	for (auto son : sft.ch[now]) {
		int to = son.second;
		sum[to] = sum[now];
		dfs2(to);
	}
	if (sft.tag[now]) {
		ans[sft.tag[now]] += sum[now];
//		printf("now : %d tag[now] : %d sum : %d\n", now, sft.tag[now], sum[now]);
	}
}

int main() {
	scanf("%d%d", &strNum, &common);
	int tmp = 0;
	for (int sI = 1; sI <= strNum; ++sI) {
		scanf("%s", str + 1);
		int len = strlen(str + 1);
		tmp += len + 1;
		for (int pos = 1; pos <= len; ++pos)
			sft.Extend(str[pos] - 'a', sI, tmp);
		sft.Extend(25 + sI, sI, tmp);
	}
	dfs1(1);
	dfs2(1);
	for (int sI = 1; sI <= strNum; ++sI)
		printf("%I64d\n", ans[sI]);
	return 0;
}


#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <map>

const int MaxN = 4e5;
typedef long long LL;
using namespace std;

int n, K;
LL res[MaxN + 54];

struct SAM {
	int a[MaxN + 5][26], fa[MaxN + 5], mx[MaxN + 5];
	int last, t; map <int, int> h[MaxN + 5];
	vector <int> G[MaxN + 5];
	SAM() {
		last = t = 0; last = ++t;
	}
	void Insert(int c, int id) {
		int p = last, np = last = ++t; mx[np] = mx[p] + 1;
		h[np][id]++;
		while(p && !a[p][c]) a[p][c] = np, p = fa[p];
		if(!p) fa[np] = 1;
		else {
			int q = a[p][c];
			if(mx[p] + 1 == mx[q]) fa[np] = q;
			else {
				int nq = ++t; mx[nq] = mx[p] + 1;
				memcpy(a[nq], a[q], sizeof(a[q]));
				fa[nq] = fa[q]; fa[np] = fa[q] = nq;
				while(p && a[p][c] == q) a[p][c] = nq, p = fa[p];
			}
		}
	}
	void Pre() {
		for (int i = 0; i <= t; i++) G[i].clear();
		for (int i = 1; i <= t; i++){
			G[fa[i]].push_back(i);
		}
	}
	void Merge(map <int, int> &A, map <int, int> &B) {
		if(A.size() < B.size()) swap(A, B);
		for (auto now : B) A[now.first] += now.second;
		B.clear();
	}
	void Dfs(int x, int K) {
		for (int i = 0; i < G[x].size(); i++) {
			Dfs(G[x][i], K);
			Merge(h[x], h[G[x][i]]);
		}
		if(h[x].size() >= K) {
			for (auto v : h[x]) {
				res[v.first] += (LL)v.second * (mx[x] - mx[fa[x]]);
			}
		}
	}
	void Print() {
		for (int i = 1; i <= n; i++) printf("%I64d ", res[i]); printf("\n");
	}
}sam;

char s[MaxN + 5];

int main()
{
	scanf("%d%d", &n, &K);
	for (int i = 1; i <= n; i++) {
		scanf("%s", s); int len = strlen(s);
		for (int j = 0; j < len; j++) sam.Insert(s[j] - 'a', i);
		sam.last = 1;
	}
	sam.Pre(); sam.Dfs(1, K); sam.Print();
	return 0;
}


#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <map>

const int MaxN = 4e5;
typedef long long LL;
using namespace std;

int n, K;
LL res[MaxN + 54];

struct SAM {
	int a[MaxN + 5][26], fa[MaxN + 5], mx[MaxN + 5];
	int last, t; map <int, int> h[MaxN + 5];
	vector <int> G[MaxN + 5];
	SAM() {
		last = t = 0; last = ++t;
	}
	void Insert(int c, int id) {
		int p = last, np = last = ++t; mx[np] = mx[p] + 1;
		h[np][id]++;
		while(p && !a[p][c]) a[p][c] = np, p = fa[p];
		if(!p) fa[np] = 1;
		else {
			int q = a[p][c];
			if(mx[p] + 1 == mx[q]) fa[np] = p;
			else {
				int nq = ++t; mx[nq] = mx[p] + 1;
				memcpy(a[nq], a[q], sizeof(a[q]));
				fa[nq] = fa[q]; fa[np] = fa[q] = nq;
				while(p && a[p][c] == q) a[p][c] = nq, p = fa[p];
			}
		}
	}
	void Pre() {
		for (int i = 1; i <= t; i++) G[fa[i]].push_back(i);
	}
	void Merge(map <int, int> &A, map <int, int> &B) {
		if(A.size() < B.size()) swap(A, B);
		for (auto now :B) A[now.first] += now.second;
		B.clear();
	}
	void Dfs(int x, int K) {
		for (int i = 0; i < G[x].size(); i++) {
			Dfs(G[x][i], K);
			Merge(h[x], h[G[x][i]]);
		}
		if(h[x].size() >= K) {
			for (auto v : h[x]) {
				res[v.first] += (LL)v.second * (mx[x] - mx[fa[x]]);
			}
		}
	}
	void Print() {
		for (int i = 1; i <= n; i++) printf("%lld ", res[i]); printf("\n");
	}
}sam;

char s[MaxN + 5];

int main()
{
	scanf("%d%d", &n, &K);
	for (int i = 1; i <= n; i++) {
		scanf("%s", s); int len = strlen(s);
		sam.last = 1;
		for (int j = 0; j < len; j++) sam.Insert(s[j] - 'a', i);
	}
	sam.Pre(); sam.Dfs(1, K); sam.Print();
	return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define x first
#define y second

using namespace std;

typedef long long ll;

struct triple
{
    int x, min, max;
    triple(int a = 0, int b = 0, int c = 0) {x = a, min = b, max = c;}
};

struct My_stack
{
    triple masbeg[200005], masend[200005];
    int tail1 = 0, tail2 = 0;
    bool empty()
    {
        return (tail1 == 0) && (tail2 == 0);
    }
    void clear()
    {
        tail1 = 0, tail2 = 0;
        return;
    }
    void add(int x)
    {
        tail2++;
        if (tail2 == 1) masend[tail2] = triple(x, x, x);
        else masend[tail2] = triple(x, min(x, masend[tail2 - 1].min), max(x, masend[tail2 - 1].max));
        return;
    }
    void pop()
    {
        if (tail1 == 0 && tail2 == 0) return;
        if (tail1 > 0) {tail1--; return;}
        while (tail2 > 0)
        {
            tail1++;
            if (tail1 == 1) masbeg[tail1] = triple(masend[tail2].x, masend[tail2].x, masend[tail2].x);
            else masbeg[tail1] = triple(masend[tail2].x, min(masend[tail2].x, masbeg[tail1 - 1].min), max(masend[tail2].x, masbeg[tail1 - 1].max));
            tail2--;
        }
        tail1--;
        return;
    }
    int get_min()
    {
        if (tail1 == 0) return masend[tail2].min;
        if (tail2 == 0) return masbeg[tail1].min;
        return min(masbeg[tail1].min, masend[tail2].min);
    }
    int get_max()
    {
        if (tail1 == 0) return masend[tail2].max;
        if (tail2 == 0) return masbeg[tail1].max;
        return max(masbeg[tail1].max, masend[tail2].max);
    }
};

int mas[200005], copmas[200005], color[200005], copcolor[200005], head[200005];
pair <int, int> origin[200005];
int lcp[200005], ord[200005], endss[200005];
ll answer[200005];
int open[200005], lefts[200005], rights[200005], L[200005], R[200005], kuku[200005];
My_stack S;

bool cmp(int A, int B)
{
    return color[A] < color[B];
}

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    ios_base::sync_with_stdio(0); cin.tie(0);
    int n, k, tail = 0;
    cin >> n >> k;
    for (int i = 1; i <= n; i++)
    {
        string s;
        cin >> s;
        for (int j = 0; j < (int) s.length(); j++)
        {
            mas[tail] = tail;
            color[tail] = 100000 + s[j] - 'a' + 1;
            origin[tail] = mp(100000 + s[j] - 'a' + 1, i);
            tail++;
        }
        mas[tail] = tail;
        color[tail] = i;
        origin[tail] = mp(i, i);
        endss[i] = tail;
        tail++;
    }

    sort(mas, mas + tail, cmp);
    int quant = 0;
    for (int i = 0; i < tail; i++)
    {
        if (i == 0 || origin[mas[i]].x != origin[mas[i - 1]].x) {quant++; head[quant] = i;}
        color[mas[i]] = quant;
    }

    int len = 1;
    while (len < tail)
    {
        for (int i = 0; i < tail; i++)
        {
            int j = (mas[i] - len + tail) % tail;
            copmas[head[color[j]]++] = j;
        }
        quant = 0;
        for (int i = 0; i < tail; i++)
        {
            if (i == 0 || color[copmas[i]] != color[copmas[i - 1]] || color[(copmas[i] + len) % tail] != color[(copmas[i - 1] + len) % tail]) {quant++; head[quant] = i;}
            copcolor[copmas[i]] = quant;
        }
        for (int i = 0; i < tail; i++) mas[i] = copmas[i], color[i] = copcolor[i];
        len *= 2;
    }

    for (int i = 0; i < tail; i++)
        ord[mas[i]] = i;
    int x = 0;
    for (int i = 0; i < tail; i++)
    {
        x = max(x - 1, 0);
        if (ord[i] == tail - 1) x = 0;
        else while (origin[i + x].x == origin[mas[ord[i] + 1] + x].x) x++;
        lcp[ord[i]] = x;
    }

    int tek = 0, uk = -1;
    for (int i = 0; i < tail; i++)
    {
        while (uk + 1 < tail && tek < k)
        {
            uk++;
            if (open[origin[mas[uk]].y] == 0) tek++;
            open[origin[mas[uk]].y]++;
            if (uk > i) S.add(lcp[uk - 1]);
        }
        if (tek < k) break;

        int T = endss[origin[mas[i]].y] - mas[i];
        if (!S.empty()) T = S.get_min();
        lefts[i] = T, rights[uk]++;

        if (!S.empty()) S.pop();
        if (open[origin[mas[i]].y] == 1) tek--;
        open[origin[mas[i]].y]--;
    }
    S.clear();
    for (int i = 0; i < tail; i++)
    {
        S.add(lefts[i]);
        kuku[i] = S.get_max();
        for (int j = 1; j <= rights[i]; j++) S.pop();
    }

    S.clear();
    tek = 0, uk = tail;
    for (int i = 1; i <= n; i++) open[i] = 0;
    for (int i = tail - 1; i >= 0; i--)
    {
        while (uk >= 1 && tek < k)
        {
            uk--;
            if (open[origin[mas[uk]].y] == 0) tek++;
            open[origin[mas[uk]].y]++;
            if (uk < i) S.add(lcp[uk]);
        }
        if (tek < k) break;

        int T = endss[origin[mas[i]].y] - mas[i];
        if (!S.empty()) T = S.get_min();
        R[i] = T, L[uk]++;

        if (!S.empty()) S.pop();
        if (open[origin[mas[i]].y] == 1) tek--;
        open[origin[mas[i]].y]--;
    }
    S.clear();
    for (int i = tail - 1; i >= 0; i--)
    {
        S.add(R[i]);
        kuku[i] = max(S.get_max(), kuku[i]);
        for (int j = 1; j <= L[i]; j++) S.pop();
    }

    for (int i = 0; i < tail; i++) answer[origin[mas[i]].y] += (ll) kuku[i];
    for (int i = 1; i <= n; i++) cout << answer[i] << ' ';
    return 0;
}


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

struct suffixArray{
	string s;
	Long n, alphabet;
	vector<Long> p, c, cnt, rank, lcp;
	vector<Long> posPerm;
	vector< vector<Long> > st;

	suffixArray(){}
	suffixArray(string s) : s(s){
		s += '$'; // add adicional chacracter thas it is lower than other characters
		n = s.size();
		alphabet = 256;
		p.resize(n,0); // p is a permutation of suffix array order
		c.resize(n,0); // c assing a class to every index
		cnt.resize(max(alphabet,n),0); // its a count to use radix sort
		rank.resize(n-1,0); // position of suffix in sorted list of suffixes
		lcp.resize(n-2,0); // lcp between 2 continuous suffix in sorted list of suffixes
	}

	void build(){ //O(nlogn)
		for(Long i = 0; i < n; i++) cnt[s[i]]++;
		for(Long i = 1; i < alphabet; i++) cnt[i] += cnt[i-1];
		for(Long i = 0; i < n; i++) p[--cnt[s[i]]] = i; // get a permutation

		// assing the classes = 0 to the fist in lexicographical order, same substring have same class
		c[p[0]] = 0;
		Long classes = 1;
		for(Long i = 1; i < n; i++){
			if(s[p[i]] != s[p[i-1]]) classes++;
			c[p[i]] = classes - 1;
		}

		vector<Long> pn(n), cn(n);
		for(Long h = 0; (1<<h) < n; h++){
			for(Long i = 0; i < n; i++){
				pn[i] = p[i] - (1<<h);
				if(pn[i] < 0) pn[i] += n;
			}

			// reorder the permutation by the previous substring
			fill(cnt.begin(), cnt.begin() + classes, 0);
			for(Long i = 0; i < n; i++) cnt[c[pn[i]]]++;
			for(Long i = 1; i < classes; i++) cnt[i] += cnt[i-1];
			for(Long i = n-1; i >= 0; i--) p[--cnt[c[pn[i]]]] = pn[i];

			// assing the new classes
			cn[p[0]] = 0;
			classes = 1;
			for(Long i = 1; i < n; i++){
				pair<Long,Long> cur = {c[p[i]],c[(p[i] + (1<<h)) % n]};
				pair<Long,Long> prev = {c[p[i-1]],c[(p[i-1] + (1<<h)) % n]};
				if(cur != prev) classes++;
				cn[p[i]] = classes - 1;
			}
			swap(c,cn);
		}
		n--;
		p.erase(p.begin());
		return;
	}

	// i and j are positions on the string
	Long lcp2(Long i, Long j){ // LCP of 2 substring of s O(1)
		Long l = posPerm[i];
		Long r = posPerm[j];
		if(l > r) swap(l,r);
		Long T = r-l+1;
		Long lg = 31-(__builtin_clz(T));
		return min(st[lg][l],st[lg][r-(1<<lg)+1]);
	}

	void buildST(){ //O(nlogn)
		posPerm.resize(n,0);
		for(Long i = 0; i < n; i++) posPerm[p[i]] = i;
		st.push_back(vector<Long> (n,-1));
		for(Long i = 0; i < n; i++) st[0][i] = n - p[i];
		for(Long h = 1; (1<<h) <= n; h++){
			st.push_back(vector<Long> (n,-1));
			for(Long i = 0; i + (1<<h) - 1 < n; i++){
				st[h][i] = min({st[h-1][i],st[h-1][i+(1<<(h-1))],lcp[i-1+(1<<(h-1))]});
			}
		}
		return;
	}

	void lcp_construction(){ // lcp construction O(n)
		for(Long i = 0; i < n; i++) rank[p[i]] = i;
		Long k = 0;
		for(Long i = 0; i < n; i++){
			if(rank[i] == n - 1){
				k = 0;
				continue;
			}
			Long 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--;
		}
		buildST(); // use if need sparse table in lcp
		return;
	}
};

const Long MX = 1e6 + 10;

Long id[MX];
suffixArray sa;
vector< pair<Long,Long> > update[MX];

string toStr(Long n){
	string cad = "";
	while(n > 0){
		cad += char('0' + n%10);
		n /= 10;
	}
	reverse(cad.begin(),cad.end());
	return cad;
}

Long bb(Long l, Long r, Long ini, Long val){
	while(l != r){
		Long med = (l + r) / 2;
		if(sa.lcp2(sa.p[ini],sa.p[med]) >= val){
			l = med + 1;
		}else{
			r = med;
		}
	}
	if(sa.lcp2(sa.p[ini],sa.p[l]) >= val) l++;
	return l;
}

Long bb2(Long l, Long r, Long fin, Long val){
	while(l != r){
		Long med = (l + r) / 2;
		if(sa.lcp2(sa.p[med],sa.p[fin]) < val){
			l = med + 1;
		}else{
			r = med;
		}
	}
	if(sa.lcp2(sa.p[l],sa.p[fin]) < val) l++;
	return l;
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	cout.precision(10);
	cout << fixed;

	Long n, k;
	cin >> n >> k;

	string s = "", x;
	for(Long i = 1; i <= n; i++){
		cin >> x;
		s += x + toStr(i);
	}

	sa = suffixArray(s);
	sa.build();
	sa.lcp_construction();

	vector<Long> val(s.size(),0);
	vector<Long> mxlen;
	Long pos = 0;
	Long id = 0;
	while(pos < s.size()){
		Long cnt = 0;
		while(pos < s.size() && 'a' <= s[pos] && s[pos] <= 'z'){
			val[pos] = id;
			pos++;
			cnt++;
		}
		for(Long i = 0; i < cnt; i++) mxlen.push_back(cnt-i);
		cnt = 0;
		while(pos < s.size() && !('a' <= s[pos] && s[pos] <= 'z')){
			val[pos] = -1;
			pos++;
			cnt++;
		}
		for(Long i = 0; i < cnt; i++) mxlen.push_back(-1);
		id++;
	}

	Long fin = 0;
	map<Long,Long> cnt;
	for(Long i = 0; i < s.size(); i++){
		while(fin < s.size() && cnt.size() < k){
			if(val[sa.p[fin]] != -1) cnt[val[sa.p[fin]]]++;
			fin++;
		}
		Long auxi = sa.lcp2(sa.p[i],sa.p[fin-1]);
		Long posi = bb(fin-1,s.size()-1,i,auxi);
		if(cnt.size() == k){
			update[i].push_back({1,auxi});
			update[posi].push_back({-1,auxi});
		}
		if(val[sa.p[i]] != -1){
			cnt[val[sa.p[i]]]--;
			if(cnt[val[sa.p[i]]] == 0) cnt.erase(val[sa.p[i]]);
		}
	}

	fin = s.size() - 1;
	cnt.clear();
	for(Long i = s.size() - 1; i >= 0; i--){
		while(fin >= 0 && cnt.size() < k){
			if(val[sa.p[fin]] != -1) cnt[val[sa.p[fin]]]++;
			fin--;
		}
		Long auxi = sa.lcp2(sa.p[fin+1],sa.p[i]);
		Long posi = bb2(0,fin+1,i,auxi);
		if(cnt.size() == k){
			update[posi].push_back({1,auxi});
			update[i+1].push_back({-1,auxi});
		}
		if(val[sa.p[i]] != -1){
			cnt[val[sa.p[i]]]--;
			if(cnt[val[sa.p[i]]] == 0) cnt.erase(val[sa.p[i]]);
		}
	}

	multiset<Long> ms;
	vector<Long> ans(s.size(),0);
	for(Long i = 0; i < s.size(); i++){
		for(auto par : update[i]){
			if(par.first == 1){
				ms.insert(par.second);
			}else{
				ms.erase(ms.find(par.second));
			}
		}
		if(!ms.empty()){
			auto it = ms.end();
			it--;
			ans[i] = min((*it),mxlen[sa.p[i]]);
		}
	}

	vector<long long> rp(n,0);
	for(Long i = 0; i < s.size(); i++){
		if(val[sa.p[i]] != -1){
			rp[val[sa.p[i]]] += (long long) ans[i];
		}
	}

	for(long long xx : rp) cout << xx << " ";
	cout << "\n";
	return 0;
}


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

struct state{
	Long len, link, ult = -1, tot = 0;
	map<char,Long> next;
	state(){}
	state(Long len, Long link) : len(len), link(link){}
};

struct suffixAutomaton{
	vector<bool> isClone;
	vector<state> st;
	Long sz, last;

	suffixAutomaton(){}
	suffixAutomaton(Long n){ // clear map if need reuse!!
		st.resize(n << 1ll);
		isClone.resize(n << 1ll,true);
		last = 0;
		st[0].len = 0;
		st[0].link = -1;
		sz = 1;
	}

	void addChar(char c){
		Long cur = sz++;
		isClone[cur] = false;
		st[cur].len = st[last].len + 1;
		Long p = last;
		while(p != -1 && !st[p].next.count(c)){
			st[p].next[c] = cur;
			p = st[p].link;
		}
		if(p == -1){
			st[cur].link = 0;
		}else{
			Long q = st[p].next[c];
			if(st[p].len + 1 == st[q].len){
				st[cur].link = q;
			}else{
				Long clone = sz++;
				st[clone].len = st[p].len + 1;
            	st[clone].next = st[q].next;
            	st[clone].link = st[q].link;
				while(p != -1 && st[p].next[c] == q){
					st[p].next[c] = clone;
					p = st[p].link;
				}
				st[q].link = st[cur].link = clone;
			}
		}
		last = cur;
	}

	void build(string &s){
		for(char c : s) addChar(c);
		return;
	}

};

const Long MX = 1e5 + 10;
suffixAutomaton sa;

void update(Long cur, Long id){
	while(cur != 0 && sa.st[cur].ult != id){
		sa.st[cur].ult = id;
		sa.st[cur].tot++;
		cur = sa.st[cur].link;
	}
	return;
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	cout.precision(10);
	cout << fixed;

	Long n, k;
	cin >> n >> k;

	sa = suffixAutomaton(MX);

	vector<string> S(n);
	for(Long i = 0; i < n; i++){
		cin >> S[i];
		sa.last = 0;
		for(char c : S[i]) sa.addChar(c);
	}

	for(Long i = 0; i < n; i++){
		Long cur = 0;
		for(char c : S[i]){
			cur = sa.st[cur].next[c];
			update(cur,i);
		}
	}

	for(Long i = 0; i < n; i++){
		long long ans = 0;
		Long cur = 0;
		for(char c : S[i]){
			cur = sa.st[cur].next[c];
			while(cur != 0 && sa.st[cur].tot < k) cur = sa.st[cur].link;
			ans += (long long) sa.st[cur].len;
		}
		cout << ans << " ";
	}
	cout << "\n";
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define REP(i,j,k)     for(int i = j ; i < k ; ++i)
#define RREP(i,j,k)    for(int i = j ; i >=k ; --i)
#define IOS cin.tie(0) , cout.sync_with_stdio(0)
#define endl "\n"
///------------------------------------------------------------
#define int int_fast64_t
#define MAX 200900
#define INF 0x3f3f3f3f

int n , k , pos , id[MAX] , siz[MAX] , ans[MAX];
int N , sa[MAX] , rk[MAX] , lcp[MAX] , sp[MAX][20] , one[MAX];
int gap , tma[MAX] , chr[MAX];
string s;
int cmp(int i , int j){
	if(chr[i] != chr[j]) return chr[i] < chr[j];
	i += gap , j += gap;
	return (i < N && j < N) ? chr[i] < chr[j] : i > j;
}
void getsa(){
	REP(i , 0 , N) sa[i] = i , chr[i] = s[i];
	for(gap = 1 ; tma[N - 1] != N - 1 ; gap <<= 1){
		stable_sort(sa , sa + N , cmp);
		REP(i , 1 , N) tma[i] = tma[i - 1] + cmp(sa[i - 1] , sa[i]);
		REP(i , 0 , N) chr[sa[i]] = tma[i];
	}
}
void getlcp(int tmp = 0){
	REP(i , 0 , N) rk[sa[i]] = i;
	REP(i , 0 , N) if(rk[i]){
		if(tmp) tmp --;
		int res = sa[rk[i] - 1];
		while(tmp + res < N && tmp + i < N && s[tmp + res] == s[tmp + i]) tmp ++;
		lcp[rk[i]] = min(min(siz[res] , siz[i]) , tmp);
	}
}
int query(int l , int r){
	if(l == r) return N - sa[l];
	int tmp = one[r - l];
	return min(sp[l + 1][tmp] , sp[r - (1 << tmp) + 1][tmp]);
}
void getsp(){
	REP(i , 2 , N) one[i] = one[i >> 1] + 1;
	REP(i , 0 , N) sp[i][0] = lcp[i];
	REP(j , 1 , 20) REP(i , 0 , N){
		int to = i + (1 << (j - 1));
		if(to < N) sp[i][j] = min(sp[i][j - 1] , sp[to][j - 1]);
		else break;
	}
}
int inq[MAX] , inqnum = 0 , okr[MAX];
void pushqueue(int idx , int val){
	int now = id[sa[idx]];
	inqnum += inq[now] == 0;
	inq[now] += val;
	inqnum -= inq[now] == 0;
}
void solve(int r = 0){
	REP(l , 0 , N){
		while(r < N && inqnum < k) pushqueue(r ++ , 1);
		okr[l] = inqnum == k ? r - 1 : INF;
		pushqueue(l , -1);
	}
	REP(i , 0 , N){
		int val = 0;
		RREP(ii , 17 , 0){
			int goal = val + (1 << ii);
			if(goal <= siz[sa[i]]){
				int ll = i , rr = i;
				RREP(jj , 17 , 0){
					int tol = ll - (1 << jj) , tor = rr + (1 << jj);
					if(tol >= 0 && query(tol , i) >= goal) ll = tol;
					if(tor <  N && query(i , tor) >= goal) rr = tor;
				}
				if(okr[ll] <= rr) val = goal;
			}
		}
		ans[id[sa[i]]] += val;
	}
}
int32_t main(){
	IOS;
	cin >> n >> k;
	REP(i , 1 , n + 1){
		string in; cin >> in , s += in;
		REP(j , 0 , in.size()){
			siz[pos] = in.size() - j;
			id[pos ++] = i;
		}
		s += "@" , pos ++;
	}
	N = s.size();
	getsa() , getlcp() , getsp() , solve();
	REP(i , 1 , n + 1) cout << ans[i] << " "; cout << endl;
    return 0;
}


/*input
7 4
rubik
furik
abab
baba
aaabbbababa
abababababa
zero
*/
// 3 1 3
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
#define REP(i,j,k)     for(int i = j ; i < k ; ++i)
#define RREP(i,j,k)    for(int i = j ; i >=k ; --i)
#define A    first
#define B    second
#define mp   make_pair
#define pb   emplace_back
#define PII pair<int , int>
#define MEM(i,j)   memset(i , j , sizeof i)
#define ALL(i)     i.begin() , i.end()
#define DBGG(i,j)     cout << i << " " << j << endl
#define DB4(i,j,k,l)  cout << i << " " << j << " " << k << " " << l << endl
#define IOS cin.tie(0) , cout.sync_with_stdio(0)
#define endl "\n"
///------------------------------------------------------------
#define int int_fast64_t
#define MAX 300900
#define INF 0x3f3f3f3f
#define ls (now << 1)
#define rs (now << 1 | 1)
#define mid (l + r >> 1)

int n , k , pos , id[MAX] , siz[MAX] , ans[MAX];
int N , sa[MAX] , rk[MAX] , lcp[MAX] , sp[MAX][20] , one[MAX];
int gap , tma[MAX] , chr[MAX];
string s;
int cmp(int i , int j){
	if(chr[i] != chr[j]) return chr[i] < chr[j];
	i += gap , j += gap;
	return (i < N && j < N) ? chr[i] < chr[j] : i > j;
}
void getsa(){
	REP(i , 0 , N) sa[i] = i , chr[i] = s[i];
	for(gap = 1 ; tma[N - 1] != N - 1 ; gap <<= 1){
		stable_sort(sa , sa + N , cmp);
		REP(i , 1 , N) tma[i] = tma[i - 1] + cmp(sa[i - 1] , sa[i]);
		REP(i , 0 , N) chr[sa[i]] = tma[i];
	}
}
void getlcp(int tmp = 0){
	REP(i , 0 , N) rk[sa[i]] = i;
	REP(i , 0 , N) if(rk[i]){
		if(tmp) tmp --;
		int res = sa[rk[i] - 1];
		while(tmp + res < N && tmp + i < N && s[tmp + res] == s[tmp + i]) tmp ++;
		lcp[rk[i]] = min(min(siz[res] , siz[i]) , tmp);
	}
}
int query(int l , int r){
	if(l == r) return N - sa[l];
	int tmp = one[r - l];
	return min(sp[l + 1][tmp] , sp[r - (1 << tmp) + 1][tmp]);
}
void getsp(){
	REP(i , 2 , N) one[i] = one[i >> 1] + 1;
	REP(i , 0 , N) sp[i][0] = lcp[i];
	REP(j , 1 , 20) REP(i , 0 , N){
		int to = i + (1 << (j - 1));
		if(to < N) sp[i][j] = min(sp[i][j - 1] , sp[to][j - 1]);
	}
}
int inq[MAX] , inqnum = 0 , okr[MAX];
void pushqueue(int idx , int val){
	int now = id[sa[idx]];
	inq[now] += val;
	inqnum += inq[now] == 1 && val == 1;
	inqnum -= inq[now] == 0 && val == -1;
}
void solve(int r = 0){
	REP(l , 0 , N){
		while(r < N && inqnum < k) pushqueue(r ++ , 1);
		okr[l] = inqnum == k ? r - 1 : INF;
		pushqueue(l , -1);
	}
	REP(i , 0 , N){
		int val = 0;
		RREP(ii , 17 , 0){
			int goal = val + (1 << ii);
			if(goal <= siz[sa[i]]){
				int ll = i , rr = i;
				RREP(jj , 17 , 0){
					int tol = ll - (1 << jj) , tor = rr + (1 << jj);
					if(tol >= 0 && query(tol , i) >= goal) ll = tol;
					if(tor <  N && query(i , tor) >= goal) rr = tor;
				}
				if(okr[ll] <= rr) val = goal;
			}
		}
		ans[id[sa[i]]] += val;
	}
}
int32_t main(){
	IOS;
	cin >> n >> k;
	REP(i , 1 , n + 1){
		string in; cin >> in , s += in;
		REP(j , 0 , in.size()){
			siz[pos] = in.size() - j;
			id[pos ++] = i;
		}
		s += "@" , pos ++;
	}
	N = s.size();
	getsa() , getlcp() , getsp() , solve();
	REP(i , 1 , n + 1) cout << ans[i] << " "; cout << endl;
    return 0;
}


/*input
7 4
rubik
furik
abab
baba
aaabbbababa
abababababa
zero
*/
// 3 1 3
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
#define REP(i,j,k)     for(int i = j ; i < k ; ++i)
#define RREP(i,j,k)    for(int i = j ; i >=k ; --i)
#define A    first
#define B    second
#define mp   make_pair
#define pb   emplace_back
#define PII pair<int , int>
#define MEM(i,j)   memset(i , j , sizeof i)
#define ALL(i)     i.begin() , i.end()
#define DBGG(i,j)     cout << i << " " << j << endl
#define DB4(i,j,k,l)  cout << i << " " << j << " " << k << " " << l << endl
#define IOS cin.tie(0) , cout.sync_with_stdio(0)
#define endl "\n"
///------------------------------------------------------------
#define int int_fast64_t
#define MAX 300900
#define INF 0x3f3f3f3f
#define ls (now << 1)
#define rs (now << 1 | 1)
#define mid (l + r >> 1)

int n , k , pos , id[MAX] , siz[MAX] , ans[MAX];
int N , sa[MAX] , rk[MAX] , lcp[MAX] , sp[MAX][20] , one[MAX];
int gap , tma[MAX] , chr[MAX];
string s;
int cmp(int i , int j){
	if(chr[i] != chr[j]) return chr[i] < chr[j];
	i += gap , j += gap;
	return (i < N && j < N) ? chr[i] < chr[j] : i > j;
}
void getsa(){
	REP(i , 0 , N) sa[i] = i , chr[i] = s[i];
	for(gap = 1 ; tma[N - 1] != N - 1 ; gap <<= 1){
		stable_sort(sa , sa + N , cmp);
		REP(i , 1 , N) tma[i] = tma[i - 1] + cmp(sa[i - 1] , sa[i]);
		REP(i , 0 , N) chr[sa[i]] = tma[i];
	}
}
void getlcp(){
	int tmp = 0;
	REP(i , 0 , N) rk[sa[i]] = i;
	REP(i , 0 , N) if(rk[i]){
		if(tmp) tmp --;
		int res = sa[rk[i] - 1];
		while(tmp + res < N && tmp + i < N && s[tmp + res] == s[tmp + i]) tmp ++;
		lcp[rk[i]] = min(min(siz[res] , siz[i]) , tmp);
	}
}
int query(int l , int r){
	if(l == r) return N - sa[l];
	int tmp = one[r - l];
	return min(sp[l + 1][tmp] , sp[r - (1 << tmp) + 1][tmp]);
}
void getsp(){
	REP(i , 2 , N) one[i] = one[i >> 1] + 1;
	REP(i , 0 , N) sp[i][0] = lcp[i];
	REP(j , 1 , 20) REP(i , 0 , N){
		int to = i + (1 << (j - 1));
		if(to < N) sp[i][j] = min(sp[i][j - 1] , sp[to][j - 1]);
	}
}
int inq[MAX] , inqnum = 0 , okr[MAX];
void pushqueue(int idx , int val){
	int now = id[sa[idx]];
	inq[now] += val;
	inqnum += inq[now] == 1 && val == 1;
	inqnum -= inq[now] == 0 && val == -1;
}
void solve(int r = 0){
	REP(l , 0 , N){
		while(r < N && inqnum < k) pushqueue(r ++ , 1);
		okr[l] = inqnum == k ? r - 1 : INF;
		pushqueue(l , -1);
	}
	REP(i , 0 , N){
		int val = 0;
		RREP(ii , 20 , 0){
			int goal = val + (1 << ii);
			if(goal <= siz[sa[i]]){
				int ll = i , rr = i;
				RREP(jj , 20 , 0){
					int tol = ll - (1 << jj) , tor = rr + (1 << jj);
					if(tol >= 0 && query(tol , i) >= goal) ll = tol;
					if(tor <  N && query(i , tor) >= goal) rr = tor;
				}
				if(okr[ll] <= rr) val = goal;
			}
		}
		ans[id[sa[i]]] += val;
	}
}
int32_t main(){
	IOS;
	cin >> n >> k;
	REP(i , 1 , n + 1){
		string in; cin >> in , s += in;
		REP(j , 0 , in.size()){
			siz[pos] = in.size() - j;
			id[pos ++] = i;
		}
		s += '@' , pos ++;
	}
	N = s.size();
	getsa() , getlcp() , getsp() , solve();
	REP(i , 1 , n + 1) cout << ans[i] << " "; cout << endl;
    return 0;
}


/*input
7 4
rubik
furik
abab
baba
aaabbbababa
abababababa
zero
*/
// 3 1 3
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
#define REP(i,j,k)     for(int i = j ; i < k ; ++i)
#define RREP(i,j,k)    for(int i = j ; i >=k ; --i)
#define A    first
#define B    second
#define mp   make_pair
#define pb   emplace_back
#define PII pair<int , int>
#define MEM(i,j)   memset(i , j , sizeof i)
#define ALL(i)     i.begin() , i.end()
#define DBGG(i,j)     cout << i << " " << j << endl
#define DB4(i,j,k,l)  cout << i << " " << j << " " << k << " " << l << endl
#define IOS cin.tie(0) , cout.sync_with_stdio(0)
#define endl "\n"
///------------------------------------------------------------
#define int int_fast64_t
#define MAX 300900
#define INF 0x3f3f3f3f
#define ls (now << 1)
#define rs (now << 1 | 1)
#define mid (l + r >> 1)

int n , k , pos , id[MAX] , siz[MAX] , ans[MAX];
int N , sa[MAX] , rk[MAX] , lcp[MAX] , sp[MAX][20] , one[MAX];
int gap , tma[MAX] , chr[MAX];
string s;
int cmp(int i , int j){
	if(chr[i] != chr[j]) return chr[i] < chr[j];
	i += gap , j += gap;
	return (i < N && j < N) ? chr[i] < chr[j] : i > j;
}
void getsa(){
	REP(i , 0 , N) sa[i] = i , chr[i] = s[i];
	for(gap = 1 ; tma[N - 1] != N - 1 ; gap <<= 1){
		sort(sa , sa + N , cmp);
		REP(i , 1 , N) tma[i] = tma[i - 1] + cmp(sa[i - 1] , sa[i]);
		REP(i , 0 , N) chr[sa[i]] = tma[i];
		// REP(i , 0 , N) cout << tma[i] << " ";cout << endl;
	}
}
void getlcp(){
	int tmp = 0;
	REP(i , 0 , N) rk[sa[i]] = i;
	REP(i , 0 , N) if(rk[i]){
		if(tmp) tmp --;
		int res = sa[rk[i] - 1];
		while(tmp + res < N && tmp + i < N && s[tmp + res] == s[tmp + i]) tmp ++;
		lcp[rk[i]] = min(min(siz[res] , siz[i]) , tmp);
	}
	// REP(i , 0 , N){ if(i < 10) cout << " ";cout << i << " " << id[sa[i]];
	// REP(j , sa[i] , sa[i] + siz[sa[i]]) cout << s[j]; cout << endl; }

	// cout << "sa = " ; REP(i , 0 , N) cout << sa[i] << " "; cout << endl;
	// cout << "rk = " ; REP(i , 0 , N) cout << rk[i] << " "; cout << endl;
	// cout << "lcp= " ; REP(i , 0 , N) cout << lcp[i] << " ";cout << endl;
}
int query(int l , int r){
	// cout << "query = " << l << " " << r << " ";
	if(l == r) return /*DBGG("ans = " , N - sa[l]) , */N - sa[l];
	int tmp = one[r - l];
	// DBGG("ans = " , min(sp[l + 1][tmp] , sp[r - (1 << tmp) + 1][tmp]));
	return min(sp[l + 1][tmp] , sp[r - (1 << tmp) + 1][tmp]);
}
void getsp(){
	REP(i , 2 , N) one[i] = one[i >> 1] + 1;
	REP(i , 0 , N) sp[i][0] = lcp[i];
	REP(j , 1 , 20) REP(i , 0 , N){
		int to = i + (1 << (j - 1));
		if(to < N) sp[i][j] = min(sp[i][j - 1] , sp[to][j - 1]);
	}
}

int inq[MAX] , inqnum = 0 , okr[MAX];
void pushqueue(int idx , int val){
	// if(val == 1) DBGG("add = " , idx);
	// if(val == -1) DBGG("str = " , idx);
	int now = id[sa[idx]];
	inq[now] += val;
	inqnum += inq[now] == 1 && val == 1;
	inqnum -= inq[now] == 0 && val == -1;
}
void solve(int r = 0){
	REP(l , 0 , N){
		while(r < N && inqnum < k) pushqueue(r ++ , 1);
		okr[l] = inqnum == k ? r - 1 : INF;
		pushqueue(l , -1);
	}
	REP(i , 0 , N){
		int val = 0;
		RREP(ii , 20 , 0){
			int goal = val + (1 << ii);
			if(goal <= siz[sa[i]]){
				int ll = i , rr = i;
				RREP(jj , 20 , 0){
					int tol = ll - (1 << jj) , tor = rr + (1 << jj);
					if(tol >= 0 && query(tol , i) >= goal) ll = tol;
					if(tor <  N && query(i , tor) >= goal) rr = tor;
				}
				if(okr[ll] <= rr) val = goal;
			}
		}
		ans[id[sa[i]]] += val;
	}
}
int32_t main(){
	IOS;
	cin >> n >> k;
	REP(i , 1 , n + 1){
		string in; cin >> in , s += in;
		REP(j , 0 , in.size()){
			siz[pos] = in.size() - j;
			id[pos ++] = i;
		}
		s += '@' , pos ++;
	}
	N = s.size();
	// DBGG("the string is like = " , s);
	// REP(i , 20 , 20 + siz[20]) cout << s[i] ; cout << endl;
	// REP(i , 39 , 39 + siz[39]) cout << s[i] ; cout << endl;
	// DBGG("N = " , N);
	getsa() , getlcp() , getsp() , solve();
	// cout << "id =  "; `REP(i , 0 , N) cout << id[sa[i]] << " ";cout << endl;
	REP(i , 1 , n + 1) cout << ans[i] << " "; cout << endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N=200005;
#define ll long long
char a[N];int n,k;
vector <char> s[N];
struct Suffix_Automaton{
	int ch[N][26],len[N],fa[N],cnt,last;
	int Head[N],Next[N],Adj[N],tot;
	void init(){cnt=last=1;tot=0;}
	void insert(int c){
		if (ch[last][c]&&len[ch[last][c]]==len[last]+1) {last=ch[last][c];return;}
		int np=++cnt,p=last;last=np,len[np]=len[p]+1;
		for (;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
		if (!p) fa[np]=1;
		else {
			int q=ch[p][c];
			if (len[q]==len[p]+1) fa[np]=q;
			else{
				int nq=++cnt;len[nq]=len[p]+1;
				memcpy(ch[nq],ch[q],sizeof(ch[nq]));
				fa[nq]=fa[q],fa[q]=fa[np]=nq;
				for (;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
			}
		}
	}
	int lst[N];ll val[N],size[N];
	void work(int x){
		int now=1;
		for (int i=0;i<s[x].size();i++){
			now=ch[now][s[x][i]-'a'];
			int t=now;
			while (t!=1&&lst[t]!=x) val[t]++,lst[t]=x,t=fa[t];
		}
	}
	void addedge(int u,int v){
		Next[++tot]=Head[u],Head[u]=tot,Adj[tot]=v;
	}
	void dfs(int x){
		size[x]=size[fa[x]]+(val[x]>=k)*(len[x]-len[fa[x]]);
		for (int e=Head[x];e;e=Next[e])
			dfs(Adj[e]);
	}
	void build(){
		for (int i=2;i<=cnt;i++) addedge(fa[i],i);
		dfs(1);
	}
	void calc(int x){
		int now=1;ll ans=0;
		for (int i=0;i<s[x].size();i++)
			now=ch[now][s[x][i]-'a'],ans+=size[now];
		printf ("%lld ",ans);
	}
}SAM;
int main (){
	scanf ("%d%d",&n,&k);
	SAM.init();
	for (int i=1;i<=n;i++){
		scanf ("%s",a+1);
		int m=strlen(a+1);SAM.last=1;
		for (int j=1;j<=m;j++)
			s[i].push_back(a[j]),SAM.insert(a[j]-'a');
	}
	for (int i=1;i<=n;i++) SAM.work(i);
	SAM.build();
	for (int i=1;i<=n;i++) SAM.calc(i);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N=200005;
#define ll long long
char a[N];int n,k;
vector <char> s[N];
struct Suffix_Automaton{
	int ch[N][26],len[N],fa[N],size[N],cnt,last;
	int Head[N],Next[N],Adj[N],tot;
	void init(){cnt=last=1;tot=0;}
	void insert(int c){
		if (ch[last][c]&&len[ch[last][c]]==len[last]+1) {last=ch[last][c];return;}
		int np=++cnt,p=last;last=np,len[np]=len[p]+1;
		for (;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
		if (!p) fa[np]=1;
		else {
			int q=ch[p][c];
			if (len[q]==len[p]+1) fa[np]=q;
			else{
				int nq=++cnt;len[nq]=len[p]+1;
				memcpy(ch[nq],ch[q],sizeof(ch[nq]));
				fa[nq]=fa[q],fa[q]=fa[np]=nq;
				for (;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
			}
		}size[np]=1;
	}
	int lst[N];ll val[N];
	void work(int x){
		int now=1;
		for (int i=0;i<s[x].size();i++){
			now=ch[now][s[x][i]-'a'];
			int t=now;
			while (t!=1&&lst[t]!=x) val[t]++,lst[t]=x,t=fa[t];
		}
	}
	void addedge(int u,int v){
		Next[++tot]=Head[u],Head[u]=tot,Adj[tot]=v;
	}
	void dfs(int x){
		for (int e=Head[x];e;e=Next[e])
			dfs(Adj[e]),size[x]+=size[Adj[e]];
	}
	void build(){
		for (int i=2;i<=cnt;i++) addedge(fa[i],i);
		dfs(1);
	}
	void calc(int x){
		int now=1;ll ans=0;
		for (int i=0;i<s[x].size();i++){
			now=ch[now][s[x][i]-'a'];
			int t=now;
			while (t!=1) {
				if (val[t]>=k) ans+=len[t]-len[fa[t]];
				t=fa[t];
			}
		}
		printf ("%lld ",ans);
	}
}SAM;
int main (){
	scanf ("%d%d",&n,&k);
	SAM.init();
	for (int i=1;i<=n;i++){
		scanf ("%s",a+1);
		int m=strlen(a+1);SAM.last=1;
		for (int j=1;j<=m;j++)
			s[i].push_back(a[j]),SAM.insert(a[j]-'a');
	}
	SAM.build();
	for (int i=1;i<=n;i++) SAM.work(i);
	memset (SAM.lst,0,sizeof(SAM.lst));
	for (int i=1;i<=n;i++) SAM.calc(i);
	return 0;
}