#pragma GCC target ("avx2")
#pragma GCC optimize ("unroll-loops")
#pragma GCC optimize ("O3")
#include "bits/stdc++.h"
#include <unordered_set>
#include <unordered_map>
#include <random>
using namespace std;
typedef long long ll;
const ll MOD = 1'000'000'007LL; /*998'244'353LL;*/
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for(int (i)=0; (i)<(n); (i)++)
const int dx[4]={ 1,0,-1,0 };
const int dy[4]={ 0,1,0,-1 };

int N;
int X[200005], Y[200005];
char C[200005];

vector<int> U[200005], D[200005], L[200005], R[200005];
unordered_map<char, vector<int>> v;
unordered_map<int, vector<int>> b;

signed main(){
    cin >> N;
    rep(i, N){
        cin >> X[i] >> Y[i] >> C[i];
        v[C[i]].pb(i);
        if(C[i] == 'U') U[X[i]].pb(Y[i]);
        if(C[i] == 'D') D[X[i]].pb(Y[i]);
        if(C[i] == 'L') L[Y[i]].pb(X[i]);
        if(C[i] == 'R') R[Y[i]].pb(X[i]);
    }
    sort(all(v['U']));
    sort(all(v['D']));
    sort(all(v['L']));
    sort(all(v['R']));

    int ans = INT_MAX;

    // UD
    rep(i, 200001){
        sort(all(U[i]));
        sort(all(D[i]));
        rep(j, U[i].size()){
            int idx = lower_bound(all(D[i]), U[i][j]) - D[i].begin();
            if(idx < D[i].size()){
                ans = min(ans, (D[i][idx]-U[i][j])*5);
            }
        }
    }

    // LR
    rep(i, 200001){
        sort(all(L[i]));
        sort(all(R[i]));
        rep(j, R[i].size()){
            int idx = lower_bound(all(L[i]), R[i][j]) - L[i].begin();
            if(idx < L[i].size()){
                ans = min(ans, (L[i][idx]-R[i][j])*5);
            }
        }
    }

    // LU
    b.clear();
    rep(i, N){
        if(C[i] == 'L'){
            b[Y[i]-X[i]].pb(X[i]);
        }
    }
    for(int i=-200005; i<=400005; i++){
        if(b[i].size()) sort(all(b[i]));
    }
    rep(i, N){
        if(C[i] == 'U'){
            if(b[Y[i]-X[i]].size()){
                int idx = lower_bound(all(b[Y[i]-X[i]]), X[i]) - b[Y[i]-X[i]].begin();
                if(idx < b[Y[i]-X[i]].size()) ans = min(ans, (b[Y[i]-X[i]][idx]-X[i])*10);
            }
        }
    }

    // LD
    b.clear();
    rep(i, N){
        if(C[i] == 'L'){
            b[Y[i]+X[i]].pb(X[i]);
        }
    }
    for(int i=-200005; i<=400005; i++){
        if(b[i].size()) sort(all(b[i]));
    }
    rep(i, N){
        if(C[i] == 'D'){
            if(b[Y[i]+X[i]].size()){
                int idx = lower_bound(all(b[Y[i]+X[i]]), X[i]) - b[Y[i]+X[i]].begin();
                if(idx < b[Y[i]+X[i]].size()) ans = min(ans, (b[Y[i]+X[i]][idx]-X[i])*10);
            }
        }
    }

    // UR
    b.clear();
    rep(i, N){
        if(C[i] == 'U'){
            b[Y[i]+X[i]].pb(X[i]);
        }
    }
    for(int i=-200005; i<=400005; i++){
        if(b[i].size()) sort(all(b[i]));
    }
    rep(i, N){
        if(C[i] == 'R'){
            if(b[Y[i]+X[i]].size()){
                int idx = lower_bound(all(b[Y[i]+X[i]]), X[i]) - b[Y[i]+X[i]].begin();
                if(idx < b[Y[i]+X[i]].size()) ans = min(ans, (b[Y[i]+X[i]][idx]-X[i])*10);
            }
        }
    }

    // DR
    b.clear();
    rep(i, N){
        if(C[i] == 'D'){
            b[Y[i]-X[i]].pb(X[i]);
        }
    }
    for(int i=-200005; i<=400005; i++){
        if(b[i].size()) sort(all(b[i]));
    }
    rep(i, N){
        if(C[i] == 'R'){
            if(b[Y[i]-X[i]].size()){
                int idx = lower_bound(all(b[Y[i]-X[i]]), X[i]) - b[Y[i]-X[i]].begin();
                if(idx < b[Y[i]-X[i]].size()) ans = min(ans, (b[Y[i]-X[i]][idx]-X[i])*10);
            }
        }
    }

    if(ans == INT_MAX) cout << "SAFE" << endl;
    else cout << ans << endl;
}

Measured memory_bytes: 73124