#include <stdio.h>#include <iostream>#include <string.h>#include <cmath>#include <vector>#include <set>#include <map>#include <algorithm>#include <queue>using namespace std;typedef long long ll;#define sfll(x) scanf("%I64d",&x)#define sfint(x) scanf("%d",&x)#define sfstr(c) scanf("%s",c)#define fr(i,s,n) for(int i=s;i<n;++i)#define cl(a) memset(a,0,sizeof(a))#define SIZE(x) ( (int)(x.size()))#define PB push_back#define MP make_pairtypedef pair<double,double > point;#define X first#define Y secondconst double eps = 1e-8;const double pi = acos(-1.);const int maxm = 200000;const int maxp = 20000;const int maxn = 90;int e[maxm],prev[maxm],mark[maxm],tote;int info[maxp];int N,P;point a[maxn],b[maxn];point p[maxp];bool zero(double x){ return fabs(x) < eps;}point operator - (const point &a ,const point &b){ return MP(a.X - b.X ,a.Y - b.Y);}point operator * ( const point &a, double k) { return point(a.X * k ,a.Y * k);}point operator / (const point &a,double k){ return point(a.X / k,a.Y/k);}double getAngle(const point &a){ return atan2(a.Y , a.X);}double det(const point &a,const point &b){ return a.X * b.Y - a.Y * b.X;}bool operator == ( const point &a,const point &b){ return zero(a.X - b.X) && zero(a.Y - b.Y);}bool intersect(const point &a , const point &b ,const point &c,const point &d,point &res){ double k1 = det(b-a , c-a) , k2 = det(b - a, d - a); if( zero(k1 - k2)) return false; res = (d * k1 - c * k2) / (k1 - k2); return true;}void addedge(int x,int y){ e[tote] = y;prev[tote] = info[x];info[x] = tote++; e[tote] = x;prev[tote] = info[y];info[y] = tote++;}vector<double > Devide(){ P = 0; fr(i , 0 ,N){ fr(j ,i+1,N){ if(intersect(a[i] , b[i], a[j], b[j], p[P])) ++P; } } sort(p , p +P); int tot = 1; for(int i = 1; i < P;++i){ if(!(p[i] == p[tot-1])) p[tot++] = p[i]; } P = tot; cl(info); tote = 2; fr(i , 0 ,N){ int last = -1; fr(j , 0 ,P){ if( zero(det(b[i] - a[i],p[j] - a[i]))){ if(last != -1) addedge(last,j); last = j; } } } cl(mark); vector<double> area; fr(i ,2, tote){ if( !mark[i]){ int laste = i^1; int lastp = e[i]; int head = e[laste]; mark[i] = true; double ans ; for(ans = det(p[head], p[lastp]) ; lastp != head; ) { double best = 1E20; int cur = -1; double base = getAngle(p[e[laste]] - p[lastp]); for(int k = info[lastp] ; k ; k = prev[k]) { if(k != laste){ double tmp = getAngle(p[e[k]] - p[lastp]) - base; if(tmp < 0) tmp += pi*2; if(tmp >= pi * 2) tmp -= pi*2; if( tmp < best){ best = tmp; cur = k; } } } ans += det(p[lastp] , p[e[cur]]); lastp = e[cur]; laste = cur ^ 1; mark[cur] = true; } area.PB(fabs(ans) * .5); } } sort(area.begin(),area.end()); if( SIZE(area) ) area.erase(area.end() - 1); return area;}namespace Sol{ void sol(){ int t; sfint(t); while(t--){ int n; sfint(n); N = n; fr(i , 0 ,n){ scanf("%lf %lf %lf %lf",&a[i].X,&a[i].Y,&b[i].X,&b[i].Y); } vector<double> ans = Devide(); printf("%dn",ans.size()); fr(i , 0 ,ans.size()){ printf("%.5fn",ans[i]); } } }}int main(){ Sol::sol();return 0;}


