#include <bits/stdc++.h>

using namespace std;

#define LOG(...) fprintf(stderr,__VA_ARGS__)
//#define LOG(...)
#define FOR(i,a,b) for(int i=(int)(a);i<(int)(b);++i)
#define REP(i,n) for(int i=0;i<(int)(n);++i)
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define SORT(c) sort(ALL(c))
#define RSORT(c) sort(RALL(c))

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

const int dx[] = {-1,0,1,0}, dy[] = {0,1,0,-1};

char field[30][30];

struct P {
    int x, y;
    int cnt;
    int pressed;
};

int main() {
    int w, h;
    while (cin >> w >> h, w|h) {
        int x, y, gx, gy;
        map<tuple<int, int, int>, bool> G;
        map<int, int> id;
        REP(i, h) {
            REP(j, w) {
                cin >> field[i][j];
                switch (field[i][j]) {
                case '@':
                    field[i][j] = '.';
                    x = j;
                    y = i;
                    break;
                case '<':
                    field[i][j] = '.';
                    gx = j;
                    gy = i;
                    break;
                case '#':
                    break;
                default: {
                    char c = tolower(field[i][j]);
                    if (!EXIST(id, c)) {
                        id[c] = id.size();
                    }
                }
                }
            }
        }
        REP(i, h) {
            REP(j, w) {
                char c = field[i][j];
                if ('a' <= c && c <= 'z') {
                    field[i][j] = id[c] + 'a';
                } else if ('A' <= c && c <= 'Z') {
                    field[i][j] = id[c+0x20] + 'A';
                }
            }
        }
//        REP(i, h) {
//            REP(j, w) {
//                char c = field[i][j];
//                LOG("%c", c);
//            }
//            LOG("\n");
//        }

        queue<P> que;
        que.push({x, y, 0, 0});
        while (!que.empty()) {
            P p = que.front(); que.pop();
            int x = p.x, y = p.y;

            if (x == gx && y == gy) {
                cout << p.cnt << endl;
                goto NEXT;
            }

            REP(i, 4) {
                int sx = x + dx[i], sy = y + dy[i];
                if (field[sy][sx] == '#') {
                    continue;
                } else if (field[sy][sx] == '.') {
                    tuple<int, int, int> k = make_tuple(sx, sy, p.pressed);
                    if (!EXIST(G, k)) {
                        G[k] = true;
                        que.push({sx, sy, p.cnt+1, p.pressed});
                    }
                } else if ('a' <= field[sy][sx] && field[sy][sx] <= 'z') {
                    int pressed = p.pressed ^ (1 << (field[sy][sx] - 'a'));
                    tuple<int, int, int> k = make_tuple(sx, sy, pressed);
                    if (!EXIST(G, k)) {
                        G[k] = true;
                        que.push({sx, sy, p.cnt+1, pressed});
                    }
                } else if ((1 << (field[sy][sx] - 'A')) & p.pressed) {
                    tuple<int, int, int> k = make_tuple(sx, sy, p.pressed);
                    if (!EXIST(G, k)) {
                        G[k] = true;
                        que.push({sx, sy, p.cnt+1, p.pressed});
                    }
                }
            }
        }
        cout << -1 << endl;
NEXT: {}
    }
}