#include <iostream>
#include <iomanip>
#include <sstream>
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cassert>
#include <climits>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
#define chmax(a,b) (a<b?(a=b,1):0)
#define chmin(a,b) (a>b?(a=b,1):0)
#define valid(y,x,h,w) (0<=y&&y<h&&0<=x&&x<w)
typedef long long ll;
typedef pair<int,int> pii;
const int INF = 1<<29;
const double PI = acos(-1);
const double EPS = 1e-8;

double p[20][20];
double dp[1<<16][17];
int m,n;

double solve(int S, int now) {
  if (now == n) return 1;
  double &r = dp[S][now];
  if (r >= 0) return r;
  double res = 0;
  REP(i,m) {
    if (S>>i&1) continue;
    double tmp = 0;
    double q = 1;
    for (int j=now; j<=n; ++j) {
      double qq = q*(1-p[i][j]);
      tmp += qq * solve(S|1<<i,j);
      q *= p[i][j];
    }
    chmax(res, tmp);
  }
  return r = res;
}

int main() {
  cin >> m >> n;
  REP(i,m) {
    REP(j,n) {
      cin >> p[i][j];
    }
  }
  memset(dp,-1,sizeof(dp));
  double ans = solve(0,0);
  printf("%.12f\n", ans);
}