![]()
![]()
/*
KMP+高斯消元
设N为未结束状态的概率。
假设用两个串TTH和HTT,设第一个获胜的概率是A,第二个人获胜的概率为B。
如果在N后面加上TTH,那么有三种可能。
NTTH=A+BTH+BH ,是什么意思呢?就是如果在N后面加入TTH,那么第一个人猜的序列出现在了硬币序列中,第一个人获胜,但是N是什么我们不清楚,但是有可能到达第一个T或者第二个T的时候第二个人就获胜了。
所以对于状态NTTH,可以由三个状态得到。
0.125N=A+0.25B+0.5B,0.5是正反面的概率。
上述式子可以用kmp球的,然后高斯消元求解。
*/
#include<iostream>
#include<cstdio>
#define N 1010
using namespace std;
char s[N][N];
double ec[N],a[N][N];
int va[N],vb[N],n,m;
void init(){
ec[m]=1.0;
for(int i=m-1;i;i--) ec[i]=ec[i+1]*0.5;
for(int i=1;i<=n;i++){
va[1]=0;
for(int k=2,p=0;k<=m;k++){
while(p&&s[i][k]!=s[i][p+1]) p=va[p];
if(s[i][k]==s[i][p+1]) p++;
va[k]=p;
}
for(int j=1;j<=n;j++){
vb[0]=0;
for(int k=1,p=0;k<=m;k++){
while(p&&s[j][k]!=s[i][p+1]) p=va[p];
if(s[j][k]==s[i][p+1]) p++;
vb[k]=p;
}
for(int now=vb[m];now;now=va[now]) a[i][j]+=ec[now];
}
a[i][n+1]=1;
}
}
void gauss(){
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n+1;j++) a[i][j]/=a[i][i];
a[i][i]=1;
for(int j=i+1;j<=n;j++)
for(int k=i+1;k<=n+1;k++)
a[j][k]-=a[i][k]*a[j][i];
}
for(int i=n;i;i--)
for(int j=i+1;j<=n;j++)
a[i][n+1]-=a[i][j]*a[j][n+1];
double sum=0,ans=0;
for(int i=1;i<=n;i++) sum+=a[i][n+1];
for(int i=1;i<=n;i++){
ans=a[i][n+1];ans/=sum;
printf("%.10f\n",(double)ans);
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%s",s[i]+1);
init();gauss();
return 0;
}