### BUGGY CODE ###

import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**9)

INF = 10**10
M = 4*10**5 + 10

N = int(input())
PUs = [[] for _ in range(M)]
PRs = [[] for _ in range(M)]
PDs = [[] for _ in range(M)]
PLs = [[] for _ in range(M)]
nUs = [[] for _ in range(M)]
nRs = [[] for _ in range(M)]
nDs = [[] for _ in range(M)]
nLs = [[] for _ in range(M)]
xUs = [[] for _ in range(M)]
xDs = [[] for _ in range(M)]
yLs = [[] for _ in range(M)]
yRs = [[] for _ in range(M)]

for _ in range(N):
    X, Y, U = input().split()
    X, Y = int(X), int(Y)
    if U == 'L':
        PLs[X+Y].append((X, U))
        nLs[X-Y].append((X, U))
        yLs[Y].append((X, U))
    elif U == 'R':
        PRs[X+Y].append((X, U))
        nRs[X-Y].append((X, U))
        yRs[Y].append((X, U))
    elif U == 'U':
        PUs[X+Y].append((X, U))
        nUs[X-Y].append((X, U))
        xUs[X].append((Y, U))
    else:  # U == 'D'
        PDs[X+Y].append((X, U))
        nDs[X-Y].append((X, U))
        xDs[X].append((Y, U))

def func(P1s, P2s, dir1, dir2):
    dist = INF
    for z in range(M):
        Ps = sorted(P1s[z] + P2s[z])
        for i in range(len(Ps)-1):
            if Ps[i][1] == dir1 and Ps[i+1][1] == dir2:
                d = Ps[i+1][0] - Ps[i][0]
                if d < dist:
                    dist = d
    return dist

ans = INF
dists = []
dists += [func(PRs, PUs, 'R', 'U') * 2]
dists += [func(PDs, PLs, 'D', 'L') * 2]
dists += [func(nRs, nDs, 'R', 'D') * 2]
dists += [func(nUs, nLs, 'U', 'L') * 2]
dists += [func(yRs, yLs, 'R', 'L')]
dists += [func(xUs, xDs, 'U', 'D')]

ans = min(dists)
if ans == INF:
    print('SAFE')
else:
    print(ans*5)


### FIXED CODE ###

import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**9)

INF = 10**10
M = 4*10**5 + 10

N = int(input())
PUs = [[] for _ in range(M)]
PRs = [[] for _ in range(M)]
PDs = [[] for _ in range(M)]
PLs = [[] for _ in range(M)]
nUs = [[] for _ in range(M)]
nRs = [[] for _ in range(M)]
nDs = [[] for _ in range(M)]
nLs = [[] for _ in range(M)]
xUs = [[] for _ in range(M)]
xDs = [[] for _ in range(M)]
yLs = [[] for _ in range(M)]
yRs = [[] for _ in range(M)]

for _ in range(N):
    X, Y, U = input().split()
    X, Y = int(X), int(Y)
    if U == 'L':
        PLs[X+Y].append((X, U))
        nLs[X-Y].append((X, U))
        yLs[Y].append((X, U))
    elif U == 'R':
        PRs[X+Y].append((X, U))
        nRs[X-Y].append((X, U))
        yRs[Y].append((X, U))
    elif U == 'U':
        PUs[X+Y].append((X, U))
        nUs[X-Y].append((X, U))
        xUs[X].append((Y, U))
    else:  # U == 'D'
        PDs[X+Y].append((X, U))
        nDs[X-Y].append((X, U))
        xDs[X].append((Y, U))

def func(P1s, P2s, dir1, dir2):
    dist = INF
    for z in range(M):
        Ps = sorted(P1s[z] + P2s[z])
        for i in range(len(Ps)-1):
            if Ps[i][1] == dir1 and Ps[i+1][1] == dir2:
                d = Ps[i+1][0] - Ps[i][0]
                if d < dist:
                    dist = d
    return dist

ans = INF
dists = []
dists += [func(PRs, PUs, 'R', 'U') * 2]
dists += [func(PDs, PLs, 'D', 'L') * 2]
dists += [func(nRs, nDs, 'R', 'D') * 2]
dists += [func(nUs, nLs, 'U', 'L') * 2]
dists += [func(yRs, yLs, 'R', 'L')]
dists += [func(xUs, xDs, 'U', 'D')]

ans = min(dists)
if ans == INF:
    print('SAFE')
else:
    print(ans*5)