#include <bits/stdc++.h>
using namespace std;
#define FOR(i,k,n) for(int i = (int)(k); i < (int)(n); i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(a) a.begin(), a.end()
#define MS(m,v) memset(m,v,sizeof(m))
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-12;
template<class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template<class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/

typedef long double ld;
const ld PI = acos(-1.0);
bool eq(ld a, ld b) { return abs(a - b) < EPS; }
typedef complex<ld> Point;
typedef vector<Point> Polygon;

namespace std
{
	bool operator < (const Point& a, const Point& b)
	{
		return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
	}
}

struct Line
{
	Point a, b;
	Line(Point p, Point q) :a(p), b(q) {};
	Line(ld x1, ld y1, ld x2, ld y2) :a(Point(x1, y1)), b(Point(x2, y2)) {};
};

struct Circle
{
	Point p; ld r;
	Circle(Point a, ld b) :p(a), r(b) {};
};

ld dot(Point a, Point b)
{
	return real(conj(a)*b);
}

ld cross(Point a, Point b)
{
	return imag(conj(a)*b);
}

int ccw(Point a, Point b, Point c)
{
	b -= a; c -= a;
	if (cross(b, c) > EPS) return 1;    //counter cloclwise
	if (cross(b, c) < -EPS) return -1;  //cloclwise
	if (dot(b, c) < 0) return 2;        //c--a--b on line 
	if (norm(b) < norm(c)) return -2;   //a--b--c on line
	return 0;                           //a--c--b on line
}

bool isis_ll(Line l, Line m)
{
	return abs(cross(l.b - l.a, m.b - m.a)) > EPS;
}

bool isis_sp(Line s, Point p)
{
	if (s.a == p || s.b == p) return false;
	return (abs(s.a - p) + abs(s.b - p) - abs(s.b - s.a)) < EPS;
}

bool is_cover(Line s, Line t)
{
	if (isis_ll(s, t)) return false;
	if ((s.a == t.a && s.b == t.b) || (s.a == t.b && t.a == s.b)) return true;
	int cnt = 0;
	if (isis_sp(s, t.a)) cnt++;
	if (isis_sp(s, t.b)) cnt++;
	if (isis_sp(t, s.a)) cnt++;
	if (isis_sp(t, s.b)) cnt++;
	return cnt > 0;
}

typedef int Weight;
struct Edge
{
	int from, to; Weight cost;
	bool operator < (const Edge& e) const { return cost < e.cost; }
	bool operator > (const Edge& e) const { return cost > e.cost; }
};
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;
void add_edge(Graph &g, int from, int to, Weight cost)
{
	g[from].push_back(Edge{ from, to, cost });
}

int ans;
int cnt;
Matrix g;
vi belong;

void solve(int bit, int col)
{
	if (bit == (1 << cnt) - 1)
	{
		chmin(ans, col);
		return;
	}
	if (col == ans) return;
	vi white;
	REP(i, cnt)
	{
		if (!((bit >> i) & 1))
		{
			white.push_back(i);
		}
	}
	REP(i, 1<<white.size())
	{
		if (!i & 1) continue;
		vi use;
		REP(j, white.size())
		{
			if ((i >> j) & 1) use.push_back(white[j]);
		}
		bool f = false;
		REP(j, use.size())REP(k, j)
		{
			if (g[use[j]][use[k]]) f = true;
		}
		if (f) continue;
		int nx = bit;
		REP(j, use.size()) nx |= 1 << use[j];
		solve(nx, col + 1);
	}
}


int main()
{
	cin.sync_with_stdio(false); cout << fixed << setprecision(10);
	int n;
	while (cin >> n, n)
	{
		belong.clear();
		g.clear();
		belong.resize(n);
		ans = 10;
		cnt = 0;
		vector<Polygon> ps(n);
		map<string, int> mp;
		REP(i, n)
		{
			string s; cin >> s;
			if (!mp.count(s))
			{
				mp[s] = cnt;
				cnt++;
			}
			belong[i] = mp[s];
			int a, b;
			while (cin >> a, a >= 0)
			{
				cin >> b;
				ps[i].emplace_back(a, b);
			}
		}
		g.resize(cnt, Array(cnt));
		REP(i, n)REP(j, i)
		{
			if (belong[i] == belong[j]) continue;
			bool f = false;
			REP(k, ps[i].size())REP(l, ps[j].size())
			{
				Line s1(ps[i][k], ps[i][(k + 1) % ps[i].size()]), s2(ps[j][l], ps[j][(l + 1) % ps[j].size()]);
				if (is_cover(s1, s2)) f = true;
			}
			if (f)
			{
				g[belong[j]][belong[i]] = 1;
				g[belong[i]][belong[j]] = 1;
			}
		}
		solve(0, 0);
		cout << ans << endl;
	}
	return 0;
}

Measured memory_bytes: 3336