#include <bits/stdc++.h>
using namespace std;

using pii = pair<int, int>;
using ll = long long;
using ld = long double;
using cd = complex<ld>;

struct pt {
	int x, y;
};

bool operator<(const pt &a, const pt &b) {
	return tie(a.x, a.y) < tie(b.x, b.y);
}

map<int, map<int, vector<int>>> ptsX;
map<int, map<int, vector<int>>> ptsY;
map<int, map<int, vector<int>>> ptsOtherDiag;
map<int, map<int, vector<int>>> ptsMainDiag;

const int MAX_RES = 20 * 200'000 + 100;

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);

	map<char, int> typeToId = {
		{'U', 0},
		{'D', 1},
		{'R', 2},
		{'L', 3}
	};

	int n;
	cin >> n;
	vector<pt> upPts;
	vector<pt> downPts;
	for (int i = 0; i < n; i++) {
		int x, y;
		char t;
		cin >> x >> y >> t;

		x *= 20;
		y *= 20;
		ptsX[typeToId[t]][x].push_back(y);
		ptsY[typeToId[t]][y].push_back(x);
		ptsOtherDiag[typeToId[t]][x + y].push_back(x);
		ptsMainDiag[typeToId[t]][x - y].push_back(x);

		if (t == 'U') {
			upPts.push_back(pt{x, y});
		} else if (t == 'D') {
			downPts.push_back(pt{x, y});
		}
	}

	int res = MAX_RES;
	for (auto&[type, ptsOnX] : ptsX) {
		for (auto&[x, pts] : ptsOnX) {
			sort(pts.begin(), pts.end());
		}
	}
	for (auto&[coord, ptsOnY] : ptsY) {
		for (auto&[x, pts] : ptsOnY) {
			sort(pts.begin(), pts.end());
		}
	}
	for (auto&[coord, ptsOnXY] : ptsOtherDiag) {
		for (auto&[x, pts] : ptsOnXY) {
			sort(pts.begin(), pts.end());
		}
	}
	for (auto&[coord, ptsOnXY] : ptsMainDiag) {
		for (auto&[x, pts] : ptsOnXY) {
			sort(pts.begin(), pts.end());
		}
	}

	//U-D
	for (const auto&[coord, ptsOnX] : ptsX[0]) {
		if (!ptsX[1].count(coord)) {
			continue;
		}
		for (int p : ptsOnX) {
			auto it = lower_bound(ptsX[1][coord].begin(), ptsX[1][coord].end(), p);
			if (it != ptsX[1][coord].end()) {
				res = min(res, (*it - p) / 2);
			}
		}
	}
	//L-R
	for (const auto&[coord, ptsOnX] : ptsY[2]) {
		if (!ptsY[3].count(coord)) {
			continue;
		}
		for (int p : ptsOnX) {
			auto it = lower_bound(ptsY[3][coord].begin(), ptsY[3][coord].end(), p);
			if (it != ptsY[3][coord].end()) {
				res = min(res, (*it - p) / 2);
			}
		}
	}
	//U, D
	for (const pt &p : upPts) {
		if (ptsOtherDiag[2].count(p.x + p.y)) {
			const auto &diagPts = ptsOtherDiag[2][p.x + p.y];
			auto it = upper_bound(diagPts.begin(), diagPts.end(), p.x);
			if (it != diagPts.begin()) {
				--it;
				res = min(res, abs(p.x - *it));
			}
		}
		if (ptsMainDiag[3].count(p.x - p.y)) {
			const auto &diagPts = ptsMainDiag[3][p.x - p.y];
			auto it = lower_bound(diagPts.begin(), diagPts.end(), p.x);
			if (it != diagPts.end()) {
				res = min(res, abs(p.x - *it));
			}
		}
	}
	for (const pt &p : downPts) {
		if (ptsOtherDiag[3].count(p.x + p.y)) {
			const auto &diagPts = ptsOtherDiag[3][p.x + p.y];
			auto it = lower_bound(diagPts.begin(), diagPts.end(), p.x);
			if (it != diagPts.end()) {
				res = min(res, abs(p.x - *it));
			}
		}
		if (ptsMainDiag[2].count(p.x - p.y)) {
			const auto &diagPts = ptsMainDiag[2][p.x - p.y];
			auto it = upper_bound(diagPts.begin(), diagPts.end(), p.x);
			if (it != diagPts.begin()) {
				--it;
				res = min(res, abs(p.x - *it));
			}
		}
	}

	if (res == MAX_RES) {
		cout << "SAFE";
	} else {
		cout << (res / 2);
	}

	return 0;
}

Measured memory_bytes: 83032