#include <cstdio>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

int dy[] = {1, -1, 0, 0};
int dx[] = {0, 0, 1, -1};

vector<string> s;
int n;                    // 氷の塊の数
vector<vector<int> > ice; // 各氷の番号
vector<int> iceNum;       // 各塊の氷の数
int gy, gx;
int ret;

void solve(int y, int x, int step, vector<vector<bool> >& used, vector<int>& usedIce)
{
    if(y == gy && x == gx){
        ret = step;
        return;
    }

    // 明らかに解を更新できなければ終了
    if(step + abs(y - gy) + abs(x - gx) >= ret)
        return;

    // ループが発生した場合、より良い解があることが分かるため終了
    int tmp = 0;
    for(int i=0; i<4; ++i){
        int y2 = y + dy[i];
        int x2 = x + dx[i];
        if(used[y2][x2])
            ++ tmp;
    }
    if(tmp > 1)
        return;

    // 氷が割れるかを調べる
    if(ice[y][x] != -1){
        if(usedIce[ice[y][x]] + 1 > iceNum[ice[y][x]] / 2)
            return;
        ++ usedIce[ice[y][x]];
    }
    used[y][x] = true;

    for(int i=0; i<4; ++i){
        int y2 = y + dy[i];
        int x2 = x + dx[i];
        if(used[y2][x2] || s[y2][x2] == '#')
            continue;
        solve(y2, x2, step+1, used, usedIce);
    }

    if(ice[y][x] != -1)
        -- usedIce[ice[y][x]];
    used[y][x]= false;
}

int main()
{
    for(;;){
        int h, w;
        cin >> w >> h;
        if(h == 0)
            return 0;

        s.assign(h+2, string(w+2, '#'));
        int sy, sx;
        for(int i=1; i<=h; ++i){
            for(int j=1; j<=w; ++j){
                cin >> s[i][j];
                if(s[i][j] == 'S'){
                    sy = i;
                    sx = j;
                }else if(s[i][j] == 'G'){
                    gy = i;
                    gx = j;
                }
            }
        }

        n = 0;
        ice.assign(h+2, vector<int>(w+2, -1));
        iceNum.clear();
        for(int i=1; i<=h; ++i){
            for(int j=1; j<=w; ++j){
                if(s[i][j] != 'X' || ice[i][j] != -1)
                    continue;

                queue<pair<int, int> > q;
                q.push(make_pair(i, j));
                ice[i][j] = n;
                iceNum.push_back(1);
                while(!q.empty()){
                    int y0 = q.front().first;
                    int x0 = q.front().second;
                    q.pop();

                    for(int k=0; k<4; ++k){
                        int y = y0 + dy[k];
                        int x = x0 + dx[k];
                        if(s[y][x] == 'X' && ice[y][x] == -1){
                            q.push(make_pair(y, x));
                            ice[y][x] = n;
                            ++ iceNum[n];
                        }
                    }
                }
                ++ n;
            }
        }

        ret = INT_MAX;
        vector<vector<bool> > used(h+2, vector<bool>(w+2, false));
        used[sy][sx] = true;
        vector<int> usedIce(n, 0);
        solve(sy, sx, 0, used, usedIce);

        cout << ret << endl;
    }
}

Measured memory_bytes: 932