#include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
template<class T>
using Table = vector<vector<T>>;


vector<vector<ld>>pers;
ld memo[16][1 << 16];
bool ok[16][1 << 16];
int M, N;
ld check(const int now,bitset<16>&lives) {
	const int a = lives.to_ulong();
	if (!(memo[now][a]<-1)) {
		return memo[now][a];
	}
	else {
		ld amax = 0;
		for (int i = 0; i < M; ++i) {
			if (lives[i]) {
				lives[i] = false;
				ld per = 0;
				ld living = 1;
				for (int enemy = now; enemy < N; ++enemy) {
					per += living*(1 - pers[i][enemy])*check(enemy,lives);
					living *= pers[i][enemy];
				}
				per += living;
				amax = max(amax, per);
				lives[i] = true;
			}
		}
		return memo[now][a] =amax;
	}

}

int main() {cin >> M >> N;
	pers.resize(M);
	for (int i = 0; i < 16; ++i) {
		for (int j = 0; j < 1 << 16; ++j) {
			memo[i][j] = -2;
		}
	}
	for (int i = 0; i < M; ++i) {
		for (int j = 0; j < N; ++j) {
			ld p; cin >> p;
			pers[i].push_back(p);
		}
	}
	bitset<16>bs((1 << 16) - 1);
	ld ans = check(0, bs);
	cout << fixed << setprecision(22) << ans << endl;
	return 0;
}