This documentation is automatically generated by online-judge-tools/verification-helper
// verification-helper: PROBLEM http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1254
#include<bits/stdc++.h>
using namespace std;
#define call_from_test
#include "../../graph/chromatic.cpp"
#undef call_from_test
const double EPS = 1e-10;
struct Point{
double x,y;
Point(){}
Point(double x,double y) :x(x),y(y){}
Point operator+(Point p) {return Point(x+p.x,y+p.y);}
Point operator-(Point p) {return Point(x-p.x,y-p.y);}
Point operator*(double k){return Point(x*k,y*k);}
Point operator/(double k){return Point(x/k,y/k);}
};
typedef Point Vector;
typedef vector<Point> Polygon;
double norm(Vector a){
return a.x*a.x+a.y*a.y;
}
double abs(Vector a){
return sqrt(norm(a));
}
double cross(Vector a,Vector b){
return a.x*b.y-a.y*b.x;
}
bool calc(Point a1,Point a2,Point b1,Point b2){
if(abs(cross(a2-a1,b1-a1))>EPS) return 0;
if(abs(cross(a2-a1,b2-a1))>EPS) return 0;
double ml=0;
ml=max(ml,abs(a1-a2));
ml=max(ml,abs(a1-b1));
ml=max(ml,abs(a1-b2));
ml=max(ml,abs(a2-b1));
ml=max(ml,abs(a2-b2));
ml=max(ml,abs(b1-b2));
return (ml+EPS<abs(a1-a2)+abs(b1-b2));
}
signed main(){
cin.tie(0);
ios::sync_with_stdio(0);
int n;
while(cin>>n,n){
vector<Polygon> p(n);
vector<string> name(n);
map<string,int> m;
for(int i=0;i<n;i++){
cin>>name[i];
if(!m.count(name[i])){
int k=m.size();
m[name[i]]=k;
}
int x,y;
while(cin>>x,~x){
cin>>y;
p[i].emplace_back(x,y);
}
}
vector<vector<int> > G(m.size(),vector<int>(m.size(),0));
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(name[i]==name[j]) continue;
for(int k=0;k<(int)p[i].size();k++){
for(int l=0;l<(int)p[j].size();l++){
G[m[name[i]]][m[name[j]]]|=
calc(p[i][k],p[i][(k+1)%p[i].size()],
p[j][l],p[j][(l+1)%p[j].size()]);
G[m[name[j]]][m[name[i]]]|=
calc(p[i][k],p[i][(k+1)%p[i].size()],
p[j][l],p[j][(l+1)%p[j].size()]);
}
}
}
}
cout<<chromatic(G)<<endl;
}
return 0;
}
#line 1 "test/aoj/1254.test.cpp"
// verification-helper: PROBLEM http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1254
#include<bits/stdc++.h>
using namespace std;
#define call_from_test
#line 1 "graph/chromatic.cpp"
#line 3 "graph/chromatic.cpp"
using namespace std;
#endif
//BEGIN CUT HERE
int chromatic(vector< vector<int> > G){
int n=G.size();
if(n==0) return 0;
assert(n<=30);
vector<int> es(n,0);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
es[i]|=G[i][j]<<j;
int s=1<<n;
vector<int> dp(s);
for(int b=0;b<s;b++)
dp[b]=((n-__builtin_popcount(b))&1?-1:1);
auto calc=
[&](const int MOD){
vector<int> res(s);
res[0]=1;
for(int b=1;b<s;b++){
int ctz=__builtin_ctz(b);
res[b]=res[b-(1<<ctz)]+res[(b-(1<<ctz))&~es[ctz]];
if(res[b]>=MOD) res[b]-=MOD;
}
return res;
};
constexpr int MOD1 = 1077563119;
constexpr int MOD2 = 1e9+7;
vector<int> ind1=calc(MOD1);
vector<int> ind2=calc(MOD2);
using ll = long long;
vector<int> dp1=dp,dp2=dp;
for(int i=1;i<n;i++){
ll sum1=0,sum2=0;
for(int b=0;b<s;b++){
dp1[b]=((ll)dp1[b]*ind1[b])%MOD1;
sum1+=dp1[b];
dp2[b]=((ll)dp2[b]*ind2[b])%MOD2;
sum2+=dp2[b];
}
if(sum1%MOD1!=0) return i;
if(sum2%MOD2!=0) return i;
}
return n;
}
//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
#endif
#line 8 "test/aoj/1254.test.cpp"
#undef call_from_test
const double EPS = 1e-10;
struct Point{
double x,y;
Point(){}
Point(double x,double y) :x(x),y(y){}
Point operator+(Point p) {return Point(x+p.x,y+p.y);}
Point operator-(Point p) {return Point(x-p.x,y-p.y);}
Point operator*(double k){return Point(x*k,y*k);}
Point operator/(double k){return Point(x/k,y/k);}
};
typedef Point Vector;
typedef vector<Point> Polygon;
double norm(Vector a){
return a.x*a.x+a.y*a.y;
}
double abs(Vector a){
return sqrt(norm(a));
}
double cross(Vector a,Vector b){
return a.x*b.y-a.y*b.x;
}
bool calc(Point a1,Point a2,Point b1,Point b2){
if(abs(cross(a2-a1,b1-a1))>EPS) return 0;
if(abs(cross(a2-a1,b2-a1))>EPS) return 0;
double ml=0;
ml=max(ml,abs(a1-a2));
ml=max(ml,abs(a1-b1));
ml=max(ml,abs(a1-b2));
ml=max(ml,abs(a2-b1));
ml=max(ml,abs(a2-b2));
ml=max(ml,abs(b1-b2));
return (ml+EPS<abs(a1-a2)+abs(b1-b2));
}
signed main(){
cin.tie(0);
ios::sync_with_stdio(0);
int n;
while(cin>>n,n){
vector<Polygon> p(n);
vector<string> name(n);
map<string,int> m;
for(int i=0;i<n;i++){
cin>>name[i];
if(!m.count(name[i])){
int k=m.size();
m[name[i]]=k;
}
int x,y;
while(cin>>x,~x){
cin>>y;
p[i].emplace_back(x,y);
}
}
vector<vector<int> > G(m.size(),vector<int>(m.size(),0));
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(name[i]==name[j]) continue;
for(int k=0;k<(int)p[i].size();k++){
for(int l=0;l<(int)p[j].size();l++){
G[m[name[i]]][m[name[j]]]|=
calc(p[i][k],p[i][(k+1)%p[i].size()],
p[j][l],p[j][(l+1)%p[j].size()]);
G[m[name[j]]][m[name[i]]]|=
calc(p[i][k],p[i][(k+1)%p[i].size()],
p[j][l],p[j][(l+1)%p[j].size()]);
}
}
}
}
cout<<chromatic(G)<<endl;
}
return 0;
}