#include <bits/stdc++.h>
#define x first
#define y second

using namespace std;
typedef pair<int,int> pii;
typedef long long INT;

#define NN 400010
string s;
int I[NN], H[NN], rk[NN], sa[NN];
int head[NN], buf[NN], nxt[NN], mn[NN][20];
pii pos[NN];

void bucket_sort(int n){
	int E=0,m=max(n+10,256);
	for(int i=0;i<=m;i++) head[i]=0;
	for(int i=0,u;i<n;i++){
		u=pos[I[i]].y;
		buf[++E]=I[i];
		nxt[E]=head[u];
		head[u]=E;
	}
	for(int i=m,K=0;i>=0;i--){
		for(int j=head[i];j;j=nxt[j]) I[K++]=buf[j];
	}
	for(int i=0;i<=m;i++) head[i]=0;
	for(int i=0,u;i<n;i++){
		u=pos[I[i]].x;
		buf[++E]=I[i];
		nxt[E]=head[u];
		head[u]=E;
	}
	for(int i=0,K=0;i<=m;i++){
		for(int j=head[i];j;j=nxt[j]) I[K++]=buf[j];
	}
}

void buildSA(int n){
	for(int i=0;i<=n;i++) rk[i]=s[i];
	for(int i=0;i<19;i++){
		for (int j=0;j<n;j++){
			pos[j]=pii(rk[j],rk[min(n,j+(1<<i))]);
			I[j]=j;
		}
		bucket_sort(n);
		int cnt=0;
		pos[n]=pii(-1,-1);
		I[n]=n;
		for(int j=0;j<n;j++){
			rk[I[j]]=cnt+1;
			cnt+=pos[I[j]]!=pos[I[j+1]];
		}
		if(cnt==n) break;
	}
	for(int i=0;i<n;i++) sa[rk[i]]=i;
	for(int i=0,h=0;i<n;i++){
		if(rk[i]==1) continue;
		h=max(h-1,0);
		for(int j=sa[rk[i]-1];s[i+h]==s[j+h];h++);
		H[rk[i]]=h;
	}
	for(int j=1;j<19;j++){
		for(int i=1;i<=n;i++){
			if(i+(1<<j)-1>n) continue;
			if(j==1) mn[i][j]=H[i+1];
			else mn[i][j]=min(H[i+(1<<(j-1))],min(mn[i][j-1],mn[i+(1<<(j-1))][j-1]));
		}
	}
}

int lcp(int u,int v){
	if(u>v) swap(u,v);
	int rr=31-__builtin_clz(v-u+1);
	return min(mn[u][rr],mn[v-(1<<rr)+1][rr]);
}

string t[NN];
int sz[NN];
int a[NN],val[NN];

#define MM 10000000
#define umid (L+R>>1)
int uqe[MM],ls[MM],rs[MM];
int root[NN];
int ID;

void push_up(int u,int L,int R){
	uqe[u]=uqe[ls[u]]+uqe[rs[u]];
}

int build(int L,int R){
	int u=ID++;
	if(L+1==R){
		uqe[u]=0;
		return u;
	}
	ls[u]=build(L,umid);
	rs[u]=build(umid,R);
	push_up(u,L,R);
	return u;
}

int clone(int u){
	uqe[ID++]=uqe[u];
	return ID-1;
}

int update(int u,int L,int R,int st,int ed,int x){
	if(st>=R||ed<=L) return u;
	int xx=clone(u);
	if(st<=L&&ed>=R){
		uqe[xx]+=x;
		return xx;
	}
	ls[xx]=update(ls[u],L,umid,st,ed,x);
	rs[xx]=update(rs[u],umid,R,st,ed,x);
	push_up(xx,L,R);
	return xx;
}

int calc(int u,int L,int R,int st,int ed){
	if(st>=R||ed<=L) return 0;
	if(st<=L&&ed>=R) return uqe[u];
	return calc(ls[u],L,umid,st,ed)+calc(rs[u],umid,R,st,ed);
}

int pre[NN],fv[NN];
int in[NN];

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif

	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>t[i];
		in[i]=t[i].size()+1;
		sz[i]=in[i]+sz[i-1];
		s+='*';
		s+=t[i];
	}
	int len=s.size();
	buildSA(len);
	int CT=0;
	for(int i=1;i<=n;i++){
		for(int j=0;j<in[i];j++){
			val[CT++]=i;
		}
	}
	for(int i=1;i<=len;i++) a[i]=val[sa[i]];
	for(int i=1;i<=len;i++){
		pre[i]=fv[a[i]];
		fv[a[i]]=i;
	}
	root[0]=build(1,len+1);
	for(int i=1;i<=len;i++){
		root[i]=update(root[i-1],1,len+1,i,i+1,1);
		if(pre[i]) root[i]=update(root[i],1,len+1,pre[i],pre[i]+1,-1);
	}
	for(int ii=1;ii<=n;ii++){
		INT ans=0;
		for(int jj=1;jj<in[ii];jj++){
			int id=rk[sz[ii-1]+jj];
			int stlen=0,edlen=in[ii]-jj+1;
			while(stlen+1<edlen){
				int midlen=(stlen+edlen)>>1;
				int st,ed,mid,p,q;
				st=0,ed=id;
				while(st+1<ed){
					mid=(st+ed)>>1;
					if(lcp(mid,id)>=midlen) ed=mid;
					else st=mid;
				}
				p=ed;
				st=id,ed=len+1;
				while(st+1<ed){
					mid=(st+ed)>>1;
					if(lcp(id,mid)>=midlen) st=mid;
					else ed=mid;
				}
				q=st;
				int RES=calc(root[q],1,len+1,p,q+1);
				if(RES>=k) stlen=midlen;
				else edlen=midlen;
			}
			ans+=stlen;
		}
		cout<<ans<<' ';
	}
    return 0;
}


#include <bits/stdc++.h>
#define x first
#define y second

using namespace std;
typedef pair<int,int> pii;
typedef long long INT;

#define NN 200011
string s;
int I[NN], H[NN], rk[NN], sa[NN];
int head[NN], buf[NN], nxt[NN], mn[NN][20];
pii pos[NN];

void bucket_sort(int n){
	int E=0,m=max(n+10,256);
	for(int i=0;i<=m;i++) head[i]=0;
	for(int i=0,u;i<n;i++){
		u=pos[I[i]].y;
		buf[++E]=I[i];
		nxt[E]=head[u];
		head[u]=E;
	}
	for(int i=m,K=0;i>=0;i--){
		for(int j=head[i];j;j=nxt[j]) I[K++]=buf[j];
	}
	for(int i=0;i<=m;i++) head[i]=0;
	for(int i=0,u;i<n;i++){
		u=pos[I[i]].x;
		buf[++E]=I[i];
		nxt[E]=head[u];
		head[u]=E;
	}
	for(int i=0,K=0;i<=m;i++){
		for(int j=head[i];j;j=nxt[j]) I[K++]=buf[j];
	}
}

void buildSA(int n){
	for(int i=0;i<=n;i++) rk[i]=s[i];
	for(int i=0;i<19;i++){
		for (int j=0;j<n;j++){
			pos[j]=pii(rk[j],rk[min(n,j+(1<<i))]);
			I[j]=j;
		}
		bucket_sort(n);
		int cnt=0;
		pos[n]=pii(-1,-1);
		I[n]=n;
		for(int j=0;j<n;j++){
			rk[I[j]]=cnt+1;
			cnt+=pos[I[j]]!=pos[I[j+1]];
		}
		if(cnt==n) break;
	}
	for(int i=0;i<n;i++) sa[rk[i]]=i;
	for(int i=0,h=0;i<n;i++){
		if(rk[i]==1) continue;
		h=max(h-1,0);
		for(int j=sa[rk[i]-1];s[i+h]==s[j+h];h++);
		H[rk[i]]=h;
	}
	for(int j=1;j<19;j++){
		for(int i=1;i<=n;i++){
			if(i+(1<<j)-1>n) continue;
			if(j==1) mn[i][j]=H[i+1];
			else mn[i][j]=min(H[i+(1<<(j-1))],min(mn[i][j-1],mn[i+(1<<(j-1))][j-1]));
		}
	}
}

int lcp(int u,int v){
	if(u>v) swap(u,v);
	int rr=31-__builtin_clz(v-u+1);
	return min(mn[u][rr],mn[v-(1<<rr)+1][rr]);
}

string t[NN];
int sz[NN];
int a[NN],val[NN];

#define MM 10000000
#define umid (L+R>>1)
int uqe[MM],ls[MM],rs[MM];
int root[NN];
int ID;

void push_up(int u,int L,int R){
	uqe[u]=uqe[ls[u]]+uqe[rs[u]];
}

int build(int L,int R){
	int u=ID++;
	if(L+1==R){
		uqe[u]=0;
		return u;
	}
	ls[u]=build(L,umid);
	rs[u]=build(umid,R);
	push_up(u,L,R);
	return u;
}

int clone(int u){
	uqe[ID++]=uqe[u];
	return ID-1;
}

int update(int u,int L,int R,int st,int ed,int x){
	if(st>=R||ed<=L) return u;
	int xx=clone(u);
	if(st<=L&&ed>=R){
		uqe[xx]+=x;
		return xx;
	}
	ls[xx]=update(ls[u],L,umid,st,ed,x);
	rs[xx]=update(rs[u],umid,R,st,ed,x);
	push_up(xx,L,R);
	return xx;
}

int calc(int u,int L,int R,int st,int ed){
	if(st>=R||ed<=L) return 0;
	if(st<=L&&ed>=R) return uqe[u];
	return calc(ls[u],L,umid,st,ed)+calc(rs[u],umid,R,st,ed);
}

int pre[NN],fv[NN];
int in[NN];

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif

	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>t[i];
		in[i]=t[i].size()+1;
		sz[i]=in[i]+sz[i-1];
		s+='*';
		s+=t[i];
	}
	int len=s.size();
	buildSA(len);
	int CT=0;
	for(int i=1;i<=n;i++){
		for(int j=0;j<in[i];j++){
			val[CT++]=i;
		}
	}
	for(int i=1;i<=len;i++) a[i]=val[sa[i]];
	for(int i=1;i<=len;i++){
		pre[i]=fv[a[i]];
		fv[a[i]]=i;
	}
	root[0]=build(1,len+1);
	for(int i=1;i<=len;i++){
		root[i]=update(root[i-1],1,len+1,i,i+1,1);
		if(pre[i]) root[i]=update(root[i],1,len+1,pre[i],pre[i]+1,-1);
	}
	for(int ii=1;ii<=n;ii++){
		INT ans=0;
		for(int jj=1;jj<in[ii];jj++){
			int id=rk[sz[ii-1]+jj];
			int stlen=0,edlen=in[ii]-jj+1;
			while(stlen+1<edlen){
				int midlen=(stlen+edlen)>>1;
				int st,ed,mid,p,q;
				st=0,ed=id;
				while(st+1<ed){
					mid=(st+ed)>>1;
					if(lcp(mid,id)>=midlen) ed=mid;
					else st=mid;
				}
				p=ed;
				st=id,ed=len+1;
				while(st+1<ed){
					mid=(st+ed)>>1;
					if(lcp(id,mid)>=midlen) st=mid;
					else ed=mid;
				}
				q=st;
				int RES=calc(root[q],1,len+1,p,q+1);
				if(RES>=k) stlen=midlen;
				else edlen=midlen;
			}
			ans+=stlen;
		}
		cout<<ans<<' ';
	}
    return 0;
}


#include <bits/stdc++.h>
#define x first
#define y second

using namespace std;
typedef pair<int,int> pii;
typedef long long INT;

#define NN 200010
string s;
int I[NN], H[NN], rk[NN], sa[NN];
int head[NN], buf[NN], nxt[NN], mn[NN][19];
pii pos[NN];

void bucket_sort(int n){
	int E=0,m=max(n+10,256);
	for(int i=0;i<=m;i++) head[i]=0;
	for(int i=0,u;i<n;i++){
		u=pos[I[i]].y;
		buf[++E]=I[i];
		nxt[E]=head[u];
		head[u]=E;
	}
	for(int i=m,K=0;i>=0;i--){
		for(int j=head[i];j;j=nxt[j]) I[K++]=buf[j];
	}
	for(int i=0;i<=m;i++) head[i]=0;
	for(int i=0,u;i<n;i++){
		u=pos[I[i]].x;
		buf[++E]=I[i];
		nxt[E]=head[u];
		head[u]=E;
	}
	for(int i=0,K=0;i<=m;i++){
		for(int j=head[i];j;j=nxt[j]) I[K++]=buf[j];
	}
}

void buildSA(int n){
	for(int i=0;i<=n;i++) rk[i]=s[i];
	for(int i=0;i<18;i++){
		for (int j=0;j<n;j++){
			pos[j]=pii(rk[j],rk[min(n,j+(1<<i))]);
			I[j]=j;
		}
		bucket_sort(n);
		int cnt=0;
		pos[n]=pii(-1,-1);
		I[n]=n;
		for(int j=0;j<n;j++){
			rk[I[j]]=cnt+1;
			cnt+=pos[I[j]]!=pos[I[j+1]];
		}
		if(cnt==n) break;
	}
	for(int i=0;i<n;i++) sa[rk[i]]=i;
	for(int i=0,h=0;i<n;i++){
		if(rk[i]==1) continue;
		h=max(h-1,0);
		for(int j=sa[rk[i]-1];s[i+h]==s[j+h];h++);
		H[rk[i]]=h;
	}
	for(int j=1;j<18;j++){
		for(int i=1;i<=n;i++){
			if(i+(1<<j)-1>n) continue;
			if(j==1) mn[i][j]=H[i+1];
			else mn[i][j]=min(H[i+(1<<(j-1))],min(mn[i][j-1],mn[i+(1<<(j-1))][j-1]));
		}
	}
}

int lcp(int u,int v){
	if(u>v) swap(u,v);
	int rr=31-__builtin_clz(v-u+1);
	return min(mn[u][rr],mn[v-(1<<rr)+1][rr]);
}

string t[NN];
int sz[NN];
int a[NN],val[NN];

#define MM 6100000
#define umid (L+R>>1)
int uqe[MM],ls[MM],rs[MM];
int root[NN];
int ID;

void push_up(int u,int L,int R){
	uqe[u]=uqe[ls[u]]+uqe[rs[u]];
}

int build(int L,int R){
	int u=ID++;
	if(L+1==R){
		uqe[u]=0;
		return u;
	}
	ls[u]=build(L,umid);
	rs[u]=build(umid,R);
	push_up(u,L,R);
	return u;
}

int clone(int u){
	uqe[ID++]=uqe[u];
	return ID-1;
}

int update(int u,int L,int R,int st,int ed,int x){
	if(st>=R||ed<=L) return u;
	int xx=clone(u);
	if(st<=L&&ed>=R){
		uqe[xx]+=x;
		return xx;
	}
	ls[xx]=update(ls[u],L,umid,st,ed,x);
	rs[xx]=update(rs[u],umid,R,st,ed,x);
	push_up(xx,L,R);
	return xx;
}

int calc(int u,int L,int R,int st,int ed){
	if(st>=R||ed<=L) return 0;
	if(st<=L&&ed>=R) return uqe[u];
	return calc(ls[u],L,umid,st,ed)+calc(rs[u],umid,R,st,ed);
}

