#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=2*1010;
struct tree{
double l,r,len,length;
int lazy,vis;
}t[maxn<<3];
double val[maxn];
int vis[maxn<<3];
struct node{
double x,y1,y2;
int flag;
bool operator<(node a) const
{
return x<a.x;
}
}p[maxn];
void build(int p,int l,int r)
{
t[p].l=val[l],t[p].r=val[r];
if(r-l<=1)
{
vis[p]=1;
return;
}
int mid=l+r>>1;
build(p<<1,l,mid);
build(p<<1|1,mid,r);
}
void spread(int p)
{
if(t[p].lazy>=2)
{
t[p].length=t[p].r-t[p].l;
t[p].len=0;
}
else if(t[p].lazy==1) {
if(vis[p])
t[p].len=t[p].r-t[p].l,t[p].length=0;
double all=t[p].r-t[p].l;
t[p].length=t[p<<1].length+t[p<<1|1].length+t[p<<1].len+t[p<<1|1].len;
t[p].len=all-t[p].length;
}
else {
t[p].len=t[p<<1].len+t[p<<1|1].len;
t[p].length=t[p<<1].length+t[p<<1|1].length;
}
}
void modify(int p,double l,double r,int w)
{
if(t[p].l>=l&&t[p].r<=r)
{
t[p].lazy+=w;
spread(p);
return;
}
if(t[p<<1].r>l)
modify(p<<1,l,r,w);
if(t[p<<1|1].l<r)
modify(p<<1|1,l,r,w);
spread(p);
}
int main(){
int T,n;
scanf("%d",&T);
for(int i=1;i<=T;i++)
{
int cnt=0;
double ans=0;
memset(val,0,sizeof val);
memset(t,0,sizeof t);
memset(p,0,sizeof p);
memset(vis,0,sizeof vis);
scanf("%d",&n);
double x1,y1,x2,y2;
for(int j=1;j<=n;j++)
{
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
p[j*2-1]=(node){x1,y1,y2,1};
p[j*2]=(node){x2,y1,y2,-1};
val[++cnt]=y1,val[++cnt]=y2;
}
sort(val+1,val+1+cnt);
sort(p+1,p+1+cnt);
build(1,1,cnt);
for(int j=1;j<cnt;j++)
{
modify(1,p[j].y1,p[j].y2,p[j].flag);
ans+=(p[j+1].x-p[j].x)*t[1].length;
}
printf("%.2f\n",ans);
}
return 0;
}