Problem:
パチモンクリーチャー
某国で
大人気のゲーム、パチモンクリーチャーが日本でリメイクされて発売されました。 ゲームが大好きなあなたは、  このゲームを
何度もプレイするうちにどうしたら最速でクリアできるのか考えるようになりました。しかし、いくら考えても最速の攻略方法がわからなかったあなたは、どれだけ早くゲームをクリアできるかを求めるプログラムを作成することにしました。
ゲームの詳細は以下の通りです。
パチモンクリーチャー(以下、パチクリ)という生物が多く存在する世界がゲームの舞台です。各パチクリは、火属性、氷属性、木属性、土属性、水属性の 5 種類の属性のいずれか１つの属性を持ちます。ゲームの主人公は、ゲーム開始時に好きな属性のパチクリ一匹を冒険のパートナーとして選びます。そのパチクリと共にゴールを目指し、ゴールにいるライバルを倒してパチクリマスターになることがゲームの目的です。
しかし、ライバルを倒すためには全属性のパチクリがいないと勝てないので、途中で全属性のパチクリを捕まえなければなりません。パチクリを捕まえるには属性がカギとなります。火属性のパチクリは氷属性のパチクリを捕まえることができ、同様に、氷属性は木属性、木属性は土属性、土属性は水属性、水属性は火属性を捕まえることができます。属性の関連は以下の図のようになります。
以下の図はゲームが行われるマップの一例を表しています。
主人公はパチクリを一匹もってスタート地点である「S」から出発し、一マスずつ移動しながらゴール地点である「G」を目指します。その途中で、最初に持っているパチクリ以外の 4 つの属性のパチクリを捕まえ、ゴール地点であるマス目に移動するとゲーム終了となります。
主人公は、今いるマス目から、辺を共有する隣のマス目に移動することができ、それを一回の移動と数えます。主人公がパチクリのいるマスに移動した場合、そのパチクリを捕まえられる属性のパチクリを持っていればそのパチクリを捕まえたことになります。そのマスにいるパチクリを捕まえられるかの可否にかかわらず、すべてのマスに何度でも移動することができます。
マップの大きさ(横方向の列数、縦方向の行数)とマップの初期状態を入力とし、初めに選んだパチクリの属性と、それ以外の 4 つの属性のパチクリを捕まえるのにかかる、スタート地点からゴール地点に至る最小移動数を出力するプログラムを作成してください。
Input
複数のデータセットの並びが入力として与えられます。入力の終りはゼロふたつの行で示されます。各データセットは以下の形式で与えられます。
W
H
c
11
c
12
...
c
1W
c
21
c
22
...
c
2W
:
c
H1
c
H2
...
c
HW
1 行目にマップの横方向の列数
W
と縦方向の行数
H
(2 ≤
W, H
≤ 1000) が与えられます。続く
H
行にマップの
i
行目の情報が与えられます。入力されるマップには各マスの状態が与えられます。     「S」は主人公のスタート地点を、  「G」はゴール地点を、「1」「2」「3」「4」「5」はそこにいるパチクリの属性を( 1:火属性、 2:氷属性、    3:木属性、 4:土属性、 5:水属性 をそれぞれ表します)、 「.(ピリオド) 」は何もないマスをそれぞれ表します。 
各属性のパチクリの数はそれぞれ 0 以上 1000 以下とします。
データセットの数は140 を超えません。また、データセットの 80 % について、
W, H
は100 を超えません。
Output
入力データセットごとに、最初に選んだパチクリの属性と最小移動数を１行に出力します。なお、どのように初めのパチクリを選んでも、どのような経路で移動してもそれら 4 つの属性のパチクリを捕まえることができない場合は NA と出力してください。  また、最小移動数が同じになるような最初のパチクリの選び方が複数ある場合は、属性の数字が小さいものを出力してください。
Sample Input
6 6
S.1..4
3..5..
..4.1.
4....5
.2.32.
5.1..G
3 2
...
S.G
0 0
Output for the Sample Input
2 10
NA

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int W, H;
    while (cin >> W >> H) {
        if (W == 0 && H == 0) break;

        vector<string> g(H);
        for (int r = 0; r < H; ++r) cin >> g[r];

        int sr = -1, sc = -1, gr = -1, gc = -1;
        int cnt[6] = {0}; // сколько клеток с типом 1..5

        for (int r = 0; r < H; ++r)
            for (int c = 0; c < W; ++c) {
                char ch = g[r][c];
                if (ch == 'S') { sr = r; sc = c; }
                else if (ch == 'G') { gr = r; gc = c; }
                else if ('1' <= ch && ch <= '5') cnt[ch - '0']++;
            }


        int  ok = 0;
        for (int t = 1; t <= 5; ++t)
            if (cnt[t] == 0) { ok++; }

        if(ok>=2) {
            cout << "NA\n";
            continue;
        }
        int bestStart = -1;
        int bestDist  = INT_MAX;
        const int dr[4] = {-1, 1, 0, 0};
        const int dc[4] = {0, 0, -1, 1};

        // Перебираем стартовую стихию s = 1..5
        for (int s = 1; s <= 5; ++s) {


            vector<vector<array<int,5>>> dist(H, vector<array<int,5>>(W));
            for (int r = 0; r < H; ++r)
                for (int c = 0; c < W; ++c)
                    for (int k = 0; k < 5; ++k)
                        dist[r][c][k] = -1;

            queue<tuple<int,int,int>> q;
            dist[sr][sc][0] = 0;
            q.emplace(sr, sc, 0);

            int reached = -1;

            while (!q.empty()) {
                auto [r, c, k] = q.front(); q.pop();

                if (r == gr && c == gc && k == 4) {
                    reached = dist[r][c][k];
                    break; // BFS: это минимум для данного s
                }

                int nextType = ((s - 1 + (k + 1)) % 5) + 1; // 1..5

                for (int mv = 0; mv < 4; ++mv) {
                    int nr = r + dr[mv], nc = c + dc[mv];
                    if (nr < 0 || nr >= H || nc < 0 || nc >= W) continue;

                    int nk = k;
                    char ch = g[nr][nc];
                    if (k < 4 && ch >= '1' && ch <= '5') {
                        if (ch - '0' == nextType) nk = k + 1;
                    }

                    if (dist[nr][nc][nk] == -1) {
                        dist[nr][nc][nk] = dist[r][c][k] + 1;
                        q.emplace(nr, nc, nk);
                    }
                }
            }

            if (reached != -1) {
                if (reached < bestDist || (reached == bestDist && s < bestStart)) {
                    bestDist = reached;
                    bestStart = s;
                }
            }
        }

       
            cout << bestStart << ' ' << bestDist << '\n';
        
    }
}
accuracy: 1
time_ms: 2670
memory_kb: 23984
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int W, H;
    while (cin >> W >> H) {
        if (W == 0 && H == 0) break;

        vector<string> g(H);
        for (int r = 0; r < H; ++r) cin >> g[r];

        int sr = -1, sc = -1, gr = -1, gc = -1;
        int cnt[6] = {0}; // сколько клеток с типом 1..5

        for (int r = 0; r < H; ++r)
            for (int c = 0; c < W; ++c) {
                char ch = g[r][c];
                if (ch == 'S') { sr = r; sc = c; }
                else if (ch == 'G') { gr = r; gc = c; }
                else if ('1' <= ch && ch <= '5') cnt[ch - '0']++;
            }

        const int dr[4] = {-1, 1, 0, 0};
        const int dc[4] = {0, 0, -1, 1};

        int bestStart = -1;
        int bestDist  = INT_MAX;
        int  ok = 0;
        for (int t = 1; t <= 5; ++t)
            if (cnt[t] == 0) { ok++; }
            
        if(ok>=2) {
            cout << "NA\n";
            continue;
        }
        // Перебираем стартовую стихию s = 1..5
        for (int s = 1; s <= 5; ++s) {
            
            // Быстрая отсечка: 4 остальные стихи должны присутствовать

            // dist[r][c][k], k=0..4 — сколько стихий подряд собрано
            vector<vector<array<int,5>>> dist(H, vector<array<int,5>>(W));
            for (int r = 0; r < H; ++r)
                for (int c = 0; c < W; ++c)
                    for (int k = 0; k < 5; ++k)
                        dist[r][c][k] = -1;

            queue<tuple<int,int,int>> q;
            dist[sr][sc][0] = 0;
            q.emplace(sr, sc, 0);

            int reached = -1;

            while (!q.empty()) {
                auto [r, c, k] = q.front(); q.pop();

                if (r == gr && c == gc && k == 4) {
                    reached = dist[r][c][k];
                    break; // BFS: это минимум для данного s
                }

                int nextType = ((s - 1 + (k + 1)) % 5) + 1; // 1..5

                for (int mv = 0; mv < 4; ++mv) {
                    int nr = r + dr[mv], nc = c + dc[mv];
                    if (nr < 0 || nr >= H || nc < 0 || nc >= W) continue;

                    int nk = k;
                    char ch = g[nr][nc];
                    if (k < 4 && ch >= '1' && ch <= '5') {
                        if (ch - '0' == nextType) nk = k + 1;
                    }

                    if (dist[nr][nc][nk] == -1) {
                        dist[nr][nc][nk] = dist[r][c][k] + 1;
                        q.emplace(nr, nc, nk);
                    }
                }
            }

            if (reached != -1) {
                if (reached < bestDist || (reached == bestDist && s < bestStart)) {
                    bestDist = reached;
                    bestStart = s;
                }
            }
        }

        if (bestStart == -1) {
            cout << "NA\n";
        } else {
            cout << bestStart << ' ' << bestDist << '\n';
        }
    }
    return 0;
}
accuracy: 1
time_ms: 2620
memory_kb: 23996
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int W, H;
    while (cin >> W >> H) {
        if (W == 0 && H == 0) break;

        vector<string> g(H);
        for (int r = 0; r < H; ++r) cin >> g[r];

        int sr = -1, sc = -1, gr = -1, gc = -1;
        int cnt[6] = {0}; // сколько клеток с типом 1..5

        for (int r = 0; r < H; ++r)
            for (int c = 0; c < W; ++c) {
                char ch = g[r][c];
                if (ch == 'S') { sr = r; sc = c; }
                else if (ch == 'G') { gr = r; gc = c; }
                else if ('1' <= ch && ch <= '5') cnt[ch - '0']++;
            }

        const int dr[4] = {-1, 1, 0, 0};
        const int dc[4] = {0, 0, -1, 1};

        int bestStart = -1;
        int bestDist  = INT_MAX;

        // Перебираем стартовую стихию s = 1..5
        for (int s = 1; s <= 5; ++s) {
            // Быстрая отсечка: 4 остальные стихи должны присутствовать
            bool ok = true;
            for (int t = 1; t <= 5; ++t) if (t != s) {
                if (cnt[t] == 0) { ok = false; break; }
            }
            if (!ok) continue;

            // dist[r][c][k], k=0..4 — сколько стихий подряд собрано
            vector<vector<array<int,5>>> dist(H, vector<array<int,5>>(W));
            for (int r = 0; r < H; ++r)
                for (int c = 0; c < W; ++c)
                    for (int k = 0; k < 5; ++k)
                        dist[r][c][k] = -1;

            queue<tuple<int,int,int>> q;
            dist[sr][sc][0] = 0;
            q.emplace(sr, sc, 0);

            int reached = -1;

            while (!q.empty()) {
                auto [r, c, k] = q.front(); q.pop();

                if (r == gr && c == gc && k == 4) {
                    reached = dist[r][c][k];
                    break; // BFS: это минимум для данного s
                }

                int nextType = ((s - 1 + (k + 1)) % 5) + 1; // 1..5

                for (int mv = 0; mv < 4; ++mv) {
                    int nr = r + dr[mv], nc = c + dc[mv];
                    if (nr < 0 || nr >= H || nc < 0 || nc >= W) continue;

                    int nk = k;
                    char ch = g[nr][nc];
                    if (k < 4 && ch >= '1' && ch <= '5') {
                        if (ch - '0' == nextType) nk = k + 1;
                    }

                    if (dist[nr][nc][nk] == -1) {
                        dist[nr][nc][nk] = dist[r][c][k] + 1;
                        q.emplace(nr, nc, nk);
                    }
                }
            }

            if (reached != -1) {
                if (reached < bestDist || (reached == bestDist && s < bestStart)) {
                    bestDist = reached;
                    bestStart = s;
                }
            }
        }

        if (bestStart == -1) {
            cout << "NA\n";
        } else {
            cout << bestStart << ' ' << bestDist << '\n';
        }
    }
    return 0;
}
accuracy: 1
time_ms: 2630
memory_kb: 24052
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int W, H;
    while (cin >> W >> H) {
        if (W == 0 && H == 0) break;

        vector<string> grid(H);
        for (int r = 0; r < H; ++r) cin >> grid[r];

        int sr = -1, sc = -1, gr = -1, gc = -1;
        array<int, 6> cnt{}; // счётчики типов 1..5
        for (int r = 0; r < H; ++r) {
            for (int c = 0; c < W; ++c) {
                char ch = grid[r][c];
                if (ch == 'S') { sr = r; sc = c; }
                else if (ch == 'G') { gr = r; gc = c; }
                else if (ch >= '1' && ch <= '5') cnt[ch - '0']++;
            }
        }

        auto inside = [&](int r, int c) -> bool {
            return 0 <= r && r < H && 0 <= c && c < W;
        };
        const int N = W * H;   // клеток на слой
        const int LAYERS = 5;  // k = 0..4 (сколько стихий собрано)
        auto enc = [&](int r, int c, int k) -> int { return k * N + r * W + c; };

        const int dr[4] = {-1, 1, 0, 0};
        const int dc[4] = {0, 0, -1, 1};

        long long bestDist = LLONG_MAX;
        int bestStart = -1;

        for (int s = 1; s <= 5; ++s) {
            // Быстрая отсечка: все 4 остальные стихии должны присутствовать
            bool ok = true;
            for (int t = 1; t <= 5; ++t) if (t != s) {
                if (cnt[t] == 0) { ok = false; break; }
            }
            if (!ok) continue;

            vector<int> dist(LAYERS * N, -1);
            queue<int> q;

            int start = enc(sr, sc, 0);
            dist[start] = 0;
            q.push(start);

            int reachedDist = -1;

            while (!q.empty()) {
                int idx = q.front(); q.pop();
                int k = idx / N;
                int rc = idx % N;
                int r = rc / W;
                int c = rc % W;

                if (r == gr && c == gc && k == 4) {
                    reachedDist = dist[idx];
                    break; // BFS обеспечивает минимум
                }

                int nextType = ((s - 1 + k + 1) % 5) + 1; // следующая требуемая стихия (1..5)

                for (int mv = 0; mv < 4; ++mv) {
                    int nr = r + dr[mv], nc = c + dc[mv];
                    if (!inside(nr, nc)) continue;

                    int nk = k;
                    char ch = grid[nr][nc];
                    if (k < 4 && ch >= '1' && ch <= '5') {
                        int t = ch - '0';
                        if (t == nextType) nk = k + 1; // поймали следующую стихию
                    }

                    int nidx = enc(nr, nc, nk);
                    if (dist[nidx] == -1) {
                        dist[nidx] = dist[idx] + 1;
                        q.push(nidx);
                    }
                }
            }

            if (reachedDist != -1) {
                if (reachedDist < bestDist || (reachedDist == bestDist && s < bestStart)) {
                    bestDist = reachedDist;
                    bestStart = s;
                }
            }
        }

        if (bestStart == -1) {
            cout << "NA\n";
        } else {
            cout << bestStart << ' ' << bestDist << '\n';
        }
    }
    return 0;
}
accuracy: 1
time_ms: 3630
memory_kb: 53072
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;

