#include <bits/stdc++.h>
using namespace std;
struct arr {
  double v;
  int i;
  arr() {}
  arr(double v1, int i1) {
    v = v1;
    i = i1;
  }
  bool operator<(const arr &t) const { return v < t.v; }
};
priority_queue<arr> Q;
int n, m;
double a[308][3008], s[308];
vector<vector<double> > g[308];
struct Tprogram {
  void open() {
    freopen("", "r", stdin);
    freopen("", "w", stdout);
  }
  void close() {
    fclose(stdin);
    fclose(stdout);
  }
  void find_next(int p) {
    g[p].push_back(vector<double>(n + 2));
    int t = g[p].size() - 1;
    g[p][t][0] = 0;
    for (int i = 1; i <= n; i++)
      g[p][t][i] =
          g[p][t - 1][i - 1] * a[p][i] + g[p][t][i - 1] * (1 - a[p][i]);
    Q.push(arr(1 - s[p], p));
    s[p] += g[p][t][n];
  }
  void init() {
    scanf("%d%d", &n, &m);
    int v;
    for (int i = 1; i <= n; i++)
      for (int j = 1; j <= m; j++) {
        scanf("%d", &v);
        a[j][i] = v / 1000.0;
      }
    for (int i = 1; i <= m; i++) {
      g[i].push_back(vector<double>(n + 2));
      g[i][0][0] = 1;
      for (int j = 1; j <= n; j++) g[i][0][j] = g[i][0][j - 1] * (1 - a[i][j]);
      s[i] = g[i][0][n];
    }
    for (int i = 1; i <= m; i++) find_next(i);
  }
  void work() {
    long double ans = 0;
    for (int i = 1; i <= n; i++) {
      ans += Q.top().v;
      find_next(Q.top().i);
      Q.pop();
    }
    printf("%.10lf\n", (double)ans);
  }
} Program;
int main() {
  Program.init();
  Program.work();
  return 0;
}
