#include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
struct aa {
	int x;
	int y;
	bitset<5>gets;
	int cost;
};
class Compare {
public:
	bool operator()(const aa&l, const aa&r) {
		return l.cost>r.cost;
	}
};

int main() {
	int H,W;cin>>W>>H;
	vector<vector<int>>field(H,vector<int>(W,1));
	vector<pair<int,int>>makis;
	int sx, sy, gx, gy;
	{
		vector<pair<int, int>>holes;
		for (int i = 0; i < H; ++i) {
			string st; cin >> st;
			for (int j = 0; j < W; ++j) {
				char ch(st[j]);
				if (ch == 'S') {
					sx = j;
					sy = i;
				}
				else if (ch == 'G') {
					gx = j;
					gy = i;
				}
				else if (ch == '#') {
					holes.push_back(make_pair(j, i));
				}
				else if (ch == 'M') {
					makis.push_back(make_pair(j,i));
				}
			}
		}
		for (auto hole : holes) {
			for (int y = 0; y < H; ++y) {
				for (int x = 0; x < W; ++x) {
					int x_dis = abs(x - hole.first);
					int y_dis = abs(y - hole.second);
					int dis = max(x_dis, y_dis);
					if (dis == 0) {
						field[y][x] = max(field[y][x],10000);
					}
					else if (dis <= 3) {
						field[y][x] =max(field[y][x],4-dis);
					}
				}
			}
		}
	}

	priority_queue<aa,vector<aa>,Compare>que;

	que.push(aa{ sx,sy,bitset<5>(),0 });
	vector<vector<vector<int>>>memo(W,vector<vector<int>>(H,vector<int>(32,1e9)));
	memo[sx][sy][0]=0;
	int dx[4] = { -1,0,1,0 };
	int dy[4] = { 0,1,0,-1 };
	int ans=-1;
	while (!que.empty()) {
		auto atop(que.top());
		const int now_x=atop.x;
		const int now_y=atop.y;
		const bitset<5>gets(atop.gets);
		const int now_cost=atop.cost;

		if (now_x == gx&&now_y == gy&&gets.count() == makis.size()) {
			ans=now_cost;
			break;
		}
		que.pop();
		for (int way = 0; way < 4; ++way) {
			const int next_x=now_x+dx[way];
			const int next_y=now_y+dy[way];

			if (0 <= next_x&&next_x < W&&next_y < H && 0 <= next_y) {
				const int next_cost=now_cost+field[now_y][now_x];
				auto next_gets(gets);
				for (int i = 0; i < makis.size(); ++i) {
					if (next_x == makis[i].first&&next_y == makis[i].second) {
						next_gets[i]=true;
					}
				}
				if (memo[next_x][next_y][next_gets.to_ulong()] > next_cost) {
					memo[next_x][next_y][next_gets.to_ulong()]=next_cost;
					que.push(aa{ next_x,next_y,next_gets,next_cost });
				}
			}
		}
	}
	cout<<ans<<endl;
	

	return 0;
}