#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1010;
char str[MAXN][MAXN];
bool used[MAXN][MAXN];
int n, m;
int Move[][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
int pp[4];
void gao(int id, int dis[][MAXN]) {
  queue<pair<int, int> > q;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (str[i][j] == ('0' + id)) {
        dis[i][j] = 0;
        q.push(make_pair(i, j));
      }
    }
  }
  while (!q.empty()) {
    pair<int, int> tmp = q.front();
    q.pop();
    char ss = str[tmp.first][tmp.second];
    if (ss >= '1' && ss <= '3') {
      if (pp[ss - '0'] == -1) pp[ss - '0'] = dis[tmp.first][tmp.second];
    }
    if (str[tmp.first][tmp.second] != ('0' + id) &&
        str[tmp.first][tmp.second] != '.')
      continue;
    for (int i = 0; i < 4; i++) {
      int x = tmp.first + Move[i][0];
      int y = tmp.second + Move[i][1];
      if (x < 0 || x >= n || y < 0 || y >= m) continue;
      if (dis[x][y] != -1) continue;
      if (str[x][y] == '#') continue;
      dis[x][y] = dis[tmp.first][tmp.second] + 1;
      q.push(make_pair(x, y));
    }
  }
}
int dp1[MAXN][MAXN], dp2[MAXN][MAXN], dp3[MAXN][MAXN];
void Update(int &a, int b) {
  if (b == -1) return;
  if (a == -1)
    a = b;
  else
    a = min(a, b);
}
int main() {
  while (scanf("%d%d", &n, &m) == 2) {
    int ans = -1;
    for (int i = 0; i < n; i++) scanf("%s", str[i]);
    memset(pp, -1, sizeof(pp));
    memset(dp1, -1, sizeof(dp1));
    gao(1, dp1);
    if (pp[1] != -1 && pp[2] != -1 && pp[3] != -1)
      Update(ans, pp[1] + pp[2] + pp[3] - 2);
    memset(pp, -1, sizeof(pp));
    memset(dp2, -1, sizeof(dp2));
    gao(2, dp2);
    if (pp[1] != -1 && pp[2] != -1 && pp[3] != -1)
      Update(ans, pp[1] + pp[2] + pp[3] - 2);
    memset(pp, -1, sizeof(pp));
    memset(dp3, -1, sizeof(dp3));
    gao(3, dp3);
    if (pp[1] != -1 && pp[2] != -1 && pp[3] != -1)
      Update(ans, pp[1] + pp[2] + pp[3] - 2);
    for (int i = 0; i < n; i++)
      for (int j = 0; j < m; j++) {
        if (dp1[i][j] == -1) continue;
        if (dp2[i][j] == -1) continue;
        if (dp3[i][j] == -1) continue;
        Update(ans, max(0, dp1[i][j] - 1) + max(0, dp2[i][j] - 1) +
                        max(0, dp3[i][j] - 1) + (str[i][j] == '.'));
      }
    printf("%d\n", ans);
  }
  return 0;
}
