//新生训练
#include <queue>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 1e3 + 5;
struct Node
{
int v, m;
Node() {}
Node(int V, int M)
{
v = V;
m = M;
}
friend bool operator<(Node x, Node y)
{
return x.m > y.m;
}
};
priority_queue<Node> q;
vector<Node> a[MAXN];
int mp[MAXN][MAXN];
int x[MAXN] = {0, -1, 1, 0, 0};
int y[MAXN] = {0, 0, 0, -1, 1};
int d[MAXN];
bool f[MAXN];
int N, M, n, m, c, t;
int c1, c2, t1, t2;
void Init()
{
c1 = c2 = t1 = t2 = n = m = c = t = 0;
memset(d, 0, sizeof(d));
memset(f, 0, sizeof(f));
memset(mp, 0, sizeof(mp));
while (!q.empty())
q.pop();
for (int i = 0; i < MAXN; i++)
a[i].clear();
}
void Read()
{
char A;
for (int i = 1; i <= N; i++)
{
for (int j = 1; j <= M; j++)
{
cin >> A;
if (A == '.')
mp[i][j] = 1;
else if (A == '#')
mp[i][j] = 2;
else if (A == '@')
{
mp[i][j] = 3;
c1 = i;
c2 = j;
}
else
{
mp[i][j] = 4;
t1 = i;
t2 = j;
}
}
}
c = M * (c1 - 1) + c2;
t = M * (t1 - 1) + t2;
for (int i = 1; i <= N; i++)
{
for (int j = 1; j <= M; j++)
{
int A = M * (i - 1) + j, B;
if (mp[i][j] == 0 || mp[i][j] == 2)
continue;
for (int k = 1; k <= 4; k++)
{
int X = i + x[k], Y = j + y[k];
if (mp[X][Y] >= 1 && mp[X][Y] != 2)
{
B = M * (X - 1) + Y;
a[A].push_back(Node(B, 1));
a[B].push_back(Node(A, 1));
}
}
}
}
q.push(Node(c, 0));
}
void Dijkstra()
{
memset(d, 0x3f, sizeof(d));
d[c] = 0;
while (!q.empty())
{
Node now = q.top();
q.pop();
int i = now.v;
if (f[i])
continue;
f[i] = 1;
int SIZ = a[i].size();
for (int j = 0; j < SIZ; j++)
{
if (d[a[i][j].v] > d[i] + a[i][j].m)
{
d[a[i][j].v] = d[i] + a[i][j].m;
q.push(Node(a[i][j].v, d[a[i][j].v]));
}
}
}
if (d[t] == 0x3f3f3f3f)
cout << "-1" << endl;
else
cout << d[t] << endl;
}
int main()
{
while (cin >> N >> M)
{
Init();
Read();
Dijkstra();
}
return 0;
}
//同样是计数,此题的复杂度就增加许多,还用到了C++的 STL ;
~~~//仅当笔者个人备忘录使用。