int pre[NN],fv[NN];
int in[NN];

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif

	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>t[i];
		in[i]=t[i].size()+1;
		sz[i]=in[i]+sz[i-1];
		s+='*';
		s+=t[i];
	}
	int len=s.size();
	buildSA(len);
	int CT=0;
	for(int i=1;i<=n;i++){
		for(int j=0;j<in[i];j++){
			val[CT++]=i;
		}
	}
	for(int i=1;i<=len;i++) a[i]=val[sa[i]];
	for(int i=1;i<=len;i++){
		pre[i]=fv[a[i]];
		fv[a[i]]=i;
	}
	root[0]=build(1,len+1);
	for(int i=1;i<=len;i++){
		root[i]=update(root[i-1],1,len+1,i,i+1,1);
		if(pre[i]) root[i]=update(root[i],1,len+1,pre[i],pre[i]+1,-1);
	}
	for(int ii=1;ii<=n;ii++){
		INT ans=0;
		for(int jj=1;jj<in[ii];jj++){
			int id=rk[sz[ii-1]+jj];
			int stlen=0,edlen=in[ii]-jj+1;
			while(stlen+1<edlen){
				int midlen=(stlen+edlen)>>1;
				int st,ed,mid,p,q;
				st=0,ed=id;
				while(st+1<ed){
					mid=(st+ed)>>1;
					if(lcp(mid,id)>=midlen) ed=mid;
					else st=mid;
				}
				p=ed;
				st=id,ed=len+1;
				while(st+1<ed){
					mid=(st+ed)>>1;
					if(lcp(id,mid)>=midlen) st=mid;
					else ed=mid;
				}
				q=st;
				int RES=calc(root[q],1,len+1,p,q+1);
				if(RES>=k) stlen=midlen;
				else edlen=midlen;
			}
			ans+=stlen;
		}
		cout<<ans<<' ';
	}
    return 0;
}


#include <bits/stdc++.h>
#define x first
#define y second

using namespace std;
typedef pair<int,int> pii;
typedef long long INT;

#define NN 100010
string s;
int I[NN], H[NN], rk[NN], sa[NN];
int head[NN], buf[NN], nxt[NN], mn[NN][19];
pii pos[NN];

void bucket_sort(int n){
	int E=0,m=max(n+10,256);
	for(int i=0;i<=m;i++) head[i]=0;
	for(int i=0,u;i<n;i++){
		u=pos[I[i]].y;
		buf[++E]=I[i];
		nxt[E]=head[u];
		head[u]=E;
	}
	for(int i=m,K=0;i>=0;i--){
		for(int j=head[i];j;j=nxt[j]) I[K++]=buf[j];
	}
	for(int i=0;i<=m;i++) head[i]=0;
	for(int i=0,u;i<n;i++){
		u=pos[I[i]].x;
		buf[++E]=I[i];
		nxt[E]=head[u];
		head[u]=E;
	}
	for(int i=0,K=0;i<=m;i++){
		for(int j=head[i];j;j=nxt[j]) I[K++]=buf[j];
	}
}

void buildSA(int n){
	for(int i=0;i<=n;i++) rk[i]=s[i];
	for(int i=0;i<18;i++){
		for (int j=0;j<n;j++){
			pos[j]=pii(rk[j],rk[min(n,j+(1<<i))]);
			I[j]=j;
		}
		bucket_sort(n);
		int cnt=0;
		pos[n]=pii(-1,-1);
		I[n]=n;
		for(int j=0;j<n;j++){
			rk[I[j]]=cnt+1;
			cnt+=pos[I[j]]!=pos[I[j+1]];
		}
		if(cnt==n) break;
	}
	for(int i=0;i<n;i++) sa[rk[i]]=i;
	for(int i=0,h=0;i<n;i++){
		if(rk[i]==1) continue;
		h=max(h-1,0);
		for(int j=sa[rk[i]-1];s[i+h]==s[j+h];h++);
		H[rk[i]]=h;
	}
	for(int j=1;j<18;j++){
		for(int i=1;i<=n;i++){
			if(i+(1<<j)-1>n) continue;
			if(j==1) mn[i][j]=H[i+1];
			else mn[i][j]=min(H[i+(1<<(j-1))],min(mn[i][j-1],mn[i+(1<<(j-1))][j-1]));
		}
	}
}

int lcp(int u,int v){
	if(u>v) swap(u,v);
	int rr=31-__builtin_clz(v-u+1);
	return min(mn[u][rr],mn[v-(1<<rr)+1][rr]);
}

string t[NN];
int sz[NN];
int a[NN],val[NN];

#define MM 6100000
#define umid (L+R>>1)
int uqe[MM],ls[MM],rs[MM];
int root[NN];
int ID;

void push_up(int u,int L,int R){
	uqe[u]=uqe[ls[u]]+uqe[rs[u]];
}

int build(int L,int R){
	int u=ID++;
	if(L+1==R){
		uqe[u]=0;
		return u;
	}
	ls[u]=build(L,umid);
	rs[u]=build(umid,R);
	push_up(u,L,R);
	return u;
}

int clone(int u){
	uqe[ID++]=uqe[u];
	return ID-1;
}

int update(int u,int L,int R,int st,int ed,int x){
	if(st>=R||ed<=L) return u;
	int xx=clone(u);
	if(st<=L&&ed>=R){
		uqe[xx]+=x;
		return xx;
	}
	ls[xx]=update(ls[u],L,umid,st,ed,x);
	rs[xx]=update(rs[u],umid,R,st,ed,x);
	push_up(xx,L,R);
	return xx;
}

int calc(int u,int L,int R,int st,int ed){
	if(st>=R||ed<=L) return 0;
	if(st<=L&&ed>=R) return uqe[u];
	return calc(ls[u],L,umid,st,ed)+calc(rs[u],umid,R,st,ed);
}

int pre[NN],fv[NN];
int in[NN];

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif

	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>t[i];
		in[i]=t[i].size()+1;
		sz[i]=in[i]+sz[i-1];
		s+='*';
		s+=t[i];
	}
	int len=s.size();
	buildSA(len);
	int CT=0;
	for(int i=1;i<=n;i++){
		for(int j=0;j<in[i];j++){
			val[CT++]=i;
		}
	}
	for(int i=1;i<=len;i++) a[i]=val[sa[i]];
	for(int i=1;i<=len;i++){
		pre[i]=fv[a[i]];
		fv[a[i]]=i;
	}
	root[0]=build(1,len+1);
	for(int i=1;i<=len;i++){
		root[i]=update(root[i-1],1,len+1,i,i+1,1);
		if(pre[i]) root[i]=update(root[i],1,len+1,pre[i],pre[i]+1,-1);
	}
	for(int ii=1;ii<=n;ii++){
		INT ans=0;
		for(int jj=1;jj<in[ii];jj++){
			int id=rk[sz[ii-1]+jj];
			int stlen=0,edlen=in[ii]-jj+1;
			while(stlen+1<edlen){
				int midlen=(stlen+edlen)>>1;
				int st,ed,mid,p,q;
				st=0,ed=id;
				while(st+1<ed){
					mid=(st+ed)>>1;
					if(lcp(mid,id)>=midlen) ed=mid;
					else st=mid;
				}
				p=ed;
				st=id,ed=len+1;
				while(st+1<ed){
					mid=(st+ed)>>1;
					if(lcp(id,mid)>=midlen) st=mid;
					else ed=mid;
				}
				q=st;
				int RES=calc(root[q],1,len+1,p,q+1);
				if(RES>=k) stlen=midlen;
				else edlen=midlen;
			}
			ans+=stlen;
		}
		cout<<ans<<' ';
	}
    return 0;
}


#include <bits/stdc++.h>
#define x first
#define y second

using namespace std;
typedef pair<int,int> pii;
typedef long long INT;

#define NN 400010
string s;
int I[NN], H[NN], rk[NN], sa[NN];
int head[NN], buf[NN], nxt[NN], mn[NN][20];
pii pos[NN];

void bucket_sort(int n){
	int E=0,m=max(n+10,256);
	for(int i=0;i<=m;i++) head[i]=0;
	for(int i=0,u;i<n;i++){
		u=pos[I[i]].y;
		buf[++E]=I[i];
		nxt[E]=head[u];
		head[u]=E;
	}
	for(int i=m,K=0;i>=0;i--){
		for(int j=head[i];j;j=nxt[j]) I[K++]=buf[j];
	}
	for(int i=0;i<=m;i++) head[i]=0;
	for(int i=0,u;i<n;i++){
		u=pos[I[i]].x;
		buf[++E]=I[i];
		nxt[E]=head[u];
		head[u]=E;
	}
	for(int i=0,K=0;i<=m;i++){
		for(int j=head[i];j;j=nxt[j]) I[K++]=buf[j];
	}
}

void buildSA(int n){
	for(int i=0;i<=n;i++) rk[i]=s[i];
	for(int i=0;i<19;i++){
		for (int j=0;j<n;j++){
			pos[j]=pii(rk[j],rk[min(n,j+(1<<i))]);
			I[j]=j;
		}
		bucket_sort(n);
		int cnt=0;
		pos[n]=pii(-1,-1);
		I[n]=n;
		for(int j=0;j<n;j++){
			rk[I[j]]=cnt+1;
			cnt+=pos[I[j]]!=pos[I[j+1]];
		}
		if(cnt==n) break;
	}
	for(int i=0;i<n;i++) sa[rk[i]]=i;
	for(int i=0,h=0;i<n;i++){
		if(rk[i]==1) continue;
		h=max(h-1,0);
		for(int j=sa[rk[i]-1];s[i+h]==s[j+h];h++);
		H[rk[i]]=h;
	}
	for(int j=1;j<19;j++){
		for(int i=1;i<=n;i++){
			if(i+(1<<j)-1>n) continue;
			if(j==1) mn[i][j]=H[i+1];
			else mn[i][j]=min(H[i+(1<<(j-1))],min(mn[i][j-1],mn[i+(1<<(j-1))][j-1]));
		}
	}
}

int lcp(int u,int v){
	if(u>v) swap(u,v);
	int rr=31-__builtin_clz(v-u+1);
	return min(mn[u][rr],mn[v-(1<<rr)+1][rr]);
}

string t[NN];
int sz[NN];
int a[NN],val[NN];

#define MM 10000000
#define umid (L+R>>1)
int uqe[MM],ls[MM],rs[MM];
int root[NN];
int ID;

void push_up(int u,int L,int R){
	uqe[u]=uqe[ls[u]]+uqe[rs[u]];
}

int build(int L,int R){
	int u=ID++;
	if(L+1==R){
		uqe[u]=0;
		return u;
	}
	ls[u]=build(L,umid);
	rs[u]=build(umid,R);
	push_up(u,L,R);
	return u;
}

int clone(int u){
	uqe[ID++]=uqe[u];
	return ID-1;
}

int update(int u,int L,int R,int st,int ed,int x){
	if(st>=R||ed<=L) return u;
	int xx=clone(u);
	if(st<=L&&ed>=R){
		uqe[xx]+=x;
		return xx;
	}
	ls[xx]=update(ls[u],L,umid,st,ed,x);
	rs[xx]=update(rs[u],umid,R,st,ed,x);
	push_up(xx,L,R);
	return xx;
}

int calc(int u,int L,int R,int st,int ed){
	if(st>=R||ed<=L) return 0;
	if(st<=L&&ed>=R) return uqe[u];
	return calc(ls[u],L,umid,st,ed)+calc(rs[u],umid,R,st,ed);
}

int pre[NN],fv[NN];
int in[NN];

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif

	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>t[i];
		in[i]=t[i].size()+1;
		sz[i]=in[i]+sz[i-1];
		s+='*';
		s+=t[i];
	}
	int len=s.size();
	if(len>NN/2) while(1);
	buildSA(len);
	int CT=0;
	for(int i=1;i<=n;i++){
		for(int j=0;j<in[i];j++){
			val[CT++]=i;
		}
	}
	for(int i=1;i<=len;i++) a[i]=val[sa[i]];
	for(int i=1;i<=len;i++){
		pre[i]=fv[a[i]];
		fv[a[i]]=i;
	}
	root[0]=build(1,len+1);
	for(int i=1;i<=len;i++){
		root[i]=update(root[i-1],1,len+1,i,i+1,1);
		if(pre[i]) root[i]=update(root[i],1,len+1,pre[i],pre[i]+1,-1);
	}
	for(int ii=1;ii<=n;ii++){
		INT ans=0;
		for(int jj=1;jj<in[ii];jj++){
			int id=rk[sz[ii-1]+jj];
			int stlen=0,edlen=in[ii]-jj+1;
			while(stlen+1<edlen){
				int midlen=(stlen+edlen)>>1;
				int st,ed,mid,p,q;
				st=0,ed=id;
				while(st+1<ed){
					mid=(st+ed)>>1;
					if(lcp(mid,id)>=midlen) ed=mid;
					else st=mid;
				}
				p=ed;
				st=id,ed=len+1;
				while(st+1<ed){
					mid=(st+ed)>>1;
					if(lcp(id,mid)>=midlen) st=mid;
					else ed=mid;
				}
				q=st;
				int RES=calc(root[q],1,len+1,p,q+1);
				if(RES>=k) stlen=midlen;
				else edlen=midlen;
			}
			ans+=stlen;
		}
		cout<<ans<<' ';
	}
    return 0;
}


#include <bits/stdc++.h>
#define x first
#define y second

using namespace std;
typedef pair<int,int> pii;
typedef long long INT;

#define NN 200011
string s;
int I[NN], H[NN], rk[NN], sa[NN];
int head[NN], buf[NN], nxt[NN], mn[NN][20];
pii pos[NN];

void bucket_sort(int n){
	int E=0,m=max(n+10,256);
	for(int i=0;i<=m;i++) head[i]=0;
	for(int i=0,u;i<n;i++){
		u=pos[I[i]].y;
		buf[++E]=I[i];
		nxt[E]=head[u];
		head[u]=E;
	}
	for(int i=m,K=0;i>=0;i--){
		for(int j=head[i];j;j=nxt[j]) I[K++]=buf[j];
	}
	for(int i=0;i<=m;i++) head[i]=0;
	for(int i=0,u;i<n;i++){
		u=pos[I[i]].x;
		buf[++E]=I[i];
		nxt[E]=head[u];
		head[u]=E;
	}
	for(int i=0,K=0;i<=m;i++){
		for(int j=head[i];j;j=nxt[j]) I[K++]=buf[j];
	}
}

void buildSA(int n){
	for(int i=0;i<=n;i++) rk[i]=s[i];
	for(int i=0;i<19;i++){
		for (int j=0;j<n;j++){
			pos[j]=pii(rk[j],rk[min(n,j+(1<<i))]);
			I[j]=j;
		}
		bucket_sort(n);
		int cnt=0;
		pos[n]=pii(-1,-1);
		I[n]=n;
		for(int j=0;j<n;j++){
			rk[I[j]]=cnt+1;
			cnt+=pos[I[j]]!=pos[I[j+1]];
		}
		if(cnt==n) break;
	}
	for(int i=0;i<n;i++) sa[rk[i]]=i;
	for(int i=0,h=0;i<n;i++){
		if(rk[i]==1) continue;
		h=max(h-1,0);
		for(int j=sa[rk[i]-1];s[i+h]==s[j+h];h++);
		H[rk[i]]=h;
	}
	for(int j=1;j<19;j++){
		for(int i=1;i<=n;i++){
			if(i+(1<<j)-1>n) continue;
			if(j==1) mn[i][j]=H[i+1];
			else mn[i][j]=min(H[i+(1<<(j-1))],min(mn[i][j-1],mn[i+(1<<(j-1))][j-1]));
		}
	}
}

