#include <bits/stdc++.h>
using namespace std;
const int dx[] = {1, 0, -1, 0};
const int dy[] = {0, 1, 0, -1};
char zzz[1010];
string scan() {
  scanf("%s", zzz);
  return string(zzz);
}
int n, m;
vector<string> arr;
int dist[3][1010][1010];
deque<pair<int, int> > dq;
int main() {
  scanf("%d%d", &n, &m);
  arr = vector<string>(n);
  for (int i = 0; i < n; i++) arr[i] = scan();
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
      for (int k = 0; k < 3; k++) dist[k][i][j] = (1 << 30);
  for (char c = '1'; c <= '3'; c++) {
    for (int i = 0; i < n; i++)
      for (int j = 0; j < m; j++)
        if (arr[i][j] == c)
          dq.push_back(make_pair(i, j)), dist[c - '1'][i][j] = 0;
    while (!dq.empty()) {
      int x = dq.front().first;
      int y = dq.front().second;
      dq.pop_front();
      for (int i = 0; i < 4; i++) {
        int nx = x + dx[i];
        int ny = y + dy[i];
        if (!(nx >= 0 && nx < n && ny >= 0 && ny < m && arr[nx][ny] != '#'))
          continue;
        int nd = dist[c - '1'][x][y] + (arr[x][y] == '.');
        if (nd < dist[c - '1'][nx][ny]) {
          dist[c - '1'][nx][ny] = nd;
          if (arr[x][y] == '.')
            dq.push_back(make_pair(nx, ny));
          else
            dq.push_front(make_pair(nx, ny));
        }
      }
    }
  }
  long long ans = INT_MAX;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      long long cur = 0;
      for (int k = 0; k < 3; k++) cur += dist[k][i][j];
      ans = min(ans, cur + (arr[i][j] == '.'));
    }
  }
  if (ans < (1 << 30))
    printf("%I64d\n", ans);
  else
    puts("-1");
}
