#include <bits/stdc++.h>
using namespace std;
char s[1005][1005];
int node[1005][1005];
vector<int> adj[1005 * 1005];
bool f[4][4] = {0};
int no = 3;
void checkcon(int i, int j) {
  char c = s[i][j];
  if (c == '1') {
    if (s[i + 1][j] == '2' || s[i - 1][j] == '2' || s[i][j + 1] == '2' ||
        s[i][j - 1] == '2')
      f[1][2] = f[2][1] = 1;
    if (s[i + 1][j] == '3' || s[i - 1][j] == '3' || s[i][j + 1] == '3' ||
        s[i][j - 1] == '3')
      f[1][3] = f[3][1] = 1;
  } else if (c == '2') {
    if (s[i + 1][j] == '1' || s[i - 1][j] == '1' || s[i][j + 1] == '1' ||
        s[i][j - 1] == '1')
      f[1][2] = f[2][1] = 1;
    if (s[i + 1][j] == '3' || s[i - 1][j] == '3' || s[i][j + 1] == '3' ||
        s[i][j - 1] == '3')
      f[2][3] = f[3][2] = 1;
  }
  if (c == '3') {
    if (s[i + 1][j] == '2' || s[i - 1][j] == '2' || s[i][j + 1] == '2' ||
        s[i][j - 1] == '2')
      f[3][2] = f[2][3] = 1;
    if (s[i + 1][j] == '1' || s[i - 1][j] == '1' || s[i][j + 1] == '1' ||
        s[i][j - 1] == '1')
      f[1][3] = f[3][1] = 1;
  }
}
void checkcon1(int i, int j) {
  char c = s[i][j];
  if (c == '.') {
    no++;
    node[i][j] = no;
    if (s[i - 1][j] == '1' || s[i][j + 1] == '1' || s[i + 1][j] == '1' ||
        s[i][j - 1] == '1') {
      adj[no].push_back(1);
      adj[1].push_back(no);
    }
    if (s[i - 1][j] == '2' || s[i][j + 1] == '2' || s[i + 1][j] == '2' ||
        s[i][j - 1] == '2') {
      adj[no].push_back(2);
      adj[2].push_back(no);
    }
    if (s[i - 1][j] == '3' || s[i][j + 1] == '3' || s[i + 1][j] == '3' ||
        s[i][j - 1] == '3') {
      adj[no].push_back(3);
      adj[3].push_back(no);
    }
    if (s[i - 1][j] == '.') {
      adj[no].push_back(node[i - 1][j]);
      adj[node[i - 1][j]].push_back(no);
    }
    if (s[i][j - 1] == '.') {
      adj[no].push_back(node[i][j - 1]);
      adj[node[i][j - 1]].push_back(no);
    }
  }
}
int dis[4][1005 * 1005];
bool dircon() {
  if (f[1][2] && f[1][3]) return 1;
  if (f[2][1] && f[2][3]) return 1;
  if (f[3][2] && f[3][1]) return 1;
  return 0;
}
bool sincon() {
  if (f[1][2]) return 1;
  if (f[2][3]) return 1;
  if (f[3][1]) return 1;
  return 0;
}
bool vis[1005 * 1005];
void bfs1(int r, vector<int> vec) {
  vector<int> tem;
  for (int i = 0; i < vec.size(); i++) {
    int n1 = vec[i];
    for (int j = 0; j < adj[n1].size(); j++) {
      int v = adj[n1][j];
      if (vis[v]) continue;
      vis[v] = 1;
      if (v == 1 || v == 2 || v == 3) {
        dis[r][v] = dis[r][n1];
        vec.push_back(v);
      } else {
        dis[r][v] = dis[r][n1] + 1;
        tem.push_back(v);
      }
    }
  }
  if (tem.size() == 0) return;
  bfs1(r, tem);
}
void getdis() {
  for (int i = 1; i <= 3; i++) {
    vector<int> vec;
    memset(vis, 0, sizeof(vis));
    vec.push_back(i);
    dis[i][i] = 0;
    vis[i] = 1;
    bfs1(i, vec);
  }
}
int main() {
  for (int i = 1; i <= 3; i++)
    for (int j = 1; j < 1005 * 1005; j++) dis[i][j] = 1000000007;
  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) scanf("%s", s[i] + 1);
  ;
  for (int i = 0; i <= n + 1; i++) s[i][0] = s[i][m + 1] = '#';
  for (int i = 0; i <= m + 1; i++) s[0][i] = s[n + 1][i] = '#';
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) {
      checkcon(i, j);
      checkcon1(i, j);
    }
  if (f[1][2]) {
    adj[1].push_back(2);
    adj[2].push_back(1);
  }
  if (f[2][3]) {
    adj[2].push_back(3);
    adj[3].push_back(2);
  }
  if (f[3][1]) {
    adj[3].push_back(1);
    adj[1].push_back(3);
  }
  getdis();
  if (dis[1][2] == 1000000007 || dis[1][3] == 1000000007) {
    printf("%d\n", -1);
    return 0;
  }
  if (dircon()) {
    printf("0\n");
    return 0;
  }
  if (sincon()) {
    if (f[1][2])
      printf("%d\n", min(dis[3][1], dis[3][2]));
    else if (f[2][3])
      printf("%d\n", min(dis[1][2], dis[1][3]));
    else if (f[3][1])
      printf("%d\n", min(dis[2][1], dis[2][3]));
    return 0;
  }
  int ans = min(dis[2][1] + dis[3][1],
                min(dis[1][2] + dis[3][2], dis[1][3] + dis[2][3]));
  for (int i = 4; i <= no; i++) {
    if (dis[1][i] == 1000000007 || dis[2][i] == 1000000007 ||
        dis[3][i] == 1000000007)
      continue;
    ans = min(ans, dis[1][i] + dis[2][i] + dis[3][i] - 2);
  }
  printf("%d\n", ans);
  return 0;
}
