#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define rep(i,s,e) for(i64 (i) = (s);(i) < (e);(i)++)
#define all(x) x.begin(),x.end()
#define STRINGIFY(n) #n
#define TOSTRING(n) STRINGIFY(n)
#define PREFIX "#" TOSTRING(__LINE__) "| "
#define debug(x) \
{ \
  std::cout << PREFIX << #x << " = " << x << std::endl; \
}

std::ostream& output_indent(std::ostream& os, int ind) {
  for(int i = 0; i < ind; i++) os << " ";
  return os;
}

template<class S, class T> std::ostream& operator<<(std::ostream& os, const std::pair<S, T>& p);
template<class T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& v);

template<class S, class T> std::ostream& operator<<(std::ostream& os, const std::pair<S, T>& p) {
  return (os << "(" << p.first << ", " << p.second << ")");
}
template<class T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
  os << "[";
  for(int i = 0;i < v.size();i++) os << v[i] << ", ";
  return (os << "]");
}

template<class T>
static inline std::vector<T> ndvec(size_t&& n, T val) { return std::vector<T>(n, std::forward<T>(val)); }
template<class... Tail>
static inline auto ndvec(size_t&& n, Tail&&... tail) {
  return std::vector<decltype(ndvec(std::forward<Tail>(tail)...))>(n, ndvec(std::forward<Tail>(tail)...));
}
template<class Cond> struct chain {
  Cond cond; chain(Cond cond) : cond(cond) {}
  template<class T> bool operator()(T& a, const T& b) const { if(cond(a, b)) { a = b; return true; } return false; }
};
template<class Cond> chain<Cond> make_chain(Cond cond) { return chain<Cond>(cond); }

i64 N;
const i64 MAX = 202020;
i64 same_direction(const vector<i64>& X,const vector<i64>& Y,const vector<char>& U) {
  vector<vector<std::pair<i64, char>>> Ys(MAX);
  rep(i,0,N) {
    i64 x = X[i];
    i64 y = Y[i];
    if(U[i] == 'U') {
      Ys[x].emplace_back(y, 'U');
    }
    if(U[i] == 'D') {
      Ys[x].emplace_back(y, 'D');
    }
  }
  i64 ans = 1e18;
  rep(i,0,MAX) {
    std::sort(all(Ys[i]));
    i64 maxU = -1e18;
    for(auto p: Ys[i]) {
      i64 y = p.first;
      char u = p.second;
      if(u == 'U') {
        maxU = y;
      }
      else {
        ans = std::min(ans, y - maxU);
      }
    }
  }
  return ans;
}

i64 triangle(const vector<i64>& X, const vector<i64>& Y, const vector<char>& U) {
  std::map<i64, i64> mp;
  vector<i64> idx(N);
  std::iota(all(idx), 0);
  std::sort(all(idx), [&](i64 i, i64 j) { return X[i] < X[j]; });
  i64 ans = 1e18;
  for(auto i: idx) {
    i64 x = X[i] - Y[i];
    i64 y = X[i] + Y[i];
    //debug(make_pair(x, y));
    //debug(U[i]);
    if(U[i] == 'U') {
      auto iter = mp.find(y);
      if(iter != mp.end()) {
        i64 nxp = iter->second;
        i64 ny = y - nxp;
        ans = std::min(ans, ny - Y[i] * 2);
      }
    }
    if(U[i] == 'R') {
      if(mp.count(y)) {
          mp[y] = std::max(mp[y], x);
      }
      else {
        mp[y] = x;
      }
    }
  }
  return ans;
}

int main() {
  cin >> N;
  vector<i64> X(N), Y(N);
  vector<char> U(N);
  rep(i,0,N) {
    cin >> X[i] >> Y[i] >> U[i];
  }
  i64 ans = 1e18;
  ans = std::min(ans, same_direction(X, Y, U));
  std::map<char, char> mp;
  mp['D'] = 'L';
  mp['U'] = 'R';
  mp['L'] = 'D';
  mp['R'] = 'U';

  rep(i,0,N) {
    std::swap(X[i], Y[i]);
    U[i] = mp[U[i]];
  }
  ans = std::min(ans, same_direction(X, Y, U));
  rep(i,0,N) {
    std::swap(X[i], Y[i]);
    U[i] = mp[U[i]];
  }

  auto swap_func = [&]() {
    rep(i,0,N) {
      std::swap(X[i], Y[i]);
      U[i] = mp[U[i]];
    }
  };

  auto tri = [&](auto func) {
  {
    // R U
    func();
    ans = std::min(ans, triangle(X, Y, U));
    func();
  }

  {
    // R D
    rep(i,0,N) {
      Y[i] *= -1;
      if(U[i] == 'D') U[i] = 'U';
      else if(U[i] == 'U') U[i] = 'D';
    }
    func();
    ans = std::min(ans, triangle(X, Y, U));
    func();
    rep(i,0,N) {
      Y[i] *= -1;
      if(U[i] == 'D') U[i] = 'U';
      else if(U[i] == 'U') U[i] = 'D';
    }
  }
  {
    // L U
    rep(i,0,N) {
      X[i] *= -1;
      if(U[i] == 'R') U[i] = 'L';
      else if(U[i] == 'L') U[i] = 'R';
    }
    func();
    ans = std::min(ans, triangle(X, Y, U));
    func();
    rep(i,0,N) {
      X[i] *= -1;
      if(U[i] == 'R') U[i] = 'L';
      else if(U[i] == 'L') U[i] = 'R';
    }
  }
  {
    // L D
    rep(i,0,N) {
      Y[i] *= -1;
      if(U[i] == 'D') U[i] = 'U';
      else if(U[i] == 'U') U[i] = 'D';
    }
    rep(i,0,N) {
      X[i] *= -1;
      if(U[i] == 'R') U[i] = 'L';
      else if(U[i] == 'L') U[i] = 'R';
    }
    func();
    ans = std::min(ans, triangle(X, Y, U));
    func();
    rep(i,0,N) {
      Y[i] *= -1;
      if(U[i] == 'D') U[i] = 'U';
      else if(U[i] == 'U') U[i] = 'D';
    }
    rep(i,0,N) {
      X[i] *= -1;
      if(U[i] == 'R') U[i] = 'L';
      else if(U[i] == 'L') U[i] = 'R';
    }
  }
  };

  tri([](){});
  //tri(swap_func);
  if(ans == 1e18) {
    cout << "SAFE" << endl;
  }
  else {
    cout << ans * 5 << endl;
  }
}


Measured memory_bytes: 18436