#include <bits/stdc++.h>
const int N = 1010;
inline int min(int a, int b) { return a < b ? a : b; }
struct ps {
  ps *n, *to[4];
  int art[3];
  bool ava, city, in;
  ps() {
    memset(this, 0, sizeof(ps));
    memset(art, 0x27, sizeof(art));
  }
  bool upd(int *nart) {
    bool re = false;
    if (!ava) return false;
    for (int i = 0; i < 3; i++)
      if (art[i] > nart[i] + !city) re = true, art[i] = nart[i] + !city;
    return re;
  }
} p[N][N];
int main() {
  int n, m, ans = 0x27272727;
  ps *e = p[0];
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) {
    char st[N];
    scanf("%s", st + 1);
    for (int j = 1; j <= m; j++) {
      p[i][j].to[0] = p[i - 1] + j;
      p[i][j].to[1] = p[i + 1] + j;
      p[i][j].to[2] = p[i] + j + 1;
      p[i][j].to[3] = p[i] + j - 1;
      if (st[j] == '#') continue;
      p[i][j].ava = true;
      if (st[j] == '.') continue;
      p[i][j].city = true;
      p[i][j].art[st[j] - '1'] = 0;
      e = e->n = p[i] + j, e->n = 0, e->in = true;
    }
  }
  for (ps *s = p[0][0].n; s; s = s->n) {
    for (int i = 0; i < 4; i++) {
      if (!s->to[i]->upd(s->art)) continue;
      if (s->to[i]->in) continue;
      s->to[i]->in = true;
      if (s->to[i]->city)
        s->to[i]->n = s->n, s->n = s->to[i];
      else
        e = e->n = s->to[i], e->n = 0;
    }
    s->in = false;
  }
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      if (p[i][j].city)
        ans = min(ans, p[i][j].art[0] + p[i][j].art[1] + p[i][j].art[2]);
      else
        ans = min(ans, p[i][j].art[0] + p[i][j].art[1] + p[i][j].art[2] - 2);
  if (ans == 0x27272727)
    printf("-1\n");
  else
    printf("%d\n", ans);
  return 0;
}
