#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using P = pair<int, int>;
constexpr ld EPS = 1e-12;
constexpr int INF = numeric_limits<int>::max() / 2;
constexpr int MOD = 1e9 + 7;
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int n, m;
  cin >> n >> m;
  vector<string> s(n);
  vector<vector<ll>> d1(n, vector<ll>(m, INF));
  vector<vector<ll>> d2(n, vector<ll>(m, INF));
  vector<vector<ll>> d3(n, vector<ll>(m, INF));
  vector<vector<ll>> dist(4, vector<ll>(4, INF));
  queue<P> q1, q2, q3;
  for (int i = 0; i < n; i++) {
    cin >> s[i];
    for (int j = 0; j < m; j++) {
      if (s[i][j] == '1') {
        d1[i][j] = 0;
        q1.push(P(i, j));
      } else if (s[i][j] == '2') {
        d2[i][j] = 0;
        q2.push(P(i, j));
      } else if (s[i][j] == '3') {
        d3[i][j] = 0;
        q3.push(P(i, j));
      }
    }
  }
  while (!q1.empty()) {
    P p = q1.front();
    q1.pop();
    int x = p.first, y = p.second;
    for (int i = 0; i < 4; i++) {
      int nx = x + dx[i], ny = y + dy[i];
      if (nx < 0 || n <= nx || ny < 0 || m <= ny) continue;
      if (d1[nx][ny] != INF) continue;
      if (s[nx][ny] == '#') continue;
      if (s[nx][ny] == '.') {
        d1[nx][ny] = d1[x][y] + 1;
        q1.push(P(nx, ny));
      } else if (s[nx][ny] == '2') {
        dist[1][2] = min(dist[1][2], d1[x][y]);
      } else if (s[nx][ny] == '3') {
        dist[1][3] = min(dist[1][3], d1[x][y]);
      }
    }
  }
  while (!q2.empty()) {
    P p = q2.front();
    q2.pop();
    int x = p.first, y = p.second;
    for (int i = 0; i < 4; i++) {
      int nx = x + dx[i], ny = y + dy[i];
      if (nx < 0 || n <= nx || ny < 0 || m <= ny) continue;
      if (d2[nx][ny] != INF) continue;
      if (s[nx][ny] == '#') continue;
      if (s[nx][ny] == '.') {
        d2[nx][ny] = d2[x][y] + 1;
        q2.push(P(nx, ny));
      } else if (s[nx][ny] == '1') {
        dist[2][1] = min(dist[2][1], d2[x][y]);
      } else if (s[nx][ny] == '3') {
        dist[2][3] = min(dist[2][3], d2[x][y]);
      }
    }
  }
  while (!q3.empty()) {
    P p = q3.front();
    q3.pop();
    int x = p.first, y = p.second;
    for (int i = 0; i < 4; i++) {
      int nx = x + dx[i], ny = y + dy[i];
      if (nx < 0 || n <= nx || ny < 0 || m <= ny) continue;
      if (d3[nx][ny] != INF) continue;
      if (s[nx][ny] == '#') continue;
      if (s[nx][ny] == '.') {
        d3[nx][ny] = d3[x][y] + 1;
        q3.push(P(nx, ny));
      } else if (s[nx][ny] == '1') {
        dist[3][1] = min(dist[3][1], d3[x][y]);
      } else if (s[nx][ny] == '2') {
        dist[3][2] = min(dist[3][2], d3[x][y]);
      }
    }
  }
  ll res = INF;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      res = min(res, d1[i][j] + d2[i][j] + d3[i][j] - 2);
    }
  }
  res = min(res, dist[1][2] + dist[2][3]);
  res = min(res, dist[1][2] + dist[1][3]);
  res = min(res, dist[1][3] + dist[2][3]);
  if (res == INF)
    cout << -1 << endl;
  else
    cout << res << endl;
}
