#include<bits/stdc++.h>
using namespace std;
#define FOR(i,a,b) for(int i = (a); i < (b); i++)
#define RFOR(i,a,b) for(int i = (a-1) ; i>=(b);i--)
#define rep(i,n) FOR(i,0,n)
#define PB push_back
#define SZ(a) (int)a.size()
#define ALL(a) a.begin(), a.end()
#define FILL(a, value) memset(a, value, sizeof(a))
typedef long long LL ;
typedef vector<int > VI ;
typedef vector<LL > VL;
typedef pair<int,int > PII;
const LL LINF = 1e18 +47;
const int INF = 1e9 +47 ;
const int MOD = 1e9 + 7;
const int modulo = 1e8 ;
const int nax = 51;
const double EPS = 1e-7;
const int MAX = 1000*1000 + 47;
struct point {
double x, y;
vector<PII> origins;
point() {}
point(double x, double y) : x(x), y(y) {};
point operator-(const point& p) const {
return point (x - p.x, y - p.y);
}
double operator*(const point & p) const {
return x * p.y - y * p.x;
}
point operator*(double k) const {
return point(k * x, k * y);
}
bool operator==(const point & p) const {
return abs(x - p.x) < EPS && abs(y - p.y) < EPS;
}
bool operator<(const point & p) const {
if (abs(x - p.x) > EPS) return x < p.x;
if (abs(y - p.y) > EPS) return y < p.y;
return 0;
}
};
struct line {
point n;
double c;
line() {}
line(double a, double b, double c)
{
n = point(a, b);
this->c = c;
}
line(point a, point b) {
double A = b.y - a.y;
double B = a.x - b.x;
double C = -a.x * A - a.y * B;
n = point(A, B);
c = C;
}
bool paralel(const line& l) const {
return abs(n * l.n) < EPS;
}
point intersect(const line &l) const {
double z = n * l.n;
double x = - (c * l.n.y - n.y * l.c) / z;
double y = - (n.x * l.c - c * l.n.x) / z;
return point(x, y);
}
};
int sign(double x)
{
if (abs(x) < EPS) return 0;
return x > 0 ? 1 : -1;
}
struct segment {
point a, b;
segment() {}
segment(point a, point b) {
this -> a = a;
this -> b = b;
}
line getLine() const {
return line(a, b);
}
bool intersect(const segment& s) const {
if (min(s.a.x, s.b.x) > max(a.x, b.x)) return false;
if (min(s.a.y, s.b.y) > max(a.y, b.y)) return false;
if (max(s.a.x, s.b.x) < min(a.x, b.x)) return false;
if (max(s.a.y, s.b.y) < min(a.y, b.y)) return false;
int s1 = sign((a - s.a) * (b - s.a));
int s2 = sign((a - s.b) * (b - s.b));
int s3 = sign((s.a - a) * (s.b - a));
int s4 = sign((s.a - b) * (s.b - b));
return s1 * s2 <= 0 && s3 * s4 <= 0;
}
};
struct polygon
{
vector<point> p;
polygon() {}
polygon(const vector<point> &a)
{
p = a;
if (SZ(a)) p.PB(a[0]);
}
int sz() const {
return max(SZ(p) - 1, 0);
}
vector<point> intersect(const polygon& x) const {
vector<point> ans;
FOR(i, 0, sz()) {
segment a = segment(p[i], p[i + 1]);
line l = a.getLine();
FOR(j, 0, x.sz()) {
segment b = segment(x.p[j], x.p[j + 1]);
if (a.intersect(b)) {
line bl = b.getLine();
if (!bl.paralel(l))
ans.push_back(l.intersect(bl));
}
}
}
return ans;
}
};
polygon P[1111];
double ANS[111];
int main() {
int n;
scanf("%d", &n);
FOR(i, 0, n) {
vector<point> pts;
int k;
scanf("%d", &k);
FOR(j, 0, k) {
int x, y;
scanf("%d%d", &x, &y);
pts.PB(point(x, y));
}
P[i] = polygon(pts);
}
vector<point> I;
FOR(i, 0, n) {
FOR(j, 0, i) {
const vector<point> &inter = P[i].intersect(P[j]);
FOR(k, 0, SZ(inter))
I.PB(inter[k]);
}
FOR(j, 0, P[i].sz()) {
point x = P[i].p[j];
x.origins.PB({i, j});
x.origins.PB({i, j ? j - 1: P[i].sz() - 1});
I.PB(x);
}
}
sort(ALL(I));
vector<point> II;
for(auto p: I) {
if (II.empty() || !(II.back() == p)) {
II.push_back(p);
} else {
for(auto o: p.origins)
II.back().origins.PB(o);
}
}
set<PII> active;
FOR(i, 0, SZ(II) - 1) {
point p = II[i];
for(auto o: p.origins) {
if (!active.count(o)) active.insert(o);
else active.erase(o);
}
vector<pair<double, int>> v;
double h = II[i + 1].x - p.x;
if (abs(h) < EPS)continue;
double x = (p.x + II[i + 1].x) / 2;
for(auto o: active) {
point a = P[o.first].p[o.second];
point b = P[o.first].p[o.second + 1];
if (!sign(a.x - b.x)) continue;;
line l = line(a, b);
double y = - (l.c + x * l.n.x) / l.n.y;
v.emplace_back(y, a.x < b.x ? 1 : -1);
}
sort(ALL(v));
int cnt = 0;
FOR(j, 0, SZ(v) - 1) {
cnt += v[j].second;
double m = v[j + 1].first - v[j].first;
ANS[cnt] += h * m;
}
}
FOR(i, 1, n + 1) printf("%.9lf ", ANS[i]);
return 0;
}