#include <iostream>
#include <queue>
using namespace std;
const int MaxM = 1287, MaxN = 129, MaxL = 61;
int pixel[MaxM][MaxN][MaxL];
bool status[MaxM][MaxN][MaxL]{false};
int M, N, L, T; // 注意是L层,每层是M*N,门槛是T
class Point {
public:
int x, y, z;
Point(int a, int b, int c) : x(a), y(b), z(c) {}
~Point() = default;
Point operator+(Point add) const { return Point{x + add.x, y + add.y, z + add.z}; }
bool check() const
{
if (x >= M '' x < 0 '' y >= N '' y < 0 '' z >= L '' z < 0)
return false; // 越界返回false
if (pixel[x][y][z] == 0 '' status[x][y][z])
return false; // 当前非肿块点,或已经被访问过,返回false
return true;
}
};
const Point adj[6] = { // 一个点的六个相邻点的移动方向 //NOLINT
Point{0, 0, 1}, Point{0, 0, -1}, Point{1, 0, 0}, Point{-1, 0, 0}, Point{0, 1, 0}, Point{0, -1, 0}};
int BFS(int x, int y, int z)
{
int cur = 0; // 此次bfs中的符合的点的个数
queue<Point> q;
Point point{x, y, z};
q.push(point);
status[x][y][z] = true;
while (!q.empty()) {
Point top = q.front();
++cur;
q.pop();
for (auto i : adj) {
point = top + i;
if (point.check()) { // 经检测,新位置符合要求
q.push(point); // 入队
status[point.x][point.y][point.z] = true; // 并设置已经检测过
}
}
}
if (cur >= T)
return cur;
else
return 0;
}
int main()
{
cin >> M >> N >> L >> T;
for (int z = 0; z < L; ++z) {
for (int x = 0; x < M; ++x) {
for (int y = 0; y < N; ++y)
cin >> pixel[x][y][z];
}
}
int ans = 0;
for (int z = 0; z < L; ++z) {
for (int x = 0; x < M; ++x) {
for (int y = 0; y < N; ++y)
// 当前位置为1,且没被访问过,则从当前点开始BFS
if (pixel[x][y][z] == 1 && !status[x][y][z])
ans += BFS(x, y, z);
}
}
cout << ans;
return 0;
}