#include <bits/stdc++.h>
#define mk make_pair
#define fs first
#define sc second
using namespace std;
typedef long long ll;
typedef long double ld;
// please, read the question correctly (do you need set or multiset)???
const int N=200010; //check the limits, dummy
int x[N], y[N];
int n, m;
char s[N][11];
int main(){
	int t;
	// while(){
	scanf("%d",&n);
	vector<pair<int,int>>v1,v2, v3, v4, v5, v6;
	for(int i=0; i<n; ++i){
		scanf("%d%d%s",x+i, y+i, s[i]);
		if(s[i][0]=='U'){
			v1.push_back(mk(x[i], i));
			v5.push_back(mk(y[i], i));
		}
		else if(s[i][0]=='D'){
			v2.push_back(mk(x[i], i));
			v6.push_back(mk(y[i], i));
		}
		else if(s[i][0]=='R'){
			v3.push_back(mk(x[i], i));
		}
		else{
			v4.push_back(mk(x[i], i));
		}
	}
	sort(v1.begin(), v1.end());
	sort(v2.begin(), v2.end());
	sort(v3.begin(), v3.end());
	sort(v4.begin(), v4.end());

	sort(v5.begin(), v5.end());
	sort(v6.begin(), v6.end());

	int ans=1e9;
	int j=0, j1=0, j2=0;
	map<int, int> mp, mp1, mp2;
	for(int i=0; i<v4.size(); ++i){
		for(j;j<v1.size(); ++j){
			if(v1[j].fs>v4[i].fs)break;
			auto tmp=v1[j].sc;
			mp[x[tmp]-y[tmp]]=x[tmp];
		}
		auto tmp=v4[i].sc;
		if(mp.count(x[tmp]-y[tmp])){
			ans=min(ans, (x[tmp]-mp[x[tmp]-y[tmp]])*10);
		}

		for(j1;j1<v3.size(); ++j1){
			if(v3[j1].fs>v4[i].fs)break;
			auto tmp=v3[j1].sc;
			mp1[y[tmp]]=x[tmp];
		}
		 tmp=v4[i].sc;
		if(mp1.count(y[tmp])){
			ans=min(ans, (x[tmp]-mp1[y[tmp]])*5);
		}

		for(j2; j2<v2.size(); ++j2){
			if(v2[j2].fs>v4[i].fs)break;
			auto tmp=v2[j2].sc;
			mp2[x[tmp]+y[tmp]]=x[tmp];
		}
		 tmp=v4[i].sc;
		if(mp2.count(x[tmp]+y[tmp])){
			ans=min(ans, (x[tmp]-mp2[x[tmp]+y[tmp]])*10);
		}
	}
	mp.clear();
	mp1.clear();
	j=(int)v1.size()-1;
	j1=(int)v2.size()-1;
	for(int i=(int)(v3.size())-1; i>=0; --i){
		for(j; j>=0; --j){
			if(v1[j].fs<v3[i].fs)break;
			auto tmp=v1[j].sc;
			mp[x[tmp]+y[tmp]]=x[tmp];
		}
		auto tmp=v3[i].sc;
		if(mp.count(x[tmp]+y[tmp])){
			ans=min(ans, (mp[x[tmp]+y[tmp]]-x[tmp])*10);
		}

		for(j1; j1>=0; --j1){
			if(v2[j1].fs<v3[i].fs)break;
			auto tmp=v2[j1].sc;
			mp1[x[tmp]-y[tmp]]=x[tmp];
		}
		 tmp=v3[i].sc;
		if(mp1.count(x[tmp]-y[tmp])){
			ans=min(ans, (mp1[x[tmp]-y[tmp]]-x[tmp])*10);
		}
	}

	j=0;
	mp.clear();
	for(int i=0; i<v6.size(); ++i){
		for(j; j<v5.size(); ++j){
			if(v5[j].fs>v6[i].fs)break;
			auto tmp=v5[j].sc;
			mp[x[tmp]]=y[tmp];
		}
		auto tmp=v6[i].sc;
		if(mp.count(x[tmp])){
			ans=min(ans, (y[tmp]-mp[x[tmp]])*5);
		}
	}
	if(ans==1e9)
		printf("SAFE\n");
	else
		cout<<ans<<endl;
	// }
}
#include <bits/stdc++.h>
#define all(vec) vec.begin(), vec.end()
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
constexpr ll INF = (1LL << 30) - 1LL;
constexpr ll LINF = (1LL << 60) - 1LL;
constexpr double eps = 1e-9;
constexpr ll MOD = 1000000007LL;
template <typename T>
bool chmin(T& a, T b) {
    if(a > b) {
        a = b;
        return true;
    }
    return false;
};
template <typename T>
bool chmax(T& a, T b) {
    if(a < b) {
        a = b;
        return true;
    }
    return false;
};
template <typename T>
ostream& operator<<(ostream& os, vector<T> v) {
    for(int i = 0; i < v.size(); i++) {
        os << v[i] << (i + 1 == v.size() ? "\n" : " ");
    }
    return os;
}
template <typename T>
vector<T> make_v(size_t a) {
    return vector<T>(a);
}
template <typename T, typename... Ts>
auto make_v(size_t a, Ts... ts) {
    return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...));
}
template <typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type fill_v(T& t, const V& v) {
    t = v;
}
template <typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type fill_v(T& t, const V& v) {
    for(auto& e : t) {
        fill_v(e, v);
    }
};
struct UnionFind {
    vector<int> par, siz;
    UnionFind(int n) {
        par.resize(n);
        siz.resize(n, 1);
        for(int i = 0; i < n; i++)
            par[i] = i;
    }
    int find(int x) {
        if(par[x] == x) {
            return x;
        } else {
            return par[x] = find(par[x]);
        }
    }
    bool unite(int u, int v) {
        u = find(u), v = find(v);
        if(u == v)
            return false;
        if(siz[u] < siz[v])
            swap(u, v);
        par[v] = u;
        siz[u] += siz[v];
        return true;
    }
    bool same(int u, int v) { return find(u) == find(v); }
};
struct edge {
    ll u, v, cost;
    bool operator<(const edge& e) { return cost < e.cost; }
};
ll d;
vector<ll> a;
vector<edge> es;
void calc(int l, int r) {
    if(r - l <= 1) {
        return;
    }
    int m = (l + r) / 2;
    ll mi = LINF, s, t;
    for(ll i = l; i < m; i++) {
        ll k = -i * d + a[i];
        if(mi > k) {
            mi = k;
            s = i;
        }
    }
    mi = LINF;
    for(ll i = m; i < r; i++) {
        ll k = i * d + a[i];
        if(mi > k) {
            mi = k;
            t = i;
        }
    }
    for(ll i = l; i < m; i++) {
        es.push_back({i, t, (t - i) * d + a[t] + a[i]});
    }
    for(ll i = m; i < r; i++) {
        es.push_back({s, i, (i - s) * d + a[i] + a[s]});
    }
    calc(l, m);
    calc(m, r);
}
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    ll n;
    cin >> n >> d;
    a.resize(n + 1);
    for(ll i = 1; i <= n; i++) {
        cin >> a[i];
    }
    calc(1, n + 1);
    UnionFind uf(n + 1);
    sort(all(es));
    ll ans = 0;
    for(auto e : es) {
        if(uf.unite(e.u, e.v)) {
            ans += e.cost;
        }
    }
    cout << ans << endl;
}