int lcp(int u,int v){
	if(u>v) swap(u,v);
	int rr=31-__builtin_clz(v-u+1);
	return min(mn[u][rr],mn[v-(1<<rr)+1][rr]);
}

string t[NN];
int sz[NN];
int a[NN],val[NN];

#define MM 10000000
#define umid (L+R>>1)
int uqe[MM],ls[MM],rs[MM];
int root[NN];
int ID;

void push_up(int u,int L,int R){
	uqe[u]=uqe[ls[u]]+uqe[rs[u]];
}

int build(int L,int R){
	int u=ID++;
	if(L+1==R){
		uqe[u]=0;
		return u;
	}
	ls[u]=build(L,umid);
	rs[u]=build(umid,R);
	push_up(u,L,R);
	return u;
}

int clone(int u){
	uqe[ID++]=uqe[u];
	return ID-1;
}

int update(int u,int L,int R,int st,int ed,int x){
	if(st>=R||ed<=L) return u;
	int xx=clone(u);
	if(st<=L&&ed>=R){
		uqe[xx]+=x;
		return xx;
	}
	ls[xx]=update(ls[u],L,umid,st,ed,x);
	rs[xx]=update(rs[u],umid,R,st,ed,x);
	push_up(xx,L,R);
	return xx;
}

int calc(int u,int L,int R,int st,int ed){
	if(st>=R||ed<=L) return 0;
	if(st<=L&&ed>=R) return uqe[u];
	return calc(ls[u],L,umid,st,ed)+calc(rs[u],umid,R,st,ed);
}

int pre[NN],fv[NN];
int in[NN];

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif

	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>t[i];
		in[i]=t[i].size()+1;
		sz[i]=in[i]+sz[i-1];
		s+='*';
		s+=t[i];
	}
	int len=s.size();
	if(len>NN/2) while(1);
	buildSA(len);
	int CT=0;
	for(int i=1;i<=n;i++){
		for(int j=0;j<in[i];j++){
			val[CT++]=i;
		}
	}
	for(int i=1;i<=len;i++) a[i]=val[sa[i]];
	for(int i=1;i<=len;i++){
		pre[i]=fv[a[i]];
		fv[a[i]]=i;
	}
	root[0]=build(1,len+1);
	for(int i=1;i<=len;i++){
		root[i]=update(root[i-1],1,len+1,i,i+1,1);
		if(pre[i]) root[i]=update(root[i],1,len+1,pre[i],pre[i]+1,-1);
	}
	for(int ii=1;ii<=n;ii++){
		INT ans=0;
		for(int jj=1;jj<in[ii];jj++){
			int id=rk[sz[ii-1]+jj];
			int stlen=0,edlen=in[ii]-jj+1;
			while(stlen+1<edlen){
				int midlen=(stlen+edlen)>>1;
				int st,ed,mid,p,q;
				st=0,ed=id;
				while(st+1<ed){
					mid=(st+ed)>>1;
					if(lcp(mid,id)>=midlen) ed=mid;
					else st=mid;
				}
				p=ed;
				st=id,ed=len+1;
				while(st+1<ed){
					mid=(st+ed)>>1;
					if(lcp(id,mid)>=midlen) st=mid;
					else ed=mid;
				}
				q=st;
				int RES=calc(root[q],1,len+1,p,q+1);
				if(RES>=k) stlen=midlen;
				else edlen=midlen;
			}
			ans+=stlen;
		}
		cout<<ans<<' ';
	}
    return 0;
}


#include <bits/stdc++.h>
#define x first
#define y second

using namespace std;
typedef pair<int,int> pii;
typedef long long INT;

#define NN 100010
string s;
int I[NN], H[NN], rk[NN], sa[NN];
int head[NN], buf[NN], nxt[NN], mn[NN][19];
pii pos[NN];

void bucket_sort(int n){
	int E=0,m=max(n+10,256);
	for(int i=0;i<=m;i++) head[i]=0;
	for(int i=0,u;i<n;i++){
		u=pos[I[i]].y;
		buf[++E]=I[i];
		nxt[E]=head[u];
		head[u]=E;
	}
	for(int i=m,K=0;i>=0;i--){
		for(int j=head[i];j;j=nxt[j]) I[K++]=buf[j];
	}
	for(int i=0;i<=m;i++) head[i]=0;
	for(int i=0,u;i<n;i++){
		u=pos[I[i]].x;
		buf[++E]=I[i];
		nxt[E]=head[u];
		head[u]=E;
	}
	for(int i=0,K=0;i<=m;i++){
		for(int j=head[i];j;j=nxt[j]) I[K++]=buf[j];
	}
}

void buildSA(int n){
	for(int i=0;i<=n;i++) rk[i]=s[i];
	for(int i=0;i<18;i++){
		for (int j=0;j<n;j++){
			pos[j]=pii(rk[j],rk[min(n,j+(1<<i))]);
			I[j]=j;
		}
		bucket_sort(n);
		int cnt=0;
		pos[n]=pii(-1,-1);
		I[n]=n;
		for(int j=0;j<n;j++){
			rk[I[j]]=cnt+1;
			cnt+=pos[I[j]]!=pos[I[j+1]];
		}
		if(cnt==n) break;
	}
	for(int i=0;i<n;i++) sa[rk[i]]=i;
	for(int i=0,h=0;i<n;i++){
		if(rk[i]==1) continue;
		h=max(h-1,0);
		for(int j=sa[rk[i]-1];s[i+h]==s[j+h];h++);
		H[rk[i]]=h;
	}
	for(int j=1;j<18;j++){
		for(int i=1;i<=n;i++){
			if(i+(1<<j)-1>n) continue;
			if(j==1) mn[i][j]=H[i+1];
			else mn[i][j]=min(H[i+(1<<(j-1))],min(mn[i][j-1],mn[i+(1<<(j-1))][j-1]));
		}
	}
}

int lcp(int u,int v){
	if(u>v) swap(u,v);
	int rr=31-__builtin_clz(v-u+1);
	return min(mn[u][rr],mn[v-(1<<rr)+1][rr]);
}

string t[NN];
int sz[NN];
int a[NN],val[NN];

#define MM 6100000
#define umid (L+R>>1)
int uqe[MM],ls[MM],rs[MM];
int root[NN];
int ID;

void push_up(int u,int L,int R){
	uqe[u]=uqe[ls[u]]+uqe[rs[u]];
}

int build(int L,int R){
	int u=ID++;
	if(L+1==R){
		uqe[u]=0;
		return u;
	}
	ls[u]=build(L,umid);
	rs[u]=build(umid,R);
	push_up(u,L,R);
	return u;
}

int clone(int u){
	uqe[ID++]=uqe[u];
	return ID-1;
}

int update(int u,int L,int R,int st,int ed,int x){
	if(st>=R||ed<=L) return u;
	int xx=clone(u);
	if(st<=L&&ed>=R){
		uqe[xx]+=x;
		return xx;
	}
	ls[xx]=update(ls[u],L,umid,st,ed,x);
	rs[xx]=update(rs[u],umid,R,st,ed,x);
	push_up(xx,L,R);
	return xx;
}

int calc(int u,int L,int R,int st,int ed){
	if(st>=R||ed<=L) return 0;
	if(st<=L&&ed>=R) return uqe[u];
	return calc(ls[u],L,umid,st,ed)+calc(rs[u],umid,R,st,ed);
}

int pre[NN],fv[NN];
int in[NN];

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif

	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>t[i];
		in[i]=t[i].size();
		sz[i]=in[i]+sz[i-1];
		s+=t[i];
	}
	int len=s.size();
	buildSA(len);
	int CT=0;
	for(int i=1;i<=n;i++){
		for(int j=0;j<in[i];j++){
			val[CT++]=i;
		}
	}
	for(int i=1;i<=len;i++) a[i]=val[sa[i]];
	for(int i=1;i<=len;i++){
		pre[i]=fv[a[i]];
		fv[a[i]]=i;
	}
	build(1,len+1);
	for(int i=1;i<=len;i++){
		root[i]=update(root[i-1],1,len+1,i,i+1,1);
		if(pre[i]) root[i]=update(root[i],1,len+1,pre[i],pre[i]+1,-1);
	}
	for(int ii=1;ii<=n;ii++){
		INT ans=0;
		for(int jj=0;jj<in[ii];jj++){
			int id=rk[sz[ii-1]+jj];
			int stlen=0,edlen=in[ii]-jj+1;
			while(stlen+1<edlen){
				int midlen=(stlen+edlen)>>1;
				int st,ed,mid,p,q;
				st=0,ed=id;
				while(st+1<ed){
					mid=(st+ed)>>1;
					if(lcp(mid,id)>=midlen) ed=mid;
					else st=mid;
				}
				p=ed;
				st=id,ed=len+1;
				while(st+1<ed){
					mid=(st+ed)>>1;
					if(lcp(id,mid)>=midlen) st=mid;
					else ed=mid;
				}
				q=st;
				int RES=calc(root[q],1,len+1,p,q+1);
				if(RES>=k) stlen=midlen;
				else edlen=midlen;
			}
			ans+=stlen;
		}
		cout<<ans<<' ';
	}
    return 0;
}


#include <bits/stdc++.h>
#define x first
#define y second

using namespace std;
typedef pair<int,int> pii;
typedef long long INT;

#define NN 200010
string s;
int I[NN], H[NN], rk[NN], sa[NN];
int head[NN], buf[NN], nxt[NN], mn[NN][19];
pii pos[NN];

void bucket_sort(int n){
	int E=0,m=max(n+10,256);
	for(int i=0;i<=m;i++) head[i]=0;
	for(int i=0,u;i<n;i++){
		u=pos[I[i]].y;
		buf[++E]=I[i];
		nxt[E]=head[u];
		head[u]=E;
	}
	for(int i=m,K=0;i>=0;i--){
		for(int j=head[i];j;j=nxt[j]) I[K++]=buf[j];
	}
	for(int i=0;i<=m;i++) head[i]=0;
	for(int i=0,u;i<n;i++){
		u=pos[I[i]].x;
		buf[++E]=I[i];
		nxt[E]=head[u];
		head[u]=E;
	}
	for(int i=0,K=0;i<=m;i++){
		for(int j=head[i];j;j=nxt[j]) I[K++]=buf[j];
	}
}

void buildSA(int n){
	for(int i=0;i<=n;i++) rk[i]=s[i];
	for(int i=0;i<18;i++){
		for (int j=0;j<n;j++){
			pos[j]=pii(rk[j],rk[min(n,j+(1<<i))]);
			I[j]=j;
		}
		bucket_sort(n);
		int cnt=0;
		pos[n]=pii(-1,-1);
		I[n]=n;
		for(int j=0;j<n;j++){
			rk[I[j]]=cnt+1;
			cnt+=pos[I[j]]!=pos[I[j+1]];
		}
		if(cnt==n) break;
	}
	for(int i=0;i<n;i++) sa[rk[i]]=i;
	for(int i=0,h=0;i<n;i++){
		if(rk[i]==1) continue;
		h=max(h-1,0);
		for(int j=sa[rk[i]-1];s[i+h]==s[j+h];h++);
		H[rk[i]]=h;
	}
	for(int j=1;j<18;j++){
		for(int i=1;i<=n;i++){
			if(i+(1<<j)-1>n) continue;
			if(j==1) mn[i][j]=H[i+1];
			else mn[i][j]=min(H[i+(1<<(j-1))],min(mn[i][j-1],mn[i+(1<<(j-1))][j-1]));
		}
	}
}

int lcp(int u,int v){
	if(u>v) swap(u,v);
	int rr=31-__builtin_clz(v-u+1);
	return min(mn[u][rr],mn[v-(1<<rr)+1][rr]);
}

string t[NN];
int sz[NN];
int a[NN],val[NN];

#define MM 10000000
#define umid (L+R>>1)
int uqe[MM],ls[MM],rs[MM];
int root[NN];
int ID;

void push_up(int u,int L,int R){
	uqe[u]=uqe[ls[u]]+uqe[rs[u]];
}

int build(int L,int R){
	int u=ID++;
	if(L+1==R){
		uqe[u]=0;
		return u;
	}
	ls[u]=build(L,umid);
	rs[u]=build(umid,R);
	push_up(u,L,R);
	return u;
}

int clone(int u){
	uqe[ID++]=uqe[u];
	return ID-1;
}

int update(int u,int L,int R,int st,int ed,int x){
	if(st>=R||ed<=L) return u;
	int xx=clone(u);
	if(st<=L&&ed>=R){
		uqe[xx]+=x;
		return xx;
	}
	ls[xx]=update(ls[u],L,umid,st,ed,x);
	rs[xx]=update(rs[u],umid,R,st,ed,x);
	push_up(xx,L,R);
	return xx;
}

int calc(int u,int L,int R,int st,int ed){
	if(st>=R||ed<=L) return 0;
	if(st<=L&&ed>=R) return uqe[u];
	return calc(ls[u],L,umid,st,ed)+calc(rs[u],umid,R,st,ed);
}

int pre[NN],fv[NN];
int in[NN];

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif

	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>t[i];
		in[i]=t[i].size()+1;
		sz[i]=in[i]+sz[i-1];
		s+='*';
		s+=t[i];
	}
	int len=s.size();
	buildSA(len);
	int CT=0;
	for(int i=1;i<=n;i++){
		for(int j=0;j<in[i];j++){
			val[CT++]=i;
		}
	}
	for(int i=1;i<=len;i++) a[i]=val[sa[i]];
	for(int i=1;i<=len;i++){
		pre[i]=fv[a[i]];
		fv[a[i]]=i;
	}
	root[0]=build(1,len+1);
	for(int i=1;i<=len;i++){
		root[i]=update(root[i-1],1,len+1,i,i+1,1);
		if(pre[i]) root[i]=update(root[i],1,len+1,pre[i],pre[i]+1,-1);
	}
	for(int ii=1;ii<=n;ii++){
		INT ans=0;
		for(int jj=1;jj<in[ii];jj++){
			int id=rk[sz[ii-1]+jj];
			int stlen=0,edlen=in[ii]-jj+1;
			while(stlen+1<edlen){
				int midlen=(stlen+edlen)>>1;
				int st,ed,mid,p,q;
				st=0,ed=id;
				while(st+1<ed){
					mid=(st+ed)>>1;
					if(lcp(mid,id)>=midlen) ed=mid;
					else st=mid;
				}
				p=ed;
				st=id,ed=len+1;
				while(st+1<ed){
					mid=(st+ed)>>1;
					if(lcp(id,mid)>=midlen) st=mid;
					else ed=mid;
				}
				q=st;
				int RES=calc(root[q],1,len+1,p,q+1);
				if(RES>=k) stlen=midlen;
				else edlen=midlen;
			}
			ans+=stlen;
		}
		cout<<ans<<' ';
	}
    return 0;
}


