#include <bits/stdc++.h>

using namespace std;

#define LOG(...) fprintf(stderr,__VA_ARGS__)
//#define LOG(...)
#define FOR(i,a,b) for(int i=(int)(a);i<(int)(b);++i)
#define REP(i,n) for(int i=0;i<(int)(n);++i)
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define SORT(c) sort(ALL(c))
#define RSORT(c) sort(RALL(c))

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

#define INF 1e9

int W, H;
int start_x, start_y, goal_x, goal_y;
int *ices[12][12];
char maze[12][12];
bool G[12][12];
int depth;
int next_depth;

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

void dfs_count(int *ice, int x, int y) {
    (*ice)++;
    ices[y][x] = ice;
    maze[y][x] = '?'; // used

    REP(i, 4) {
        int sx = x + dx[i], sy = y + dy[i];
        if (0 <= sx && sx < W && 0 <= sy && sy < H) {
            if (maze[sy][sx] == 'X') {
                dfs_count(ice, sx, sy);
            }
        }
    }
}

bool iddfs(int x, int y, int step) {
    if (x == goal_x && y == goal_y) return true;
    int dist = abs(x - goal_x) + abs(y - goal_y);
    if (step + dist > depth) {
        next_depth = min(next_depth, step + dist);
        return false;
    }
    REP(i, 4) {
        int sx = x + dx[i], sy = y + dy[i];
        if (0 <= sx && sx < W && 0 <= sy && sy < H) {
            if (*ices[sy][sx] > 0 && !G[sy][sx]) {
                (*ices[sy][sx])--;
                G[sy][sx] = true;
                if (iddfs(sx, sy, step+1)) return true;
                G[sy][sx] = false;
                (*ices[sy][sx])++;
            }
        }
    }
    return false;
}

int main() {
    while (cin >> W >> H, W|H) {
        REP(y, H) REP(x, W) cin >> maze[y][x];

        int empty = 100000;
        int wall = 0;

        int ice[12][12] = {};

        REP(y, H) REP(x, W) {
            switch (maze[y][x]) {
            case '.':
                ices[y][x] = &empty;
                break;
            case '#':
                ices[y][x] = &wall;
                break;
            case 'S':
                start_x = x;
                start_y = y;
                ices[y][x] = &empty;
                break;
            case 'G':
                goal_x = x;
                goal_y = y;
                ices[y][x] = &empty;
                break;
            case 'X': {
                dfs_count(&ice[y][x], x, y);
                ice[y][x] /= 2;
                ices[y][x] = &ice[y][x];
                break;
            }
            }
            maze[y][x] = '?'; // used
        }

        fill_n((bool *)G, 12*12, false);
        depth = abs(start_x - goal_x) + abs(start_y - goal_y);
        while (!iddfs(start_x, start_y, 0)) {
            depth = next_depth;
            next_depth = INF;
        }
        cout << depth << endl;
    }
}