#include<bits/stdc++.h>
using namespace std;
const int maxn = 210;
struct edg
{
double l,r,h;
int flag;
bool operator<(const edg &b)const
{
return h<b.h;
}
} edge[maxn*2];
struct node
{
int l,r,lazy;
double len;
} tree[maxn*4];
double ls[maxn*2],ans;
int cnt,n,NUM,nums;
void add(double x1,double x2,double y,int id)
{
edge[cnt].flag=id;
edge[cnt].h=y;
edge[cnt].l=x1;
edge[cnt++].r=x2;
}
void build(int root,int l,int r)
{
tree[root].l=l;
tree[root].r=r;
tree[root].len=0;
tree[root].lazy=0;
if(l==r)return ;
int mid=(l+r)/2;
build(root*2,l,mid);
build(root*2+1,mid+1,r);
}
void pushup(int root)
{
if(tree[root].lazy)
tree[root].len=ls[tree[root].r+1]-ls[tree[root].l];
else if(tree[root].l==tree[root].r)
tree[root].len=0;
else tree[root].len=tree[root*2].len+tree[root*2+1].len;
}
void updata(int root,int l,int r,int val)
{
if(tree[root].l==l&&tree[root].r==r)
{
tree[root].lazy+=val;
pushup(root);
return ;
}
int mid=(tree[root].l+tree[root].r)/2;
if(l>mid)
updata(root*2+1,l,r,val);
else if(mid>=r)
updata(root*2,l,r,val);
else
{
updata(root*2,l,mid,val);
updata(root*2+1,mid+1,r,val);
}
pushup(root);
}
int main()
{
while(scanf("%d", &n))
{
if(n==0)break;
ans=cnt=nums=0;
for(int i=0; i<n; i++)
{
double x1,y,x2,y2;
scanf("%lf%lf%lf%lf",&x1,&y,&x2,&y2);
add(x1,x2,y,1);
add(x1,x2,y2,-1);
ls[nums++]=x1;
ls[nums++]=x2;
}
sort(edge,edge+cnt);
sort(ls,ls+nums);
int m=unique(ls,ls+nums)-ls;
build(1,0, m-1);
for(int i=0; i<cnt-1; i++)
{
int l=lower_bound(ls,ls+m,edge[i].l)-ls;
int r=lower_bound(ls,ls+m,edge[i].r)-ls;
updata(1,l,r-1,edge[i].flag);
ans+=(edge[i+1].h-edge[i].h)*tree[1].len;
}
printf("Test case #%d\n", ++NUM);
printf("Total explored area: %.2f\n\n", ans);
}
return 0;
}