#include <bits/stdc++.h>
using namespace std;
int n, m, dis[1000][1000][3], compdis[3][3], res = 1e9;
bool nores, visited[1000][1000], check(int, int);
char grid[1000][1001];
void BFS(int);
vector<pair<int, int> > state[3];
pair<int, int> mv[] = {make_pair(0, 1), make_pair(1, 0), make_pair(-1, 0),
                       make_pair(0, -1)};
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; i++) {
    scanf("%s", grid[i]);
    for (int j = 0; j < m; j++) {
      dis[i][j][0] = dis[i][j][1] = dis[i][j][2] = 1e9;
      if ('1' <= grid[i][j] && grid[i][j] <= '3')
        state[grid[i][j] - '0' - 1].push_back(make_pair(i, j));
    }
  }
  for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++) compdis[i][j] = 1e9 * (i != j);
  BFS(0);
  BFS(1);
  BFS(2);
  for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++) nores |= (compdis[i][j] == 1e9);
  if (nores) {
    puts("-1");
    return 0;
  }
  int nodes[] = {0, 1, 2};
  do {
    int s = nodes[0], t1 = nodes[1], t2 = nodes[2];
    res = min(res, compdis[s][t1] + compdis[s][t2] - 2);
  } while (next_permutation(nodes, nodes + 3));
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
      if (grid[i][j] != '#')
        if (dis[i][j][0] != 1e9 && dis[i][j][1] != 1e9 && dis[i][j][2] != 1e9)
          res = min(res, dis[i][j][0] + dis[i][j][1] + dis[i][j][2] - 2);
  printf("%d", res);
}
void BFS(int idx) {
  queue<pair<pair<int, int>, int> > q;
  memset(visited, false, sizeof(visited));
  for (int i = 0, x, y; i < state[idx].size(); i++) {
    x = state[idx][i].first, y = state[idx][i].second;
    visited[x][y] = true, dis[x][y][idx] = 0,
    q.push(make_pair(state[idx][i], 0));
  }
  while (!q.empty()) {
    int x = q.front().first.first, y = q.front().first.second,
        d = q.front().second, ctp;
    q.pop();
    for (int k = 0, nx, ny; k < 4; k++) {
      nx = x + mv[k].first, ny = y + mv[k].second;
      if (check(nx, ny)) {
        ctp = grid[nx][ny] - '0' - 1;
        visited[nx][ny] = true, dis[nx][ny][idx] = d + 1,
        q.push(make_pair(make_pair(nx, ny), d + 1));
        if ((!ctp || ctp == 1 || ctp == 2))
          compdis[idx][ctp] = compdis[ctp][idx] = min(compdis[idx][ctp], d + 1);
      }
    }
  }
}
bool check(int x, int y) {
  return (x >= 0 && x < n && y >= 0 && y < m && grid[x][y] != '#' &&
          !visited[x][y]);
}
