Buggy python submission (verdict: Time Limit Exceeded):
#root.search(x): ◯.data == x のものが存在するある場合それを出力、ない場合Noneを出力
#root.insert(x): ◯.data == xが存在する場合Falseを出力、ない場合◯.data == x なる頂点を作る
#y.to_s(): 頂点yのdataを出力
#y.left_s(): 頂点yのleftを出力(ない場合はNone)
#root.search_lower(x,None): ○.dataがxより小さいものの中で最も大きいものを出力、ない場合Noneを出力
#root.search_higher(x,None): xより大きいものの中で最も小さいものを出力、ない場合Noneを出力

################################################################################
class Avltree:
    def __init__(self,key=None):
        self.key = key
        self.left = None
        self.right = None 
        self.balance = "Even"
    def search(self,key):
        if self.key == None:
            return None
        if self.key > key:
            if self.left == None:
                return None
            else:
                return self.left.search(key)
        if self.key < key:
            if self.right == None:
                return None
            else:
                return self.right.search(key)
        return self # self.key == keyの場合
        
    def search_lower(self,key,key_lower):
        if self.key == None:
            return key_lower
        if self.key > key:
            if self.left == None:
                return key_lower
            else:
                return self.left.search_lower(key,key_lower)
        if self.key < key:
            key_lower = self.key
            if self.right == None:
                return key_lower
            else:
                return self.right.search_lower(key,key_lower)
        #self.key == keyの場合
        if self.left == None:
            return key_lower
        else:
            if key_lower == None:
                return self.left.end_higher(self.left.key)
            else:
                return max(key_lower,self.left.end_higher(self.left.key))
    
    def search_higher(self,key,key_higher):
        if self.key == None:
            return key_higher
        if self.key > key:
            key_higher = self.key
            if self.left == None:
                return key_higher
            else:
                return self.left.search_higher(key,key_higher)
        if self.key < key:
            if self.right == None:
                return key_higher
            else:
                return self.right.search_higher(key,key_higher)
        #self.key == keyの場合
        if self.right == None:
            return key_higher
        else:
            if key_higher == None:
                return self.right.end_lower(self.right.key)
            else:
                return min(key_higher,self.right.end_lower(self.right.key))
        
    
    def end_lower(self,end_lower_key):
        if self.left == None:
            return end_lower_key
        else:
            end_lower_key = self.left.key
            return self.left.end_lower(end_lower_key)
    def end_higher(self,end_higher_key):
        if self.right == None:
            return end_higher_key
        else:
            end_higher_key = self.right.key
            return self.right.end_higher(end_higher_key)
    
            
    def DoubleRightRotation(self):
        tl = self.left
        self.left = tl.right.right
        tl.right.right = self # selfはそのノード
        tlr = tl.right
        tl.right = tlr.left
        tlr.left = tl
        if tlr.balance == "Left":
            tlr.right.balance = "Right"
            tlr.left.balance = "Even"
        elif tlr.balance == "Right":
            tlr.right.balance = "Even"
            tlr.left.balance = "Left"
        elif tlr.balance == "Even":
            tlr.right.balance = "Even"
            tlr.left.balance = "Even"
        tlr.balance = "Even"
        return tlr
    def DoubleLeftRotation(self):
        tr = self.right
        self.right = tr.left.left
        tr.left.left = self
        trl = tr.left
        tr.left = trl.right
        trl.right = tr
        if trl.balance == "Right":
            trl.left.balance = "Left"
            trl.right.balance = "Even"
        elif trl.balance == "Left":
            trl.left.balance = "Even"
            trl.right.balance = "Right"
        elif trl.balance == "Even":
            trl.left.balance = "Even"
            trl.right.balance = "Even"
        trl.balance = "Even"
        return trl
    def SingleLeftRotation(self):
        tr = self.right
        tr.balance = "Even"
        self.balance = "Even"
        self.right = tr.left
        tr.left = self
        return tr
    def SingleRightRotation(self):
        tl = self.left
        tl.balance = "Even"
        self.balance = "Even"
        self.left = tl.right
        tl.right = self
        return tl
    def replace(self,p,v): # 親ノードpの下にある自分(self)をvに置き換える。
        if p.left == self:
            p.left = v
        else :
            p.right = v 
    def insert(self,key): # rootでのみ呼ばれる挿入
        if self.key == None: # rootを含むrotationはしないことにする。
            self.key = key
            return self
        if key < self.key:
            if self.left == None:
                self.left = Avltree(key)
            else:
                self.left.insertx(self,key)
        elif key > self.key:
            if self.right == None:
                self.right = Avltree(key)
            else:
                self.right.insertx(self,key)
        else: # key == self.key:
            pass # do not overwrite
    def insertx(self,p,key): # replaceを呼ぶために一つ上の親を持っているinsert
        if self.key > key:
            if self.left == None:
                self.left = Avltree(key)
            else:
                if not self.left.insertx(self, key): # 左の木が生長しなければ、
                    return False # 成長しない
            if self.balance == "Right":
                self.balance = "Even"
                return False
            elif self.balance == "Even":
                self.balance = "Left"
                return True # 成長した
            elif self.balance == "Left":
                if self.left.balance == "Right":
                    self.replace(p,self.DoubleRightRotation())
                elif self.left.balance == "Left":
                    self.replace(p,self.SingleRightRotation())
                return False # rotationを行うと成長しない
        if self.key < key:
            if self.right == None:
                self.right = Avltree(key)
            else:
                if not self.right.insertx(self, key):
                    return False 
            if self.balance == "Left":
                self.balance = "Even"
                return False
            elif self.balance == "Even":
                self.balance = "Right"
                return True
            elif self.balance == "Right":
                if self.right.balance == "Left": 
                    self.replace(p,self.DoubleLeftRotation())
                elif self.right.balance == "Right":
                    self.replace(p,self.SingleLeftRotation())
                return False
        return False # self.key == keyの時は何もしないので成長もしない 

    def to_s(self):
        return self.key
    def left_s(self):
        if self.left == None:
            return None
        return (self.left).key
    def right_s(self):
        if self.right == None:
            return None
        return (self.right).key
