#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <utility>
#include <functional>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <deque>
#include <ctime>
  
using namespace std;
  
#define rep(i,n) REP(i,0,n)
#define REP(i,s,e) for(int i=(s); i<(int)(e); i++)
#define pb push_back
#define mp make_pair
#define all(r) (r).begin(),(r).end()
#define rall(r) (r).rbegin(),(r).rend()
#define fi first
#define se second
#define println(X) cout<<X<<endl;
#define DBG(X) cout<<#X<<" : "<<X<<endl;
  
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vii;
typedef vector<ll> vl;
typedef vector<vl> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
 
const int INF = 1e9;
const ll LINF = 1e18;
const ll MOD = 1e9 + 7;
double EPS = 1e-8;
const double PI = acos(-1);


struct UFT{ //O(loga(n))
    int n;
    vi d, r;
    UFT(int n) : n(n), d(n, -1), r(n, 0){};
    int root(int i){
        if(d[i] < 0) return i;
        return d[i] = root(d[i]);
    }
    bool same(int x, int y){
        return root(x) == root(y);
    }
    bool unite(int x, int y){
        x = root(x);
        y = root(y);
        if(x == y) return false;
 
        if(r[x] < r[y]) swap(x, y);
        else if(r[x] == r[y]) r[x]++;
        d[x] += d[y];
        d[y] = x;
        return true;
    }
    int size(int i){
        return -d[root(i)];
    }
};

struct P{
	double x, y;
	P operator -(const P& p) const{
        return {x - p.x, y - p.y};
    }
};

struct R{
	vector<P> p;
};

double cross(const P& p, const P& q) {
	return p.x * q.y - q.x * p.y;
}

bool isPinR(const P& p, const R& r) {
	for(int i = 0; i < 4; i++) {
        int a = i, b = (i+1) % 4;
        if(cross(p - r.p[a], r.p[b]-r.p[a]) < 0.0) return false;
    }
    return true;
}

int main(){
	int n;
    while(cin>>n && n){
        while(n--) {
            int m;
            cin>> m;
            UFT u(m);
            vector<R> r(m);
            rep(i, m) {
                rep(j, 4) {
                    double x, y;
                    cin>>x>>y;
                    r[i].p.push_back({x, y});
                }
            }
            rep(i, m) rep(j, i) {
                for(int k = 0; k < 4; k++) if(isPinR(r[i].p[k], r[j])) {
                    u.unite(i, j);
                    break;
                }
            }
            set<int> st;
            rep(i, m) st.insert(u.root(i));
            cout<<st.size()<<endl;
        }
    }
}