template<class Iterator>
class SlicerRange {
private:
    Iterator begin_, end_;
public:
    SlicerRange(Iterator b, Iterator e) : begin_(b), end_(e) {}

    Iterator begin() const {
        return begin_;
    }

    Iterator end() const {
        return end_;
    }

    size_t size() const {
        return distance(begin_, end_);
    }
};

template<class Iterator>
class Slicer {
private:
    size_t size_;
    vector<SlicerRange<Iterator>> pages_;
public:
    Slicer(Iterator b, Iterator e, size_t page_size) {
        auto d = distance(b, e);
        size_ = d / page_size + (d % page_size != 0 ? 1 : 0);
        for (int i = 0; i < size_; ++i) {
            auto b_it = next(b, page_size * i);
            auto e_it = (i == size_ - 1 ? e : next(b_it, page_size));
            pages_.push_back({b_it, e_it});
        }
    }

    size_t size() const {
        return size_;
    }

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

    auto end() {
        return pages_.end();
    }
};

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