#include <bits/stdc++.h>

//{{{ graph.hpp
#ifndef INCLUDE_GRAPH_HPP
#define INCLUDE_GRAPH_HPP
#include <vector>
namespace orliv {
struct Edge {
  typedef int weight_t;
  int from, to;
  weight_t w;
  Edge(int from, int to, weight_t w) : from(from), to(to), w(w) {}
  bool operator<(const Edge& e) const {
    return w != e.w ? w > e.w : from != e.from ? from < e.from : to < e.to;
  }
  static const weight_t INF;
};
const int Edge::INF=INT_MAX;
typedef std::vector<Edge> Edges;
typedef std::vector<Edges> Graph;
}
#endif
//}}}

using namespace std;
using namespace orliv;

//{{{ void dijkstra(g, s, &dist, &prev)
void dijkstra(const Graph& g, int s, vector<Edge::weight_t>& dist, vector<int>& prev)
{
  const int V = g.size();
  prev.assign(V, -1);
  dist.assign(V, Edge::INF);
  dist[s] = 0;
  priority_queue<Edge> pq;
  for (pq.push(Edge(-2, s, 0)); !pq.empty();){
    Edge c = pq.top();
    pq.pop();
    if (prev[c.to] != -1) continue;
    prev[c.to] = c.from;
    for (const auto& e : g[c.to]){
      if (dist[e.to] > e.w + c.w){
        dist[e.to] = e.w + c.w;
        pq.push(Edge(e.from, e.to, e.w + c.w));
      }
    }
  }
}
//}}}

typedef pair<int, int> P;

const int INF = 1 << 29;

inline int dist(const P& a, const P& b){
  return abs(a.first - b.first) + abs(a.second - b.second);
}

int main()
{
  int w, h;
  while (scanf("%d %d", &w, &h), w){
    vector<P> ps[5];
    vector<int> is[5];
    P start, goal;
    for (int y = 0; y < h; y++){
      char line[1024];
      scanf("%s", line);
      for (int x = 0; x < w; x++){
        if (line[x] == 'S') start = P(x, y);
        else if (line[x] == 'G') goal = P(x, y);
        else if (line[x] != '.') {
          int id = line[x] - '1';
          ps[id].push_back(P(x, y));
        }
      }
    }
    int V = 2;
    for (int i = 0; i < 5; i++){
      for (auto& p : ps[i]){
        is[i].push_back(V++);
      }
    }
    int mini = INF;
    int mini_id = -1;
    Graph G(V);
    for (int init = 0; init < 5; init++){
      int nxt = (init + 1) % 5;
      for (int i = 0; i < ps[nxt].size(); i++){
        G[0].emplace_back(0, is[nxt][i], dist(start, ps[nxt][i]));
      }
      for (int i = 0; i < 3; i++){
        int nnxt = (nxt + 1) % 5;
        for (int j = 0; j < ps[nxt].size(); j++){
          for (int k = 0; k < ps[nnxt].size(); k++){
            G[is[nxt][j]].emplace_back(is[nxt][j], is[nnxt][k], dist(ps[nxt][j], ps[nnxt][k]));
          }
        }
        nxt = nnxt;
      }
      for (int i = 0; i < ps[nxt].size(); i++){
        G[is[nxt][i]].emplace_back(is[nxt][i], 1, dist(goal, ps[nxt][i]));
      }
      vector<int> d, prev;
      dijkstra(G, 0, d, prev);
      if (mini > d[1]){
        mini = d[1];
        mini_id = init;
      }
    }
    if (mini_id == -1) puts("NA");
    else printf("%d %d\n", mini_id + 1, mini);
  }
  return 0;
}