#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N = 2000020;
int A, B, C, m;
LL s[N], b[N], bp[N];
//s[i][j][k] = b[i][j][k] + s[i-1][j][k] + s[i][j-1][k] - s[i-1][j-1][k]
// + s[i][j][k-1] - s[i-1][j][k-1] - s[i][j-1][k-1] + s[i-1][j-1][k-1];
//观察上述式子,发现偶数个坐标减一前面的系数为+1,奇数个坐标减一系数为-1。
//且三个坐标的偏移量是能表示成二进制。(0,0,0), (0,0,1),(0,1,0)等等到(1,1,1)
//所以考虑用一个数组的值,代替这个坐标的变化。
//前三个数表示,三个方向坐标的偏移量,最后一个数表示正负。
int d[8][4] = {
{0, 0, 0, 1},
{0, 0, 1, -1},
{0, 1, 0, -1},
{0, 1, 1, 1},
{1, 0, 0, -1},
{1, 0, 1, 1},
{1, 1, 0, 1},
{1, 1, 1, -1},
};
int op[N / 2][7]; //存储m轮攻击的范围和数值
//进行地址映射
int get(int i, int j, int k)
{
return (i * B + j) * C + k;
}
bool check(int mid)
{
memcpy(b, bp, sizeof b);
//对差分数组进行mid轮操作,攻击战舰的血量值
for(int i = 1; i <= mid; i ++)
{
int x1 = op[i][0], x2 = op[i][1], y1 = op[i][2], y2 = op[i][3], z1 = op[i][4], z2 = op[i][5], h = op[i][6];
b[get(x1, y1, z1)] -= h;
b[get(x1, y1, z2 + 1)] += h;
b[get(x1, y2 + 1, z1)] += h;
b[get(x1, y2 + 1, z2 + 1)] -= h;
b[get(x2 + 1, y1, z1)] += h;
b[get(x2 + 1, y1, z2 + 1)] -= h;
b[get(x2 + 1, y2 + 1, z1)] -= h;
b[get(x2 + 1, y2 + 1, z2 + 1)] += h;
}
//清空前缀和数组s,求更新后差分数组b的前缀和数组s
memset(s, 0, sizeof s);
for (int i = 1; i <= A; i ++ )
for (int j = 1; j <= B; j ++ )
for (int k = 1; k <= C; k ++ )
{
s[get(i, j, k)] = b[get(i, j, k)];
for (int u = 1; u < 8; u ++ )
{
int x = i - d[u][0], y = j - d[u][1], z = k - d[u][2], t = d[u][3];
s[get(i, j, k)] -= s[get(x, y, z)] * t; //和求差分数组bp时符号相反
}
if (s[get(i, j, k)] < 0) return true;
}
return false;
}
int main()
{
scanf("%d%d%d%d", &A, &B, &C, &m);
//获取战舰血量
for(int i = 1; i <= A; i ++)
for(int j = 1; j <= B; j ++)
for(int k = 1; k <= C; k ++)
scanf("%lld", &s[get(i, j, k)]);
//求差分数组
for(int i = 1; i <= A; i ++)
for(int j = 1; j <= B; j ++)
for(int k = 1; k <= C; k ++)
for(int u = 0; u < 8; u ++)
{
int x = i - d[u][0], y = j - d[u][1], z = k - d[u][2], t = d[u][3];
bp[get(i, j, k)] += s[get(x, y, z)] * t;
}
//读入m轮攻击
for(int i = 1; i <= m; i ++)
for(int j = 0; j < 7 ; j ++)
scanf("%d", &op[i][j]);
//进行二分找到第一个被摧毁的战舰
int l = 1, r = m;
while(l < r)
{
int mid = l + r >> 1;
if(check(mid)) r = mid;
else l = mid + 1;
}
printf("%d", r);
return 0;
}