// tsukasa_diary's programing contest code template
#include <bits/stdc++.h>
using namespace std;
// define
#define for_(i,a,b) for(int i=a;i<b;++i)
#define for_rev(i,a,b) for(int i=a;i>=b;--i)
#define allof(a) a.begin(),a.end()
#define minit(a,b) memset(a,b,sizeof(a))
#define size_of(a) (int)a.size()
// typedef
typedef long long lint;
typedef double Double;
typedef pair<int, int> pii;
//
typedef vector< int > Array;
typedef vector< Array > Matrix;
typedef vector< Double > DArray;
typedef vector< DArray > DMatrix;
typedef vector< string > SArray;
typedef vector< pii > PArray;
// popcount
inline int POPCNT(int _x) { return __builtin_popcount(_x); }
inline int POPCNT(lint _x) { return __builtin_popcountll(_x); }
// inf
const int iINF = 1L << 30;
const lint lINF = 1LL << 60;
// eps
Double EPS = 1e-9;
// in range
inline bool in_range(int _v, int _mx, int _mi) { return _mi <= _v && _v < _mx; }
inline bool in_range(Double _v, Double _mi, Double _mx) { return -EPS < _v - _mi && _v - _mx < EPS; }
inline bool in_range(int _x, int _y, int _W, int _H) { return 0 <= _x && _x < _W && 0 <= _y && _y < _H; }
// neighbor clockwise
const int DX[4] = {0,1,0,-1}, DY[4] = {-1,0,1,0};
const int DX_[8] = {0,1,1,1,0,-1,-1,-1}, DY_[8] = {-1,-1,0,1,1,1,0,-1};

struct State {
	int x, y, c;
	State(int _x, int _y, int _c) : x(_x), y(_y), c(_c) {}
};

bool operator > (const State& a, const State& b) { return a.c > b.c; }

int W, H;
string grid[110];

int sx, sy, gx, gy;
PArray mvec;
int c_grid[110][110];

int cost[110][110];

int cost_bet(int stx, int sty, int glx, int gly) {
	for_(i,0,110) fill(cost[i], cost[i] + 110, iINF);
	priority_queue< State, vector< State >, greater< State> > q;
	q.push(State(stx, sty, 0));
	cost[sty][stx] = 0;
	
	while (!q.empty()) {
		State s = q.top(); q.pop();
		
		if (cost[s.y][s.x] < s.c) continue;
		
		if (s.x == glx && s.y == gly) return s.c;
		
		for_(d,0,4) {
			int nx = s.x + DX[d], ny = s.y + DY[d];
			if (!in_range(nx, ny, W, H)) continue;
			if (grid[ny][nx] == '#') continue;
			
			int adc = c_grid[s.y][s.x];
			if (cost[ny][nx] > s.c + adc) {
				cost[ny][nx] = s.c + adc;
				q.push(State(nx, ny, s.c + adc));
			}
		}
	}
	
	return cost[gly][glx];
}

void calc_cost(int hx, int hy) {
	for_(y,0,H) for_(x,0,W) {
		int v = 4 - max( abs(hx - x), abs(hy - y) );
		v = max(v, 1);
		c_grid[y][x] = max(c_grid[y][x], v);
	}
}

int poyo[10][10];

void solve() {
	for_(y,0,H) for_(x,0,W) c_grid[y][x] = 1;
	
	mvec.clear();
	for_(y,0,H) for_(x,0,W) {
		if (grid[y][x] == '#') calc_cost(x, y);
		if (grid[y][x] == 'M') mvec.push_back(pii(x, y));
		if (grid[y][x] == 'S') sx = x, sy = y;
		if (grid[y][x] == 'G') gx = x, gy = y;
	}
	
	int SS = 5, GG = 6;
	
	int m_size = size_of(mvec);
	for_(i,0,m_size) {
		pii p = mvec[i];
		
		poyo[SS][i] = cost_bet(sx, sy, p.first, p.second);
		poyo[i][GG] = cost_bet(p.first, p.second, gx, gy);
		
		for_(j,0,m_size) {
			pii pp = mvec[j];
			poyo[i][j] = cost_bet(p.first, p.second, pp.first, pp.second);
		}
	}
	
	vector< int > perm(m_size, 0);
	for_(i,0,m_size) perm[i] = i;
	
	int ans = iINF;
	
	do {
		int pans = poyo[SS][ perm[0] ] + poyo[ perm[m_size - 1] ][GG];
		for_(i,0,m_size - 1) pans += poyo[ perm[i] ][ perm[i + 1] ];
		ans = min(ans, pans);
	} while (next_permutation(allof(perm)));
	
	cout << ans << endl;
}

int main() {
	cin >> W >> H;
	
	for_(i,0,H) cin >> grid[i];
	
	solve();
	return 0;
}

Measured memory_bytes: 1328