#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <queue>
#include <math.h>
using namespace std;
#define INF 0x3f3f3f3f
#define fi first
#define se second
struct node
{
int x , y;
}hourse[20000],man[20000];
struct e
{
int to;
int c;
int w;
int next;
}edge[200*200*200];
int head[500] , h[500], cnt, dis[1000], pre[1000], pc[1000], n ,m ,hourseCnt , manCnt, st, ed;
//h为势函数数组,pc为到达当前的流,pre记录路径,dis记录距离
int ansflow , anscost;
void add(int f, int t, int c, int w)
{
edge[cnt].to = t;
edge[cnt].c = c;
edge[cnt].next = head[f];
edge[cnt].w = w;
head[f] = cnt ++;
}
void dij()
{
priority_queue <pair<int,int> > q;
while(true) //从汇点出发,不断寻找花费最短路作为增广路
{
memset(dis,INF,sizeof(dis));
dis[st] = 0;
pre[st] = -1;
pc[st] = INF; //用于记录该增广路所能承受的最大流
q.push(make_pair(0,st));
while(!q.empty()) //采用堆优化的dij寻找
{
pair<int,int> p = q.top();
q.pop();
int u = p.se;
if(-p.fi > dis[u]) continue;
for(int i = head[u] ; i != -1 ; i = edge[i].next)
{
int v = edge[i].to , c = edge[i].c, w = edge[i].w;
int ww = w + h[u] - h[v]; //引入势函数作为新权,保证正数,从而让成功,类似于Johnson算法
if(c > 0 && dis[u] + ww < dis[v])
{
dis[v] = dis[u] + ww; //修改距离
q.push(make_pair(-dis[v],v));
pre[v] = i; //记录路径
pc[v] = min(pc[u],c); //修改最大流
}
}
}
if(dis[ed] == INF) //如果为INF说明不存在增广路,跳出即可
break;
for(int i = st ; i <= ed ; i ++) h[i] += dis[i]; //更新势函数
int nowflow = pc[ed];
ansflow += nowflow;
anscost += h[ed]*nowflow;
for(int i = ed ; pre[i] != -1 ; i = edge[pre[i]^1].to) //递归回溯路径,改变流大小
{
edge[pre[i]].c -= nowflow;
edge[pre[i]^1].c += nowflow;
}
}
}
int main(void)
{
while(scanf("%d %d",&n , &m) != EOF)
{
memset(pre,0,sizeof(pre));
memset(pc,0,sizeof(pre));
memset(h,0,sizeof(h));
if(n == 0 && m == 0)
return 0;
memset(head,-1,sizeof(head));
cnt = hourseCnt = manCnt = ansflow = anscost = 0;
char ch[105];
for(int i = 0 ; i < n ; i ++) {
scanf("%s",ch);
for(int j = 0 ; j < m ; j ++){
if(ch[j] == 'm')
man[manCnt].x = i+1 , man[manCnt].y = j+1 , manCnt ++;
if(ch[j] == 'H')
hourse[hourseCnt].x = i+1 , hourse[hourseCnt].y = j+1 , hourseCnt ++;
}
}
st = 0 , ed = 1+2*manCnt;
for(int i = 1 ; i <= manCnt ; i ++)
{
add(st,i,1,0);
add(i,st,0,0);
}
for(int i = 0 ; i < manCnt ; i ++)
{
for(int j = 0 ; j < hourseCnt ; j ++)
{
int w = abs(man[i].x-hourse[j].x) + abs(man[i].y - hourse[j].y);
add(1+i,1+manCnt+j,1,w);
add(1+manCnt+j,1+i,0,-w);
}
}
for(int i = 0 ; i < hourseCnt ; i ++)
{
add(1+manCnt+i,ed,1,0);
add(ed,1+manCnt+i,0,0);
}
dij();
printf("%d\n",anscost);
}
}