struct FastQueue {
    // очередь индексов (int), без накладных расходов std::queue
    vector<int> data;
    size_t head = 0;
    void clear() { data.clear(); head = 0; }
    bool empty() const { return head >= data.size(); }
    void push(int x) { data.push_back(x); }
    int pop() { return data[head++]; }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int W, H;
    while ( (cin >> W >> H) ) {
        if (W == 0 && H == 0) break;

        vector<string> grid(H);
        for (int r = 0; r < H; ++r) cin >> grid[r];

        int sr = -1, sc = -1, gr = -1, gc = -1;
        array<int,6> cnt{}; // сколько клеток с типом 1..5
        for (int r = 0; r < H; ++r)
            for (int c = 0; c < W; ++c) {
                char ch = grid[r][c];
                if (ch == 'S') { sr = r; sc = c; }
                else if (ch == 'G') { gr = r; gc = c; }
                else if ('1' <= ch && ch <= '5') cnt[ch - '0']++;
            }

        auto inside = [&](int r, int c)->bool {
            return 0 <= r && r < H && 0 <= c && c < W;
        };
        const int N = W * H;
        const int LAYERS = 5; // k = 0..4

        // Кодирование состояния: idx = k*N + r*W + c
        auto enc = [&](int r, int c, int k)->int { return k * N + r * W + c; };

        // движение по сторонам
        const int dr[4] = {-1, 1, 0, 0};
        const int dc[4] = {0, 0, -1, 1};

        long long bestDist = LLONG_MAX;
        int bestStart = -1;

        // пробуем все стартовые стихии s = 1..5
        for (int s = 1; s <= 5; ++s) {
            // Быстрая проверка: 4 остальные стихии должны существовать на карте
            bool okCounts = true;
            for (int t = 1; t <= 5; ++t) if (t != s) {
                if (cnt[t] == 0) { okCounts = false; break; }
            }
            if (!okCounts) continue;

            // dist: -1 = не посещено; иначе число ходов
            vector<int> dist(LAYERS * N, -1);
            FastQueue q; q.clear();

            int startIdx = enc(sr, sc, 0);
            dist[startIdx] = 0;
            q.push(startIdx);

            int targetIdxDist = -1;

            while (!q.empty()) {
                int idx = q.pop();
                int k = idx / N;
                int rem = idx % N;
                int r = rem / W;
                int c = rem % W;

                if (r == gr && c == gc && k == 4) {
                    targetIdxDist = dist[idx];
                    break; // BFS гарантирует минимум
                }

                int nextType = ((s - 1 + k + 1) % 5) + 1; // 1..5

                for (int mv = 0; mv < 4; ++mv) {
                    int nr = r + dr[mv], nc = c + dc[mv];
                    if (!inside(nr, nc)) continue;
                    char ch = grid[nr][nc];

                    int nk = k;
                    if (k < 4 && ch >= '1' && ch <= '5') {
                        int t = ch - '0';
                        if (t == nextType) nk = k + 1; // поймали «следующую» стихию
                    }
                    int nidx = enc(nr, nc, nk);
                    if (dist[nidx] == -1) {
                        dist[nidx] = dist[idx] + 1;
                        q.push(nidx);
                    }
                }
            }

            if (targetIdxDist != -1) {
                if (targetIdxDist < bestDist || (targetIdxDist == bestDist && s < bestStart)) {
                    bestDist = targetIdxDist;
                    bestStart = s;
                }
            }
        }

        if (bestStart == -1) {
            cout << "NA\n";
        } else {
            cout << bestStart << " " << bestDist << "\n";
        }
    }
    return 0;
}
accuracy: 1
time_ms: 3750
memory_kb: 74308
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int w, h;
    while(cin >> w >> h, h){
        vector<string> A(h);
        int sy, sx, gy, gx, y1, x1, y2, x2, p = -1;
        deque<vector<pair<int,int>>> dq(5);
        for(int y = 0; y < h; y++){
            cin >> A[y];
            for(int x = 0; x < w; x++){
                if(A[y][x] == 'S')sy = y, sx = x;
                if(A[y][x] == 'G')gy = y, gx = x;
                if(A[y][x] >= '1' && A[y][x] <= '5'){
                    dq[A[y][x] - '1'].emplace_back(y, x);
                }
            }
        }
        int ans = 1 << 30, d;
        for(int i = 0; i < 5; i++){
            vector<vector<int>> dp(5);
            for(int j = 0; j < 5; j++)dp[j].resize(dq[j].size(), 1 << 30);
            for(int j = 0; j < dq[1].size(); j++){
                tie(y1, x1) = dq[1][j];
                dp[1][j] = abs(y1 - sy) + abs(x1 - sx);
            }
            for(int j = 1; j < 4; j++){
                for(int k = 0; k < dp[j].size(); k++){
                    tie(y1, x1) = dq[j][k];
                    for(int l = 0; l < dp[j + 1].size(); l++){
                        tie(y2, x2) = dq[j + 1][l];
                        dp[j + 1][l] = min(dp[j + 1][l], dp[j][k] + abs(y2 - y1) + abs(x2 - x1));
                    }
                }
            }
            d = 1 << 30;
            for(int j = 0; j < dp[4].size(); j++){
                tie(y1, x1) = dq[4][j];
                d = min(d, dp[4][j] + abs(y1 - gy) + abs(x1 - gx));
            }
            if(d < ans){
                ans = d;
                p = i + 1;
            }
            dq.push_back(dq.front());
            dq.pop_front();
        }
        if(p == -1)cout << "NA" << '\n';
        else cout << p << " " << ans << '\n';
    }
}
accuracy: 1
time_ms: 280
memory_kb: 4428
final_rank: 1

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <vector>

