#include <stdio.h>
#define MAX_N 50
#define MAX_K 12000
#define MAX_Q (MAX_N * MAX_N * MAX_K)
#define INF 2000000000
#define NUM_DIR 4
#define OBSTACLE 0
int dir[NUM_DIR][2] = { {-1, 0}, {1, 0}, {0, 1}, {0, -1} };
int a[MAX_N + 2][MAX_N + 2]; // matricea data, bordata cu 0
/* d[i][j][mod] = costum minim de a ajunge in (i, j) cu restul mod */
int d[MAX_N + 2][MAX_N + 2][MAX_K];
typedef struct {
int x, y;
int mod;
} coada;
coada Q[MAX_Q];
int qStart, qEnd;
void enqueue(int x, int y, int mod) {
Q[qEnd] = { x, y, mod };
if (++qEnd == MAX_Q) {
qEnd = 0;
}
}
void dequeue(int *x, int *y, int *mod) {
*x = Q[qStart].x;
*y = Q[qStart].y;
*mod = Q[qStart].mod;
if (++qStart == MAX_Q) {
qStart = 0;
}
}
int main(void) {
FILE *f = fopen("kdrum.in", "r");
int n, m, k, i, j, x, y, mod;
int X, Y, endX, endY, newMod;
fscanf(f, "%d%d%d%d%d%d%d", &n, &m, &k, &X, &Y, &endX, &endY);
for (i = 1; i <= n; i++) {
for (j = 1; j <= m; j++) {
fscanf(f, "%d", &a[i][j]);
for (x = 0; x < k; x++) {
d[i][j][x] = INF;
}
}
}
fclose(f);
newMod = a[X][Y] % k;
enqueue(X, Y, newMod);
d[X][Y][newMod] = 1;
while (qStart != qEnd) {
dequeue(&x, &y, &mod);
for (i = 0; i < NUM_DIR; i++) {
X = x + dir[i][0];
Y = y + dir[i][1];
newMod = (mod + a[X][Y]) % k;
if ((a[X][Y] != OBSTACLE) && (d[X][Y][newMod] > d[x][y][mod] + 1)) {
d[X][Y][newMod] = d[x][y][mod] + 1;
enqueue(X, Y, newMod);
}
}
}
f = fopen("kdrum.out", "w");
fprintf(f, "%d\n", d[endX][endY][0]);
fclose(f);
return 0;
}