#include <bits/stdc++.h>
using namespace std;
struct Interval {
  double X0, Y0;
  double XF, YF;
  Interval(double x0, double y0, double xf, double yf) {
    X0 = x0;
    Y0 = y0;
    XF = xf;
    YF = yf;
  }
  Interval *getRange(double x0, double xf) {
    double y0 = Y0 + (slope() * (x0 - X0));
    double yf = Y0 + (slope() * (xf - X0));
    return new Interval(x0, y0, xf, yf);
  }
  double slope() { return (YF - Y0) / (XF - X0); }
  double area() { return (YF + Y0) * (XF - X0) / 2; }
};
struct Point {
  double X, Y;
  Point(double x, double y) {
    X = x;
    Y = y;
  }
};
bool doubleEqual(double lhs, double rhs) { return fabs(lhs - rhs) <= 1e-12; }
bool intersect(Interval *lhs, Interval *rhs, double &x, double &y) {
  if (doubleEqual(lhs->X0, rhs->X0) && doubleEqual(lhs->Y0, rhs->Y0)) {
    return false;
  }
  double XA = lhs->X0;
  double YA = lhs->Y0;
  double MA = lhs->slope();
  double XB = rhs->X0;
  double YB = rhs->Y0;
  double MB = rhs->slope();
  x = (YB - YA + (MA * XA) - (MB * XB)) / (MA - MB);
  if (x <= XA || x <= XB || x >= lhs->XF || x >= rhs->XF) {
    return false;
  }
  y = (MA * (x - XA)) + YA;
  return true;
}
double pointsEqual(Point *lhs, Point *rhs) {
  return doubleEqual(lhs->X, rhs->X) && doubleEqual(lhs->Y, rhs->Y);
}
bool intersect(Point *p0, Point *p1, Point *q0, Point *q1, double &x,
               double &y) {
  double px = p0->X;
  double py = p0->Y;
  double pm = (p1->Y - p0->Y) / (p1->X - p0->X);
  double qx = q0->X;
  double qy = q0->Y;
  double qm = (q1->Y - q0->Y) / (q1->X - q0->X);
  if (doubleEqual(pm, qm)) {
    return false;
  }
  x = (qy - py + (pm * px) - (qm * qx)) / (pm - qm);
  if (x <= px || x <= qx || x >= p1->X || x >= q1->X) {
    return false;
  }
  y = py + (pm * (x - px));
  return true;
}
string getInterval(Interval *iv) {
  ostringstream oss;
  oss << "(" << iv->X0 << ", " << iv->Y0 << ") => (" << iv->XF << ", " << iv->YF
      << ")";
  return oss.str();
}
double calcArea(vector<Point *> &pts) {
  double area = 0;
  for (int i = 1; i < pts.size(); i++) {
    Point *prev = pts[i - 1];
    Point *curr = pts[i];
    area += (curr->Y + prev->Y) * (curr->X - prev->X) / 2;
  }
  return area;
}
string getPoint(Point *pt) {
  ostringstream oss;
  oss << pt->X << ", " << pt->Y;
  return oss.str();
}
int main() {
  std::ios::sync_with_stdio(false);
  int N, K;
  cin >> N >> K;
  vector<Point *> points[K];
  for (int i = 0; i < K; i++) {
    Point *p0 = new Point(0, 0);
    Point *pf = new Point(1, 0);
    points[i].push_back(p0);
    points[i].push_back(pf);
  }
  for (int i = 0; i < N; i++) {
    int Y[K + 1];
    for (int j = 0; j <= K; j++) {
      cin >> Y[j];
    }
    double sum = 0;
    for (int j = 0; j < K; j++) {
      double slope = Y[j + 1] - Y[j];
      Point *start = new Point(0, Y[j]);
      Point *end = new Point(1, Y[j + 1]);
      vector<Point *> temp;
      temp.push_back(points[j][0]);
      for (int k = 1; k < points[j].size(); k++) {
        Point *prev = points[j][k - 1];
        Point *curr = points[j][k];
        double xi, yi;
        if (intersect(start, end, prev, curr, xi, yi)) {
          Point *pt = new Point(xi, yi);
          temp.push_back(pt);
        }
        temp.push_back(curr);
      }
      vector<Point *> nodup;
      nodup.push_back(temp[0]);
      for (int k = 1; k < temp.size(); k++) {
        if (!pointsEqual(temp[k - 1], temp[k])) {
          nodup.push_back(temp[k]);
        }
      }
      vector<Point *> next;
      for (int k = 0; k < nodup.size(); k++) {
        Point *pt = nodup[k];
        double x = pt->X;
        double y = Y[j] + (slope * x);
        if (y >= pt->Y) {
          Point *curr = new Point(x, y);
          next.push_back(curr);
        } else {
          next.push_back(pt);
        }
      }
      double areaBefore = calcArea(points[j]);
      double areaAfter = calcArea(next);
      sum += areaAfter - areaBefore;
      points[j] = next;
    }
    cout << fixed << setprecision(12) << sum << endl;
  }
  return 0;
}
