#include <iostream>
#include <cstdio>
#include <cstring>
#include <cassert>
using namespace std ;
const int N = 100 + 11 ;
struct Graph {
int w[N][N] ;
int lx[N] , ly[N] ;
int my[N] , slack[N] ;
bool vx[N] , vy[N] ;
int n , m ;
int cntx , cnty ;
void addinfo() {//构建二分图
char err[N][N] ;
int num[N][2] ;
memset(lx , 1<<7 , sizeof(lx)) ;//设为一个极小值
cntx = 0 , cnty = 0 ;
for(int i = 1 ; i <= n ; ++i) {
for(int j = 1; j <= m ; ++j) {
scanf(" %c" ,&err[i][j]) ;
if(err[i][j] == 'H') {
++cnty ;
num[cnty][0] = i ;
num[cnty][1] = j ;
}
}
}
int t1 , t2 ;
for(int i = 1 ; i <= n ;++i) {
for(int j = 1 ; j <= m ; ++j) {
if(err[i][j] == 'm') {
++cntx ;
for(int k = 1 ; k <= cnty ; ++k) {
if(num[k][0] < i) t1 = num[k][0] - i ;
else t1 = i - num[k][0] ;
if(num[k][1] < j) t2 = num[k][1] - j ;
else t2 = j - num[k][1] ;
w[cntx][k] = t1 + t2 ;
if(w[cntx][k] > lx[cntx]) lx[cntx] = w[cntx][k] ;
}
}
}
}
}
bool match(int u) {
vx[u] = true ;
for(int i = 1; i <= cnty ; ++i) {
if(vy[i]) continue ;
int tmp = lx[u] + ly[i] - w[u][i] ;
if(tmp == 0) {
vy[i] = true ;
if(my[i] == -1 || match(my[i])) {
my[i] = u ;
return true ;
}
}else {
if(slack[i] > tmp) slack[i] = tmp ;
}
}
return false ;
}
void std_fun() {
addinfo() ;
memset(ly , 0 ,sizeof(ly)) ;
memset(my , -1 , sizeof(my)) ;
for(int i = 1 ; i <= cntx ; ++i) {
memset(slack , (1<<7)-1 , sizeof(slack)) ;
while(true) {
memset(vy , 0 , sizeof(vy)) ;
memset(vx , 0 , sizeof(vx)) ;
if(match(i)) break ;
int d = 1<<30 ;
for(int i = 1; i <= cnty ; ++ i) {
if(!vy[i] && d > slack[i]) {
d = slack[i] ;
}
}
for(int i = 1; i <= cntx ;++i) {
if(vx[i]) lx[i] -= d ;
}
for(int i = 1; i <= cnty ;++i) {
if(vy[i]) ly[i] += d;
}
}
}
int sum = 0 ;
for(int i = 1; i <= cnty ; ++i) {
if(my[i] != -1) sum += w[my[i]][i] ;
}
printf("%d\n" ,-sum) ;
}
}g ;
int main() {//freopen("/home/zqdnr/data.in" , "r" , stdin) ;
while(scanf("%d%d" ,&g.n ,&g.m)==2 && g.n + g.m) {
g.std_fun() ;
}
}