#include <bits/stdc++.h>
using namespace std;
const int maxw = 15;
char table[maxw][maxw + 1];
const int maxn = (int)1e6, maxlen = 9;
int maxv;
pair<int, int> poss[maxn][maxlen];
pair<int, int> tmp[maxlen];
int h, w;
int len;
const int go[4][2] = {{-1, 0}, {0, -1}, {0, 1}, {1, 0}};
inline bool ok(int y, int x) { return y >= 0 && x >= 0 && y < h && x < w; }
void precalc(int it, int y, int x) {
  if (it == len) {
    assert(maxv < maxn);
    memcpy(poss[maxv], tmp, sizeof(tmp));
    maxv++;
    return;
  }
  for (int g = 0; g < 4; g++) {
    int yn = y + go[g][0], xn = x + go[g][1];
    if (!ok(yn, xn)) continue;
    if (table[yn][xn] == '#') continue;
    tmp[it] = make_pair(yn, xn);
    bool fail = 0;
    for (int i = 0; i < it; i++) {
      if (tmp[it] == tmp[i]) {
        fail = 1;
        break;
      }
    }
    if (fail) continue;
    precalc(it + 1, yn, xn);
  }
}
bool compare(pair<int, int> *a, pair<int, int> *b) {
  for (int i = 0; i < len; i++)
    if (a[i] != b[i]) return a[i] < b[i];
  return 0;
}
int find(pair<int, int> *cur) {
  int l = 0, r = maxv;
  while (l + 1 < r) {
    int m = (l + r) / 2;
    if (compare(cur, poss[m]))
      r = m;
    else
      l = m;
  }
  return l;
}
void prec() {
  maxv = 0;
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++) {
      if (table[i][j] == '#') continue;
      tmp[0] = make_pair(i, j);
      precalc(1, i, j);
    }
}
int dist[maxn];
int st[maxn];
int main() {
  while (scanf("%d%d", &h, &w) >= 1) {
    len = 0;
    for (int i = 0; i < h; i++) {
      scanf("%s", table[i]);
      for (int j = 0; j < w; j++)
        len += (table[i][j] >= '1' && table[i][j] <= '9');
    }
    prec();
    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++)
        if (table[i][j] >= '1' && table[i][j] <= '9') {
          tmp[table[i][j] - '1'] = make_pair(i, j);
        }
    for (int i = 0; i < maxv; i++) dist[i] = ((int)1E9);
    st[0] = find(tmp);
    dist[st[0]] = 0;
    int ans = ((int)1E9);
    for (int l = 0, r = 1; l < r; l++) {
      int v = st[l];
      if (table[poss[v][0].first][poss[v][0].second] == '@')
        ans = min(ans, dist[v]);
      for (int g = 0; g < 4; g++) {
        int yn = poss[v][0].first + go[g][0], xn = poss[v][0].second + go[g][1];
        if (!ok(yn, xn) || table[yn][xn] == '#') continue;
        bool fail = 0;
        for (int i = 0; i < len - 1; i++)
          if (poss[v][i].first == yn && poss[v][i].second == xn) {
            fail = 1;
            break;
          }
        if (fail) continue;
        memcpy(tmp + 1, poss[v], sizeof(tmp[0]) * (len - 1));
        tmp[0] = make_pair(yn, xn);
        int u = find(tmp);
        if (dist[u] <= dist[v] + 1) continue;
        dist[u] = dist[v] + 1;
        st[r++] = u;
      }
    }
    if (ans == ((int)1E9)) ans = -1;
    printf("%d\n", ans);
  }
  return 0;
}
