// 以下为DFS代码
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
const int MAXN = 305;
char mp[MAXN][MAXN];
bool vis[MAXN][MAXN];
int dist[MAXN][MAXN];
int n, m, ans = 100000;
int sx, sy, endx, endy;
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
struct Portal{
int x1, y1;
int x2, y2;
};
struct coord{
int x, y;
bool operator<(const coord& other) const {
if (x != other.x) return x < other.x;
return y < other.y;
}
};
map<char, Portal> _ptls;
map<coord, coord> ptls;
bool is_letter(int x, int y){
return mp[x][y] >= 'A' && mp[x][y] <= 'Z';
}
void dfs(int x, int y, int cnt){
if (dist[x][y] && cnt >= dist[x][y]) return;
else dist[x][y] = cnt;
// cout << x << " " << y << " " << mp[x][y] << endl;
// if (mp[x][y] == '=') {ans = min(cnt, ans); return;}
for (int k = 0; k < 4; k++){
int nx = x + dx[k], ny = y + dy[k];
// cout << nx << " " << ny << " " << mp[nx][ny] << endl;
if (nx >= 1 && ny >= 1 && nx <= n && ny <= m
&& mp[nx][ny] != '#' && mp[nx][ny] != '@'){
// cout << nx << " " << ny << " " << mp[nx][ny] << endl;
char nt = mp[nx][ny];
if (nt == '.' && !vis[nx][ny]) {
vis[nx][ny] = true;
dfs(nx, ny, cnt + 1);
vis[nx][ny] = false;
}
if (nt == '='){
ans = min(ans, cnt + 1);
continue;
}
if (is_letter(nx, ny)){
coord p = ptls[{nx, ny}];
if (vis[p.x][p.y]) continue;
vis[p.x][p.y] = true;
dfs(p.x, p.y, cnt + 1);
vis[p.x][p.y] = false;
}
}
}
}
int main(){
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++){
cin >> mp[i][j];
if (mp[i][j] >= 'A' && mp[i][j] <= 'Z'){
if (_ptls.find(mp[i][j]) == _ptls.end()) _ptls[mp[i][j]].x1 = i, _ptls[mp[i][j]].y1 = j;
else _ptls[mp[i][j]].x2 = i, _ptls[mp[i][j]].y2 = j;
}
else if(mp[i][j] == '@')
sx = i, sy = j;
}
for (auto pt : _ptls){
coord p1, p2;
p1.x = pt.second.x1, p1.y = pt.second.y1;
p2.x = pt.second.x2, p2.y = pt.second.y2;
ptls[p1] = p2;
ptls[p2] = p1;
}
dfs(sx, sy, 0);
cout << ans;
}
// 以下为BFS代码
void bfs(int sx, int sy) {
queue<coord> q;
q.push({sx, sy});
vis[sx][sy] = true;
dist[sx][sy] = 0;
while (!q.empty()) {
coord u = q.front();
q.pop();
for (int k = 0; k < 4; k++) {
int nx = u.x + dx[k];
int ny = u.y + dy[k];
if (nx < 1 || ny < 1 || nx > n || ny > m)
continue;
char nt = mp[nx][ny];
if (nt == '#' || nt == '@')
continue;
if (nt == '=') {
ans = dist[u.x][u.y] + 1;
return;
}
coord p = {nx, ny};
if (is_letter(nx, ny))
p = ptls[p];
if (vis[p.x][p.y])
continue;
vis[p.x][p.y] = true;
dist[p.x][p.y] = dist[u.x][u.y] + 1;
q.push(p);
}
}
}