#include<bits/stdc++.h>
#define REP(x,y,z) for(int x=y;x<=z;x++)
#define FORD(x,y,z) for(int x=y;x>=z;x--)
#define MSET(x,y) memset(x,y,sizeof(x))
#define FOR(x,y) for(__typeof(y.begin()) x=y.begin();x!=y.end();x++)
#define F first
#define S second
#define MP make_pair
#define PB push_back
#define SZ size()
#define M 35
void RI(){}
template<typename... T>
void RI( int& head, T&... tail ) {
    scanf("%d",&head);
    RI(tail...);
}
using namespace std;
typedef long long LL;
struct P{ int x,y,d; };
bool operator < (P a,P b) { return a.d > b.d; }
P mt(int x,int y,int d)
{
	P re;
	re.x = x;
	re.y = y;
	re.d = d;
	return re;
}
//
int n,m;
int dx[4]={0,0,1,-1}, dy[4]={1,-1,0,0};
int dis[M][M];
char mp[M][M];
bool ins(int x,int y)
{
	return x>=1 && x<=n && y>=1 && y<=m && mp[x][y]!='#';
}
int main()
{
	int x,y,d;
	int nx,ny,nd;
	priority_queue<P> q;
	MSET(dis, -1);

	RI(n,m);
	REP(i,1,n) scanf("%s", mp[i]+1);
	REP(i,1,n)REP(j,1,m) if(mp[i][j]=='S')
	{
		q.push( mt(i,j,0) );
		break;
	}

	while(!q.empty())
	{
		x = q.top().x;
		y = q.top().y;
		d = q.top().d;
		q.pop();
		if(dis[x][y] != -1) continue;
		dis[x][y] = d;
		///////
		
		REP(i,0,3)
		{
			nx = x + dx[i];
			ny = y + dy[i];
			if( !ins(nx, ny) ) continue;
			if( dis[nx][ny] != -1 ) continue;
			if( mp[nx][ny]=='x' ) continue;

			nd = mp[nx][ny]=='o' ? 1:2;
			q.push( mt(nx, ny, d+nd) );
		}

		REP(i,0,3)
		{
			nx = x;
			ny = y;
			REP(j,1,3)
			{
				nx = nx+dx[i];
				ny = ny+dy[i];
				if( !ins(nx, ny) ) break;
				if( dis[nx][ny] != -1 ) continue;
				
				nd = 2+j;
				q.push( mt(nx, ny, d+nd) );
			}
		}
	}

	int ans=0;
	REP(i,1,n) REP(j,1,m) if(mp[i][j]=='G') ans = dis[i][j];
	printf("%d\n", ans);
	
	return 0;
}