#include <iostream>
#include <vector>
#include <utility>
#include <complex>
using namespace std;

using D = double;
using P = complex<D>;
using L = pair<P,P>;
using Poly = vector<P>;

#define X real()
#define Y imag()

const D EPS = 1e-8;

D dot(const P a, const P b){ return a.X*b.X + a.Y*b.Y; }
D cross(const P a, const P b){ return a.X*b.Y - a.Y*b.X; }

int ccw(P a, P b, P c){
  b -= a, c -= a;
  if(cross(b,c) > EPS) return 1;
  if(cross(b,c) < -EPS) return -1;
  if(dot(b,c) < 0) return 2;
  if(norm(b) < norm(c) - EPS) return -2;
  return 0;
}

bool is_cross(L a, L b){
  P af = a.first, as = a.second, bf = b.first, bs = b.second;
  return (ccw(af,as,bf)*ccw(af,as,bs) <= 0 and ccw(bf,bs,af)*ccw(bf,bs,as) <= 0);
}

int in_poly(P a, const Poly &p){
  int n = p.size(), c = 0;
  for(int i = 0; i < n; ++i){
    P s  = p[i] - a, t = p[(i+1)%n] - a;
    if(not ccw(s,t,P(0,0))) return 1;
    if(s.Y > t.Y + EPS) swap(s,t);
    if((s.Y*t.Y < 0 or (s.Y*t.Y < EPS and t.Y > EPS)) and cross(s,t) < EPS) ++c;
  }
  if(c%2) return 2;
  return 0;
}

struct UnionFind{
private:
  vector<int> data;
public:
  int N;
  UnionFind(int n) : data(n,-1), N(n) {}
  bool unite(int x, int y){
    x = find(x);
    y = find(y);
    if(x == y) return false;
    --N;
    if(data[y] < data[x]) swap(x,y);
    data[x] += data[y];
    data[y] = x;
    return x != y;
  }
  int find(int x){
    if(data[x] < 0) return x;
    return (data[x] = find(data[x]));
  }
};

bool connected(const Poly &A, const Poly &B){
  int n = A.size(), m = B.size();
  for(auto p : A){
    if(in_poly(p,B)) return true;
  }
  for(auto p : B){
    if(in_poly(p,A)) return true;
  }
  for(size_t i = 0; i < A.size(); ++i){
    L a(A[i],A[(i+1)%n]);
    for(size_t j = 0; j < B.size(); ++j){
      L b(B[j],B[(j+1)%m]);
      if(is_cross(a,b)) return true;
    }
  }
  return false;
}


int main(){
  int N;
  while(cin >> N, N){
    for(int i = 0; i < N; ++i){
    vector<Poly> V;
      int M;
      cin >> M;
      UnionFind uf(M);
      for(int j = 0; j < M; ++j){
        Poly pol;
        for(int k = 0; k < 4; ++k){
          D x, y;
          cin >> x >> y;
          pol.emplace_back(x,y);
        }
        V.push_back(pol);
      }
      for(int j = 0; j < M; ++j){
        for(int k = 0; k < j; ++k){
          if(connected(V[j],V[k]))
            uf.unite(k,j);
        }
      }
      cout << uf.N << endl;
    }
  }
}

