Implement avg_pool2d(x, k, stride=None) for input of shape (N, C, H, W) with a square k×k window and no padding (stride defaults to k). Output size is (H - k) // stride + 1 in each dimension.
Also implement avg_pool2d_backward(dout, x_shape, k, stride=None): each output gradient is spread equally over the k*k inputs in its window (overlapping windows add up).