#include <bits/stdc++.h>
using namespace std;
const int mxn = 1006;
const int MXL = 0x1f1f1f1f;
const int X_[] = {0, 0, 1, -1};
const int Y_[] = {1, -1, 0, 0};
int N, M;
char a[mxn][mxn];
int dist[3][mxn][mxn];
deque<pair<int, int> > que;
int c;
void Push(pair<int, int> p, int d) {
  if (a[p.first][p.second] == '#') return;
  if (dist[c][p.first][p.second] != MXL) return;
  dist[c][p.first][p.second] = d;
  que.push_back(p);
}
void Pop() {
  pair<int, int> p = que.front();
  que.pop_front();
  for (int i = 0; i < 4; ++i)
    Push(make_pair(p.first + X_[i], p.second + Y_[i]),
         dist[c][p.first][p.second] + 1);
}
void EXEC() {
  scanf("%d%d", &N, &M);
  gets(a[0]);
  for (int i = 1; i <= N; ++i) gets(a[i] + 1);
  for (int i = 0; i <= N + 1; ++i) a[i][0] = a[i][M + 1] = '#';
  for (int i = 0; i <= M + 1; ++i) a[0][i] = a[N + 1][i] = '#';
  memset(dist, 31, sizeof dist);
  for (c = 0; c < 3; ++c) {
    que.clear();
    for (int i = 1; i <= N; ++i)
      for (int j = 1; j <= M; ++j)
        if (a[i][j] == '1' + c) Push(make_pair(i, j), 0);
    while (!que.empty()) Pop();
  }
  int ans = MXL;
  for (int i = 1; i <= N; ++i)
    for (int j = 1; j <= M; ++j)
      if (a[i][j] == '.')
        ans = min(ans, dist[0][i][j] + dist[1][i][j] + dist[2][i][j] - 2);
  int d[3][3];
  memset(d, 31, sizeof d);
  for (int i = 1; i <= N; ++i)
    for (int j = 1; j <= M; ++j)
      if (isdigit(a[i][j]))
        for (int k = 0; k < 3; ++k)
          d[a[i][j] - '1'][k] = min(d[a[i][j] - '1'][k], dist[k][i][j]);
  int mn[3];
  mn[0] = d[0][1] - 1;
  mn[1] = d[0][2] - 1;
  mn[2] = d[1][2] - 1;
  sort(mn, mn + 3);
  ans = min(ans, mn[0] + mn[1]);
  if (ans >= MXL - 3) ans = -1;
  printf("%d\n", ans);
}
int main() {
  EXEC();
  return 0;
}
