#include <bits/stdc++.h>
using namespace std;
const int MAXN = 3000, MAXM = 300;
int n, m;
long double last[MAXN + 5], delt[MAXM + 5], dp[MAXM + 5][MAXN + 5],
    p[MAXN + 5][MAXM + 5];
inline void DynamicProgramming(void) {
  register int i, j;
  memset(delt, 0, sizeof(delt));
  memset(dp, 0, sizeof(dp));
  for (i = 1; i <= m; ++i) {
    dp[i][0] = 1.;
    for (j = 1; j <= n; ++j) {
      dp[i][j] = dp[i][j - 1] * (1. - p[j][i]);
    }
    delt[i] = 1. - dp[i][n];
  }
}
inline void updata(int x) {
  register int i;
  for (i = 0; i <= n; ++i) {
    last[i] = dp[x][i];
  }
  dp[x][0] = 0.;
  for (i = 1; i <= n; ++i) {
    dp[x][i] = dp[x][i - 1] * (1. - p[i][x]) + last[i - 1] * p[i][x];
  }
  delt[x] -= dp[x][n];
}
int main(int argc, char *argv[]) {
  register int i, j;
  double ans;
  while (~scanf("%d%d", &n, &m)) {
    ans = 0;
    for (i = 1; i <= n; ++i) {
      for (j = 1; j <= m; ++j) {
        int tmp;
        scanf("%d", &tmp);
        p[i][j] = (long double)tmp / 1000.;
      }
    }
    DynamicProgramming();
    for (i = 1; i <= n; ++i) {
      int tmp = 0;
      for (j = 1; j <= m; ++j) {
        if (delt[j] > delt[tmp]) {
          tmp = j;
        }
      }
      ans += delt[tmp];
      if (!tmp) break;
      updata(tmp);
    }
    cout << fixed << setprecision(12) << ans << endl;
  }
  return 0;
}