using namespace std;

const unsigned int inf = 0xffffffff;

class PcInfo {
public:
	int x;
	int y;
	unsigned int num_moves;

public:
	PcInfo() : x(-1), y(-1), num_moves(inf) {
	}

	~PcInfo() {
	}
};


int main(int argc, char** argv) {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif
	while (true) {
		int width = -1;
		int height = -1;
		const int num_pc = 5;
		int start_x = -1;
		int start_y = -1;
		int goal_x = -1;
		int goal_y = -1;
		int num_absent_pc = 0;
		unsigned int min_num_moves = inf;
		int min_num_moves_idx = -1;
		vector<vector<PcInfo>> pc_infos(num_pc);
		vector<int> init_pc_idx_vec;
		string buf;

		cin >> width >> height;
		if (width == 0 && height == 0) {
			break;
		}

		for (int y = 0; y < height; y++) {
			cin >> buf;
			for (int x = 0; x < width; x++) {
				if ('1' <= buf[x] && buf[x] <= '5') {
					PcInfo pc_info;
					int pc_idx = buf[x] - '1';

					pc_info.x = x;
					pc_info.y = y;
					pc_infos[pc_idx].push_back(pc_info);
				}
				else if (buf[x] == '.') {
				}
				else if (buf[x] == 'S') {
					start_x = x;
					start_y = y;
				}
				else {
					goal_x = x;
					goal_y = y;
				}
			}
		}

		for (int i = 0; i < num_pc; i++) {
			if (pc_infos[i].empty()) {
				num_absent_pc++;
			}
		}

		if (num_absent_pc >= 2) {
			cout << "NA" << endl;
			continue;
		}
		else if (num_absent_pc == 1) {
			for (int i = 0; i < num_pc; i++) {
				if (pc_infos[i].empty()) {
					init_pc_idx_vec.push_back(i);
					break;
				}
			}
		}
		else {
			for (int i = 0; i < num_pc; i++) {
				init_pc_idx_vec.push_back(i);
			}
		}

		for (int& init_pc_idx : init_pc_idx_vec) {
			int next_pc_idx = (init_pc_idx + 1) % num_pc;
			int last_pc_idx = (init_pc_idx + num_pc - 1) % num_pc;
			unsigned int total_moves = inf;
			vector<PcInfo>& next_pc_info_vec = pc_infos[next_pc_idx];

			for (vector<PcInfo>& tmp_pc_info_vec : pc_infos) {
				for (PcInfo& pc_info : tmp_pc_info_vec) {
					pc_info.num_moves = inf;
				}
			}

			for (PcInfo& next_pc_info : next_pc_info_vec) {
				next_pc_info.num_moves = abs(next_pc_info.x - start_x) + abs(next_pc_info.y - start_y);
			}

			for (int i = 1; i < num_pc; i++) {
				int cur_pc_idx = (init_pc_idx + i) % num_pc;
				int next_pc_idx = (cur_pc_idx + 1) % num_pc;

				for (PcInfo& cur_pc_info : pc_infos[cur_pc_idx]) {
					for (PcInfo& next_pc_info : pc_infos[next_pc_idx]) {
						unsigned int num_moves = cur_pc_info.num_moves + abs(next_pc_info.x - cur_pc_info.x) + abs(next_pc_info.y - cur_pc_info.y);

						if (next_pc_info.num_moves > num_moves) {
							next_pc_info.num_moves = num_moves;
						}
					}
				}
			}

			for (PcInfo& pc_info : pc_infos[last_pc_idx]) {
				unsigned int num_moves = pc_info.num_moves + abs(goal_x - pc_info.x) + abs(goal_y - pc_info.y);

				if (total_moves > num_moves) {
					total_moves = num_moves;
				}
			}

			if (min_num_moves > total_moves) {
				min_num_moves = total_moves;
				min_num_moves_idx = init_pc_idx;
			}
			else if (min_num_moves == total_moves && min_num_moves_idx > init_pc_idx) {
				min_num_moves_idx = init_pc_idx;
			}
		}
		cout << min_num_moves_idx + 1 << " " << min_num_moves << endl;
	}

	return 0;
}
accuracy: 1
time_ms: 510
memory_kb: 3292
final_rank: 4

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <vector>

using namespace std;

const unsigned int inf = 0xffffffff;

class PcInfo {
public:
	int x;
	int y;
	unsigned int num_moves;

public:
	PcInfo() : x(-1), y(-1), num_moves(inf) {
	}

	~PcInfo() {
	}
};


