#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>

using namespace std;

const int INF = (1<<25);
const int MAX = 100;

struct State{
  int t,come,x,y;
  State(){}
  State(int t, int come, int x, int y):t(t),come(come),x(x),y(y){}
  bool operator < (const State& s) const { return t > s.t;}
};
typedef pair<int,int> P;

int F[5][5] = {{2,2,2,2,2},
	       {2,3,3,3,2},
	       {2,3,INF,3,2},
	       {2,3,3,3,2},
	       {2,2,2,2,2}};

int T[(1<<5)][MAX][MAX];
char M[MAX][MAX];
int E[MAX][MAX];
int w,h;
int sx,sy,gx,gy;
vector<P> V;

bool isInside(int x, int y){return 0<=x&&x<w&&0<=y&&y<h;}

void hole(int y, int x){
  
  for(int i = y-2; i <= y+2; i++)
    for(int j = x-2; j <= x+2; j++)
      if(isInside(j,i)) E[i][j] = max(E[i][j],F[i-y+2][j-x+2]);
}

void init(){
  fill(T[0][0],T[0][0]+(1<<5)*MAX*MAX,INF);
  for(int i = 0; i < MAX; i++) for(int j = 0; j < MAX; j++) E[i][j] = 1;
}

void input(){
  cin >> w >> h;

  for(int i = 0; i < h; i++)
    for(int j = 0; j < w; j++){
      cin >> M[i][j];
      if(M[i][j] == 'S') sx=j,sy=i;
      if(M[i][j] == 'G') gx=j,gy=i;
      if(M[i][j] == 'M') V.push_back(P(i,j));
      if(M[i][j] == '#') hole(i,j);
    }
}

int getNum(int x, int y){
  for(int i = 0; i < (int)V.size(); i++)
    if(V[i].first == y && V[i].second == x) return i;
  return -1;
}

void solve(){
  
  int dx[] = {1,-1,0,0};
  int dy[] = {0,0,1,-1};
  priority_queue<State> Q;
  Q.push(State(0,0,sx,sy));
  T[0][sy][sx] = 0;
  
  while(!Q.empty()){
    State now = Q.top();
    Q.pop();
    
    for(int i = 0; i < 4; i++){
      State nex = now;
      nex.x += dx[i];
      nex.y += dy[i];
      nex.t += E[now.y][now.x];
      if(!isInside(nex.x,nex.y)) continue;
      
      if(M[nex.y][nex.x] == 'M'){
	int num = getNum(nex.x,nex.y);
	nex.come |= (1<<num);
      }

      if(T[nex.come][nex.y][nex.x] > nex.t){
	T[nex.come][nex.y][nex.x] = nex.t;
	Q.push(nex);
      }
    }
  }
  cout << T[(1<<V.size())-1][gy][gx] << endl;
}


int main(){
  init();
  input();
  solve();
  return 0;
}