#include <iostream>
#include <vector>
using namespace std;
struct Queue {
struct node {
int x, y;
int step;
};
node u[1010100];
int head = 1, tail = 0;
inline void reuse() {
head = 1, tail = 0;
}
inline void push(node a) {
u[++tail] = a;
}
inline void pop_front() {
++head;
}
inline void pop_back() {
--tail;
}
inline node front() {
return u[head];
}
inline node back() {
return u[tail];
}
inline int size() {
return tail - head + 1;
}
inline bool empty() {
return tail < head;
}
} q;
int dis[1010][1010];
char a[1010][1010];
int dir[4][2] = {
{0, 1},
{1, 0},
{0, -1},
{-1, 0}
};
char Getchar() {
char c = getchar();
while (c != '@' && c != '.' && c != '=' && c != '#' && !(c >= 'A' && c <= 'Z')) c = getchar();
return c;
}
vector<pair<int, int> > g[30];
int main() {
int n, m, x, y;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
a[i][j] = Getchar();
if (a[i][j] >= 'A' && a[i][j] <= 'Z') {
g[a[i][j] - 'A'].emplace_back(i, j);
}
if (a[i][j] == '@') {
x = i, y = j;
}
}
}
q.push({x, y, 0});
dis[x][y] = -1;
while (!q.empty()) {
Queue::node frt = q.front();
q.pop_front();
if (a[frt.x][frt.y] == '=') {
return printf("%d\n", frt.step), 0;
}
for (int i = 0; i < 4; ++i) {
int _x = frt.x + dir[i][0], _y = frt.y + dir[i][1];
if (_x < 1 || _y < 1 || _x > n || _y > m || a[_x][_y] == '#') continue;
if (a[_x][_y] >= 'A' && a[_x][_y] <= 'Z') {
pair<int, int> qwq;
if (g[a[_x][_y] - 'A'][0] != make_pair(_x, _y)) {
qwq = g[a[_x][_y] - 'A'][0];
} else {
qwq = g[a[_x][_y] - 'A'][1];
}
if (dis[qwq.first][qwq.second] == 0 || dis[qwq.first][qwq.second] > frt.step + 1) {
q.push({qwq.first, qwq.second, frt.step + 1});
dis[qwq.first][qwq.second] = frt.step + 1;
}
}
if ((dis[_x][_y] > frt.step + 1 || dis[_x][_y] == 0)) {
dis[_x][_y] = frt.step + 1;
q.push({_x, _y, dis[_x][_y]});
}
}
}
return 0;
}