#include <algorithm>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;

constexpr double EPS = 1e-9;

struct point {
	double x, y;
	point(double x_ = 0.0, double y_ = 0.0):x(x_), y(y_) {}
	point(const point& p):x(p.x), y(p.y) {}

	point operator+ (const point& p) const {
		return point(x + p.x, y + p.y);
	}

	point operator- (const point& p) const {
		return point(x - p.x, y - p.y);
	}

	point operator* (double s) const {
		return point(x * s, y * s);
	}

	point operator* (const point& p) const {
		return point(x * p.x - y * p.y, x * p.y + y * p.x);
	}

	point operator/ (double s) const {
		return point(x / s, y / s);
	}

	bool operator< (const point& p) const {
		return x + EPS < p.x || (abs(x - p.x) < EPS && y + EPS < p.y);
	}

	bool operator== (const point& p) const {
		return abs(x - p.x) < EPS && abs(y - p.y) < EPS;
	}
};

double dot(const point& a, const point& b) {
	return a.x * b.x + a.y * b.y;
}

double cross(const point& a, const point& b) {
	return a.x * b.y - a.y * b.x;
}

double norm(const point& p) {
	return p.x * p.x + p.y * p.y;
}

int ccw(const point& a, point b, point c) {
	b = b - a;
	c = c - a;
	const double tmp = cross(b, c);
	if(tmp > EPS) return 1; // ccw
	if(tmp < -EPS) return -1; // cw
	if(dot(b, c) < 0) return 2; // c, a, b 順に一直線上
	if(norm(b) < norm(c)) return -2; // a, b, c 順に一直線上
	return 0; //a, c, b 順で一直線上
}

struct segment {
	point a, b;
	segment(point a_, point b_):a(a_), b(b_) {}
};

typedef vector<point> polygon;

bool intersect(const segment &s, const segment &t) {
	return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0
		&& ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

bool intersect(const polygon &P, const polygon &Q) {
	point p1 = P.back();
	for(const auto &p2 : P) {
		const segment s1(p1 + (p2 - p1) * EPS, p2 + (p1 - p2) * EPS);

		point q1 = Q.back();
		for(const auto &q2 : Q) {
			const segment s2(q1 + (q2 - q1) * EPS, q2 + (q1 - q2) * EPS);
			if(intersect(s1, s2)) return true;
			q1 = q2;
		}
		p1 = p2;
	}
	return false;
}

bool check(int num, const vector<vector<int>> &G) {
	vector<int> colors(G.size(), -1);

	function<bool(int)> dfs = [&](int v) {
		if(v == G.size()) return true;
		if(G[v].empty()) return dfs(v + 1);

		vector<bool> can(num, true);
		for(const auto &to : G[v]) {
			if(colors[to] != -1) can[colors[to]] = false;
		}

		for(int c = 0; c < num; ++c) {
			if(!can[c]) continue;
			colors[v] = c;
			if(dfs(v + 1)) return true;
		}
		colors[v] = -1;
		return false;
	};

	return dfs(0);
}

int calc(const vector<vector<int>> &G) {
	for(int num = 1;; ++num) {
		if(check(num, G)) return num;
	}
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);

	for(int n; cin >> n && n;) {
		unordered_map<string, int> converter;
		vector<int> idx(n);
		vector<polygon> territories;
		territories.reserve(n);

		for(int i = 0; i < n; ++i) {
			string name;
			cin >> name;
			if(!converter.count(name)) converter.insert({name, converter.size()});
			idx[i] = converter[name];
			polygon P;
			for(int x, y; cin >> x && x != -1;) {
				cin >> y;
				P.emplace_back(x, y);
			}
			territories.emplace_back(P);
		}

		const int V = converter.size();
		vector<vector<int>> G(V);

		for(int i = 0; i < n; ++i) {
			for(int j = i + 1; j < n; ++j) {
				if(idx[i] == idx[j]) continue;
				if(intersect(territories[i], territories[j])) {
					G[idx[i]].emplace_back(idx[j]);
					G[idx[j]].emplace_back(idx[i]);
				}
			}
		}

		for(auto &vec : G) {
			sort(vec.begin(), vec.end());
			vec.erase(unique(vec.begin(), vec.end()), vec.end());
		}

		cout << calc(G) << endl;
	}

	return EXIT_SUCCESS;
}

Measured memory_bytes: 1272