#include <bits/stdc++.h>
using namespace std;
map<int, bool> v;
int num, N, M;
bool vis[99][99];
char s[22][22];
bool valid() {
  bool flag = 1;
  int n = num;
  int r = 50, c = 50;
  vis[50][50] = 1;
  while (n) {
    if (n % 10 == 1) r--;
    if (n % 10 == 2) c++;
    if (n % 10 == 3) r++;
    if (n % 10 == 4) c--;
    if (vis[r][c]) flag = 0;
    vis[r][c] = 1;
    n /= 10;
  }
  n = num;
  vis[50][50] = 0;
  r = 50, c = 50;
  while (n) {
    if (n % 10 == 1) r--;
    if (n % 10 == 2) c++;
    if (n % 10 == 3) r++;
    if (n % 10 == 4) c--;
    vis[r][c] = 0;
    n /= 10;
  }
  return flag;
}
void generate4(int ind) {
  if (valid() && num) {
    v[num] = 1;
  }
  if (ind == 8) return;
  for (int i = 1; i < 5; i++) {
    num *= 10;
    num += i;
    generate4(ind + 1);
    num /= 10;
  }
}
class node {
 public:
  int r, c, format, cost;
};
int first;
void get(int r, int c, int n) {
  if (r + 1 < N && s[r + 1][c] - '0' == n + 1) {
    first *= 10;
    first += 3;
    get(r + 1, c, n + 1);
  }
  if (r - 1 >= 0 && s[r - 1][c] - '0' == n + 1) {
    first *= 10;
    first += 1;
    get(r - 1, c, n + 1);
  }
  if (c + 1 < M && s[r][c + 1] - '0' == n + 1) {
    first *= 10;
    first += 2;
    get(r, c + 1, n + 1);
  }
  if (c - 1 >= 0 && s[r][c - 1] - '0' == n + 1) {
    first *= 10;
    first += 4;
    get(r, c - 1, n + 1);
  }
}
int dx[] = {1, 0, -1, 0};
int dy[] = {0, -1, 0, 1};
bool check(node t) {
  if (t.r < 0 || t.c < 0 || t.r >= N || t.c >= M || s[t.r][t.c] == '#')
    return 0;
  num = t.format;
  return valid();
}
bool VIS[15][15][65539];
int base10(int x) {
  int k = 1, ret = 0;
  while (x) {
    ret += k * (x % 10 - 1);
    k *= 4;
    x /= 10;
  }
  return ret;
}
int main() {
  queue<node> q;
  num = 0;
  generate4(0);
  scanf("%d %d", &N, &M);
  for (int i = 0; i < N; i++) scanf("%s", s[i]);
  node t, cur;
  int ar, ac;
  int maxi = 0;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < M; j++) {
      if (s[i][j] == '1') {
        first = 0;
        get(i, j, 1);
        t.format = first;
        t.r = i;
        t.c = j;
        t.cost = 0;
        q.push(t);
      }
      if (s[i][j] == '@') {
        ar = i;
        ac = j;
      }
      if (isdigit(s[i][j])) {
        maxi = max(maxi, s[i][j] - '0');
      }
    }
  }
  int len = 1;
  for (int i = 0; i < maxi - 2; i++) len *= 10;
  bool FOUND = 0;
  while (!q.empty()) {
    cur = q.front();
    q.pop();
    int b = base10(cur.format);
    if (VIS[cur.r][cur.c][b]) continue;
    VIS[cur.r][cur.c][b] = 1;
    if (cur.r == ar && cur.c == ac) {
      printf("%d\n", cur.cost);
      FOUND = 1;
      break;
    }
    int nw = 0;
    for (int i = 0; i < 4; i++) {
      nw++;
      t.r = cur.r + dx[i];
      t.c = cur.c + dy[i];
      t.cost = cur.cost + 1;
      t.format = cur.format / 10 + nw * len;
      if (check(t)) q.push(t);
    }
  }
  if (!FOUND) printf("-1\n");
}