#include <bits/stdc++.h>
#define x first
#define y second

using namespace std;
typedef pair<int,int> pii;
typedef long long INT;

#define NN 200010
string s;
int I[NN], H[NN], rk[NN], sa[NN];
int head[NN], buf[NN], nxt[NN], mn[NN][20];
pii pos[NN];

void bucket_sort(int n){
	int E=0,m=max(n+10,256);
	for(int i=0;i<=m;i++) head[i]=0;
	for(int i=0,u;i<n;i++){
		u=pos[I[i]].y;
		buf[++E]=I[i];
		nxt[E]=head[u];
		head[u]=E;
	}
	for(int i=m,K=0;i>=0;i--){
		for(int j=head[i];j;j=nxt[j]) I[K++]=buf[j];
	}
	E=0;
	for(int i=0;i<=m;i++) head[i]=0;
	for(int i=0,u;i<n;i++){
		u=pos[I[i]].x;
		buf[++E]=I[i];
		nxt[E]=head[u];
		head[u]=E;
	}
	for(int i=0,K=0;i<=m;i++){
		for(int j=head[i];j;j=nxt[j]) I[K++]=buf[j];
	}
}

void buildSA(int n){
	for(int i=0;i<=n;i++) rk[i]=s[i];
	for(int i=0;i<19;i++){
		for (int j=0;j<n;j++){
			pos[j]=pii(rk[j],rk[min(n,j+(1<<i))]);
			I[j]=j;
		}
		bucket_sort(n);
		int cnt=0;
		pos[n]=pii(-1,-1);
		I[n]=n;
		for(int j=0;j<n;j++){
			rk[I[j]]=cnt+1;
			cnt+=pos[I[j]]!=pos[I[j+1]];
		}
		if(cnt==n) break;
	}
	for(int i=0;i<n;i++) sa[rk[i]]=i;
	for(int i=0,h=0;i<n;i++){
		if(rk[i]==1) continue;
		h=max(h-1,0);
		for(int j=sa[rk[i]-1];s[i+h]==s[j+h];h++);
		H[rk[i]]=h;
	}
	for(int j=1;j<19;j++){
		for(int i=1;i<=n;i++){
			if(i+(1<<j)-1>n) continue;
			if(j==1) mn[i][j]=H[i+1];
			else mn[i][j]=min(H[i+(1<<(j-1))],min(mn[i][j-1],mn[i+(1<<(j-1))][j-1]));
		}
	}
}

int lcp(int u,int v){
	if(u>v) swap(u,v);
	int rr=31-__builtin_clz(v-u+1);
	return min(mn[u][rr],mn[v-(1<<rr)+1][rr]);
}

string t[NN];
int sz[NN];
int a[NN],val[NN];

#define MM 10000000
#define umid (L+R>>1)
int uqe[MM],ls[MM],rs[MM];
int root[NN];
int ID;

void push_up(int u,int L,int R){
	uqe[u]=uqe[ls[u]]+uqe[rs[u]];
}

int build(int L,int R){
	int u=ID++;
	if(L+1==R){
		uqe[u]=0;
		return u;
	}
	ls[u]=build(L,umid);
	rs[u]=build(umid,R);
	push_up(u,L,R);
	return u;
}

int clone(int u){
	uqe[ID++]=uqe[u];
	return ID-1;
}

int update(int u,int L,int R,int st,int ed,int x){
	if(st>=R||ed<=L) return u;
	int xx=clone(u);
	if(st<=L&&ed>=R){
		uqe[xx]+=x;
		return xx;
	}
	ls[xx]=update(ls[u],L,umid,st,ed,x);
	rs[xx]=update(rs[u],umid,R,st,ed,x);
	push_up(xx,L,R);
	return xx;
}

int calc(int u,int L,int R,int st,int ed){
	if(st>=R||ed<=L) return 0;
	if(st<=L&&ed>=R) return uqe[u];
	return calc(ls[u],L,umid,st,ed)+calc(rs[u],umid,R,st,ed);
}

int pre[NN],fv[NN];
int in[NN];

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif

	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>t[i];
		in[i]=t[i].size()+1;
		sz[i]=in[i]+sz[i-1];
		s+='*';
		s+=t[i];
	}
	int len=s.size();
	buildSA(len);
	int CT=0;
	for(int i=1;i<=n;i++){
		for(int j=0;j<in[i];j++){
			val[CT++]=i;
		}
	}
	for(int i=1;i<=len;i++) a[i]=val[sa[i]];
	for(int i=1;i<=len;i++){
		pre[i]=fv[a[i]];
		fv[a[i]]=i;
	}
	root[0]=build(1,len+1);
	for(int i=1;i<=len;i++){
		root[i]=update(root[i-1],1,len+1,i,i+1,1);
		if(pre[i]) root[i]=update(root[i],1,len+1,pre[i],pre[i]+1,-1);
	}
	for(int ii=1;ii<=n;ii++){
		INT ans=0;
		for(int jj=1;jj<in[ii];jj++){
			int id=rk[sz[ii-1]+jj];
			int stlen=0,edlen=in[ii]-jj+1;
			while(stlen+1<edlen){
				int midlen=(stlen+edlen)>>1;
				int st,ed,mid,p,q;
				st=0,ed=id;
				while(st+1<ed){
					mid=(st+ed)>>1;
					if(lcp(mid,id)>=midlen) ed=mid;
					else st=mid;
				}
				p=ed;
				st=id,ed=len+1;
				while(st+1<ed){
					mid=(st+ed)>>1;
					if(lcp(id,mid)>=midlen) st=mid;
					else ed=mid;
				}
				q=st;
				int RES=calc(root[q],1,len+1,p,q+1);
				if(RES>=k) stlen=midlen;
				else edlen=midlen;
			}
			ans+=stlen;
		}
		cout<<ans<<' ';
	}
    return 0;
}


#include <bits/stdc++.h>
#define x first
#define y second

using namespace std;
typedef pair<int,int> pii;
typedef long long INT;

#define NN 200010
string s;
int I[NN], H[NN], rk[NN], sa[NN];
int head[NN], buf[NN], nxt[NN], mn[NN][20];
pii pos[NN];

void bucket_sort(int n){
	int E=0,m=max(n+10,256);
	for(int i=0;i<=m;i++) head[i]=0;
	for(int i=0,u;i<n;i++){
		u=pos[I[i]].y;
		buf[++E]=I[i];
		nxt[E]=head[u];
		head[u]=E;
	}
	for(int i=m,K=0;i>=0;i--){
		for(int j=head[i];j;j=nxt[j]) I[K++]=buf[j];
	}
	for(int i=0;i<=m;i++) head[i]=0;
	for(int i=0,u;i<n;i++){
		u=pos[I[i]].x;
		buf[++E]=I[i];
		nxt[E]=head[u];
		head[u]=E;
	}
	for(int i=0,K=0;i<=m;i++){
		for(int j=head[i];j;j=nxt[j]) I[K++]=buf[j];
	}
}

void buildSA(int n){
	for(int i=0;i<=n;i++) rk[i]=s[i];
	for(int i=0;i<19;i++){
		for (int j=0;j<n;j++){
			pos[j]=pii(rk[j],rk[min(n,j+(1<<i))]);
			I[j]=j;
		}
		bucket_sort(n);
		int cnt=0;
		pos[n]=pii(-1,-1);
		I[n]=n;
		for(int j=0;j<n;j++){
			rk[I[j]]=cnt+1;
			cnt+=pos[I[j]]!=pos[I[j+1]];
		}
		if(cnt==n) break;
	}
	for(int i=0;i<n;i++) sa[rk[i]]=i;
	for(int i=0,h=0;i<n;i++){
		if(rk[i]==1) continue;
		h=max(h-1,0);
		for(int j=sa[rk[i]-1];s[i+h]==s[j+h];h++);
		H[rk[i]]=h;
	}
	for(int j=1;j<19;j++){
		for(int i=1;i<=n;i++){
			if(i+(1<<j)-1>n) continue;
			if(j==1) mn[i][j]=H[i+1];
			else mn[i][j]=min(H[i+(1<<(j-1))],min(mn[i][j-1],mn[i+(1<<(j-1))][j-1]));
		}
	}
}

int lcp(int u,int v){
	if(u>v) swap(u,v);
	int rr=31-__builtin_clz(v-u+1);
	return min(mn[u][rr],mn[v-(1<<rr)+1][rr]);
}

string t[NN];
int sz[NN];
int a[NN],val[NN];

#define MM 10000000
#define umid (L+R>>1)
int uqe[MM],ls[MM],rs[MM];
int root[NN];
int ID;

void push_up(int u,int L,int R){
	uqe[u]=uqe[ls[u]]+uqe[rs[u]];
}

int build(int L,int R){
	int u=ID++;
	if(L+1==R){
		uqe[u]=0;
		return u;
	}
	ls[u]=build(L,umid);
	rs[u]=build(umid,R);
	push_up(u,L,R);
	return u;
}

int clone(int u){
	uqe[ID++]=uqe[u];
	return ID-1;
}

int update(int u,int L,int R,int st,int ed,int x){
	if(st>=R||ed<=L) return u;
	int xx=clone(u);
	if(st<=L&&ed>=R){
		uqe[xx]+=x;
		return xx;
	}
	ls[xx]=update(ls[u],L,umid,st,ed,x);
	rs[xx]=update(rs[u],umid,R,st,ed,x);
	push_up(xx,L,R);
	return xx;
}

int calc(int u,int L,int R,int st,int ed){
	if(st>=R||ed<=L) return 0;
	if(st<=L&&ed>=R) return uqe[u];
	return calc(ls[u],L,umid,st,ed)+calc(rs[u],umid,R,st,ed);
}

int pre[NN],fv[NN];
int in[NN];

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif

	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>t[i];
		in[i]=t[i].size()+1;
		sz[i]=in[i]+sz[i-1];
		s+='*';
		s+=t[i];
	}
	int len=s.size();
	buildSA(len);
	int CT=0;
	for(int i=1;i<=n;i++){
		for(int j=0;j<in[i];j++){
			val[CT++]=i;
		}
	}
	for(int i=1;i<=len;i++) a[i]=val[sa[i]];
	for(int i=1;i<=len;i++){
		pre[i]=fv[a[i]];
		fv[a[i]]=i;
	}
	root[0]=build(1,len+1);
	for(int i=1;i<=len;i++){
		root[i]=update(root[i-1],1,len+1,i,i+1,1);
		if(pre[i]) root[i]=update(root[i],1,len+1,pre[i],pre[i]+1,-1);
	}
	for(int ii=1;ii<=n;ii++){
		INT ans=0;
		for(int jj=1;jj<in[ii];jj++){
			int id=rk[sz[ii-1]+jj];
			int stlen=0,edlen=in[ii]-jj+1;
			while(stlen+1<edlen){
				int midlen=(stlen+edlen)>>1;
				int st,ed,mid,p,q;
				st=0,ed=id;
				while(st+1<ed){
					mid=(st+ed)>>1;
					if(lcp(mid,id)>=midlen) ed=mid;
					else st=mid;
				}
				p=ed;
				st=id,ed=len+1;
				while(st+1<ed){
					mid=(st+ed)>>1;
					if(lcp(id,mid)>=midlen) st=mid;
					else ed=mid;
				}
				q=st;
				int RES=calc(root[q],1,len+1,p,q+1);
				if(RES>=k) stlen=midlen;
				else edlen=midlen;
			}
			ans+=stlen;
		}
		cout<<ans<<' ';
	}
    return 0;
}


#include <bits/stdc++.h>
#define x first
#define y second

using namespace std;
typedef pair<int,int> pii;
typedef long long INT;

#define NN 100010
string s;
int I[NN], H[NN], rk[NN], sa[NN];
int head[NN], buf[NN], nxt[NN], mn[NN][19];
pii pos[NN];

void bucket_sort(int n){
	int E=0,m=max(n+10,256);
	for(int i=0;i<=m;i++) head[i]=0;
	for(int i=0,u;i<n;i++){
		u=pos[I[i]].y;
		buf[++E]=I[i];
		nxt[E]=head[u];
		head[u]=E;
	}
	for(int i=m,K=0;i>=0;i--){
		for(int j=head[i];j;j=nxt[j]) I[K++]=buf[j];
	}
	for(int i=0;i<=m;i++) head[i]=0;
	for(int i=0,u;i<n;i++){
		u=pos[I[i]].x;
		buf[++E]=I[i];
		nxt[E]=head[u];
		head[u]=E;
	}
	for(int i=0,K=0;i<=m;i++){
		for(int j=head[i];j;j=nxt[j]) I[K++]=buf[j];
	}
}

void buildSA(int n){
	for(int i=0;i<=n;i++) rk[i]=s[i];
	for(int i=0;i<18;i++){
		for (int j=0;j<n;j++){
			pos[j]=pii(rk[j],rk[min(n,j+(1<<i))]);
			I[j]=j;
		}
		bucket_sort(n);
		int cnt=0;
		pos[n]=pii(-1,-1);
		I[n]=n;
		for(int j=0;j<n;j++){
			rk[I[j]]=cnt+1;
			cnt+=pos[I[j]]!=pos[I[j+1]];
		}
		if(cnt==n) break;
	}
	for(int i=0;i<n;i++) sa[rk[i]]=i;
	for(int i=0,h=0;i<n;i++){
		if(rk[i]==1) continue;
		h=max(h-1,0);
		for(int j=sa[rk[i]-1];s[i+h]==s[j+h];h++);
		H[rk[i]]=h;
	}
	for(int j=1;j<18;j++){
		for(int i=1;i<=n;i++){
			if(i+(1<<j)-1>n) continue;
			if(j==1) mn[i][j]=H[i+1];
			else mn[i][j]=min(H[i+(1<<(j-1))],min(mn[i][j-1],mn[i+(1<<(j-1))][j-1]));
		}
	}
}

int lcp(int u,int v){
	if(u>v) swap(u,v);
	int rr=31-__builtin_clz(v-u+1);
	return min(mn[u][rr],mn[v-(1<<rr)+1][rr]);
}

string t[NN];
int sz[NN];
int a[NN],val[NN];

#define MM 6100000
#define umid (L+R>>1)
int uqe[MM],ls[MM],rs[MM];
int root[NN];
int ID;

void push_up(int u,int L,int R){
	uqe[u]=uqe[ls[u]]+uqe[rs[u]];
}

int build(int L,int R){
	int u=ID++;
	if(L+1==R){
		uqe[u]=0;
		return u;
	}
	ls[u]=build(L,umid);
	rs[u]=build(umid,R);
	push_up(u,L,R);
	return u;
}

int clone(int u){
	uqe[ID++]=uqe[u];
	return ID-1;
}

int update(int u,int L,int R,int st,int ed,int x){
	if(st>=R||ed<=L) return u;
	int xx=clone(u);
	if(st<=L&&ed>=R){
		uqe[xx]+=x;
		return xx;
	}
	ls[xx]=update(ls[u],L,umid,st,ed,x);
	rs[xx]=update(rs[u],umid,R,st,ed,x);
	push_up(xx,L,R);
	return xx;
}

