#include <bits/stdc++.h>
using namespace std;
struct node {
  int hx, hy;
  int tx, ty;
  int dep;
  long dir;
  int zt[15];
};
queue<node> q;
int n, m, len;
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
bool v[15][15][262144];
char c[30][30];
bool init(int a, int b) {
  if (a < 0 || a >= n || b < 0 || b >= m) return 0;
  return 1;
}
int update(int d, int nd) {
  d = d | (nd << ((len - 1) * 2));
  d >>= 2;
  return d;
}
void out(int d) {
  for (int i = 1; i < len; i++) {
    int t = d % 4;
    if (t == 0) cout << 'w';
    if (t == 1) cout << 'd';
    if (t == 2) cout << 's';
    if (t == 3) cout << 'a';
    d /= 4;
  }
}
void zut(int x) {
  for (int i = 1; i <= m; i++) {
    cout << x % 2;
    x /= 2;
  }
}
int ax, ay;
node fst;
int main() {
  cin >> n >> m;
  int fhx, fhy, ftx, fty;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) {
      cin >> c[i][j];
      if (c[i][j] >= '1' && c[i][j] <= '9') len = max(len, c[i][j] - '0');
      if (c[i][j] == '1') {
        fhx = i;
        fhy = j;
      }
      if (c[i][j] == len + '0') {
        ftx = i;
        fty = j;
      }
      if (c[i][j] == '@') {
        ax = i;
        ay = j;
      }
    }
  int fdir = 0;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
      if (c[i][j] >= '1' && c[i][j] <= '9') {
        for (int k = 0; k < 4; k++) {
          int nx = i + dx[k], ny = j + dy[k];
          if (init(nx, ny) && c[nx][ny] == c[i][j] - 1) {
            int nk = k;
            fdir = fdir | (nk << ((len - (c[i][j] - '0')) * 2));
            break;
          }
        }
        fst.zt[i] |= (1 << j);
      }
  fst.dir = fdir, fst.hx = fhx, fst.hy = fhy, fst.tx = ftx, fst.ty = fty,
  fst.dep = 0;
  q.push(fst);
  while (!q.empty()) {
    node f = q.front();
    q.pop();
    if (f.hx == ax && f.hy == ay) {
      cout << f.dep;
      return 0;
    } else {
      for (int i = 0; i < 4; i++) {
        int nx = f.hx + dx[i], ny = f.hy + dy[i];
        if (!init(nx, ny)) continue;
        if (c[nx][ny] == '#') continue;
        if (f.zt[nx] & (1 << ny) && !(nx == f.tx && ny == f.ty)) continue;
        node nf = f;
        nf.hx = nx;
        nf.hy = ny;
        nf.tx = dx[f.dir & (3)] + f.tx;
        nf.ty = dy[f.dir & (3)] + f.ty;
        nf.zt[f.tx] ^= (1 << f.ty);
        nf.zt[nx] |= (1 << ny);
        nf.dir = update(f.dir, i);
        nf.dep++;
        if (v[nx][ny][nf.dir]) continue;
        v[nx][ny][nf.dir] = 1;
        q.push(nf);
      }
    }
  }
  cout << -1;
  return 0;
}
