/**
 *   @FileName	a.cpp
 *   @Author	kanpurin
 *   @Created	2020.08.20 03:18:30
**/

#include "bits/stdc++.h" 
using namespace std; 
typedef long long ll;


class UnionFind {
private:
    vector<int> par;
public:
    UnionFind(int n) {
        par.resize(n, -1);
    }
    int root(int x) {
        if (par[x] < 0) return x;
        return par[x] = root(par[x]);
    }
    bool unite(int x, int y) {
        int rx = root(x);
        int ry = root(y);
        if (rx == ry) return false;
        if (size(rx) < size(ry)) swap(rx, ry);
        par[rx] += par[ry];
        par[ry] = rx;
        return true;
    }
    bool same(int x, int y) {
        int rx = root(x);
        int ry = root(y);
        return rx == ry;
    }
    int size(int x) {
        return -par[root(x)];
    }
};
int main() {
    int n;cin >> n;
    vector<pair<int,int>> p(n),q(n);
    for (int i = 0; i < n; i++) {
        int a,b;cin >> a >> b;
        p[i].first = a;
        p[i].second = q[i].second = i;
        q[i].first = b;
    }
    sort(p.begin(), p.end());
    sort(q.begin(), q.end());
    UnionFind uf(n);
    typedef tuple<int,int,int> T;
    priority_queue<T,vector<T>,greater<T>> pq;
    for (int i = 0; i < n-1; i++) {
        pq.push(make_tuple(p[i+1].first - p[i].first,p[i+1].second,p[i].second));
        pq.push(make_tuple(q[i+1].first - q[i].first,q[i+1].second,q[i].second));
    }
    ll ans = 0;
    while(!pq.empty()) {
        auto t = pq.top();
        pq.pop();
        int x = get<1>(t);
        int y = get<2>(t);
        if (!uf.same(x,y)) {
            ans += get<0>(t);
            uf.unite(x,y);
        }
    }
    cout << ans << endl;
    return 0;
}
#include <iostream>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <cassert>
#include <vector>
#include <list>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <string>
#include <algorithm>
#include <utility>
#define llint long long
#define inf 1e18
#define rep(x, s, t) for(llint (x) = (s); (x) < (t); (x)++)
#define Rep(x, s, t) for(llint (x) = (s); (x) <= (t); (x)++)
#define chmin(x, y) (x) = min((x), (y))
#define chmax(x, y) (x) = max((x), (y))

using namespace std;
typedef pair<llint, llint> P;

llint n;
llint x[200005], y[200005], u[200005], v[200005];
char c[200005];
vector<P> vec[6][4000005];

llint calc(vector<P> &vec)
{
	llint ret = inf, l = -inf;
	for(int i = 0; i < vec.size(); i++){
		if(vec[i].second == -1) l = vec[i].first;
		else ret = min(ret, vec[i].first - l);
	}
	return ret;
}

int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	
	cin >> n;
	for(int i = 1; i <= n; i++){
		cin >> x[i] >> y[i] >> c[i];
		x[i] *= 10, y[i] *= 10;
		u[i] = x[i] + y[i], v[i] = x[i] - y[i] + 2000002;
	}
	
	for(int i = 1; i <= n; i++){
		if(c[i] == 'R') vec[0][y[i]].push_back(P(x[i], -1));
		if(c[i] == 'L') vec[0][y[i]].push_back(P(x[i], 1));
		
		if(c[i] == 'U') vec[1][x[i]].push_back(P(y[i], -1));
		if(c[i] == 'D') vec[1][x[i]].push_back(P(y[i], 1));
		
		if(c[i] == 'R') vec[2][u[i]].push_back(P(v[i], -1));
		if(c[i] == 'U') vec[2][u[i]].push_back(P(v[i], 1));
		
		if(c[i] == 'D') vec[3][u[i]].push_back(P(v[i], -1));
		if(c[i] == 'L') vec[3][u[i]].push_back(P(v[i], 1));
		
		if(c[i] == 'L') vec[4][v[i]].push_back(P(u[i], 1));
		if(c[i] == 'U') vec[4][v[i]].push_back(P(u[i], -1));
		
		if(c[i] == 'R') vec[5][v[i]].push_back(P(u[i], -1));
		if(c[i] == 'D') vec[5][v[i]].push_back(P(u[i], 1));
	}
	
	llint ans = inf;
	for(int i = 0; i < 6; i++){
		for(int j = 0; j < 4000005; j++){
			sort(vec[i][j].begin(), vec[i][j].end());
			ans = min(ans, calc(vec[i][j]));
		}
	}
	
	if(ans > inf/2) cout << "SAFE" << endl;
	else cout << ans / 2 << endl;
	
	return 0;
}