Problem: The Kingdom of Aqua Canora Mystica is a very affluent and peaceful country, but around the kingdom, there are many evil monsters that kill people. So the king gave an order to you to kill the master monster.

You came to the dungeon where the monster lived. The dungeon consists of a grid of square cells. You explored the dungeon moving up, down, left and right. You finally found, fought against, and killed the monster.

Now, you are going to get out of the dungeon and return home. However, you found strange carpets and big rocks are placed in the dungeon, which were not there until you killed the monster. They are caused by the final magic the monster cast just before its death! Every rock occupies one whole cell, and you cannot go through that cell. Also, each carpet covers exactly one cell. Each rock is labeled by an uppercase letter and each carpet by a lowercase. Some of the rocks and carpets may have the same label.

While going around in the dungeon, you observed the following behaviors. When you enter into the cell covered by a carpet, all the rocks labeled with the corresponding letter (e.g., the rocks with ‘A’ for the carpets with ‘a’) disappear. After the disappearance, you can enter the cells where the rocks disappeared, but if you enter the same carpet cell again or another carpet cell with the same label, the rocks revive and prevent your entrance again. After the revival, you have to move on the corresponding carpet cell again in order to have those rocks disappear again.

Can you exit from the dungeon? If you can, how quickly can you exit? Your task is to write a program that determines whether you can exit the dungeon, and computes the minimum required time.



Input

The input consists of some data sets.

Each data set begins with a line containing two integers, W and H (3 ≤ W, H ≤ 30). In each of the following H lines, there are W characters, describing the map of the dungeon as W × H grid of square cells. Each character is one of the following:

* ‘@’ denoting your current position,
* ‘<’ denoting the exit of the dungeon,
* A lowercase letter denoting a cell covered by a carpet with the label of that letter,
* An uppercase letter denoting a cell occupied by a rock with the label of that letter,
* ‘#’ denoting a wall, and
* ‘.’ denoting an empty cell.



Every dungeon is surrounded by wall cells (‘#’), and has exactly one ‘@’ cell and one ‘<’ cell. There can be up to eight distinct uppercase labels for the rocks and eight distinct lowercase labels for the carpets.

You can move to one of adjacent cells (up, down, left, or right) in one second. You cannot move to wall cells or the rock cells.

A line containing two zeros indicates the end of the input, and should not be processed.

Output

For each data set, output the minimum time required to move from the ‘@’ cell to the ‘<’ cell, in seconds, in one line. If you cannot exit, output -1.

Examples

Input

8 3
########
#<A.@.a#
########
8 3
########
#<AaAa@#
########
8 4
########
#<EeEe@#
#FG.e#.#
########
8 8
########
#mmm@ZZ#
#mAAAbZ#
#mABBBZ#
#mABCCd#
#aABCDD#
#ZZcCD<#
########
0 0


Output

7
-1
7
27


Input

8 3

<A.@.a#

8 3

<AaAa@#

8 4

<EeEe@#
FG.e#.#

8 8

mmm@ZZ#
mAAAbZ#
mABBBZ#
mABCCd#
aABCDD#
ZZcCD<#

0 0


Output

7
-1
7
27

Solution (in CPP):

Solution:
/*
16:54 - 17;14
 */
#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
#include<climits>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define IINF (INT_MAX)
#define MAX 31

using namespace std;

struct Data{
  int cur,state,cost;
  Data(int cur=IINF,int state=IINF,int cost=IINF):cur(cur),state(state),cost(cost){}
  bool operator < (const Data& a)const{ return cost > a.cost; }
};

int H,W,sp,gp;
char G[MAX*MAX];
int mincost[MAX*MAX][(1<<9)];
int dx[] = {0,1,0,-1};
int dy[] = {1,0,-1,0};
int Index[30];

inline bool isValid(int x,int y){ return (0 <= x && x < W && 0 <= y && y < H); }

void compute(){
  rep(i,H)rep(j,W)rep(k,(1<<9))mincost[j+i*W][k] = IINF;
  mincost[sp][0] = 0;
  priority_queue<Data> Q;
  Q.push(Data(sp,0,0));
  while(!Q.empty()){
    Data data = Q.top(); Q.pop();
    int x = data.cur % W, y = data.cur / W;

    if(G[data.cur] == '<'){
      cout << data.cost << endl;
      return;
    }
    rep(i,4){
      int nx = x + dx[i], ny = y + dy[i], nstate = data.state;

      if(!isValid(nx,ny))continue;
      if(G[nx+ny*W] == '#')continue;
      if('a' <= G[nx+ny*W] && G[nx+ny*W] <= 'z'){
	int index = Index[G[nx+ny*W]-'a'];
	if((nstate>>index) & 1)nstate  = nstate & ~(1<<index);
	else                   nstate |= (1<<index);
      } else if('A' <= G[nx+ny*W] && G[nx+ny*W] <= 'Z'){
	int index = Index[G[nx+ny*W]-'A'];
	if(!((data.state>>index) & 1))continue;
      }
      if(mincost[nx+ny*W][nstate] > data.cost+1){
	mincost[nx+ny*W][nstate] = data.cost+1;
	Q.push(Data(nx+ny*W,nstate,data.cost+1));
      }
    }
  }
  cout << -1 << endl;
}

int main(){
  while(cin >> W >> H,W|H){
    int idx = 0;
    rep(i,30)Index[i] = IINF;
    rep(y,H)rep(x,W){
      cin >> G[x+y*W];
      if(G[x+y*W] == '@')sp = x + y * W;
      if('a' <= G[x+y*W] && G[x+y*W] <= 'z')if(Index[G[x+y*W]-'a'] == IINF)Index[G[x+y*W]-'a'] = idx++;
    }
    compute();
  }
  return 0;
}