int main(int argc, char** argv) {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif
	while (true) {
		int width = -1;
		int height = -1;
		const int num_pc = 5;
		int start_x = -1;
		int start_y = -1;
		int goal_x = -1;
		int goal_y = -1;
		int num_absent_pc = 0;
		unsigned int min_num_moves = inf;
		int min_num_moves_idx = -1;
		vector<vector<PcInfo>> pc_infos(num_pc);
		vector<int> init_pc_idx_vec;

		cin >> width >> height;
		if (width == 0 && height == 0) {
			break;
		}

		for (int y = 0; y < height; y++) {
			string buf;

			cin >> buf;
			for (int x = 0; x < width; x++) {
				if ('1' <= buf[x] && buf[x] <= '5') {
					PcInfo pc_info;
					int pc_idx = buf[x] - '1';

					pc_info.x = x;
					pc_info.y = y;
					pc_infos[pc_idx].push_back(pc_info);
				}
				else if (buf[x] == '.') {

				}
				else if (buf[x] == 'S') {
					start_x = x;
					start_y = y;
				}
				else {
					goal_x = x;
					goal_y = y;
				}
			}
		}

		for (int i = 0; i < num_pc; i++) {
			if (pc_infos[i].empty()) {
				num_absent_pc++;
			}
		}

		if (num_absent_pc >= 2) {
			cout << "NA" << endl;
			continue;
		}
		else if (num_absent_pc == 1) {
			for (int i = 0; i < num_pc; i++) {
				if (pc_infos[i].empty()) {
					init_pc_idx_vec.push_back(i);
					break;
				}
			}
		}
		else {
			for (int i = 0; i < num_pc; i++) {
				init_pc_idx_vec.push_back(i);
			}
		}

		for (int& init_pc_idx : init_pc_idx_vec) {
			int next_pc_idx = (init_pc_idx + 1) % num_pc;
			int last_pc_idx = (init_pc_idx + num_pc - 1) % num_pc;
			unsigned int total_moves = inf;
			vector<PcInfo>& next_pc_info_vec = pc_infos[next_pc_idx];

			for (vector<PcInfo>& tmp_pc_info_vec : pc_infos) {
				for (PcInfo& pc_info : tmp_pc_info_vec) {
					pc_info.num_moves = inf;
				}
			}

			for (PcInfo& next_pc_info : next_pc_info_vec) {
				next_pc_info.num_moves = abs(next_pc_info.x - start_x) + abs(next_pc_info.y - start_y);
			}

			for (int i = 1; i < num_pc; i++) {
				int cur_pc_idx = (init_pc_idx + i) % num_pc;
				int next_pc_idx = (cur_pc_idx + 1) % num_pc;

				for (PcInfo& cur_pc_info : pc_infos[cur_pc_idx]) {
					for (PcInfo& next_pc_info : pc_infos[next_pc_idx]) {
						unsigned int num_moves = cur_pc_info.num_moves + abs(next_pc_info.x - cur_pc_info.x) + abs(next_pc_info.y - cur_pc_info.y);

						if (next_pc_info.num_moves > num_moves) {
							next_pc_info.num_moves = num_moves;
						}
					}
				}
			}

			for (PcInfo& pc_info : pc_infos[last_pc_idx]) {
				unsigned int num_moves = pc_info.num_moves + abs(goal_x - pc_info.x) + abs(goal_y - pc_info.y);

				if (total_moves > num_moves) {
					total_moves = num_moves;
				}
			}

			if (min_num_moves > total_moves) {
				min_num_moves = total_moves;
				min_num_moves_idx = init_pc_idx;
			}
			else if (min_num_moves == total_moves && min_num_moves_idx > init_pc_idx) {
				min_num_moves_idx = init_pc_idx;
			}
		}
		cout << min_num_moves_idx + 1 << " " << min_num_moves << endl;
	}

	return 0;
}
accuracy: 1
time_ms: 510
memory_kb: 3364
final_rank: 5

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <vector>

using namespace std;

const unsigned int inf = 0xffffffff;

class PcInfo {
public:
	int x;
	int y;
	unsigned int num_moves;

public:
	PcInfo() : x(-1), y(-1), num_moves(inf) {
	}

	~PcInfo() {
	}
};


int main(int argc, char** argv) {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif
	int width = -1;
	int height = -1;
	const int num_pc = 5;
	int start_x = -1;
	int start_y = -1;
	int goal_x = -1;
	int goal_y = -1;

	while (true) {
		int num_absent_pc = 0;
		unsigned int min_num_moves = inf;
		int min_num_moves_idx = -1;
		vector<vector<PcInfo>> pc_infos(num_pc);
		vector<int> init_pc_idx_vec;

		cin >> width >> height;
		if (width == 0 && height == 0) {
			break;
		}

		for (int y = 0; y < height; y++) {
			string buf;

			cin >> buf;
			for (int x = 0; x < width; x++) {
				if ('1' <= buf[x] && buf[x] <= '5') {
					PcInfo pc_info;
					int pc_idx = buf[x] - '1';

					pc_info.x = x;
					pc_info.y = y;
					pc_infos[pc_idx].push_back(pc_info);
				}
				else if (buf[x] == '.') {

				}
				else if (buf[x] == 'S') {
					start_x = x;
					start_y = y;
				}
				else {
					goal_x = x;
					goal_y = y;
				}
			}
		}

		for (int i = 0; i < num_pc; i++) {
			if (pc_infos[i].empty()) {
				num_absent_pc++;
			}
		}

		if (num_absent_pc >= 2) {
			cout << "NA" << endl;
			continue;
		}
		else if (num_absent_pc == 1) {
			for (int i = 0; i < num_pc; i++) {
				if (pc_infos[i].empty()) {
					init_pc_idx_vec.push_back(i);
					break;
				}
			}
		}
		else {
			for (int i = 0; i < num_pc; i++) {
				init_pc_idx_vec.push_back(i);
			}
		}

		for (int& init_pc_idx : init_pc_idx_vec) {
			int next_pc_idx = (init_pc_idx + 1) % num_pc;
			int last_pc_idx = (init_pc_idx + num_pc - 1) % num_pc;
			unsigned int total_moves = inf;
			vector<PcInfo>& next_pc_info_vec = pc_infos[next_pc_idx];

			for (vector<PcInfo>& tmp_pc_info_vec : pc_infos) {
				for (PcInfo& pc_info : tmp_pc_info_vec) {
					pc_info.num_moves = inf;
				}
			}

			for (PcInfo& next_pc_info : next_pc_info_vec) {
				next_pc_info.num_moves = abs(next_pc_info.x - start_x) + abs(next_pc_info.y - start_y);
			}

			for (int i = 1; i < num_pc; i++) {
				int cur_pc_idx = (init_pc_idx + i) % num_pc;
				int next_pc_idx = (cur_pc_idx + 1) % num_pc;

				for (PcInfo& cur_pc_info : pc_infos[cur_pc_idx]) {
					for (PcInfo& next_pc_info : pc_infos[next_pc_idx]) {
						unsigned int num_moves = cur_pc_info.num_moves + abs(next_pc_info.x - cur_pc_info.x) + abs(next_pc_info.y - cur_pc_info.y);

						if (next_pc_info.num_moves > num_moves) {
							next_pc_info.num_moves = num_moves;
						}
					}
				}
			}

			for (PcInfo& pc_info : pc_infos[last_pc_idx]) {
				unsigned int num_moves = pc_info.num_moves + abs(goal_x - pc_info.x) + abs(goal_y - pc_info.y);

				if (total_moves > num_moves) {
					total_moves = num_moves;
				}
			}

			if (min_num_moves > total_moves) {
				min_num_moves = total_moves;
				min_num_moves_idx = init_pc_idx;
			}
			else if (min_num_moves == total_moves && min_num_moves_idx > init_pc_idx) {
				min_num_moves_idx = init_pc_idx;
			}
		}
		cout << min_num_moves_idx + 1 << " " << min_num_moves << endl;
	}

	return 0;
}
accuracy: 1
time_ms: 520
memory_kb: 3420
final_rank: 6

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <vector>

using namespace std;

const unsigned int inf = 0xffffffff;

class PcInfo {
public:
	int x;
	int y;
	unsigned int num_moves;

public:
	PcInfo() : x(-1), y(-1), num_moves(inf) {
	}

	~PcInfo() {
	}
};


