// #pragma GCC optimize("Ofast")
// #pragma GCC optimize ("unroll-loops")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp> 
using namespace std;
using namespace __gnu_pbds;

typedef long long int ll;
#define endl '\n'
#define ld long double
#define all(a) a.begin(),a.end()
#define int long long
#define pb push_back
#define pii pair <int, int>
#define ff first
#define ss second
#define sz(v) (int)v.size() 
#define UB upper_bound
#define LB lower_bound
#define BP(x) __builtin_popcountll(x)
#define PQS priority_queue <int, vector<int>, greater<int> > 
#define OST tree<pii, null_type,less<pii>, rb_tree_tag,tree_order_statistics_node_update>
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int getRand(int l, int r) {
  uniform_int_distribution<int> uid(l, r);
  return uid(rng);
}

const int INF = 1e18 + 0;
const int mod = 1e9 + 7;
//const int mod = 998244353;

// u = 0, d = 1, l = 2, r, 3;

const int N = 2e5 + 5;

void solve() {

  map <int, vector <pair <int, char> > > left, rght;
  map <int, vector <int> > up, rt, lf, dwn;

  int n; cin >> n;
  int dif = 10000000;
  for(int i = 1; i <= n; i++) {
    int x, y; cin >> x >> y;
    char c; cin >> c;
    left[x-y].pb({x,c});
    rght[x+y].pb({x,c});
    if(c == 'U') {
      up[x].pb(y);
    }
    if(c == 'D') {
      dwn[x].pb(y);
    }
    if(c == 'L') {
      lf[y].pb(x);
    }
    if(c == 'R') {
      rt[y].pb(x);
    }
  }
  
  for(int i = 0; i <= N-5; i++) {
    sort(all(up[i])); sort(all(rt[i])); sort(all(dwn[i])); sort(all(lf[i]));
  }

  // vertical
  for(int i = 0; i <= N-5; i++) {
    if(!up[i].empty() && !dwn[i].empty()) {
      for(auto j : up[i]) {
        auto t = UB(all(dwn[i]), j);
        if(t != dwn[i].end()) {
          dif = min(dif, (*t-j)*5);
        }
      }
    }
  }
  
  // horizontal
  for(int i = 0; i <= N-5; i++) {
    if(!lf[i].empty() && !rt[i].empty()) {
      for(auto j : rt[i]) {
        auto t = UB(all(lf[i]), j);
        if(t != lf[i].end()) {
          dif = min(dif, (*t-j)*5);
        }
      }
    }
  }

  // left diagonal
  for(auto i : left) {
    vector <int> l, r, u, d;
    for(auto j : i.ss) {
      if(j.ss == 'U') u.pb(j.ff);
      if(j.ss == 'D') d.pb(j.ff);
      if(j.ss == 'L') l.pb(j.ff);
      if(j.ss == 'R') r.pb(j.ff);
    }
    sort(all(l)); sort(all(r)); sort(all(d)); sort(all(u));
    
    // left and up /
    for(auto j : u) {
      auto t = UB(all(l), j);
      if(t != l.end()) {
        dif = min(dif, (*t-j)*10);
      }
    }
    for(auto j : d) {
      auto t = LB(all(r), j);
      if(t != r.begin() && !r.empty()) {
        t--;
        dif = min(dif, (j-*t)*10);
      }
    }
  }
  
  // right diagonal
  for(auto i : rght) {
    vector <int> l, r, u, d;
    for(auto j : i.ss) {
      if(j.ss == 'U') u.pb(j.ff);
      if(j.ss == 'D') d.pb(j.ff);
      if(j.ss == 'L') l.pb(j.ff);
      if(j.ss == 'R') r.pb(j.ff);
    }
    sort(all(l)); sort(all(r)); sort(all(d)); sort(all(u));
    
    // left and up /
    for(auto j : u) {
      auto t = LB(all(r), j);
      if(t != r.begin() && !r.empty()) {
        t--;
        dif = min(dif, (j-*t)*10);
      }
    }
    for(auto j : d) {
      auto t = UB(all(l), j);
      if(t != l.end()) {
        dif = min(dif, (*t-j)*10);
      }
    }
  }


  if(dif == 10000000) {
    cout << "SAFE\n"; return;
  } else {
     cout << dif << '\n';
  }
}

signed main() {   
  ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);

  #ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
  #endif
   int t = 1;  //cin >> t;
   for(int i = 1; i <= t; i++) {
   //  cout << "Case #" << i << ": ";
     solve();
  }
}    

/*

*/

Measured memory_bytes: 115584