#include <bits/stdc++.h>
using namespace std;
long long x, y, l, i, j, n, k, k1, k2, k3, m, fldgjdflgjhrthrl,
    fldggfhfghjdflgjl, fldgjdflgrtyrtyjl, ffgfldgjdflgjl, r, z, max1, tx, pnt,
    flag;
vector<long long> divisors, ans;
long long min_path[5][5];
string s;
long long a[105];
char c[1005][1005];
long long d1[1005][1005], d2[1005][1005], d3[1005][1005], used[1005][1005];
vector<pair<long long, long long> > f;
int main() {
  cin >> n >> m;
  for (i = 1; i <= n; i++)
    for (j = 1; j <= m; j++) cin >> c[i][j];
  for (i = 0; i <= n + 1; i++)
    for (j = 0; j <= m + 1; j++) used[i][j] = 1;
  for (i = 1; i <= n; i++)
    for (j = 1; j <= m; j++) used[i][j] = 0;
  for (i = 1; i <= n; i++)
    for (j = 1; j <= m; j++) {
      if (c[i][j] == '1') {
        f.push_back(make_pair(i, j));
        used[i][j] = 1;
        d1[i][j] = 0;
      } else
        d1[i][j] = ((long long)1e+9);
      if (c[i][j] == '#') used[i][j] = 1;
    }
  i = 0;
  while (i < f.size()) {
    long long x = f[i].first;
    long long y = f[i].second;
    i++;
    long long pos[4][2] = {{1, 0}, {-1, 0}, {0, -1}, {0, 1}};
    for (j = 0; j < 4; j++)
      if (!used[x + pos[j][0]][y + pos[j][1]]) {
        used[x + pos[j][0]][y + pos[j][1]] = 1;
        d1[x + pos[j][0]][y + pos[j][1]] = d1[x][y] + 1;
        f.push_back(make_pair(x + pos[j][0], y + pos[j][1]));
      }
  }
  f.clear();
  for (i = 1; i <= n; i++)
    for (j = 1; j <= m; j++) used[i][j] = 0;
  for (i = 1; i <= n; i++)
    for (j = 1; j <= m; j++) {
      if (c[i][j] == '2') {
        f.push_back(make_pair(i, j));
        used[i][j] = 1;
        d2[i][j] = 0;
      } else
        d2[i][j] = ((long long)1e+9);
      if (c[i][j] == '#') used[i][j] = 1;
    }
  i = 0;
  while (i < f.size()) {
    long long x = f[i].first;
    long long y = f[i].second;
    i++;
    long long pos[4][2] = {{1, 0}, {-1, 0}, {0, -1}, {0, 1}};
    for (j = 0; j < 4; j++)
      if (!used[x + pos[j][0]][y + pos[j][1]]) {
        used[x + pos[j][0]][y + pos[j][1]] = 1;
        d2[x + pos[j][0]][y + pos[j][1]] = d2[x][y] + 1;
        f.push_back(make_pair(x + pos[j][0], y + pos[j][1]));
      }
  }
  f.clear();
  for (i = 1; i <= n; i++)
    for (j = 1; j <= m; j++) used[i][j] = 0;
  for (i = 1; i <= n; i++)
    for (j = 1; j <= m; j++) {
      if (c[i][j] == '3') {
        f.push_back(make_pair(i, j));
        used[i][j] = 1;
        d3[i][j] = 0;
      } else
        d3[i][j] = ((long long)1e+9);
      if (c[i][j] == '#') used[i][j] = 1;
    }
  i = 0;
  while (i < f.size()) {
    long long x = f[i].first;
    long long y = f[i].second;
    i++;
    long long pos[4][2] = {{1, 0}, {-1, 0}, {0, -1}, {0, 1}};
    for (j = 0; j < 4; j++)
      if (!used[x + pos[j][0]][y + pos[j][1]]) {
        used[x + pos[j][0]][y + pos[j][1]] = 1;
        d3[x + pos[j][0]][y + pos[j][1]] = d3[x][y] + 1;
        f.push_back(make_pair(x + pos[j][0], y + pos[j][1]));
      }
  }
  f.clear();
  min_path[1][2] = min_path[1][3] = min_path[2][3] = ((long long)1e+9);
  for (i = 1; i <= n; i++)
    for (j = 1; j <= m; j++) {
      if (c[i][j] == '1') {
        min_path[1][3] = min(min_path[1][3], d3[i][j]);
        min_path[1][2] = min(min_path[1][2], d2[i][j]);
      }
      if (c[i][j] == '2') {
        min_path[2][3] = min(min_path[2][3], d3[i][j]);
        min_path[1][2] = min(min_path[1][2], d1[i][j]);
      }
      if (c[i][j] == '3') {
        min_path[1][3] = min(min_path[1][3], d1[i][j]);
        min_path[2][3] = min(min_path[2][3], d2[i][j]);
      }
    }
  long long ans = ((long long)1e+9);
  ans = min(ans, min_path[1][2] + min_path[2][3]);
  ans = min(ans, min_path[1][3] + min_path[2][3]);
  ans = min(ans, min_path[1][2] + min_path[1][3]);
  ans -= 2;
  for (i = 1; i <= n; i++)
    for (j = 1; j <= m; j++) ans = min(ans, d1[i][j] + d2[i][j] + d3[i][j] - 2);
  if (ans > 1005000)
    cout << -1 << endl;
  else
    cout << ans << endl;
  return 0;
}