int main(int argc, char** argv) {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif
	while (true) {
		int width = -1;
		int height = -1;
		const int num_pc = 5;
		int start_x = -1;
		int start_y = -1;
		int goal_x = -1;
		int goal_y = -1;
		int num_absent_pc = 0;
		unsigned int min_num_moves = inf;
		int min_num_moves_idx = -1;
		vector<vector<PcInfo>> pc_info_vec(num_pc);
		vector<int> init_pc_idx_vec;

		cin >> width >> height;
		if (width == 0 && height == 0) {
			break;
		}

		for (int y = 0; y < height; y++) {
			string buf;

			cin >> buf;
			for (int x = 0; x < width; x++) {
				if ('1' <= buf[x] && buf[x] <= '5') {
					PcInfo pc_info;
					int pc_idx = buf[x] - '1';

					pc_info.x = x;
					pc_info.y = y;
					pc_info_vec[pc_idx].push_back(pc_info);
				}
				else if (buf[x] == '.') {

				}
				else if (buf[x] == 'S') {
					start_x = x;
					start_y = y;
				}
				else {
					goal_x = x;
					goal_y = y;
				}
			}
		}

		for (int i = 0; i < num_pc; i++) {
			if (pc_info_vec[i].empty()) {
				num_absent_pc++;
			}
		}

		if (num_absent_pc >= 2) {
			cout << "NA" << endl;
			continue;
		}
		else if (num_absent_pc == 1) {
			for (int i = 0; i < num_pc; i++) {
				if (pc_info_vec[i].empty()) {
					init_pc_idx_vec.push_back(i);
					break;
				}
			}
		}
		else {
			for (int i = 0; i < num_pc; i++) {
				init_pc_idx_vec.push_back(i);
			}
		}

		for (int &init_pc_idx: init_pc_idx_vec) {
			int next_pc_idx = (init_pc_idx + 1) % num_pc;
			int last_pc_idx = (init_pc_idx + num_pc - 1) % num_pc;
			unsigned int total_moves = inf;
			vector<PcInfo>& next_pc_info_vec = pc_info_vec[next_pc_idx];

			for (vector<PcInfo> &tmp_pc_info_vec: pc_info_vec) {
				for (PcInfo &pc_info: tmp_pc_info_vec) {
					pc_info.num_moves = inf;
				}
			}

			for (PcInfo& next_pc_info: next_pc_info_vec) {
				next_pc_info.num_moves = abs(next_pc_info.x - start_x) + abs(next_pc_info.y - start_y);
			}

			for (int i = 1; i < num_pc; i++) {
				int cur_pc_idx = (init_pc_idx + i) % num_pc;
				int next_pc_idx = (cur_pc_idx + 1) % num_pc;

				for (PcInfo& cur_pc_info: pc_info_vec[cur_pc_idx]) {
					for (PcInfo& next_pc_info: pc_info_vec[next_pc_idx]) {
						unsigned int num_moves = cur_pc_info.num_moves + abs(next_pc_info.x - cur_pc_info.x) + abs(next_pc_info.y - cur_pc_info.y);

						if (next_pc_info.num_moves > num_moves) {
							next_pc_info.num_moves = num_moves;
						}
					}
				}
			}

			for (PcInfo& pc_info: pc_info_vec[last_pc_idx]) {
				unsigned int num_moves = pc_info.num_moves + abs(goal_x - pc_info.x) + abs(goal_y - pc_info.y);

				if (total_moves > num_moves) {
					total_moves = num_moves;
				}
			}

			if (min_num_moves > total_moves) {
				min_num_moves = total_moves;
				min_num_moves_idx = init_pc_idx;
			}
			else if (min_num_moves == total_moves && min_num_moves_idx > init_pc_idx) {
				min_num_moves_idx = init_pc_idx;
			}
		}
		cout << min_num_moves_idx + 1 << " " << min_num_moves << endl;
	}

	return 0;
}
accuracy: 1
time_ms: 520
memory_kb: 3440
final_rank: 7

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <vector>

using namespace std;

const unsigned int inf = 0xffffffff;

class PcInfo {
public:
	int x;
	int y;
	unsigned int num_moves;

public:
	PcInfo() : x(-1), y(-1), num_moves(inf) {
	}

	~PcInfo() {
	}
};


int main(int argc, char** argv) {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif
	while (true) {
		int width = -1;
		int height = -1;
		const int num_pc = 5;
		int start_x = -1;
		int start_y = -1;
		int goal_x = -1;
		int goal_y = -1;
		int num_exists_pc = 0;
		unsigned int min_num_moves = inf;
		int min_num_moves_idx = -1;
		vector<vector<PcInfo>> pc_info_vec(num_pc);
		vector<int> init_pc_idx_vec;

		cin >> width >> height;
		if (width == 0 && height == 0) {
			break;
		}

		for (int y = 0; y < height; y++) {
			string buf;

			cin >> buf;
			for (int x = 0; x < width; x++) {
				if ('1' <= buf[x] && buf[x] <= '5') {
					PcInfo pc_info;
					int pc_idx = buf[x] - '1';

					pc_info.x = x;
					pc_info.y = y;
					pc_info_vec[pc_idx].push_back(pc_info);
				}
				else if (buf[x] == '.') {

				}
				else if (buf[x] == 'S') {
					start_x = x;
					start_y = y;
				}
				else {
					goal_x = x;
					goal_y = y;

				}
			}
		}

		for (int i = 0; i < num_pc; i++) {
			if (!pc_info_vec[i].empty()) {
				num_exists_pc++;
			}
		}

		if (num_pc - num_exists_pc >= 2) {
			cout << "NA" << endl;
			continue;
		}
		else if (num_pc - num_exists_pc == 1) {
			for (int i = 0; i < num_pc; i++) {
				if (pc_info_vec[i].empty()) {
					init_pc_idx_vec.push_back(i);
					break;
				}
			}
		}
		else {
			for (int i = 0; i < num_pc; i++) {
				init_pc_idx_vec.push_back(i);
			}
		}

		for (int i = 0; i < init_pc_idx_vec.size(); i++) {
			int init_pc_idx = init_pc_idx_vec[i];
			int next_pc_idx = (init_pc_idx + 1) % num_pc;
			int last_pc_idx = (init_pc_idx + num_pc - 1) % num_pc;
			unsigned int total_moves = inf;
			vector<PcInfo>& next_pc_info_vec = pc_info_vec[next_pc_idx];

			for (int j = 0; j < num_pc; j++) {
				for (int k = 0; k < pc_info_vec[j].size(); k++) {
					pc_info_vec[j][k].num_moves = inf;
				}
			}

			for (int j = 0; j < next_pc_info_vec.size(); j++) {
				PcInfo& next_pc_info = next_pc_info_vec[j];

				next_pc_info.num_moves = abs(next_pc_info.x - start_x) + abs(next_pc_info.y - start_y);
			}

			for (int j = 1; j < num_pc; j++) {
				int cur_pc_idx = (init_pc_idx + j) % num_pc;
				int next_pc_idx = (cur_pc_idx + 1) % num_pc;

				for (int k = 0; k < pc_info_vec[cur_pc_idx].size(); k++) {
					PcInfo& cur_pc_info = pc_info_vec[cur_pc_idx][k];

					for (int l = 0; l < pc_info_vec[next_pc_idx].size(); l++) {
						PcInfo& next_pc_info = pc_info_vec[next_pc_idx][l];
						unsigned int num_moves = cur_pc_info.num_moves + abs(next_pc_info.x - cur_pc_info.x) + abs(next_pc_info.y - cur_pc_info.y);

						if (next_pc_info.num_moves > num_moves) {
							next_pc_info.num_moves = num_moves;
						}
					}
				}
			}

			for (int j = 0; j < pc_info_vec[last_pc_idx].size(); j++) {
				PcInfo& pc_info = pc_info_vec[last_pc_idx][j];
				unsigned int num_moves = pc_info.num_moves + abs(goal_x - pc_info.x) + abs(goal_y - pc_info.y);

				if (total_moves > num_moves) {
					total_moves = num_moves;
				}
			}

			if (min_num_moves > total_moves) {
				min_num_moves = total_moves;
				min_num_moves_idx = init_pc_idx;
			}
			else if (min_num_moves == total_moves && min_num_moves_idx > init_pc_idx) {
				min_num_moves_idx = init_pc_idx;
			}
		}
		cout << min_num_moves_idx + 1 << " " << min_num_moves << endl;
	}

	return 0;
}
accuracy: 1
time_ms: 460
memory_kb: 3540
final_rank: 3

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <vector>

using namespace std;

typedef long long ll;
const ll inf = 0xffffffff;

class PcInfo {
public:
	int x;
	int y;
	ll num_moves;

public:
	PcInfo() : x(-1), y(-1), num_moves(inf) {
	}

	~PcInfo() {
	}
};


