#include <bits/stdc++.h>
using namespace std;
int n, m, l;
bool block[20][20], vis[20][20][1 << 16];
int steps;
pair<int, int> snack[12];
typedef struct {
  int state;
  pair<int, int> head;
  int step;
} NODE;
NODE beg;
int dx[] = {-1, 0, 1, 0}, dy[] = {0, -1, 0, 1};
void SetBit(int &a, int v, int k) {
  if (v) {
    a |= (1 << k);
  } else
    a &= (~(1 << k));
}
bool IsOk(pair<int, int> s) {
  if (s.first >= 0 && s.first < n && s.second >= 0 && s.second < m) return true;
  return false;
}
bool crash(NODE u, pair<int, int> h) {
  pair<int, int> t = u.head;
  int sta = u.state;
  if (h == t) return true;
  for (int i = 0, j; i < l - 2; i++) {
    j = sta & 1;
    j += ((sta >> 1) & 1) * 2;
    t.first -= dx[j];
    t.second -= dy[j];
    if (h == t) return true;
    sta >>= 2;
  }
  return false;
}
int gs, ge;
int FindMax() {
  bool flag[22][22];
  memset(flag, 0, sizeof(flag));
  queue<NODE> q;
  NODE u, v;
  for (int i = 1; i < l; i++) {
    block[snack[i].first][snack[i].second] = true;
  }
  u.head = snack[0];
  u.step = 0;
  q.push(u);
  flag[snack[0].first][snack[0].second] = true;
  while (!q.empty()) {
    u = q.front();
    q.pop();
    if (u.head.first == gs && u.head.second == ge) {
      return u.step;
    }
    u.step++;
    for (int i = 0; i < 4; i++) {
      v = u;
      v.head.first += dx[i];
      v.head.second += dy[i];
      if (IsOk(v.head) && !block[v.head.first][v.head.second] &&
          !flag[v.head.first][v.head.second]) {
        flag[v.head.first][v.head.second] = true;
        q.push(v);
      }
    }
  }
  return 100000;
}
int F(int first) { return first >= 0 ? first : -first; }
bool bfs() {
  queue<NODE> q;
  NODE u, v;
  pair<int, int> h;
  q.push(beg);
  int up = 10000;
  for (int i = 1; i < l; i++) {
    block[snack[i].first][snack[i].second] = false;
  }
  while (!q.empty()) {
    u = q.front();
    q.pop();
    if (u.head.first == gs && u.head.second == ge) {
      steps = u.step;
      return true;
    }
    if (u.step + min(F(u.head.first - gs), F(u.head.second - ge)) > up)
      continue;
    u.step++;
    for (int i = 0; i < 4; i++) {
      h.first = u.head.first + dx[i];
      h.second = u.head.second + dy[i];
      if (IsOk(h) && !block[h.first][h.second] && !crash(u, h)) {
        v = u;
        v.head = h;
        v.state = (v.state << 2) % (1 << 16);
        SetBit(v.state, i & 1, 0);
        SetBit(v.state, (i >> 1) & 1, 1);
        if (!vis[v.head.first][v.head.second][v.state]) {
          vis[v.head.first][v.head.second][v.state] = true;
          q.push(v);
        }
      }
    }
  }
  return false;
}
char g[20][20];
int main() {
  int k, a, b, con = 1;
  scanf("%d %d", &n, &m);
  memset(block, 0, sizeof(block));
  memset(vis, 0, sizeof(vis));
  for (int i = 0; i < n; i++) scanf("%s", g[i]);
  bool ok = true;
  l = 0;
  while (ok) {
    ok = false;
    for (int i = 0; !ok && i < n; i++)
      for (int j = 0; j < m; j++) {
        if (g[i][j] - '0' == l + 1) {
          ok = true;
          snack[l].first = i;
          snack[l].second = j;
          l++;
          break;
        }
      }
  }
  beg.head = snack[0];
  beg.state = beg.step = 0;
  for (int i = 0; i < l - 1; i++) {
    for (int j = 0; j < 4; j++) {
      if (snack[i].first == snack[i + 1].first + dx[j] &&
          snack[i].second == snack[i + 1].second + dy[j]) {
        SetBit(beg.state, j & 1, 2 * i);
        SetBit(beg.state, (j >> 1) & 1, 2 * i + 1);
      }
    }
  }
  vis[beg.head.first][beg.head.second][beg.state] = true;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (g[i][j] == '#') {
        block[i][j] = true;
      } else if (g[i][j] == '@') {
        gs = i;
        ge = j;
      }
    }
  }
  if (bfs()) {
    printf("%d\n", steps);
  } else
    printf("-1\n");
  return 0;
}
