Problem: A crop circle suddenly appeared on the vast agricultural land of Argentina. A total of n crop circles were confirmed, including overlapping, popping, large, and small ones.

When a mystery hunter tried to capture the whole picture of a crop circle from the air, he found it difficult to show the beautiful pattern in the image because the outline of each circle was not clear.

Therefore, the mystery hunter proposed to emphasize the contour by installing a string of special material along the contour.

The part where the string is installed is the part on the circumference of one crop circle that is not included in any other crop circle.

The film crew asked you to create a program to measure the required string length. Enter the center coordinates and radius of each crop circle and create a program to report the length of the string to be installed.

For reference, the first and second cases of the input / output examples are shown in FIGS. 1 and 2, respectively. The part of the string is shown by a thick line.


<image>


Figure 1



<image>


Figure 2



Constraints

* n ≤ 100
* -1000 ≤ xi, yi ≤ 1000
* 0 <ri ≤ 100

Input

Multiple datasets are given as input. Each dataset is given in the following format:

n (number of crop circles: integer)
x1 y1 r1 (center coordinates and radius of the first circle: real numbers separated by blanks)
x2 y2 r2 (center coordinates and radius of the second circle: real numbers separated by blanks)
..
..
xn yn rn (center coordinates and radius of the nth circle: real numbers separated by blanks)


When n is 0, it indicates the end of input.

Output

Output the string length on one line for each dataset. The output may contain an error of 0.000001 or less.

Example

Input

4
6 4 2
4 7 3
7 10 3
13 6 1
4
7 4 2
4 7 3
7 10 3
11 6 3
0


Output

39.664699289572
45.627024663706

Solution (in CPP):

Solution:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cassert>
#include<iostream>
#include<sstream>
#include<string>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<utility>
#include<numeric>
#include<algorithm>
#include<bitset>
#include<complex>
#include<stack>

using namespace std;

typedef long long Int;
typedef vector<int> vint;
typedef pair<int,int> pint;
typedef vector<string> vstring;
typedef vector<pint> vpint;
typedef stringstream SS;

template<class T> void chmin(T &t, T f) { if (t > f) t = f; }
template<class T> void chmax(T &t, T f) { if (t < f) t = f; }

#define rep(i,n) for(int i=0;i<(n);++i)
#define repn(i,m,n) for(int i=(m);i<(n);++i)
#define repd(i,n) for(int i=(n)-1;i>=0;--i)
#define repnd(i,m,n) for(int i=(n)-1;i>=(m);--i)
#define rep0(i,n) for(i=0;i<(n);++i)
#define repn0(i,m,n) for(i=(m);i<(n);++i)
#define repd0(i,n) for(i=(n)-1;i>=0;--i)
#define repnd0(i,m,n) for(i=(n)-1;i>=(m);--i)
#define repc(i,n) for(int i=0;i<=(n);++i)
#define repcn(i,m,n) for(int i=(m);i<=(n);++i)
#define repcd(i,n) for(int i=(n);i>=0;--i)
#define repcnd(i,m,n) for(int i=(n);i>=(m);--i)
#define repc0(i,n) for(i=0;i<=(n);++i)
#define repcn0(i,m,n) for(i=(m);i<=(n);++i)
#define repcd0(i,n) for(i=(n);i>=0;--i)
#define repcnd0(i,m,n) for(i=(n);i>=(m);--i)
#define all(n) n.begin(),n.end()
#define sz(n) ((int)(n).size())
#define IL for(;;)
#define MP make_pair
#define PB push_back
#define X second
#define Y first
#define p_queue(n) priority_queue<n,vector<n>,greater<n> >
#define PUTLINE cout<<"LINE:"<<__LINE__<<endl;

const int INF = 2147483647/3;
const double EPS = 1e-10;
const double PI = acos(-1.0);

const int dx[]={1,-1,0,0,1,1,-1,-1,0};
const int dy[]={0,0,1,-1,1,-1,1,-1,0};

int sig(double r) { return r < -EPS ? -1 : r > EPS ? 1 : 0; }

struct P {
	double x, y;
	P() {}
	P(double x, double y) : x(x), y(y) {}
	P operator+(const P &a) const { return P(x + a.x, y + a.y); }
	P operator-(const P &a) const { return P(x - a.x, y - a.y); }
	P operator*(const P &a) const { return P(x * a.x - y * a.y, x * a.y + y * a.x); }
	P operator-() const { return P(-x, -y); }
	P operator*(const double &k) const { return P(x * k, y * k); }
	P operator/(const double &k) const { return P(x / k, y / k); }
	double abs2() const { return x * x + y * y; }
	double abs() const { return sqrt(abs2()); }
	double arg() const { return atan2(y, x); }
	double dot(const P &a) const { return x * a.x + y * a.y; }
	double det(const P &a) const { return x * a.y - y * a.x; }
	P proj(const P &a) const { double k = dot(a) / abs2(); return P(x * k, y * k); }
	bool operator<(const P &a) const { return x != a.x ? x < a.x : y < a.y; }
	bool operator==(const P &a) const { return sig(x - a.x) == 0 && sig(y - a.y) == 0; }
};

ostream &operator<<(ostream&os, const P&a) { os << "(" << a.x << ", " << a.y << ")"; return os; }
double tri(P a, P b, P c) { return (b - a).det(c - a); }

