#include <bits/stdc++.h>
using namespace std;
struct Cell {
  char type;
  int dists[3];
};
const int MAX_N = 1001;
Cell table[MAX_N][MAX_N];
int height, width;
void input() {
  scanf("%i %i", &height, &width);
  for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
      scanf(" %c", &table[x][y].type);
    }
  }
}
void calc_dist(int state) {
  queue<pair<int, int>> next;
  for (int x = 0; x < width; x++) {
    for (int y = 0; y < height; y++) {
      if (table[x][y].type == state + '1') {
        table[x][y].dists[state] = 0;
        next.push(make_pair(x, y));
      } else {
        table[x][y].dists[state] = -1;
      }
    }
  }
  while (not next.empty()) {
    int curX = next.front().first;
    int curY = next.front().second;
    int curDist = table[curX][curY].dists[state];
    next.pop();
    int dirs[][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
    for (int i = 0; i < 4; i++) {
      int newX = curX + dirs[i][0];
      int newY = curY + dirs[i][1];
      if ((newX < 0) || (newX >= width)) {
        continue;
      }
      if ((newY < 0) || (newY >= height)) {
        continue;
      }
      if (table[newX][newY].type == '#') {
        continue;
      }
      if (table[newX][newY].dists[state] >= 0) {
        continue;
      }
      table[newX][newY].dists[state] = curDist + 1;
      next.push(make_pair(newX, newY));
    }
  }
}
int main() {
  input();
  for (int i = 0; i < 3; i++) {
    calc_dist(i);
  }
  int min_dists[3][3];
  int min_combined = -1;
  for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
      min_dists[i][j] = -1;
    }
  }
  for (int x = 0; x < width; x++) {
    for (int y = 0; y < height; y++) {
      int curCombined = 1;
      int curState;
      if ((table[x][y].type >= '1') && (table[x][y].type <= '3')) {
        curState = table[x][y].type - '1';
      } else {
        curState = -1;
      }
      for (int i = 0; i < 3; i++) {
        int curDist = table[x][y].dists[i] - 1;
        if (curState == i) {
          curDist = 0;
        }
        if (curDist < 0) {
          curCombined = -1;
          continue;
        }
        if (curState >= 0) {
          if ((min_dists[curState][i] < 0) ||
              (min_dists[curState][i] > curDist)) {
            min_dists[curState][i] = curDist;
            min_dists[i][curState] = curDist;
          }
        }
        if (curCombined > -1) {
          curCombined += curDist;
        }
      }
      if (curCombined == -1) {
        continue;
      }
      if ((min_combined < 0) || (min_combined > curCombined)) {
        min_combined = curCombined;
      }
    }
  }
  int dists[] = {min_dists[0][1], min_dists[0][2], min_dists[1][2]};
  int minSum = 1e8;
  if ((min_dists[0][1] < 0) || (min_dists[0][2] < 0) || (min_dists[1][2] < 0)) {
    printf("-1\n");
    return 0;
  }
  for (int i = 0; i < 3; i++) {
    for (int j = i + 1; j < 3; j++) {
      int curSum = dists[i] + dists[j];
      minSum = min(curSum, minSum);
    }
  }
  if ((min_dists[0][1] < 0) || (min_dists[0][2] < 0) || (min_dists[1][2] < 0)) {
    printf("-1\n");
    return 0;
  }
  int awns = min(minSum, min_combined);
  if (min_combined < 0) {
    awns = minSum;
  }
  printf("%i\n", awns);
}
