#include<iostream>
#include<algorithm>
#include<iomanip>
using namespace std;
#define max_size 110
typedef struct
{
int n,m;
float value;//n为饼干的序号,m为冰激凌序号,value为组合的价值
}zh;
long double res=0,max_res=0,min_res=0;
long sum=0;//总份数
float rule(zh a,zh b)//从大到小排序,求最大收益用
{
return a.value>b.value;
}
float rule1(zh a,zh b)//从小到大排序,求最小收益用
{
return a.value<b.value;
}
void f(int bk[],int ice[],zh a[],int b,int c)//b排序好后的第几个数 c已完成配对数
{
if(c>=sum);
else if(a[b].value<0) f(bk,ice,a,b+1,c);
else if(bk[a[b].n]==0||ice[a[b].m]==0) f(bk,ice,a,b+1,c);
else
{
if(bk[a[b].n]<ice[a[b].m])
{
res=res+a[b].value*bk[a[b].n];
c=c+bk[a[b].n];
ice[a[b].m]=ice[a[b].m]-bk[a[b].n];
bk[a[b].n]=0;
f(bk,ice,a,b+1,c);
}
else
{
res=res+a[b].value*ice[a[b].m];
c=c+ice[a[b].m];
bk[a[b].n]=bk[a[b].n]-ice[a[b].m];
ice[a[b].m]=0;
f(bk,ice,a,b+1,c);
}
}
}
int main()
{
int P,I;
cin>>P>>I;
int i,j,num_bk[max_size]={0},num_ice[max_size]={0};
int bk[max_size],ice[max_size];
zh combination[3000];
for(i=1;i<=P;i++)
{
cin>>num_bk[i];
bk[i]=num_bk[i];
sum=sum+num_bk[i];
}
for(i=1;i<=I;i++)
{
cin>>num_ice[i];
ice[i]=num_ice[i];
}
int a;
for(i=1,a=0;i<=P;i++)
{
for(j=1;j<=I;j++)
{
cin>>combination[a].value;
combination[a].n=i;
combination[a++].m=j;
}
}
sort(combination,combination+a,rule);//给收益排序
f(num_bk,num_ice,combination,0,0);
max_res=res;
res=0;
sort(combination,combination+a,rule1);
f(bk,ice,combination,0,0);
min_res=res;
cout<<fixed<<setprecision(2)<<(long double)min_res<<" to "<<(long double)max_res;//设置输出格式为保留小数点后两位
return 0;
}
//我这么做只得了20分,我找不到问题在哪