#include <cassert>
#include <cstdio>
#include <cmath>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <numeric>
#include <algorithm>

using namespace std;
using lint = long long;
constexpr int MOD = 1000000007, INF = 1010101010;
constexpr lint LINF = 1LL << 60;

#ifdef _DEBUG
#include "../../library/library/debug_template.cpp"
#define DMP(...) dump(#__VA_ARGS__, __VA_ARGS__)
#else 
#define DMP(...) ((void)0)
#endif

struct init {
	init() {
		cin.tie(nullptr); ios::sync_with_stdio(false);
		cout << fixed << setprecision(10);
	}
} init_;

template<class T = lint, class R = lint>
struct Point2D {
	T x, y;
	constexpr Point2D(T x = 0, T y = 0) noexcept : x(x), y(y) {};
	constexpr Point2D(pair<T, T> p) noexcept : x(p.first), y(p.second) {};
	constexpr bool operator==(const Point2D& rhs) const noexcept { return x == rhs.x && y == rhs.y; }
	constexpr bool operator!=(const Point2D& rhs) const noexcept { return !((*this) == rhs); }
	constexpr bool operator< (const Point2D& rhs) const noexcept { return x < rhs.x || (x == rhs.x && y < rhs.y); }
	constexpr bool operator> (const Point2D& rhs) const noexcept { return rhs < (*this); }
	constexpr bool operator<=(const Point2D& rhs) const noexcept { return !((*this) > rhs); }
	constexpr bool operator>=(const Point2D& rhs) const noexcept { return !((*this) < rhs); }
	constexpr Point2D  operator+ (const Point2D& rhs) const noexcept { return { x + rhs.x, y + rhs.y }; }
	constexpr Point2D  operator- (const Point2D& rhs) const noexcept { return { x - rhs.x, y - rhs.y }; }
	constexpr Point2D  operator* (const T& l) const noexcept { return { l * x, l * y }; }
	constexpr Point2D  operator/ (const T& l) const noexcept { return { x / l, y / l }; }
	constexpr Point2D& operator+=(const Point2D& rhs) noexcept { return ((*this) = (*this) + rhs); }
	constexpr Point2D& operator-=(const Point2D& rhs) noexcept { return ((*this) = (*this) - rhs); }
	constexpr Point2D& operator*=(const T& l) noexcept { return ((*this) = (*this) * l); }
	constexpr Point2D& operator/=(const T& l) noexcept { return ((*this) = (*this) / l); }
	constexpr Point2D  operator- () const noexcept { return { -x, -y }; }
	constexpr T operator* (const Point2D& rhs) const noexcept { return x * rhs.x + y * rhs.y; }
	constexpr Point2D nor() const noexcept { return { y, -x }; }
	constexpr long double hypot() const noexcept { return ::hypotl(x, y); }
	friend istream& operator>>(istream& is, Point2D& p) { return is >> p.x >> p.y; }
	friend ostream& operator<<(ostream& os, const Point2D& p) { return os << p.x << " " << p.y << "\n"; }
	R& operator[](vector<vector<R>>& v) { return v[x][y]; }
};

using pnt = Point2D<>;

template<class T>
inline bool chmin(T& a, const T b) { return a > b && (a = b, true); }

int main() {

	int N;
	cin >> N;

	vector<pnt> U, R, L, D;
	for (int ir = 0; ir < N; ir++) {
		pnt xy;
		char d;
		cin >> xy >> d;
		if (d == 'R') R.emplace_back(xy);
		if (d == 'L') L.emplace_back(xy);
		if (d == 'U') U.emplace_back(xy);
		if (d == 'D') D.emplace_back(xy);
	}
	sort(R.begin(), R.end(), [](auto l, auto d) {return l.x < d.x; });
	sort(L.begin(), L.end(), [](auto l, auto d) {return l.x < d.x; });
	sort(U.begin(), U.end(), [](auto l, auto d) {return l.x < d.x; });
	sort(D.begin(), D.end(), [](auto l, auto d) {return l.x < d.x; });

	map<lint, vector<lint>> Rp, Rn, Lp, Ln, Up, Un, Dp, Dn;
	for (const auto& xy : R) Rp[xy * pnt(1, 1)].emplace_back(xy.x);
	for (const auto& xy : R) Rn[xy * pnt(1, -1)].emplace_back(xy.x);
	for (const auto& xy : L) Lp[xy * pnt(1, 1)].emplace_back(xy.x);
	for (const auto& xy : L) Ln[xy * pnt(1, -1)].emplace_back(xy.x);
	for (const auto& xy : U) Up[xy * pnt(1, 1)].emplace_back(xy.x);
	for (const auto& xy : U) Un[xy * pnt(1, -1)].emplace_back(xy.x);
	for (const auto& xy : D) Dp[xy * pnt(1, 1)].emplace_back(xy.x);
	for (const auto& xy : D) Dn[xy * pnt(1, -1)].emplace_back(xy.x);

	map<lint, vector<lint>> Ry, Ly, Ux, Dx;
	for (const auto& xy : R) Ry[xy * pnt(0, 1)].emplace_back(xy.x);
	for (const auto& xy : L) Ly[xy * pnt(0, 1)].emplace_back(xy.x);
	sort(U.begin(), U.end(), [](auto l, auto d) {return l.y < d.y; });
	sort(D.begin(), D.end(), [](auto l, auto d) {return l.y < d.y; });
	for (const auto& xy : U) Ux[xy * pnt(1, 0)].emplace_back(xy.y);
	for (const auto& xy : D) Dx[xy * pnt(1, 0)].emplace_back(xy.y);

	lint ans = LINF;
	auto update = [&ans](auto &l, auto &r, int speed) {

		for (const auto& [key, vecl] : l) {
			auto it = r.find(key);
			if (it != r.end()) {

				auto vecr = it->second;

				auto ir = vecr.begin();
				for (const auto& xl : vecl) {
					while (ir != vecr.end() && *ir < xl) ir++;
					if (ir == vecr.end()) break;
					chmin(ans, (*ir - xl) * speed);
				}
			}
		}
	
	};

	update(Rp, Up, 10);
	update(Dp, Lp, 10);
	update(Rn, Dn, 10);
	update(Un, Ln, 10);
	update(Ry, Ly, 5);
	update(Ux, Dx, 5);

	if (ans == LINF) cout << "SAFE" << "\n";
	else cout << ans << "\n";

	return 0;
}



Measured memory_bytes: 72008