#include <cstdio>
#include <iostream>
#include <vector>
#include <list>
#include <cmath>
#include <fstream>
#include <algorithm>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <complex>
#include <iterator>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <stack>

using namespace std;

const double EPS=(1e-10);
typedef long long ll;
typedef pair<int,int> pii;
typedef complex<double> P;
typedef pair<P,P> Rect;

bool EQ(double a,double b){
  return abs((a)-(b))<EPS;
}
void fast_stream(){
  std::ios_base::sync_with_stdio(0);
}

const int INF=1000000000;
int N;

class Event{
public:
  double y;
  bool isIn;
  int id;
  Event(){}
  Event(double y_,bool isIn_,int id_){
    y=y_;
    isIn=isIn_;
    id=id_;
  }
  bool operator<(const Event& e)const{
    return e.y>this->y; 
  }
};
Event evs[1001];
Rect recs[1001];

class UnionFindTree{
public:
  // indexÌÌem[h( éWÌeð©Â¯½¢Æ«Í±±ð¼ÚQÆ¹¸Afindðg¤)
  vector<int> par;
  // indexðªÆ·éØÌN
  vector<int> rank;
  vector<double> ls,rs;
  // ØÌÅål
  int treeSize;
public:
  UnionFindTree(int initTreeSize = 1000){
    // øÅ^¦çê½lðÅåi[Æ·éUnionFindTreeÌì¬
    treeSize = initTreeSize;
    init();
  }
  void init(){
    for(int i = 0; i < treeSize; i++){
      par.push_back(i);
      rank.push_back(0);
      ls.push_back(0);
      rs.push_back(0);
    }
  }
  // ^¦çê½ªi[³êÄ¢éØÌ[gðTõ
  int find(int x){  
    if(par[x] == x)return x;
    else return par[x] = find(par[x]);
  }
  // aWðÆéB½¾µ±±ÅÍeWÌeÌt¯Ö¦ÍN±çÈ¢
  void unite(int x,int y,double l,double r){
    x = find(x);
    y = find(y);
    if(x == y)return;
    if(rank[x] < rank[y])par[x] = y;
    else{
      par[y] = x;
      if(rank[y] == rank[x])rank[x]++;
    }
    int p=find(x);
    ls[p]=l;
    rs[p]=r;
  }
  bool same(int x,int y){
    return find(x) == find(y);
  }
};

int main(){
  int cnt=0;
  while(cin>>N&&N){
    int NN=0;
    for(int i=0;i<N;i++){
      double x,y,r;
      cin>>x>>y>>r;
      recs[i].first=P(x-r,y-r);
      recs[i].second=P(x+r,y+r);
      if(EQ(r,0))continue;
      evs[2*NN]=Event(y-r,true,i);
      evs[2*NN+1]=Event(y+r,false,i);
      NN++;
    }
    sort(evs,evs+2*NN);
    double prvy=-INF;
    double sumLen=0;
    double res=0;
    vector<int> v;
    // yÌ¬³¢ÔÉCxgð
    for(int k=0;k<2*NN;k++){
      Event &e=evs[k];
      if(!EQ(prvy,-INF))res+=sumLen*(e.y-prvy);
      prvy=e.y;
      // _ÌÇÁAí
      if(e.isIn)v.push_back(e.id);
      else v.erase(find(v.begin(),v.end(),e.id));
      // ¡ñÌ¡ðvZ
      UnionFindTree uft(v.size());
      for(int i=0;i<v.size();i++){
	uft.ls[i]=recs[v[i]].first.real();
	uft.rs[i]=recs[v[i]].second.real();
      }
      for(int i=0;i<v.size();i++){
	for(int j=i+1;j<v.size();j++){
	  // ÍÍª©Ôéæ¤ÈçÎAunite
	  if((EQ(uft.rs[uft.find(i)]
		 ,uft.ls[uft.find(j)])
	      ||(uft.rs[uft.find(i)]
		 >uft.ls[uft.find(j)]))
	     &&(EQ(uft.ls[uft.find(i)]
		   ,uft.rs[uft.find(j)])
		||(uft.ls[uft.find(i)]
		   <uft.rs[uft.find(j)]))){
	    double minx=min(uft.ls[uft.find(i)]
			    ,uft.ls[uft.find(j)]);
	    double maxx=max(uft.rs[uft.find(i)]
			    ,uft.rs[uft.find(j)]);
	    uft.unite(i,j,minx,maxx);
	  }
	}
      }
      set<int> s;
      for(int i=0;i<v.size();i++)
	s.insert(uft.find(i));
      sumLen=0;
      for(set<int>::iterator it
	    =s.begin();it!=s.end();it++){
	sumLen+=(uft.rs[*it]-uft.ls[*it]);
      }
    }
    cnt++;
    printf("%d %.2f\n",cnt,res);
  }

  return 0;
}

Measured memory_bytes: 0