#include <iostream>
#include <stdlib>
#include <set>
#include <memory>
using namespace std;

const int size = 101;
const double eps = 1e-9;

struct Vector2D {
    int x;
    int y;
    Vector2D(): x(0), y(0) {}
    Vector2D( int x, int y ): x(x), y(y) {}
    Vector2D operator -( Vector2D& right ) {
        return Vector2D( x-right.x, y-right.y );
    }
    bool operator ==( Vector2D& right ) {
        return x == right.x && y == right.y;
    }
};
typedef Vector2D* PVector2D;

// ツ四ツ角ツ形ツデツーツタ
int Q[size][8];
int QC;
void initQ() {
    QC = 0;
}
void inputQ() {
    for ( int i = 0; i < 8; i++ ) {
        cin >> Q[QC][i];
    }
    QC++;
}

// disjoint sets
int F[size];
int FC;
void initF() {
    FC = 0;
}
int get( int ind ) {
    return F[ind] == -1 ? ind : get( F[ind] );
}
bool same( int a, int b ) {
    int fa = get( a );
    int fb = get( b );
    return fa == fb;
}
void merge( int a, int b ) {
    int fa = get( a );
    int fb = get( b );
    if ( fa != fb ) {
        F[fb] = fa;
    }
}

//
PVector2D getTriangleA( int a ) {
    PVector2D answer = new Vector2D[3];
    answer[0] = Vector2D( Q[a][0], Q[a][1] );
    answer[1] = Vector2D( Q[a][2], Q[a][3] );
    answer[2] = Vector2D( Q[a][6], Q[a][7] );
    return answer;
}

PVector2D getTriangleB( int a ) {
    PVector2D answer = new Vector2D[3];
    answer[0] = Vector2D( Q[a][2], Q[a][3] );
    answer[1] = Vector2D( Q[a][4], Q[a][5] );
    answer[2] = Vector2D( Q[a][6], Q[a][7] );
    return answer;
}

int cross( Vector2D a, Vector2D b ) {
    return a.x*b.y - a.y*b.x;
}

int getM( Vector2D a ) {
    return abs(a.x) + abs(a.y);
}

bool collision( PVector2D t, Vector2D p ) {
    for ( int i = 0; i < 3; i++ ) {
        int ii = i;
        int kk = (i+2)%3;
        int c = cross( t[ii]-t[kk], p-t[kk] );
        //if ( c == 0 && getM( p-t[kk] ) <= getM( t[ii]-t[kk] ) ) {
        //    return true;
        //}
    }
    for ( int i = 0; i < 3; i++ ) {
        int ii = i;
        int jj = (i+1)%3;
        int kk = (i+2)%3;
        int c1 = cross( t[ii]-t[kk], p-t[kk] );
        int c2 = cross( t[jj]-t[kk], p-t[kk] );
        if ( ( c1 > 0 && c2 > 0 ) || ( c1 < 0 && c2 < 0 ) ) return false;
    }
    return true;
}

bool collision( int a, int b ) {
    PVector2D ta = getTriangleA( a );
    PVector2D tb = getTriangleB( b );

    for ( int i = 0; i < 3; i++ ) {
        if ( collision( ta, tb[i] ) ) return true;
        if ( collision( tb, ta[i] ) ) return true;
    }
    for ( int i = 0; i < 3; i++ ) {
        for ( int j = 0; j < 3; j++ ) {
            if ( ta[i] == tb[j] ) return true;
        }
    }

    return false;
}

int main() {
    int n;
    while ( cin >> n && n ) {

        for ( int i = 0; i < n; i++ ) {
            initF();
            initQ();

            int m;
            cin >> m;
            for ( int j = 0; j < m; j++ ) {
                inputQ();
                F[FC++] = -1;
            }

            for ( int ii = 0; ii < m; ii++ ) {
                for ( int jj = 0; jj < m; jj++ ) {
                    if ( same( ii, jj ) ) continue;
                    if ( collision( ii, jj ) ) merge( ii, jj );
                }
            }

            set <int> S;
            for ( int j = 0; j < m; j++ ) {
                S.insert( get(j) );
            }

            cout << S.size() << endl;
        }
    }
    return 0;
}