#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;
int main()
{
int n,m;
while(cin>>n>>m){
vector<int> c(m);
for (int i = 0; i < m; ++i)
{
cin>>c[i];
}
vector<vector<double>> p(n,vector<double>(m));
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < m; ++j)
{
cin>>p[i][j];
}
}
vector<vector<double>> dp(m);//dp[i][j]是第i种礼物剩下j的概率,也是第i种礼物被取走c[i]-j的概率
for (int i = 0; i < m; ++i)
{
dp[i]=vector<double>(c[i]+1,0.0);
dp[i][c[i]]=1.0;
}
for (int k = 0; k < n; ++k)//k个人依次取
{
for (int i = 0; i < m; ++i)
{
if(c[i]!=0){//这里是自少向多更新,想想为什么,因为要获得还剩j个的概率时,需要知道还剩j+1个的概率.
//类似于后移拷贝,防止从多向少更新时,发生数据覆盖。
dp[i][0]=dp[i][0]+dp[i][1]*p[k][i];
for (int j = 1; j < c[i]; ++j)
{
dp[i][j]=dp[i][j]*(1-p[k][i])+dp[i][j+1]*p[k][i];
}
dp[i][c[i]]*=1-p[k][i];
}
}
}
double E=0.0;//求期望。
for (int i = 0; i < m; ++i)
{
for (int j = 0; j <= c[i]; ++j)
{
E+=dp[i][j]*(c[i]-j);
}
}
cout<<setiosflags(ios::fixed)<<setprecision(1)<<E<<endl;
}
return 0;
}