#include <bits/stdc++.h>
using namespace std;
const int N = 1005;
char s[N][N];
int ans[4][4];
int n, m;
struct point {
  int x, y, d;
  point(int x, int y, int d) { this->x = x, this->y = y, this->d = d; }
  friend bool operator<(point A, point B) { return A.d > B.d; }
};
int v[4][N][N];
int dx[] = {0, 0, -1, 1};
int dy[] = {-1, 1, 0, 0};
void output(int k) {
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) cout << v[k][i][j] << "\t";
    cout << endl;
  }
  cout << endl;
}
int bfs(int f, int t, int vis[N][N]) {
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) vis[i][j] = 1e8;
  priority_queue<point> q;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
      if (s[i][j] == '0' + f) {
        q.push(point(i, j, 0));
        vis[i][j] = 0;
      }
  while (!q.empty()) {
    point tp = q.top();
    q.pop();
    for (int k = 0; k < 4; k++) {
      int x = dx[k] + tp.x, y = dy[k] + tp.y;
      if (x >= 0 && x < n && y >= 0 && y < m && vis[x][y] == 1e8 &&
          s[x][y] != '#') {
        int d = tp.d + (s[x][y] == '.' ? 1 : 0);
        q.push(point(x, y, d));
        vis[x][y] = d;
      }
    }
  }
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
      if (s[i][j] == '0' + t) return vis[i][j];
}
int main() {
  cin >> n >> m;
  for (int i = 0; i < n; i++) scanf("%s", s[i]);
  for (int i = 1; i <= 3; i++)
    for (int j = 1; j <= 3; j++)
      if (i != j) ans[i][j] = bfs(i, j, v[i]);
  int MIN = 1e8;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
      MIN = min(MIN, v[1][i][j] + v[2][i][j] + v[3][i][j] +
                         (s[i][j] == '.' ? -2 : 0));
  cout << (MIN < 1e8 ? MIN : -1) << endl;
  return 0;
}
