unittest
{
	assert( [ "2", "11 1 U", "11 47 D" ].solve == "230" );
	assert( [ "4", "20 30 U", "30 20 R", "20 10 D", "10 20 L" ].solve == "SAFE" );
	assert( [ "8", "168 224 U", "130 175 R", "111 198 D", "121 188 L", "201 116 U", "112 121 R", "145 239 D", "185 107 L" ].solve == "100" );
}



import std.algorithm;
import std.conv;
import std.range;
import std.stdio;
import std.typecons;

void main()
{
	stdin.byLineCopy.solve.writeln;
}

auto solve( Range )( Range input )
if( isInputRange!Range && is( ElementType!Range == string ) )
{
	auto n = input.front.to!( long );
	auto xyus = new Tuple!( long, long, dchar )[ n ];
	foreach( ref xyu; xyus )
	{
		input.popFront;
		auto as = input.front.split;
		xyu = tuple( as[ 0 ].to!( long ), as[ 1 ].to!( long ), as[ 2 ].to!( dchar ) );
	}
	
	// 衝突判定用基準値を作成
	long[][ long ] udss;
	long[][ long ] urss;
	long[][ long ] ulss;
	long[][ long ] duss;
	long[][ long ] drss;
	long[][ long ] dlss;
	long[][ long ] rlss;
	long[][ long ] russ;
	long[][ long ] rdss;
	long[][ long ] lrss;
	long[][ long ] ldss;
	long[][ long ] luss;
	foreach( i, xyu; xyus )
	{
		auto a = xyu[ 1 ] + xyu[ 0 ];
		auto b = xyu[ 1 ] - xyu[ 0 ];
		final switch( xyu[ 2 ] )
		{
			case 'U':
				udss[ xyu[ 0 ] ] ~= i.signed;
				urss[ a ] ~= i.signed;
				ulss[ b ] ~= i.signed;
				break;
			
			case 'D':
				duss[ xyu[ 0 ] ] ~= i.signed;
				drss[ b ] ~= i.signed;
				dlss[ a ] ~= i.signed;
				break;
			
			case 'R':
				rlss[ xyu[ 1 ] ] ~= i.signed;
				russ[ a ] ~= i.signed;
				rdss[ b ] ~= i.signed;
				break;
			
			case 'L':
				lrss[ xyu[ 1 ] ] ~= i.signed;
				luss[ b ] ~= i.signed;
				ldss[ a ] ~= i.signed;
				break;
		}
	}
	
	auto ans = long.max;
	
	// UとDの衝突を判定
	foreach( k, uds; udss )
	{
		if( k !in duss ) continue;
		foreach( ud; uds )
		{
			foreach( du; duss[ k ] )
			{
				auto t = ( xyus[ du ][ 1 ] - xyus[ ud ][ 1 ] ) * 10 / 2;
				if( 0 < t ) ans = min( ans, t );
			}
		}
	}
	
	// RとLの衝突を判定
	foreach( k, rls; rlss )
	{
		if( k !in lrss ) continue;
		foreach( rl; rls )
		{
			foreach( lr; lrss[ k ] )
			{
				auto t = ( xyus[ lr ][ 0 ] - xyus[ rl ][ 0 ] ) * 10 / 2;
				if( 0 < t ) ans = min( ans, t );
			}
		}
	}
	
	// UとRの衝突を判定
	foreach( k, urs; urss )
	{
		if( k !in russ ) continue;
		foreach( ur; urs )
		{
			foreach( ru; russ[ k ] )
			{
				auto t = ( xyus[ ur ][ 0 ] - xyus[ ru ][ 0 ] ) * 10;
				if( 0 < t ) ans = min( ans, t );
			}
		}
	}
	
	// UとLの衝突を判定
	foreach( k, uls; ulss )
	{
		if( k !in luss ) continue;
		foreach( ul; uls )
		{
			foreach( lu; luss[ k ] )
			{
				auto t = ( xyus[ lu ][ 0 ] - xyus[ ul ][ 0 ] ) * 10;
				if( 0 < t ) ans = min( ans, t );
			}
		}
	}
	
	// DとRの衝突を判定
	foreach( k, drs; drss )
	{
		if( k !in rdss ) continue;
		foreach( dr; drs )
		{
			foreach( rd; rdss[ k ] )
			{
				auto t = ( xyus[ dr ][ 0 ] - xyus[ rd ][ 0 ] ) * 10;
				if( 0 < t ) ans = min( ans, t );
			}
		}
	}
	
	// DとLの衝突を判定
	foreach( k, dls; dlss )
	{
		if( k !in ldss ) continue;
		foreach( dl; dls )
		{
			foreach( ld; ldss[ k ] )
			{
				auto t = ( xyus[ ld ][ 0 ] - xyus[ dl ][ 0 ] ) * 10;
				if( 0 < t ) ans = min( ans, t );
			}
		}
	}
	
	return ( ans == long.max ) ? "SAFE" : ans.to!( string );
}
