#include <bits/stdc++.h>
using namespace std;
const int INF = INT_MAX / 3;
vector<int> dx = {0, 0, 1, -1};
vector<int> dy = {1, -1, 0, 0};
const char OBSTACLE = '#';
const char FREECELL = '.';
bool valid(int a, int b) { return a >= 0 && a < b; }
vector<vector<int> > bfs(char c, vector<string> &S, int n, int m) {
  vector<vector<int> > dist(n, vector<int>(m, INF));
  deque<pair<int, int> > Q;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) {
      if (S[i][j] == c) {
        Q.push_front(make_pair(i, j));
        dist[i][j] = 0;
      }
    }
  while (!Q.empty()) {
    pair<int, int> U = Q.front();
    Q.pop_front();
    int x = U.first, y = U.second;
    for (int k = 0; k < 4; k++) {
      int nx = x + dx[k];
      int ny = y + dy[k];
      if (valid(nx, n) && valid(ny, m) && S[nx][ny] != OBSTACLE) {
        int w = (S[nx][ny] == FREECELL);
        if (dist[x][y] + w < dist[nx][ny]) {
          dist[nx][ny] = dist[x][y] + w;
          if (w == 0)
            Q.push_front(make_pair(nx, ny));
          else
            Q.push_back(make_pair(nx, ny));
        }
      }
    }
  }
  return dist;
}
int main() {
  ios_base ::sync_with_stdio(0);
  int n, m;
  while (cin >> n >> m) {
    vector<string> S(n);
    for (int i = 0; i < n; i++) cin >> S[i];
    vector<vector<vector<int> > > T(3);
    for (int k = 0; k < 3; k++) T[k] = bfs('1' + k, S, n, m);
    int ans = INF;
    for (int i = 0; i < n; i++)
      for (int j = 0; j < m; j++) {
        if (S[i][j] == OBSTACLE) continue;
        ans = min(ans, T[0][i][j] + T[1][i][j] + T[2][i][j] -
                           2 * (S[i][j] == FREECELL));
      }
    if (ans >= INF - 2) ans = -1;
    printf("%d\n", ans);
  }
}
