#include <bits/stdc++.h>
using namespace std;
int const LIM = 1001;
int const INF = 1e9;
int const dx[] = {0, 0, 1, -1};
int const dy[] = {1, -1, 0, 0};
struct point_t {
  int x, y;
  bool operator>(point_t const &p) const {
    return x > p.x || (x == p.x && y > p.y);
  }
  bool operator<(point_t const &p) const {
    return x < p.x || (x == p.x && y < p.y);
  }
};
int n, m, sx[3], sy[3];
int dist[LIM][LIM][3], cnt[3][3];
string g[LIM];
int main() {
  ios_base::sync_with_stdio(false);
  cin >> n >> m;
  for (int i = 0; i < n; ++i) cin >> g[i];
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      if (g[i][j] == '1' || g[i][j] == '2' || g[i][j] == '3') {
        sx[g[i][j] - '1'] = i;
        sy[g[i][j] - '1'] = j;
      }
    }
  }
  for (int i = 0; i < 3; ++i)
    for (int j = 0; j < 3; ++j) cnt[i][j] = INF;
  for (int c = 0; c < 3; ++c) {
    for (int i = 0; i < n; ++i)
      for (int j = 0; j < m; ++j) dist[i][j][c] = INF;
    dist[sx[c]][sy[c]][c] = 0;
    priority_queue<pair<int, point_t>, vector<pair<int, point_t>>,
                   greater<pair<int, point_t>>>
        q;
    q.push(make_pair(0, point_t{sx[c], sy[c]}));
    while (!q.empty()) {
      int count = q.top().first;
      point_t p = q.top().second;
      q.pop();
      if (dist[p.x][p.y][c] < count) continue;
      for (int i = 0; i < 4; i++) {
        int x1 = p.x + dx[i];
        int y1 = p.y + dy[i];
        if (x1 < 0 || x1 >= n || y1 < 0 || y1 >= m) continue;
        if (g[x1][y1] == '#') continue;
        int new_count = dist[p.x][p.y][c];
        if (g[x1][y1] == '.') ++new_count;
        if (new_count < dist[x1][y1][c]) {
          dist[x1][y1][c] = new_count;
          q.push(make_pair(dist[x1][y1][c], point_t{x1, y1}));
        }
      }
    }
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < m; ++j) {
        if (g[i][j] == '1' || g[i][j] == '2' || g[i][j] == '3') {
          int c1 = g[i][j] - '1';
          if (cnt[c][c1] == INF || cnt[c][c1] > dist[i][j][c]) {
            cnt[c][c1] = dist[i][j][c];
          }
        }
      }
    }
  }
  for (int i = 0; i < 3; ++i) {
    for (int j = 0; j < 3; ++j) {
      if (cnt[i][j] == INF) {
        cout << -1 << endl;
        return 0;
      }
    }
  }
  int answer = cnt[0][1] + cnt[0][2];
  answer = min(answer, cnt[1][0] + cnt[1][2]);
  answer = min(answer, cnt[2][0] + cnt[2][1]);
  answer = min(answer, cnt[0][1] + cnt[1][2]);
  answer = min(answer, cnt[0][2] + cnt[2][1]);
  answer = min(answer, cnt[2][1] + cnt[1][0]);
  answer = min(answer, cnt[2][0] + cnt[0][1]);
  answer = min(answer, cnt[1][0] + cnt[0][2]);
  answer = min(answer, cnt[1][2] + cnt[2][0]);
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      if (g[i][j] == '.' && dist[i][j][0] != INF && dist[i][j][1] != INF &&
          dist[i][j][2] != INF) {
        answer = min(answer, dist[i][j][0] + dist[i][j][1] + dist[i][j][2] - 2);
      }
    }
  }
  cout << answer << endl;
  return 0;
}
