#include<bits/stdc++.h>usingnamespace std;constint N=10,M=505;constdouble eps=1e-10;struct Point{double x,y,k;Point(){}Point(double a_,double b_){x=a_,y=b_,k=atan2(y,x);}friend Point operator*(const Point a,constdouble b){returnPoint(a.x*b,a.y*b);}//---friend Point operator+(const Point a,const Point b){returnPoint(a.x+b.x,a.y+b.y);}friend Point operator-(const Point a,const Point b){returnPoint(a.x-b.x,a.y-b.y);}frienddoubleoperator*(const Point a,const Point b){return a.x*b.x+a.y*b.y;}frienddoubleoperator^(const Point a,const Point b){return a.x*b.y-a.y*b.x;}}d[M];int d_p;struct Line{
Point A,B;double k;Line(){}Line(Point a,Point b){A=a,B=b,k=atan2(B.y-A.y,B.x-A.x);}friendbooloperator<(const Line a,const Line b){return(fabs(a.k-b.k)<=eps)?((a.B-a.A)^(b.B-a.A))>=eps:a.k<b.k;}}t[M];
Point get(Point a,Point b){returnPoint(b.x-a.x,b.y-a.y);}
Point cross(Line a,Line b)//求交点{double s1=(get(a.A,b.A)^get(a.A,b.B));double s2=(get(a.B,b.B)^get(a.B,b.A));return a.A+(get(a.A,a.B)*(s1/(s1+s2)));}boolrit(Line a,Line b,Line c)//a是否在b,c交点的右边{
Point d=cross(b,c);return((a.B-a.A)^(d-a.A))<eps;}
Line z[M];int n,m;int p1,p2,cnt;intmain(){scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&m);for(int j=1;j<=m;j++){double x,y;scanf("%lf%lf",&x,&y);
d[j]={x,y};}for(int j=1;j<=m;j++)
t[++d_p]={d[j],d[j==m?1:j+1]};//此题保证为逆时针}
n=d_p;sort(t+1,t+n+1);//极角排序for(int i=1;i<n;i++){if(fabs(t[i].k-t[i+1].k)<=eps)continue;
t[++cnt]=t[i];}
t[++cnt]=t[n];//保留最左
p1=1,p2=0;
z[++p2]=t[1];z[++p2]=t[2];for(int i=3;i<=cnt;i++){while(p1<p2&&rit(t[i],z[p2],z[p2-1]))p2--;while(p1<p2&&rit(t[i],z[p1],z[p1+1]))p1++;
z[++p2]=t[i];}while(p1<p2&&rit(z[p1],z[p2],z[p2-1]))p2--;while(p1<p2&&rit(z[p2],z[p1],z[p1+1]))p1++;//双端队列维护double ans=0;for(int i=p1;i<=p2;i++)d[i]=cross(z[i],z[i==p2?p1:i+1]);if(p2-p1+1>2)//判是否为空集for(int i=p1;i<=p2;i++)ans+=(d[i]^d[i==p2?p1:i+1]);//面积printf("%.3lf",ans/2);}