#include <iostream>
#include <queue>
#include <map>
using namespace std;
struct node1 {
int x1;
int y1;
int x2;
int y2;
};
map<char, node1>ma;
int n, m,u, v,xx1,yy1;
int flag=0;
char map1[355][355];
int tx[4] = {1, -1, 0, 0};
int ty[4] = {0, 0, 1, -1};
bool vis[355][355];
struct node {
int x;
int y;
int t;
} temp;
queue<node>q;
void check(int &xx, int &yy) {
if(ma[map1[xx][yy]].x1!=0&&ma[map1[xx][yy]].x2==0)
{
flag=1;
}
else
{
if (ma[map1[xx][yy]].x1 != xx && ma[map1[xx][yy]].y1 != yy) {
xx = ma[map1[temp.x][temp.y]].x1;
yy = ma[map1[temp.x][temp.y]].y1;
} else {
xx = ma[map1[temp.x][temp.y]].x2;
yy = ma[map1[temp.x][temp.y]].y2;
}
}
}
void read(int n,int m)
{
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> map1[i][j];
if (map1[i][j] == '@') {
u = i;
v = j;
} else if (map1[i][j] >= 'A' && map1[i][j] <= 'Z') {
if (ma[map1[i][j]].x1 == 0 && ma[map1[i][j]].y1 == 0) {
ma[map1[i][j]].x1 = i;
ma[map1[i][j]].y1 = j;
} else {
ma[map1[i][j]].x2 = i;
ma[map1[i][j]].y2 = j;
}
}
}
}
}
int main() {
cin >> n >> m;
read(n,m);
vis[u][v] = 1;
q.push((node) { u, v, 0 });
while (!q.empty()) {
temp = q.front();
q.pop() ;
int xx = temp.x;
int yy = temp.y;
if (map1[xx][yy] >= 'A' && map1[xx][yy] <= 'Z')
{
check(xx,yy);
if(flag)
{ flag=0;
continue;
}
}
for (int i = 0; i < 4; i++) {
xx1=xx+tx[i];
yy1=yy+ty[i];
if (xx1 <= 0 || yy1 <= 0 || xx1 >n || yy1 >m)
continue;
if(vis[xx1][yy1])
continue;
if (map1[xx1][yy1] == '#')
continue;
if (map1[xx1][yy1] == '.') {
vis[xx1][yy1] = 1;
q.push((node) { xx1, yy1, temp.t+1});
}
if(map1[xx1][yy1]>='A'&&map1[xx1][yy1]<='Z')
{
q.push((node) { xx1, yy1, temp.t+1});
}
if (map1[xx1][yy1] == '=') {
cout<<temp.t+1;return 0;
}
}
}
return 0;
}