#include <bits/stdc++.h>

using namespace std;
using ll = int;
using point = pair<int, int>;
constexpr int CMAX = 200010;
constexpr int INF = 1000000000;

vector<point> yxMirror(vector<point> pts) {
	vector<point> ans = pts;
	for (point &x : ans) swap(x.first, x.second);
	return ans;
}

vector<point> xaMirror(vector<point> pts) {
	vector<point> ans = pts;
	for (point &x : ans) x.second *= -1;
	return ans;
}

vector<point> yaMirror(vector<point> pts) {
	vector<point> ans = pts;
	for (point &x : ans) x.first *= -1;
	return ans;
}

// guaranteed in [0, CMAX)
ll checkUpDownCollision(vector<point> ups, vector<point> downs) {
	ll ans = INF;
	vector<vector<pair<int, bool>>> pointsAt(CMAX);
	for (point p : ups) pointsAt[p.first].emplace_back(p.second, false);
	for (point p : downs) pointsAt[p.first].emplace_back(p.second, true);
	for (int i = 0; i < CMAX; ++i) sort(begin(pointsAt[i]), end(pointsAt[i]));
	for (int i = 0; i < CMAX; ++i) {
		for (int j = 0, k = 1; k < pointsAt[i].size(); ++j, ++k) {
			if (!pointsAt[i][j].second && pointsAt[i][k].second) {
				ans = min(ans, (pointsAt[i][k].first - pointsAt[i][j].first) * 5);
			}
		}
	}
	return ans;
}

// might need to be adjusted
ll checkUpRightCollision(vector<point> ups, vector<point> rights) {
	vector<pair<point, bool>> pTypes;
	for (point p : ups) pTypes.emplace_back(p, false);
	for (point p : rights) pTypes.emplace_back(p, true);
	ll ans = INF;
	sort(begin(pTypes), end(pTypes), [] (pair<point, bool> ax, pair<point, bool> bx) {
		point a = ax.first, b = bx.first;	
		return pair<int, int>(a.first + a.second, a.first) < pair<int, int>(b.first + b.second, b.first);
	});
//	printf("URCP\n");
	for (int i = 0, j = 1; j < pTypes.size(); ++i, ++j) {
		point a = pTypes[i].first, b = pTypes[j].first;
//		printf("check %d %d %d %d\n", a.first, a.second, b.first, b.second);
//		printf("psums %d %d\n", a.first + a.second, b.first + b.second);
		if (a.first + a.second == b.first + b.second && pTypes[i].second && !pTypes[j].second) {
//			printf("psums %d %d\n", a.first + a.second, b.first + b.second);
			ans = min(ans, 5 * (abs(a.second - b.second) + abs(a.first - b.first)));
		}
	}
	return ans;
}

int main() {
	int n; scanf("%d", &n);
	vector<point> pts(n); vector<char> direct(n);
	for (int i = 0; i < n; ++i) {
		char c;
		scanf("%d %d %c", &pts[i].first, &pts[i].second, &c);
		direct[i] = c;
	}
	vector<point> up, down, left, right;
	for (int i = 0; i < n; ++i) {
		point p = pts[i];
		if (direct[i] == 'U') up.push_back(p);
		if (direct[i] == 'D') down.push_back(p);
		if (direct[i] == 'L') left.push_back(p);
		if (direct[i] == 'R') right.push_back(p);
	}
	ll ans = INF;
	// check up-down
	ans = min(ans, checkUpDownCollision(up, down));
	// check left-right
	vector<point> leftMir = yxMirror(left), rightMir = yxMirror(right);
	ans = min(ans, checkUpDownCollision(rightMir, leftMir));
	// check up-right
	ans = min(ans, checkUpRightCollision(up, right));
	// check up-left
	ans = min(ans, checkUpRightCollision(yaMirror(up), yaMirror(left)));
	// check down-right
	ans = min(ans, checkUpRightCollision(xaMirror(down), xaMirror(right)));
	// check down-left
	ans = min(ans, checkUpRightCollision(xaMirror(yaMirror(down)), xaMirror(yaMirror(left))));
	if (ans == INF) printf("SAFE\n");
	else printf("%d\n", ans);
	return 0;
}


Measured memory_bytes: 18972