Problem: A mobile phone company ACMICPC (Advanced Cellular, Mobile, and Internet-Connected Phone Corporation) is planning to set up a collection of antennas for mobile phones in a city called Maxnorm. The company ACMICPC has several collections for locations of antennas as their candidate plans, and now they want to know which collection is the best choice.

for this purpose, they want to develop a computer program to find the coverage of a collection of antenna locations. Each antenna Ai has power ri, corresponding to "radius". Usually, the coverage region of the antenna may be modeled as a disk centered at the location of the antenna (xi, yi) with radius ri. However, in this city Maxnorm such a coverage region becomes the square [xi − ri, xi + ri] × [yi − ri, yi + ri]. In other words, the distance between two points (xp, yp) and (xq, yq) is measured by the max norm max{ |xp − xq|, |yp − yq|}, or, the L∞ norm, in this city Maxnorm instead of the ordinary Euclidean norm √ {(xp − xq)2 + (yp − yq)2}.

As an example, consider the following collection of 3 antennas


4.0 4.0 3.0
5.0 6.0 3.0
5.5 4.5 1.0


depicted in the following figure

<image>

where the i-th row represents xi, yi ri such that (xi, yi) is the position of the i-th antenna and ri is its power. The area of regions of points covered by at least one antenna is 52.00 in this case.

Write a program that finds the area of coverage by a given collection of antenna locations.



Input

The input contains multiple data sets, each representing a collection of antenna locations. A data set is given in the following format.



n
x1 y1 r1
x2 y2 r2
. . .
xn yn rn



The first integer n is the number of antennas, such that 2 ≤ n ≤ 100. The coordinate of the i-th antenna is given by (xi, yi), and its power is ri. xi, yi and ri are fractional numbers between 0 and 200 inclusive.

The end of the input is indicated by a data set with 0 as the value of n.

Output

For each data set, your program should output its sequence number (1 for the first data set, 2 for the second, etc.) and the area of the coverage region. The area should be printed with two digits to the right of the decimal point, after rounding it to two decimal places.

The sequence number and the area should be printed on the same line with no spaces at the beginning and end of the line. The two numbers should be separated by a space.

Example

Input

3
4.0 4.0 3.0
5.0 6.0 3.0
5.5 4.5 1.0
2
3.0 3.0 3.0
1.5 1.5 1.0
0


Output

1 52.00
2 36.00

Solution (in CPP):

Solution:
#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
using namespace std;

typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 998244353;
typedef long double ld;
typedef complex<ld> Point;
const ll INF = mod * mod;
typedef pair<int, int> P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
const ld eps = 1e-8;
const ld pi = acos(-1.0);
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;
typedef vector<int> vec;
typedef vector<string> svec;

bool eq(ld a, ld b) {
	return (abs(a - b) < eps);
}

class Line {
public:
	Point a, b;
};
class Circle {
public:
	Point p; ld r;
};

ld dot(Point a, Point b) {
	return real(conj(a)*b);
}
ld cross(Point a, Point b) {
	return imag(conj(a)*b);
}
namespace std {
	bool operator<(const Point &lhs, const Point &rhs) {
		return lhs.real() == rhs.real() ? lhs.imag() < rhs.imag() : lhs.real() < rhs.real();
	}
}
Point proj(Line l, Point p) {
	ld t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
	return l.a + t * (l.a - l.b);
}

ld dist_lp(Line l, Point p) {
	return abs(p - proj(l, p));
}

int ccw(Point a, Point b, Point c) {
	b -= a; c -= a;
	if (cross(b, c) > eps)return 1;//a,b,cが反時計回り
	if (cross(b, c) < -eps)return -1;//a,b,cが時計回り
	if (dot(b, c) < 0)return 2;//c,a,bの順に一直線
	if (norm(b) < norm(c))return -2;//a,b,cの順に一直線
	return 0;//a,c,bの順に一直線
}
bool isis_ll(Line l, Line m) {
	return !eq(cross(l.b - l.a, m.b - m.a), 0);
}
Point is_ll(Line s, Line t) {
	Point sv = s.b - s.a; Point tv = t.b - t.a;
	return s.a + sv * cross(tv, t.a - s.a) / cross(tv, sv);
}

//直線lに幅dをつける
vector<Line> make_w(Line l, ld d) {
	Point dif = l.b - l.a;
	dif = dif*Point{0, 1};
	dif = dif * (d / abs(dif));
	vector<Line> ret;
	for (int id = 1; id >= -1; id -= 2) {
		Point a = l.a + dif * (ld)id;
		Point b = l.b + dif * (ld)id;
		ret.push_back({ a,b });
	}
	return ret;
}

