public function nearest(array $sample, int $k = 1) : array
    {
        if ($k < 1) {
            throw new InvalidArgumentException('The number of nearest'
                . " neighbors must be greater than 0, $k given.");
        }

        $neighborhood = $this->search($sample);

        if (!$neighborhood) {
            return [[], []];
        }

        $distances = $labels = [];

        $visited = new SplObjectStorage();

        $stack = [$neighborhood];

        while ($stack) {
            $current = array_pop($stack);

            if ($visited->contains($current)) {
                continue 1;
            }

            $visited->attach($current);

            $parent = $current->parent();

            if ($parent) {
                $stack[] = $parent;
            }

            if ($current instanceof Neighborhood) {
                foreach ($current->samples() as $neighbor) {
                    $distances[] = $this->kernel->compute($sample, $neighbor);
                }

                $labels = array_merge($labels, $current->labels());

                array_multisort($distances, $labels);

                continue 1;
            }

            $target = $distances[$k - 1] ?? INF;

            foreach ($current->children() as $child) {
                if ($visited->contains($child)) {
                    continue 1;
                }

                if ($child instanceof Box) {
                    foreach ($child->sides() as $side) {
                        $distance = $this->kernel->compute($sample, $side);

                        if ($distance < $target) {
                            $stack[] = $child;

                            continue 2;
                        }
                    }
                }

                $visited->attach($child);
            }
        }

        $distances = array_slice($distances, 0, $k);
        $labels = array_slice($labels, 0, $k);

        return [$labels, $distances];
    }