#include <bits/stdc++.h>
using namespace std;
void task();
int main() {
  srand(time(0));
  task();
  return 0;
}
const int INF = 0x3f3f3f3f;
const int N = 1e3 + 10;
const int M = 1e5 + 10;
int n, m;
char a[N][N];
int dist[4][N][N];
const int di[4] = {0, 0, -1, 1};
const int dj[4] = {1, -1, 0, 0};
int dd[4][4];
int ok(int i, int j) { return i >= 0 && i < n && j >= 0 && j < m; }
void bfs(int id) {
  queue<pair<int, pair<int, int>>> q;
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < m; ++j)
      if (a[i][j] - '0' == id) {
        q.push(pair<int, pair<int, int>>{0, pair<int, int>{i, j}});
        dist[id][i][j] = 0;
      }
  while (!q.empty()) {
    int d = q.front().first;
    int i = q.front().second.first;
    int j = q.front().second.second;
    q.pop();
    if (a[i][j] >= '1' && a[i][j] <= '3')
      dd[id][a[i][j] - '0'] = min(dist[id][i][j], dd[id][a[i][j] - '0']);
    if (dist[id][i][j] != d) continue;
    for (int h = 0; h < 4; ++h) {
      int ii = i + di[h];
      int jj = j + dj[h];
      if (ok(ii, jj) && a[ii][jj] != '#' && d + 1 < dist[id][ii][jj]) {
        dist[id][ii][jj] = d + 1;
        q.push(pair<int, pair<int, int>>{d + 1, pair<int, int>{ii, jj}});
      }
    }
  }
}
void task() {
  scanf("%d %d", &n, &m);
  for (int i = 0; i < n; ++i) scanf("%s", a[i]);
  memset(dist, 0x3f, sizeof(dist));
  memset(dd, 0x3f, sizeof(dd));
  bfs(1);
  bfs(2);
  bfs(3);
  for (int i = 1; i < 4; ++i)
    for (int j = 1; j < 4; ++j) {
      if (dd[i][j] == INF) {
        cout << -1;
        return;
      }
    }
  int ans = INF;
  ans = min(ans, dd[1][2] + dd[1][3] - 2);
  ans = min(ans, dd[2][1] + dd[2][3] - 2);
  ans = min(ans, dd[3][1] + dd[3][2] - 2);
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < m; ++j)
      if (dist[1][i][j] != INF && dist[2][i][j] != INF && dist[3][i][j] != INF)
        ans = min(ans, dist[1][i][j] + dist[2][i][j] + dist[3][i][j] - 2);
  printf("%d", ans);
}