int main(int argc, char** argv) {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif
	while (true) {
		int width = -1;
		int height = -1;
		const int num_pc = 5;
		int start_x = -1;
		int start_y = -1;
		int goal_x = -1;
		int goal_y = -1;
		int num_exists_pc = 0;
		ll min_num_moves = inf;
		int min_num_moves_idx = -1;
		vector<vector<PcInfo>> pc_info_vec(num_pc);
		vector<int> init_pc_idx_vec;

		cin >> width >> height;
		if (width == 0 && height == 0) {
			break;
		}

		for (int y = 0; y < height; y++) {
			string buf;

			cin >> buf;
			for (int x = 0; x < width; x++) {
				if ('1' <= buf[x] && buf[x] <= '5') {
					PcInfo pc_info;
					int pc_idx = buf[x] - '1';

					pc_info.x = x;
					pc_info.y = y;
					pc_info_vec[pc_idx].push_back(pc_info);
				}
				else if (buf[x] == '.') {

				}
				else if (buf[x] == 'S') {
					start_x = x;
					start_y = y;
				}
				else {
					goal_x = x;
					goal_y = y;

				}
			}
		}

		for (int i = 0; i < num_pc; i++) {
			if (!pc_info_vec[i].empty()) {
				num_exists_pc++;
			}
		}

		if (num_pc - num_exists_pc >= 2) {
			cout << "NA" << endl;
			continue;
		}
		else if (num_pc - num_exists_pc == 1) {
			for (int i = 0; i < num_pc; i++) {
				if (pc_info_vec[i].empty()) {
					init_pc_idx_vec.push_back(i);
					break;
				}
			}
		}
		else {
			for (int i = 0; i < num_pc; i++) {
				init_pc_idx_vec.push_back(i);
			}
		}

		for (int i = 0; i < init_pc_idx_vec.size(); i++) {
			int init_pc_idx = init_pc_idx_vec[i];
			int next_pc_idx = (init_pc_idx + 1) % num_pc;
			int last_pc_idx = (init_pc_idx + num_pc - 1) % num_pc;
			ll total_moves = inf;
			vector<PcInfo>& next_pc_info_vec = pc_info_vec[next_pc_idx];

			for (int j = 0; j < num_pc; j++) {
				for (int k = 0; k < pc_info_vec[j].size(); k++) {
					pc_info_vec[j][k].num_moves = inf;
				}
			}

			for (int j = 0; j < next_pc_info_vec.size(); j++) {
				PcInfo& next_pc_info = next_pc_info_vec[j];

				next_pc_info.num_moves = abs(next_pc_info.x - start_x) + abs(next_pc_info.y - start_y);
			}

			for (int j = 1; j < num_pc; j++) {
				int cur_pc_idx = (init_pc_idx + j) % num_pc;
				int next_pc_idx = (cur_pc_idx + 1) % num_pc;

				for (int k = 0; k < pc_info_vec[cur_pc_idx].size(); k++) {
					PcInfo& cur_pc_info = pc_info_vec[cur_pc_idx][k];

					for (int l = 0; l < pc_info_vec[next_pc_idx].size(); l++) {
						PcInfo& next_pc_info = pc_info_vec[next_pc_idx][l];
						ll num_moves = cur_pc_info.num_moves + abs(next_pc_info.x - cur_pc_info.x) + abs(next_pc_info.y - cur_pc_info.y);

						if (next_pc_info.num_moves > num_moves) {
							next_pc_info.num_moves = num_moves;
						}
					}
				}
			}

			for (int j = 0; j < pc_info_vec[last_pc_idx].size(); j++) {
				PcInfo& pc_info = pc_info_vec[last_pc_idx][j];
				ll num_moves = pc_info.num_moves + abs(goal_x - pc_info.x) + abs(goal_y - pc_info.y);

				if (total_moves > num_moves) {
					total_moves = num_moves;
				}
			}

			if (min_num_moves > total_moves) {
				min_num_moves = total_moves;
				min_num_moves_idx = init_pc_idx;
			}
			else if (min_num_moves == total_moves && min_num_moves_idx > init_pc_idx) {
				min_num_moves_idx = init_pc_idx;
			}
		}
		cout << min_num_moves_idx + 1 << " " << min_num_moves << endl;
	}

	return 0;
}
accuracy: 1
time_ms: 460
memory_kb: 3492
final_rank: 2

code_snippet: #include <iostream>
#include <unordered_map>
#include <vector>
#include <set>
#include <unordered_set>
#include <algorithm>
#include <cmath>
#include <cstdlib>
using namespace std;
#define INF 1000010

pair<int,int> get(int W, int H, char** c);

struct Pachimon {
        int x;
        int y;
        int dist;
        bool operator==(const Pachimon &p) const {
                return x==p.x and y==p.y and dist==p.dist;
        }
        bool operator<(const Pachimon &p) const {
                if(x<p.x) return true;
                else if(x>p.x) return false;
                else if(y<p.y) return true;
                else if(y>p.y) return false;
                else return (dist<p.dist);
        }
} typedef Pachimon;

int distance(Pachimon p1, Pachimon p2);


int main(void){
        while(1) {
                int W,H;
                cin>>W>>H;
                if(W==0 and H==0) {break;}
                char** c=new char*[H];
                for(int i=0; i<H; i++) {
                        c[i]=new char[W];
                }
                for(int i=0; i<H; i++) {
                        for(int j=0; j<W; j++) {
                                cin>>c[i][j];
                        }
                }
                auto p=get(W,H,c);
                if(p.second==INF) {
                        cout<<"NA"<<endl;
                }
                else{
                        cout<<p.first+1<<" "<<p.second<<endl;
                }
                for(int i=0; i<H; i++) {
                        delete[] c[i];
                }
                delete[] c;
        }
        return 0;
}


pair<int,int> get(int W,int H, char** c){
        vector<Pachimon>* pachimons = new vector<Pachimon> [5];
        Pachimon S,G;
        for(int i=0; i<5; i++) {
                pachimons[i].clear();
        }

        for(int i=0; i<H; i++) {
                for(int j=0; j<W; j++) {
                        switch(c[i][j]) {
                                Pachimon p;
                        case '1':
                                p.x=i;
                                p.y=j;
                                p.dist=INF;
                                pachimons[0].push_back(p);
                                break;
                        case '2':
                                p.x=i;
                                p.y=j;
                                p.dist=INF;
                                pachimons[1].push_back(p);
                                break;
                        case '3':
                                p.x=i;
                                p.y=j;
                                p.dist=INF;
                                pachimons[2].push_back(p);
                                break;
                        case '4':
                                p.x=i;
                                p.y=j;
                                p.dist=INF;
                                pachimons[3].push_back(p);
                                break;
                        case '5':
                                p.x=i;
                                p.y=j;
                                p.dist=INF;
                                pachimons[4].push_back(p);
                                break;
                        case 'S':
                                S.x=i;
                                S.y=j;
                                S.dist=0;
                                break;
                        case 'G':
                                G.x=i;
                                G.y=j;
                                G.dist=INF;
                                break;
                        default:
                                ;
                        }
                }
        }

        int retval=INF;
        int min_first_select;
        for(int first_select=0; first_select<5; first_select++) {
                for(int i=0; i<5; i++) {
                        for(auto iter=pachimons[i].begin(); iter!=pachimons[i].end(); iter++) {
                                (*iter).dist=INF;
                        }
                }
                G.dist=INF;
                for(auto iter=pachimons[(first_select+1)%5].begin(); iter!=pachimons[(first_select+1)%5].end(); iter++) {
                        (*iter).dist=min((*iter).dist,distance(S,*iter));
                }
                for(int i=0; i<5; i++) {
                        for(auto iter=pachimons[(first_select+1+i)%5].begin(); iter!=pachimons[(first_select+1+i)%5].end(); iter++) {
                                for(auto iter2=pachimons[(first_select+1+i+1)%5].begin(); iter2!=pachimons[(first_select+1+i+1)%5].end(); iter2++) {
                                        (*iter2).dist=min((*iter2).dist,distance(*iter,*iter2));
                                }
                        }
                }
                for(auto iter=pachimons[(first_select+4)%5].begin(); iter!=pachimons[(first_select+4)%5].end(); iter++) {
                        G.dist=min(G.dist,distance(*iter,G));
                }
                if(G.dist<retval){
                  min_first_select=first_select;
                  retval=G.dist;
                }
        }

        return make_pair(min_first_select,retval);

};

int distance(Pachimon p1, Pachimon p2){
  return abs(p1.x - p2.x) + abs(p1.y - p2.y) + p1.dist;
}
accuracy: 1
time_ms: 940
memory_kb: 5364
final_rank: 12

code_snippet: #include<bits/stdc++.h>

using namespace std;

int W, H, StartId, Ans;
char MapData[1000][1000];
vector<pair<int, int> > CreatureInfo[7];
int DpCount[5][1001];

const int INF = 2e9;


void clearDpArray() {
	for (int j = 0; j < 5; ++j) {
		for (int k = 0; k < 1001; ++k) {
			DpCount[j][k] = INF;
		}
	}
}

void solve() {
	int currentId, nextId, nextIdSize, next2Id, next2IdSize, xLen, yLen, currentLen;

	Ans = INF;
	for (currentId = 0; currentId <= 4; ++currentId) {
		clearDpArray();

		nextId = (currentId + 1) % 5;
		nextIdSize = CreatureInfo[nextId].size();
		for (int i = 0; i < nextIdSize; ++i) {
			xLen = abs(CreatureInfo[5][0].second - CreatureInfo[nextId][i].second);
			yLen = abs(CreatureInfo[5][0].first - CreatureInfo[nextId][i].first);
			DpCount[1][i] = xLen + yLen;
		}

		for (int cnt = 2; cnt <= 4; ++cnt) {
			next2Id = (nextId + 1) % 5;
			next2IdSize = CreatureInfo[next2Id].size();
			for (int i = 0; i < nextIdSize; ++i) {
				for (int j = 0; j < next2IdSize; ++j) {
					xLen = abs(CreatureInfo[next2Id][j].second - CreatureInfo[nextId][i].second);
					yLen = abs(CreatureInfo[next2Id][j].first - CreatureInfo[nextId][i].first);
					DpCount[cnt][j] = min(DpCount[cnt][j], DpCount[cnt - 1][i] + xLen + yLen);
				}
			}
			nextId = (nextId + 1) % 5;
			nextIdSize = CreatureInfo[nextId].size();
		}

		for (int i = 0; i < nextIdSize; ++i) {
			xLen = abs(CreatureInfo[6][0].second - CreatureInfo[nextId][i].second);
			yLen = abs(CreatureInfo[6][0].first - CreatureInfo[nextId][i].first);
			currentLen = DpCount[4][i] + xLen + yLen;
			if (currentLen < Ans) {
				Ans = currentLen;
				StartId = currentId + 1;
			}
		}
	}

	if (Ans == INF) {
		cout << "NA" << endl;
		return;
	}
	cout << StartId << " " << Ans << endl;
}