int calc(int u,int L,int R,int st,int ed){
	if(st>=R||ed<=L) return 0;
	if(st<=L&&ed>=R) return uqe[u];
	return calc(ls[u],L,umid,st,ed)+calc(rs[u],umid,R,st,ed);
}

int pre[NN],fv[NN];
int in[NN];

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif

	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>t[i];
		in[i]=t[i].size();
		sz[i]=in[i]+sz[i-1];
		s+=t[i];
	}
	int len=s.size();
	buildSA(len);
	int CT=0;
	for(int i=1;i<=n;i++){
		for(int j=0;j<in[i];j++){
			val[CT++]=i;
		}
	}
	for(int i=1;i<=len;i++) a[i]=val[sa[i]];
	for(int i=1;i<=len;i++){
		pre[i]=fv[a[i]];
		fv[a[i]]=i;
	}
	root[0]=build(1,len+1);
	for(int i=1;i<=len;i++){
		root[i]=update(root[i-1],1,len+1,i,i+1,1);
		if(pre[i]) root[i]=update(root[i],1,len+1,pre[i],pre[i]+1,-1);
	}
	for(int ii=1;ii<=n;ii++){
		INT ans=0;
		for(int jj=0;jj<in[ii];jj++){
			int id=rk[sz[ii-1]+jj];
			int stlen=0,edlen=in[ii]-jj+1;
			while(stlen+1<edlen){
				int midlen=(stlen+edlen)>>1;
				int st,ed,mid,p,q;
				st=0,ed=id;
				while(st+1<ed){
					mid=(st+ed)>>1;
					if(lcp(mid,id)>=midlen) ed=mid;
					else st=mid;
				}
				p=ed;
				st=id,ed=len+1;
				while(st+1<ed){
					mid=(st+ed)>>1;
					if(lcp(id,mid)>=midlen) st=mid;
					else ed=mid;
				}
				q=st;
				int RES=calc(root[q],1,len+1,p,q+1);
				if(RES>=k) stlen=midlen;
				else edlen=midlen;
			}
			ans+=stlen;
		}
		cout<<ans<<' ';
	}
    return 0;
}


#include<bits/stdc++.h>

#define pb push_back
#define sz(a) ((int)a.size())
#define x first
#define y second

using namespace std;

typedef long long INT;
typedef pair<int, int> pii;

template<typename T, typename U> inline void smin(T &a, U b) {if(a>b) a=b;}
template<typename T, typename U> inline void smax(T &a, U b) {if(a<b) a=b;}

