#include <vector>

template <typename It>
class IteratorRange {
public:
    IteratorRange<It>(It b, It e) : begin_(b), end_(e), size_(std::distance(b, e)) {}

    It begin() const {
        return begin_;
    }
    It end() const {
        return end_;
    }
    size_t size() const {
        return size_;
    }

private:
    It begin_, end_;
    size_t size_;
};

template <typename It>
class Slicer {
public:
    Slicer(It first_, It last_, const size_t size_of_page) {
        const size_t size = std::distance(first_, last_);
        for (size_t sz = size; sz > 0;) {
            size_t cur_page_size = std::min(size_of_page, sz);
            auto cur_page_end = std::next(first_, cur_page_size);
            pages_.push_back(IteratorRange<It>(first_, cur_page_end));

            sz -= cur_page_size;
            first_ = cur_page_end;
        }
    }

    auto begin() const {
        return pages_.begin();
    }

    auto end() const {
        return pages_.end();
    }
    size_t size() const {
        return pages_.size();
    }

private:
    std::vector<IteratorRange<It>> pages_;
};

template <typename C>
auto Slice(C& c, size_t page_size) {
    return Slicer(c.begin(), c.end(), page_size);
}