int main() {
	char ch;

	while (cin >> W >> H, W) {
		for (int i = 0; i < 7; ++i) {
			CreatureInfo[i].clear();
		}

		memset(MapData, '\0', sizeof(MapData));
		for (int i = 0; i < H; ++i) {
			for (int j = 0; j < W; ++j) {
				cin >> ch;
				if (ch == 'S') {
					CreatureInfo[5].push_back(make_pair(i, j));
				}
				else if (ch == 'G') {
					CreatureInfo[6].push_back(make_pair(i, j));
				}
				else if (ch >= '1' && ch <= '5') {
					CreatureInfo[ch-'1'].push_back(make_pair(i, j));
				}
				MapData[i][j] = ch;
			}
		}
		solve();
	}

	return 0;
}
accuracy: 1
time_ms: 790
memory_kb: 4124
final_rank: 10

code_snippet: #include<bits/stdc++.h>

using namespace std;

int W, H, StartId, Ans;
char MapData[1000][1000];
vector<pair<int,int> > CreatureInfo[7];
int DpCount[5][5][1001];


void clearDpCount() {
	for (int i = 0; i < 5; ++i) {
		for (int j = 0; j < 5; ++j) {
			for (int k = 0; k < 1001; ++k) {
				DpCount[i][j][k] = -1;
			}
		}
	}
}

int judge(int gotTotal, int gotId, int gotNum) {
	int xLen, yLen, cntOfNextId, ans;

	if (DpCount[gotTotal][gotId][gotNum] != -1) {
		return DpCount[gotTotal][gotId][gotNum];
	}

	if (gotTotal == 4) {
		xLen = abs(CreatureInfo[6][0].second - CreatureInfo[gotId][gotNum].second);
		yLen = abs(CreatureInfo[6][0].first - CreatureInfo[gotId][gotNum].first);
		return xLen + yLen;
	}

	ans = 2e9;
	cntOfNextId = CreatureInfo[gotId + 1].size();
	for (int i = 0; i < cntOfNextId; ++i) {
		xLen = abs(CreatureInfo[gotId + 1][i].second - CreatureInfo[gotId][gotNum].second);
		yLen = abs(CreatureInfo[gotId + 1][i].first - CreatureInfo[gotId][gotNum].first);
		ans = min(ans, judge(gotTotal + 1, gotId + 1, i) + xLen + yLen);
	}

	DpCount[gotTotal][gotId][gotNum] = ans;
	return ans;
}

void solve() {
	int currentCnt;

	Ans = 2e9;
	for (int id = 1; id <= 5; ++id) {
		clearDpCount();
		rotate(CreatureInfo + 1, CreatureInfo + 2, CreatureInfo + 6);

		currentCnt = judge(0, 0, 0);
		if (currentCnt < Ans) {
			Ans = currentCnt;
			StartId = id;
		}
	}

	if (Ans == 2e9) {
		cout << "NA" << endl;
		return;
	}
	cout << StartId << " " << Ans << endl;
}

void show() {
	cout << "Map:" << endl;
	for (int i = 0; i < H; ++i) {
		for (int j = 0; j < W; ++j) {
			cout<<MapData[i][j];
		}
		cout << endl;
	}

	cout << "Creature:" << endl;
	for (int i = 0; i < 7; ++i) {
		cout << "num_" << i << endl;
		for (int j = 0; j < CreatureInfo[i].size(); ++j) {
			cout << " " << CreatureInfo[i][j].first << " " << CreatureInfo[i][j].second << endl;
		}
	}
}

int main() {
	char ch;

	while (cin >> W >> H, W) {
		for (int i = 0; i < 7; ++i) {
			CreatureInfo[i].clear();
		}

		memset(MapData, '\0', sizeof(MapData));
		for (int i = 0; i < H; ++i) {
			for (int j = 0; j < W; ++j) {
				cin >> ch;
				if (ch == 'S') {
					CreatureInfo[0].push_back(make_pair(i, j));
				} else if (ch == 'G') {
					CreatureInfo[6].push_back(make_pair(i, j));
				} else if (ch >= '1' && ch <= '5') {
					CreatureInfo[ch-'0'].push_back(make_pair(i, j));
				}
				MapData[i][j] = ch;
			}
		}
		//show();
		solve();
	}

	return 0;
}
accuracy: 1
time_ms: 1110
memory_kb: 4224
final_rank: 14

code_snippet: #include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <numeric>
#include <bitset>
#include <cmath>

static const int MOD = 1000000007;
using ll = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using namespace std;

template<class T> constexpr T INF = ::numeric_limits<T>::max()/32*15+208;

template <class T, class U>
vector<T> make_v(U size, const T& init){ return vector<T>(static_cast<size_t>(size), init); }

template<class... Ts, class U>
auto make_v(U size, Ts... rest) { return vector<decltype(make_v(rest...))>(static_cast<size_t>(size), make_v(rest...)); }

template<class T> void chmin(T &a, const T &b){ a = (a < b ? a : b); }
template<class T> void chmax(T &a, const T &b){ a = (a > b ? a : b); }

void solve(int w, int h){
    int sy = 0, sx = 0, gy = 0, gx = 0;
    vector<vector<int>> ys(5), xs(5);
    for (int i = 0; i < h; ++i) {
        string s;
        cin >> s;
        for (int j = 0; j < w; ++j) {
            if(s[j] == 'S') sy = i, sx = j;
            else if(s[j] == 'G') gy = i, gx = j;
            else if(isdigit(s[j])){
                ys[s[j]-'1'].emplace_back(i);
                xs[s[j]-'1'].emplace_back(j);
            }
        }
    }
    vector<vector<int>> dp(5);
    for (int i = 0; i < 5; ++i) {
        dp[i].resize(ys[i].size());
    }
    int ans = INF<int>, cur = 0;
    for (int i = 0; i < 5; ++i) {
        for (int j = 0; j < 5; ++j) {
            fill(dp[j].begin(),dp[j].end(), INF<int>);
        }
        int st = (i+1)%5;
        for (int j = 0; j < dp[st].size(); ++j) {
            dp[st][j] = abs(sy-ys[st][j])+abs(sx-xs[st][j]);
        }
        for (int _ = 0; _ < 3; ++_) {
            int stt = (st+1)%5;
            for (int j = 0; j < dp[st].size(); ++j) {
                for (int k = 0; k < dp[stt].size(); ++k) {
                    chmin(dp[stt][k], dp[st][j]+abs(ys[st][j]-ys[stt][k])+abs(xs[st][j]-xs[stt][k]));
                }
            }
            st = stt;
        }
        for (int j = 0; j < dp[st].size(); ++j) {
            int dist = dp[st][j]+abs(gy-ys[st][j])+abs(gx-xs[st][j]);
            if(ans > dist){
                ans = dist;
                cur = i;
            }
        }
    }
    if(ans == INF<int>)puts("NA");
    else printf("%d %d\n", cur+1, ans);
}

int main() {
    int w, h;
    while(cin >> w >> h, w){
        solve(w, h);
    }
    return 0;
}
accuracy: 1
time_ms: 580
memory_kb: 3336
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;
#define INF 1000000

int main() {
    while (true) {
        int W, H; cin >> W >> H;
        
        if (W==0 && H==0) {
            break;
        }
    
        char c[H][W];
        vector<P> pos[7];
        int sx, sy, gx, gy;
    
        for (int i=0; i<H; i++) {
            for (int j=0; j<W; j++) {
                cin >> c[i][j];
            
                if (c[i][j]=='S') {
                    sx=i, sy=j;
                    pos[0].push_back(P(i, j));
                }
                else if (c[i][j]=='G') {
                    gx=i, gy=j;
                    pos[6].push_back(P(i, j));
                }
                else if (c[i][j]!='.') {
                    pos[c[i][j]-'0'].push_back(P(i, j));
                }
            }
        }
    
        int dp[6][H][W];
    
        for (int i=0; i<6; i++) {
            for (int j=0; j<H; j++) {
                for (int k=0; k<W; k++) {
                    dp[i][j][k] = INF;
                }
            }
        }
    
        dp[0][sx][sy] = 0;
        int ans0;
        int ans1 = INF;
    
        for (int i=1; i<=5; i++) {
            int now = 0;

            for (int j=1; j<=5; j++) {
                int next;
            
                if (j==5) {
                    next = 6;
                }
                else if (i+j==5) {
                    next = 5;
                }
                else {
                    next = (i+j)%5;
                }
                
                for (int k=0; k<pos[now].size(); k++) {
                    for (int l=0; l<pos[next].size(); l++) {
                        int x1=pos[now][k].first, y1=pos[now][k].second;
                        int x2=pos[next][l].first, y2=pos[next][l].second;
                    
                        dp[j][x2][y2] = min(dp[j][x2][y2], dp[j-1][x1][y1]+abs(x1-x2)+abs(y1-y2));
                    }
                }
            
                now = next;
            }

            if (ans1>dp[5][gx][gy]) {
                ans0 = i;
                ans1 = dp[5][gx][gy];
            }
        }
        
        if (ans1==INF) {
            cout << "NA" << endl;
        }
        else {
            cout << ans0 << " " << ans1 << endl;
        }
    }
}
accuracy: 1
time_ms: 940
memory_kb: 27556
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;
typedef pair<ll, P> P3;
typedef pair<P ,P> PP;
constexpr ll MOD = ll(1e9) + 7;
constexpr int IINF = INT_MAX;
constexpr ll LLINF = LLONG_MAX;

