#include <bits/stdc++.h>
const int INF = 0x3f3f3f3f;
const long long int INFLL = 0x3f3f3f3f3f3f3f3fll;
long long int getint() {
  long long int ret = 0;
  bool f = 0;
  char c;
  while ((c = getchar()) < '0' || c > '9')
    if (c == '-') f ^= 1;
  while (c >= '0' && c <= '9') {
    ret = ret * 10 + c - '0';
    c = getchar();
  }
  return f ? -ret : ret;
}
using namespace std;
const int MAXN = 3000, MAXM = 300;
double p[MAXN + 10][MAXM + 10];
double g[MAXM + 10][MAXN + 10], sump[MAXM + 10];
struct cmp {
  bool operator()(int i, int j) const { return sump[i] < sump[j]; }
};
multiset<int, cmp> st;
int main() {
  int n = getint(), m = getint();
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= m; ++j) p[i][j] = getint() / 1000.0;
  for (int i = 1; i <= m; ++i) {
    g[i][0] = 1;
    for (int j = 1; j <= n; ++j) g[i][j] = (1 - p[j][i]) * g[i][j - 1];
    sump[i] = g[i][n];
    st.insert(i);
  }
  double ans = 0;
  for (int times = 1; times <= n; ++times) {
    int i = *st.begin();
    st.erase(st.begin());
    ans += 1 - sump[i];
    double t = g[i][0] * p[1][i];
    g[i][0] = 0;
    for (int j = 1; j <= n; ++j) {
      double ct = g[i][j] * p[j + 1][i] + t * (1 - p[j + 1][i]);
      g[i][j] = t;
      t = ct;
    }
    sump[i] += g[i][n];
    st.insert(i);
  }
  printf("%.12f\n", ans);
}
