#include<iostream>
#include<cstdio>
#include<vector>
#include<complex>
#include<cmath>
#include<cstdlib>
#include<algorithm>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)(n);++i)

typedef complex<double> P;

const double EPS = 1e-8;
inline double dot(P a, P b) {return real( conj(a)*b);}
inline double cross(P a, P b) {return imag( conj(a)*b);}
int ccw(P a, P b, P c) {
  b -= a; c -= a;
  if (cross(b, c) > EPS)   return +1;       // counter clockwise
  if (cross(b, c) < -EPS)   return -1;       // clockwise
  if (dot(b, c) < -EPS)     return +2;       // c--a--b on line
  if (norm(b) + EPS < norm(c)) return -2;       // a--b--c on line
  return 0;
}
bool IsIntersectSS(P a1, P a2, P b1, P b2) {
  return ccw(a1,a2,b1) * ccw (a1,a2,b2) <= 0 &&
    ccw(b1,b2,a1) * ccw(b1,b2,a2) <= 0;
}

enum { OUT, IN, ON };
int Contains(const vector<P>& Ps, P p) {
  bool in = false;
  int size = Ps.size();
  for (int i = 0; i < size; ++i) {
    P a = Ps[i] - p, b = Ps[(i+1)%size] - p;
    if (imag(a) > imag(b)) swap(a, b);
    if (imag(a) <= 0 && 0 < imag(b))
      if (cross(a, b) < 0) in = !in;
    if (cross(a, b) == 0 && dot(a, b) <= 0) return ON;
  }
  return in ? IN : OUT;
}

bool connect(const vector<P> &a, const vector<P> &b) {
  for(int i = 0; i < (int)a.size(); i++)
    for(int j = 0; j < (int)b.size(); j++)
      if( IsIntersectSS( a[i], a[(i + 1) % a.size()], b[j], b[(j + 1) % b.size()]) )
        return true;
  for(int i = 0; i < (int)a.size(); i++)
    if(Contains( b, a[i] ) ) return true;
  for(int i = 0; i < (int)b.size(); i++)
    if(Contains( a, b[i] ) ) return true;
  return false;
}

int table[128][128];
int visited[128];
void dfs(int p, int N) {
  if( visited[p] ) return;
  visited[p] = 1;
  REP(i, N) if( table[p][i] ) dfs(i, N);
}

void input(vector<P> &v) {
  v.clear();
  REP(k, 4) {
    int x, y; cin >> x >> y;
    v.push_back( P(x, y) );
  }
  reverse(v.begin(), v.end());
}

int solve(int N) {
  vector<P> v[N];
  REP(i, N) input(v[i]);

  REP(i, N) REP(j, N) table[i][j] = 0;

  REP(i, N) REP(j, i) {
    if( connect( v[i], v[j] ) )
      table[i][j] = table[j][i] = 1;
  }

  REP(i, N) visited[i] = 0;
  int cnt = 0;
  REP(i, N) {
    if( !visited[i] ) {
      cnt++;
      dfs(i, N);
    }
  }
  return cnt;
}

int main() {
  for(;;) {
    int N; cin >> N; if( N == 0 ) break;
    REP(i, N) {
      int M; cin >> M;
      int res = solve(M);
      cout << res << endl;
    }
  }
  return 0;
}