#include <bits/stdc++.h>
using namespace std;
int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
int lcm(int a, int b) { return a * (b / gcd(a, b)); }
int n, m, temp[1010][1010], level[3][1000010], dist1, dist2, dist3;
char matrix[1010][1010];
set<int> graph[1000010];
vector<int> label(1000010, -1);
queue<int> Q;
void bfs(int u) {
  Q.push(u);
  label[u] = 0;
  level[u - 1][u] = 0;
  while (!Q.empty()) {
    int v = Q.front();
    Q.pop();
    for (set<int>::iterator it = graph[v].begin(); it != graph[v].end(); it++) {
      if (label[*it] == -1) {
        Q.push(*it);
        level[u - 1][*it] = level[u - 1][v] + 1;
        label[*it] = 0;
      }
    }
    label[v] = 1;
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  int result = INT_MAX, pos = 4;
  cin >> n >> m;
  for (int i = 0; i < n; i++) cin >> matrix[i];
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (matrix[i][j] == '.') temp[i][j] = pos++;
      if (matrix[i][j] == '1') temp[i][j] = 1;
      if (matrix[i][j] == '2') temp[i][j] = 2;
      if (matrix[i][j] == '3') temp[i][j] = 3;
      if (matrix[i][j] == '#') temp[i][j] = -1;
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (temp[i][j] != -1) {
        if (i - 1 >= 0) {
          if (temp[i - 1][j] != -1 && temp[i - 1][j] != temp[i][j])
            graph[temp[i][j]].insert(temp[i - 1][j]);
        }
        if (i + 1 < n) {
          if (temp[i + 1][j] != -1 && temp[i + 1][j] != temp[i][j])
            graph[temp[i][j]].insert(temp[i + 1][j]);
        }
        if (j - 1 >= 0) {
          if (temp[i][j - 1] != -1 && temp[i][j - 1] != temp[i][j])
            graph[temp[i][j]].insert(temp[i][j - 1]);
        }
        if (j + 1 < m) {
          if (temp[i][j + 1] != -1 && temp[i][j + 1] != temp[i][j])
            graph[temp[i][j]].insert(temp[i][j + 1]);
        }
      }
    }
  }
  bfs(1);
  if (label[2] == -1 || label[3] == -1) {
    cout << "-1";
    return 0;
  }
  label.assign(pos + 1, -1);
  bfs(2);
  label.assign(pos + 1, -1);
  bfs(3);
  for (int i = 4; i < pos; i++) {
    if (label[i] != -1)
      result = min(result, level[0][i] - 1 + level[1][i] - 1 + level[2][i]);
  }
  result = min(result, level[1][1] - 1 + level[2][1] - 1);
  result = min(result, level[0][2] - 1 + level[2][2] - 1);
  result = min(result, level[0][3] - 1 + level[1][3] - 1);
  cout << result;
  return 0;
}
