#include <bits/stdc++.h>
#pragma GCC optimize(3, "Ofast", "inline")
const int MAXN = 7200;
const int INF = 0x3f3f3f3f;
bool vis[MAXN];
char s[55][55];
struct Edge {
  int x, y, z, nxt;
} e[MAXN << 1];
int dx[5] = {0, 0, 1, -1};
int dy[5] = {1, -1, 0, 0};
int n, m, cnt, tot, ans = INF, head[MAXN], dis[MAXN], NUM[55][55];
inline void add_edge(int x, int y, int z) {
  e[++cnt].x = x, e[cnt].y = y, e[cnt].z = z;
  e[cnt].nxt = head[x], head[x] = cnt;
}
inline void spfa(int nowx) {
  for (register int i = 1; i <= tot; i++) dis[i] = INF, vis[i] = false;
  std::queue<int> q;
  dis[nowx] = 1, vis[nowx] = true, q.push(nowx);
  while (!q.empty()) {
    int x = q.front();
    q.pop();
    for (register int i = head[x]; i; i = e[i].nxt) {
      int to = e[i].y;
      if (dis[to] > dis[x] + e[i].z) {
        dis[to] = dis[x] + e[i].z;
        if (!vis[to]) q.push(to), vis[to] = true;
      }
    }
    vis[x] = false;
  }
  int res = 0;
  for (register int i = 1; i <= n; i++)
    for (register int j = 1; j <= m; j++)
      if (s[i][j] == 'B') res = std::max(res, dis[NUM[i][j]]);
  ans = std::min(ans, res);
}
signed main() {
  scanf("%d %d", &n, &m);
  for (register int i = 1; i <= n; i++) scanf("%s", s[i] + 1);
  for (register int i = 1; i <= n; i++)
    for (register int j = 1; j <= m; j++) NUM[i][j] = ++tot;
  for (register int i = 1; i <= n; i++) {
    for (register int j = 1; j <= m; j++) {
      for (register int k = 0; k < 4; k++) {
        int nowx = i + dx[k], nowy = j + dy[k];
        nowx = i + dx[k], nowy = j + dy[k];
        if (nowx < 1 or nowx > n or nowy < 1 or nowy > m) continue;
        if (s[i][j] == s[nowx][nowy]) add_edge(NUM[i][j], NUM[nowx][nowy], 0);
        if (s[i][j] != s[nowx][nowy]) add_edge(NUM[i][j], NUM[nowx][nowy], 1);
      }
    }
  }
  for (register int i = 1; i <= tot; i++) spfa(i);
  printf("%d\n", ans);
  return 0;
}
