#include<bits/stdc++.h>
#define inf 1e9
#define res 1e-8
using namespace std;
int n,s,t,num;
int head[205],cnt=1;
struct node{
int v,nxt;
double c,w;
}e[20005];
void adde(int u,int v,int w,double c){
cnt++;
e[cnt].v=v;
e[cnt].w=w;
e[cnt].c=c;
e[cnt].nxt=head[u];
head[u]=cnt;
}
void add(int u,int v,int w,double c){
adde(u,v,w,c);adde(v,u,0,-c);
}
int inq[205],cur[205];
double dis[205];
bool spfa(){
queue<int> q;
for(int i=1;i<=num;i++){
dis[i]=-inf;
cur[i]=head[i];
inq[i]=0;
}
dis[s]=0;
inq[s]=1;
q.push(s);
while(!q.empty()){
int u=q.front();
q.pop();
inq[u]=0;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].v;
if(dis[v]<dis[u]+e[i].c&&e[i].w){
dis[v]=dis[u]+e[i].c;
if(!inq[v]){
inq[v]=1;
q.push(v);
}
}
}
}
return dis[t]!=-inf;
}
double maxflow,cost;
bool vis[205];
double dfs(int u,double flow){
int rlow=0;
if(u==t){
vis[t]=1;
maxflow+=flow;
return flow;
}
double used=0;
vis[u]=1;
for(int i=cur[u];i;i=e[i].nxt){
int v=e[i].v;
cur[u]=i;
if(dis[v]==dis[u]+e[i].c&&e[i].w&&(v==t||!vis[t])){
if(rlow=dfs(v,min(flow-used,e[i].w))){
used+=rlow;
e[i].w-=rlow;
e[i^1].w+=rlow;
cost+=1.0*rlow*e[i].c;
if(used==flow) break;
}
}
}
return used;
}
double dinic(){
while(spfa()){
vis[t]=1;
while(vis[t]==1){
memset(vis,0,sizeof(vis));
dfs(s,inf);
}
}
return maxflow;
}
double a[105][105],b[105][105];
void clean(){
cnt=1;maxflow=0;cost=0;
memset(head,0,sizeof(head));
memset(e,0,sizeof(e));
memset(dis,0,sizeof(dis));
memset(cur,0,sizeof(cur));
memset(inq,0,sizeof(inq));
memset(vis,0,sizeof(vis));
}
bool p(double C){
clean();
for(int i=1;i<=n;i++){
add(s,i,1,0);
add(i+n,t,1,0);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
add(i,j+n,1,a[i][j]-C*b[i][j]);
}
}
dinic();
return cost>=0;
}
signed main(){
cin>>n;
num=2*n+2;
s=2*n+1,t=2*n+2;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>b[i][j];
}
}
double l=0,r=1e5+5,ans=0,d=1e-9;
while(r-l>res){
double mid=(l+r)/2.0;
if(p(mid)){
ans=mid,l=mid+d;
}
else{
r=mid-d;
}
}
printf("%.6lf",ans);
return 0;
}