#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<algorithm>#include<string>#include<map>#include<set>#include<iostream>#include<vector>#include<queue>using namespace std;#define sz(v) ((int)(v).size())#define rep(i, n) for (int i = 0; i < (n); ++i)#define repf(i, a, b) for (int i = (a); i <= (b); ++i)#define repd(i, a, b) for (int i = (a); i >= (b); --i)#define clr(x) memset(x,0,sizeof(x))#define clrs( x , y ) memset(x,y,sizeof(x))#define out(x) printf(#x" %dn", x)#define sqr(x) ((x) * (x))typedef long long lint;const int maxint = -1u>>1;const double eps = 1e-8;const int maxn = 50 * 50 * 2 + 10;const double pi = acos(-1.0);int sgn(const double &x) { return (x > eps) - (x < -eps); }struct point { double x, y; point (double _x = 0, double _y = 0) : x(_x), y(_y) { } void input() { scanf("%lf%lf", &x, &y); } void output() { printf("%.3f %.3fn", x, y); } double len() const { return sqrt(x * x + y * y); } point trunc (double l) const { double r = l / len(); return point(x * r, y * r); } point rotate_left() const { return point(-y, x); } point rotate_right() const { return point(y, -x); } point rotate_left(double c) const { double s = sqrt(1 - c * c); return point(x * c - y * s, y * c + x * s); } point rotate_right(double c) const { double s = sqrt(1 - c * c); return point(x * c + y * s, y * c - x * s); } point set() { double l = len(); return point(x / l, y / l); } bool operator < (const point &p) const { if (sgn(p.x - x) != 0) return x < p.x; else return y < p.y; } bool operator == (const point &p) const { return sgn(x - p.x) == 0 && sgn(y - p.y) == 0; } double operator * (const point &p) const { return (x * p.y) - (y * p.x); } double operator ^ (const point &p) const { return (x * p.x) + (y * p.y); } point operator + (const point &p) const { return point(x + p.x, y + p.y); } point operator - (const point &p) const { return point(x - p.x, y - p.y); } point operator / (double mul) const { return point(x / mul, y / mul); }};vector<point> ogn, inter;double rr[maxn];int fa[maxn], sumv[maxn], sume[maxn];int find(int w) { if (fa[w] == w) return w; int k = find(fa[w]); sumv[k] += sumv[w]; sume[k] += sumv[w]; fa[w] = k; return k;}void getInter(vector<point> &inter, int i, int j) { if (rr[i] > rr[j]) swap (i, j); double a = rr[i]; double b = rr[j]; double c = (ogn[i] - ogn[j]).len(); if (sgn(b - a - c) >= 0) { return; } if (sgn(c - a - b) > 0) return; else if (sgn(c - a - b) == 0) { inter.push_back(ogn[i] + (ogn[j] - ogn[i]).trunc(a)); } else { double cs = (-b * b + a * a + c * c) / (2 * a * c); point dir = (ogn[j] - ogn[i]).trunc(a); inter.push_back(ogn[i] + dir.rotate_left(cs)); inter.push_back(ogn[i] + dir.rotate_right(cs)); }}int main() { int T; scanf("%d", &T); while (T--) { int n; scanf("%d", &n); ogn.clear(); rep (i, n) { point x; x.input(); ogn.push_back(x); scanf("%lf", &rr[i]); } inter.clear(); rep (i, n) { repf (j, i + 1, n - 1) { getInter(inter, i, j); } } sort(inter.begin(), inter.end()); inter.erase(unique(inter.begin(), inter.end()), inter.end()); rep (i, sz(inter)) { fa[i] = i; sumv[i] = 1; sume[i] = 0; } int ans = 1; rep (i, n) { vector<int> have; rep (k, sz(inter)) { if (sgn((ogn[i] - inter[k]).len() - rr[i]) == 0) { have.push_back(k); } } if (sz(have) == 0) ans++; else { rep (j, sz(have)) repf (k, j + 1, sz(have) - 1) { int r = find(have[j]); int h = find(have[k]); if (r != h) { if (r > h) swap(r, h); fa[h] = r; sumv[r] += sumv[h]; sume[r] += sume[h]; } } int r = find(have[0]); sume[r] += sz(have); } } int v[maxn]; memset(v, 0, sizeof(v)); rep (i, sz(inter)) { int r = find(i); if (v[r] == 0) { v[r] = 1; ans += sume[r] - sumv[r] + 1; } } printf("%dn", ans); } return 0;}