#include<iostream>
#include<vector>
#include<algorithm>
#include<set>
#include<cmath>

const double EPS = 1e-24;

struct P{
	double x, y;
	P operator-(const P& rp);
	bool operator==(const P& rp);
};

P P::operator-(const P& rp){
	return {x-rp.x, y-rp.y};
}

bool P::operator==(const P& rp){
	return abs(x-rp.x) < EPS && abs(y-rp.y) < EPS;
}

typedef P Vector;

double dotProduct(Vector v1, Vector v2){
	return v1.x * v1.y + v2.x * v2.y;
}

double crossProduct(Vector v1, Vector v2){
	return v1.x * v2.y - v2.x * v1.y;
}

double abs(P p){
	return sqrt(p.x * p.x + p.y * p.y);
}

struct Rectangle{
	P ps[4];
};

class UnionFind{
public:
	int size;
	std::vector<int> par, rank;
	UnionFind(int _size);
	int find(int x);
	void unite(int x, int y);
};

UnionFind::UnionFind(int _size)
	:par(_size), rank(_size), size(_size){
	for(int i=0;i<size;i++){
		par[i] = i;
		rank[i] = 0;
	}
}

int UnionFind::find(int x){
	if(par[x] == x){
		return x;
	}
	return par[x] = find(par[x]);
}

void UnionFind::unite(int x, int y){
	x = find(x);
	y = find(y);
	if(x == y)return;//もう併合している

	if(rank[x] < rank[y]){
		par[x] = par[y];
	}else{
		par[y] = par[x];
		if(rank[x] == rank[y]){
			rank[x]++;
		}
	}
}

bool kousa(Rectangle r1, Rectangle r2){
	for(int k=2;k;k--){
		for(int i=0;i<4;i++){
			P c = r1.ps[i];
			int count = 0;
			for(int j=0;j<4;j++){
				P a = r2.ps[j], b = r2.ps[(j+1)%4];

				if(a == c || b == c || (abs(crossProduct(b-a, c-a)) < EPS) && dotProduct(b-a, c-a) > -EPS && abs(b-a) < abs(c-a) + EPS){//長方形の線分上
					return true;
				}

				if(crossProduct(b-a, c-a) > -EPS){
					count++;
				}else{
					count--;
				}
			}
			if(abs(count) == 4){
				return true;
			}
		}
		std::swap(r1, r2);
	}

	return false;
}

int main(){
	int n;
	while(std::cin >> n, n){
		int res[100];
		for(int k=0;k<n;k++){
			int m;
			std::cin >> m;

			Rectangle rs[100];
			for(int i=0;i<m;i++){
				P (&ps)[4] = rs[i].ps;
				for(int j=0;j<4;j++){
					std::cin >> ps[j].x >> ps[j].y;
				}
			}

			UnionFind uf(100);
			for(int i=0;i<m;i++){
				for(int j=i+1;j<m;j++){
					if(kousa(rs[i], rs[j])){//片方灯せばいいかなー
						uf.unite(i, j);//併合
					}
				}
			}

			std::set<int> s;//大元さん
			for(int i=0;i<m;i++){
				s.insert(uf.find(i));
			}

			std::cout << s.size() << std::endl;
		}
	}
}