#include <bits/stdc++.h>
using namespace std;
const long long N = 1000 + 5, INF = 0x3f3f3f3f;
char maze[N][N];
long long dist[N][N][4], n, m;
long long fx[4] = {1, -1, 0, 0}, fy[4] = {0, 0, 1, -1};
deque<pair<long long, long long> > q;
void bfs(long long country) {
  for (long long i = 1; i <= n; i++)
    for (long long j = 1; j <= m; j++)
      if (maze[i][j] == country + '0') {
        dist[i][j][country] = 0;
        q.push_back(pair<long long, long long>(i, j));
      }
  while (!q.empty()) {
    pair<long long, long long> p = q.front();
    q.pop_front();
    long long x = p.first, y = p.second;
    for (long long d = 0; d < 4; d++) {
      long long nx = x + fx[d], ny = y + fy[d];
      if (nx >= 1 && nx <= n && ny >= 1 && ny <= m && maze[nx][ny] != '#' &&
          dist[nx][ny][country] == INF) {
        long long cost = maze[nx][ny] == '.';
        dist[nx][ny][country] = dist[x][y][country] + cost;
        if (cost)
          q.push_back(pair<long long, long long>(nx, ny));
        else
          q.push_front(pair<long long, long long>(nx, ny));
      }
    }
  }
}
signed main() {
  scanf("%lld%lld", &n, &m);
  for (long long i = 1; i <= n; i++) scanf("%s", maze[i] + 1);
  for (long long i = 1; i <= n; i++)
    for (long long j = 1; j <= m; j++)
      for (long long k = 1; k <= 3; k++) dist[i][j][k] = INF;
  bfs(1);
  bfs(2);
  bfs(3);
  long long minn = INF;
  for (long long i = 1; i <= n; i++)
    for (long long j = 1; j <= m; j++) {
      long long cost = dist[i][j][1] + dist[i][j][2] + dist[i][j][3];
      if (maze[i][j] == '.') cost -= 2;
      minn = min(minn, cost);
    }
  if (minn == INF)
    puts("-1");
  else
    printf("%lld\n", minn);
  return 0;
}
