stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
//#include<bits/stdc++.h>

//#include<tr1/unordered_map>

#include<iostream>

#include<string>

#include<algorithm>

#include<utility>

#include<functional>

#include<vector>



#pragma GCC optimize ("Ofast")

#define ll long long

#define pll pair<long long,long long>

#define pii pair<int,int>

#define mp make_pair

#define pb push_back

#define F first

#define S second

#define forn(i, n) for(int i=0; i<int(n); i++)

#define Forn(i, n) for(int i=1; i<=int(n); i++)



using namespace std;



/*#include <ext/pb_ds/tree_policy.hpp>

#include <ext/pb_ds/assoc_container.hpp>

using namespace __gnu_pbds;

typedef tree<pii, null_type, less<pii>, rb_tree_tag, tree_order_statistics_node_update> rbtree;*/



string s;



int main()

{

    cin.tie(0);ios_base::sync_with_stdio(false);

    cin >> s;

    sort(s.begin(), s.end());

    for(char c = 'a'; c<='z'; c++)

    {

        if(!binary_search(s.begin(), s.end(), c))

        {

            cout << c << endl;

            return 0;

        }

    }

    cout << "None" << endl;

}


// Faster C++ solution for the same problem (measured speedup: 5.392566548279426x):
#include <stdio.h>

#include <string.h>



int cnt[26] = {};

char s[100005];



