/*
    题意:有N个工件要在M个机器上加工,有一个N*M的矩阵描述其加工时间。
    同一时间内每个机器只能加工一个工件,问加工完所有工件后,使得平均加工时间最小。

    将工件作为二分图中X部的点,总共N个。
    将每个机器拆成N个点作为二分图中Y部的点,总共N*M个。
    第J个机器的第P个点代表,使用机器 J进行倒数第P次加工。
    假设我们按顺序在J机器上工件I1,I2,I3..IK个工件,则总共需要花费I1*K+I2*(K- 1)+I3*(K-3)++IK。
    所以我们对于X中每个点I,Y中每个点(J,P),连接一条A[I,J]*P权值的边。
    接下来进行二分图最佳匹配即可。
*/

#include
<cstdio>
#include
<cstring>

const int MAXN=55;
const int INF=1000000000;

int n,m;
int g[MAXN][MAXN*MAXN];
int data[MAXN][MAXN];
int lx[MAXN],ly[MAXN*MAXN];//可行顶标
int cx[MAXN],cy[MAXN*MAXN];//匹配边集
bool sx[MAXN],sy[MAXN*MAXN];

bool path(int u){//扩展二分图 判断是否存在由行元素u出发的可增广路径
    sx[u]=1;
    
for(int v=1;v<=m;v++){
        
if(g[u][v]==lx[u]+ly[v]&&!sy[v]){
            sy[v]
=1;
            
if(cy[v]==0||path(cy[v])){
                cx[u]
=v;cy[v]=u;
                
return true;
            }

        }

    }

    
return false;
}

int KM(){
    memset(ly,
0,sizeof(ly));
    memset(cx,
0,sizeof(cx));
    memset(cy,
0,sizeof(cy));
    
for(int i=1;i<=n;i++){
        lx[i]
=-INF;
        
for(int j=1;j<=m;j++)
            
if(lx[i]<g[i][j])lx[i]=g[i][j];
    }

    
for(int u=1;u<=n;u++){
        memset(sx,
0,sizeof(sx));
        memset(sy,
0,sizeof(sy));
        
while(!path(u)){
            
int Min=INF;
            
for(int i=1;i<=n;i++){
                
if(!sx[i])continue;
                
for(int j=1;j<=m;j++)
                    
if(!sy[j]&&lx[i]+ly[j]-g[i][j]<Min)
                        Min
=lx[i]+ly[j]-g[i][j];
            }

            
//调整顶标,二分图撤去该元素
            for(int i=1;i<=n;i++)
                
if(sx[i]){lx[i]-=Min;sx[i]=false;}
            
for(int i=1;i<=m;i++)
                
if(sy[i]){ly[i]+=Min;sy[i]=false;}
        }

    }

    
int ans=0;
    
for(int i=1;i<=n;i++)
        ans
+=g[i][cx[i]];
    
return ans;
}
    
int main(){
    
int T;
    scanf(
"%d",&T);
    
while(T--){
        scanf(
"%d%d",&n,&m);
        
for(int i=1;i<=n;i++)
            
for(int j=1;j<=m;j++)
                scanf(
"%d",&data[i][j]);
        
//build
        for(int i=1;i<=n;i++)
            
for(int j=1;j<=m;j++)
                
for(int k=1;k<=n;k++)
                    g[i][(j
-1)*n+k]=-data[i][j]*k;//花费
        m=n*m;
        
double ans=-1.0*KM()/n;
        printf(
"%.6f\n",ans);
    }

    
return 0;
}