#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1000 + 10, mod = 1000 * 1000 * 1000 + 7;
int n, m, h1[MAXN][MAXN], h2[MAXN][MAXN], h3[MAXN][MAXN], n_c = 2;
string second[MAXN];
bool mrk[MAXN][MAXN];
deque<pair<int, int> > d1, d2, d3;
vector<pair<int, int> > v[4];
void get() {
  cin >> n >> m;
  for (int i = 0; i < n; i++) cin >> second[i];
  return;
}
void addv() {
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
      if (second[i][j] != '.' && second[i][j] != '#')
        v[int(int(second[i][j]) - int('0'))].push_back({i, j});
}
void add1_d() {
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
      if (second[i][j] == '1') mrk[i][j] = 1, d1.push_back({i, j});
  return;
}
void add2_d() {
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
      if (second[i][j] == '2') mrk[i][j] = 1, d2.push_back({i, j});
  return;
}
void add3_d() {
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
      if (second[i][j] == '3') mrk[i][j] = 1, d3.push_back({i, j});
  return;
}
void bfs1() {
  while (d1.size()) {
    pair<int, int> x = d1.front();
    for (int k = -1; k <= 1; k++)
      for (int l = -1; l <= 1; l++)
        if ((!l && k) || (l && !k))
          if (0 <= x.first + k && x.first + k < n && 0 <= x.second + l &&
              x.second + l < m && second[x.first + k][x.second + l] != '#' &&
              !mrk[x.first + k][x.second + l]) {
            if (second[x.first + k][x.second + l] == '.')
              h1[x.first + k][x.second + l] = h1[x.first][x.second] + 1;
            else {
              int z;
              if (second[x.first + k][x.second + l] == '2')
                z = 2;
              else if (second[x.first + k][x.second + l] == '3')
                z = 3;
              h1[x.first + k][x.second + l] = h1[x.first][x.second];
              for (int i = 0; i < v[z].size(); i++)
                if (!mrk[v[z][i].first][v[z][i].second]) {
                  mrk[v[z][i].first][v[z][i].second] = 1;
                  h1[v[z][i].first][v[z][i].second] =
                      h1[x.first + k][x.second + l];
                  d1.push_back({v[z][i].first, v[z][i].second});
                }
            }
            mrk[x.first + k][x.second + l] = 1, d1.push_back({x.first + k,
                                                              x.second + l});
          }
    d1.pop_front();
  }
  return;
}
void bfs2() {
  while (d2.size()) {
    pair<int, int> x = d2.front();
    for (int k = -1; k <= 1; k++)
      for (int l = -1; l <= 1; l++)
        if ((!l && k) || (l && !k))
          if (0 <= x.first + k && x.first + k < n && 0 <= x.second + l &&
              x.second + l < m && second[x.first + k][x.second + l] != '#' &&
              !mrk[x.first + k][x.second + l]) {
            if (second[x.first + k][x.second + l] == '.')
              h2[x.first + k][x.second + l] = h2[x.first][x.second] + 1;
            else {
              int z;
              if (second[x.first + k][x.second + l] == '1')
                z = 1;
              else if (second[x.first + k][x.second + l] == '3')
                z = 3;
              h2[x.first + k][x.second + l] = h2[x.first][x.second];
              for (int i = 0; i < v[z].size(); i++)
                if (!mrk[v[z][i].first][v[z][i].second]) {
                  mrk[v[z][i].first][v[z][i].second] = 1;
                  h2[v[z][i].first][v[z][i].second] =
                      h2[x.first + k][x.second + l];
                  d2.push_back({v[z][i].first, v[z][i].second});
                }
            }
            mrk[x.first + k][x.second + l] = 1, d2.push_back({x.first + k,
                                                              x.second + l});
          }
    d2.pop_front();
  }
  return;
}
void bfs3() {
  while (d3.size()) {
    pair<int, int> x = d3.front();
    for (int k = -1; k <= 1; k++)
      for (int l = -1; l <= 1; l++)
        if ((!l && k) || (l && !k))
          if (0 <= x.first + k && x.first + k < n && 0 <= x.second + l &&
              x.second + l < m && second[x.first + k][x.second + l] != '#' &&
              !mrk[x.first + k][x.second + l]) {
            if (second[x.first + k][x.second + l] == '.')
              h3[x.first + k][x.second + l] = h3[x.first][x.second] + 1;
            else {
              int z;
              if (second[x.first + k][x.second + l] == '1')
                z = 1;
              else if (second[x.first + k][x.second + l] == '2')
                z = 2;
              h3[x.first + k][x.second + l] = h3[x.first][x.second];
              for (int i = 0; i < v[z].size(); i++)
                if (!mrk[v[z][i].first][v[z][i].second]) {
                  mrk[v[z][i].first][v[z][i].second] = 1;
                  h3[v[z][i].first][v[z][i].second] =
                      h3[x.first + k][x.second + l];
                  d3.push_back({v[z][i].first, v[z][i].second});
                }
            }
            mrk[x.first + k][x.second + l] = 1, d3.push_back({x.first + k,
                                                              x.second + l});
          }
    d3.pop_front();
  }
  return;
}
bool cl() {
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) {
      if (second[i][j] != '.' && second[i][j] != '#' && !mrk[i][j]) return 1;
      mrk[i][j] = 0;
    }
  return 0;
}
void find_ans() {
  long long int ans = 1000 * 1000 * 1000;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      long long int d = 0;
      d += h1[i][j];
      d += h2[i][j];
      d += h3[i][j];
      if (second[i][j] == '.') d -= 2;
      if (second[i][j] != '#' && mrk[i][j]) ans = min(ans, d);
    }
  }
  cout << ans << endl;
  return;
}
int main() {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  get();
  addv();
  add1_d();
  bfs1();
  if (cl()) {
    cout << -1;
    return 0;
  }
  add2_d();
  bfs2();
  cl();
  add3_d();
  bfs3();
  find_ans();
  return 0;
}
