#include <bits/stdc++.h>
using namespace std;
struct cell {
  int x, y, cos;
  bool operator<(const cell &e) const { return cos > e.cos; }
};
const int NMAX = 1005;
const int LIMIT = 2005;
int n, m, dp[5][NMAX][NMAX];
char s[NMAX][NMAX];
priority_queue<cell> Q;
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
bool Interior(int x, int y) {
  if (x >= 1 && x <= n && y >= 1 && y <= m) return 1;
  return 0;
}
void Go(int val) {
  int i, kx, ky, cst;
  cell aux, kkt;
  while (!Q.empty()) {
    aux = Q.top();
    Q.pop();
    if (aux.cos == dp[val][aux.x][aux.y])
      for (i = 0; i < 4; i++) {
        kx = aux.x + dx[i];
        ky = aux.y + dy[i];
        cst = aux.cos;
        if (s[kx][ky] == '.') cst++;
        if (Interior(kx, ky) && s[kx][ky] != '#' && dp[val][kx][ky] > cst) {
          dp[val][kx][ky] = cst;
          kkt.x = kx;
          kkt.y = ky;
          kkt.cos = cst;
          Q.push(kkt);
        }
      }
  }
}
int main() {
  int i, j, l, k, sol, cnt;
  cell kkt;
  cin.sync_with_stdio(false);
  cin >> n >> m;
  for (i = 1; i <= n; i++) cin >> (s[i] + 1);
  for (k = 1; k <= 3; k++) {
    for (i = 1; i <= n; i++)
      for (j = 1; j <= m; j++) {
        dp[k][i][j] = 1 << 20;
        if (s[i][j] == ('0' + k)) {
          dp[k][i][j] = 0;
          kkt.x = i;
          kkt.y = j;
          kkt.cos = 0;
          Q.push(kkt);
        }
      }
    Go(k);
  }
  sol = 1 << 20;
  for (i = 1; i <= n; i++)
    for (j = 1; j <= m; j++)
      if (s[i][j] != '#') {
        if (s[i][j] == '.')
          cnt = 2;
        else
          cnt = 0;
        sol = min(sol, dp[1][i][j] + dp[2][i][j] + dp[3][i][j] - cnt);
      }
  if (sol == (1 << 20)) {
    cout << "-1\n";
    return 0;
  }
  cout << sol << "\n";
  return 0;
}
