module revolving_lasers;
version = IO_FILES;
import std.algorithm;
import std.math;
import std.stdio;
import std.typecons;

immutable string PROBLEM_NAME = "revolving-lasers";
immutable int    MAX_S =  360;
immutable int    ADD   =    2;
immutable double EPS   = 1E-9;

alias Tuple !(double, "x", double, "y") point;
alias Tuple !(int, "x", int, "y", int, "a") laser;
alias Tuple !(int, "x", int, "y") coord;

immutable coord NA = coord (-1, -1);
immutable char [3] [3] code =
	[['1', '4', '7'], ['2', '5', '8'], ['3', '6', '9']];

double vp (point a, point b, point c)
{
	return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
}

double sp (point a, point b, point c)
{
	return (b.x - a.x) * (c.x - a.x) + (b.y - a.y) * (c.y - a.y);
}

bool possible (point a, point b, point c, point u, point v)
{
	if ((sp (a, b, u) < -EPS) && (sp (a, b, v) < -EPS) &&
	    (sp (a, c, u) < -EPS) && (sp (a, c, v) < -EPS))
	{
		return true;
	}
	double x = vp (a, b, u);
	double y = vp (a, c, v);
	return (abs (y) > EPS) && (x * y > EPS);
}

string solve (laser [] p)
{
	int n = p.length;

	int xlo = 0;
	int xhi = 0;
	int ylo = 0;
	int yhi = 0;
	foreach (i; 0..n)
	{
		xlo = min (xlo, p[i].x - ADD);
		xhi = max (xhi, p[i].x + ADD);
		ylo = min (ylo, p[i].y - ADD);
		yhi = max (yhi, p[i].y + ADD);
	}
	int xsize = xhi - xlo + 1;
	int ysize = yhi - ylo + 1;

	auto q = new point [n];
	foreach (i; 0..n)
	{
		q[i] = point (p[i].x - xlo, p[i].y - ylo);
	}

	auto r = new point [] [] (MAX_S + 1, n);
	foreach (s; 0..MAX_S + 1)
	{
		foreach (i; 0..n)
		{
			double angle = 0.25 + p[i].a * s * 1.0 / MAX_S;
			angle *= 2.0 * PI;
			r[s][i] = point (p[i].x - xlo + cos (angle),
			                 p[i].y - ylo + sin (angle));
		}
	}

	auto f = new coord [] [] [] (MAX_S + 1, xsize, ysize);
	foreach (s; 0..MAX_S + 1)
		foreach (x; 0..xsize)  foreach (y; 0..ysize)
		{
			f[s][x][y] = NA;
		}
	f[0][0 - xlo][0 - ylo] = coord (0 - xlo, 0 - ylo);
	foreach (s; 0..MAX_S)
	{
		foreach (x; 0..xsize)  foreach (y; 0..ysize)
		if (f[s][x][y] != NA)
		{
			debug {writefln ("s = %s, (%s, %s)", s, x, y);}
			auto u = point (x, y);
			foreach (dx; -1..+2)  dy_loop: foreach (dy; -1..+2)
			{
				int nx = x + dx;
				int ny = y + dy;
				if (nx < 0 || nx >= xsize ||
				    ny < 0 || ny >= ysize)
				{
					continue dy_loop;
				}
				foreach (i; 0..n)
				{
					if ((nx == p[i].x) && (ny == p[i].y))
					{
						continue dy_loop;
					}
				}
				auto v = point (nx, ny);
				foreach (i; 0..n)
				{
					if (!possible (q[i], r[s][i],
					               r[s + 1][i],
					               u, v))
					{
						continue dy_loop;
					}
				}
				debug {writefln ("to (%s, %s)", nx, ny);}
				f[s + 1][nx][ny] = coord (x, y);
			}
		}
	}

	debug {writeln (f[MAX_S][0 - xlo][0 - ylo]);}
	if (f[MAX_S][0 - xlo][0 - ylo] == NA)
	{
		return "None";
	}

	char [] res;
	auto u = coord (0 - xlo, 0 - ylo);
	foreach_reverse (s; 0..MAX_S)
	{
		auto v = f[s + 1][u.x][u.y];
		res ~= code[u.x - v.x + 1][u.y - v.y + 1];
		u = v;
	}
	res.reverse ();
	return cast (string) res;
}

void main ()
{
	version (IO_FILES)
	{
		stdin  = File (PROBLEM_NAME ~ ".in",  "rt");
		stdout = File (PROBLEM_NAME ~ ".out", "wt");
	}

	int n;
	while (readf (" %s", &n) > 0)
	{
		auto p = new laser [n];
		foreach (i; 0..n)
		{
			readf (" %s %s %s", &p[i].x, &p[i].y, &p[i].a);
		}
		writeln (solve (p));
		stdout.flush ();
	}
}
