#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


struct Info{
	Info(int arg_row,int arg_col,int arg_state,int arg_total_time){
		row = arg_row;
		col = arg_col;
		state = arg_state;
		total_time = arg_total_time;
	}
	int row,col,state,total_time;
};


int W,H;
int POW[17],index_table[26];
int min_Time[30][30][256],diff_row[4] = {-1,0,0,1},diff_col[4] = {0,-1,1,0};
char base_map[30][31];

void func(){

	for(int i = 0; i < 26; i++)index_table[i] = -1;

	int start_row,start_col,index = 0;

	for(int row = 0; row < H; row++){

		scanf("%s",base_map[row]);

		for(int col = 0; col < W; col++){
			if(base_map[row][col] == '@'){
				start_row = row;
				start_col = col;
				base_map[row][col] = '.';
			}else if(base_map[row][col] >= 'a' && base_map[row][col] <= 'z'){
				if(index_table[base_map[row][col]-'a'] == -1){
					index_table[base_map[row][col]-'a'] = index;
					index++;
				}
			}
		}
	}

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			for(int state = 0; state < POW[index]; state++)min_Time[row][col][state] = BIG_NUM;
		}
	}

	queue<Info> Q;
	min_Time[start_row][start_col][0] = 0;
	Q.push(Info(start_row,start_col,0,0));

	int next_row,next_col,next_state,loc;

	while(!Q.empty()){

		if(base_map[Q.front().row][Q.front().col] == '<'){
			printf("%d\n",Q.front().total_time);
			return;
		}else if(Q.front().total_time > min_Time[Q.front().row][Q.front().col][Q.front().state]){
			Q.pop();
		}else{

			for(int i = 0; i < 4; i++){
				next_row = Q.front().row + diff_row[i];
				next_col = Q.front().col + diff_col[i];

				if(base_map[next_row][next_col] == '#')continue;

				if(base_map[next_row][next_col] == '.' || base_map[next_row][next_col] == '<'){
					if(min_Time[next_row][next_col][Q.front().state] > Q.front().total_time+1){
						min_Time[next_row][next_col][Q.front().state] = Q.front().total_time+1;
						Q.push(Info(next_row,next_col,Q.front().state,Q.front().total_time+1));
					}
				}else if(base_map[next_row][next_col] >= 'a' && base_map[next_row][next_col] <= 'z'){
					loc = index_table[base_map[next_row][next_col]-'a'];

					if(Q.front().state&(1 << loc)){
						next_state = Q.front().state-POW[loc];
					}else{
						next_state = Q.front().state+POW[loc];
					}

					if(min_Time[next_row][next_col][next_state] > Q.front().total_time+1){
						min_Time[next_row][next_col][next_state] = Q.front().total_time+1;
						Q.push(Info(next_row,next_col,next_state,Q.front().total_time+1));
					}
				}else if(base_map[next_row][next_col] >= 'A' && base_map[next_row][next_col] <= 'Z'){
					loc = index_table[base_map[next_row][next_col]-'A'];

					if((Q.front().state&(1 << loc)) == 0)continue;

					if(min_Time[next_row][next_col][Q.front().state] > Q.front().total_time+1){
						min_Time[next_row][next_col][Q.front().state] = Q.front().total_time+1;
						Q.push(Info(next_row,next_col,Q.front().state,Q.front().total_time+1));
					}
				}
			}
			Q.pop();
		}
	}

	printf("-1\n");
}

int main(){

	for(int i = 0; i < 17; i++)POW[i] = pow(2,i);

	while(true){
		scanf("%d %d",&W,&H);
		if(W == 0 && H == 0)break;

		func();
	}

	return 0;
}