// MADE BY QT666
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstring>
#include<vector>
#define RG register
#define int long long
using namespace std;
typedef long long ll;
const int N=100000;
const double eps=1e-9;
const double Inf=19260817.0;
int gi() {
int x=0,flag=1;
char ch=getchar();
while(ch<‘0‘||ch>‘9‘) {if(ch==‘-‘) flag=-1;ch=getchar();}
while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
return x*flag;
}
int n,ans,flag1,flag2;
int head[N],nxt[N],to[N],s[N],cnt=1,S,T;
double cc[N],dis[N],cost;
int a[300][300],b[300][300];
int level[N],q[N*10],F,fa[N],W[N];
struct data {
int l,r,s,t;
} hh[N];
inline void Addedge(RG int x,RG int y,RG int z,RG double u) {
to[++cnt]=y,s[cnt]=z,cc[cnt]=u,nxt[cnt]=head[x],head[x]=cnt;
}
inline void lnk(RG int x,RG int y,RG int z,RG double u) {
Addedge(x,y,z,u),Addedge(y,x,0,-u);
}
inline bool spfa() {
for(RG int i=S; i<=T; i++) dis[i]=Inf,W[i]=0;
RG int t=0,sum=1;
q[0]=S,W[S]=1,dis[S]=0;
while(t<sum) {
RG int x=q[t++];
W[x]=0;
for(RG int i=head[x];i;i=nxt[i]) {
RG int y=to[i];
if(s[i]&&dis[y]-(dis[x]+cc[i])>=eps) {
dis[y]=dis[x]+cc[i];
fa[y]=i;
if(!W[y]) W[y]=1,q[sum++]=y;
}
}
}
if(dis[T]==Inf) return 0;
RG int f=Inf;
for(RG int i=fa[T];i;i=fa[to[i^1]]) f=min(f,s[i]);
for(RG int i=fa[T];i;i=fa[to[i^1]]) s[i]-=f,s[i^1]+=f;
cost+=dis[T]*f;
return 1;
}
inline void Maxcost() {
while(spfa());
}
inline bool check(RG double mid){
cnt=1;memset(head,0,sizeof(head));
for(RG int i=1;i<=n;i++)
for(RG int j=1;j<=n;j++)
lnk(i,j+n,1,-(a[i][j]-mid*b[i][j]));
for(RG int i=1;i<=n;i++) lnk(S,i,1,0),lnk(i+n,T,1,0);
cost=0;Maxcost();cost=-cost;
return cost-0>=eps;
}
main() {
freopen("1.in","r",stdin);
n=gi();S=0,T=2*n+1;
for(RG int i=1;i<=n;i++)
for(RG int j=1;j<=n;j++)
a[i][j]=gi();
for(RG int i=1;i<=n;i++)
for(RG int j=1;j<=n;j++)
b[i][j]=gi();
double l=0,r=10000.0,ans=0;
while(r-l>=eps){
double mid=(l+r)/2;
if(check(mid)) l=mid,ans=mid;
else r=mid;
}
printf("%.6f",ans);
}