//#include <ext/pb_ds/assoc_container.hpp> 
 //#include <ext/pb_ds/tree_policy.hpp>
//#include <bits/stdc++.h>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <cstring>
#include <vector>
#include <deque>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <iterator>
#include <functional>
#include <limits>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <cassert>
#include <unordered_map>
#include <unordered_set>
#include <stack>
using namespace std;
#define IOS ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define trace(x) cerr << #x << ": " << x << " " << endl;

typedef int64_t ll;
 
#define endl '\n'
#define int ll
ll mod=1e9+7;
ll mod1=1e9+5;
ll power(ll a,ll b)
{
    if(b==0) return 1;
    else if(b%2==0)
        return power(((((a)%mod)*((a)%mod))%mod),b/2)%mod;
    else return (((a)%mod)*(power(((((a)%mod)*((a)%mod))%mod),b/2)%mod))%mod;
}
inline ll inverse(ll a,ll md) {
  a %= md;
  if (a < 0) a += md;
  ll b = md, u = 0, v = 1;
  while (a) {
    ll t = b / a;
    b -= t * a; swap(a, b);
    u -= t * v; swap(u, v);
  }
  assert(b == 1);
  if (u < 0) u += md;
  return u;
}
  
  
 //using namespace __gnu_pbds;
 //#define ordered_set tree<pair<int,int>, null_type,less<pair<int,int>>, rb_tree_tag,tree_order_statistics_node_update>
//find_by_order(k)  returns iterator to kth element starting from 0;
//order_of_key(k) returns count of elements strictly smaller than k;
//erase,insert same as normal set
// mt19937 mrand(chrono::high_resolution_clock::now().time_since_epoch().count()); for randomized solution
const int ce=1e9+7;
ll fast_mod(ll input)
{
    return input < ce ? input : input%ce;
}

int32_t main()
{
    IOS

    int n;
    cin>>n;
    map<int,set<int>> m,m1,m3,m4;
    map<int,set<int>> m5,m6,m7,m8;
    for(int i=1;i<=n;i++)
    {
    	int x,y;
    	cin>>x>>y;
    	char ch;
    	cin>>ch;
    	if(ch=='U')
    	{
    		m[x].insert(y);
    		m5[x+y].insert(y);
    		m7[x-y].insert(y);
    	}
    	if(ch=='D')
    	{
    		m1[x].insert(y);
    		m6[x-y].insert(y);
    		m8[x+y].insert(y);
    	}
    	if(ch=='R')
    	{
    		m3[y].insert(x);
    	}
    	if(ch=='L')
    	{
    		m4[y].insert(x);
    	}
    }
    int ans=1e13;
    for(auto i:m)
    {
    	if(m1[i.first].size()==0)
    		continue;
    	for(auto j:i.second)
    	{
    		auto it=m1[i.first].lower_bound(j);
    		if(it==m1[i.first].end())
    			continue;
    		ans=min(ans,abs((*it-j))*5);
    	}
    }
    for(auto i:m3)
    {
    	
    	for(auto j:i.second)
    	{
    		int sum=j+i.first;
    		auto it1=m5[sum].lower_bound(i.first);
    		if(it1!=m5[sum].begin() and m5[sum].size()!=0)
    		{
    			it1--;
    			ans=min(ans,abs(i.first-*it1)*10);
    		}
    		sum=j-i.first;
    		auto it2=m6[sum].lower_bound(i.first);
    		if(it2!=m6[sum].end() and m6[sum].size()!=0)
    		{
    			ans=min(ans,abs(i.first-*it2)*10);
    		}
    		if(m4[i.first].size()==0)
    		continue;
    		auto it=m4[i.first].lower_bound(j);
    		if(it==m4[i.first].end())
    			continue;
    		ans=min(ans,abs((j-*it))*5);
    	}
    }
    for(auto i:m4)
    {
    	
    	for(auto j:i.second)
    	{
    		int sum=j-i.first;
    		auto it1=m7[sum].lower_bound(i.first);
    		if(it1!=m7[sum].begin() and m7[sum].size()!=0)
    		{
    			it1--;
    			ans=min(ans,abs(i.first-*it1)*10);
    		}
    		sum=j+i.first;
    		auto it2=m8[sum].lower_bound(i.first);
    		if(it2!=m8[sum].end() and m8[sum].size()!=0)
    		{
    			ans=min(ans,abs(i.first-*it2)*10);
    		}
    	}
    }
    if(ans==1e13)
    {
    	cout<<"SAFE"<<endl;
    	return 0;
    }

    cout<<abs(ans)<<endl;
}       


Measured memory_bytes: 87200