#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
vector<char> check;
vector<int> fin;
char arr[20][20];
int r, c;
bool flag = false;
bool visit[20][20];
void dfs(int i, int j, int cnt) {
visit[i][j] = true;
flag = false;
if (i > 0 && !visit[i-1][j]) {
for (int k = 0; k < (int)check.size(); k++)
if (check[k] == arr[i - 1][j]) {
flag = true;
break;
}
if (!flag) {
check.push_back(arr[i - 1][j]);
dfs(i - 1, j, cnt+1);
}
flag = false;
}
if (j > 0 && !visit[i][j-1]) {
for (int k = 0; k < (int)check.size(); k++)
if (check[k] == arr[i][j - 1]) {
flag = true;
break;
}
if (!flag) {
check.push_back(arr[i][j - 1]);
dfs(i, j - 1, cnt + 1);
}
flag = false;
}
if (j < c - 1 && !visit[i][j+1]) {
for (int k = 0; k < (int)check.size(); k++)
if (check[k] == arr[i][j + 1]) {
flag = true;
break;
}
if (!flag) {
check.push_back(arr[i][j + 1]);
dfs(i, j + 1, cnt + 1);
}
flag = false;
}
if (i < r - 1 && !visit[i + 1][j]) {
for (int k = 0; k < (int)check.size(); k++)
if (check[k] == arr[i + 1][j]) {
flag = true;
break;
}
if (!flag) {
check.push_back(arr[i + 1][j]);
dfs(i + 1, j, cnt + 1);
}
flag = false;
}
if (cnt != 1)
fin.push_back(cnt);
visit[i][j] = false;
check.pop_back();
}
int main() {
cin >> r >> c;
for (int i = 0; i < r; i++)
for (int j = 0; j < c; j++)
cin >> arr[i][j];
check.push_back(arr[0][0]);
dfs(0, 0, 1);
sort(fin.begin(), fin.end(), greater<int>());
cout << fin[0];
return 0;
}