struct L {
	P a, b;
	L() {}
	L(P a, P b) : a(a), b(b) {}
	P vec() const { return b - a; }
	P proj(const P &p) const { return a + vec().proj(p - a); }
	P refl(const P &p) const { return proj(p) * 2 - p; }
	int iSP(const P &p) const {
		int s = sig(vec().det(p - a));
		if (s != 0) return s;
		if (sig(vec().dot(p - a)) < 0) return -2;
		if (sig(-vec().dot(p - b)) < 0) return 2;
		return 0;
	}
	int iLL(const L &l) const {
		if (sig(vec().det(l.vec()))) return 1;
		if (sig(vec().det(l.a - a))) return 0;
		return -1;
	}
	bool iLS(const L &l) const { return sig(tri(a, b, l.a)) * sig(tri(a, b, l.b)) <= 0; }
	bool iSS(const L &l) const { return this->iSP(l.a) * this->iSP(l.b) <= 0 && l.iSP(a) * l.iSP(b) <=0; }
	P pLL(const L &l) const { return a + vec() * (l.a - a).det(l.vec()) / b.det(l.vec()); }
	double dLP(const P &p) const { return abs(tri(a, b, p)) / vec().abs(); }
	double dSP(const P &p) const {
		if (sig(vec().dot(p - a)) <= 0) return (p - a).abs();
		if (sig(vec().dot(p - b)) >= 0) return (p - b).abs();
		return dLP(p);
	}
	double dLL(const L &l) const { return iLL(l) ? 0 : dLP(l.a); }
	double dLS(const L &l) const { return iLS(l) ? 0 : min(dLP(l.a), dLP(l.b)); }
	double dSS(const L &l) const { return iSS(l) ? 0 : min(min(dSP(l.a), dSP(l.b)), min(l.dSP(a), l.dSP(b))); }
};

struct C {
	P p;
	double r;
	C() {}
	C(P p, double r) : p(p), r(r) {}
	int iCC(C c) {
		double d = (c.p - p).abs();
		if (sig(d) == 0 && sig(r - c.r) == 0) return -1;
		if (sig(r - c.r - d) >= 0) return 2;
		if (sig(c.r - r - d) >= 0) return -2;
		return (sig(r + c.r - d) >= 0) ? 1 : 0;
	}
	bool iCS(L l) {
		return (sig(r - l.dSP(p)) >= 0&& sig(r - max((l.a - p).abs(), (l.b - p).abs())) <= 0);
	}
	pair<P,P> pCC(C c) {
		double d = (c.p - p).abs();
		double x = (d * d + r * r - c.r * c.r) / (d * 2);
		P e = (c.p - p) / d, w = e * P(0, 1) * sqrt(max(r * r - x * x, 0.0));
		return make_pair(p + e * x - w, p + e * x + w);
	}
	pair<P,P> pCL(L l) {
		P h = l.proj(p);
		double d = (h - p).abs();
		double y = sqrt(max(r * r - d * d, 0.0));
		P e = (l.b - l.a) / (l.b - l.a).abs();
		return make_pair(h - e * y, h + e * y);
	}
	pair<P,P> tCP(P p) {
		double d2 = (p - this->p).abs2();
		double x = sqrt(max(d2 - r * r, 0.0));
		P h = this->p + (p - this->p) * (r * r / d2);
		P w = (p - this->p) * P(0, 1) * (x * r / d2);
		return make_pair(h - w, h + w);
	}
	double aCC(C c) {
		double d = (p - c.p).abs();
		if (sig(r - c.r - d) >= 0) return c.r * c.r * PI;
		if (sig(c.r - r - d) >= 0) return r * r * PI;
		if (sig(r + c.r - d) <= 0) return 0;
		double x = (d * d + r * r - c.r * c.r) / (d * 2);
		double h = sqrt(r * r - x * x);
		return r * r * atan2(h, x) + c.r * c.r * atan2(h, d - x) - d * h; 
	}
};


int main() {
	int n;
	C c[110];
	IL {
		cin >> n;
		if (n == 0) break;
		rep (i, n) cin >> c[i].p.x >> c[i].p.y >> c[i].r;
		double res = 0;
		rep (i, n) {
			vector<pair<double,int> > v;
			v.PB(MP(-PI, 0));
			v.PB(MP(PI, 0));
			rep (j, n) {
				if (i == j) continue;
				int icc = c[i].iCC(c[j]);
				//cout << i << " " << icc <<endl;
				if (icc == -2 || icc == -1 && i < j) {
					v.PB(MP(-PI, 1));
					v.PB(MP(PI, -1));
				} else if (icc == 1) {
					pair<P,P> p = c[i].pCC(c[j]);
					P a = p.first - c[i].p, b = p.second - c[i].p;
					//cout << a << " " << b << endl;
					if (sig((a - b).abs()) == 0) continue;
					if (a.arg() < b.arg()) {
						v.PB(MP(a.arg(), 1));
						v.PB(MP(b.arg(), -1));
					} else {
						v.PB(MP(a.arg(), 1));
						v.PB(MP(PI, -1));
						v.PB(MP(-PI, 1));
						v.PB(MP(b.arg(), -1));
					}
				}
			}
			sort(all(v));
			//rep (j, sz(v)) cout << v[j].first << " " << v[j].second << endl;
			int cover = 0;
			rep (j, sz(v) - 1) {
				cover += v[j].second;
				if (cover == 0) res += c[i].r * (v[j + 1].first - v[j].first);
			}
		}
		printf("%.12f\n", res);
	}
	return 0;
}