//  Copyright 2020 Nikita Golikov

#include <bits/stdc++.h>

using namespace std;

using i64 = int64_t;
using ui64 = uint64_t;

#ifdef GOLIKOV
mt19937_64 rng(566);
#else
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
#endif

template <typename T>
T rnd_helper(T from, T to, true_type) {
  return uniform_int_distribution<T>(from, to)(rng);
}

template <typename T>
T rnd_helper(T from, T to, false_type) {
  return uniform_real_distribution<T>(from, to)(rng);
}

template <typename T>
T rnd(T from, T to) {
  return rnd_helper(from, to, is_integral<T>{});
}

template <typename A, typename B, typename Cmp>
bool set_min(A &x, B const &y, Cmp &&cmp) {
  if (cmp(y, x)) {
    x = y;
    return true;
  }
  return false;
}

template <typename A, typename B>
bool set_min(A &x, B const &y) {
  return set_min(x, y, less<typename common_type<A, B>::type>{});
}

template <typename A, typename B>
bool set_max(A &x, B const &y) {
  return set_min(x, y, greater<typename common_type<A, B>::type>{});
}

#include <ext/pb_ds/assoc_container.hpp>

using namespace __gnu_pbds;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,
                         tree_order_statistics_node_update>;

template <typename K, typename V>
using ordered_map = tree<K, V, less<K>, rb_tree_tag,
                         tree_order_statistics_node_update>;

//  https://codeforces.com/blog/entry/62393
struct custom_hash {
  static uint64_t splitmix64(uint64_t x) {
    // http://xorshift.di.unimi.it/splitmix64.c
    x += 0x9e3779b97f4a7c15;
    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
    x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
    return x ^ (x >> 31);
  }

  size_t operator()(uint64_t x) const {
    static const uint64_t
        FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
    return static_cast<size_t>(splitmix64(x + FIXED_RANDOM));
  }
};

#ifdef __cpp_deduction_guides
template <typename F>
struct rec_fun {
  F fun;

  rec_fun(F &&fun_) : fun(std::forward<F>(fun_)) {}

  template <typename... Args>
  decltype(auto) operator()(Args &&... args) const {
    return fun(*this, std::forward<Args>(args)...);
  }
};
#endif

#ifdef __cpp_inline_variables
template <typename T>
inline constexpr auto type_min = numeric_limits<T>::lowest();

template <typename T>
inline constexpr auto type_max = numeric_limits<T>::max();
#endif

//  fast alloc
#if 0
int const MAX_MEM = 1e8;
int mpos = 0;
char mem[MAX_MEM];
void* operator new(size_t n) {
  mpos += n;
  return (void*)(mem + mpos - n);
}
void operator delete (void*) noexcept {}
#endif

//  pragmas
#if 0
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4")
#pragma GCC optimize("unroll-loops")
#endif

int ans = (int) 1e9;

void solve(vector<pair<int, int>> v) {
  sort(v.begin(), v.end());
  int n = (int) v.size();
  for (int i = 1; i < n; ++i) {
    if (v[i].second == -1 && v[i - 1].second == 1) {
      set_min(ans, (v[i].first - v[i - 1].first) * 5);
    }
  }
}

int main() {
#ifdef GOLIKOV
  assert(freopen("in", "rt", stdin));
  auto _clock_start = chrono::high_resolution_clock::now();
#endif
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  int n;
  cin >> n;
  int const MAX = (int) 2e5 + 10;
  vector<vector<pair<int, int>>> by_y(MAX), by_x(MAX);
  int const U = 0;
  int const D = 1;
  int const R = 2;
  int const L = 3;
  struct guy {
    int x;
    int y;
    int dir;
  };
  vector<guy> guys;
  for (int i = 0; i < n; ++i) {
    int x, y;
    string dir;
    cin >> x >> y >> dir;
    int d;
    if (dir == "U") {
      by_x[x].emplace_back(y, 1);
      d = U;
    } else if (dir == "D") {
      by_x[x].emplace_back(y, -1);
      d = D;
    } else if (dir == "R") {
      by_y[y].emplace_back(x, 1);
      d = R;
    } else {
      by_y[y].emplace_back(x, -1);
      d = L;
    }
    guys.push_back({x, y, d});
  }
  for (int c = 0; c < MAX; ++c) {
    solve(by_x[c]);
    solve(by_y[c]);
  }
  {
    sort(guys.begin(), guys.end(), [](auto& x, auto& y) {
      return x.y < y.y;
    });
    vector<set<int>> by_sum(2 * MAX), by_diff(2 * MAX);
    for (int i = n - 1; i >= 0; --i) {
      if (guys[i].dir == U) {
        {
          auto diff = guys[i].y - guys[i].x + MAX;
          auto& st = by_diff[diff];
          auto it = st.upper_bound(guys[i].x);
          if (it != st.end()) {
            set_min(ans, (*it - guys[i].x) * 10);
          }
        }
        {
          auto sum = guys[i].y + guys[i].x;
          auto& st = by_sum[sum];
          auto it = st.lower_bound(guys[i].x);
          if (it != st.begin()) {
            --it;
            set_min(ans, (guys[i].x - *it) * 10);
          }
        }
      } else if (guys[i].dir == R) {
        by_sum[guys[i].x + guys[i].y].insert(guys[i].x);
      } else if (guys[i].dir == L) {
        by_diff[guys[i].y - guys[i].x + MAX].insert(guys[i].x);
      }
    }
  }
  {
    sort(guys.begin(), guys.end(), [](auto& x, auto& y) {
      return x.y > y.y;
    });
    vector<set<int>> by_sum(2 * MAX), by_diff(2 * MAX);
    for (int i = n - 1; i >= 0; --i) {
      if (guys[i].dir == D) {
        {
          auto diff = guys[i].y - guys[i].x + MAX;
          auto& st = by_diff[diff];
          auto it = st.lower_bound(guys[i].x);
          if (it != st.begin()) {
            --it;
            set_min(ans, (guys[i].x - *it) * 10);
          }
        }
        {
          auto sum = guys[i].y + guys[i].x;
          auto& st = by_sum[sum];
          auto it = st.upper_bound(guys[i].x);
          if (it != st.end()) {
            set_min(ans, (*it - guys[i].x) * 10);
          }
        }
      } else if (guys[i].dir == L) {
        by_sum[guys[i].x + guys[i].y].insert(guys[i].x);
      } else if (guys[i].dir == R) {
        by_diff[guys[i].y - guys[i].x + MAX].insert(guys[i].x);
      }
    }
  }
  if (ans == (int) 1e9) {
    cout << "SAFE\n";
  } else cout << ans << '\n';

#ifdef GOLIKOV
  cerr << "Executed in " << chrono::duration_cast<chrono::milliseconds>(
      chrono::high_resolution_clock::now()
          - _clock_start).count() << "ms." << endl;
#endif
  return 0;
}


Measured memory_bytes: 64776