#include <bits/stdc++.h>
using namespace std;
int N, M;
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
char grid[20][20];
int sbody[20][2];
int len;
bool valid(int x, int y) { return x >= 0 && y >= 0 && x < N && y < M; }
int encode(int x, int y) {
  char t = grid[x][y];
  assert(t == '1');
  t += 1;
  int ret = 0;
  grid[x][y] = '.';
  for (int i = 1; i < len; i++) {
    for (int k = 0; k < 4; k++) {
      int nx = x + dx[k], ny = y + dy[k];
      if (valid(nx, ny) == false || grid[nx][ny] != t) continue;
      grid[nx][ny] = '.';
      x = nx;
      y = ny;
      ret <<= 2;
      ret |= k;
      t += 1;
      break;
    }
  }
  return ret;
}
void decode(int x, int y, int ret) {
  char t = '1';
  sbody[0][0] = x;
  sbody[0][1] = y;
  grid[x][y] = t;
  t += 1;
  for (int i = (len - 1) * 2 - 1, j = 1; i > 0; i -= 2, j++) {
    int k = 0;
    if (ret & (1 << i)) k |= 2;
    if (ret & (1 << (i - 1))) k |= 1;
    int nx = x + dx[k], ny = y + dy[k];
    assert(valid(nx, ny) && grid[nx][ny] == '.');
    grid[nx][ny] = t;
    t += 1;
    x = nx;
    y = ny;
    sbody[j][0] = x;
    sbody[j][1] = y;
  }
}
set<tuple<int, int, int> > vis;
int bfs(int sx, int sy, int se) {
  queue<tuple<int, int, int, int> > q;
  vis.insert(make_tuple(sx, sy, se));
  q.push(make_tuple(sx, sy, se, 0));
  while (!q.empty()) {
    auto tp = q.front();
    q.pop();
    int x = get<0>(tp), y = get<1>(tp), e = get<2>(tp), moves = get<3>(tp);
    for (int k = 0; k < 4; k++) {
      int nx = x + dx[k], ny = y + dy[k];
      if (valid(nx, ny) == false) continue;
      if (grid[nx][ny] == '@') return moves + 1;
      decode(x, y, e);
      grid[sbody[len - 1][0]][sbody[len - 1][1]] = '.';
      if (grid[nx][ny] != '.') {
        grid[sbody[len - 1][0]][sbody[len - 1][1]] = '0' + len;
        encode(x, y);
        continue;
      }
      char t = '1';
      grid[nx][ny] = t++;
      for (int j = 0; j + 1 < len; j++) grid[sbody[j][0]][sbody[j][1]] = t++;
      int ne = encode(nx, ny);
      tuple<int, int, int> state = make_tuple(nx, ny, ne);
      if (vis.count(state) != 0) continue;
      vis.insert(state);
      q.push(make_tuple(nx, ny, ne, moves + 1));
    }
  }
  return -1;
}
int main() {
  scanf("%d %d", &N, &M);
  for (int i = 0; i < N; i++) {
    string s;
    cin >> s;
    for (int j = 0; j < M; j++) grid[i][j] = s[j];
  }
  int sx = -1, sy = -1;
  for (int i = 0; i < N; i++)
    for (int j = 0; j < M; j++)
      if (grid[i][j] >= '1' && grid[i][j] <= '9') {
        if (grid[i][j] == '1') {
          sx = i;
          sy = j;
        }
        len = max(len, grid[i][j] - '0');
      }
  cout << bfs(sx, sy, encode(sx, sy)) << endl;
  return 0;
}
