#include <iostream>
#include <cstring>
#include <cmath>
#include <queue>
using namespace std;
const int MAXN = 105;
const int MAXK = 5005;
const int INF = 0x3f3f3f3f;
struct Edge
{
int y, next;
int v, c;
}edge[MAXK * MAXK];
char mp[MAXN][MAXN]; //地图
int man[MAXK][2], house[MAXK][2]; //人的坐标,房子的坐标
int total; //边的数量
int head[MAXK];
int S, T; //源点,汇点
int dis[MAXK], pre[MAXK];
bool vis[MAXK];
void addEdge(int x, int y, int v, int c)
{
edge[total] = { y,head[x],v,c };
head[x] = total++;
}
bool SPFA()
{
memset(dis, INF, sizeof(dis));
memset(pre, -1, sizeof(pre));
queue<int> q;
q.push(S);
dis[S] = 0;
while (!q.empty())
{
int now = q.front();
q.pop();
vis[now] = 0;
for (int i = head[now]; ~i; i = edge[i].next)
{
int y = edge[i].y;
if (edge[i].v && dis[y] > dis[now] + edge[i].c)
{
dis[y] = dis[now] + edge[i].c;
pre[y] = i;
if (!vis[y])
{
q.push(y);
vis[y] = 1;
}
}
}
}
return dis[T] != INF;
}
int minCost()
{
int ans = 0;
while (SPFA())
{
int mins = INF;
for (int i = pre[T]; ~i; i = pre[edge[i ^ 1].y])
mins = min(mins, edge[i].v);
for (int i = pre[T]; ~i; i = pre[edge[i ^ 1].y])
{
edge[i].v -= mins;
edge[i ^ 1].v += mins;
}
ans += mins * dis[T];
}
return ans;
}
int main()
{
int N, M;
while (cin >> N >> M)
{
if (N == 0 && M == 0)
break;
for (int i = 1; i <= N; i++)
cin >> mp[i] + 1;
int num1 = 0, num2 = 0; //人的数量,房子的数量
for (int i = 1; i <= N; i++)
{
for (int j = 1; j <= M; j++)
{
if (mp[i][j] == 'm')
{
++num1;
man[num1][0] = i;
man[num1][1] = j;
}
else if (mp[i][j] == 'H')
{
++num2;
house[num2][0] = i;
house[num2][1] = j;
}
}
}
memset(head, -1, sizeof(head));
total = 0;
S = 0, T = 2 * num1 + 1;
for (int i = 1; i <= num1; i++)
{
addEdge(S, i, 1, 0);
addEdge(i, S, 0, 0);
addEdge(i + num1, T, 1, 0);
addEdge(T, i + num1, 0, 0);
for (int j = 1; j <= num1; j++)
{
addEdge(i, j + num1, 1, abs(man[i][0] - house[j][0]) + abs(man[i][1] - house[j][1]));
addEdge(j + num1, i, 0, -abs(man[i][0] - house[j][0]) - abs(man[i][1] - house[j][1]));
}
}
cout << minCost() << endl;
}
return 0;
}