#include <bits/stdc++.h>
using namespace std;
const int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int dis_state[4][4];
struct Node {
  int x;
  int y;
  int dis;
  Node() {}
  Node(int a, int b, int c) {
    x = a;
    y = b;
    dis = c;
  }
};
char s[1500][1500];
long long dist[4][1500][1500];
int X, Y;
bool In(int x, int y) { return x >= 0 and x < X and y >= 0 and y < Y; }
queue<Node> q;
void bfs(int k) {
  while (not q.empty()) {
    Node t = q.front();
    q.pop();
    if (dist[k][t.x][t.y] > t.dis and s[t.x][t.y] != '#') {
      dist[k][t.x][t.y] = t.dis;
      for (int i = 0; i < 4; i++) {
        int xx = t.x + dx[i], yy = t.y + dy[i];
        if (In(xx, yy) and s[xx][yy] != '#')
          ;
        { q.push(Node(xx, yy, t.dis + 1)); }
      }
    }
  }
}
void Init() {
  scanf("%d%d", &X, &Y);
  for (int i = 0; i < X; i++) {
    scanf("%s", s[i]);
  }
  for (int k = 1; k <= 3; k++) {
    for (int i = 0; i < X; i++) {
      for (int j = 0; j < Y; j++) {
        dist[k][i][j] = 0x3f3f3f3f;
      }
    }
    while (not q.empty()) q.pop();
    char c = '0' + k;
    for (int i = 0; i < X; i++) {
      for (int j = 0; j < Y; j++) {
        if (s[i][j] == c) {
          q.push(Node(i, j, 0));
        }
      }
    }
    bfs(k);
  }
  memset(dis_state, 0x3f, sizeof(dis_state));
  for (int ii = 1; ii <= 3; ii++) {
    dis_state[ii][ii] = 0;
    for (int jj = 1; jj < ii; jj++) {
      char c = '0' + jj;
      for (int i = 0; i < X; i++) {
        for (int j = 0; j < Y; j++) {
          if (s[i][j] == c) {
            dis_state[ii][jj] = dis_state[jj][ii] =
                ((dis_state[ii][jj]) < (dist[ii][i][j]) ? (dis_state[ii][jj])
                                                        : (dist[ii][i][j]));
          }
        }
      }
    }
  }
}
long long res = 0x3f3f3f3f;
void Solve() {
  for (int i = 0; i < X; i++) {
    for (int j = 0; j < Y; j++) {
      res = ((res) < (dist[1][i][j] + dist[2][i][j] + dist[3][i][j] - 2)
                 ? (res)
                 : (dist[1][i][j] + dist[2][i][j] + dist[3][i][j] - 2));
    }
  }
  res = ((res) < (dis_state[1][2] + dis_state[2][3] - 2)
             ? (res)
             : (dis_state[1][2] + dis_state[2][3] - 2));
  res = ((res) < (dis_state[1][3] + dis_state[2][3] - 2)
             ? (res)
             : (dis_state[1][3] + dis_state[2][3] - 2));
  res = ((res) < (dis_state[1][2] + dis_state[1][3] - 2)
             ? (res)
             : (dis_state[1][2] + dis_state[1][3] - 2));
  printf("%I64d\n", res < (0x3f3f3f3f / 2) ? res : -1);
}
int main() {
  Init();
  Solve();
  return 0;
}
