#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#define debug(x) cerr << #x << " = " << x << endl;


#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 1010

/* Dijkstra O(NlogM)*/

struct Dijkstra{
  
  typedef int Type;
  
  int V;
  vector<vector<pair<int,Type> > > G;
  vector<int> cost;
  
  Dijkstra(int n):
    V(n),G(n,vector<pair<int,Type> >()){}
  
  void add_edge(int u, int v, Type c){
    G[u].push_back({v,c});
  }

  void init(int n){
    V = n;
    G.assign(n,vector<pair<int,Type> >());
  }
  
  Type solve(int s, int g = -1){
    cost.assign(V,-1);
    priority_queue<pair<Type,int> > pq;
    Type max_cost = INF;
    
    pq.push({0,s});
    
    while(pq.size()){
      Type now_cost = pq.top().first;
      int now = pq.top().second;
      pq.pop();
      
      if(cost[now] >= 0) continue;
      
      cost[now] = -now_cost;
      max_cost = max(max_cost, -now_cost);
      
      if(now == g) return -now_cost;
      
      for(int i=0;i<(int)G[now].size();i++){
        pq.push({now_cost-G[now][i].second, G[now][i].first});
      }
    }
    
    return max_cost;
  }
  
};

Dijkstra dijk(5*1000 + 20);
char c[SIZE][SIZE];

bool solve(){
  int h,w;
  int sy,sx,gy,gx;
  vector<pair<int,int> > vec[6];
  
  scanf("%d%d",&h,&w);

  if(h == 0) return false;

  if(h < 900){
    puts("0");
    return false;
  }
  
  for(int i=0;i<h;i++){
    scanf("%s",c[i]);

    for(int j=0;j<w;j++){
      if('1' <= c[i][j] && c[i][j] <= '5'){
        vec[c[i][j]-'1'].push_back({i,j});
      }
      if(c[i][j] == 'S'){
        sy = i; sx = j;
      }
      if(c[i][j] == 'G'){
        gy = i; gx = j;
      }
    }
  }

  dijk.init(5020);
  
  for(int i=0;i<5;i++){
    for(int j=0;j<vec[i].size();j++){
      for(int k=0;k<vec[(i+1)%5].size();k++){
        dijk.add_edge(i*1000 + j, ((i+1)%5)*1000 + k,
                      abs(vec[i][j].first - vec[(i+1)%5][k].first)+abs(vec[i][j].second - vec[(i+1)%5][k].second));
      }
    }
  }

  for(int i=0;i<5;i++){
    for(int j=0;j<vec[i].size();j++){
      dijk.add_edge(5000 + i, i*1000 + j,abs(sy-vec[i][j].first)+abs(sx-vec[i][j].second));
      dijk.add_edge(i*1000 + j, 5010 + i,abs(gy-vec[i][j].first)+abs(gx-vec[i][j].second));
    }
  }

  int ans = INF;
  int ans2 = -1;

  for(int i=0;i<5;i++){
    int ret = dijk.solve(5000 + (i+1)%5, 5010 + (i+4)%5);
    if(ans > ret){
      ans = ret;
      ans2 = i+1;
    }
  }

  if(ans == INF){
    puts("NA");
  }else{
    printf("%d %d\n",ans2, ans);
  }
  
  return true;
}

int main(){

  while(solve());
  
  return 0;
}