#include <bits/stdc++.h>
using namespace std;
const long long maxn = 1010;
const long long INF = (1e9) - 1;
long long n, m, dis1[maxn][maxn], dis2[maxn][maxn], dis3[maxn][maxn],
    mark1[maxn][maxn], mark2[maxn][maxn], mark3[maxn][maxn],
    diss12 = INF, diss13 = INF, diss23 = INF, ans1 = INF, ans2 = INF;
char a[maxn][maxn];
deque<pair<long long, long long> > qu1, qu2, qu3;
int main() {
  std::ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    string s1;
    cin >> s1;
    for (int j = 0; j < m; j++) {
      dis1[i][j] = INF;
      dis2[i][j] = INF;
      dis3[i][j] = INF;
      a[i][j] = s1[j];
      if (s1[j] == '1') {
        qu1.push_back({i, j});
        mark1[i][j] = 1;
        dis1[i][j] = 0;
      } else if (s1[j] == '2') {
        qu2.push_back({i, j});
        mark2[i][j] = 1;
        dis2[i][j] = 0;
      } else if (s1[j] == '3') {
        qu3.push_back({i, j});
        mark3[i][j] = 1;
        dis3[i][j] = 0;
      } else if (s1[j] == '#') {
        mark1[i][j] = 1;
        mark2[i][j] = 1;
        mark3[i][j] = 1;
      }
    }
  }
  while (qu1.size()) {
    long long x1 = qu1.front().first, y1 = qu1.front().second;
    qu1.pop_front();
    if ((x1 - 1) >= 0 && mark1[x1 - 1][y1] == 0) {
      mark1[x1 - 1][y1] = 1;
      dis1[x1 - 1][y1] = dis1[x1][y1] + 1;
      qu1.push_back({x1 - 1, y1});
    }
    if ((x1 + 1) < n && mark1[x1 + 1][y1] == 0) {
      mark1[x1 + 1][y1] = 1;
      dis1[x1 + 1][y1] = dis1[x1][y1] + 1;
      qu1.push_back({x1 + 1, y1});
    }
    if ((y1 - 1) >= 0 && mark1[x1][y1 - 1] == 0) {
      mark1[x1][y1 - 1] = 1;
      dis1[x1][y1 - 1] = dis1[x1][y1] + 1;
      qu1.push_back({x1, y1 - 1});
    }
    if ((y1 + 1) < m && mark1[x1][y1 + 1] == 0) {
      mark1[x1][y1 + 1] = 1;
      dis1[x1][y1 + 1] = dis1[x1][y1] + 1;
      qu1.push_back({x1, y1 + 1});
    }
  }
  while (qu2.size()) {
    long long x1 = qu2.front().first, y1 = qu2.front().second;
    qu2.pop_front();
    if ((x1 - 1) >= 0 && mark2[x1 - 1][y1] == 0) {
      mark2[x1 - 1][y1] = 1;
      dis2[x1 - 1][y1] = dis2[x1][y1] + 1;
      qu2.push_back({x1 - 1, y1});
    }
    if ((x1 + 1) < n && mark2[x1 + 1][y1] == 0) {
      mark2[x1 + 1][y1] = 1;
      dis2[x1 + 1][y1] = dis2[x1][y1] + 1;
      qu2.push_back({x1 + 1, y1});
    }
    if ((y1 - 1) >= 0 && mark2[x1][y1 - 1] == 0) {
      mark2[x1][y1 - 1] = 1;
      dis2[x1][y1 - 1] = dis2[x1][y1] + 1;
      qu2.push_back({x1, y1 - 1});
    }
    if ((y1 + 1) < m && mark2[x1][y1 + 1] == 0) {
      mark2[x1][y1 + 1] = 1;
      dis2[x1][y1 + 1] = dis2[x1][y1] + 1;
      qu2.push_back({x1, y1 + 1});
    }
  }
  while (qu3.size()) {
    long long x1 = qu3.front().first, y1 = qu3.front().second;
    qu3.pop_front();
    if ((x1 - 1) >= 0 && mark3[x1 - 1][y1] == 0) {
      mark3[x1 - 1][y1] = 1;
      dis3[x1 - 1][y1] = dis3[x1][y1] + 1;
      qu3.push_back({x1 - 1, y1});
    }
    if ((x1 + 1) < n && mark3[x1 + 1][y1] == 0) {
      mark3[x1 + 1][y1] = 1;
      dis3[x1 + 1][y1] = dis3[x1][y1] + 1;
      qu3.push_back({x1 + 1, y1});
    }
    if ((y1 - 1) >= 0 && mark3[x1][y1 - 1] == 0) {
      mark3[x1][y1 - 1] = 1;
      dis3[x1][y1 - 1] = dis3[x1][y1] + 1;
      qu3.push_back({x1, y1 - 1});
    }
    if ((y1 + 1) < m && mark3[x1][y1 + 1] == 0) {
      mark3[x1][y1 + 1] = 1;
      dis3[x1][y1 + 1] = dis3[x1][y1] + 1;
      qu3.push_back({x1, y1 + 1});
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (a[i][j] == '1') {
        diss12 = min(diss12, dis2[i][j]);
        diss13 = min(diss13, dis3[i][j]);
      } else if (a[i][j] == '2') {
        diss12 = min(diss12, dis1[i][j]);
        diss23 = min(diss23, dis3[i][j]);
      } else if (a[i][j] == '3') {
        diss23 = min(diss23, dis2[i][j]);
        diss13 = min(diss13, dis1[i][j]);
      } else if (a[i][j] == '.') {
        ans2 = min(ans2, dis1[i][j] + dis2[i][j] + dis3[i][j] - 2);
      }
    }
  }
  if (diss12 != INF) diss12--;
  if (diss13 != INF) diss13--;
  if (diss23 != INF) diss23--;
  vector<long long> vv;
  vv.push_back(diss12);
  vv.push_back(diss13);
  vv.push_back(diss23);
  sort(vv.begin(), vv.end());
  ans1 = vv[0] + vv[1];
  if (vv[0] == INF || vv[1] == INF || vv[2] == INF) ans1 = INF;
  if (ans1 >= INF && ans2 >= INF)
    return cout << -1, 0;
  else
    cout << min(ans1, ans2);
  return 0;
}
