#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <cassert>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <algorithm>
#include <numeric>
#include <complex>
#include <stack>
#include <queue>
#include <list>
#include <set>
#include <map>
#include <bitset>
#include <functional>
#include <iterator>

using namespace std;

#define dump(n) cout<<"# "<<#n<<'='<<(n)<<endl
#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define peri(i,a,b) for(int i=int(b);i-->int(a);)
#define rep(i,n) repi(i,0,n)
#define per(i,n) peri(i,0,n)
#define iter(c) __typeof__((c).begin())
#define foreach(i,c) for(iter(c) i=(c).begin();i!=(c).end();++i)
#define all(c) (c).begin(),(c).end()
#define mp make_pair

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;
typedef pair<int,int> pii;

const int INFTY=1<<29;
const double EPS=1e-9;

template<typename T1,typename T2>
ostream& operator<<(ostream& os,const pair<T1,T2>& p){
	return os<<'('<<p.first<<','<<p.second<<')';
}
template<typename T>
ostream& operator<<(ostream& os,const vector<T>& a){
	os<<'[';
	rep(i,a.size()) os<<(i?" ":"")<<a[i];
	return os<<']';
}

struct UnionFind{
	vi data;
	UnionFind(int size):data(size,-1){}
	int Find(int n){
		return data[n]<0?n:(data[n]=Find(data[n]));
	}
	void Unite(int a,int b){
		int ra=Find(a),rb=Find(b);
		if(ra!=rb){
			if(-data[ra]<-data[rb])
				swap(ra,rb);
			data[ra]+=data[rb];
			data[rb]=ra;
		}
	}
	int Size(int n){
		return -data[Find(n)];
	}
};

int h,w;
char grid[12][13];
int ice[12][12],vis[12][12],lim[12*12];
int gi,gj;
int res;

inline void dfs(int i,int j,int step)
{
	if(grid[i][j]=='X' && lim[ice[i][j]]==0) return;
	if(grid[i][j]=='G') res=min(res,step);
	if(step+abs(gi-i)+abs(gj-j)>=res) return;
	
	vis[i][j]=true;
	if(grid[i][j]=='X') lim[ice[i][j]]--;
	rep(k,4){
		int ni=i+"\xff\x1\0\0"[k],nj=j+"\0\0\xff\x1"[k];
		if(ni<0 || h<=ni || nj<0 || w<=nj || grid[ni][nj]=='#' || vis[ni][nj]) continue;
		dfs(ni,nj,step+1);
	}
	if(grid[i][j]=='X') lim[ice[i][j]]++;
	vis[i][j]=false;
}

int main()
{
	for(;cin>>w>>h,w|h;){
		rep(i,h) cin>>grid[i];
		
		UnionFind uf(h*w);
		rep(i,h) rep(j,w){
			if(grid[i][j]=='X'){
				if(i+1<h && grid[i+1][j]=='X')
					uf.Unite(i*w+j,(i+1)*w+j);
				if(j+1<w && grid[i][j+1]=='X')
					uf.Unite(i*w+j,i*w+(j+1));
			}
		}
		map<int,int> f;
		memset(ice,-1,sizeof(ice));
		rep(i,h) rep(j,w) if(grid[i][j]=='X'){
			if(!f.count(uf.Find(i*w+j)))
				f.insert(mp(uf.Find(i*w+j),f.size()));
			ice[i][j]=f[uf.Find(i*w+j)];
		}
		vi cnt(f.size());
		rep(i,h) rep(j,w) if(grid[i][j]=='X')
			cnt[ice[i][j]]++;
		rep(i,cnt.size()) lim[i]=cnt[i]/2;
		
		res=INFTY;
		rep(i,h) rep(j,w) if(grid[i][j]=='G')
			gi=i,gj=j;
		rep(i,h) rep(j,w) if(grid[i][j]=='S')
			dfs(i,j,0);
		cout<<res<<endl;
	}
	
	return 0;
}