#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
#include <numeric>
#include <functional>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
using namespace std;

typedef istringstream ISS;
typedef ostringstream OSS;
typedef vector<string> VS;
typedef int INT;
typedef vector<INT> VI;
typedef vector<VI> VVI;
typedef pair <INT, INT> II;
typedef vector <II> VII;

template<class T> ostream& operator << ( ostream& os, vector<T> v ) {
    for ( typename vector<T>::iterator it_i = v.begin(); it_i != v.end(); ++it_i ) {
        os << *it_i << ", ";
    }
    return os;
}


const char START = 'S';
const char GOAL = 'G';
const char EMPTY = '.';
const int MAX_MONSTER = 1001;
const int NONE = -1;
const int TYPES = 5;

int w, h;
VS M;
II res; 
II P[5][MAX_MONSTER]; 
int PC[5];
int sr, sc;
int gr, gc;

void init() {
    M = VS(h);
    res = II( INT_MAX, -1 );
    for ( int i = 0; i < 5; ++ i ) PC[i] = 0;
}

void input() {
    for ( int i = 0; i < h; ++ i ) {
        cin >> M[i];
    }
}

void output() {
    if ( res.second == -1 ) {
        cout << "NA" << endl;
    } else {
        cout << res.second << " " << res.first << endl;
    }
}

bool isMonster( char c ) {
    return c != START && c != GOAL && c != EMPTY;
}

int getDistance( int r1, int c1, int r2, int c2 ) {
    return abs( r2 - r1 ) + abs( c2 - c1 );
}

int dp1[MAX_MONSTER];
int dp2[MAX_MONSTER];
void solve() {
    for ( int i = 0; i < h; ++ i ) {
        for ( int j = 0; j < w; ++ j ) {
            if ( ! isMonster( M[i][j] ) ) continue;
            int type = M[i][j] - '1';
            P[type][PC[type]++] = II( i, j );
        }
    }
    for ( int i = 0; i < h; ++ i ) {
        for ( int j = 0; j < w; ++ j ) {
            if ( M[i][j] == START ) {
                sr = i;
                sc = j;
                M[i][j] = EMPTY;
            } else if ( M[i][j] == GOAL ) {
                gr = i;
                gc = j;
                M[i][j] = EMPTY;
            }
        }
    }

    for ( int start = 0; start < TYPES; ++ start ) {
        int prev;
        int next = start;
        bool flag = false;
        for ( int lpc1 = 0; lpc1 < 4; ++ lpc1 ) {
            prev = next;
            next = ( next + 1 ) % TYPES;
            if ( PC[next] == 0 ) {
                flag = true;
            }
        
            for ( int i = 0; i < PC[next]; ++ i ) {
                dp2[i] = INT_MAX;
                if ( PC[prev] == 0 ) {
                    if ( prev == start ) {
                        fill( dp2, dp2 + MAX_MONSTER, getDistance( P[next][i].first, P[next][i].second, sr, sc ) );
                        break;
                    }
                } else {
                    for ( int j = 0; j < PC[prev]; ++ j ) {
                        if ( lpc1 == 0 ) {
                            dp2[i] = min( dp2[i], getDistance( P[next][i].first, P[next][i].second, sr, sc ) );
                        } else {
                            dp2[i] = min( dp2[i],
                                          dp1[j] + getDistance( P[next][i].first, P[next][i].second,
                                                                P[prev][j].first, P[prev][j].second ) );
                        }
                    }
                }
            }
        
            copy( dp2, dp2 + MAX_MONSTER, dp1 );
        }
        if ( flag ) continue;
        for ( int i = 0; i < PC[(start+4)%TYPES]; ++ i ) {
            int last = ( start + 4 ) % TYPES;
            int cost = dp1[i] + getDistance( P[last][i].first, P[last][i].second, gr, gc );
            res = min( res, II( cost, start + 1 ) );
        }
    }
}

int main() {
    while ( cin >> w >> h ) {
        if ( w == 0 && h == 0 ) break;
        init();
        input();
        solve();
        output();
    }
    return 0;
}

Measured memory_bytes: 2004