#include <bits/stdc++.h>
using namespace std;
int n, m;
const int N = 1005;
string grid[N];
int dis[N][N][4];
int dd[4][4];
const int INF = 1e6 + 7;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
int type(int x, int y, int v) {
  if (!(0 <= x && x < n && 0 <= y && y < m)) return -1;
  if ('1' <= grid[x][y] && grid[x][y] <= '3') return grid[x][y] - '0';
  if (grid[x][y] == '.' && dis[x][y][v] == INF) return 0;
  return -1;
}
int main() {
  cin >> n >> m;
  for (int i = 0; i < n; i++) cin >> grid[i];
  for (int i = 0; i < N; i++)
    for (int j = 0; j < N; j++)
      for (int k = 1; k <= 3; k++) dis[i][j][k] = INF;
  dd[1][2] = dd[1][3] = dd[2][1] = dd[2][3] = dd[3][1] = dd[3][2] = INF;
  for (int v = 1; v <= 3; v++) {
    char c = '0' + v;
    queue<pair<int, int> > q;
    for (int i = 0; i < n; i++)
      for (int j = 0; j < m; j++)
        if (grid[i][j] == c) q.push(pair<int, int>(i, j)), dis[i][j][v] = 0;
    while (q.size()) {
      int cx = q.front().first;
      int cy = q.front().second;
      int d = dis[cx][cy][v];
      q.pop();
      for (int i = 0; i < 4; i++) {
        int nx = cx + dx[i];
        int ny = cy + dy[i];
        int t = type(nx, ny, v);
        if (t == -1) continue;
        if (t > 0)
          dd[v][t] = min(dd[v][t], 1 + d);
        else {
          q.push({nx, ny});
          dis[nx][ny][v] = 1 + d;
        }
      }
    }
  }
  int ans = INF;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
      ans = min(ans, dis[i][j][1] + dis[i][j][2] + dis[i][j][3]);
  ans = min(dd[1][1] + dd[1][2] + dd[1][3], ans);
  ans = min(dd[2][1] + dd[2][2] + dd[2][3], ans);
  ans = min(dd[3][1] + dd[3][2] + dd[3][3], ans);
  if (ans >= INF) ans = 1;
  ans -= 2;
  cout << ans << endl;
}
