#include<bits/stdc++.h>
using namespace std;
int h,w;
vector<string> s;
int dp[55][55][55][55];
bool used[55][55][55][55];
bool mv[55][55][55][55];
bool oc[55][55];
vector<int> cy[2][30],cx[2][30];
typedef pair<int,int> P;
void calc(){
  memset(mv,0,sizeof(mv));
  int ax[]={1,0};
  int ay[]={0,1};
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      if(s[i][j]=='#') continue;
      queue<P> q;
      q.push(P(i,j));
      mv[i][j][i][j]=1;
      while(!q.empty()){
	P p=q.front();q.pop();
	int y=p.first,x=p.second;
	for(int k=0;k<2;k++){
	  int ny=y+ay[k],nx=x+ax[k];
	  if(ny>=h||nx>=w) continue;
	  if(s[ny][nx]=='#') continue;
	  if(mv[i][j][ny][nx]) continue;
	  q.push(P(ny,nx));
	  mv[i][j][ny][nx]=1;
	}
      }
    }
  }
}
int in(int sy,int sx,int ty,int tx,int y,int x){
  return sy<=y&&y<=ty&&sx<=x&&x<=tx;
}
int dfs(int sy,int sx,int ty,int tx){
  //cout<<sy<<" "<<sx<<" "<<ty<<" "<<tx<<endl;
  if(used[sy][sx][ty][tx]) return dp[sy][sx][ty][tx];
  if(!mv[sy][sx][ty][tx]) return dp[sy][sx][ty][tx]=-1;
  //if(sy==ty&&sx==tx) return dp[c][sy][sx][ty][tx]=0;
  int res=0;
  for(int k=0;k<26;k++){
    for(int i=0;i<(int)cy[0][k].size();i++){
      if(oc[cy[0][k][i]][cx[0][k][i]]) continue;
      for(int j=0;j<(int)cy[1][k].size();j++){
	if(oc[cy[1][k][j]][cx[1][k][j]]) continue;
	if(!in(sy,sx,ty,tx,cy[0][k][i],cx[0][k][i])) continue;
	if(!in(sy,sx,ty,tx,cy[1][k][j],cx[1][k][j])) continue;
	if(!mv[sy][sx][cy[0][k][i]][cx[0][k][i]]) continue;
	if(!mv[cy[0][k][i]][cx[0][k][i]][cy[1][k][j]][cx[1][k][j]]) continue;
	if(!mv[cy[1][k][j]][cx[1][k][j]][ty][tx]) continue;
	oc[cy[0][k][i]][cx[0][k][i]]=1;
	oc[cy[1][k][j]][cx[1][k][j]]=1;
	//cout<<k<<endl;
	int tmp=0,cur;
	cur=dfs(sy,sx,cy[0][k][i],cx[0][k][i]);
	if(cur<0){
	  oc[cy[0][k][i]][cx[0][k][i]]=0;
	  oc[cy[1][k][j]][cx[1][k][j]]=0;
	  continue;
	}
	tmp+=cur;
	cur=dfs(cy[0][k][i],cx[0][k][i],cy[1][k][j],cx[1][k][j]);
	if(cur<0){
	  oc[cy[0][k][i]][cx[0][k][i]]=0;
	  oc[cy[1][k][j]][cx[1][k][j]]=0;
	  continue;
	}
	tmp+=cur;
	cur=dfs(cy[1][k][j],cx[1][k][j],ty,tx);
	if(cur<0){
	  oc[cy[0][k][i]][cx[0][k][i]]=0;
	  oc[cy[1][k][j]][cx[1][k][j]]=0;
	  continue;
	}
	tmp+=cur;
	res=max(res,tmp+1);
	oc[cy[0][k][i]][cx[0][k][i]]=0;
	oc[cy[1][k][j]][cx[1][k][j]]=0;
	//cout<<":"<<res<<endl;
      }
    }
  }
  //cout<<res<<endl;
  //if(sy==ty&&sx==tx&&res) cout<<sy<<" "<<sx<<endl;
  used[sy][sx][ty][tx]=1;
  return dp[sy][sx][ty][tx]=res;
}
signed main(){
  while(cin>>h>>w,h){
    s.clear();
    s.resize(h);
    for(int i=0;i<h;i++) cin>>s[i];
    memset(dp,-1,sizeof(dp));
    memset(used,0,sizeof(used));
    for(int i=0;i<26;i++){
      cy[0][i].clear();
      cy[1][i].clear();
      cx[0][i].clear();
      cx[1][i].clear();
    }
    for(int i=0;i<h;i++){
      for(int j=0;j<w;j++){
	if(islower(s[i][j])){
	  cy[0][s[i][j]-'a'].push_back(i);
	  cx[0][s[i][j]-'a'].push_back(j);
	}
	if(isupper(s[i][j])){
	  cy[1][s[i][j]-'A'].push_back(i);
	  cx[1][s[i][j]-'A'].push_back(j);
	}
      }
    }
    calc();
    memset(oc,0,sizeof(oc));
    cout<<dfs(0,0,h-1,w-1)<<endl;
  }
  return 0;
}