package main

import (
  "bufio"
  "os"
  "strconv"
  "strings"
  "fmt"
  "sort"
)

const C = 200000

func Solve() {
  var N int
  NextInt(&N)
  D := make([][][][]int, 4)
  for i := range D {
    D[i] = make([][][]int, 4)
    for j := range D[i] {
      D[i][j] = make([][]int, 2 * C + 1)
      for k := range D[i][j] {
        D[i][j][k] = make([]int, 0)
      }
    }
  }
  for i := 0; i < N; i++ {
    S := strings.Split(NextLine(), " ")
    X, _ := strconv.Atoi(S[0])
    Y, _ := strconv.Atoi(S[1])
    U := S[2]
    if U == "U" {
      D[0][0][X] = append(D[0][0][X], Y)
      D[2][0][X - Y + C] = append(D[2][0][X - Y + C], X)
      D[3][0][X + Y] = append(D[3][0][X + Y], X)
    } else if U == "R" {
      D[1][1][Y] = append(D[1][1][Y], X)
      D[2][1][X - Y + C] = append(D[2][1][X - Y + C], X)
      D[3][1][X + Y] = append(D[3][1][X + Y], X)
    } else if U == "D" {
      D[0][2][X] = append(D[0][2][X], Y)
      D[2][2][X - Y + C] = append(D[2][2][X - Y + C], X)
      D[3][2][X + Y] = append(D[3][2][X + Y], X)
    } else {
      D[1][3][Y] = append(D[1][3][Y], X)
      D[2][3][X - Y + C] = append(D[2][3][X - Y + C], X)
      D[3][3][X + Y] = append(D[3][3][X + Y], X)
    }
  }
  for i := range D {
    for j := range D[i] {
      for k := range D[i][j] {
        sort.Ints(D[i][j][k])
      }
    }
  }
  X := 10 * C + 1
  F := func(A, B []int, s bool, x int) int {
    X := 10 * C + 1
    a, b := 0, 0
    for a < len(A) && b < len(B) {
      if A[a] < B[b] {
        if s { X = MinInt((B[b] - A[a]) * x, X) }
        a++
      } else {
        if !s { X = MinInt((A[a] - B[b]) * x, X) }
        b++
      }
    }
    return X
  }
  for k := 0; k <= 2 * C; k++ {
    X = MinInt(F(D[0][0][k], D[0][2][k], true, 5), X)
    X = MinInt(F(D[1][1][k], D[1][3][k], true, 5), X)
    X = MinInt(F(D[2][0][k], D[2][3][k], true, 10), X)
    X = MinInt(F(D[2][1][k], D[2][2][k], true, 10), X)
    X = MinInt(F(D[3][0][k], D[3][1][k], false, 10), X)
    X = MinInt(F(D[3][2][k], D[3][3][k], true, 10), X)
  }
  if X > 10 * C {
    Write("SAFE")
  } else {
    Write(X)
  }
}

func main() {
  Solve()
  Output()
}

var reader = bufio.NewReaderSize(os.Stdin, 1000000)
var writer = bufio.NewWriter(os.Stdout)
func NextLine() string {
  buffer := make([]byte, 0)
  for true {
    line, isPrefix, err := reader.ReadLine()
    if err != nil { panic(err) }
    buffer = append(buffer, line...)
    if !isPrefix { break }
  }
  return string(buffer)
}
func NextInt(A ...*int) {
  L := strings.Split(NextLine(), " ")
  for i, a := range A {
    *a, _ = strconv.Atoi(L[i])
  }
}
func NextIntSlice(A *[]int) {
  L := strings.Split(NextLine(), " ")
  if len(L) == 1 && L[0] == "" {
    (*A) = make([]int, 0)
    return
  }
  (*A) = make([]int, len(L))
  for i, l := range L {
    (*A)[i], _ = strconv.Atoi(l)
  }
}
func NextFloat(A ...*float64) {
  L := strings.Split(NextLine(), " ")
  for i, a := range A {
    *a, _ = strconv.ParseFloat(L[i], 64)
  }
}
func NextFloatSlice(A *[]float64) {
  L := strings.Split(NextLine(), " ")
  if len(L) == 1 && L[0] == "" {
    (*A) = make([]float64, 0)
    return
  }
  (*A) = make([]float64, len(L))
  for i, l := range L {
    (*A)[i], _ = strconv.ParseFloat(l, 64)
  }
}
func Write(S ...interface{}) {
  fmt.Fprintln(writer, S...)
}
func WriteIntSlice(A []int) {
  B := make([]interface{}, len(A))
  for i, a := range A { B[i] = a }
  fmt.Fprintln(writer, B...)
}
func Output() {
  _ = writer.Flush()
}
func MaxInt(A ...int) int {
  max := A[0]
  for _, a := range A {
    if max < a { max = a }
  }
  return max
}
func MinInt(A ...int) int {
  min := A[0]
  for _, a := range A {
    if a < min { min = a }
  }
  return min
}
func SumInt(A ...int) int {
  sum := 0
  for _, a := range A {
    sum += a
  }
  return sum
}
func AbsInt(x int) int {
  if x < 0 { x = -x }
  return x
}

Measured memory_bytes: 396028