#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <string>
#include <cmath>
#include <cassert>
#include <ctime>
#include <algorithm>
#include <sstream>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <cstdlib>
#include <cstdio>
#include <iterator>
#include <functional>
#include <unordered_set>
#include <unordered_map>
#include <stdio.h>
#include <bitset>
using namespace std;
 
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define sz(x) (int)x.size()
#define all(x) x.begin(), x.end()
#define pii pair<int, int>
#define vi vector<int>
#define fast_io ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
 
typedef long long ll;
typedef short inth;
 
const int N = 2e5;
const int M = N + 7;
const int MOD = 1e9 + 7;
const ll INF = 1e16 + 17;

const int K = 2e6 + 7;

vi up[K], down[K], le[K], ri[K];
vi diagUpR[K + K], diagUpL[K + K], diagDownR[K + K], diagDownL[K + K];
vi diagUpU[K + K], diagUpD[K + K], diagDownU[K + K], diagDownD[K + K];

int x[M], y[M];
char c[M];

int main() {
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        scanf("%d %d %c", &x[i], &y[i], &c[i]);
        x[i] *= 10;
        y[i] *= 10;
        if (c[i] == 'U') {
            up[x[i]].pb(y[i]);
            diagUpU[x[i] - y[i] + K].pb(x[i]);
            diagDownU[x[i] + y[i]].pb(x[i]);
        } else if (c[i] == 'D') {
            down[x[i]].pb(y[i]);
            diagUpD[x[i] - y[i] + K].pb(x[i]);
            diagDownD[x[i] + y[i]].pb(x[i]);
        } else if (c[i] == 'L') {
            le[y[i]].pb(x[i]);
            diagUpL[x[i] - y[i] + K].pb(x[i]);
            diagDownL[x[i] + y[i]].pb(x[i]);
        } else {
            ri[y[i]].pb(x[i]);
            diagUpR[x[i] - y[i] + K].pb(x[i]);
            diagDownR[x[i] + y[i]].pb(x[i]);
        }
    }
    for (int i = 0; i < K; ++i) {
        sort(up[i].begin(), up[i].end());
        sort(down[i].begin(), down[i].end());
        sort(le[i].begin(), le[i].end());
        sort(ri[i].begin(), ri[i].end());
    }
    for (int i = 0; i < K + K; ++i) {
        sort(diagUpL[i].begin(), diagUpL[i].end());
        sort(diagUpR[i].begin(), diagUpR[i].end());
        sort(diagDownL[i].begin(), diagDownL[i].end());
        sort(diagDownR[i].begin(), diagDownR[i].end());
        sort(diagDownU[i].begin(), diagDownU[i].end());
        sort(diagDownD[i].begin(), diagDownD[i].end());
        sort(diagUpU[i].begin(), diagUpU[i].end());
        sort(diagUpD[i].begin(), diagUpD[i].end());
    }

    int ans = MOD;

    for (int i = 1; i <= n; ++i) {
        int dUp = x[i] - y[i] + K, dDown = x[i] + y[i];
        if (c[i] == 'U') {
            auto it = lower_bound(down[x[i]].begin(), down[x[i]].end(), y[i]);
            if (it != down[x[i]].end())
                ans = min(ans, ((*it) - y[i]) / 2);
            it = lower_bound(diagUpL[dUp].begin(), diagUpL[dUp].end(), x[i]);
            if (it != diagUpL[dUp].end())
                ans = min(ans, (*it) - x[i]);
        } else if (c[i] == 'D') {
            auto it = lower_bound(diagDownL[dDown].begin(), diagDownL[dDown].end(), x[i]);
            if (it != diagDownL[dDown].end())
                ans = min(ans, (*it) - x[i]);
        } else if (c[i] == 'R') {
            auto it = lower_bound(le[y[i]].begin(), le[y[i]].end(), x[i]);
            if (it != le[y[i]].end())
                ans = min(ans, ((*it) - x[i]) / 2);
            it = lower_bound(diagUpD[dUp].begin(), diagUpD[dUp].end(), x[i]);
            if (it != diagUpD[dUp].end())
                ans = min(ans, (*it) - x[i]);
            it = lower_bound(diagDownU[dDown].begin(), diagDownU[dDown].end(), x[i]);
            if (it != diagDownU[dDown].end())
                ans = min(ans, (*it) - x[i]);
        }
    }

    if (ans == MOD) {
        printf("SAFE\n");
    } else {
        printf("%d\n", ans);
    }
    return 0;
}

Measured memory_bytes: 961648