#include <cstdio>
#include <queue>
using namespace std;
const double INF=1e10,eps=1e-5;
int n,m,all,S,T,can[55][55],a[55],b[55],sum;
int h[110],tot;
int dis[110],cur[110];
struct Edge{int v,next;double f;}g[6010];
queue<int> q;
inline double min(double x,double y){return x<y?x:y;}
inline double abs(double x){return x<0?-x:x;}
inline void addEdge(int u,int v,double f){
g[++tot].v=v; g[tot].f=f; g[tot].next=h[u]; h[u]=tot;
g[++tot].v=u; g[tot].f=0; g[tot].next=h[v]; h[v]=tot;
}
bool bfs(){
while(!q.empty()) q.pop();
q.push(S);
for(int i=1;i<=all;i++) dis[i]=-1;
dis[S]=0;
while(!q.empty()){
int u=q.front(); q.pop();
for(int i=h[u],v;i;i=g[i].next)
if(g[i].f>eps&&dis[v=g[i].v]==-1){
dis[v]=dis[u]+1;
if(v==T) return true;
q.push(v);
}
}
return dis[T]!=-1;
}
double dfs(int u,double delta){
if(u==T) return delta;
double get,ret=0;
for(int i=cur[u],v;i&&delta>eps;i=g[i].next)
if(g[i].f>eps&&dis[v=g[i].v]==dis[u]+1){
get=dfs(v,min(delta,g[i].f));
g[i].f-=get;
g[i^1].f+=get;
if(g[i].f>eps) cur[u]=i;
delta-=get;
ret+=get;
}
if(ret<eps) dis[u]=-1;
return ret;
}
double dinic(){
double ret=0;
while(bfs()){
for(int i=1;i<=all;i++) cur[i]=h[i];
ret+=dfs(S,INF);
}
return ret;
}
void buildGraph(double t){
tot=1;
for(int i=1;i<=all;i++) h[i]=0;
for(int i=1;i<=m;i++)
addEdge(S,i,t*b[i]);
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
if(can[i][j])
addEdge(i,m+j,INF);
for(int i=1;i<=n;i++)
addEdge(m+i,T,a[i]);
}
int main(){
scanf("%d%d",&n,&m);
all=n+m+2; S=n+m+1; T=n+m+2;
for(int i=1;i<=n;i++) scanf("%d",&a[i]),sum+=a[i];
for(int i=1;i<=m;i++) scanf("%d",&b[i]);
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++) scanf("%d",&can[i][j]);
double l=0,r=1000000000,mid,ans;
while(l+eps<r){
mid=(l+r)/2;
buildGraph(mid);
ans=dinic();
if(abs(sum-ans)<eps) r=mid;
else l=mid;
}
printf("%.8lf\n",l);
return 0;
}