#include <bits/stdc++.h>
using namespace std;
int nextint() {
  int t;
  if (scanf("%d", &t) != 1) exit(0);
  return t;
}
const int MAXT = 5000;
char mp[15][15];
int n, m, len;
int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1}, dist[(1 << 16)][15][15],
    used[15][15];
bool isgood(int cx, int cy) { return 0 <= cx && cx < n && 0 <= cy && cy < m; }
int getmask(int cx, int cy, char seek) {
  for (int i = 0; i < 4; i++) {
    if (isgood(cx + dx[i], cy + dy[i]) && mp[cx + dx[i]][cy + dy[i]] == seek)
      return (getmask(cx + dx[i], cy + dy[i], seek + 1) << 2) | i;
  }
  return 0;
}
int trim(int mask) { return mask & ((1 << (2 * len - 2)) - 1); }
void unwrap(int tmpi, int tmpj, int tmask, int place) {
  for (int i = 0; i < len - 1; i++) {
    int j = tmask & 3;
    tmask >>= 2;
    tmpi += dx[j];
    tmpj += dy[j];
    used[tmpi][tmpj] = place;
  }
}
int main() {
  n = nextint(), m = nextint();
  for (int i = 0; i < n; i++) scanf("%s", mp[i]);
  int ti, tj, si, sj;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) {
      if (mp[i][j] == '@')
        ti = i, tj = j;
      else if (mp[i][j] == '1')
        si = i, sj = j;
      if (isdigit(mp[i][j])) len = max(len, mp[i][j] - '1');
    }
  int smask = trim(getmask(si, sj, '2'));
  queue<int> q;
  q.push(smask), q.push(si), q.push(sj);
  dist[smask][si][sj] = 1;
  while (!q.empty()) {
    int cmask = q.front();
    q.pop();
    int ci = q.front();
    q.pop();
    int cj = q.front();
    q.pop();
    unwrap(ci, cj, cmask, 1);
    if (ci == ti && cj == tj) {
      printf("%d\n", dist[cmask][ci][cj] - 1);
      return 0;
    }
    for (int i = 0; i < 4; i++) {
      int nmask = trim(cmask << 2 | (i ^ 1));
      int ni = ci + dx[i];
      int nj = cj + dy[i];
      if (isgood(ni, nj) && !used[ni][nj] && mp[ni][nj] != '#') {
        if (dist[nmask][ni][nj] == 0) {
          dist[nmask][ni][nj] = dist[cmask][ci][cj] + 1;
          q.push(nmask), q.push(ni), q.push(nj);
        }
      }
    }
    unwrap(ci, cj, cmask, 0);
  }
  puts("-1");
  return 0;
}
