#include <bits/stdc++.h>
using namespace std;
int dp[55][55][55][55], reach[55][55][55][55];
char maz[55][55];
int n, m;
void dfs(int x, int y, int nx, int ny) {
  cout << x << " " << y << " " << nx << " " << ny << endl;
  if (nx > n || ny > m) return;
  reach[x][y][nx][ny] = 1;
  if (maz[nx + 1][ny] != '#' && !reach[x][y][nx][ny]) dfs(x, y, nx + 1, ny);
  if (maz[nx][ny + 1] != '#' && !reach[x][y][nx][ny]) dfs(x, y, nx, ny + 1);
}
const int inf = 1000000;
bool check(int x, int y) { return maz[x][y] != '#'; }
int DP(int x1, int y1, int x2, int y2) {
  if (x1 > x2 || y1 > y2) {
    return -inf;
  }
  if (!reach[x1][y1][x2][y2]) {
    return -inf;
  }
  if (x1 == x2 && y1 == y2) return 0;
  if ((maz[x1][y1] - 'a' + 'A') == maz[x2][y2]) {
    dp[x1][y1][x2][y2] = max(dp[x1][y1][x2][y2], DP(x1 + 1, y1, x2 - 1, y2));
    dp[x1][y1][x2][y2] = max(dp[x1][y1][x2][y2], DP(x1 + 1, y1, x2, y2 - 1));
    dp[x1][y1][x2][y2] = max(dp[x1][y1][x2][y2], DP(x1, y1 + 1, x2 - 1, y2));
    dp[x1][y1][x2][y2] = max(dp[x1][y1][x2][y2], DP(x1, y1 + 1, x2, y2 - 1));
    return dp[x1][y1][x2][y2] = dp[x1][y1][x2][y2] + 1;
  } else {
    dp[x1][y1][x2][y2] = max(dp[x1][y1][x2][y2], DP(x1, y1, x2 - 1, y2));
    dp[x1][y1][x2][y2] = max(dp[x1][y1][x2][y2], DP(x1, y1, x2, y2 - 1));
    dp[x1][y1][x2][y2] = max(dp[x1][y1][x2][y2], DP(x1 + 1, y1, x2, y2));
    dp[x1][y1][x2][y2] = max(dp[x1][y1][x2][y2], DP(x1, y1 + 1, x2, y2));
    return dp[x1][y1][x2][y2];
  }
}
int main() {
  freopen("data.in", "r", stdin);
  while (scanf("%d%d", &n, &m) && n && m) {
    for (int i = 1; i <= n; i++) scanf("%s", maz[i] + 1);
    memset(dp, -1, sizeof(dp));
    memset(reach, 0, sizeof(reach));
    for (int i = 1; i <= n; i++)
      for (int j = 1; j <= m; j++)
        if (maz[i][j] != '#') {
          cout << "  cao  " << endl;
          dfs(i, j, i, j);
        }
    for (int i = 1; i <= n; i++)
      for (int j = 1; j <= m; j++)
        for (int k = 1; k <= n; k++)
          for (int q = 1; k <= m; k++)
            cout << i << " " << j << " " << k << " " << q << " "
                 << reach[i][j][k][q] << endl;
    cout << DP(1, 1, n, m) << endl;
  }
  return 0;
}
