#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <string>
#include <algorithm>
using namespace std;

typedef pair<int,int> P;
const int MAX_W = 12;
const int INF = 1e+8;

int w, h;
vector<string> s;
int dx[4] = {0,0,-1,1};
int dy[4] = {-1,1,0,0};
// ice[y][x] := 氷の番号を返す. (連結な氷をひとつのまとまりとする)
int ice[MAX_W][MAX_W];
// g[y][x] := (x,y) からゴールへの仮の距離
int g[MAX_W][MAX_W];

// (コスト,スタートからの距離,位置,氷の耐久)
struct State{
	int cost, cnt, x, y;
	vector<int> b;
	State(int cost_, int cnt_, int x_, int y_, const vector<int>& b_){
		cost = cost_; cnt = cnt_; x = x_; y = y_; b = b_;
	}
};
bool operator<(const State& a, const State& b){
	return a.cost > b.cost;
}

// 氷の連結成分を調べる.
void dfs(int x, int y, vector<P>& vp){
	if( s[y][x] == 'X' ){
		s[y][x] = 'x';
		vp.push_back( P(x,y) );
	}else{
		return;
	}
	for(int i=0 ; i < 4 ; i++ ){
		int mx = x + dx[i];
		int my = y + dy[i];
		if( mx < 0 || my < 0 || w <= mx || h <= my ) continue;
		if( s[my][mx] == 'X' ){
			dfs(mx,my,vp);
		}
	}
}

// ゴールからの仮の距離を調べる
void bfs(int gx, int gy){
	queue<P> q;
	q.push( P(gx,gy) );
	g[gy][gx] = 0;
	while( !q.empty() ){
		int x = q.front().first;
		int y = q.front().second;
		int cnt = g[y][x];
		q.pop();
		
		for(int i=0 ; i < 4 ; i++ ){
			int mx = x + dx[i];
			int my = y + dy[i];
			if( mx < 0 || my < 0 || w <= mx || h <= my ) continue;
			if( s[my][mx] == '.' || s[my][mx] == 'x' ){
				if( g[my][mx] == INF ){
					g[my][mx] = cnt + 1;
					q.push( P(mx,my) );
				}
			}
		}
	}
}

int solve(){
	int sx, sy, gx, gy;
	int memo[MAX_W][MAX_W];
	// 初期化
	for(int y=0 ; y < h ; y++ ){
		for(int x=0 ; x < w ; x++ ){
			ice[y][x] = -1;
			g[y][x] = INF;
			memo[y][x] = 0;
		}
	}
	// b[id] := 氷の番号 id があと何歩で壊れるかを返す.
	vector<int> b;
	// スタートとゴールと氷の連結成分を調べる.
	int id=0;
	for(int y=0 ; y < h ; y++ ){
		for(int x=0 ; x < w ; x++ ){
			if( s[y][x] == 'S' ){
				s[y][x]  = '.';
				sx = x;
				sy = y;
			}
			if( s[y][x] == 'G' ){
				s[y][x]  = '.';
				gx = x;
				gy = y;
			}
			if( s[y][x] == 'X' ){
				vector<P> vp;
				dfs(x,y,vp);
				for(int i=0 ; i < vp.size() ; i++ ){
					int ax = vp[i].first;
					int ay = vp[i].second;
					ice[ay][ax] = id;
				}
				b.push_back( vp.size()/2 );
				id++;
			}
		}
	}
	// ゴールからの仮の距離を調べる
	bfs(gx,gy);
	
	// (コスト,スタートからの距離,位置) を優先度つきキューで保持
	// コストは スタートからの距離 + ゴールまでの仮の距離
	priority_queue<State> q;
	q.push( State(g[sy][sx],0,sx,sy,b) );
	
	int res = INF;
	while( !q.empty() ){
		int cost = q.top().cost;
		int cnt = q.top().cnt;
		int x = q.top().x;
		int y = q.top().y;
		vector<int> b = q.top().b;
		q.pop();
		memo[y][x]++;
		if( memo[y][x] > 100 ) continue;
		
		if( res < cnt + g[y][x] ) continue;
		if( x == gx && y == gy ){
			res = min( res , cnt );
			continue;
		}
		for(int i=0 ; i < 4 ; i++ ){
			int mx = x + dx[i];
			int my = y + dy[i];
			if( mx < 0 || my < 0 || w <= mx || h <= my ) continue;
			if( s[my][mx] == '.' ){
				q.push( State(cnt+g[my][mx],cnt+1,mx,my,b) );
			}
			if( s[my][mx] == 'x' ){
				int id = ice[my][mx];
				if( id < b.size() && b[id] > 0 ){
					b[id]--;
					q.push( State(cnt+g[my][mx],cnt+1,mx,my,b) );
					b[id]++;
				}
			}
		}
	}
	return res;
}

int main(){
	while( cin >> w >> h , w || h ){
		s = vector<string>(h);
		for(int y=0 ; y < h ; y++ ){
			cin >> s[y];
		}
		int ans = solve();
		cout << ans << endl;
	}
}

Measured memory_bytes: 3480