#include <bits/stdc++.h>
using namespace std;
#define el '\n'
#define all(x) begin(x), end(x)
#define sz(s) (int)(s.size())
const int N = 4000 + 36;
int h, w;
char a[N][N];
int root[N][N];
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};
void Solve() {
cin >> h >> w;
for(int i = 1; i <= h; i++) {
for(int j = 1; j <= w; j++) {
cin >> a[i][j];
}
}
int comp = 1;
for(int i = 1; i <= h; i++) {
for(int j = 1; j <= w; j++) {
if(root[i][j] || a[i][j] == '.') continue;
queue<pair<int, int>> q;
q.push({i, j});
root[i][j] = comp;
while(!q.empty()) {
auto [x, y] = q.front();
q.pop();
for(int k = 0; k < 4; k++) {
int nx = x + dx[k];
int ny = y + dy[k];
if(nx < 1 || nx > h || ny < 1 || ny > w) continue;
if(root[nx][ny]) continue;
if(a[nx][ny] != a[x][y]) continue;
root[nx][ny] = comp;
q.push({nx, ny});
}
}
comp++;
}
}
vector<vector<int>> adj(comp);
for(int i = 1; i <= h; i++) {
for(int j = 1; j <= w; j++) {
if(root[i][j] == 0) continue;
int u = root[i][j];
for(int k = 0; k < 4; k++) {
int ni = i + dx[k];
int nj = j + dy[k];
if(ni < 1 || ni > h || nj < 1 || nj > w) continue;
if(root[ni][nj] == 0) continue;
int v = root[ni][nj];
if(u != v) {
adj[u].push_back(v);
}
}
}
}
for(int i = 1; i < comp; i++) {
sort(all(adj[i]));
adj[i].erase(unique(all(adj[i])), adj[i].end());
}
vector<int> dist(comp, 0);
queue<int> q;
int start = root[1][1];
dist[start] = 1;
q.push(start);
while(!q.empty()) {
int u = q.front();
q.pop();
for(int v : adj[u]) {
if(dist[v]) continue;
dist[v] = dist[u] + 1;
q.push(v);
}
}
int ans = 0;
for(int i = 1; i < comp; i++) {
ans = max(ans, dist[i]);
}
cout << ans << el;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
Solve();
return 0;
}