#include <bits/stdc++.h>   using namespace std;   int n, m;   int sz = 1;   string data[109];   struct node {     int x, y;     int pos;   };   bool operator<(const node& a, const node& b) {     if (a.x == b.x) {       if (a.y == b.y) {         return a.pos < b.pos;       }       return a.y < b.y;     }     return a.x < b.x;   }   map<node, int> mem;   int conv(vector<int> v) {     int ret = 0;     for (typeof(v.begin()) it = (v.begin()); it != v.end(); it++) {       ret = ret * 4 + (*it);     }     return ret;   }   vector<int> conv2(int pos) {     vector<int> ret;     for (long long i = 0; i < (long long)sz - 1; i++) {       ret.push_back(pos % 4);       pos /= 4;     }     reverse(ret.begin(), ret.end());     return ret;   }   int main() {     scanf( %d , &n);     scanf( %d , &m);     for (long long i = 0; i < (long long)n; i++) cin >> data[i];     queue<node> q;     vector<int> p;     int x = -1, y;     node top;     for (long long i = 0; i < (long long)n; i++) {       for (long long j = 0; j < (long long)m; j++) {         if (data[i][j] ==  1 ) {           x = i;           y = j;         }         if (data[i][j] >  1  && data[i][j] <=  9 ) {           sz = max(sz, (int)(data[i][j] -  0 ));         }       }     }     top.x = x;     top.y = y;     int xx, yy, px = x, py = y;     for (long long i = 0; i < (long long)sz - 1; i++) {       if (px - 1 >= 0) {         if ((data[px - 1][py] -  1 ) == i + 1) {           px--;           p.push_back(0);         }       }       if (px + 1 < n) {         if ((data[px + 1][py] -  1 ) == i + 1) {           px++;           p.push_back(1);         }       }       if (py - 1 >= 0) {         if ((data[px][py - 1] -  1 ) == i + 1) {           py--;           p.push_back(2);         }       }       if (py + 1 < m) {         if ((data[px][py + 1] -  1 ) == i + 1) {           py++;           p.push_back(3);         }       }     }     top.pos = conv(p);     q.push(top);     mem[top] = 1;     while (!q.empty()) {       top = q.front();       x = top.x;       y = top.y;       int pos = top.pos;       int cost = mem[top];       q.pop();       p = conv2(pos);       if (data[x][y] ==  @ ) {         cout << cost - 1 << endl;         return 0;       }       px = x;       py = y;       if (px - 1 >= 0 && ((data[px - 1][py]) !=  # )) {         vector<int> nw;         nw.push_back(1);         nw.insert(nw.end(), p.begin(), p.end() - 1);         int xx, yy;         xx = px - 1;         yy = py;         node temp;         temp.x = xx;         temp.y = yy;         xx = x;         yy = y;         int flag = 0;         for (int i = 1; i < sz - 1; i++) {           if (nw[i] == 0) {             xx--;           } else if (nw[i] == 1)             xx++;           else if (nw[i] == 2)             yy--;           else             yy++;           if (xx == temp.x && yy == temp.y) {             flag = 1;             break;           }         }         if (flag == 0) {           temp.pos = conv(nw);           if (mem.find(temp) == mem.end()) {             mem[temp] = cost + 1;             q.push(temp);           }         }       }       if (px + 1 < n && ((data[px + 1][py]) !=  # )) {         vector<int> nw;         nw.push_back(0);         nw.insert(nw.end(), p.begin(), p.end() - 1);         int xx, yy;         xx = px + 1;         yy = py;         node temp;         temp.x = xx;         temp.y = yy;         xx = x;         yy = y;         int flag = 0;         for (int i = 1; i < sz - 1; i++) {           if (nw[i] == 0) {             xx--;           } else if (nw[i] == 1)             xx++;           else if (nw[i] == 2)             yy--;           else             yy++;           if (xx == temp.x && yy == temp.y) {             flag = 1;             break;           }         }         if (flag == 0) {           temp.pos = conv(nw);           if (mem.find(temp) == mem.end()) {             mem[temp] = cost + 1;             q.push(temp);           }         }       }       if (py - 1 >= 0 && ((data[px][py - 1]) !=  # )) {         vector<int> nw;         nw.push_back(3);         nw.insert(nw.end(), p.begin(), p.end() - 1);         int xx, yy;         xx = px;         yy = py - 1;         node temp;         temp.x = xx;         temp.y = yy;         xx = x;         yy = y;         int flag = 0;         for (int i = 1; i < sz - 1; i++) {           if (nw[i] == 0) {             xx--;           } else if (nw[i] == 1)             xx++;           else if (nw[i] == 2)             yy--;           else             yy++;           if (xx == temp.x && yy == temp.y) {             flag = 1;             break;           }         }         if (flag == 0) {           temp.pos = conv(nw);           if (mem.find(temp) == mem.end()) {             mem[temp] = cost + 1;             q.push(temp);           }         }       }       if (py + 1 < m && ((data[px][py + 1]) !=  # )) {         vector<int> nw;         nw.push_back(2);         nw.insert(nw.end(), p.begin(), p.end() - 1);         int xx, yy;         xx = px;         yy = py + 1;         node temp;         temp.x = xx;         temp.y = yy;         xx = x;         yy = y;         int flag = 0;         for (int i = 1; i < sz - 1; i++) {           if (nw[i] == 0) {             xx--;           } else if (nw[i] == 1)             xx++;           else if (nw[i] == 2)             yy--;           else             yy++;           if (xx == temp.x && yy == temp.y) {             flag = 1;             break;           }         }         if (flag == 0) {           temp.pos = conv(nw);           if (mem.find(temp) == mem.end()) {             mem[temp] = cost + 1;             q.push(temp);           }         }       }     }     cout << -1 << endl;   }