template<class T>inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>'9' || c<'0') && c!='-');for((c=='-'?sg=1, c=getchar():0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0';if (sg) x=-x;}
template<class T>inline void print(T x) {if (x<0) {putchar('-');return print(-x);}if (x<10) {putchar('0'+x);return;} print(x/10);putchar(x%10+'0');}
template<class T, class T1>inline void gn(T &x, T1 &y) {gn(x); gn(y);}
template<class T, class T1, class T2>inline void gn(T &x, T1 &y, T2 &z) {gn(x); gn(y); gn(z);}
template <class T> inline void println(T x) {print(x); putchar('\n');}
template <class T> inline void printsp(T x) {print(x); putchar(' ');}
template <class T1, class T2> inline void print(T1 x1, T2 x2) {printsp(x1), println(x2);}
template <class T1, class T2, class T3> inline void print(T1 x1, T2 x2, T3 x3) {printsp(x1), printsp(x2), println(x3);}
template <class T1, class T2, class T3, class T4> inline void print(T1 x1, T2 x2, T3 x3, T4 x4) {printsp(x1), printsp(x2), printsp(x3), println(x4);}

#define NN 200011
int n, k;
const int sma=27;
const int MM = NN*2;
int val[NN*2];

struct tnode{
    tnode *l, *r;
    int C;
} buf[NN*50], *cur = buf;

struct automaton{
	int sz, ed;

    struct node{
		int deep, fail, nxt[sma]; // cnt is the number of any path from this node.
		int id;
        tnode *r;
		void clear() {
			for(int i=0; i<sma; i++) nxt[i]=-1;
			fail=0; deep=0;
			r=NULL;
		}
	} mem[NN*2];

	void init() {
		mem[1].clear(); mem[0].clear();
		for(int i=0; i<sma; i++) mem[0].nxt[i]=1;
		mem[0].deep=-1;
		sz=2; ed=1;
		return ;
	}

	#define mid (st+ed>>1)

    inline void push_up(tnode *p) {
        if(p == NULL) return ;
        p->C = 0;
        if(p->l) p->C += p->l->C;
        if(p->r) p->C += p->r->C;
        if(p->C == 0) p->C=1;
    }

	tnode *build(int st, int ed, int x) {
	    tnode *p = cur++;
	    if(ed > st + 1) {
            if(x>=mid) p->r = build(mid, ed, x);
            else p->l = build(st, mid, x);
            push_up(p);
	    } else p -> C = 1;
        return p;
	}

    tnode *merge(tnode *a, tnode *b) {
        tnode *p;
        if(!a or !b) {
            if(a) p = a;
            else p = b;
        } else {
            p = cur++;
            p->l = merge(a->l, b->l);
            p->r = merge(a->r, b->r);
            push_up(p);
        }
        return p;
    }

	void insert(int c, int st) {
		int p=sz++;
		mem[p].clear();
		mem[p].deep=mem[ed].deep+1;
		mem[p].id = st;
		while(mem[ed].nxt[c]==-1) {
			mem[ed].nxt[c]=p;
			ed=mem[ed].fail;
		}
		int p1=mem[ed].nxt[c];
		if(mem[p1].deep==mem[ed].deep+1) mem[p].fail=p1;
		else {
			int p2=sz++;
			mem[p2]=mem[p1];
			mem[p2].id = n + 1;
			mem[p2].deep=mem[ed].deep+1;
			mem[p1].fail=mem[p].fail=p2;
			while(mem[ed].nxt[c]==p1) {
				mem[ed].nxt[c]=p2;
				ed=mem[ed].fail;
			}
		}
		ed=p;
        if(st <= n) mem[ed].r = build(1, n+1, st);
		return ;
	}
    int cnt[NN*2], ord[NN*2];
    void solve(int n) {
        for(int i=0; i<n+3; i++) cnt[i]=0;
		for(int i=1; i<sz; i++) cnt[mem[i].deep] ++;
		for(int i=1; i<n+3; i++) cnt[i] += cnt[i-1];
		for(int i=1; i<sz; i++) ord[--cnt[mem[i].deep] ]=i;
		for(int i=sz-2; i >= 0; i--) {
			int cur=ord[i];
			int prv=mem[cur].fail;
            if(mem[cur].r) val[cur] = mem[cur].r->C;
			if(mem[cur].r) mem[prv].r = merge(mem[prv].r, mem[cur].r);
		}
    }
} sam;

char s[NN];
vector<char> t[NN];

int main() {
#ifndef	ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif

	gn(n, k);
	sam.init();
	int len=0;

	for(int i=1; i<=n; i++) {
		scanf("%s", s);
		for(int j=0; s[j]; j++) sam.insert(s[j] - 'a', i), len++, t[i].pb(s[j]);
		if(i<n) sam.insert(26, n+1), len++;
	}

	sam.solve(len);
	for(int i=1; i<=n; i++) {
		int now = 1;
		INT ans=0;
		int add=0;

		for(int j=0; j<sz(t[i]); j++) {
			int c=t[i][j]-'a';
			while(sam.mem[now].nxt[c] == -1) now = sam.mem[now].fail;
			now = sam.mem[now].nxt[c];
			add++;
			while(now > 1 and val[now]<k) {
				now = sam.mem[now].fail;
				add = sam.mem[now].deep;
			}
			ans += add;
		}
		printsp(ans);
	}

	puts("");
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int MAXLEN = 501005;

typedef long long ll;

int q[2*MAXLEN], deg[2*MAXLEN];

ll ans[MAXLEN];

map<int,int> has[2*MAXLEN];

map<int,int> merge(map<int,int>a, map<int,int>b)
{
	if(a.size() < b.size())
		swap(a,b);
	for(auto &x: b)
		a[x.first] += x.second;
	return a;
}

int n,kk;

struct automaton
{
	struct state
	{
		int link;
		int next[27];
		int len;
	};
	state st[2*MAXLEN];
	int sz;
	void sa_init()
	{

		sz = 1;
		last = 0;
		st[0].link = -1;
		st[0].len = 0;
		memset(st[0].next,0,sizeof(st[0].next));
	}
	int last = 0;
	void sa_extend(int c, int id)
	{
		int cur = sz++;
		st[cur].len = st[last].len + 1;
		has[cur][id]++;
		int p = last;
		while(p != -1 && !st[p].next[c])
		{
			st[p].next[c] = cur;
			p = st[p].link;
		}
		if(p == -1)
		{
			st[cur].link = 0;
		}
		else
		{
			int q = st[p].next[c];
			if(st[p].len + 1 == st[q].len)
			{
				st[cur].link = q;
			}
			else
			{
				int clone = sz++;
				st[clone] = st[q];
				st[clone].len = st[p].len+1;
				while( p != -1 && st[p].next[c] == q )
				{
					st[p].next[c] = clone;
					p = st[p].link;
				}
				st[cur].link = st[q].link = clone;
			}
		}
		last = cur;
	}
	void sa_counting()
	{
		int p = 0;
		for(int i = 1 ;  i < sz  ;  i++  )
			deg[st[i].link]++;
		for(int i = 1 ;  i < sz  ;  i++  )
		{
			if( deg[i] == 0 )
				q[++p] = i;
		}
		while( p > 0 )
		{
			int k = q[p];
			p--;
			if(k <= 0)
				continue;
			has[st[k].link] = merge(has[st[k].link], has[k]);
			if(has[k].size() >= kk)
			{
				for(auto &x: has[k])
					ans[x.first] += (long long )x.second * (st[k].len - st[st[k].link].len);
			}
			if(  (--deg[st[k].link] ) == 0  )
				q[++p] = st[k].link;

		}
	}
}a;

char s[MAXLEN];

int main()
{

	scanf("%d %d",&n,&kk);
	a.sa_init();
	for(int i = 1 ; i <= n; i++)
	{
		a.last = 0;
		scanf("%s",s);
		int m = strlen(s);
		for(int j = 0; j < m; j++)
		{
			a.sa_extend(s[j] - 'a', i);
		}

	}

	a.sa_counting();

	for(int i = 1; i <= n; i++)
	{
		printf("%lld ",ans[i]);
	}
	puts("");

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int MAXLEN = 501005;

typedef long long ll;

int q[2*MAXLEN];

vector<int>graph[2*MAXLEN];

ll ans[MAXLEN];

map<int,int> has[2*MAXLEN];

void merge(map<int,int>&a, map<int,int>&b)
{
	if(a.size() < b.size())
		swap(a,b);
	for(auto &x: b)
		a[x.first] += x.second;
	b.clear();
}

int n,kk;

struct automaton
{
	struct state
	{
		int link;
		int next[27];
		int len;
	};
	state st[2*MAXLEN];
	int sz;
	void sa_init()
	{

		sz = 1;
		last = 0;
		st[0].link = -1;
		st[0].len = 0;
		memset(st[0].next,0,sizeof(st[0].next));
	}
	int last = 0;
	void sa_extend(int c, int id)
	{
		int cur = sz++;
		st[cur].len = st[last].len + 1;
		has[cur][id]++;
		int p = last;
		while(p != -1 && !st[p].next[c])
		{
			st[p].next[c] = cur;
			p = st[p].link;
		}
		if(p == -1)
		{
			st[cur].link = 0;
		}
		else
		{
			int q = st[p].next[c];
			if(st[p].len + 1 == st[q].len)
			{
				st[cur].link = q;
			}
			else
			{
				int clone = sz++;
				st[clone] = st[q];
				st[clone].len = st[p].len+1;
				while( p != -1 && st[p].next[c] == q )
				{
					st[p].next[c] = clone;
					p = st[p].link;
				}
				st[cur].link = st[q].link = clone;
			}
		}
		last = cur;
	}

	void dfs(int u)
	{
		for(auto &v: graph[u])
		{
			dfs(v);
			merge(has[u], has[v]);
		}
		if(has[u].size() >= kk)
		{
			for(auto &x: has[u])
				ans[x.first] += (long long )x.second*(st[u].len - st[st[u].link].len);
		}
	}

	void sa_counting()
	{
		for(int i = 1 ;  i < sz  ;  i++  )
			graph[st[i].link].push_back(i);
		dfs(0);
	}
}a;

char s[MAXLEN];

int main()
{

	scanf("%d %d",&n,&kk);
	a.sa_init();
	for(int i = 1 ; i <= n; i++)
	{
		a.last = 0;
		scanf("%s",s);
		int m = strlen(s);
		for(int j = 0; j < m; j++)
		{
			a.sa_extend(s[j] - 'a', i);
		}
	}

	a.sa_counting();

	for(int i = 1; i <= n; i++)
	{
		printf("%lld ",ans[i]);
	}
	puts("");

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int MAXLEN = 501005;

typedef long long ll;

int q[2*MAXLEN], deg[2*MAXLEN];

ll ans[MAXLEN];

map<int,int> has[2*MAXLEN];

void merge(map<int,int>&a, map<int,int>&b)
{
	for(auto &x: b)
		a[x.first] += x.second;
}

int n,kk;

struct automaton
{
	struct state
	{
		int link;
		int next[27];
		int len;
	};
	state st[2*MAXLEN];
	int sz;
	void sa_init()
	{

		sz = 1;
		last = 0;
		st[0].link = -1;
		st[0].len = 0;
		memset(st[0].next,0,sizeof(st[0].next));
	}
	int last = 0;
	void sa_extend(int c, int id)
	{
		int cur = sz++;
		st[cur].len = st[last].len + 1;
		has[cur][id]++;
		int p = last;
		while(p != -1 && !st[p].next[c])
		{
			st[p].next[c] = cur;
			p = st[p].link;
		}
		if(p == -1)
		{
			st[cur].link = 0;
		}
		else
		{
			int q = st[p].next[c];
			if(st[p].len + 1 == st[q].len)
			{
				st[cur].link = q;
			}
			else
			{
				int clone = sz++;
				st[clone] = st[q];
				st[clone].len = st[p].len+1;
				while( p != -1 && st[p].next[c] == q )
				{
					st[p].next[c] = clone;
					p = st[p].link;
				}
				st[cur].link = st[q].link = clone;
			}
		}
		last = cur;
	}
	void sa_counting()
	{
		int p = 0;
		for(int i = 1 ;  i < sz  ;  i++  )
			deg[st[i].link]++;
		for(int i = 1 ;  i < sz  ;  i++  )
		{
			if( deg[i] == 0 )
				q[++p] = i;
		}
		while( p > 0 )
		{
			int k = q[p];
			p--;
			if(k <= 0)
				continue;
			merge(has[st[k].link], has[k]);
			if(has[k].size() >= kk)
			{
				for(auto &x: has[k])
					ans[x.first] += (long long )x.second*(st[k].len - st[st[k].link].len);
			}
			has[k].clear();
			if(  (--deg[st[k].link] ) == 0  )
				q[++p] = st[k].link;

		}
	}
}a;

char s[MAXLEN];

int main()
{

	scanf("%d %d",&n,&kk);
	a.sa_init();
	for(int i = 1 ; i <= n; i++)
	{
		a.last = 0;
		scanf("%s",s);
		int m = strlen(s);
		for(int j = 0; j < m; j++)
		{
			a.sa_extend(s[j] - 'a', i);
		}
	}

	a.sa_counting();

	for(int i = 1; i <= n; i++)
	{
		printf("%lld ",ans[i]);
	}
	puts("");

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define rep(i, a, b) for(int i=(a); i<(b); i++)
#define per(i, a, b) for(int i=(b)-1; i>=(a); i--)
#define sz(a) (int)a.size()
#define de(a) cout << #a << " = " << a << endl
#define dd(a) cout << #a << " = " << a << " "
#define all(a) a.begin(), a.end()
#define pw(x) (1ll<<(x))
#define endl "\n"
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

const int N = 101010;

int n, k;
string s[N];

struct SAM {
	static const int N = ::N << 1, M = 26;
	int par[N], l[N], ne[N][M], vis[N], cnt[N], a[N], b[N];
	int rt, last, L;
	ll f[N];
	void add(int c) {
		int p = last;
		if(ne[p][c] && l[ne[p][c]] == l[p] + 1) {
			last = ne[p][c];
			return ;
		}
		int np = ++L;
		fill(ne[np], ne[np] + M, 0);
		l[np] = l[p] + 1;
		last = np;
		while(p && !ne[p][c]) ne[p][c] = np, p = par[p];
		if(!p) par[np] = rt;
		else{
			int q = ne[p][c];
			if(l[q] == l[p] + 1) par[np] = q;
			else {
				int nq = ++L;
				l[nq] = l[p] + 1;
				copy(ne[q], ne[q] + M, ne[nq]);
				par[nq] = par[q];
				par[q] = par[np] = nq;
				while(p && ne[p][c] == q) ne[p][c] = nq, p = par[p];
			}
		}
	}
	void ini() {
		rt = last = L = 1;
		fill(ne[rt], ne[rt] + M, 0);
		l[0] = -1;
	}
	void solve() {
		fill_n(vis, L + 1, -1);
		rep(i, 0, n) {
			int p = 1;
			rep(j, 0, sz(s[i])) {
				p = ne[p][s[i][j] - 'a'];
				int q = p;
				while(q && vis[q] != i) {
					vis[q] = i;
					++cnt[q];
					q = par[q];
				}
			}
		}
		cnt[1] = 0;
		rep(i, 1, L + 1) ++b[l[i]];
		rep(i, 1, L + 1) b[i] += b[i - 1];
		for(int i = L; i; --i) a[b[l[i]]--] = i;
		rep(i, 1, L + 1) {
			int u = a[i];
			f[u] = f[par[u]] + (cnt[u] >= k) * (l[u] - l[par[u]]);
		}
		rep(i, 0, n) {
			int p = 1;
			ll ans = 0;
			rep(j, 0, sz(s[i])) {
				p = ne[p][s[i][j] - 'a'];
				ans += f[p];
			}
			cout << ans << " \n"[i == n - 1];
		}
	}
}sam;

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	cin >> n >> k;
	sam.ini();
	rep(i, 0, n) {
		cin >> s[i];
		sam.last = 1;
		rep(j, 0, sz(s[i])) sam.add(s[i][j] - 'a');
	}
	sam.solve();
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define rep(i, a, b) for(int i=(a); i<(b); i++)
#define per(i, a, b) for(int i=(b)-1; i>=(a); i--)
#define sz(a) (int)a.size()
#define de(a) cout << #a << " = " << a << endl
#define dd(a) cout << #a << " = " << a << " "
#define all(a) a.begin(), a.end()
#define pw(x) (1ll<<(x))
#define endl "\n"
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

const int N = 101010;

int n, k;
string s[N];

struct SAM {
	static const int N = ::N << 1, M = 26;
	int par[N], l[N], ne[N][M], vis[N], cnt[N], a[N], b[N];
	int rt, last, L;
	ll f[N];
	void add(int c) {
		int p = last;
		/*
		if(ne[p][c] && l[ne[p][c]] == l[p] + 1) {
			last = ne[p][c];
			return ;
		}
		*/
		int np = ++L;
		fill(ne[np], ne[np] + M, 0);
		l[np] = l[p] + 1;
		last = np;
		while(p && !ne[p][c]) ne[p][c] = np, p = par[p];
		if(!p) par[np] = rt;
		else{
			int q = ne[p][c];
			if(l[q] == l[p] + 1) par[np] = q;
			else {
				int nq = ++L;
				l[nq] = l[p] + 1;
				copy(ne[q], ne[q] + M, ne[nq]);
				par[nq] = par[q];
				par[q] = par[np] = nq;
				while(p && ne[p][c] == q) ne[p][c] = nq, p = par[p];
			}
		}
	}
	void ini() {
		rt = last = L = 1;
		fill(ne[rt], ne[rt] + M, 0);
		l[0] = -1;
	}
	void solve() {
		fill_n(vis, L + 1, -1);
		rep(i, 0, n) {
			int p = 1;
			rep(j, 0, sz(s[i])) {
				p = ne[p][s[i][j] - 'a'];
				int q = p;
				while(q && vis[q] != i) {
					vis[q] = i;
					++cnt[q];
					q = par[q];
				}
			}
		}
		cnt[1] = 0;
		rep(i, 1, L + 1) ++b[l[i]];
		rep(i, 1, L + 1) b[i] += b[i - 1];
		for(int i = L; i; --i) a[b[l[i]]--] = i;
		rep(i, 1, L + 1) {
			int u = a[i];
			f[u] = f[par[u]] + (cnt[u] >= k) * (l[u] - l[par[u]]);
		}
		rep(i, 0, n) {
			int p = 1;
			ll ans = 0;
			rep(j, 0, sz(s[i])) {
				p = ne[p][s[i][j] - 'a'];
				ans += f[p];
			}
			cout << ans << " \n"[i == n - 1];
		}
	}
}sam;

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	cin >> n >> k;
	sam.ini();
	rep(i, 0, n) {
		cin >> s[i];
		sam.last = 1;
		rep(j, 0, sz(s[i])) sam.add(s[i][j] - 'a');
	}
	sam.solve();
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define rep(i, a, b) for(int i=(a); i<(b); i++)
#define per(i, a, b) for(int i=(b)-1; i>=(a); i--)
#define sz(a) (int)a.size()
#define de(a) cout << #a << " = " << a << endl
#define dd(a) cout << #a << " = " << a << " "
#define all(a) a.begin(), a.end()
#define pw(x) (1ll<<(x))
#define endl "\n"
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

const int N = 101010;

int n, k;
string s[N];

struct SAM {
	static const int N = ::N << 1, M = 26;
	int par[N], l[N], ne[N][M], vis[N], cnt[N], a[N], b[N];
	int rt, last, L;
	ll f[N];
	void add(int c) {
		int p = last;
		if(ne[p][c] && l[ne[p][c]] == l[p] + 1) {
			last = ne[p][c];
			return ;
		}
		int np = ++L;
		fill(ne[np], ne[np] + M, 0);
		l[np] = l[p] + 1;
		last = np;
		while(p && !ne[p][c]) ne[p][c] = np, p = par[p];
		if(!p) par[np] = rt;
		else{
			int q = ne[p][c];
			if(l[q] == l[p] + 1) par[np] = q;
			else {
				int nq = ++L;
				l[nq] = l[p] + 1;
				copy(ne[q], ne[q] + M, ne[nq]);
				par[nq] = par[q];
				par[q] = par[np] = nq;
				while(p && ne[p][c] == q) ne[p][c] = nq, p = par[p];
			}
		}
	}
	void ini() {
		rt = last = L = 1;
		fill(ne[rt], ne[rt] + M, 0);
		l[0] = -1;
	}
	void solve() {
		fill_n(vis, L + 1, -1);
		rep(i, 0, n) {
			int p = 1;
			rep(j, 0, sz(s[i])) {
				p = ne[p][s[i][j] - 'a'];
				int q = p;
				while(q && vis[q] != i) {
					vis[q] = i;
					++cnt[q];
					q = par[q];
				}
			}
		}
		rep(i, 1, L + 1) ++b[l[i]];
		rep(i, 1, L + 1) b[i] += b[i - 1];
		for(int i = L; i; --i) a[b[l[i]]--] = i;
		rep(i, 1, L + 1) {
			int u = a[i];
			f[u] = f[par[u]] + (cnt[u] >= k) * (l[u] - l[par[u]]);
		}
		rep(i, 0, n) {
			int p = 1;
			ll ans = 0;
			rep(j, 0, sz(s[i])) {
				p = ne[p][s[i][j] - 'a'];
				ans += f[p];
			}
			cout << ans << " \n"[i == n - 1];
		}
	}
}sam;

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	cin >> n >> k;
	sam.ini();
	rep(i, 0, n) {
		cin >> s[i];
		sam.last = 1;
		rep(j, 0, sz(s[i])) sam.add(s[i][j] - 'a');
	}
	sam.solve();
	return 0;
}


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

#define N 200200

int n, m, last;
int nxt[N][26], link[N], dp[N], cnt[N], ord[N], f[N];

void extend(int c) {
	if (nxt[last][c] && dp[nxt[last][c]] == dp[last] + 1) {
		last = nxt[last][c]; return;
	}
	int x = last, y = last = ++ m;
	dp[y] = dp[x] + 1;
	while (x && !nxt[x][c]) nxt[x][c] = y, x = link[x];
	if (!x) link[y] = 1;
	else {
		int z = nxt[x][c];
		if (dp[z] == dp[x] + 1) link[y] = z;
		else {
			int u = ++ m;
			memcpy(nxt[u], nxt[z], sizeof nxt[u]);
			link[u] = link[z], link[z] = link[y] = u;
			dp[u] = dp[x] + 1;
			while (x && nxt[x][c] == z) nxt[x][c] = u, x = link[x];
		}
	}
}

int k, least, vis[N];
char buf[N];
string s[N];

int main() {
//	freopen("e.in", "r", stdin);
	scanf("%d %d", &k, &least);
	last = ++ m;
	for (int i = 1; i <= k; i ++) {
		scanf("%s", buf);
		s[i] = buf;
		last = 1;
		for (int j = 0; j < s[i].size(); j ++) extend(s[i][j] - 'a');
		n = max(n, (int)s[i].size());
	}
	for (int i = 1; i <= m; i ++) cnt[dp[i]] ++;
	for (int i = 1; i <= n; i ++) cnt[i] += cnt[i-1];
	for (int i = 1; i <= m; i ++) ord[cnt[dp[i]]--] = i;
	for (int i = 1; i <= k; i ++) {
		int x = 1;
		for (int j = 0; j < s[i].size(); j ++) {
			int c = s[i][j] - 'a';
			x = nxt[x][c];
			for (int y = x; y && vis[y] != i; y = link[y]) f[y] ++, vis[y] = i;
		}
	}
	for (int i = 1; i <= m; i ++) f[i] = (f[i] >= least) ? dp[i] - dp[link[i]] : 0;
	for (int i = 1; i <= m; i ++) f[ord[i]] += f[link[ord[i]]];
	for (int i = 1; i <= k; i ++) {
		long long ans = 0;
		int x = 1;
		for (int j = 0; j < s[i].size(); j ++) {
			int c = s[i][j] - 'a';
			assert(dp[nxt[x][c]] == dp[x][c] + 1);
			x = nxt[x][c];
			ans += f[x];
		}
		printf("%I64d%c", ans, i < k ? ' ' : '\n');
	}
	return 0;
}


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

#define N 200200

int n, m, last;
int nxt[N][26], link[N], dp[N], cnt[N], ord[N], f[N];

void extend(int c) {
	if (nxt[last][c] && dp[nxt[last][c]] == dp[last] + 1) {
		last = nxt[last][c]; return;
	}
	int x = last, y = last = ++ m;
	dp[y] = dp[x] + 1;
	while (x && !nxt[x][c]) nxt[x][c] = y, x = link[x];
	if (!x) link[y] = 1;
	else {
		int z = nxt[x][c];
		if (dp[z] == dp[x] + 1) link[y] = z;
		else {
			int u = ++ m;
			memcpy(nxt[u], nxt[z], sizeof nxt[u]);
			link[u] = link[z], link[z] = link[y] = u;
			dp[u] = dp[x] + 1;
			while (x && nxt[x][c] == z) nxt[x][c] = u, x = link[x];
		}
	}
}

int k, least, vis[N];
char buf[N];
string s[N];

int main() {
//	freopen("e.in", "r", stdin);
	scanf("%d %d", &k, &least);
	last = ++ m;
	for (int i = 1; i <= k; i ++) {
		scanf("%s", buf);
		s[i] = buf;
		last = 1;
		for (int j = 0; j < s[i].size(); j ++) extend(s[i][j] - 'a');
		n = max(n, (int)s[i].size());
	}
	for (int i = 1; i <= m; i ++) cnt[dp[i]] ++;
	for (int i = 1; i <= n; i ++) cnt[i] += cnt[i-1];
	for (int i = 1; i <= m; i ++) ord[cnt[dp[i]]--] = i;
	for (int i = 1; i <= k; i ++) {
		int x = 1;
		for (int j = 0; j < s[i].size(); j ++) {
			int c = s[i][j] - 'a';
			x = nxt[x][c];
			for (int y = x; y && vis[y] != i; y = link[y]) f[y] ++, vis[y] = i;
		}
	}
	for (int i = 1; i <= m; i ++) f[i] = (f[i] >= least) ? dp[i] - dp[link[i]] : 0;
	for (int i = 1; i <= m; i ++) f[ord[i]] += f[link[ord[i]]];
	for (int i = 1; i <= k; i ++) {
		long long ans = 0;
		int x = 1;
		for (int j = 0; j < s[i].size(); j ++) {
			int c = s[i][j] - 'a';
			x = nxt[x][c];
			ans += f[x];
		}
		printf("%I64d%c", ans, i < k ? ' ' : '\n');
	}
	return 0;
}


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

#define N 200200

int n, m, last;
int nxt[N][26], link[N], dp[N], cnt[N], ord[N], f[N];

void extend(int c) {
	if (nxt[last][c] && dp[nxt[last][c]] == dp[last] + 1) {
		last = nxt[last][c]; return;
	}
	int x = last, y = last = ++ m;
	dp[y] = dp[x] + 1;
	while (x && !nxt[x][c]) nxt[x][c] = y, x = link[x];
	if (!x) link[y] = 1;
	else {
		int z = nxt[x][c];
		if (dp[z] == dp[x] + 1) link[y] = z;
		else {
			int u = ++ m;
			memcpy(nxt[u], nxt[z], sizeof nxt[u]);
			link[u] = link[z], link[z] = link[y] = u;
			dp[u] = dp[x] + 1;
			while (x && nxt[x][c] == z) nxt[x][c] = u, x = link[x];
		}
	}
}

int k, least, vis[N];
string s[N];

int main() {
//	freopen("e.in", "r", stdin);
	cin >> k >> least;
	last = ++ m;
	for (int i = 1; i <= k; i ++) {
		last = 1;
		cin >> s[i];
		for (int j = 0; j < s[i].size(); j ++) extend(s[i][j] - 'a');
		n = max(n, (int)s[i].size());
	}
	for (int i = 1; i <= m; i ++) cnt[dp[i]] ++;
	for (int i = 1; i <= n; i ++) cnt[i] += cnt[i-1];
	for (int i = 1; i <= m; i ++) ord[cnt[dp[i]]--] = i;
	for (int i = 1; i <= k; i ++) {
		int x = 1;
		for (int j = 0; j < s[i].size(); j ++) {
			int c = s[i][j] - 'a';
			x = nxt[x][c];
			for (int y = x; y && vis[y] != i; y = link[y]) f[y] ++, vis[y] = i;
		}
	}
	for (int i = 1; i <= m; i ++) f[i] = (f[i] >= least) ? dp[i] - dp[link[i]] : 0;
	for (int i = 1; i <= m; i ++) f[ord[i]] += f[link[ord[i]]];
	for (int i = 1; i <= k; i ++) {
		long long ans = 0;
		int x = 1;
		for (int j = 0; j < s[i].size(); j ++) {
			int c = s[i][j] - 'a';
			x = nxt[x][c];
			ans += f[x];
		}
		cout << ans << (i < k ? ' ' : '\n');
	}
	return 0;
}


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

#define N 200200

int n, m, last;
int nxt[N][26], link[N], dp[N], cnt[N], ord[N], f[N];

void extend(int c) {
	if (nxt[last][c] && dp[nxt[last][c]] == dp[last] + 1) {
		last = nxt[last][c]; return;
	}
	int x = last, y = last = ++ m;
	dp[y] = dp[x] + 1;
	while (x && !nxt[x][c]) nxt[x][c] = y, x = link[x];
	if (!x) link[y] = 1;
	else {
		int z = nxt[x][c];
		if (dp[z] == dp[x] + 1) link[y] = z;
		else {
			int u = ++ m;
			memcpy(nxt[u], nxt[z], sizeof nxt[u]);
			link[u] = link[z], link[z] = link[y] = u;
			dp[u] = dp[x] + 1;
			while (x && nxt[x][c] == z) nxt[x][c] = u, x = link[x];
		}
	}
}

int k, least, vis[N];
char buf[N];
string s[N];

int main() {
//	freopen("e.in", "r", stdin);
	scanf("%d %d", &k, &least);
	last = ++ m;
	for (int i = 1; i <= k; i ++) {
		scanf("%s", buf);
		s[i] = buf;
		last = 1;
		for (int j = 0; j < s[i].size(); j ++) extend(s[i][j] - 'a');
		n = max(n, (int)s[i].size());
	}
	for (int i = 1; i <= m; i ++) cnt[dp[i]] ++;
	for (int i = 1; i <= n; i ++) cnt[i] += cnt[i-1];
	for (int i = 1; i <= m; i ++) ord[cnt[dp[i]]--] = i;
	for (int i = 1; i <= k; i ++) {
		int x = 1;
		for (int j = 0; j < s[i].size(); j ++) {
			int c = s[i][j] - 'a';
			x = nxt[x][c];
			for (int y = x; y && vis[y] != i; y = link[y]) f[y] ++, vis[y] = i;
		}
	}
	for (int i = 1; i <= m; i ++) f[i] = (f[i] >= least) ? dp[i] - dp[link[i]] : 0;
	for (int i = 1; i <= m; i ++) f[ord[i]] += f[link[ord[i]]];
	for (int i = 1; i <= k; i ++) {
		long long ans = 0;
		int x = 1;
		for (int j = 0; j < s[i].size(); j ++) {
			int c = s[i][j] - 'a';
			assert(dp[nxt[x][c]] == dp[x] + 1);
			x = nxt[x][c];
			ans += f[x];
		}
		printf("%I64d%c", ans, i < k ? ' ' : '\n');
	}
	return 0;
}


//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>

#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define foreach(it, v) for(auto it=(v).begin(); it != (v).end(); ++it)

#define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define __ freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);

#define tr(...) cout<<__FUNCTION__<<' '<<__LINE__<<" = ";trace(#__VA_ARGS__, __VA_ARGS__)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;

template<typename S, typename T>
ostream& operator<<(ostream& out,pair<S,T> const& p){out<<'('<<p.fi<<", "<<p.se<<')';return out;}

template<typename T>
ostream& operator<<(ostream& out,vector<T> const& v){
int l=v.size();for(int i=0;i<l-1;i++)out<<v[i]<<' ';if(l>0)out<<v[l-1];return out;}

template<typename T>
void trace(const char* name, T&& arg1){cout<<name<<" : "<<arg1<<endl;}

template<typename T, typename... Args>
void trace(const char* names, T&& arg1, Args&&... args){
const char* comma = strchr(names + 1, ',');cout.write(names, comma-names)<<" : "<<arg1<<" | ";trace(comma+1,args...);}

const int LOGN = 18;
const int N = 1 << LOGN;

// Segtree starts
struct node{
	int mx;
	node() { mx = 0; }
	void update(int x){
		mx = max(mx, x);
	}
	void combine(node &left, node &right){
		mx = min(left.mx, right.mx);
	}
};

node tree[N*2];
int lazy[N*2];

void push(int id, int val){
  lazy[id] = max(lazy[id], val);
  tree[id].update(val);
}

inline void propagate(int id, int left, int right){
  if(lazy[id] == -1) return;

  push(left, lazy[id]);
  push(right, lazy[id]);

  lazy[id] = -1;
}

void update(int x, int y, int val, int id, int l, int r){
  if(r < x or y < l) return;
  if(x <= l and r <= y){
    push(id, val);
    return;
  }

  int mid = (l+r) >> 1, left = 2*id, right = left + 1;
  propagate(id, left, right);

  update(x, y, val, left, l, mid);
  update(x, y, val, right, mid+1, r);

}

int query(int x, int id, int l, int r){
  if(l == r){
    return tree[id].mx;
  }

  int mid = (l+r) >> 1, left = 2*id, right = left + 1;
  propagate(id, left, right);

  if(x <= mid) return query(x, left, l, mid);
  else return query(x, right, mid+1, r);
}

// End of Segtree

int pos[N];
ll ans[N];

struct SuffixArray {
  // sa[i] = i'th smallest suffix
	int sa[N], lcp[N], n;
	int w[N], rnk[N], tb[N]; // buffer
	string s;

	SuffixArray(string &str){
		s = str;
		n = s.length();

		int m = 128;  // alphabet size
		int *rnkp = rnk, *tbp = tb, *zp; // pointers

		rnkp[n] = 0;
		for(int i = 0; i < n; i++) rnkp[i] = s[i], tbp[i] = i;

		sort(rnkp, tbp, m);
		for(int k = 1, p = 1; p < n; k <<= 1, m = p) {  // p is the number of distinct ranks seen so far
			p = 0;
			for(int i = n-k; i < n; i++) tbp[p++] = i;
			for(int i = 0; i < n; i++) {
				if(sa[i] >= k)
					tbp[p++] = sa[i] - k;
			}

			sort(rnkp, tbp, m);
			zp = rnkp, rnkp = tbp, tbp = zp;

			rnkp[sa[0]] = 0;
			p = 1;

			for(int i = 1; i < n; i++) rnkp[sa[i]] = cmp(tbp, sa[i-1], sa[i], k) ? p-1 : p++;
		}

		for(int i = 0; i < n; i++)  rnkp[sa[i]] = i;

		// lcp in linear time
		for(int i = 0, k = 0; i < n; i++, k ? k-- : 0){
			if(rnkp[i] == n-1){
				k = 0;
				continue;
			}
			int j = sa[rnkp[i]+1];
			while(i + k < n and j + k < n and s[i+k] == s[j+k]) k++;
			lcp[rnkp[i]] = k;
		}
	}

	void sort(int *rnk, int *tb, int m) { // radix sort
		for(int i = 0; i < m; i++) w[i] = 0;
		for(int i = 0; i < n; i++) w[rnk[tb[i]]]++;
		for(int i = 1; i < m; i++) w[i] += w[i-1];
		for(int i = n-1; i >= 0; i--) sa[--w[rnk[tb[i]]]] = tb[i]; // inorder sort over all suffixes with same position in w
	}

	bool cmp(int *r, int a, int b, int l) {
		if(r[a] == r[b]) {
			if(a+l >= n || b+l >= n) return false;
			return r[a+l] == r[b+l];
		}
		return false;
	}

	void process(int n, int k){
	  int start = n-1; // first n-1 positions are the '#"

	  int cnt = 0;
	  vector<int> f(n, 0);

	  deque<pii> q;

	  for(int i = start, j = start; i < s.length(); i++){
	    if(++f[pos[sa[i]]] == 1) cnt++;

	    if(i > start){
	      while(!q.empty() and q.back().fi >= lcp[i-1]) q.pop_back();
	      q.push_back(mp(lcp[i-1], i-1));
	    }

	    while(cnt >= k){
	      int val = q.front().fi;

        update(j, i, val, 1, 0, s.length()-1);

	      if(f[pos[sa[j]]] == 1){
	        if(cnt > k){
	          if(q.front().se == j) q.pop_front();
	          f[pos[sa[j++]]]--;
	          cnt--;
	        }
	        else{
	          break;
	        }
	      }
	      else{
	        if(q.front().se == j) q.pop_front();
	        f[pos[sa[j++]]]--;
	      }
	    }
	  }

	  for(int i = start; i < s.length(); i++){
	    int val = query(i, 1, 0, s.length()-1);
	    ans[pos[sa[i]]] += val;
	  }
	}
};

string a[N];

int main(){ _
  int n, k;
  cin >> n >> k;

  for(int i = 0; i < n; i++){
    cin >> a[i];
  }

  if(k == 1){
    for(int i = 0; i < n; i++){
      ll l = a[i].length();
      cout << ((l * (l+1)) / 2) << ' ';
    }
    cout << '\n';
    return 0;
  }

  string s = a[0];
  for(int i = 1; i < n; i++){
    s += '#';
    s += a[i];
  }

  for(int i = 0, j = 0; i < n; i++){
    if(i) pos[j++] = -1;
    for(int k = 0; k < a[i].length(); k++){
      pos[j++] = i;
    }
  }

  fill(lazy, lazy + 2 * N, -1);

  SuffixArray *sa = new SuffixArray(s);

  sa->process(n, k);

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

  return 0;
}


//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>

#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define foreach(it, v) for(auto it=(v).begin(); it != (v).end(); ++it)

#define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define __ freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);

#define tr(...) cout<<__FUNCTION__<<' '<<__LINE__<<" = ";trace(#__VA_ARGS__, __VA_ARGS__)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;

template<typename S, typename T>
ostream& operator<<(ostream& out,pair<S,T> const& p){out<<'('<<p.fi<<", "<<p.se<<')';return out;}

template<typename T>
ostream& operator<<(ostream& out,vector<T> const& v){
int l=v.size();for(int i=0;i<l-1;i++)out<<v[i]<<' ';if(l>0)out<<v[l-1];return out;}

template<typename T>
void trace(const char* name, T&& arg1){cout<<name<<" : "<<arg1<<endl;}

template<typename T, typename... Args>
void trace(const char* names, T&& arg1, Args&&... args){
const char* comma = strchr(names + 1, ',');cout.write(names, comma-names)<<" : "<<arg1<<" | ";trace(comma+1,args...);}

const int LOGN = 18;
const int N = 1 << LOGN;

// Segtree starts
struct node{
	int mx;
	node() { mx = 0; }
	void update(int x){
		mx = max(mx, x);
	}
	void combine(node &left, node &right){
		mx = min(left.mx, right.mx);
	}
};

node tree[N*2];
int lazy[N*2];

void push(int id, int val){
  lazy[id] = max(lazy[id], val);
  tree[id].update(val);
}

inline void propagate(int id, int left, int right){
  if(lazy[id] == -1) return;

  push(left, lazy[id]);
  push(right, lazy[id]);

  lazy[id] = -1;
}

void update(int x, int y, int val, int id, int l, int r){
  if(r < x or y < l) return;
  if(x <= l and r <= y){
    push(id, val);
    return;
  }

  int mid = (l+r) >> 1, left = 2*id, right = left + 1;
  propagate(id, left, right);

  update(x, y, val, left, l, mid);
  update(x, y, val, right, mid+1, r);

}

int query(int x, int id, int l, int r){
  if(l == r){
    return tree[id].mx;
  }

  int mid = (l+r) >> 1, left = 2*id, right = left + 1;
  propagate(id, left, right);

  if(x <= mid) return query(x, left, l, mid);
  else return query(x, right, mid+1, r);
}

// End of Segtree

int pos[N];
ll ans[N];

// sa[i] = i'th smallest suffix
int sa[N], lcp[N], n;
int w[N], rnk[N], tb[N]; // buffer

struct SuffixArray {
	vector<int> s;

	SuffixArray(vector<int> &str){
		s = str;
		n = s.size();

		int m = N;  // alphabet size
		int *rnkp = rnk, *tbp = tb, *zp; // pointers

		rnkp[n] = 0;
		for(int i = 0; i < n; i++) rnkp[i] = s[i], tbp[i] = i;

		sort(rnkp, tbp, m);
		for(int k = 1, p = 1; p < n; k <<= 1, m = p) {  // p is the number of distinct ranks seen so far
			p = 0;
			for(int i = n-k; i < n; i++) tbp[p++] = i;
			for(int i = 0; i < n; i++) {
				if(sa[i] >= k)
					tbp[p++] = sa[i] - k;
			}

			sort(rnkp, tbp, m);
			zp = rnkp, rnkp = tbp, tbp = zp;

			rnkp[sa[0]] = 0;
			p = 1;

			for(int i = 1; i < n; i++) rnkp[sa[i]] = cmp(tbp, sa[i-1], sa[i], k) ? p-1 : p++;
		}

		for(int i = 0; i < n; i++)  rnkp[sa[i]] = i;

		// lcp in linear time
		for(int i = 0, k = 0; i < n; i++, k ? k-- : 0){
			if(rnkp[i] == n-1){
				k = 0;
				continue;
			}
			int j = sa[rnkp[i]+1];
			while(i + k < n and j + k < n and s[i+k] == s[j+k]) k++;
			lcp[rnkp[i]] = k;
		}

	}

	void sort(int *rnk, int *tb, int m) { // radix sort
		for(int i = 0; i < m; i++) w[i] = 0;
		for(int i = 0; i < n; i++) w[rnk[tb[i]]]++;
		for(int i = 1; i < m; i++) w[i] += w[i-1];
		for(int i = n-1; i >= 0; i--) sa[--w[rnk[tb[i]]]] = tb[i]; // inorder sort over all suffixes with same position in w
	}

	bool cmp(int *r, int a, int b, int l) {
		if(r[a] == r[b]) {
			if(a+l >= n || b+l >= n) return false;
			return r[a+l] == r[b+l];
		}
		return false;
	}

	void process(int n, int k){
	  int start = n-1; // first n-1 positions are the '#"

	  int cnt = 0;
	  vector<int> f(n, 0);

	  deque<pii> q;

	  for(int i = start, j = start; i < s.size(); i++){
	    if(++f[pos[sa[i]]] == 1) cnt++;

	    if(i > start){
	      while(!q.empty() and q.back().fi >= lcp[i-1]) q.pop_back();
	      q.push_back(mp(lcp[i-1], i-1));
	    }

	    while(cnt >= k){
	      int val = q.front().fi;
        update(j, i, val, 1, 0, s.size()-1);
	      if(f[pos[sa[j]]] == 1){
	        if(cnt == k) break;
          if(q.front().se == j) q.pop_front();
	        f[pos[sa[j++]]]--;
	        cnt--;
	      }
	      else{
	        if(q.front().se == j) q.pop_front();
	        f[pos[sa[j++]]]--;
	      }
	    }
	  }

	  for(int i = start; i < s.size(); i++){
	    int val = query(i, 1, 0, ((int)s.size())-1);
	    ans[pos[sa[i]]] += val;
	  }
	}
};

string a[N];

int main(){ _
  int n, k;
  cin >> n >> k;

  for(int i = 0; i < n; i++){
    cin >> a[i];
  }

  if(k == 1){
    for(int i = 0; i < n; i++){
      ll l = a[i].length();
      cout << ((l * (l+1)) / 2) << ' ';
    }
    cout << '\n';
    return 0;
  }

  vector<int> s;
  for(int i = 0; i < n; i++){
    if(i) s.pb(122+i);
    for(int j = 0; j < a[i].length(); j++){
      s.pb((int) a[i][j]);
    }
  }

  for(int i = 0, j = 0; i < n; i++){
    if(i) pos[j++] = -1;
    for(int k = 0; k < a[i].length(); k++){
      pos[j++] = i;
    }
  }

  fill(lazy, lazy + 2 * N, -1);

  SuffixArray *sa = new SuffixArray(s);

  sa->process(n, k);

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

  return 0;
}


//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>

#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define foreach(it, v) for(auto it=(v).begin(); it != (v).end(); ++it)

#define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define __ freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);

#define tr(...) cout<<__FUNCTION__<<' '<<__LINE__<<" = ";trace(#__VA_ARGS__, __VA_ARGS__)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;

template<typename S, typename T>
ostream& operator<<(ostream& out,pair<S,T> const& p){out<<'('<<p.fi<<", "<<p.se<<')';return out;}

template<typename T>
ostream& operator<<(ostream& out,vector<T> const& v){
int l=v.size();for(int i=0;i<l-1;i++)out<<v[i]<<' ';if(l>0)out<<v[l-1];return out;}

template<typename T>
void trace(const char* name, T&& arg1){cout<<name<<" : "<<arg1<<endl;}

template<typename T, typename... Args>
void trace(const char* names, T&& arg1, Args&&... args){
const char* comma = strchr(names + 1, ',');cout.write(names, comma-names)<<" : "<<arg1<<" | ";trace(comma+1,args...);}

const int LOGN = 18;
const int N = 1 << LOGN;

// Segtree starts
struct node{
	int mx;
	node() { mx = 0; }
	void update(int x){
		mx = max(mx, x);
	}
	void combine(node &left, node &right){
		mx = min(left.mx, right.mx);
	}
};

node tree[N*2];
int lazy[N*2];

void push(int id, int val){
  lazy[id] = max(lazy[id], val);
  tree[id].update(val);
}

inline void propagate(int id, int left, int right){
  if(lazy[id] == -1) return;

  push(left, lazy[id]);
  push(right, lazy[id]);

  lazy[id] = -1;
}

void update(int x, int y, int val, int id, int l, int r){
  if(r < x or y < l) return;
  if(x <= l and r <= y){
    push(id, val);
    return;
  }

  int mid = (l+r) >> 1, left = 2*id, right = left + 1;
  propagate(id, left, right);

  update(x, y, val, left, l, mid);
  update(x, y, val, right, mid+1, r);

}

int query(int x, int id, int l, int r){
  if(l == r){
    return tree[id].mx;
  }

  int mid = (l+r) >> 1, left = 2*id, right = left + 1;
  propagate(id, left, right);

  if(x <= mid) return query(x, left, l, mid);
  else return query(x, right, mid+1, r);
}

// End of Segtree

int pos[N];
ll ans[N];

// sa[i] = i'th smallest suffix
int sa[N], lcp[N], n;
int w[N], rnk[N], tb[N]; // buffer

struct SuffixArray {
	vector<int> s;

	SuffixArray(vector<int> &str){
		s = str;
		n = s.size();

		int m = N;  // alphabet size
		int *rnkp = rnk, *tbp = tb, *zp; // pointers

		rnkp[n] = 0;
		for(int i = 0; i < n; i++) rnkp[i] = s[i], tbp[i] = i;

		sort(rnkp, tbp, m);
		for(int k = 1, p = 1; p < n; k <<= 1, m = p) {  // p is the number of distinct ranks seen so far
			p = 0;
			for(int i = n-k; i < n; i++) tbp[p++] = i;
			for(int i = 0; i < n; i++) {
				if(sa[i] >= k)
					tbp[p++] = sa[i] - k;
			}

			sort(rnkp, tbp, m);
			zp = rnkp, rnkp = tbp, tbp = zp;

			rnkp[sa[0]] = 0;
			p = 1;

			for(int i = 1; i < n; i++) rnkp[sa[i]] = cmp(tbp, sa[i-1], sa[i], k) ? p-1 : p++;
		}

		for(int i = 0; i < n; i++)  rnkp[sa[i]] = i;

		// lcp in linear time
		for(int i = 0, k = 0; i < n; i++, k ? k-- : 0){
			if(rnkp[i] == n-1){
				k = 0;
				continue;
			}
			int j = sa[rnkp[i]+1];
			while(i + k < n and j + k < n and s[i+k] == s[j+k]) k++;
			lcp[rnkp[i]] = k;
		}

	}

	void sort(int *rnk, int *tb, int m) { // radix sort
		for(int i = 0; i < m; i++) w[i] = 0;
		for(int i = 0; i < n; i++) w[rnk[tb[i]]]++;
		for(int i = 1; i < m; i++) w[i] += w[i-1];
		for(int i = n-1; i >= 0; i--) sa[--w[rnk[tb[i]]]] = tb[i]; // inorder sort over all suffixes with same position in w
	}

	bool cmp(int *r, int a, int b, int l) {
		if(r[a] == r[b]) {
			if(a+l >= n || b+l >= n) return false;
			return r[a+l] == r[b+l];
		}
		return false;
	}

	void process(int n, int k){
	  int start = 0; // first n-1 positions are the '#"
	  int end = (int) s.size() - (n-1);

	  int cnt = 0;
	  vector<int> f(n, 0);

	  deque<pii> q;

	  for(int i = start, j = start; i < end; i++){
	    if(++f[pos[sa[i]]] == 1) cnt++;

	    if(i > start){
	      while(!q.empty() and q.back().fi >= lcp[i-1]) q.pop_back();
	      q.push_back(mp(lcp[i-1], i-1));
	    }

	    while(cnt >= k){
	      int val = q.front().fi;
        update(j, i, val, 1, 0, s.size()-1);
	      if(f[pos[sa[j]]] == 1){
	        if(cnt == k) break;
          if(q.front().se == j) q.pop_front();
	        f[pos[sa[j++]]]--;
	        cnt--;
	      }
	      else{
	        if(q.front().se == j) q.pop_front();
	        f[pos[sa[j++]]]--;
	      }
	    }
	  }

	  for(int i = start; i < end; i++){
	    int val = query(i, 1, 0, ((int)s.size())-1);
	    ans[pos[sa[i]]] += val;
	  }
	}
};

string a[N];

int main(){ _
  int n, k;
  cin >> n >> k;

  for(int i = 0; i < n; i++){
    cin >> a[i];
  }

  if(k == 1){
    for(int i = 0; i < n; i++){
      ll l = a[i].length();
      cout << ((l * (l+1)) / 2) << ' ';
    }
    cout << '\n';
    return 0;
  }

  vector<int> s;
  for(int i = 0; i < n; i++){
    if(i) s.pb(122+i);
    for(int j = 0; j < a[i].length(); j++){
      s.pb((int) a[i][j]);
    }
  }

  for(int i = 0, j = 0; i < n; i++){
    if(i) pos[j++] = -1;
    for(int k = 0; k < a[i].length(); k++){
      pos[j++] = i;
    }
  }

  fill(lazy, lazy + 2 * N, -1);

  SuffixArray *sa = new SuffixArray(s);

  sa->process(n, k);

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

  return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>

#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define foreach(it, v) for(auto it=(v).begin(); it != (v).end(); ++it)

#define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define __ freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);

#define tr(...) cout<<__FUNCTION__<<' '<<__LINE__<<" = ";trace(#__VA_ARGS__, __VA_ARGS__)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;

template<typename S, typename T>
ostream& operator<<(ostream& out,pair<S,T> const& p){out<<'('<<p.fi<<", "<<p.se<<')';return out;}

template<typename T>
ostream& operator<<(ostream& out,vector<T> const& v){
int l=v.size();for(int i=0;i<l-1;i++)out<<v[i]<<' ';if(l>0)out<<v[l-1];return out;}

template<typename T>
void trace(const char* name, T&& arg1){cout<<name<<" : "<<arg1<<endl;}

template<typename T, typename... Args>
void trace(const char* names, T&& arg1, Args&&... args){
const char* comma = strchr(names + 1, ',');cout.write(names, comma-names)<<" : "<<arg1<<" | ";trace(comma+1,args...);}

const int LOGN = 18;
const int N = 1 << LOGN;

// Segtree starts
struct node{
	int mx;
	node() { mx = 0; }
	void update(int x){
		mx = max(mx, x);
	}
	void combine(node &left, node &right){
		mx = min(left.mx, right.mx);
	}
};

node tree[N*2];
int lazy[N*2];

void push(int id, int val){
  lazy[id] = max(lazy[id], val);
  tree[id].update(val);
}

inline void propagate(int id, int left, int right){
  if(lazy[id] == -1) return;

  push(left, lazy[id]);
  push(right, lazy[id]);

  lazy[id] = -1;
}

void update(int x, int y, int val, int id, int l, int r){
  if(r < x or y < l) return;
  if(x <= l and r <= y){
    push(id, val);
    return;
  }

  int mid = (l+r) >> 1, left = 2*id, right = left + 1;
  propagate(id, left, right);

  update(x, y, val, left, l, mid);
  update(x, y, val, right, mid+1, r);

}

int query(int x, int id, int l, int r){
  if(l == r){
    return tree[id].mx;
  }

  int mid = (l+r) >> 1, left = 2*id, right = left + 1;
  propagate(id, left, right);

  if(x <= mid) return query(x, left, l, mid);
  else return query(x, right, mid+1, r);
}

// End of Segtree

int pos[N];
ll ans[N];

// sa[i] = i'th smallest suffix
int sa[N], lcp[N], n;
int w[N], rnk[N], tb[N]; // buffer

struct SuffixArray {
	vector<int> s;

	SuffixArray(vector<int> &str){
		s = str;
		n = s.size();

		int m = N;  // alphabet size
		int *rnkp = rnk, *tbp = tb, *zp; // pointers

		rnkp[n] = 0;
		for(int i = 0; i < n; i++) rnkp[i] = s[i], tbp[i] = i;

		sort(rnkp, tbp, m);
		for(int k = 1, p = 1; p < n; k <<= 1, m = p) {  // p is the number of distinct ranks seen so far
			p = 0;
			for(int i = n-k; i < n; i++) tbp[p++] = i;
			for(int i = 0; i < n; i++) {
				if(sa[i] >= k)
					tbp[p++] = sa[i] - k;
			}

			sort(rnkp, tbp, m);
			zp = rnkp, rnkp = tbp, tbp = zp;

			rnkp[sa[0]] = 0;
			p = 1;

			for(int i = 1; i < n; i++) rnkp[sa[i]] = cmp(tbp, sa[i-1], sa[i], k) ? p-1 : p++;
		}

		for(int i = 0; i < n; i++)  rnkp[sa[i]] = i;

		// lcp in linear time
		for(int i = 0, k = 0; i < n; i++, k ? k-- : 0){
			if(rnkp[i] == n-1){
				k = 0;
				continue;
			}
			int j = sa[rnkp[i]+1];
			while(i + k < n and j + k < n and s[i+k] == s[j+k]) k++;
			lcp[rnkp[i]] = k;
		}

	}

	void sort(int *rnk, int *tb, int m) { // radix sort
		for(int i = 0; i < m; i++) w[i] = 0;
		for(int i = 0; i < n; i++) w[rnk[tb[i]]]++;
		for(int i = 1; i < m; i++) w[i] += w[i-1];
		for(int i = n-1; i >= 0; i--) sa[--w[rnk[tb[i]]]] = tb[i]; // inorder sort over all suffixes with same position in w
	}

	bool cmp(int *r, int a, int b, int l) {
		if(r[a] == r[b]) {
			if(a+l >= n || b+l >= n) return false;
			return r[a+l] == r[b+l];
		}
		return false;
	}

	void process(int n, int k){
	  int start = 0; // first n-1 positions are the '#"
	  int end = (int) s.size() - (n-1);

	  int cnt = 0;
	  vector<int> f(n, 0);

	  deque<pii> q;

	  for(int i = start, j = start; i < end; i++){
	    if(++f[pos[sa[i]]] == 1) cnt++;

	    if(i > start){
	      while(!q.empty() and q.back().fi >= lcp[i-1]) q.pop_back();
	      q.push_back(mp(lcp[i-1], i-1));
	    }

	    while(cnt >= k){
	      int val = q.front().fi;
        update(j, i, val, 1, 0, s.size()-1);
	      if(f[pos[sa[j]]] == 1){
	        if(cnt == k) break;
          if(q.front().se == j) q.pop_front();
	        f[pos[sa[j++]]]--;
	        cnt--;
	      }
	      else{
	        if(q.front().se == j) q.pop_front();
	        f[pos[sa[j++]]]--;
	      }
	    }
	  }

	  for(int i = start; i < end; i++){
	    int val = query(i, 1, 0, ((int)s.size())-1);
	    ans[pos[sa[i]]] += val;
	  }
	}
};

string a[N];

int main(){ _
  int n, k;
  cin >> n >> k;

  for(int i = 0; i < n; i++){
    cin >> a[i];
  }

  if(k == 1){
    for(int i = 0; i < n; i++){
      ll l = a[i].length();
      cout << ((l * (l+1)) / 2) << ' ';
    }
    cout << '\n';
    return 0;
  }

  vector<int> s;
  for(int i = 0; i < n; i++){
    if(i) s.pb(122+i);
    for(int j = 0; j < a[i].length(); j++){
      s.pb((int) a[i][j]);
    }
  }

  for(int i = 0, j = 0; i < n; i++){
    if(i) pos[j++] = -1;
    for(int k = 0; k < a[i].length(); k++){
      pos[j++] = i;
    }
  }

  fill(lazy, lazy + 2 * N, -1);

  SuffixArray *sa = new SuffixArray(s);

  sa->process(n, k);

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

  return 0;
}


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

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

int n;
string s;

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

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

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

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

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

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

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

		}
	}

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

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

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

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

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

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


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

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

int n;
string s;

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

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

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

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

}

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

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

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

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

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

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