#include<cstdio>
#include<vector>
#include<complex>
#include<cmath>
#include<queue>
#include<utility>
#include<algorithm>

using namespace std;

typedef complex<double> Point;
typedef complex<double> Vector;
typedef vector<Point> Polygon;

typedef pair<int,int> P;

const double eps=1e-9;

template<class T> bool eq(T a,T b){
	return abs(a-b)<eps;
}

template<class T> int sgn(T a){
	if(eq(a,0.0)) return 0;
	if(a>0) return 1;
	return -1;
}

double crP(Vector a,Vector b){
	return (conj(a)*b).imag();
}

bool onSeg(Point a,Point b,Point c){
	return eq(abs(a-b),abs(a-c)+abs(b-c));
}

bool onLine(Point a,Point b,Point c){
	return onSeg(a,b,c)||onSeg(b,c,a)||onSeg(c,a,b);
}

bool cmp(Point a,Point b){
	if(!eq(a.real(),b.real())){
		return a.real()<b.real();
	}
	return a.imag()<b.imag();
}

bool check(Polygon a,Polygon b){
	for(int i=0;i<a.size();i++) for(int j=0;j<b.size();j++){
		Point a1=a[i],a2=a[(i+1)%a.size()];
		Point b1=b[j],b2=b[(j+1)%b.size()];
		bool flg=onLine(a1,a2,b1)&&onLine(a1,a2,b2);
		if(flg==false) continue;
		if(cmp(a1,a2)==false) swap(a1,a2);
		if(cmp(b1,b2)==false) swap(b1,b2);
		if(eq(a1,b1)&&eq(a2,b2)) return true;
		if(eq(a1,b2)||eq(a2,b1)) continue;
		if(onSeg(a1,a2,b1)||onSeg(a1,a2,b2)||onSeg(b1,b2,a1)||onSeg(b1,b2,a1)) return true;
	}
	return false;
}

vector<Polygon> polys;

void readPoly(){
	int N;
	Polygon poly;
	scanf("%d",&N);
	for(int i=0;i<N;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		poly.push_back(Point(x,y));
	}
	polys.push_back(poly);
}

void output(vector<int> vec){
	for(int i=0;i<vec.size();i++){
		printf("%d ",vec[i]);
	}
	printf("\n");
}

vector<int> G[35];
int N;

void getGraph(){
	for(int i=0;i<N;i++) for(int j=i+1;j<N;j++){
		if(check(polys[i],polys[j])){
			G[i].push_back(j);
			G[j].push_back(i);
//			printf("connect %d %d\n",i,j);
		}
	}
}

bool check1(){
	for(int i=0;i<N;i++) if(G[i].size()>0) return false;
	return true;
}

int color[35];
bool check2(){
	queue<int> que;
	for(int i=0;i<N;i++) color[i]=-1;
	for(int i=0;i<N;i++){
		if(color[i]!=-1) continue;
		que.push(i);
		color[i]=0;
		while(!que.empty()){
			int v=que.front();
			que.pop();
			for(int j=0;j<G[v].size();j++){
				int u=G[v][j];
				if(color[u]==color[v]) return false;
				if(color[u]==-1){
					color[u]=color[v]^1;
					que.push(u);
				}
			}
		}
	}
	return true;
}

vector<vector<int> > ind;
bool used[35];
void dfs(vector<int> &cur){
	vector<P> rem;
	for(int i=0;i<N;i++) if(used[i]==false){
		int cnt=0;
		for(int j=0;j<G[i].size();j++){
			if(used[G[i][j]]==false) cnt++;
		}
		rem.push_back(P(cnt,i));
	}
	if(rem.size()==0){
		ind.push_back(cur);
		return;
	}
	sort(rem.begin(),rem.end());
	int v=rem[0].second;
	vector<int> cands;
	cands.push_back(v);
	for(int i=0;i<G[v].size();i++){
		if(used[G[v][i]]==false) cands.push_back(G[v][i]);
	}
	for(int i=0;i<cands.size();i++){
		int v=cands[i];
		vector<int> flipped;
		flipped.push_back(v);
		used[v]=true;
		for(int j=0;j<G[v].size();j++){
			int u=G[v][j];
			if(used[u]==false){
				used[u]=true;
				flipped.push_back(u);
			}
		}
		cur.push_back(v);
		dfs(cur);
		cur.pop_back();
		for(int j=0;j<flipped.size();j++){
			used[flipped[j]]=false;
		}
	}
}

bool check3(){
	vector<int> vec;
	dfs(vec);
//	for(int i=0;i<ind.size();i++){
//		output(ind[i]);
//	}
	int color[35];
	for(int i=0;i<ind.size();i++){
		for(int j=0;j<N;j++) color[j]=-1;
		for(int j=0;j<ind[i].size();j++) color[ind[i][j]]=2;
		queue<int> que;
		bool ok=true;
		for(int j=0;j<N;j++){
			if(color[j]!=-1) continue;
			color[j]=0;
			que.push(j);
			while(!que.empty()){
				int v=que.front();
				que.pop();
				for(int k=0;k<G[v].size();k++){
					int u=G[v][k];
					if(color[u]==color[v]){
						ok=false;
						goto nxtInd;
					}
					if(color[u]==-1){
						color[u]=color[v]^1;
						que.push(u);
					}
				}
			}
		}
		if(ok) return true;
		nxtInd:;
	}
	return false;
}

void solve(){
	if(check1()){
		printf("1\n");
	}else if(check2()){
		printf("2\n");
	}else if(check3()){
		printf("3\n");
	}else{
		printf("4\n");
	}
}

void init(){
	polys.clear();
	for(int i=0;i<35;i++) G[i].clear();
	ind.clear();
	for(int i=0;i<35;i++) used[i]=false;
}

int main(){
	while(true){
		init();
		scanf("%d",&N);
		if(N==0) break;
//		printf("----\n");
		for(int i=0;i<N;i++) readPoly();
		getGraph();
		solve();
	}
	return 0;
}

Measured memory_bytes: 47952