OI XXIX - bom

// https://szkopul.edu.pl/problemset/problem/MfTrGDTrlrVX21vwwhgsjaLv/site/?key=statement

// Bomberman

#include <bits/stdc++.h>

using namespace std;

#define int long long

constexpr int sizik = 1007;

#define ar std::array
#define pr std::pair
#define vec std::vector

typedef vec<vec<int>> _kra;

// #define GARY_DBG

constexpr int UP = 1, DOWN = 2, LEFT = 3, RIGHT = 4, BOTH_X = 5, BOTH_Y = 6;

// [x][y]
ar<ar<char, sizik>, sizik> mapa;
ar<ar<ar<int, sizik>, sizik>, 7> visited;
ar<ar<ar<ar<int, 3>, sizik>, sizik>, 7> dir;

struct Point {
    int x, y;
    Point(int x1, int y1) : x(x1), y(y1) { ; }
    bool operator!=(const Point& a) const { return (a.x != this->x) || (a.y != this->y); }
};

struct Q : Point {
    int w, d, q, qq, bw;
    Q(int x1, int y1, int w1, int d1, int q1, int qq1, int bw1) : Point(x1, y1), w(w1), d(d1), q(q1), qq(qq1), bw(bw1) { ; }
};

struct cmp {
    bool operator()(const Q& a, const Q& b) const { return a.d > b.d; }
};

typedef std::priority_queue<Q, vec<Q>, cmp> Queue;
int n;

void go_norm(const Q& o, Queue& q) {
    if (o.w == 0) {
        if ((mapa[o.x - 1][o.y] == '#')) {
            q.push({o.x - 1, o.y, 1, o.d + 1, LEFT, 1, o.w});
        }

        if ((mapa[o.x + 1][o.y] == '#')) {
            q.push({o.x + 1, o.y, 1, o.d + 1, RIGHT, 1, o.w});
        }

        if ((mapa[o.x][o.y - 1] == '#')) {
            q.push({o.x, o.y - 1, 1, o.d + 1, UP, 1, o.w});
        }

        if ((mapa[o.x][o.y + 1] == '#')) {
            q.push({o.x, o.y + 1, 1, o.d + 1, DOWN, 1, o.w});
        }
    }

    if (o.w == 1) {
        if ((mapa[o.x - 1][o.y] != 'X')) {
            q.push({o.x - 1, o.y, 5, o.d + 1, LEFT, 1, o.w});
        }

        if ((mapa[o.x + 1][o.y] != 'X')) {
            q.push({o.x + 1, o.y, 5, o.d + 1, RIGHT, 1, o.w});
        }

        if ((mapa[o.x][o.y - 1] != 'X')) {
            q.push({o.x, o.y - 1, 6, o.d + 1, UP, 1, o.w});
        }

        if ((mapa[o.x][o.y + 1] != 'X')) {
            q.push({o.x, o.y + 1, 6, o.d + 1, DOWN, 1, o.w});
        }
    }

    if (o.w == 5) {
        if ((mapa[o.x - 1][o.y] != 'X')) {
            q.push({o.x - 1, o.y, 5, o.d + 1, LEFT, 1, o.w});
        }

        if ((mapa[o.x + 1][o.y] != 'X')) {
            q.push({o.x + 1, o.y, 5, o.d + 1, RIGHT, 1, o.w});
        }

        if ((mapa[o.x][o.y - 1] != 'X')) {
            q.push({o.x, o.y - 1, 4, o.d + 1, UP, 1, o.w});
        }

        if ((mapa[o.x][o.y + 1] != 'X')) {
            q.push({o.x, o.y + 1, 4, o.d + 1, DOWN, 1, o.w});
        }
    }

    if (o.w == 6) {
        if ((mapa[o.x - 1][o.y] != 'X')) {
            q.push({o.x - 1, o.y, 2, o.d + 1, LEFT, 1, o.w});
        }

        if ((mapa[o.x + 1][o.y] != 'X')) {
            q.push({o.x + 1, o.y, 2, o.d + 1, RIGHT, 1, o.w});
        }

        if ((mapa[o.x][o.y - 1] != 'X')) {
            q.push({o.x, o.y - 1, 6, o.d + 1, UP, 1, o.w});
        }

        if ((mapa[o.x][o.y + 1] != 'X')) {
            q.push({o.x, o.y + 1, 6, o.d + 1, DOWN, 1, o.w});
        }
    }

    if (o.w == 2) {
        if ((mapa[o.x - 1][o.y] != 'X')) {
            q.push({o.x - 1, o.y, 2, o.d + 1, LEFT, 1, o.w});
        }

        if ((mapa[o.x + 1][o.y] != 'X')) {
            q.push({o.x + 1, o.y, 2, o.d + 1, RIGHT, 1, o.w});
        }

        if ((mapa[o.x][o.y - 1] != 'X') && (mapa[o.x][o.y - 1] != '#')) {
            q.push({o.x, o.y - 1, 3, o.d + 1, UP, 1, o.w});
        }

        if ((mapa[o.x][o.y + 1] != 'X') && (mapa[o.x][o.y + 1] != '#')) {
            q.push({o.x, o.y + 1, 3, o.d + 1, DOWN, 1, o.w});
        }
    }

    if (o.w == 4) {
        if ((mapa[o.x - 1][o.y] != 'X') && (mapa[o.x - 1][o.y] != '#')) {
            q.push({o.x - 1, o.y, 3, o.d + 1, LEFT, 1, o.w});
        }

        if ((mapa[o.x + 1][o.y] != 'X') && (mapa[o.x + 1][o.y] != '#')) {
            q.push({o.x + 1, o.y, 3, o.d + 1, RIGHT, 1, o.w});
        }

        if ((mapa[o.x][o.y - 1] != 'X')) {
            q.push({o.x, o.y - 1, 4, o.d + 1, UP, 1, o.w});
        }

        if ((mapa[o.x][o.y + 1] != 'X')) {
            q.push({o.x, o.y + 1, 4, o.d + 1, DOWN, 1, o.w});
        }
    }

    if (o.w == 0 || o.w == 3) {
        if ((mapa[o.x - 1][o.y] != '#') && mapa[o.x - 1][o.y] != 'X') {
            q.push({o.x - 1, o.y, o.w, o.d + 1, LEFT, 1, o.w});
        }

        if ((mapa[o.x + 1][o.y] != '#') && mapa[o.x + 1][o.y] != 'X') {
            q.push({o.x + 1, o.y, o.w, o.d + 1, RIGHT, 1, o.w});
        }

        if ((mapa[o.x][o.y - 1] != '#') && mapa[o.x][o.y - 1] != 'X') {
            q.push({o.x, o.y - 1, o.w, o.d + 1, UP, 1, o.w});
        }

        if ((mapa[o.x][o.y + 1] != '#') && mapa[o.x][o.y + 1] != 'X') {
            q.push({o.x, o.y + 1, o.w, o.d + 1, DOWN, 1, o.w});
        }
    }
}