import sys
input = sys.stdin.readline
from collections import defaultdict
# d = defaultdict(int)で0で初期化
# d = defaultdict(lambda: 100)で100で初期化
n = int(input())
a = [list(input().split()) for i in range(n)]
for i in range(n):
    if a[i][2] == "R":
        a[i][2] = 1
    elif a[i][2] == "L":
        a[i][2] = 2
    elif a[i][2] == "U" :
        a[i][2] = 3
    else:
        a[i][2] = 4
    a[i][0] = int(a[i][0])
    a[i][1] = int(a[i][1])
a.sort(key=lambda x: x[2])
R1 = defaultdict(Avltree)
R2 = defaultdict(Avltree)
L1 = defaultdict(Avltree)
L2 = defaultdict(Avltree)
U = defaultdict(Avltree)
R = defaultdict(Avltree)

M=10000000
for x, y, u in a:
    if u == 1:
        R1[y - x].insert(x)
        R2[x + y].insert(x)
        R[y].insert(x)
    elif u == 2:
        L1[x + y].insert(x)
        L2[y - x].insert(x)
        k = R[y].search_lower(x, None)
        if k!=None:
            M = min((x - k) * 5, M)

    if u == 3:
        k = L2[y - x].search_higher(x, None)
        if k!=None:
            M = min(M, (k - x) * 10)
        
        k = R2[x + y].search_lower(x, None)
        if k!=None:
            M = min(M, (x - k) * 10)
        
        U[x].insert(y)
    if u == 4:
        k = L1[x + y].search_higher(x, None)
        if k!=None:
            M = min(M, (k - x) * 10)

        k = R1[y - x].search_lower(x, None)
        if k!=None:
            M = min(M, (x - k) * 10)

        k = U[x].search_lower(y, None)
        if k!=None:
            M = min(M, (y - k) * 5)
print(M if M < 10000000 else "SAFE")

Fixed submission:
import sys
input = sys.stdin.readline
from collections import defaultdict
from bisect import bisect_right
n = int(input())
a = [list(input().split()) for i in range(n)]
for i in range(n):
    if a[i][2] == "R":
        a[i][2] = 1
    elif a[i][2] == "L":
        a[i][2] = 2
    elif a[i][2] == "U" :
        a[i][2] = 3
    else:
        a[i][2] = 4
    a[i][0] = int(a[i][0])
    a[i][1] = int(a[i][1])
a.sort(key=lambda x: x[2])
R1 = defaultdict(list)
R2 = defaultdict(list)
L1 = defaultdict(list)
L2 = defaultdict(list)
U = defaultdict(list)
R = defaultdict(list)

R1u = defaultdict(bool)
R2u = defaultdict(bool)
L1u = defaultdict(bool)
L2u = defaultdict(bool)
Uu = defaultdict(bool)
Ru = defaultdict(bool)


M = 10000000
for x, y, u in a:
    if u == 1:
        R1[y - x].append(x)
        R2[x + y].append(x)
        R[y].append(x)
    elif u == 2:
        L1[x + y].append(x)
        L2[y - x].append(x)
        if not Ru[y]:
            R[y].sort()
            Ru[y] = True
        k = bisect_right(R[y], x)
        if k > 0:
            M = min((x - R[y][k-1]) * 5, M)

    elif u == 3:
        if not L2u[y - x]:
            L2[y - x].sort()
            L2u[y - x] = True
        k = bisect_right(L2[y - x], x)
        if k < len(L2[y - x]):
            M = min(M, (L2[y - x][k] - x) * 10)
        
        if not R2[x + y]:
            R2[x + y].sort()
            R2u[x + y] = True
        k = bisect_right(R2[x + y], x)
        if k > 0:
            M = min(M, (x - R2[x + y][k-1]) * 10)
        
        U[x].append(y)
    else:
        if not L1u[x + y]:
            L1[x + y].sort()
            L1u[x + y] = True
        k = bisect_right(L1[x + y], x)
        if k < len(L1[x + y]):
            M = min(M, (L1[x + y][k] - x) * 10)

        if not R1u[y - x]:
            R1[y - x].sort()
            R1u[y - x] = True
        k = bisect_right(R1[y - x], x)
        if k > 0:
            M = min(M, (x - R1[y - x][k-1]) * 10)

        if not Uu[x]:
            U[y].sort()
            Uu[y] = True
        k = bisect_right(U[x], y)
        if k > 0 :
            M = min((y - U[x][k-1]) * 5, M)
print(M if M < 10000000 else "SAFE")