#include<iostream>
#include<complex>
#include<algorithm>
#define EPS 1e-10
using namespace std;

typedef complex<double> P;

int n,m;
P p[100][4];

double cross(P a,P b){return imag(conj(a)*b);}

bool is_cp(P a1,P a2,P b1,P b2){
  if(cross(a2-a1,b1-a1) * cross(a2-a1,b2-a1) < EPS)
    if(cross(b2-b1,a1-b1) * cross(b2-b1,a2-b1) < EPS)return true;
  return false;
}

bool inter(int quad,int qn,int pn){
  double m = -10000.0;
  for(int i=0;i<4;i++)m = max(m,p[quad][i].real());
  m += 1.0;
  P tmp = P(m,p[qn][pn].imag());
  int res = 0;
  for(int i=0;i<4;i++)if(is_cp(p[quad][i],p[quad][(i+1)%4],p[qn][pn],tmp))res++;
  return (res&1)==1;
}

int par[100];
int rank[100];

void init(int n){
  for(int i=0;i<n;i++){
    par[i] = i;
    rank[i] = 0;
  }
}

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

void unite(int x,int y){
  x = find(x);
  y = find(y);
  if(x==y)return;

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

bool same(int x,int y){return find(x)==find(y);}

int main(){
  while(cin >> n && n){
    for(int i=0;i<n;i++){
      cin >> m;
      for(int j=0;j<m;j++)
	for(int k=0;k<4;k++)cin >> p[j][k].real() >> p[j][k].imag();

      init(m);

      for(int j=0;j<m;j++)
	for(int k=0;k<m;k++)
	  for(int l=0;l<4;l++)
	    if(j!=k && inter(j,k,l))unite(j,k);

      int ans = 0;
      for(int j=0;j<m;j++){
	find(j);
	if(par[j]==j)ans++;
      }
      cout << ans << endl;
    }
  }
}