#include<stdio.h>
#include<math.h>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
const double EPS = 1e-7;
const double INF = 1e+10;
const double PI = acos(-1);
int sig(double r) { return (r < -EPS) ? -1 : (r > +EPS) ? +1 : 0; }
inline double ABS(double a){return max(a,-a);}
struct Pt {
    double x, y;
    Pt() {}
    Pt(double x, double y) : x(x), y(y) {}
    Pt operator+(const Pt &a) const { return Pt(x + a.x, y + a.y); }
    Pt operator-(const Pt &a) const { return Pt(x - a.x, y - a.y); }
    Pt operator*(const Pt &a) const { return Pt(x * a.x - y * a.y, x * a.y + y * a.x); }
    Pt operator-() const { return Pt(-x, -y); }
    Pt operator*(const double &k) const { return Pt(x * k, y * k); }
    Pt operator/(const double &k) const { return Pt(x / k, y / k); }
    bool operator==(const Pt &a)const{ return !sig(x-a.x)&&!sig(y-a.y);}
    double ABS() const { return sqrt(x * x + y * y); }
    double abs2() const { return x * x + y * y; }
    double arg() const { return atan2(y, x); }
    double dot(const Pt &a) const { return x * a.x + y * a.y; }
    double det(const Pt &a) const { return x * a.y - y * a.x; }
};
double tri(const Pt &a, const Pt &b, const Pt &c) { return (b - a).det(c - a); }
int iSP(Pt a, Pt b, Pt c) {
    int s = sig((b - a).det(c - a));
    if (s) return s;
    if (sig((b - a).dot(c - a)) < 0) return -2; // c-a-b
    if (sig((a - b).dot(c - b)) < 0) return +2; // a-b-c
    return 0;
}
int iLL(Pt a, Pt b, Pt c, Pt d) {
    if (sig((b - a).det(d - c))) return 1; // intersect
    if (sig((b - a).det(c - a))) return 0; // parallel
    return -1; // correspond
}
int sz[40];
int g[40][40];
vector<Pt>p[40];
int deg[40];
int col;
int now[40];
int n;
int nd;
int dfs(int a){
	if(a==nd)return 1;
	int nx=-1;
	int ch=0;
	int re=0;
	int me=0;
	for(int i=0;i<n;i++){
		if(~now[i])continue;
		if(col==3&&deg[i]<3)continue;
		int mask=0;
		int ef=0;
		for(int j=0;j<n;j++){
			if(g[i][j]){
				if(~now[j])mask|=(1<<now[j]);
				else ef++;
			}
		}
		int nch=__builtin_popcount(mask);
		if(nch==col)return 0;
		if(nch>ch||(nch==ch&&me<ef)){
			nx=i;ch=nch;me=ef;re=mask;
		}
	}
	for(int i=0;i<col;i++){
		if(re&(1<<i))continue;
		now[nx]=i;
		if(dfs(a+1))return 1;
	}
	now[nx]=-1;
	return 0;
}
int main(){
	int a;
	while(scanf("%d",&a),a){
		n=a;
		for(int i=0;i<a;i++){
			p[i].clear();
			int b;
			scanf("%d",&b);
			sz[i]=b;
			for(int j=0;j<b;j++){
				int x,y;
				scanf("%d%d",&x,&y);
				p[i].push_back(Pt(x,y));
			}
			p[i].push_back(p[i][0]);
		}
		for(int i=0;i<a;i++)deg[i]=0;
		for(int i=0;i<a;i++)for(int j=0;j<a;j++)g[i][j]=0;
		for(int i=0;i<a;i++)for(int j=i+1;j<a;j++){
			bool ok=false;
			for(int k=0;k<sz[i];k++)for(int l=0;l<sz[j];l++){
				if(iLL(p[i][k],p[i][k+1],p[j][l],p[j][l+1])!=-1)continue;
				if(iSP(p[i][k],p[j][l],p[i][k+1])==2)ok=true;
				if(iSP(p[i][k],p[j][l+1],p[i][k+1])==2)ok=true;
				if(iSP(p[j][l],p[i][k],p[j][l+1])==2)ok=true;
				if(iSP(p[j][l],p[i][k+1],p[j][l+1])==2)ok=true;
				if((p[i][k]-p[j][l]).ABS()<EPS&&(p[i][k+1]-p[j][l+1]).ABS()<EPS)ok=true;
				if((p[i][k]-p[j][l+1]).ABS()<EPS&&(p[i][k+1]-p[j][l]).ABS()<EPS)ok=true;
			}
			if(ok){
				g[i][j]=g[j][i]=1;
				deg[i]++;deg[j]++;
			}
		}
		int ans=4;
		for(int i=1;i<4;i++){
			col=i;
			for(int j=0;j<a;j++)now[j]=-1;
			nd=n;
			if(i==3){
				for(int j=0;j<a;j++)if(deg[j]<3)nd--;
			}
			if(dfs(0)){
				ans=i;break;
			}
		}
		printf("%d\n",ans);
	}
}

Measured memory_bytes: 1060