typedef vector<Point> polygon;
polygon ConvexHull(polygon p) {
	int n = p.size();
	int k = 0;
	sort(p.begin(), p.end());
	polygon ch(2 * n);
	for (int i = 0; i < n; ch[k++] = p[i++]) {
		while (k >= 2 && ccw(ch[k - 2], ch[k - 1], p[i]) <= 0)--k;
	}
	for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--]) {
		while (k >= t && ccw(ch[k - 2], ch[k - 1], p[i]) <= 0)--k;
	}
	ch.resize(k - 1);
	return ch;
}
polygon convex_cut(const polygon &p, Line l) {
	vector<Point> ret;
	rep(i, p.size()) {
		Point a = p[i], b = p[(i + 1) % p.size()];
		if (ccw(l.a, l.b, a) != -1)ret.push_back(a);
		if (ccw(l.a, l.b, a)*ccw(l.a, l.b, b)<0) {
			ret.push_back(is_ll({ a,b }, l));
		}
	}
	return ret;
}
ld area(const polygon &p){
	ld ret = 0;
	int n = p.size();
	rep(j, n)ret += cross(p[j], p[(j + 1) % n]);
	return ret / 2.0;
}
ld max_distance(const polygon &p) {
	//assert(p.size()>1);
	polygon g = ConvexHull(p);
	int n = g.size(), a = 0, b = 1;
	ld ret = abs(g[0] - g[1]);
	while (a < n) {
		Point p1 = g[a%n], p2 = g[(a + 1) % n];
		Point q1 = g[b%n], q2 = g[(b + 1) % n];
		if (arg((p2 - p1) / (q1 - q2)) > 0)++b; else ++a;
		ret = max(ret, abs(p1 - q1));
	}
	return ret;
}

vector<Point> is_cc(Circle c1, Circle c2) {
	vector<Point> res;
	ld d = abs(c1.p - c2.p);
	ld rc = (d*d + c1.r*c1.r - c2.r*c2.r) / (2 * d);
	ld dfr = c1.r*c1.r - rc * rc;
	if (abs(dfr) < eps)dfr = 0.0;
	if (dfr < 0.0)return res;
	ld rs = sqrt(dfr);
	Point diff = (c2.p - c1.p) / d;
	res.push_back(c1.p + diff * Point(rc, rs));
	if (dfr != 0.0)res.push_back(c1.p + diff * Point(rc, -rs));
	return res;
}
bool in_Circle(Circle a, Circle b) {
	ld dist = abs(b.p - a.p);
	return dist < b.r - a.r+eps;
}

int n;
void solve() {
	vector<pair<pair<ld,int>, LDP>> v;
	rep(i, n) {
		ld x, y, r; cin >> x >> y >> r;
		v.push_back({ {x - r,0},{y - r,y + r} });
		v.push_back({ {x + r,1},{y - r,y + r} });
	}
	sort(v.begin(), v.end());
	vector<pair<LDP,int>> u;
	ld ans = 0;
	ld loc = -1;
	rep(i, v.size()) {
		//cout << i << endl;
		if (i > 0&&v[i].first.first!=v[i-1].first.first) {
			ld sum = 0;
			rep(j, u.size()) {
				sum += u[j].first.second - u[j].first.first;
			}
			//cout << sum << " " << v[i].first.first - loc << endl;
			ans += sum * (v[i].first.first - loc);
		}
		int id = v[i].first.second;
		ld l = v[i].second.first, r = v[i].second.second;
		if (id == 0) {
			vector<LDP> used;
			int len = u.size();
			rep(j, len) {
				ld la = u[j].first.first, lb = u[j].first.second;
				if (min(lb, r) > max(la, l)) {
					if (la < l) {
						u[j].first.first = l;
						u.push_back({ {la,l},u[j].second });
					}
					if (r<lb) {
						u[j].first.second = r;
						u.push_back({ {r,lb},u[j].second });
					}
					u[j].second++;
					used.push_back({ la,lb });
				}
			}
			ld cur = l;
			rep(j, used.size()) {
				ld a = used[j].first, b = used[j].second;
				if (a > cur) {
					u.push_back({ {cur,a},1 });
				}
				cur = used[j].second;
			}
			if (r >cur) {
				u.push_back({ {cur,r},1 });
			}
			sort(u.begin(), u.end());
		}
		else {
			rep(j, u.size()) {
				ld la = u[j].first.first, lb = u[j].first.second;
				if (min(lb, r) > max(la, l)) {
					u[j].second--;
					//cout << u[j].first.first << " " << u[j].first.second << " " << u[j].second << endl;
				}
			}
			for (int j = (int)u.size() - 1; j >= 0; j--) {
				if (u[j].second == 0)u.erase(u.begin() + j);
			}
		}
		loc = v[i].first.first;
		//rep(j, u.size())cout << u[j].first.first << " " << u[j].first.second << " "<<u[j].second<<endl;
	}
	cout << ans << endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(2);
	int t = 1;
	while (cin >> n, n) {
		cout << t << " ";
		solve();
		t++;
	}
	//solve();
	//stop
	return 0;
}