#include <stdio.h>
#define MAX_N 50
#define MAX_K 12000
#define MAX_Q (MAX_N * MAX_N * MAX_K)
#define INF 32767
#define NUM_DIR 4
#define OBSTACLE 0
int dir[NUM_DIR][2] = { {-1, 0}, {1, 0}, {0, 1}, {0, -1} };
short 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 */
short d[MAX_N + 2][MAX_N + 2][MAX_K];
typedef struct {
short x, y;
short mod;
} coada;
coada Q[MAX_Q];
int qStart, qEnd;
void enqueue(short x, short y, short mod) {
Q[qEnd] = { x, y, mod };
if (++qEnd == MAX_Q) {
qEnd = 0;
}
}
void dequeue(short *x, short *y, short *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");
short n, m, k, i, j, x, y, mod;
short X, Y, endX, endY, newMod;
fscanf(f, "%hd%hd%hd%hd%hd%hd%hd", &n, &m, &k, &X, &Y, &endX, &endY);
for (i = 1; i <= n; i++) {
for (j = 1; j <= m; j++) {
fscanf(f, "%hd", &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) && (x != endX || y != endY)) {
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, "%hd\n", d[endX][endY][0]);
fclose(f);
return 0;
}