#include <bits/stdc++.h>
using namespace std;
struct node {
  int x, y;
} a, b;
char s[1010][1010];
int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0}, i, j, n, m, cnt, x, y,
    d[4][1010][1010], c[4][4];
long long ans = INT_MAX >> 1;
queue<node> q;
void bfs(int num) {
  for (i = 1; i <= n; i++)
    for (j = 0; j < m; j++) {
      d[num][i][j] = INT_MAX >> 1;
      if (num == s[i][j] - '0') {
        d[num][i][j] = 0;
        a.x = i;
        a.y = j;
        q.push(a);
      }
    }
  while (!q.empty()) {
    for (i = 0; i < 4; i++) {
      a = q.front();
      b.x = a.x + dx[i];
      b.y = a.y + dy[i];
      if (b.x > 0 && b.x <= n && b.y >= 0 && b.y < m &&
          d[num][b.x][b.y] == INT_MAX >> 1 && s[b.x][b.y] != '#') {
        d[num][b.x][b.y] = d[num][a.x][a.y] + 1;
        if (s[b.x][b.y] > '0' && s[b.x][b.y] < '4')
          c[num][s[b.x][b.y] - '0'] =
              min(c[num][s[b.x][b.y] - '0'], d[num][b.x][b.y]);
        q.push(b);
      }
    }
    q.pop();
  }
}
int main() {
  scanf("%d%d", &n, &m);
  for (i = 1; i <= n; i++) {
    scanf("%s", &s[i]);
    while (s[i][1] == '\n') scanf("%s", &s[i]);
  }
  c[1][2] = c[1][3] = c[2][1] = c[2][3] = c[3][1] = c[3][2] = INT_MAX >> 1;
  bfs(1);
  bfs(2);
  bfs(3);
  ans = min(ans, min((long long)c[1][2] + c[1][3] - 2,
                     min((long long)c[2][1] + c[2][3] - 2,
                         (long long)c[3][1] + c[3][2] - 2)));
  for (i = 1; i <= n; i++)
    for (j = 0; j < m; j++)
      ans = min(ans, (long long)d[1][i][j] + d[2][i][j] + d[3][i][j] - 2);
  if (ans >= (INT_MAX >> 1) - 2)
    puts("-1");
  else
    printf("%d", ans);
  return 0;
}
