#include <iostream>
#include <utility>

template <class U, class V>
struct intersect_impl;

template <class U, class V>
bool intersect(const U& u, const V& v) {
    return intersect_impl<U, V>::apply(u, v);
}

template<>
struct intersect_impl<std::pair<int, int>, int> {
    static bool apply(const std::pair<int, int>& interval, int value) {
        return interval.first <= value && value <= interval.second;
    }
};

template<>
struct intersect_impl<std::pair<int, int>, std::pair<int, int>> {
    static bool apply(const std::pair<int, int>& u, const std::pair<int, int>& v) {
        return intersect(u, v.first) || intersect(u, v.second);
    }
};

int main() {
    std::cout << "[0, 2] ∩ 1 ? " << intersect(std::make_pair(0, 2), 1) << "\n";
    std::cout << "[0, 2] ∩ 1 [3, 4] ? " << intersect(std::make_pair(0, 2), std::make_pair(3, 4)) << "\n";
    std::cout << "[0, 2] ∩ 1 [1, 4] ? " << intersect(std::make_pair(0, 2), std::make_pair(1, 4)) << "\n";
    return 0;
}