#include <bits/stdc++.h>
using namespace std;
using ll=long long;
using vb=vector<bool>;
using vvb=vector<vb>;
using vvvb=vector<vvb>;
using vvvvb=vector<vvvb>;
using vd=vector<double>;
using vvd=vector<vd>;
using vi=vector<int>;
using vvi=vector<vi>;
using vvvi=vector<vvi>;
using vvvvi=vector<vvvi>;
using vl=vector<ll>;
using vvl=vector<vl>;
using pii=pair<int, int>;
using pll=pair<ll,ll>;
using tll=tuple<ll,ll>;
using tlll=tuple<ll,ll,ll>;
using vs=vector<string>;
#define all(a) a.begin(),a.end()
#define rall(a) a.rbegin(),a.rend()
#define rep(i,n) range(i,0,n)
#define rrep(i,n) for(ll i=(n)-1;i>=0;i--)
#define range(i,a,n) for(ll i=(a);i<(n);i++)
#define LINF ((ll)1ll<<60)
#define INF ((int)1<<30)
#define EPS (1e-9)
#define MOD (1000000007ll)
#define fcout(a) cout<<setprecision(a)<<fixed
#define fs first
#define sc second
#define PI (3.1415926535897932384)

int dx[]={1,0,-1,0,1,-1,-1,1},dy[]={0,1,0,-1,1,1,-1,-1};
template<class T>bool chmax(T&a,T b){if(a<b){a=b; return true;}return false;}
template<class T>bool chmin(T&a,T b){if(a>b){a=b; return true;}return false;}
template<class S>S sum(vector<S>&a){return accumulate(all(a),S());}
template<class S>S max(vector<S>&a){return *max_element(all(a));}
template<class S>S min(vector<S>&a){return *min_element(all(a));}
ll max(int a,ll b){return max((ll)a,b);} ll max(ll a,int b){return max(a,(ll)b);}

template<class T>void puta(T&&t){cout<<t<<"\n";}
template<class H,class...T>void puta(H&&h,T&&...t){cout<<h<<' ';puta(t...);}
template<class S,class T>void tf(bool b,S t,T f){if(b)puta(t);else puta(f);}
void YN(bool b){tf(b,"YES","NO");}
void Yn(bool b){tf(b,"Yes","No");}
void yn(bool b){tf(b,"yes","no");}
template<class S,class T>ostream&operator<<(ostream&os,pair<S,T>p){os<<"["<<p.first<<", "<<p.second<<"]";return os;};
template<class S>auto&operator<<(ostream&os,vector<S>t){bool a=1;for(auto s:t){os<<(a?"":" ")<<s;a=0;}return os;}
template<class S>auto&operator>>(istream&is,vector<S>&t){for(S&a:t)cin>>a;return is;}

using Pos=map<char, vector<pii>>;
using Visit=vvvvb;

constexpr bool cmp(int&a,int l, int r){
	return l<=a and a<r;
}

vvvvi memo;
vvvvi vis;
int rec(int sy, int sx, int gy, int gx, vs&f, Pos&mp){
	if(!cmp(sy,0,f.size()) or !cmp(gy,0,f.size()) or !cmp(sx,0,f[0].size()) or !cmp(gx,0,f[0].size())){
		return -1;
	}
	if(f[sy][sx]=='#' or f[gy][gx]=='#'){
		return -1;
	}
	if(sx>gx or sy>gy or (sx==gx and sy==gy)){
		return 0;
	}
	if(memo[sy][sx][gy][gx]!=INF){
		return memo[sy][sx][gy][gx];
	}
	if(vis[sy][sx][gy][gx]!=1) return -1;

	int ret=max(rec(sy+1,sx,gy,gx,f,mp), rec(sy,sx+1,gy,gx,f,mp));

	if(islower(f[sy][sx])){
		for(auto&to : mp[toupper(f[sy][sx])]){
			int ty,tx,val=0;
			tie(ty,tx) = to;
			if(vis[sy][sx][ty][tx]!=1 or vis[ty][tx][gy][gx]!=1)continue;
			val += max({rec(sy+1,sx,ty,tx-1,f,mp), rec(sy,sx+1,ty-1,tx,f,mp),
						rec(sy+1,sx,ty-1,tx,f,mp), rec(sy,sx+1,ty,tx-1,f,mp)});
			val += 1+rec(ty,tx,gy,gx,f,mp);
			chmax(ret, val);
		}
	}
	return memo[sy][sx][gy][gx] = ret;
}


bool bfs(int sy, int sx, int gy, int gx, vs&f){
	if(!cmp(sy,0,f.size()) or !cmp(gy,0,f.size()) or !cmp(sx,0,f[0].size()) or !cmp(gx,0,f[0].size())){
		return 0;
	}

	if(vis[sy][sx][gy][gx]!=-1) return vis[sy][sx][gy][gx];

	int ret = 0;
	if(sx>gx or sy>gy or f[sy][sx]=='#' or f[gy][gx]=='#'){
		;
	} else if (sx==gx and sy==gy){
		ret = f[sy][sx]=='#'?0:1;
	}else if (sx==gx and sy+1==gy and f[sy][sx]!='#' and f[gy][gx]!='#'
	            or sy==gy and sx+1==gx and f[sy][sx]!='#' and f[gy][gx]!='#'){
	    ret = 1;
	}else{
		ret|=bfs(sy+1,sx,gy-1,gx,f);
		ret|=bfs(sy+1,sx,gy,gx-1,f);
		ret|=bfs(sy,sx+1,gy-1,gx,f);
		ret|=bfs(sy,sx+1,gy,gx-1,f);
	}
	
	return vis[sy][sx][gy][gx]=ret;
}

/*他のライブラリを入れる場所*/
int solve(int h, int w){
	vs f(h);
	cin>>f;
	memo=vvvvi(h, vvvi(w, vvi(h, vi(w,INF))));
	vis=vvvvi(h, vvvi(w, vvi(h, vi(w,-1))));

	Pos mp;
	rep(i,h)rep(j,w){
		if(isalpha(f[i][j])){
			if(mp.find(f[i][j])==mp.end()){
				mp[f[i][j]] = vector<pii>();
			}
			mp[f[i][j]].emplace_back(i,j);
		}
	}
	rep(i,h)rep(j,w)rep(k,h)rep(l,w)bfs(i,j,k,l,f);
	return rec(0,0,h-1,w-1,f,mp);
}

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	ll h,w;
	while(cin>>h>>w,h+w){
		puta(solve(h,w));
	}
	return 0;
}


Measured memory_bytes: 88640