#include <bits/stdc++.h>
using namespace std;
int n, m;
int sz = 1;
string data[109];
struct node {
  int x, y;
  int pos;
};
bool operator<(const node& a, const node& b) {
  if (a.x == b.x) {
    if (a.y == b.y) {
      return a.pos < b.pos;
    }
    return a.y < b.y;
  }
  return a.x < b.x;
}
map<node, int> mem;
int conv(vector<int> v) {
  int ret = 0;
  for (typeof(v.begin()) it = (v.begin()); it != v.end(); it++) {
    ret = ret * 4 + (*it);
  }
  return ret;
}
vector<int> conv2(int pos) {
  vector<int> ret;
  for (long long i = 0; i < (long long)sz - 1; i++) {
    ret.push_back(pos % 4);
    pos /= 4;
  }
  reverse(ret.begin(), ret.end());
  return ret;
}
int main() {
  scanf("%d", &n);
  scanf("%d", &m);
  for (long long i = 0; i < (long long)n; i++) cin >> data[i];
  queue<node> q;
  vector<int> p;
  int x = -1, y;
  node top;
  for (long long i = 0; i < (long long)n; i++) {
    for (long long j = 0; j < (long long)m; j++) {
      if (data[i][j] == '1') {
        x = i;
        y = j;
      }
      if (data[i][j] > '1' && data[i][j] <= '9') {
        sz = max(sz, (int)(data[i][j] - '0'));
      }
    }
  }
  top.x = x;
  top.y = y;
  int xx, yy, px = x, py = y;
  for (long long i = 0; i < (long long)sz - 1; i++) {
    if (px - 1 >= 0) {
      if ((data[px - 1][py] - '1') == i + 1) {
        px--;
        p.push_back(0);
      }
    }
    if (px + 1 < n) {
      if ((data[px + 1][py] - '1') == i + 1) {
        px++;
        p.push_back(1);
      }
    }
    if (py - 1 >= 0) {
      if ((data[px][py - 1] - '1') == i + 1) {
        py--;
        p.push_back(2);
      }
    }
    if (py + 1 < m) {
      if ((data[px][py + 1] - '1') == i + 1) {
        py++;
        p.push_back(3);
      }
    }
  }
  top.pos = conv(p);
  q.push(top);
  mem[top] = 1;
  while (!q.empty()) {
    top = q.front();
    x = top.x;
    y = top.y;
    int pos = top.pos;
    int cost = mem[top];
    q.pop();
    p = conv2(pos);
    if (data[x][y] == '@') {
      cout << cost - 1 << endl;
      return 0;
    }
    px = x;
    py = y;
    if (px - 1 >= 0 && ((data[px - 1][py]) != '#')) {
      vector<int> nw;
      nw.push_back(1);
      nw.insert(nw.end(), p.begin(), p.end() - 1);
      int xx, yy;
      xx = px - 1;
      yy = py;
      node temp;
      temp.x = xx;
      temp.y = yy;
      xx = x;
      yy = y;
      int flag = 0;
      for (int i = 1; i < sz - 1; i++) {
        if (nw[i] == 0) {
          xx--;
        } else if (nw[i] == 1)
          xx++;
        else if (nw[i] == 2)
          yy--;
        else
          yy++;
        if (xx == temp.x && yy == temp.y) {
          flag = 1;
          break;
        }
      }
      if (flag == 0) {
        temp.pos = conv(nw);
        if (mem.find(temp) == mem.end()) {
          mem[temp] = cost + 1;
          q.push(temp);
        }
      }
    }
    if (px + 1 < n && ((data[px + 1][py]) != '#')) {
      vector<int> nw;
      nw.push_back(0);
      nw.insert(nw.end(), p.begin(), p.end() - 1);
      int xx, yy;
      xx = px + 1;
      yy = py;
      node temp;
      temp.x = xx;
      temp.y = yy;
      xx = x;
      yy = y;
      int flag = 0;
      for (int i = 1; i < sz - 1; i++) {
        if (nw[i] == 0) {
          xx--;
        } else if (nw[i] == 1)
          xx++;
        else if (nw[i] == 2)
          yy--;
        else
          yy++;
        if (xx == temp.x && yy == temp.y) {
          flag = 1;
          break;
        }
      }
      if (flag == 0) {
        temp.pos = conv(nw);
        if (mem.find(temp) == mem.end()) {
          mem[temp] = cost + 1;
          q.push(temp);
        }
      }
    }
    if (py - 1 >= 0 && ((data[px][py - 1]) != '#')) {
      vector<int> nw;
      nw.push_back(3);
      nw.insert(nw.end(), p.begin(), p.end() - 1);
      int xx, yy;
      xx = px;
      yy = py - 1;
      node temp;
      temp.x = xx;
      temp.y = yy;
      xx = x;
      yy = y;
      int flag = 0;
      for (int i = 1; i < sz - 1; i++) {
        if (nw[i] == 0) {
          xx--;
        } else if (nw[i] == 1)
          xx++;
        else if (nw[i] == 2)
          yy--;
        else
          yy++;
        if (xx == temp.x && yy == temp.y) {
          flag = 1;
          break;
        }
      }
      if (flag == 0) {
        temp.pos = conv(nw);
        if (mem.find(temp) == mem.end()) {
          mem[temp] = cost + 1;
          q.push(temp);
        }
      }
    }
    if (py + 1 < m && ((data[px][py + 1]) != '#')) {
      vector<int> nw;
      nw.push_back(2);
      nw.insert(nw.end(), p.begin(), p.end() - 1);
      int xx, yy;
      xx = px;
      yy = py + 1;
      node temp;
      temp.x = xx;
      temp.y = yy;
      xx = x;
      yy = y;
      int flag = 0;
      for (int i = 1; i < sz - 1; i++) {
        if (nw[i] == 0) {
          xx--;
        } else if (nw[i] == 1)
          xx++;
        else if (nw[i] == 2)
          yy--;
        else
          yy++;
        if (xx == temp.x && yy == temp.y) {
          flag = 1;
          break;
        }
      }
      if (flag == 0) {
        temp.pos = conv(nw);
        if (mem.find(temp) == mem.end()) {
          mem[temp] = cost + 1;
          q.push(temp);
        }
      }
    }
  }
  cout << -1 << endl;
}
