#include <bits/stdc++.h>
// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <cmath>
#include <iomanip>
#include <time.h>
#define dibs reserve
#define OVER9000 1234567890
#define ALL_THE(CAKE,LIE) for(auto LIE =CAKE.begin(); LIE != CAKE.end(); LIE++)
#define tisic 47
#define soclose 1e-8
#define chocolate win
// so much chocolate
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
#define uint unsigned int
#define dbl long double
#define pi 3.14159265358979323846
using namespace std;
// mylittledoge

using cat = long long;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

cat gcd(cat x, cat y) {
	if(x > y) swap(x, y);
	return (x == 0) ? y : gcd(y%x, x);
}

cat lcm(cat x, cat y) {
	return x / gcd(x, y) * y;
}

int main() {
	cin.sync_with_stdio(0);
	cin.tie(0);
	cout << fixed << setprecision(10);
	int N;
	cin >> N;
	vector< vector<cat> > A(N, vector<cat>(N, 1));
	vector<int> P;
	for(int p = 4; ; p++) {
		bool is_prime = true;
		for(int i = 2; i*i <= p; i++) is_prime &= (p%i != 0);
		if(!is_prime) continue;
		P.push_back(p);
		if((int)P.size() == N+10) break;
	}
	for(int i = 0; i < N; i += 2) for(int j = 0; j < N; j += 2) A[i][j] = P[i/2] * P[N/2+1+j/2];
	for(int i = 1; i < N; i += 2) for(int j = 1; j < N; j += 2) A[i][j] = 3 * A[i-1][j-1];
	for(int i = 0; i < N; i++) for(int j = 1-(i&1); j < N; j += 2) {
		if(i > 0) A[i][j] = lcm(A[i][j], A[i-1][j]);
		if(j > 0) A[i][j] = lcm(A[i][j], A[i][j-1]);
		if(i+1 < N) A[i][j] = lcm(A[i][j], A[i+1][j]);
		if(j+1 < N) A[i][j] = lcm(A[i][j], A[i][j+1]);
		if(j&1) A[i][j] *= 2;
		A[i][j]++;
	}
	for(int i = 0; i < N; i++) for(int j = 0; j < N; j++) cout << A[i][j] << ((j == N-1) ? "\n" : " ");
	return 0;
}

// look at my code
// my code is amazing

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
using vint = vector<int>;
using vvint = vector<vint>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vchar = vector<char>;
using vvchar = vector<vchar>;
using vp = vector<P>;
using vpp = vector<pair<P, P>>;
using vvp = vector<vp>;

#define rep(i, n) for (int i = 0; i < n; ++i)

P bounds = P(0, 0);
void rot(vp *up, vp *down, vp *left, vp *right)
{
    vector<vp *> vecs = {up, down, left, right};
    rep(i, 4)
    {
        vp *a = vecs[i];
        rep(j, (*a).size())
        {
            P now = (*a)[j];
            (*a)[j] = P(now.second, -now.first + bounds.first);
        }
    }
    swap(bounds.first, bounds.second);
    swap(*down, *left);
    swap(*down, *up);
    swap(*down, *right);
}

bool comp(P l, P r)
{
    return (l.first + l.second) < (r.first + r.second);
}

const ll INF = 1e10 + 5;

int main()
{
    int n;
    cin >> n;
    vp up, down, left, right;
    rep(i, n)
    {
        int x, y;
        char u;
        cin >> x >> y >> u;
        P p = P(x, y);
        if (p.first > bounds.first)
        {
            bounds = P(p.first, bounds.second);
        }
        if (p.second > bounds.second)
        {
            bounds = P(bounds.first, p.second);
        }
        if (u == 'U')
        {
            up.emplace_back(p);
        }
        else if (u == 'D')
        {
            down.emplace_back(p);
        }
        else if (u == 'R')
        {
            right.emplace_back(p);
        }
        else if (u == 'L')
        {
            left.emplace_back(p);
        }
    }

    ll ans = INF;
    rep(i, 4)
    {

        map<int, vp> m;
        for (P p : up)
        {
            int sum = p.first + p.second;
            m[sum].emplace_back(P(p.second, 0));
        }
        for (P p : right)
        {
            int sum = p.first + p.second;
            m[sum].emplace_back(P(p.second, 1));
        }
        for (auto x : m)
        {
            vp b = x.second;
            sort(b.begin(), b.end());
            rep(j, b.size() - 1)
            {
                if (!b[j].second && b[j + 1].second)
                {
                    // collision between up and right
                    // not b[j].second && !b[j].second because we sorted by Y coords
                    ll now = b[j + 1].first - b[j].first;
                    now *= 10;
                    ans = min(ans, now);
                    break;
                }
            }
        }

        map<int, vp> q;
        for (P p : up)
        {
            q[p.first].emplace_back(P(p.second, 0));
        }
        for (P p : down)
        {
            q[p.first].emplace_back(P(p.second, 1));
        }
        for (auto x : q)
        {
            vp b = x.second;
            sort(b.begin(), b.end());
            rep(j, b.size() - 1)
            {
                if (!b[j].second && b[j + 1].second)
                {
                    ll now = b[j + 1].first - b[j].first;
                    now *= 5;
                    ans = min(ans, now);
                    break;
                }
            }
        }

        rot(&up, &down, &left, &right);
    }

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

    return 0;
}