#include <bits/stdc++.h>

using namespace std;

#define REP(i, n) for (int i=0; i<(n); ++i)
#define RREP(i, n) for (int i=(int)(n)-1; i>=0; --i)
#define FOR(i, a, n) for (int i=(a); i<(n); ++i)
#define RFOR(i, a, n) for (int i=(int)(n)-1; i>=(a); --i)

#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()

#define dump(x) cerr<<#x<<" = "<<(x)<<endl
#define debug(x) cerr<<#x<<" = "<<(x)<<" (L"<<__LINE__<<")"<<endl;

template<class T>
ostream &operator<<(ostream &os, const vector <T> &v) {
    os << "[";
    REP(i, SZ(v)) {
        if (i) os << ", ";
        os << v[i];
    }
    return os << "]";
}

template<class T, class U>
ostream &operator<<(ostream &os, const pair <T, U> &p) {
    return os << "(" << p.first << " " << p.second << ")";
}

template<class T>
bool chmax(T &a, const T &b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

template<class T>
bool chmin(T &a, const T &b) {
    if (b < a) {
        a = b;
        return true;
    }
    return false;
}

using ll = long long;
using ull = unsigned long long;
using ld = long double;
using P = pair<int, int>;
using vi = vector<int>;
using vll = vector<ll>;
using vvi = vector<vi>;
using vvll = vector<vll>;

const ll MOD = 1e9 + 7;
const int INF = INT_MAX / 2;
const ll LINF = LLONG_MAX / 2;
const ld eps = 1e-9;


int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);

    for (;;) {
        int H, W; cin >> H >> W;
        if (H == 0) break;
        vector<string> C(H);
        REP(i, H) cin >> C[i];

        vvi jewel(H, vi(W, -1)), hole(H, vi(W, -1));
        REP(i, H) REP(j, W) {
            if ('a' <= C[i][j] and C[i][j] <= 'z') {
                jewel[i][j] = C[i][j] - 'a';
            }
            if ('A' <= C[i][j] and C[i][j] <= 'Z') {
                hole[i][j] = C[i][j] - 'A';
            }
        }

        const int HMAX = 50, WMAX = 50;
        int dp[HMAX][WMAX][HMAX][WMAX];
        memset(dp, -1, sizeof(dp));

        function<int(int,int,int,int)> rec = [&](int i1, int j1, int i2, int j2) {

            // out of range
            if (i1 < 0 or j1 < 0 or i2 < 0 or j2 < 0 or
                H <= i1 or W <= j1 or H <= i2 or W <= j2 or
                i1 > i2 or j1 > j2) return -INF;

            // dp
            if (dp[i1][j1][i2][j2] != -1) return dp[i1][j1][i2][j2];

            // init
            dp[i1][j1][i2][j2] = -INF;

            // start or end is wall
            if (C[i1][j1] == '#' or C[i2][j2] == '#') return -INF;

            // length 1
            if (i1 == i2 and j1 == j2) {
                chmax(dp[i1][j1][i2][j2], 0);
            }
            // length 2
            if (i1+1 == i2 and j1 == j2 or i1 == i2 and j1+1 == j2) {
                chmax(dp[i1][j1][i2][j2], 0);
            }

            // cut edge
            if (C[i1][j1] == '.') {
                chmax(dp[i1][j1][i2][j2], rec(i1+1, j1, i2, j2));
                chmax(dp[i1][j1][i2][j2], rec(i1, j1+1, i2, j2));
                return dp[i1][j1][i2][j2];
            }
            else if (C[i2][j2] == '.') {
                chmax(dp[i1][j1][i2][j2], rec(i1, j1, i2-1, j2));
                chmax(dp[i1][j1][i2][j2], rec(i1, j1, i2, j2-1));
                return dp[i1][j1][i2][j2];
            }

            // start and end is corresponding
            if (jewel[i1][j1] != -1 and hole[i2][j2] != -1 and
                jewel[i1][j1] == hole[i2][j2]) {
                int ma = -INF;
                if (i1 == i2 and j1 + 1 == j2 or
                    j1 == j2 and i1 + 1 == i2) {
                    ma = 0;
                }
                chmax(ma, rec(i1+1, j1, i2-1, j2));
                chmax(ma, rec(i1+1, j1, i2, j2-1));
                chmax(ma, rec(i1, j1+1, i2-1, j2));
                chmax(ma, rec(i1, j1+1, i2, j2-1));
                if (ma != -INF) chmax(dp[i1][j1][i2][j2], ma + 1);
            }

            // split
            FOR(i, i1, i2 + 1) FOR(j, j1, j2 + 1) {
                if (i + 1 <= i2) {
                    int l = rec(i1, j1, i, j), r = rec(i+1, j, i2, j2);
                    if (l != -INF and r != -INF) chmax(dp[i1][j1][i2][j2], l + r);
                }
                if (j + 1 <= j2) {
                    int l = rec(i1, j1, i, j), r = rec(i, j+1, i2, j2);
                    if (l != -INF and r != -INF) chmax(dp[i1][j1][i2][j2], l + r);
                }
            }

            return dp[i1][j1][i2][j2];
        };

        int ans = rec(0, 0, H-1, W-1);
        if (ans == -INF) ans = -1;

        cout << ans << endl;
    }

    return 0;
}



Measured memory_bytes: 27676