#include<cstdio>
#include<cstring>
#include<cmath>
inline int read()
{
int x;char c;
while((c=getchar())<‘0‘||c>‘9‘);
for(x=c-‘0‘;(c=getchar())>=‘0‘&&c<=‘9‘;)x=x*10+c-‘0‘;
return x;
}
#define MN 100
#define MV 200
#define ME 10200
#define S MV+1
#define T MV+2
struct edge{int nx,t,w;double c;}e[ME*2+5];
int a[MN+5][MN+5],b[MN+5][MN+5],h[MV+5],en,q[MV+5],qn,inq[MV+5],rw[MV+5];
double d[MV+5];
inline void ins(int x,int y,int w,double c)
{
e[++en]=(edge){h[x],y,w,c};h[x]=en;
e[++en]=(edge){h[y],x,0,-c};h[y]=en;
}
inline int next(int x){return x==MV+4?0:x+1;}
inline int prev(int x){return x?x-1:MV+4;}
bool spfa()
{
int i,j,x;
for(i=1;i<=T;++i)d[i]=1e18;
for(d[q[qn=1,i=0]=S]=0;i!=qn;inq[x]=0,i=next(i))
for(j=h[x=q[i]];j;j=e[j].nx)if(e[j].w&&d[x]+e[j].c<d[e[j].t])
{
d[e[j].t]=d[x]+e[j].c;rw[e[j].t]=j;
if(!inq[e[j].t])if(d[e[j].t]<=d[q[i]])inq[q[i]=e[j].t]=1,i=prev(i);
else inq[q[qn]=e[j].t]=1,qn=next(qn);
}
return d[T]<1e18;
}
int main()
{
int n=read(),i,j;double l,r,mid,ans;
for(i=1;i<=n;++i)for(j=1;j<=n;++j)a[i][j]=read();
for(i=1;i<=n;++i)for(j=1;j<=n;++j)b[i][j]=read();
for(l=0,r=1e6;r-l>1e-7;)
{
mid=(l+r)/2;
memset(h,0,sizeof(h));en=1;
for(i=1;i<=n;++i)ins(S,i,1,0),ins(i+n,T,1,0);
for(i=1;i<=n;++i)for(j=1;j<=n;++j)ins(i,j+n,1,b[i][j]*mid-a[i][j]);
for(ans=0;spfa();)for(ans+=d[T],i=T;i!=S;i=e[rw[i]^1].t)--e[rw[i]].w,++e[rw[i]^1].w;
(ans<0?l:r)=mid;
}
printf("%.6lf",l);
}