#include "bits/stdc++.h"

using namespace std;

using ll = long long;
using P = pair<int, int>;
constexpr int INF = numeric_limits<int>::max() / 2;
int h, w;

template <typename T>
void printv(const vector<T> &v)
{
    int sz = v.size();
    for (int i = 0; i < sz; i++)
    {
        cout << v[i] << " \n"[i == sz - 1];
    }
}

// mv[sx][sy][gx][gt] = (sx,sy)->(gx,gy)移動可能か
ll mv[50][50][50][50], dp[50][50][50][50];
int dx[2] = {1, 0}, dy[2] = {0, 1};

ll rec(int sx, int sy, int gx, int gy, const vector<string> &s, map<char, vector<P>> &mp)
{
    ll &ret = dp[sx][sy][gx][gy];
    if (ret != -INF)
        return ret;
    if (sx == gx && sy == gy)
        return ret = 0;
    if (s[sx][sy] == '#')
        return ret = -INF / 2;
    if (mv[sx][sy][gx][gy] != 1)
        return ret = -INF / 2;
    if (sx + 1 <= gx && s[sx + 1][sy] != '#' && mv[sx][sy][sx + 1][sy] == 1 && mv[sx + 1][sy][gx][gy] == 1)
        ret = max(ret, rec(sx + 1, sy, gx, gy, s, mp));
    if (sy + 1 <= gy && s[sx][sy + 1] != '#' && mv[sx][sy][sx][sy + 1] == 1 && mv[sx][sy + 1][gx][gy] == 1)
        ret = max(ret, rec(sx, sy + 1, gx, gy, s, mp));
    if ('a' <= s[sx][sy] && s[sx][sy] <= 'z')
    {
        for (auto p : mp[s[sx][sy]])
        {
            int x = p.first, y = p.second;
            if (mv[sx][sy][x][y] != 1 || mv[x][y][gx][gy] != 1)
                continue;
            if (x < sx || gx < x || y < sy || gy < y)
                continue;
            if (abs(x - sx) + abs(y - sy) == 1)
            {
                ret = max(ret, 1 + rec(x, y, gx, gy, s, mp));
                continue;
            }
            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 2; j++)
                {
                    int nx1 = sx + dx[i], ny1 = sy + dy[i];
                    int nx2 = x - dx[j], ny2 = y - dy[j];
                    if (nx1 < sx || x < nx1 || ny1 < sy || y < ny1)
                        continue;
                    if (nx2 < sx || x < nx2 || ny2 < sy || y < ny2)
                        continue;
                    if (mv[sx][sy][nx1][ny1] != 1 || mv[nx1][ny1][nx2][ny2] != 1 || mv[nx2][ny2][x][y] != 1)
                        continue;
                    ret = max(ret, rec(nx1, ny1, nx2, ny2, s, mp) + rec(x, y, gx, gy, s, mp) + 1);
                }
            }
        }
    }
    return ret;
}

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);

    while (cin >> h >> w, h || w)
    {
        vector<string> s(h);
        // char -> goal
        map<char, vector<P>> mp;
        for (int i = 0; i < h; i++)
        {
            cin >> s[i];
            for (int j = 0; j < w; j++)
            {
                if ('A' <= s[i][j] && s[i][j] <= 'Z')
                    mp[s[i][j] - ('A' - 'a')].emplace_back(i, j);
            }
        }
        for (int sx = 0; sx < h; sx++)
            for (int sy = 0; sy < w; sy++)
                for (int gx = 0; gx < h; gx++)
                    for (int gy = 0; gy < w; gy++)
                    {
                        mv[sx][sy][gx][gy] = -INF;
                        dp[sx][sy][gx][gy] = -INF;
                    }
        for (int i = 0; i < h; i++)
        {
            for (int j = 0; j < w; j++)
            {
                if (s[i][j] == '#')
                    continue;
                mv[i][j][i][j] = 1;
                queue<P> que;
                que.emplace(i, j);
                while (!que.empty())
                {
                    int x = que.front().first, y = que.front().second;
                    que.pop();
                    for (int k = 0; k < 2; k++)
                    {
                        int nx = x + dx[k], ny = y + dy[k];
                        if (nx < 0 || h <= nx || ny < 0 || w <= ny)
                            continue;
                        if (mv[i][j][nx][ny] != -INF)
                            continue;
                        if (s[nx][ny] == '#')
                        {
                            mv[i][j][nx][ny] = 0;
                            continue;
                        }
                        mv[i][j][nx][ny] = 1;
                        que.emplace(nx, ny);
                    }
                }
            }
        }
        int ret = rec(0, 0, h - 1, w - 1, s, mp);
        cout << (ret < 0 ? -1 : ret) << endl;
    }
}



Measured memory_bytes: 100804