#include <bits/stdc++.h>
using namespace std;
const long long maxn = 1010, maxl = 5, inf = 1e18;
long long dis[maxl][maxn][maxn], dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1}, n,
                                 m;
char a[maxn][maxn];
vector<pair<long long, long long> > v[maxl];
bool isin(pair<long long, long long> u) {
  return (u.first >= 0) && (u.second >= 0) && (u.first < n) && (u.second < m) &&
         (a[u.first][u.second] != '#');
}
void bfs(long long s) {
  queue<pair<long long, long long> > q;
  for (pair<long long, long long> u : v[s])
    dis[s][u.first][u.second] = 0, q.push(u);
  while (!q.empty()) {
    pair<long long, long long> u = q.front();
    q.pop();
    for (long long i = 0; i < 4; i++) {
      pair<long long, long long> to(u.first + dx[i], u.second + dy[i]);
      if (!isin(to)) continue;
      long long cost = (a[to.first][to.second] == '.');
      if (dis[s][to.first][to.second] > dis[s][u.first][u.second] + cost)
        dis[s][to.first][to.second] = dis[s][u.first][u.second] + cost,
        q.push(to);
    }
  }
}
signed main() {
  cin >> n >> m;
  for (long long i = 0; i < n; i++)
    for (long long j = 0; j < m; j++) {
      cin >> a[i][j];
      if (a[i][j] >= '1' && a[i][j] <= '3') v[a[i][j] - '1'].push_back({i, j});
    }
  memset(dis, 63, sizeof dis);
  bfs(0), bfs(1), bfs(2);
  long long ans = inf;
  for (long long i = 0; i < n; i++)
    for (long long j = 0; j < m; j++)
      if (a[i][j] != '#' && dis[0][i][j] < inf && dis[1][i][j] < inf &&
          dis[2][i][j] < inf)
        ans = min(ans, dis[0][i][j] + dis[1][i][j] + dis[2][i][j] -
                           2 * (a[i][j] == '.'));
  cout << (ans > n * m ? -1 : ans);
  return 0;
}
