#include <iterator>

template<typename T, typename Iterator>
Iterator Find(const T &value, Iterator first, Iterator last, std::bidirectional_iterator_tag) {
    while (first != last) {
        if (*first == value) {
            return first;
        }
        first++;
    }
    return last;
}

template<typename T, typename Iterator>
Iterator Find(const T &value, Iterator first, Iterator last, std::random_access_iterator_tag) {
    while (first != last) {
        Iterator middle = (last - first) / 2 + first;
        if (value > *middle) {
            first = middle + 1;
        } else {
            last = middle;
        }
    }
    return last;
}

template<typename T, typename Iterator>
Iterator Find(const T &value, Iterator first, Iterator last) {
    return Find(value, first, last, typename std::iterator_traits<Iterator>::iterator_category());
}