#include <bits/stdc++.h>
using namespace std;
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("Ofast,unroll-loops,fast-math,O3")
#define pb push_back
#define ll long long
#define s second
#define f first
//#define sz(v) int(v.size())
#define all(v) v.begin(),v.end()
const int N = 4000 + 10,mod = 1e9 + 7,inf = 1e9;
mt19937 rd(chrono::duration_cast<chrono::nanoseconds>
(chrono::steady_clock::now().time_since_epoch()).count());
int d2[4] = {0,0,1,-1},d1[4] = {1,-1,0,0};
int d[N][N];
char a[N][N];
int n,m;
bool ch(int x,int y){
if(x < 1 || y < 1 || x > n || y > m || a[x][y] == '.') return false;
return true;
}
void solve(){
cin >> n >> m;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
cin >> a[i][j];
d[i][j] = inf;
}
}
deque <pair<int,int>> q;
q.push_front({1,1});
d[1][1] = 1;
int ans = 0;
while(!q.empty()){
auto [x,y] = q.front();
q.pop_front();
ans = max(ans,d[x][y]);
for(int i = 0; i < 4; i++){
int x1 = d2[i] + x,y1 = d1[i] + y;
if(ch(x1,y1) && d[x1][y1] == inf){
d[x1][y1] = d[x][y] + (a[x1][y1] != a[x][y]);
if(a[x1][y1] == a[x][y]){
q.push_front({x1,y1});
}
else q.push_back({x1,y1});
}
}
}
cout << ans;
}
signed main(){
//freopen("sleepy.in", "r", stdin);
//freopen("sleepy.out", "w", stdout);
ios_base::sync_with_stdio(0);
cout.tie(0);cin.tie(0);
int t = 1;
while(t--){
solve();
}
}