#include<bits/stdc++.h>
using namespace std;
int const nax = 8e5 + 10;
const int C = 2e5 + 10;

struct pt {
    int x, y;
    char dir;

    void read () {
        scanf("%d %d %c", &x, &y, &dir);
    }

    friend bool operator == (pt a, pt b) {
        return a.x == b.x && a.y == b.y;
    }

    friend bool operator != (pt a, pt b) {
        return !(a == b);
    }
};

bool sort_by_x (pt a, pt b) {
    return a.x < b.x;
}

bool sort_by_y (pt a, pt b) {
    return a.y < b.y;
}

const pt invalid = pt{-INT_MAX, -INT_MAX, '#'};
int ans = INT_MAX;

int n;

pt p[nax];

void solveLR () {
    vector <pt> a[nax];

    for (int i = 1 ; i <= n ; ++ i) {
        a[p[i].y].push_back(p[i]);
    }

    for (int i = 1 ; i < nax ; ++ i) {
        if (a[i].empty()) continue;

        pt next_l = invalid;
        auto &b = a[i];
        sort(b.begin(), b.end(), sort_by_x);
        for (int i = int(b.size()) - 1 ; i >= 0 ; -- i) {
            if (b[i].dir == 'R') {
                if (next_l != invalid) {
                    ans = min(ans, (next_l.x - b[i].x) * 5);
                }
            }
            if (b[i].dir == 'L') next_l = b[i];
        }
    }
}

void solveUD () {
    vector <pt> a[nax];

    for (int i = 1 ; i <= n ; ++ i) {
        a[p[i].x].push_back(p[i]);
    }

    for (int i = 1 ; i < nax ; ++ i) {
        if (a[i].empty()) continue;

        pt next_d = invalid;
        auto &b = a[i];
        sort(b.begin(), b.end(), sort_by_y);
        for (int i = int(b.size()) - 1 ; i >= 0 ; -- i) {
            if (b[i].dir == 'U') {
                if (next_d != invalid) {
                    ans = min(ans, (next_d.y - b[i].y) * 5);
                }
            }
            if (b[i].dir == 'D') next_d = b[i];
        }
    }
}

void solveULandDR() {
    vector <pt> a[nax];

    for (int i = 1 ; i <= n ; ++ i) {
        a[C + p[i].y - p[i].x].push_back(p[i]);
    }

    for (int i = 0 ; i < nax ; ++ i) {
        if (a[i].empty()) continue;
        auto &b = a[i];
        sort(b.begin(), b.end(), sort_by_x);
        pt next_l = invalid;
        pt next_d = invalid;

        for (int i = int(b.size()) - 1 ; i >= 0 ; -- i) {
            if (b[i].dir == 'R') {
                if (next_d != invalid) {
                    ans = min(ans, (next_d.x - b[i].x) * 10);
                }
            }

            if (b[i].dir == 'U') {
                if (next_l != invalid) {
                    ans = min(ans, (next_l.x - b[i].x) * 10);
                }
            }

            if (b[i].dir == 'L')
                next_l = b[i];
            if (b[i].dir == 'D')
                next_d = b[i];
        }
    }
}


void solveURandDL () {
    vector <pt> a[nax];

    for (int i = 1 ; i <= n ; ++ i) {
        a[p[i].x + p[i].y].push_back(p[i]);
    }

    for (int i = 0 ; i < nax ; ++ i) {
        if (a[i].empty()) continue;
        auto &b = a[i];
        sort(b.begin(), b.end(), sort_by_x);
        pt last_r = invalid;
        pt last_d = invalid;

        for (int i = 0 ; i < int(b.size()) ; ++ i) {
            if (b[i].dir == 'U') {
                if (last_r != invalid) {
                    ans = min(ans, (b[i].x - last_r.x) * 10);
                }
            }

            if (b[i].dir == 'L') {
                if (last_d != invalid)
                    ans = min(ans, (b[i].x - last_d.x) * 10);
            }

            if (b[i].dir == 'D')
                last_d = b[i];

            if (b[i].dir == 'R')
                last_r = b[i];
        }
    }
}


int main () {

    scanf("%d", &n);
    for (int i = 1 ; i <= n ; ++ i) {
        p[i].read();
    }

    solveLR();
    solveUD();
    solveULandDR();
    solveURandDL();

    if (ans == INT_MAX) {
        printf("SAFE\n");
    } else printf("%d\n", ans);
}
/*
    Good Luck
        -Lucina
*/


Measured memory_bytes: 32292