#include <bits/stdc++.h>
using namespace std;
const long int maxx = 1e3 + 20;
const long int inf = 1e6 + 20;
char s[maxx][maxx];
long int t[3][maxx][maxx], n, m, dx[4] = {0, 0, 1, -1}, dy[4] = {1, -1, 0, 0};
bool visited[maxx][maxx], shodani[maxx][maxx];
deque<pair<long int, long int> > q;
void bfs(long int x, long int y, long int e) {
  visited[x][y] = true;
  q.push_front(make_pair(x, y));
  while (q.size()) {
    long int v1 = q.front().first, v2 = q.front().second;
    q.pop_front();
    visited[v1][v2] = true;
    for (int i = 0; i < 4; i++) {
      int xx = v1 + dx[i];
      int yy = v2 + dy[i];
      if ((xx < n) && (xx >= 0) && (yy < m) && (yy >= 0) && (s[xx][yy] == '#'))
        continue;
      else if ((xx < n) && (xx >= 0) && (yy < m) && (yy >= 0) &&
               (s[xx][yy] - '0' == e)) {
        if (!visited[xx][yy]) {
          visited[xx][yy] = true;
          t[e - 1][xx][yy] = t[e - 1][v1][v2];
          q.push_front(make_pair(xx, yy));
        }
      } else if ((xx < n) && (xx >= 0) && (yy < m) && (yy >= 0) &&
                 (s[xx][yy] != '.')) {
        if (!visited[xx][yy]) {
          visited[xx][yy] = true;
          t[e - 1][xx][yy] = t[e - 1][v1][v2];
          q.push_front(make_pair(xx, yy));
        }
      } else if ((xx < n) && (xx >= 0) && (yy < m) && (yy >= 0) &&
                 (s[xx][yy] == '.')) {
        if (!visited[xx][yy]) {
          visited[xx][yy] = true;
          t[e - 1][xx][yy] = t[e - 1][v1][v2] + 1;
          q.push_back(make_pair(xx, yy));
        }
      }
    }
  }
}
int main() {
  long long k, i, j, a1, a2, b1, b2, c1, c2, q1, q2, q3;
  cin >> n >> m;
  for (k = 0; k < 3; k++)
    for (i = 0; i < n; i++)
      for (j = 0; j < m; j++) t[k][i][j] = -1;
  for (i = 0; i < n; i++) {
    for (j = 0; j < m; j++) {
      shodani[i][j] = true;
      cin >> s[i][j];
      if (s[i][j] == '1') {
        a1 = i;
        a2 = j;
      }
      if (s[i][j] == '2') {
        b1 = i;
        b2 = j;
      }
      if (s[i][j] == '3') {
        c1 = i;
        c2 = j;
      }
    }
  }
  t[0][a1][a2] = 0;
  bfs(a1, a2, 1);
  for (i = 0; i < n; i++) {
    for (j = 0; j < m; j++) {
      visited[i][j] = false;
      if (t[0][i][j] == -1) shodani[i][j] = false;
    }
  }
  t[1][b1][b2] = 0;
  bfs(b1, b2, 2);
  for (i = 0; i < n; i++) {
    for (j = 0; j < m; j++) {
      visited[i][j] = false;
      if (t[1][i][j] == -1) shodani[i][j] = false;
      t[0][i][j] += t[1][i][j];
    }
  }
  t[2][c1][c2] = 0;
  bfs(c1, c2, 3);
  for (i = 0; i < n; i++) {
    for (j = 0; j < m; j++) {
      visited[i][j] = false;
      if (t[2][i][j] == -1) shodani[i][j] = false;
      t[0][i][j] += t[2][i][j];
    }
  }
  for (i = 0; i < n; i++) {
    for (j = 0; j < m; j++) {
      if (s[i][j] == '.') {
        t[0][i][j] -= 2;
      }
    }
  }
  long int r = 2 * inf;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (shodani[i][j]) r = min(r, t[0][i][j]);
    }
  }
  if (r == 2 * inf)
    cout << -1;
  else
    cout << r;
  return 0;
}