int main() {

    scanf("%s", s);

    for(int i = 0; s[i]; i++)

        cnt[s[i] - 'a']++;

    for(int i = 0; i < 26; i++) {

        if(!cnt[i]) {

            printf("%c\n", i + 'a');

            return 0;

        }

    }

    puts("None");

    return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;



#define all(cont) cont.begin(), cont.end()

#define rall(cont) cont.end(), cont.begin()

#define mp make_pair

#define pb push_back

#define fs first

#define sc second

#define fr(i, a, b) for(int i = a ; i < b ; i++)

#define frr(i, a, b) for(int i = a ; i >= b ; i--)

#define tr(it, var) for(__typeof(var.begin()) it = var.begin(); it != var.end(); it++)

#define trr(rit, var) for(__typeof(var.rbegin()) rit = var.rbegin(); rit != var.rend(); rit++)

#define its(x) static_cast< ostringstream & >( ( ostringstream() << dec << x ) ).str() // int to string

#define boost ios_base::sync_with_stdio(false)

#define deb(x) cout << #x" = " << x << '\n'

#define has(cont, x) ((cont).find((x)) != (cont).end())

#define sz(x) ((int)(x).size())



typedef long long ll;

typedef unsigned long long ull;

typedef long double ld;

typedef pair<int, int> pii;

typedef pair<ll, ll> pll;

typedef vector<int> vi;





int main() {

//    freopen("input.in", "r", stdin);

	int a[5];

	scanf("%d %d %d", a+0, a+1, a+2);

	sort(a, a+3);

//	printf("%d %d %	d\n", a[0], a[1], a[2]);

	bool ok = false;

	while(1) {

		if(a[0]+a[1] == a[2]) ok = true;

//		deb(a[0]);

//		deb(a[1]);

//		deb(a[2]);

		if(!next_permutation(a, a+3)) break;

	}

	puts(ok ? "Yes" : "No");

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 5.24207736361524x):
#include<cstdio>

#include<cmath>



const int N = 100000;

char a[N];

char b[N];

int main()

{

	int a,b,c;

	scanf("%d%d%d",&a,&b,&c);

	if(a == b+c || b == a+c || c == a+b)

	printf("Yes\n");

	else

	printf("No\n");

	return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;



#define all(cont) cont.begin(), cont.end()

#define rall(cont) cont.end(), cont.begin()

#define mp make_pair

#define pb push_back

#define fs first

#define sc second

#define fr(i, a, b) for(int i = a ; i < b ; i++)

#define frr(i, a, b) for(int i = a ; i >= b ; i--)

#define tr(it, var) for(__typeof(var.begin()) it = var.begin(); it != var.end(); it++)

#define trr(rit, var) for(__typeof(var.rbegin()) rit = var.rbegin(); rit != var.rend(); rit++)

#define its(x) static_cast< ostringstream & >( ( ostringstream() << dec << x ) ).str() // int to string

#define boost ios_base::sync_with_stdio(false)

#define deb(x) cout << #x" = " << x << '\n'

#define has(cont, x) ((cont).find((x)) != (cont).end())

#define sz(x) ((int)(x).size())



typedef long long ll;

typedef unsigned long long ull;

typedef long double ld;

typedef pair<int, int> pii;

typedef pair<ll, ll> pll;

typedef vector<int> vi;





int main() {

//    freopen("input.in", "r", stdin);

	int a[5];

	scanf("%d %d %d", a+0, a+1, a+2);

	sort(a, a+3);

//	printf("%d %d %	d\n", a[0], a[1], a[2]);

	bool ok = false;

	while(1) {

		if(a[0]+a[1] == a[2]) ok = true;

//		deb(a[0]);

//		deb(a[1]);

//		deb(a[2]);

		if(!next_permutation(a, a+3)) break;

	}

	puts(ok ? "Yes" : "No");

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 5.147898237896157x):
# include <stdio.h>

#include <stdlib.h>

int main()

{

	int a, b, c;

	scanf("%d%d%d", &a, &b, &c);

	if (a+b==c)

	{

		printf("Yes\n");

	}

	else 

	{

		if (b+c==a)

		{

			printf("Yes\n");

		}

		else 

		{

			if (c+a==b)

			{

				printf("Yes\n");

			}

			else 

			{ 

				printf("No\n");

			}

		}

	}

	system("pause");

}
// Slower C++ solution:
#include <iostream>

#include <algorithm>

#include <vector>

using namespace std;

#define rep(i,n) for(int i = 0 ; i < n ; i++)

struct P{int x,y;P(){}P(int a,int b){x = a , y = b;}};

int operator -(P a, P b){

	return abs(a.x - b.x) + abs(a.y - b.y);

}

int dp[1<<5][5][1000];

#define INF (1<<21)

int main(){	

	int W,H;

	while(cin >> W >> H , W){

		P s , g ;

		vector<P> v[6];

		rep(i,H)rep(j,W){

			char c; cin >> c;

			if(c == 'S') s = P(j,i);

			else if(c == 'G') g = P(j,i);

			else if(c != '.') v[c-'1'].push_back(P(j,i));

		}

		rep(i,1<<5)rep(k,5)rep(j,1000)dp[i][k][j] = INF;

		rep(i,5)rep(j,v[(i+1)%5].size()){

			dp[(1<<i) | (1<<((i+1)%5))][(i+1)%5][j] = s - v[(i+1)%5][j];

		}

		rep(bit,(1<<5)-1)rep(x,5){

			int y = (x+1)%5;

			rep(i,v[x].size()){

				if( dp[bit][x][i] == INF ) continue;

				rep(j,v[y].size()){

					dp[bit|(1<<y)][y][j] = min( dp[bit|(1<<y)][y][j] , dp[bit][x][i] + (v[x][i]-v[y][j]) );

				}

			}

		}

		int ans = INF , cho = -1;

		rep(i,5) rep( j , v[i].size() ){

			int cst = dp[(1<<5)-1][i][j] + (g - v[i][j]);

			int w = (i+1)%5;

			if(ans >= cst){

				if(ans == cst){

					cho = min(cho, w );

				}else{

					cho = w;

					ans = cst;

				}

			}

		}

		if(ans == INF) cout << "NA" << endl;

		else cout << cho+1 << " " << ans << endl;

		

		

	}

	

}

// Faster C++ solution for the same problem (measured speedup: 1.6652089805569708x):
#include <iostream>

#include <vector>

#include <tr1/unordered_map>

#include <queue>

#include <cstdio>

#include <algorithm>

using namespace std;



int X,Y;

struct NODE{

	int x,y,z,cost,fc;

	NODE(int x,int y,int z,int cost,int fc):

	x(x) , y(y) , z(z) , cost(cost) , fc(fc) {}

};

bool operator < (const NODE &a,const NODE &b){

	return a.cost != b.cost ? a.cost > b.cost : a.fc > b.fc;

}



int x[5][1000];

int y[5][1000];

int sz[5];

int main(){

	while(cin >> X >> Y && X){

		int sx,sy,gx,gy;

		for(int i = 0 ; i < 5 ; i++) sz[i]=0;

		

		for(int i = 0 ; i < Y ; i++)

			for(int j = 0 ; j < X ; j++){

				char c; scanf(" %c",&c);

				if(c == 'S'){

					sx = j , sy = i;

				}else if( c == 'G'){

					gx = j , gy = i;

				}else if( c != '.'){

					c = c - '1';

					x[c][sz[c]] = j;

					y[c][sz[c]++] = i;			

				}

			}

		priority_queue<NODE> Q;

		for(int i = 0 ; i < 5 ; i++){

			Q.push(NODE(sx,sy,(i+1)%5,0,i));

		}

		tr1::unordered_map< int , int > memo[5][5];

		

		while(Q.size()){



			NODE q = Q.top(); Q.pop();



			

			if(q.z == 10){

				cout << q.fc+1 << " " << q.cost << endl;

				goto exit;

			}

			if(memo[q.z][q.fc][(q.x<<12)|q.y] < q.cost) continue;

			if(q.z == q.fc){

				Q.push(NODE(gx,gy,10,q.cost+abs(q.x-gx)+abs(q.y-gy),q.fc));

			}else{

				for(int i = 0 ; i < sz[q.z] ; i++){

					NODE t = NODE(x[q.z][i],y[q.z][i],(q.z+1)%5,q.cost+abs(q.x-x[q.z][i])+abs(q.y-y[q.z][i]),q.fc);

					if( !memo[t.z][t.fc].count((t.x<<12)|t.y) || t.cost < memo[t.z][t.fc][(t.x<<12)|t.y])

						memo[t.z][t.fc][(t.x<<12)|t.y] = t.cost,Q.push(t);

				}

			}

		}

		cout << "NA" << endl;

		exit:;

	}

		

}
// Slower C++ solution:
#include <iostream>

#include <algorithm>

#include <vector>

using namespace std;

#define rep(i,n) for(int i = 0 ; i < n ; i++)

struct P{int x,y;P(){}P(int a,int b){x = a , y = b;}};

int operator -(P a, P b){

	return abs(a.x - b.x) + abs(a.y - b.y);

}

int dp[1<<5][5][1000];

#define INF (1<<21)

int main(){	

	int W,H;

	while(cin >> W >> H , W){

		P s , g ;

		vector<P> v[6];

		rep(i,H)rep(j,W){

			char c; cin >> c;

			if(c == 'S') s = P(j,i);

			else if(c == 'G') g = P(j,i);

			else if(c != '.') v[c-'1'].push_back(P(j,i));

		}

		rep(i,1<<5)rep(k,5)rep(j,1000)dp[i][k][j] = INF;

		rep(i,5)rep(j,v[(i+1)%5].size()){

			dp[(1<<i) | (1<<((i+1)%5))][(i+1)%5][j] = s - v[(i+1)%5][j];

		}

		rep(bit,(1<<5)-1)rep(x,5){

			int y = (x+1)%5;

			rep(i,v[x].size()){

				if( dp[bit][x][i] == INF ) break; // <- ツ催適ツ可サ

				rep(j,v[y].size()){

					dp[bit|(1<<y)][y][j] = min( dp[bit|(1<<y)][y][j] , dp[bit][x][i] + (v[x][i]-v[y][j]) );

				}

			}

		}

		int ans = INF , cho = -1;

		rep(i,5) rep( j , v[i].size() ){

			int cst = dp[(1<<5)-1][i][j] + (g - v[i][j]);

			int w = (i+1)%5;

			if(ans >= cst){

				if(ans == cst){

					cho = min(cho, w );

				}else{

					cho = w;

					ans = cst;

				}

			}

		}

		if(ans == INF) cout << "NA" << endl;

		else cout << cho+1 << " " << ans << endl;

		

		

	}

	

}

// Faster C++ solution for the same problem (measured speedup: 1.664072583697142x):
#include <iostream>

#include <vector>

#include <tr1/unordered_map>

#include <queue>

#include <cstdio>

#include <algorithm>

using namespace std;



int X,Y;

struct NODE{

	int x,y,z,cost,fc;

	NODE(int x,int y,int z,int cost,int fc):

	x(x) , y(y) , z(z) , cost(cost) , fc(fc) {}

};

bool operator < (const NODE &a,const NODE &b){

	return a.cost != b.cost ? a.cost > b.cost : a.fc > b.fc;

}



int x[5][1000];

int y[5][1000];

int sz[5];

int main(){

	while(cin >> X >> Y && X){

		int sx,sy,gx,gy;

		for(int i = 0 ; i < 5 ; i++) sz[i]=0;

		

		for(int i = 0 ; i < Y ; i++)

			for(int j = 0 ; j < X ; j++){

				char c; scanf(" %c",&c);

				if(c == 'S'){

					sx = j , sy = i;

				}else if( c == 'G'){

					gx = j , gy = i;

				}else if( c != '.'){

					c = c - '1';

					x[c][sz[c]] = j;

					y[c][sz[c]++] = i;			

				}

			}

		priority_queue<NODE> Q;

		for(int i = 0 ; i < 5 ; i++){

			Q.push(NODE(sx,sy,(i+1)%5,0,i));

		}

		tr1::unordered_map< int , int > memo[5][5];

		

		while(Q.size()){



			NODE q = Q.top(); Q.pop();



			

			if(q.z == 10){

				cout << q.fc+1 << " " << q.cost << endl;

				goto exit;

			}

			if(memo[q.z][q.fc][(q.x<<12)|q.y] < q.cost) continue;

			if(q.z == q.fc){

				Q.push(NODE(gx,gy,10,q.cost+abs(q.x-gx)+abs(q.y-gy),q.fc));

			}else{

				for(int i = 0 ; i < sz[q.z] ; i++){

					NODE t = NODE(x[q.z][i],y[q.z][i],(q.z+1)%5,q.cost+abs(q.x-x[q.z][i])+abs(q.y-y[q.z][i]),q.fc);

					if( !memo[t.z][t.fc].count((t.x<<12)|t.y) || t.cost < memo[t.z][t.fc][(t.x<<12)|t.y])

						memo[t.z][t.fc][(t.x<<12)|t.y] = t.cost,Q.push(t);

				}

			}

		}

		cout << "NA" << endl;

		exit:;

	}

		

}
// Slower C++ solution:
#include <iostream>

#include <algorithm>

#include <vector>

using namespace std;

#define rep(i,n) for(int i = 0 ; i < n ; i++)

struct P{int x,y;P(){}P(int a,int b){x = a , y = b;}};

int operator -(P a, P b){

	return abs(a.x - b.x) + abs(a.y - b.y);

}

int dp[1<<5][5][1000];

#define INF (1<<21)

int main(){	

	int W,H;

	while(cin >> W >> H , W){

		P s , g ;

		vector<P> v[6];

		rep(i,H)rep(j,W){

			char c; cin >> c;

			if(c == 'S') s = P(j,i);

			else if(c == 'G') g = P(j,i);

			else if(c != '.') v[c-'1'].push_back(P(j,i));

		}

		rep(i,1<<5)rep(k,5)rep(j,1000)dp[i][k][j] = INF;

		rep(i,5)rep(j,v[(i+1)%5].size()){

			dp[(1<<i) | (1<<((i+1)%5))][(i+1)%5][j] = s - v[(i+1)%5][j];

		}

		rep(bit,(1<<5)-1)rep(x,5){

			int y = (x+1)%5;

			rep(i,v[x].size()){

				if( dp[bit][x][i] == INF ) continue;

				rep(j,v[y].size()){

					dp[bit|(1<<y)][y][j] = min( dp[bit|(1<<y)][y][j] , dp[bit][x][i] + (v[x][i]-v[y][j]) );

				}

			}

		}

		int ans = INF , cho = -1;

		rep(i,5) rep( j , v[i].size() ){

			int cst = dp[(1<<5)-1][i][j] + (g - v[i][j]);

			int w = (i+1)%5;

			if(ans >= cst){

				if(ans == cst){

					cho = min(cho, w );

				}else{

					cho = w;

					ans = cst;

				}

			}

		}

		if(ans == INF) cout << "NA" << endl;

		else cout << cho+1 << " " << ans << endl;

		

		

	}

	

}

// Faster C++ solution for the same problem (measured speedup: 1.5412776019367789x):
#include <iostream>

#include <cstdlib>

#include <vector>

using namespace std;

struct P{

	int x,y,cost;

	P(int a,int b,int c){x = a, y = b , cost = c;}

	P(){}

};

#define INF (1<<25)

#define rep(i,n) for(int i=0; i<n ;i++)



int dist(P a,P b){

	return abs(a.x-b.x) + abs(a.y-b.y);

}

int main(){

	int w,h;

	

	while(cin >> w >> h , w) {

		vector<P> data[5];

		P start , goal ;

		

		start.cost = 0 , goal.cost = 0;

		

		rep(i,h)rep(j,w){

			char c;	cin >> c;

			if(c != '.'){

				if(c == 'S')start.x = j , start.y = i;	

				else if(c == 'G')goal.x = j , goal.y = i;

				else {P t(j,i,0) ; data[c-'1'].push_back(t);}

			}

		}

		int ret = INF , num ;

		

		P dp[5][1000];

		

		rep(lp,5){ // start

			rep(i,5)rep(j,1000){dp[i][j].cost = INF;}

			

			int so = (lp+1)%5;

			rep(i,data[so].size()){

				dp[so][i] = data[so][i];

				dp[so][i].cost = dist(data[so][i],start);

			}

			

			rep(Z,3){ // remain 

				int z = (lp+Z+2)%5;

				int prev = (z+4)%5;

				rep(i,data[prev].size()){ // prev

					rep(j,data[z].size()){ //cur

						int cost = dp[prev][i].cost + dist(dp[prev][i],data[z][j]);

						if(dp[z][j].cost > cost){

							dp[z][j] = data[z][j] , dp[z][j].cost = cost;

						}

					}

				}

			}

			rep(i,data[(lp+4)%5].size() ){

				int kCost = dp[(lp+4)%5][i].cost + dist(dp[(lp+4)%5][i],goal);

				if( kCost < ret){

					ret = kCost , num = lp+1; 

				}

			}

		}

		

		if(ret == INF)cout << "NA" << endl; 

		else cout << num << " " << ret << endl; 

	}

}
// Slower C++ solution:
#include <iostream>

#include <algorithm>

#include <vector>

using namespace std;

#define rep(i,n) for(int i = 0 ; i < n ; i++)

struct P{int x,y;P(){}P(int a,int b){x = a , y = b;}};

int operator -(P a, P b){

	return abs(a.x - b.x) + abs(a.y - b.y);

}

int dp[1<<5][5][1000];

#define INF (1<<21)

int main(){	

	int W,H;

	while(cin >> W >> H , W){

		P s , g ;

		vector<P> v[6];

		rep(i,H)rep(j,W){

			char c; cin >> c;

			if(c == 'S') s = P(j,i);

			else if(c == 'G') g = P(j,i);

			else if(c != '.') v[c-'1'].push_back(P(j,i));

		}

		rep(i,1<<5)rep(k,5)rep(j,1000)dp[i][k][j] = INF;

		rep(i,5)rep(j,v[(i+1)%5].size()){

			dp[(1<<i) | (1<<((i+1)%5))][(i+1)%5][j] = s - v[(i+1)%5][j];

		}

		rep(bit,(1<<5)-1)rep(x,5){

			int y = (x+1)%5;

			rep(i,v[x].size()){

				if( dp[bit][x][i] == INF ) break; // <- ツ催適ツ可サ

				rep(j,v[y].size()){

					dp[bit|(1<<y)][y][j] = min( dp[bit|(1<<y)][y][j] , dp[bit][x][i] + (v[x][i]-v[y][j]) );

				}

			}

		}

		int ans = INF , cho = -1;

		rep(i,5) rep( j , v[i].size() ){

			int cst = dp[(1<<5)-1][i][j] + (g - v[i][j]);

			int w = (i+1)%5;

			if(ans >= cst){

				if(ans == cst){

					cho = min(cho, w );

				}else{

					cho = w;

					ans = cst;

				}

			}

		}

		if(ans == INF) cout << "NA" << endl;

		else cout << cho+1 << " " << ans << endl;

		

		

	}

	

}

// Faster C++ solution for the same problem (measured speedup: 1.5402257801850254x):
#include <iostream>

#include <cstdlib>

#include <vector>

using namespace std;

struct P{

	int x,y,cost;

	P(int a,int b,int c){x = a, y = b , cost = c;}

	P(){}

};

#define INF (1<<25)

#define rep(i,n) for(int i=0; i<n ;i++)



int dist(P a,P b){

	return abs(a.x-b.x) + abs(a.y-b.y);

}

int main(){

	int w,h;

	

	while(cin >> w >> h , w) {

		vector<P> data[5];

		P start , goal ;

		

		start.cost = 0 , goal.cost = 0;

		

		rep(i,h)rep(j,w){

			char c;	cin >> c;

			if(c != '.'){

				if(c == 'S')start.x = j , start.y = i;	

				else if(c == 'G')goal.x = j , goal.y = i;

				else {P t(j,i,0) ; data[c-'1'].push_back(t);}

			}

		}

		int ret = INF , num ;

		

		P dp[5][1000];

		

		rep(lp,5){ // start

			rep(i,5)rep(j,1000){dp[i][j].cost = INF;}

			

			int so = (lp+1)%5;

			rep(i,data[so].size()){

				dp[so][i] = data[so][i];

				dp[so][i].cost = dist(data[so][i],start);

			}

			

			rep(Z,3){ // remain 

				int z = (lp+Z+2)%5;

				int prev = (z+4)%5;

				rep(i,data[prev].size()){ // prev

					rep(j,data[z].size()){ //cur

						int cost = dp[prev][i].cost + dist(dp[prev][i],data[z][j]);

						if(dp[z][j].cost > cost){

							dp[z][j] = data[z][j] , dp[z][j].cost = cost;

						}

					}

				}

			}

			rep(i,data[(lp+4)%5].size() ){

				int kCost = dp[(lp+4)%5][i].cost + dist(dp[(lp+4)%5][i],goal);

				if( kCost < ret){

					ret = kCost , num = lp+1; 

				}

			}

		}

		

		if(ret == INF)cout << "NA" << endl; 

		else cout << num << " " << ret << endl; 

	}

}
// Slower C++ solution:
#include <iostream>

#include <algorithm>

#include <vector>

using namespace std;

#define rep(i,n) for(int i = 0 ; i < n ; i++)

struct P{int x,y;P(){}P(int a,int b){x = a , y = b;}};

int operator -(P a, P b){

	return abs(a.x - b.x) + abs(a.y - b.y);

}

int dp[1<<5][5][1000];

#define INF (1<<21)

int main(){	

	int W,H;

	while(cin >> W >> H , W){

		P s , g ;

		vector<P> v[6];

		rep(i,H)rep(j,W){

			char c; cin >> c;

			if(c == 'S') s = P(j,i);

			else if(c == 'G') g = P(j,i);

			else if(c != '.') v[c-'1'].push_back(P(j,i));

		}

		rep(i,1<<5)rep(k,5)rep(j,1000)dp[i][k][j] = INF;

		rep(i,5)rep(j,v[(i+1)%5].size()){

			dp[(1<<i) | (1<<((i+1)%5))][(i+1)%5][j] = s - v[(i+1)%5][j];

		}

		rep(bit,(1<<5)-1)rep(x,5){

			int y = (x+1)%5;

			rep(i,v[x].size()){

				if( dp[bit][x][i] == INF ) continue;

				rep(j,v[y].size()){

					dp[bit|(1<<y)][y][j] = min( dp[bit|(1<<y)][y][j] , dp[bit][x][i] + (v[x][i]-v[y][j]) );

				}

			}

		}

		int ans = INF , cho = -1;

		rep(i,5) rep( j , v[i].size() ){

			int cst = dp[(1<<5)-1][i][j] + (g - v[i][j]);

			int w = (i+1)%5;

			if(ans >= cst){

				if(ans == cst){

					cho = min(cho, w );

				}else{

					cho = w;

					ans = cst;

				}

			}

		}

		if(ans == INF) cout << "NA" << endl;

		else cout << cho+1 << " " << ans << endl;

		

		

	}

	

}

// Faster C++ solution for the same problem (measured speedup: 1.682073972929473x):
#include <iostream>

#include <algorithm>

#include <vector>

#include <queue>

#include <map>

#include <cstring>

#include <cstdio>

#define rep(i,n) for(int i = 0 ; i < n ; i++)

using namespace std;





int W,H;

int sx,sy,gx,gy;

vector< pair<int,int> > e[5];



int memo[1000][1000][5] = {};



int dfs(int x,int y,int c,int r){

	if( memo[x][y][c] != -1 ) return memo[x][y][c];

	if( r == 0 ) return abs(gx-x)+abs(gy-y);

	int g = (c+1)%5;

	int ans = 1e8;

	for(int i = 0 ; i < e[g].size() ; i++){

		ans = min( ans , dfs(e[g][i].first,e[g][i].second,g,r-1) + abs(e[g][i].first-x)+abs(e[g][i].second-y) );

	}

	return memo[x][y][c] = ans;

}

int main(){

	ios_base::sync_with_stdio(false);

	while(cin >> W >> H && W){

		rep(i,5)e[i].clear();

		sx = sy = gx = gy = 1e7;

		

		vector< pair<int,int> > list;

		rep(i,H){

			rep(j,W){

				char c;

				cin >> c;

				if( c == 'S' ) sx = j , sy = i;

				else if( c == 'G' ) gx = j , gy = i;

				else if( c != '.' ) e[c-'1'].push_back(make_pair(j,i)), list.push_back(make_pair(j,i));

			}

		}

		list.push_back(make_pair(sx,sy));

		list.push_back(make_pair(gx,gy));

		int F = !e[0].size() + !e[1].size() + !e[2].size() + !e[3].size() + !e[4].size();

		if( F >= 2){

			cout << "NA" << endl;

			continue;

		}

		pair<int,int> ans = make_pair(1e8,1e8);

		rep(i,5){

			rep(j,list.size()) rep(k,5) memo[list[j].first][list[j].second][k] = -1;

			ans = min(ans,make_pair(dfs(sx,sy,i,4),i));

		}

		if( 1e6 > ans.first ){

			cout << ans.second+1 << " " << ans.first << endl;

		}else{

			cout << "NA" << endl;

		}

	}

}
// Slower C++ solution:
#include <iostream>

#include <algorithm>

#include <vector>

using namespace std;

#define rep(i,n) for(int i = 0 ; i < n ; i++)

struct P{int x,y;P(){}P(int a,int b){x = a , y = b;}};

int operator -(P a, P b){

	return abs(a.x - b.x) + abs(a.y - b.y);

}

int dp[1<<5][5][1000];

#define INF (1<<21)

int main(){	

	int W,H;

	while(cin >> W >> H , W){

		P s , g ;

		vector<P> v[6];

		rep(i,H)rep(j,W){

			char c; cin >> c;

			if(c == 'S') s = P(j,i);

			else if(c == 'G') g = P(j,i);

			else if(c != '.') v[c-'1'].push_back(P(j,i));

		}

		rep(i,1<<5)rep(k,5)rep(j,1000)dp[i][k][j] = INF;

		rep(i,5)rep(j,v[(i+1)%5].size()){

			dp[(1<<i) | (1<<((i+1)%5))][(i+1)%5][j] = s - v[(i+1)%5][j];

		}

		rep(bit,(1<<5)-1)rep(x,5){

			int y = (x+1)%5;

			rep(i,v[x].size()){

				if( dp[bit][x][i] == INF ) break; // <- ツ催適ツ可サ

				rep(j,v[y].size()){

					dp[bit|(1<<y)][y][j] = min( dp[bit|(1<<y)][y][j] , dp[bit][x][i] + (v[x][i]-v[y][j]) );

				}

			}

		}

		int ans = INF , cho = -1;

		rep(i,5) rep( j , v[i].size() ){

			int cst = dp[(1<<5)-1][i][j] + (g - v[i][j]);

			int w = (i+1)%5;

			if(ans >= cst){

				if(ans == cst){

					cho = min(cho, w );

				}else{

					cho = w;

					ans = cst;

				}

			}

		}

		if(ans == INF) cout << "NA" << endl;

		else cout << cho+1 << " " << ans << endl;

		

		

	}

	

}

// Faster C++ solution for the same problem (measured speedup: 1.6809260668088866x):
#include <iostream>

#include <algorithm>

#include <vector>

#include <queue>

#include <map>

#include <cstring>

#include <cstdio>

#define rep(i,n) for(int i = 0 ; i < n ; i++)

using namespace std;





int W,H;

int sx,sy,gx,gy;

vector< pair<int,int> > e[5];



int memo[1000][1000][5] = {};



int dfs(int x,int y,int c,int r){

	if( memo[x][y][c] != -1 ) return memo[x][y][c];

	if( r == 0 ) return abs(gx-x)+abs(gy-y);

	int g = (c+1)%5;

	int ans = 1e8;

	for(int i = 0 ; i < e[g].size() ; i++){

		ans = min( ans , dfs(e[g][i].first,e[g][i].second,g,r-1) + abs(e[g][i].first-x)+abs(e[g][i].second-y) );

	}

	return memo[x][y][c] = ans;

}

int main(){

	ios_base::sync_with_stdio(false);

	while(cin >> W >> H && W){

		rep(i,5)e[i].clear();

		sx = sy = gx = gy = 1e7;

		

		vector< pair<int,int> > list;

		rep(i,H){

			rep(j,W){

				char c;

				cin >> c;

				if( c == 'S' ) sx = j , sy = i;

				else if( c == 'G' ) gx = j , gy = i;

				else if( c != '.' ) e[c-'1'].push_back(make_pair(j,i)), list.push_back(make_pair(j,i));

			}

		}

		list.push_back(make_pair(sx,sy));

		list.push_back(make_pair(gx,gy));

		int F = !e[0].size() + !e[1].size() + !e[2].size() + !e[3].size() + !e[4].size();

		if( F >= 2){

			cout << "NA" << endl;

			continue;

		}

		pair<int,int> ans = make_pair(1e8,1e8);

		rep(i,5){

			rep(j,list.size()) rep(k,5) memo[list[j].first][list[j].second][k] = -1;

			ans = min(ans,make_pair(dfs(sx,sy,i,4),i));

		}

		if( 1e6 > ans.first ){

			cout << ans.second+1 << " " << ans.first << endl;

		}else{

			cout << "NA" << endl;

		}

	}

}