int w, h, si, sj, gi, gj;
int dp[1005][1005];
string s[1005];
vector<P> pos[5];

int rec(int i, int j, int S, int pre){
    if(S==(1<<5)-1){
        return abs(i-gi)+abs(j-gj);
    }
    if(dp[i][j] != -1) return dp[i][j];
    int res = IINF/3, m = (pre+1)%5;
    for(auto p : pos[m]){
        int pi = p.first, pj = p.second;
        res = min(res, rec(pi, pj, S|(1<<m), m) + abs(i-pi) + abs(j-pj));
    }
    return dp[i][j] = res;
}

int main() {
    while(cin >> w >> h, w){
        for(int i=0;i<h;i++) cin >> s[i];
        for(int i=0;i<5;i++) pos[i].clear();
        for(int i=0;i<h;i++){
            for(int j=0;j<w;j++){
                if(s[i][j] != '.'){
                    if(s[i][j]=='S'){
                        si = i;
                        sj = j;
                    }
                    else if(s[i][j]=='G'){
                        gi = i;
                        gj = j;
                    }
                    else{
                        pos[s[i][j]-'1'].push_back({i,j});
                    }
                }
            }
        }
        bool ok = true;
        for(int i=0,cnt=0;i<5;i++){
            if(pos[i].size()==0)cnt++;
            if(cnt>=2){
                cout << "NA" << endl;
                ok = false;
                break;
            }
        }
        if(!ok) continue;
        int ans=IINF, id=0;
        for(int i=0;i<5;i++){
            for(int i=0;i<h;i++) fill(dp[i], dp[i]+w, -1);
            int tmp = rec(si, sj, 1<<i, i);
            if(tmp < ans){
                ans = tmp;
                id = i+1;
            }
        }
        cout << id << " " << ans << endl;
    }
    
    return 0;
}
accuracy: 1
time_ms: 920
memory_kb: 8108
final_rank: 13

code_snippet: #include<iostream>
#include<vector>
using namespace std;
#define inRange(x,a,b) (a <= x && x <= b)

inline int dist(int si, int sj, int gi, int gj){
    return abs(si-gi)+abs(sj-gj);
}

const int INF = 1<<30;

int main(){
    int w, h;
    while(cin >> w >> h, w+h){
        vector<pair<int,int>> vp[5];
        int si, sj, gi, gj;
        char mat[h][w];
        for(int i = 0; i < h; i++){
            for(int j = 0; j < w; j++){
                cin >> mat[i][j];
                if(mat[i][j] == 'S')    si = i, sj = j;
                if(mat[i][j] == 'G')    gi = i, gj = j;
                if(inRange(mat[i][j],'1','5')){
                    vp[mat[i][j]-'1'].push_back({i,j});
                }
            }
        }
        int ans = -1, score = INF;
        for(int i = 0; i < 5; i++){
            vector<vector<int>> dp(4, vector<int>(1000,INF));
            for(int j = 0; j < vp[(i+1)%5].size(); j++){
                dp[0][j] = dist(si,sj,vp[(i+1)%5][j].first,vp[(i+1)%5][j].second);
            }
            for(int j = 0; j < 3; j++){
                int from = (i+1+j)%5, to = (i+1+j+1)%5;
                for(int k = 0; k < vp[from].size(); k++){
                    for(int l = 0; l < vp[to].size(); l++){
                        dp[j+1][l] = min(dp[j+1][l], dp[j][k]+dist(vp[from][k].first, vp[from][k].second, vp[to][l].first, vp[to][l].second));
                    }
                }
            }
            int tmp = INF;
            for(int j = 0; j < vp[(i+4)%5].size(); j++){
                tmp = min(tmp, dp[3][j] + dist(vp[(i+4)%5][j].first, vp[(i+4)%5][j].second, gi, gj));
            }
            if(score > tmp){
                score = tmp;
                ans = i;
            }
        }
        if(score == INF)    cout << "NA" << endl;
        else                cout << ans+1 << " " << score << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 770
memory_kb: 4212
final_rank: 9

code_snippet: #include <bits/stdc++.h>

#define FOR(i,a,b) for(int i= (a); i<((int)b); ++i)
#define RFOR(i,a) for(int i=(a); i >= 0; --i)
#define FOE(i,a) for(auto i : a)
#define ALL(c) (c).begin(), (c).end()
#define RALL(c) (c).rbegin(), (c).rend()
#define DUMP(x)  cerr << #x << " = " << (x) << endl;
#define SUM(x) std::accumulate(ALL(x), 0LL)
#define MIN(v) *std::min_element(v.begin(), v.end())
#define MAX(v) *std::max_element(v.begin(), v.end())
#define EXIST(v,x) (std::find(v.begin(), v.end(), x) != v.end())
#define BIT_ON(bit, i) (bit & (1LL << i))

typedef long long LL;
template<typename T> using V = std::vector<T>;
template<typename T> using VV = std::vector<std::vector<T>>;
template<typename T> using VVV = std::vector<std::vector<std::vector<T>>>;
template<typename T> using VVVV = std::vector<std::vector<std::vector<std::vector<T>>>>;

template<class T> inline T ceil(T a, T b) { return (a + b - 1) / b; }
template<class T> inline void print(T x) { std::cout << x << std::endl; }
template<class T> inline void print_vec(const std::vector<T> &v) { for (int i = 0; i < v.size(); ++i) {  if (i != 0) {std::cout << " ";} std::cout << v[i];} std::cout << "\n"; }
template<class T> inline bool inside(T y, T x, T H, T W) {return 0 <= y and y < H and 0 <= x and x < W; }
template<class T> inline double euclidean_distance(T y1, T x1, T y2, T x2) { return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); }
template<class T> inline double manhattan_distance(T y1, T x1, T y2, T x2) { return abs(x1 - x2) + abs(y1 - y2); }
template<class T> inline std::vector<T> unique(std::vector<T> v) {
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());
    return v;
}

const int INF = 1 << 30;
const double EPS = 1e-9;
const std::string YES = "YES", Yes = "Yes", NO = "NO", No = "No";
const std::vector<int> dy4 = { 0, 1, 0, -1 }, dx4 = { 1, 0, -1, 0 };    // 4近傍（右, 下, 左, 上）
const std::vector<int> dy8 = { 0, -1, 0, 1, 1, -1, -1, 1 }, dx8 = { 1, 0, -1, 0, 1, 1, -1, -1 };

using namespace std;

void solve(VV<int> route_list, int H, int W, VV<pair<int, int>> f) {

    int ans = INF;
    LL mini_dist = INF;
    FOR(r, 0, route_list.size()) {

        VV<LL> dist(H, V<LL>(W, INF));
        dist[f[5][0].first][f[5][0].second] = 0;    // start

        FOR(i, 1, route_list[r].size()) {
            int now_c = route_list[r][i - 1];
            int next_c = route_list[r][i];

            FOE(p1, f[now_c]) {
                int y = p1.first;
                int x = p1.second;

                FOE(p2, f[next_c]) {
                    int ny = p2.first;
                    int nx = p2.second;
                    dist[ny][nx] = min(dist[ny][nx], dist[y][x] + abs(ny - y) + abs(nx - x));
                }
            }
        }

        LL d = dist[f[6][0].first][f[6][0].second];
        int first = route_list[r][1];
        if (first == 0) {
            first = 5;
        }
        if (d < mini_dist) {
            ans = first;
            mini_dist = d;
        }
        else if (d == mini_dist) {
            ans = min(ans, first);
        }
    }

    if (mini_dist == INF) {
        print("NA");
    }
    else {
        cout << ans << " " << mini_dist << endl;
    }
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    while (true) {
        int W, H;
        cin >> W >> H;
        if (W + H == 0) {
            break;
        }

        VV<pair<int, int>> f(7);
        FOR(y, 0, H) {
            string s;
            cin >> s;
            FOR(x, 0, W) {
                if (s[x] == 'S') {
                    f[5].emplace_back(make_pair(y, x));
                }
                else if (s[x] == 'G') {
                    f[6].emplace_back(make_pair(y, x));
                }
                else if (s[x] == '.') {
                }
                else {
                    f[(s[x] - '0') - 1].emplace_back(make_pair(y, x));
                }
            }
        }

        VV<int> route;
        FOR(i, 0, 5) {
            V<int> r = {5};
            FOR(j, 0, 4) {
                r.emplace_back((i + j) % 5);
            }
            r.emplace_back(6);
            route.emplace_back(r);
        }

        solve(route, H, W, f);
    }

}
accuracy: 1
time_ms: 600
memory_kb: 10816
final_rank: 11