#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#include <climits>
#include <cstring>
#include <cassert>


using namespace std;
#define SZ(x) (int)(x.size())
#define REP(i, n) for(int i=0;i<n;++i)
#define FOR(i, a, b) for(int i=a;i<b;++i)
#define RREP(i, n) for(int i=n-1;i>=0;--i)
#define RFOR(i, a, b) for(int i=b-1;i>=a;--i)

#define all(x) begin(x),end(x)
#define dump(x) cerr<<#x<<" = "<<(x)<<endl
#define debug(x) cerr<<#x<<" = "<<(x)<<" (L"<<__LINE__<<")"<< endl;

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using P = pair<int, int>;
const double eps = 1e-8;
const ll MOD = 1000000007;
const int INF = INT_MAX / 2;
const ll LINF = LLONG_MAX / 2;

template<class T>
bool chmax(T &a, const T &b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

template<class T>
bool chmin(T &a, const T &b) {
    if (b < a) {
        a = b;
        return true;
    }
    return false;
}


template<typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> p) {
    os << p.first << ":" << p.second;
    return os;
}

template<class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
    os << "[";
    REP(i, SZ(v)) {
        if (i) os << ", ";
        os << v[i];
    }
    return os << "]";
}

template<class T1, class T2>
ostream &operator<<(ostream &os, const map<T1, T2> &mp) {
    os << "[";
    for (auto it = mp.begin(); it != mp.end(); ++it) {
        if (it != mp.begin()) {
            os << ", ";
        }
        os << *it;
    }
    return os << "]";
}

// edit

ll calc(const vector<ll> &lx, const vector<ll> &rx) {
    ll ret = INF;


    int lp = 0, rp = 0;
    while (lp < lx.size() && rp < rx.size()) {
        if (lx[lp] < rx[rp]) {
            ll tmp = rx[rp] - lx[lp];
            chmin(ret, tmp);
            lp++;
        } else {
            rp++;
        }
    }

    return ret;
}

void solve() {
    int N;
    cin >> N;
    int lim = 200001;
    vector<pair<int, int>> xy(N);
    vector<char> U(N);

    REP(i, N) {
        cin >> xy[i].first >> xy[i].second;
        cin >> U[i];
    }

    ll ans = INF;
    // x 同じ
    {
        vector<vector<int>> yidx(lim);
        REP(i, N) {
            yidx[xy[i].second].push_back(i);
        }

        REP(y, lim) {
            vector<ll> lx, rx;
            for (auto e : yidx[y]) {
                if (U[e] == 'R') {
                    lx.push_back(xy[e].first);
                } else if (U[e] == 'L') {
                    rx.push_back(xy[e].first);
                }
            }
            sort(all(lx));
            sort(all(rx));

            ll tmp = calc(lx, rx) * 5;
            chmin(ans, tmp);
        }
    }

    // y 同じ
    {
        vector<vector<int>> xidx(lim);
        REP(i, N) {
            xidx[xy[i].first].push_back(i);
        }

        REP(x, lim) {
            vector<ll> dy, uy;
            for (auto e : xidx[x]) {
                if (U[e] == 'U') {
                    dy.push_back(xy[e].second);
                } else if (U[e] == 'D') {
                    uy.push_back(xy[e].second);
                }
            }
            sort(all(dy));
            sort(all(uy));

            ll tmp = calc(dy, uy) * 5;
            chmin(ans, tmp);
        }
    }

    // - x + y 同じ
    {
        vector<vector<int>> idx(2 * lim);
        REP(i, N) {
            idx[-xy[i].first + xy[i].second + lim].push_back(i);
        }

        REP(z, 2 * lim) {
            vector<ll> dx, rx, ux, lx; // 今までと法則が異なるので注意

            for (auto e : idx[z]) {
                if (U[e] == 'D') {
                    dx.push_back(xy[e].first);
                } else if (U[e] == 'R') {
                    rx.push_back(xy[e].first);
                } else if (U[e] == 'U') {
                    ux.push_back(xy[e].first);
                } else {
                    lx.push_back(xy[e].first);
                }
            }
            sort(all(dx));
            sort(all(rx));
            sort(all(ux));
            sort(all(lx));

            ll tmp1 = calc(rx, dx) * 10;
            ll tmp2 = calc(ux, lx) * 10;

            chmin(ans, tmp1);
            chmin(ans, tmp2);
        }
    }

    // x + y 同じ
    {
        vector<vector<int>> idx(2 * lim);
        REP(i, N) {
            idx[xy[i].first + xy[i].second].push_back(i);
        }

        REP(z, 2 * lim) {
            vector<ll> dx, rx, ux, lx; // 今までと法則が異なるので注意

            for (auto e : idx[z]) {
                if (U[e] == 'D') {
                    dx.push_back(xy[e].first);
                } else if (U[e] == 'R') {
                    rx.push_back(xy[e].first);
                } else if (U[e] == 'U') {
                    ux.push_back(xy[e].first);
                } else {
                    lx.push_back(xy[e].first);
                }
            }
            sort(all(dx));
            sort(all(rx));
            sort(all(ux));
            sort(all(lx));

            ll tmp1 = calc(rx, ux) * 10;
            ll tmp2 = calc(dx, lx) * 10;

            chmin(ans, tmp1);
            chmin(ans, tmp2);
        }
    }

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


}


int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);
//    std::ifstream in("input.txt");
//    std::cin.rdbuf(in.rdbuf());

    solve();


    return 0;
}


Measured memory_bytes: 24828