#![allow(
    non_snake_case,
    unused_variables,
    unused_assignments,
    unused_mut,
    unused_imports,
    dead_code
)]
//use proconio::fastout;
use proconio::input;
use proconio::marker::*;
use std::cmp::*;
use std::collections::*;
//use std::collections::VecDeque;

fn main() {
    input! {
       N:usize,
       XYD:[(i64,i64,char);N]
    }
    // 飛行機を方向ごとに分類。
    let mut U = Vec::with_capacity(N);
    let mut R = Vec::with_capacity(N);
    let mut D = Vec::with_capacity(N);
    let mut L = Vec::with_capacity(N);
    for &(x, y, d) in XYD.iter() {
        match d {
            'U' => U.push(vec![x, y, x + y, x - y]),
            'D' => D.push(vec![x, y, x + y, x - y]),
            'L' => L.push(vec![x, y, x + y, x - y]),
            'R' => R.push(vec![x, y, x + y, x - y]),
            _ => (),
        }
    }
    let mut ans = std::i64::MAX;
    ans = calc(ans, &mut U, &mut D, 0, 1, "UD");
    ans = calc(ans, &mut L, &mut R, 1, 0, "LR");
    // U と R (Ux > Rx + n && Uy + n < Ry), Ux-Rx == Ry-Uy, Ux+Uy==Ry-Rx
    // U と L (Ux < Lx && Uy < Ly), Lx-Ux == Ly-Uy, Ux-Uy == Lx-Ly
    // D と R (Dx > Rx && Dy > Ry), Dx-Rx == Dy-Ry, Dx-Dy == Rx-Ry
    // D と L (Dx < Lx && Dy > Ly), Lx-Dx == Dy-Ly, Dy+Dx == Ly+Lx
    ans = calc(ans, &mut U, &mut R, 2, 0, "UR"); // ans = min(ans, (Ux - Rx) * 10);
    ans = calc(ans, &mut U, &mut L, 3, 0, "UL"); //ans = min(ans, (Lx - Ux) * 10);
    ans = calc(ans, &mut D, &mut R, 3, 0, "DR"); // ans = min(ans, (Dy - Ry) * 10);
    ans = calc(ans, &mut D, &mut L, 2, 0, "DL"); //ans = min(ans, (Dy - Ly) * 10);

    if ans == std::i64::MAX {
        println!("SAFE");
    } else {
        println!("{}", ans);
    }
}

fn calc(
    ans: i64,
    A: &mut Vec<Vec<i64>>,
    B: &mut Vec<Vec<i64>>,
    p: usize,
    q: usize,
    flag: &str,
) -> i64 {
    let mut ans = ans;
    A.sort_by_key(|v| (v[p], v[q]));
    B.sort_by_key(|v| (v[p], v[q]));
    let mut i = 0;
    let mut j = 0;
    let mut tmin = std::i64::MAX;
    while i < A.len() && j < B.len() {
        if A[i][p] < B[j][p] {
            i += 1;
            continue;
        }
        if A[i][p] > B[j][p] {
            j += 1;
            continue;
        }
        let v = A[i][p];
        let mut ii = i;
        let mut jj = j;
        while ii < A.len() && A[ii][p] == v && jj < B.len() && B[jj][p] == v {
            match flag {
                "UD" => {
                    let t = B[jj][1] - A[ii][1];
                    if t >= 0 {
                        tmin = min(tmin, t);
                        ii += 1;
                    } else if t < 0 {
                        jj += 1;
                    }
                }
                "UL" | "DL" => {
                    let t = B[jj][0] - A[ii][0];
                    if t >= 0 {
                        tmin = min(tmin, t);
                        ii += 1;
                    } else if t < 0 {
                        jj += 1;
                    }
                }
                "LR" | "UR" | "DR" => {
                    let t = A[ii][0] - B[jj][0];
                    if t >= 0 {
                        tmin = min(tmin, t);
                        jj += 1;
                    } else {
                        ii += 1;
                    }
                }
                _ => (),
            };
        }
        i = ii;
        j = jj;
    }
    if tmin < std::i64::MAX {
        match flag {
            "UD" | "LR" => ans = min(ans, tmin * 5),
            _ => ans = min(ans, tmin * 10),
        }
    }
    ans
}


Measured memory_bytes: 24488