#include <iostream>
#include <queue>
#include <climits>
#include <vector>
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
typedef pair<pair<int,int>,pair<int,int> > NODE;
#define Y first.first
#define X first.second
#define HAVE second.first
#define DEPTH second.second
#define NEXT_X (q.X+dx[i])
#define NEXT_Y (q.Y+dy[i])
const int dx[] = {1,-1,0,0};
const int dy[] = {0,0,1,-1};
int gy,gx;

int isnumber(char a){
	return (a>='0' && a<='9');
}

int abs(int a){
	return a<0 ? -a : a;
}
int goal(int y,int x){
	return abs(y-gy) + abs(x-gx);
}

int bit(int bits) {
  bits = (bits & 0x55555555) + (bits >> 1 & 0x55555555);
  bits = (bits & 0x33333333) + (bits >> 2 & 0x33333333);
  bits = (bits & 0x0f0f0f0f) + (bits >> 4 & 0x0f0f0f0f);
  bits = (bits & 0x00ff00ff) + (bits >> 8 & 0x00ff00ff);
  return (bits & 0x0000ffff) + (bits >>16 & 0x0000ffff);
}

int main(){
	int w,h,sx,sy;
	char data[1002][1002];
	rep(i,1002)rep(j,1002)data[i][j]='#';
	vector<vector< vector<int> > > memo (1002);
	rep(i,1002){
		memo[i].resize(1002);
		rep(j,31)
			memo[i][j].resize(31);
	}
	
	int mi_select=INT_MAX,mi_step = INT_MAX;
	while(cin >> w >> h && w || h){
		//rep(i,1002)rep(j,1002)rep(k,32)memo[i][j][k] = (1<<21);
		
		rep(i,h)rep(j,w){
			cin >> data[1+i][1+j];
			if(data[i+1][j+1]=='S'){sx = j+1;sy = i+1;}
			if(data[i+1][j+1]=='G'){gx = j+1;gy = i+1;}
			
		}
		queue<NODE> Q;
		Q.push(make_pair(make_pair(sy,sx),make_pair(0,0)));
		
		while(Q.size()){
			NODE q = Q.front();Q.pop();
			if( isnumber(data[q.Y][q.X]) ){
				q.HAVE = q.HAVE | (1 << (data[q.Y][q.X]-'1'));
			}
			if( q.DEPTH >= memo[q.Y][q.X][q.HAVE])continue;
				memo[q.Y][q.X][q.HAVE] = q.DEPTH;
			if( bit(q.HAVE) == 4 ){
				int z,d;
				if( q.HAVE & 1 == 0)z = 1;
				if( q.HAVE & 2 == 0)z = 2;
				if( q.HAVE & 4 == 0)z = 3;
				if( q.HAVE & 8 == 0)z = 4;
				if( q.HAVE & 16== 0)z = 5;
				
				d = q.DEPTH + goal(q.Y,q.X);
				if( d < mi_step){
					mi_step = q.DEPTH;
					mi_select = z;
				}else if( d == mi_step){
					if(z < mi_select)mi_select = z;
				}
				continue;
			}

			for(int i=0;i<4;i++){
				if( data[NEXT_Y][NEXT_X] != '#'){
					Q.push(make_pair(make_pair(NEXT_Y,NEXT_X),make_pair(q.HAVE,q.DEPTH+1) ));
				}
			}
		}
		
		
		
	}
}