#include <bits/stdc++.h>
using namespace std;
typedef pair<long long,long long> P;

int main (){
    long long N = 0;
    cin >> N;//飛んでいる飛行機
    vector<long long> X(N,0);//i個目の飛行機のx座標
    vector<long long> Y(N,0);//i個目の飛行機のy座標
    vector<char> U(N,0);//i個目の飛行機の進行方向
    vector<priority_queue<pair<long long,char> > > ru(400001);//あるx座標内でのy座標と各座標の機体の進行方向
    vector<priority_queue<pair<long long,char> > > rd(400001);//あるx座標内でのy座標と各座標の機体の進行方向
    vector<priority_queue<pair<long long,char> > > s(200001);//あるx座標内でのy座標と各座標の機体の進行方向
    vector<priority_queue<pair<long long,char> > > v(200001);//あるy座標内でのx座標と各座標の機体の進行方向
    pair<long long,char> tempair;//ペアとして上の二つの配列に代入するための一時的な


    for(long long i = 0; i < N; i++) {
    cin >> X.at(i);//i個目の飛行機のx座標の代入
    cin >> Y.at(i);//i個目の飛行機のy座標の代入
    cin >> U.at(i);//i個目の飛行機の進行方向の代入
    }

    
    for (long long i = 0; i < N; i++)
    {
        tempair.first = X.at(i);
        tempair.second = U.at(i);
        ru.at(200000 -X.at(i) + Y.at(i)).push(tempair);//i個目の飛行機が右上45度または左下にいる時の切片の配列に自機の情報を入力
        rd.at(X.at(i) + Y.at(i)).push(tempair);//上の右下，左上で考えた場合
    }

    for (long long i = 0; i < N; i++)
    {
        if (U.at(i) == 'U' || U.at(i) == 'D')//i個目の飛行機が上下に動くときは，初期値のx座標番目の配列に優先キューに進行方向（上下）を紐付けて追加
        {
            tempair.first = Y.at(i);
            tempair.second = U.at(i);
            s.at(X.at(i)).push(tempair);
        } else if (U.at(i) == 'R' || U.at(i) == 'L')//上の左右バージョン
        {
            tempair.first = X.at(i);
            tempair.second = U.at(i);
            v.at(Y.at(i)).push(tempair);
        }
    }


    long long ans = 1000000000;//答え用の配列，最小時間を求めたいので大きめの値で初期化
    long long memo = 5000000;//大きい方から見て行って最初に小さい方にぶつかろうとする値で初期化
    long long memomemo = 5000000;//上と同じ
    for (long long i = 0; i < 200001; i++)//水平方向，または垂直方向の位置関係についての衝突を見ていく
    {
        memomemo = 5000000;
        memo = 5000000;
        while(!s.at(i).empty()) {//x座標がiの飛行機のy座標が大きい順に見て行って下に向かう飛行機を更新し続け，上に向かう飛行機を発見したらその座標に一番近い下に向かう飛行機との距離から衝突までの時間を算出する
            if (s.at(i).top().second == 'D')//下に向かう飛行機を見つけるたびに値を更新
            {
                memo = s.at(i).top().first;
                s.at(i).pop();
            }
            else if (memo != 5000000 && s.at(i).top().second == 'U')//一番最初に衝突するのは，上に登る飛行機より上方かつ下に向かっている飛行機で一番低い座標にある飛行機なのでmemoとの距離を取る
            {
                ans = min(ans,5*abs(memo - s.at(i).top().first));//今までにえた衝突までの時間と短い方を現時点での解とする
                s.at(i).pop();
            }
            else if (memo == 5000000 && s.at(i).top().second == 'U')//このときの機体より上方に下へ向かう機体が存在しないときは除去して進む
            {
                s.at(i).pop();
            }
            //cout << ans << endl;
            
            
        }
        while(!v.at(i).empty()) {//同様に
            if (v.at(i).top().second == 'L')
            {
                memomemo = v.at(i).top().first;
                v.at(i).pop();
            }
            else if (memomemo != 5000000 && v.at(i).top().second == 'R')
            {
                ans = min(ans,5*abs(memomemo - v.at(i).top().first));
                v.at(i).pop();
            }
            else if (memomemo == 5000000 && v.at(i).top().second == 'R')
            {
                v.at(i).pop();
            }
            //cout << ans << endl;
            
        }
    }

    for (long long i = 0; i < 400001; i++)
    {
        memomemo = 5000000;
        memo = 5000000;
        while(!ru.at(i).empty()) {//右上左下の関係にある期待について考える，せっぺんiのときのペアがあれば進む
            if (ru.at(i).top().second == 'D')//この時衝突しうるのは同じ切片かつ，ｘの大きいほうが下，小さい方が右
            {
                memo = ru.at(i).top().first;
                ru.at(i).pop();
            }
            else if (memo != 5000000 && ru.at(i).top().second == 'R')
            {
                ans = min(ans,10*abs(memo - ru.at(i).top().first));
                ru.at(i).pop();
            }
            else if (memo == 5000000 && ru.at(i).top().second == 'R')
            {
                ru.at(i).pop();
            }


            if (ru.at(i).top().second == 'L')//と大きい方が左，小さい方が上，のときである
            {
                memomemo = ru.at(i).top().first;
                ru.at(i).pop();
            }
            else if (memomemo != 5000000 && ru.at(i).top().second == 'U')
            {
                ans = min(ans,10*abs(memomemo - ru.at(i).top().first));
                ru.at(i).pop();
            }
            else if (memomemo == 5000000 && ru.at(i).top().second == 'U')
            {
                ru.at(i).pop();
            }

            //cout << ans+ans << endl;
            
            
        }

        memomemo = 5000000;
        memo = 5000000;
        while(!rd.at(i).empty()) {
            //cout << rd.at(i).top().first << endl;
            //cout << rd.at(i).top().second << endl;
            if (rd.at(i).top().second == 'U')
            {
                memo = rd.at(i).top().first;
                rd.at(i).pop();
            }
            else if (memo != 5000000 && rd.at(i).top().second == 'R')
            {
                ans = min(ans,10*abs(memo - rd.at(i).top().first));
                rd.at(i).pop();
            }
            else if (memo == 5000000 && rd.at(i).top().second == 'R')
            {
                rd.at(i).pop();
            }


            if (rd.at(i).top().second == 'L')
            {
                memomemo = rd.at(i).top().first;
                rd.at(i).pop();
            }
            else if (memomemo != 5000000 && rd.at(i).top().second == 'D')
            {
                ans = min(ans,10*abs(memomemo - rd.at(i).top().first));
                rd.at(i).pop();
            }
            else if (memomemo == 5000000 && rd.at(i).top().second == 'D')
            {
                rd.at(i).pop();
            }
            //cout << "memo:" << memo << endl;
            //cout << "memomemo:" << memomemo << endl;
            //cout << ans << endl;
            //cout << "##" << endl;
            
        }
    }

    



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

Measured memory_bytes: 62472