#include <bits/stdc++.h>

using namespace std;

#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
#define fi first
#define se second

template<typename A, typename B> inline bool chmax(A &a, B b) { if (a<b) { a=b; return 1; } return 0; }
template<typename A, typename B> inline bool chmin(A &a, B b) { if (a>b) { a=b; return 1; } return 0; }

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<int, pll> pip;
const ll INF = 1ll<<29;
const ll MOD = 1000000007;
const double EPS  = 1e-9;

typedef complex<ll> P;
typedef complex<ll> Vec;

struct Line {
	P p;
	Vec v;
	
	Line() {}
	Line(P p, Vec v) : p(p), v(v) {}
	
	P getPoint(ll t) {
		return p + v * t;
	}
};

ll cross(Vec a, Vec b) {
	return a.real() * b.imag() - a.imag() * b.real();
}

bool isIntersectionSS(Line s1, Line s2) {
	P a1 = s1.p, a2 = s1.getPoint(1);
	P b1 = s2.p, b2 = s2.getPoint(1);
	
	return 	cross(a2 - a1, b1 - a1) * cross(a2 - a1, b2 - a1) <= 0 &&
			cross(b2 - b1, a1 - b1) * cross(b2 - b1, a2 - b1) <= 0;
}

int N, M;
P p[100][4];
bool done[100];

P input() {
	int x, y;
	scanf("%d %d", &x, &y);
	return P(x, y);
}

bool collision(int u, int t) {
	REP(i, 4) {
		bool f = true;
		REP(j, 4) if (cross(p[u][(j + 1) % 4] - p[u][j], p[t][i] - p[u][j]) > 0) f = false;
		if (f) return true;
		
		f = true;
		REP(j, 4) if (cross(p[t][(j + 1) % 4] - p[t][j], p[u][i] - p[t][j]) > 0) f = false;
		if (f) return true;
	}
	
	REP(i, 4) REP(j, 4) {
		if ( isIntersectionSS(
						Line(p[u][i], p[u][(i + 1) % 4] - p[u][i]),
						Line(p[t][j], p[t][(j + 1) % 4] - p[t][j])
					)
		)
			return true;
	}
	
	return false;
}

void dfs(int u) {
	done[u] = true;
	
	REP(i, M) if (!done[i]) {
		if (collision(u, i)) dfs(i);
	}
}

int main() {
	while (cin >> N, N) {
		REP(t, N) {
			cin >> M;
			REP(i, M) REP(j, 4) p[i][j] = input();
			
			memset(done, 0, sizeof(done));
			int ans = 0;
			REP(i, M) if (!done[i]) dfs(i), ans++;
			cout << ans << endl;
		}
	}
	return 0;
}