#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<ctime>
using namespace std;
#define N 110
#define M 10010
#define inf 0x3f3f3f3f
#define eps 1e-4
int n;
int s[N][N],t[N][N];
int cnt=-1,head[N],vis[N],tim[N];
double dis[N];
struct Edge
{
int to,nxt;
double w;
} e[M];
void adde(int u,int v,double w)
{
e[++cnt].w=w;
e[cnt].to=v;
e[cnt].nxt=head[u];
head[u]=cnt;
}
bool SPFA(int s)
{
memset(tim,0,sizeof(tim));
memset(vis,0,sizeof(vis));
memset(dis,-inf,sizeof(dis));
deque <int> q;
dis[s]=0,vis[s]=1;
q.push_back(s);
while(!q.empty())
{
int now=q.front();
q.pop_front();
vis[now]=0;
for(int i=head[now]; ~i; i=e[i].nxt)
{
int v=e[i].to;
if(dis[v]<dis[now]+e[i].w)
{
dis[v]=dis[now]+e[i].w;
if(!vis[v])
{
vis[v]=1;
tim[v]++;
if(tim[v]>n)//这是个环,那么我们之一直走下去就一定能走出一条最长路。
return 1;//所以退出去吧
q.push_back(v);
}
}
}
}
if(dis[n]>0)
return 1;
return 0;
}
bool Check(double mid)
{
cnt=-1;
memset(head,-1,sizeof(head));
for(int i=1; i<=n; ++i)
for(int j=1; j<=n; ++j)
{
double w=1.0*s[i][j]-mid*t[i][j];//1.0为了把它double化
adde(i,j,w);
}
if(SPFA(1))
return 1;
return 0;
}
int main()
{
scanf("%d",&n);
for(int i=1; i<=n; ++i)
for(int j=1; j<=n; ++j)
scanf("%d",&s[i][j]);
for(int i=1; i<=n; ++i)
for(int j=1; j<=n; ++j)
scanf("%d",&t[i][j]);
double l=0,r=10000,ans;
while(r-l>eps)//浮点数二分
{
double mid=(l+r)/2.0;
if(Check(mid))
l=mid;
else
r=mid;
}
printf("%.3f\n",l);
return 0;
}