#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
int n, m ,p;
int a[11][11];
int dist[11][11][10005];
int direction[4][2] = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
//int vis[11][11][10005];
//struct status {
// int x;
// int y;
// int cost;
// int modVal;
//};
struct status {
int x;
int y;
int modVal;
};
//看了题解之后照着写了一遍,感觉启发挺大但是还是掌握的有点模模糊糊的
//首先是余数的部分,我原先想的是用费马小定理和快速幂,大概单个数是log(log(b i, j))的时间,但是看了题解直接o(1)就行了,因为这个实际比较特殊,加入一般情况只有条件p, a(底数)互质应该是费马小定理和快速幂
//然后是bfs部分,我原来是怎么也想不通可以往回走不会死循环吗,看了题解之后认为这个搜索就是状态转移,状态一般是不重复(独一无二的),其不可重复遍历的(为此一般要加上一定的约束,比如最短路径到达该状态...),状态需要时有限的(因此约束了是mod)
int main() {
cin >> n >> m >> p;
p--;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> a[i][j];
a[i][j] %= p;
}
}
int tmp;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> tmp;
}
}
memset(dist, 0xFF, sizeof(dist));
queue<status> q;
status st;
st.x = 0;
st.y = 0;
st.modVal = a[st.x][st.y];
dist[st.x][st.y][st.modVal] = 0;
q.push(st);
while (!q.empty()) {
status s = q.front();
q.pop();
for (int i = 0; i < 4; i++) {
int x = s.x + direction[i][0];
int y = s.y + direction[i][1];
int modVal = (s.modVal + a[x][y]) % p;
if (x < n && x > -1 && y < m && y > -1 && dist[x][y][modVal] < 0) {
status new_s;
new_s.x = x;
new_s.y = y;
new_s.modVal = modVal;
q.push(new_s);
dist[x][y][modVal] = dist[s.x][s.y][s.modVal] + 1;
}
}
}
cout << dist[n - 1][m - 1][0] << endl;
}