#include <iostream>
#include <utility>
#include <vector>
using namespace std;

#define fi first
#define se second
#define x first
#define y second
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
#define EPS 1e-9

int UF[128];
int rank[128];

void UF_init() {
	for(int i = 0; i < 128; i++) {
		UF[i] = i;
		rank[i] = 1;
	}
}

bool UF_same(int a, int b) {
	int pa, pb;
	pa = a; pb = b;
	while(UF[pa] != pa)
		pa = UF[pa];
	while(UF[pb] != pb)
		pb = UF[pb];

	if(pa == pb)
		return true;
	return false;
}

void UF_merge(int a, int b) {
	int pa, pb;
	pa = a;
	while(UF[pa] != pa)
		pa = UF[pa];
	pb = b;
	while(UF[pb] != pb)
		pb = UF[pb];

	if(rank[pa] > rank[pb]) {
		UF[pb] = pa;
	}
	else {
		if(rank[pa] == rank[pb])
			rank[pa]++;
		UF[pa] = pb;
	}
}

bool inside(pii p, vector<pii> rect) {
	vector<pii> v;
	for(int i = 0; i < rect.size(); i++) {
		v.push_back(pii(rect[i].x - p.x, rect[i].y - p.y));
	}

	bool ret = true;
	for(int i = 0; i < v.size(); i++) {
		if(v[i].x * v[(i+1)%v.size()].y - v[i].y * v[(i+1)%v.size()].x > 0)
			ret = false;
	}

	return ret;
}

int cross_product(pii a, pii b) {
	return a.x * b.y - a.y * b.x;
}

int inner_product(pii a, pii b) {
	return a.x * b.x + a.y * b.y;
}

bool cross(vector<pii> r0, vector<pii> r1) {
	for(int i = 0; i < r0.size(); i++) {
		for(int j = 0; j < r1.size(); j++) {
			pii a, b, c;
			a = pii(r1[j].x - r0[i].x, r1[j].y - r0[i].y);
			b = pii(r1[(j+1)%r1.size()].x - r0[i].x, r1[(j+1)%r1.size()].y - r0[i].y);
			c = pii(r0[(i+1)%r0.size()].x - r0[i].x, r0[(i+1)%r0.size()].y - r0[i].y);

			if(cross_product(a, b) == 0) {
				if(inner_product(a,b) <= 0)
					return true;
			}

			else {
				double s, t;
				s = (double)cross_product(c,b) / cross_product(a,b);
				t = (double)cross_product(a,c) / cross_product(a,b);
				if(s + EPS > 0 && t + EPS > 0 && s + t + EPS > 1)
					return true;
			}
		}
	}

	return false;
}

int main() {
	int N;
	while(cin >> N, N) {
		for(int n = 0; n < N; n++) {
			int M;
			vector<vector<pii> > poly;
			cin >> M;
			for(int t = 0; t < M; t++) {
				vector<pii> v;
				for(int i = 0; i < 4; i++) {
					pii tmp;
					cin >> tmp.x >> tmp.y;
					v.push_back(tmp);
				}
				poly.push_back(v);
			}
			UF_init();
			for(int i = 0; i < poly.size(); i++) {
				for(int j = 0; j < poly.size(); j++) {
					int merge_flg = false;
					for(int k = 0; k < poly[j].size(); k++) {
						if(inside(poly[j][k], poly[i]))
							merge_flg = true;
					}
					if(cross(poly[i],poly[j]))
						merge_flg = true;
					if(merge_flg && !UF_same(i,j)) {
						UF_merge(i, j);
					}
				}
			}

			int ans = 0;
			for(int i = 0; i < M; i++) {
				if(UF[i] == i)
					ans++;
			}
			cout << ans << endl;
		}
	}
}