void go_ab(const Q& o, Queue& q) {
    if (o.w == 1) {
        int j = o.y;
        for (; j > 0; j--) {
            if (mapa[o.x][j] == 'X') {
                j++;
                break;
            }
        }

        for (int i = j; i <= n; i++) {
            if (mapa[o.x][i] == 'X') break;
            if (i == o.y) continue;
            int k = abs(o.y - i);
            int dq = o.y > i ? DOWN : UP;
            q.push({o.x, i, 3, o.d + k, dq, k, o.w});
        }
    } else if (o.w == 2) {
        int j = o.x;
        for (; j > 0; j--) {
            if (mapa[j][o.y] == 'X') {
                j++;
                break;
            }
        }

        for (int i = j; i <= n; i++) {
            if (mapa[i][o.y] == 'X') break;
            if (i == o.x) continue;
            int k = abs(o.x - i);
            int dq = o.x > i ? LEFT : RIGHT;
            q.push({i, o.y, 3, o.d + k, dq, k, o.w});
        }
    }
}

void solve() {
    std::cin >> n;

    Point start{0, 0}, kuniec{0, 0};

    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            char c;
            std::cin >> c;

            mapa[j][i] = c;

            if (c == 'P') {
                start = {j, i};
            } else if (c == 'K') {
                kuniec = {j, i};
            }
        }
    }
    for (int i = 0; i <= n + 2; i++) {
        mapa[0][i] = 'X';
        mapa[i][0] = 'X';
        mapa[n + 1][i] = 'X';
        mapa[i][n + 1] = 'X';
    }

    /// Q(int x1, int y1, int w1, int d1, int q1, int qq1)
    Queue q;
    q.push({start.x, start.y, 0, 0, 0, 0, 0});
    while (!q.empty()) {
        const auto o = q.top();
        q.pop();

        if (visited[o.w][o.x][o.y] || o.x <= 0 || o.y <= 0 || o.x > n || o.y > n) continue;

        visited[o.w][o.x][o.y] = true;
        dir[o.w][o.x][o.y] = {o.q, o.qq, o.bw};

        if (o.w == 3 && o.x == kuniec.x && o.y == kuniec.y) break;

        go_norm(o, q);
    }

    // odzyskaj odp;
    std::string ans;
    Point bomb_ans = start;

    Point startex = kuniec;

    int prev_w = dir[3][kuniec.x][kuniec.y][0] == 0 ? 0 : 3;

    if (dir[prev_w][kuniec.x][kuniec.y][0] == 0) {
        std::cout << "NIE\n";
        return;
    }

    while (startex != start) {
        const auto [qdir, dir_cnt, last_w] = dir[prev_w][startex.x][startex.y];
        for (int i = 1; i <= dir_cnt; i++) {
            if (qdir == LEFT) {
                ans += 'L';
                startex.x++;
            } else if (qdir == RIGHT) {
                ans += 'P';
                startex.x--;
            } else if (qdir == UP) {
                ans += 'G';
                startex.y++;
            } else if (qdir == DOWN) {
                ans += 'D';
                startex.y--;
            }
        }

        if ((last_w == 5 && prev_w == 4) || (last_w == 6 && prev_w == 2)) {
            bomb_ans = startex;
        }
        prev_w = last_w;
    }

    std::reverse(ans.begin(), ans.end());

    std::cout << ans.size() << "\n" << bomb_ans.y << " " << bomb_ans.x << "\n" << ans << '\n';
}

int32_t main() {
    std::ios_base::sync_with_stdio(0);
    std::cin.tie(0);
    std::cout.tie(0);

    int t = 1;
    // std::cin >> t;

    for (; t > 0; t--) {
        solve();
    }

    return 0;
}