#include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 12

struct Info{
	Info(){
		row = col = 0;
	}
	Info(int arg_row,int arg_col){
		row = arg_row;
		col = arg_col;
	}
	void set(int arg_row,int arg_col){
		row = arg_row;
		col = arg_col;
	}
	bool operator==(const struct Info &arg) const{
		return row == arg.row && col == arg.col;
	}
	int row,col;
};

int W,H;
int ice_index,index_table[NUM][NUM];
int diff_row[4] = {1,0,-1,0},diff_col[4] = {0,1,0,-1};
int num_member[NUM*NUM],ice_count_table[NUM*NUM];
int ans;
char base_map[NUM][NUM+1];
bool visited[NUM][NUM];
Info start,goal;

bool rangeCheck(Info info){
	if(info.row >= 0 && info.row <= H-1 && info.col >= 0 && info.col <= W-1){
		return true;
	}else{
		return false;
	}
}

void recursive(Info info,int sum_cost){

	if(info == goal){
		ans = min(ans,sum_cost);
		return;
	}

	//最小値が出ないならreturn
	if(sum_cost+abs(info.row-goal.row)+abs(info.col-goal.col) >= ans){
		return;
	}

	int adj_row,adj_col;
	int adj_row_2,adj_col_2;

	bool FLG;

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

		adj_row = info.row+diff_row[i];
		adj_col = info.col+diff_col[i];

		if(rangeCheck(Info(adj_row,adj_col)) == false || base_map[adj_row][adj_col] == '#' ||
				visited[adj_row][adj_col] == true)continue;

		//最小値が出ないならcontinue
		if(sum_cost+abs(adj_row-goal.row)+abs(adj_col-goal.col) >= ans)continue;

		FLG = true;

		for(int k = 0; k < 4; k++){
			adj_row_2 = adj_row+diff_row[k];
			adj_col_2 = adj_col+diff_col[k];

			if(rangeCheck(Info(adj_row_2,adj_col_2)) == false || base_map[adj_row_2][adj_col_2] == '#' ||
					(adj_row_2 == info.row && adj_col_2 == info.col))continue;

			if(visited[adj_row_2][adj_col_2]){
				FLG = false;
				break;
			}
		}

		if(!FLG)continue;

		if(base_map[adj_row][adj_col] == '.'){

			visited[adj_row][adj_col] = true;
			recursive(Info(adj_row,adj_col),sum_cost+1);

			visited[adj_row][adj_col] = false;

		}else{ //base_map[adj_row][adj_col] == 'X'

			int tmp_index = index_table[adj_row][adj_col];
			if(ice_count_table[tmp_index]+1 > num_member[tmp_index]/2)continue; //氷が割れるのでcontinue

			visited[adj_row][adj_col] = true;
			ice_count_table[tmp_index]++;
			recursive(Info(adj_row,adj_col),sum_cost+1);

			visited[adj_row][adj_col] = false;
			ice_count_table[tmp_index]--;
		}
	}
}

void func(){

	for(int row = 0; row < H; row++){
		scanf("%s",base_map[row]);
		for(int col = 0; col < W; col++){
			if(base_map[row][col] == 'S'){

				start.set(row,col);
				base_map[row][col] = '.';

			}else if(base_map[row][col] == 'G'){

				goal.set(row,col);
				base_map[row][col] = '.';
			}
		}
	}

	//氷マスを連結させる&枚数を数える
	ice_index = 0;

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			index_table[row][col] = -1;
		}
	}

	queue<Info> Q;
	int adj_row,adj_col,count;

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			if(base_map[row][col] != 'X' || index_table[row][col] != -1)continue;

			index_table[row][col] = ice_index;
			Q.push(Info(row,col));

			count = 1;

			while(!Q.empty()){

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

					adj_row = Q.front().row+diff_row[i];
					adj_col = Q.front().col+diff_col[i];

					if(rangeCheck(Info(adj_row,adj_col)) == false || base_map[adj_row][adj_col] != 'X' ||
							index_table[adj_row][adj_col] != -1)continue;

					index_table[adj_row][adj_col] = ice_index;
					count++;

					Q.push(Info(adj_row,adj_col));
				}
				Q.pop();
			}

			num_member[ice_index] = count;
			ice_index++;
		}
	}

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			visited[row][col] = false;
		}
	}
	visited[start.row][start.col] = true;

	ans = H*W;
	for(int i = 0; i < ice_index; i++)ice_count_table[i] = 0;

	recursive(start,0);

	printf("%d\n",ans);
}

int main(){

	while(true){
		scanf("%d %d",&W,&H);
		if(W == 0 && H == 0)break;

		func();
	}

	return 0;
}



Measured memory_bytes: 3128