#include <bits/stdc++.h>

#define _overload(_1,_2,_3,name,...) name
#define _rep(i,n) _range(i,0,n)
#define _range(i,a,b) for(int i=int(a);i<int(b);++i)
#define rep(...) _overload(__VA_ARGS__,_range,_rep,)(__VA_ARGS__)

#define _rrep(i,n) _rrange(i,n,0)
#define _rrange(i,a,b) for(int i=int(a)-1;i>=int(b);--i)
#define rrep(...) _overload(__VA_ARGS__,_rrange,_rrep,)(__VA_ARGS__)

#define _all(arg) begin(arg),end(arg)
#define uniq(arg) sort(_all(arg)),(arg).erase(unique(_all(arg)),end(arg))
#define getidx(ary,key) lower_bound(_all(ary),key)-begin(ary)
#define clr(a,b) memset((a),(b),sizeof(a))
#define bit(n) (1LL<<(n))
#define popcount(n) (__builtin_popcountll(n))

template<class T>bool chmax(T &a, const T &b) { return (a<b)?(a=b,1):0;}
template<class T>bool chmin(T &a, const T &b) { return (b<a)?(a=b,1):0;}

using namespace std;

using ll=long long;
inline int sgn(const ll& r){ return (r > 0) - (r < 0);}

using P=complex<ll>;
using L=struct{P s,t;};

namespace std{
	bool operator >  (const P& a,const P& b){ return sgn(real(a-b))?real(a-b)>0:sgn(imag(a-b))>0;}
	bool operator <  (const P& a,const P& b){ return sgn(real(a-b))?real(a-b)<0:sgn(imag(a-b))<0;}
	bool operator == (const P& a,const P& b){ return sgn(real(a-b))==0 && sgn(imag(a-b))==0;}
}

bool operator <  (const L& a,const L& b){ return a.s==b.s?a.t<b.t:a.s<b.s;}
bool operator == (const L& a,const L& b){ return a.s==b.s&&a.t==b.t;}

inline ll dot(P o,P a,P b){a-=o,b-=o; return real(conj(a)*b);}
inline ll det(P o,P a,P b){a-=o,b-=o; return imag(conj(a)*b);}

enum CCW{ LEFT = 1,RIGHT = 2,BACK = 4,FRONT = 8,ON = 16};
inline int ccw(P o,P a, P b) {
	if (sgn(det(o,a,b)) > 0) return LEFT;    // counter clockwise
	if (sgn(det(o,a,b)) < 0) return RIGHT;   // clockwise
	if (sgn(dot(o,a,b)) < 0) return BACK;    // b--base--a on line
	if (sgn(norm(a-o)-norm(b-o)) < 0) return FRONT;   // base--a--b on line
	return ON;// base--b--a on line  semnet determination betwenn a and b 
}

inline bool cross(L a,L b){
	if(det(P(0,0),a.t-a.s,b.t-b.s)!=0) return false;
	if((ccw(a.s,a.t,b.s)&28)==0) return false;

	using state=tuple<P,int>;

	vector<state> ary={state(a.s,0),state(a.t,0),state(b.s,1),state(b.t,1)};
	sort(_all(ary));
	if(get<1>(ary[0])==get<1>(ary[1])) return false;
	if(get<0>(ary[1])==get<0>(ary[2])) return false;
	return true;
}

bool cgraph[10][10];
int color[10];
int dfs(int v,int n,int c){
	if(v==n) return c;
	set<int> used;
	rep(i,v) if(cgraph[v][i]) used.insert(color[i]);

	int ret=10;
	rep(i,c+1){
		if(used.find(i)!=used.end()) continue;
		color[v]=i;
		chmin(ret,dfs(v+1,n,max(i+1,c)));
		color[v]=-1;
	}

	return ret;
}

int main(void){
	int n;
	while(cin >> n,n){
		set<L> pol[110];
		map<string,vector<int>> conv;
		rep(i,n){
			string s;
			cin >> s; 
			conv[s].push_back(i);

			int x[110],y[110],m=0;

			while(1){
				cin >> x[m];
				if(x[m]==-1) break;
				cin >> y[m++];
			}

			rep(j,m){
				P a=P(x[j],y[j]);
				P b=P(x[(j+1)%m],y[(j+1)%m]);
				if(a>b) swap(a,b);
				pol[i].insert(L({a,b})); 
			}
		}

		vector<string> ary;
		for(auto &it:conv) ary.push_back(it.first);
		const int m=ary.size();

		bool graph[110][110];
		clr(graph,0);
		
		rep(i,n)rep(j,i){
			for(auto &line:pol[i]) for(auto &line2:pol[j]){
				if(cross(line,line2))
					graph[i][j]=graph[j][i]=true;
			}
		}

		clr(cgraph,0);
		rep(i,m)rep(j,i){
			cgraph[i][j]=cgraph[j][i]=false;
			for(auto &v:conv[ary[i]]) for(auto &v2:conv[ary[j]]) if(graph[v][v2]) cgraph[i][j]=cgraph[j][i]=true;
		}

		// rep(i,m){
		// 	rep(j,m) cout << cgraph[i][j] << " ";
		// 	cout << endl;
		// }
		cout << dfs(0,m,0) << endl;
	}	
	return 0;
}

Measured memory_bytes: 3264