/*
一开始以为是个贪心 发现自己太naive了
将每个技术工人拆成n个点,一共拆n*m个,第i个表示倒数第i次修车。
让每辆车向拆出来的点连边,费用为tmp[i][j]*k,i是技工,j是车,k是拆出来的第几个点,
这样设置费用的原因是j是i倒数第k个修的,那么i修的后k个车都要等倒数第k个车。
然后跑最小费用最大流就可以了
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
inline int read()
{
char c=getchar();int num=0;
for(;!isdigit(c);c=getchar());
for(;isdigit(c);c=getchar())
num=num*10+c-'0';
return num;
}
const int N=65;
const int M=2e5+5;
int m,n,S,T;
int tim[N][N];
long long ans;
int head[M],num_edge;
struct Edge
{
int v,nxt,flow,cost;
}edge[M];
inline void add_edge(int u,int v,int flow,int cost)
{
edge[++num_edge].v=v;
edge[num_edge].flow=flow;
edge[num_edge].cost=cost;
edge[num_edge].nxt=head[u];
head[u]=num_edge;
edge[++num_edge].v=u;
edge[num_edge].flow=0;
edge[num_edge].cost=-cost;
edge[num_edge].nxt=head[v];
head[v]=num_edge;
}
int dis[M];
queue<int> que;
bool inque[M];
bool spfa()
{
memset(dis,0x3f,sizeof(dis));
que.push(S),dis[S]=0;
int now;
while(!que.empty())
{
now=que.front(),que.pop();
for(int i=head[now],v;i;i=edge[i].nxt)
{
if(edge[i].flow==0)
continue;
v=edge[i].v;
if(dis[v]>dis[now]+edge[i].cost)
{
dis[v]=dis[now]+edge[i].cost;
if(!inque[v])
{
que.push(v);
inque[v]=1;
}
}
}
inque[now]=0;
}
return dis[T]!=0x3f3f3f3f;
}
int vis[M],visf;
int dfs(int u,int flow)
{
if(u==T||!flow)
return flow;
int outflow=0;
vis[u]=visf;
for(int i=head[u],v,tmp;i;i=edge[i].nxt)
{
if(!edge[i].flow)
continue;
v=edge[i].v;
if(vis[v]!=visf&&dis[v]==dis[u]+edge[i].cost)
{
tmp=dfs(v,min(flow,edge[i].flow));
if(!tmp)
continue;
ans+=1ll*tmp*edge[i].cost;
edge[i].flow-=tmp;
edge[i^1].flow+=tmp;
flow-=tmp;
outflow+=tmp;
if(!flow)
{
vis[u]=0;
return outflow;
}
}
}
vis[u]=0;
dis[u]=0x7fffffff;
return outflow;
}
int main()
{
num_edge=1;
m=read(),n=read();
T=n+n*m+1;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
tim[j][i]=read();
for(int i=1;i<=n;++i)
add_edge(S,i,1,0);
for(int i=1,p;i<=m;++i)
{
for(int j=1;j<=n;++j)
{
p=i*n+j;
add_edge(p,T,1,0);
for(int c=1;c<=n;++c)
add_edge(c,p,1,tim[i][c]*j);
}
}
while(spfa())
{
++visf;
dfs(S,0x7fffffff);
}
printf("%.2lf",1.0*ans/n);
return 0;
}