import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

class Main {

	// 開始地点
	private static final int START = 8;
	// 終了地点
	private static final int GOAL = 9;

	public static void main(String[] args) {

		// ストリームを作成する
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				System.in));

		while (true) {
			// 入力値からフィールドを作成する
			int[][] field = readField(reader);
			// 入力がない場合は終了
			if (field == null) {
				return;
			}

			// 初期パチモン候補を取得する（クリア判定を兼ねる）
			int[] first = getFirstPachimon(field);
			if (first == null) {
				System.out.println("NA");
				continue;
			}

			// 初期パチモン候補ごとにコストを計算する
			int[] cost = new int[first.length];
			for (int i = 0; i < cost.length; i++) {
				cost[i] = getCost(field, first[i]);
			}

			// コストが一番低い初期パチモンを探す
			int index = 0;
			int minCost = cost[index];
			for (int i = 1; i < cost.length; i++) {
				if (minCost > cost[i]) {
					minCost = cost[i];
					index = i;
				}
			}

			// 結果を出力する
			System.out.println(first[index] + " " + minCost);
		}

	}

	/**
	 * ストリームから1行読み込んで、フィールド情報返す。 値が取得できなかった場合はnullを返す。
	 *
	 * @param reader
	 *            入力ストリーム
	 * @return フィールド情報
	 */
	private static int[][] readField(BufferedReader reader) {
		int[][] field = null;
		try {
			String line = reader.readLine();
			String[] mapSize = line.split(" ");
			int x = Integer.parseInt(mapSize[0]);
			int y = Integer.parseInt(mapSize[1]);

			if (x == 0 && y == 0) {
				return null;
			}

			// フィールド情報読み込み
			field = new int[y][x];
			for (int i = 0; i < y; i++) {
				line = reader.readLine();
				for (int j = 0; j < x; j++) {
					String str = line.substring(j, j + 1);
					if (".".equals(str)) {
						field[i][j] = 0;
					} else if ("S".equals(str)) {
						field[i][j] = START;
					} else if ("G".equals(str)) {
						field[i][j] = GOAL;
					} else {
						field[i][j] = Integer.parseInt(str);
					}
				}
			}

		} catch (IOException e) {
			throw new RuntimeException();
		}

		return field;
	}

	/**
	 * ゲームがクリアできるかどうかチェックし、クリアできる場合は初期パチモン候補を返す。
	 *
	 * @param field
	 *            フィールド
	 * @return クリアできる場合は初期パチモン候補の配列、そうでない場合はnull
	 */
	private static int[] getFirstPachimon(int[][] field) {

		// パチモンの種類を取得する
		boolean[] exists = new boolean[5];
		for (int i = 0; i < field.length; i++) {
			for (int j = 0; j < field[i].length; j++) {
				if (1 <= field[i][j] && field[i][j] <= 5) {
					exists[field[i][j] - 1] = true;
				}
			}
		}

		// 存在する種類数と存在しない種類を1つだけ保持する
		int count = 0;
		int notExists = -1;
		for (int i = 0; i < 5; i++) {
			if (exists[i]) {
				count++;
			} else {
				notExists = i + 1;
			}
		}

		// 4種類の場合は1種類固定、5種類の場合は全種類が候補になる
		int[] candidate = null;
		if (count == 4) {
			candidate = new int[1];
			candidate[0] = notExists;
		} else if (count == 5) {
			candidate = new int[5];
			for (int i = 0; i < 5; i++) {
				candidate[i] = i + 1;
			}
		}

		return candidate;
	}

	/**
	 * 指定フィールド・指定初期パチモンで、ゴールまでにかかるコストを調べる。
	 *
	 * @param field
	 *            フィールド
	 * @param first
	 *            初期パチモンの属性
	 * @return
	 */
	private static int getCost(int[][] field, int first) {

		Status status = getStart(field);
		int current = first;

		// System.out.println("初期パチモン： " + first);
		// System.out.println(status);

		// 4匹つかまえ、最後にゴールに向かう
		List<Status> variation = new ArrayList<Status>();
		variation.add(status);
		for (int i = 0; i < 5; i++) {

			// ターゲットが複数いた場合、バリエーションが増えていく
			int target = getTarget(current, first);
			List<Status> nextVariation = capture(field, target, variation);

			// デバッグ
			// System.out.println(" #" + i + " ターゲット: " + target);
			// for (Status s : nextVariation) {
			// 	System.out.println(s);
			// }

			// 次のループの準備
			variation = nextVariation;
			current = target;
		}

		// 一番コストが小さいものを取得する
		int minCost = variation.get(0).cost;
		// System.out.println("最小コスト： " + minCost);

		return minCost;
	}

	/**
	 * 次のターゲット属性を取得する。
	 *
	 * @param current
	 *            直前に取得したパチモンの属性
	 * @param first
	 *            初期パチモンの属性
	 * @return 次のターゲット属性、すべて揃った場合はゴール
	 */
	private static int getTarget(int current, int first) {

		// 現在の属性より1大きいものを次のターゲットとする
		int target = (current % 5) + 1;

		// 初期パチモンに戻ってきたらゴールを目指す
		if (target == first) {
			target = GOAL;
		}

		return target;
	}

	/**
	 * 開始時のステータスを取得する。
	 *
	 * @param field
	 *            フィールド
	 * @return 開始時のステータス
	 */
	private static Status getStart(int[][] field) {
		Status status = null;
		for (int i = 0; i < field.length; i++) {
			for (int j = 0; j < field[i].length; j++) {
				if (field[i][j] == START) {
					status = new Status(j, i, 0);
					break;
				}
			}
		}
		return status;
	}

	/**
	 * 次のポケモンを捕獲する。
	 *
	 * @param field
	 *            フィールド
	 * @param target
	 *            ターゲット
	 * @param current
	 *            現在の状態
	 * @return バリエーション
	 */
	private static List<Status> capture(int[][] field, int target,
			List<Status> current) {

		// フィールド全体から次のターゲットを探す
		List<Status> v = new ArrayList<Status>();
		for (int i = 0; i < field.length; i++) {
			for (int j = 0; j < field[i].length; j++) {

				// 次のターゲットに到達するコストのうち、最小のものだけを保持する
				if (field[i][j] == target) {
					int minCost = Integer.MAX_VALUE;
					for (Status s : current) {
						int cost = s.cost + Math.abs(s.x - j)
								+ Math.abs(s.y - i);
						if (minCost > cost) {
							minCost = cost;
						}
					}
					v.add(new Status(j, i, minCost));
				}

			}
		}
		return v;
	}

	/**
	 * あるパチモンを捕まえたときの状態を保持する
	 *
	 */
	private static class Status {

		// x 座標
		public int x;
		// y 座標
		public int y;
		// 累計コスト
		public int cost;

		/**
		 * コンストラクタ
		 *
		 * @param x x座標
		 * @param y y座標
		 * @param cost 累計コスト
		 */
		public Status(int x, int y, int cost) {
			this.x = x;
			this.y = y;
			this.cost = cost;
		}

		@Override
		public String toString() {
			return "(" + x + "," + y + "): " + cost;
		}
	}

}

Measured memory_bytes: 160804