#include <iostream>
#include <vector>
#include <string>
#include <cmath>
using namespace std;
const int INF = 1e8;
const int MAX_DIST = 100005;
const int MAX_Q = 5000005;
int head[MAX_DIST];
int q_u[MAX_Q];
int q_nxt[MAX_Q];
int q_ptr = 0;
int min_d = 0;
int max_d_pushed = -1;
void init_dijkstra() {
if (max_d_pushed >= 0) {
for (int i = 0; i <= max_d_pushed; ++i) head[i] = -1;
} else {
for (int i = 0; i < MAX_DIST; ++i) head[i] = -1;
}
q_ptr = 0;
min_d = INF;
max_d_pushed = -1;
}
inline void push_node(int d, int u) {
if (d >= MAX_DIST) return;
q_u[q_ptr] = u;
q_nxt[q_ptr] = head[d];
head[d] = q_ptr;
q_ptr++;
if (d < min_d) min_d = d;
if (d > max_d_pushed) max_d_pushed = d;
}
int N, M;
string grid[505];
int weight[250005];
int dT[250005], dB[250005], dL[250005], dR[250005];
int dTL[250005], dTR[250005], dTB[250005];
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
void dijkstra(int* dist) {
init_dijkstra();
for (int i = 0; i < N * M; ++i) {
if (dist[i] != INF) {
push_node(dist[i], i);
}
}
while (min_d <= max_d_pushed) {
int p = head[min_d];
if (p == -1) {
min_d++;
continue;
}
head[min_d] = q_nxt[p];
int u = q_u[p];
int d = min_d;
if (d > dist[u]) continue;
int r = u / M;
int c = u % M;
for (int i = 0; i < 4; ++i) {
int nr = r + dx[i];
int nc = c + dy[i];
if (nr >= 0 && nr < N && nc >= 0 && nc < M) {
int v = nr * M + nc;
int new_d = d + weight[v];
if (dist[v] > new_d) {
dist[v] = new_d;
push_node(new_d, v);
}
}
}
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
if (!(cin >> N >> M)) return 0;
for (int i = 0; i < N; ++i) {
cin >> grid[i];
}
int min_total_cost = INF;
for (int D = 0; D <= 9; ++D) {
for (int r = 0; r < N; ++r) {
for (int c = 0; c < M; ++c) {
weight[r * M + c] = abs((grid[r][c] - '0') - D);
dT[r * M + c] = INF;
dB[r * M + c] = INF;
dL[r * M + c] = INF;
dR[r * M + c] = INF;
}
}
for (int c = 0; c < M; ++c) {
dT[0 * M + c] = weight[0 * M + c];
dB[(N - 1) * M + c] = weight[(N - 1) * M + c];
}
for (int r = 0; r < N; ++r) {
dL[r * M + 0] = weight[r * M + 0];
dR[r * M + (M - 1)] = weight[r * M + (M - 1)];
}
dijkstra(dT);
dijkstra(dB);
dijkstra(dL);
dijkstra(dR);
for (int i = 0; i < N * M; ++i) {
dTL[i] = dT[i] + dL[i] - weight[i];
dTR[i] = dT[i] + dR[i] - weight[i];
dTB[i] = dT[i] + dB[i] - weight[i];
}
dijkstra(dTL);
dijkstra(dTR);
dijkstra(dTB);
for (int i = 0; i < N * M; ++i) {
int cost1 = dTL[i] + dB[i] + dR[i] - 2 * weight[i];
int cost2 = dTR[i] + dB[i] + dL[i] - 2 * weight[i];
int cost3 = dTB[i] + dL[i] + dR[i] - 2 * weight[i];
if (cost1 < min_total_cost) min_total_cost = cost1;
if (cost2 < min_total_cost) min_total_cost = cost2;
if (cost3 < min_total_cost) min_total_cost = cost3;
}
}
cout << min_total_cost << "\n";
return 0;
}