#include <bits/stdc++.h>
using namespace std;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
char E[1005][1005];
int N, M;
struct Node {
  int step[3];
} s[1005][1005];
struct use {
  int x, y;
};
void bfs(int x) {
  queue<use> que;
  use u, v;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < M; j++) {
      if (E[i][j] == x + '1') {
        u.x = i, u.y = j;
        s[i][j].step[x] = 0;
        que.push(u);
      }
    }
  }
  while (!que.empty()) {
    u = que.front();
    que.pop();
    for (int i = 0; i < 4; i++) {
      v = u;
      v.x += dx[i];
      v.y += dy[i];
      if (v.x >= 0 && v.x < N && v.y >= 0 && v.y < M && E[v.x][v.y] != '#') {
        int t;
        if (E[v.x][v.y] == '.')
          t = 1;
        else
          t = 0;
        if (s[v.x][v.y].step[x] == -1 ||
            s[u.x][u.y].step[x] + t < s[v.x][v.y].step[x]) {
          s[v.x][v.y].step[x] = s[u.x][u.y].step[x] + t;
          que.push(v);
        }
      }
    }
  }
}
int main() {
  scanf("%d %d", &N, &M);
  for (int i = 0; i < N; i++) scanf("%s", E[i]);
  memset(s, -1, sizeof(s));
  for (int i = 0; i < 3; i++) bfs(i);
  int ans = 1 << 30;
  for (int i = 0; i < N; i++)
    for (int j = 0; j < M; j++) {
      if (s[i][j].step[0] != -1 && s[i][j].step[1] != -1 &&
          s[i][j].step[2] != -1) {
        int t;
        if (E[i][j] == '.')
          t = 1;
        else
          t = 0;
        ans = min(ans,
                  s[i][j].step[0] + s[i][j].step[1] + s[i][j].step[2] - t * 2);
      }
    }
  if (ans == 1 << 30) {
    puts("-1");
    exit(0);
  }
  printf("%d\n", ans);
  return 0;
}
