#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1007;
const int oo = 1e9 + 7;
int dir[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
char G[MAXN][MAXN];
struct node {
  int step[3];
} a[MAXN][MAXN];
struct point {
  int x, y;
};
void BFS(int M, int N, int k) {
  queue<point> Q;
  point q, s;
  for (int i = 0; i < M; i++)
    for (int j = 0; j < N; j++) {
      if (G[i][j] == k + '1') {
        q.x = i, q.y = j;
        a[i][j].step[k] = 0;
        Q.push(q);
      }
    }
  while (Q.size()) {
    q = Q.front();
    Q.pop();
    for (int i = 0; i < 4; i++) {
      s = q;
      s.x += dir[i][0];
      s.y += dir[i][1];
      if (s.x >= 0 && s.x < M && s.y >= 0 && s.y < N && G[s.x][s.y] != '#') {
        int t = (G[s.x][s.y] == '.' ? 1 : 0);
        if (a[s.x][s.y].step[k] == -1 ||
            a[q.x][q.y].step[k] + t < a[s.x][s.y].step[k]) {
          a[s.x][s.y].step[k] = a[q.x][q.y].step[k] + t;
          Q.push(s);
        }
      }
    }
  }
}
int main() {
  int M, N;
  scanf("%d%d", &M, &N);
  for (int i = 0; i < M; i++) scanf("%s", G[i]);
  memset(a, -1, sizeof(a));
  for (int i = 0; i < 3; i++) BFS(M, N, i);
  int ans = oo;
  for (int i = 0; i < M; i++)
    for (int j = 0; j < N; j++) {
      if (a[i][j].step[0] != -1 && a[i][j].step[1] != -1 &&
          a[i][j].step[2] != -1) {
        int t = (G[i][j] == '.' ? 1 : 0);
        ans = min(ans,
                  a[i][j].step[0] + a[i][j].step[1] + a[i][j].step[2] - t * 2);
      }
    }
  if (ans == oo) ans = -1;
  printf("%d\n", ans);
  return 0;
}
