#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());
}