#include <stdio.h>
#include <iostream>
#include <vector>
#include <list>
#include <cmath>
#include <fstream>
#include <algorithm>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <complex>
#include <iterator>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <cassert>

using namespace std;

#define EPS (1e-10)
#define EQ(a,b) (abs((a) - (b)) < EPS)
#define EQV(a,b) (EQ((a).real(),(b).real()) && EQ((a).imag(),(b).imag()))

typedef complex<double> P;
typedef long long ll;

int h,w;
char field[40][40];
map<char,int> idxs;
int idx;
bool passed[1<<12][31][31];
const int dy[]={-1,0,0,1};
const int dx[]={0,-1,1,0};

class Sit{
public:
  int s;
  int x;
  int y;
};

int bfs(pair<int,int> sp,pair<int,int> goal){
  queue<Sit> *prv=new queue<Sit>();
  queue<Sit> *nxt=new queue<Sit>();
  Sit ssit;
  ssit.s=0;
  ssit.x=sp.second;
  ssit.y=sp.first;
  prv->push(ssit);
  int dist=0;
  passed[0][sp.first][sp.second]=true;
  while(prv->size()){
    while(prv->size()){
      Sit cp=prv->front();prv->pop();
      if(cp.x==goal.second&&cp.y==goal.first){
	delete prv;delete nxt;
	return dist;
      }
      for(int i = 0; i < 4; i++){
	int ny=cp.y+dy[i];
	int nx=cp.x+dx[i];
	if(ny>=0&&nx>=0&&ny<h&&nx<w){
	  int bases=cp.s;
	  // carpet
	  if(field[ny][nx]>='a'&&field[ny][nx]<='z'){
	    int x=idxs[(char)(field[ny][nx])];
	    if((bases>>x)&1)
	      bases&=~(1<<x);
	    else
	      bases|=(1<<x);
	  }
	  if(field[ny][nx]!='#'
	     &&!passed[bases][ny][nx]){
	    // iwa
	    if(field[ny][nx]>='A'&&field[ny][nx]<='Z'){
	      if(idxs.find((char)(field[ny][nx]+32))
		 ==idxs.end()){
		continue;
	      }
	      int x=idxs[field[ny][nx]+32];
	      if(!((bases>>x)&1))
		continue;
	    }
	    passed[bases][ny][nx]=true;
	    Sit nsit;
	    nsit.s=bases;
	    nsit.x=nx;
	    nsit.y=ny;
	    nxt->push(nsit);
	  }
	}
      }
    }
    dist++;
    swap(prv,nxt);
  }
  delete prv;
  delete nxt;
  return -1;
}

int main(){
while(cin>>w>>h&&!(w==0&&h==0)){
    memset(passed,0,sizeof(passed));
    pair<int,int> sp,gp;
    idxs.clear();
    idx=0;
    for(int i = 0; i < h; i++){
      for(int j = 0; j < w; j++){
	cin>>field[i][j];
	if(field[i][j]=='@'){
	  sp.first=i;sp.second=j;
	  field[i][j]='.';
	}
	else if(field[i][j]=='<'){
	  gp.first=i;gp.second=j;
	  field[i][j]='.';
	}
	else if(field[i][j]!='#'&&field[i][j]!='.'){
	  char ch=field[i][j];
	  if(ch>='a'&&ch<='z'){
	    if(idxs.find(ch)==idxs.end())
	      idxs[ch]=idx++;
	  }
	}
      }
    }
    int res=bfs(sp,gp);
    cout<<res<<endl;
  }
  return 0;
}