def merge(a_intervals, b_intervals, op):
        a_endpoints = a_intervals.flatten().tolist()
        b_endpoints = b_intervals.flatten().tolist()
        sentinel = max(a_endpoints[-1], b_endpoints[-1]) + 1
        a_endpoints += [sentinel]
        b_endpoints += [sentinel]
        a_index = 0
        b_index = 0
        res = []
        scan = min(a_endpoints[0], b_endpoints[0])
        while scan < sentinel:
            in_a = not ((scan < a_endpoints[a_index]) ^ (a_index % 2))
            in_b = not ((scan < b_endpoints[b_index]) ^ (b_index % 2))
            in_res = op(in_a, in_b)
            if in_res ^ (len(res) % 2):
                res += [scan]
            if scan == a_endpoints[a_index]:
                a_index += 1
            if scan == b_endpoints[b_index]:
                b_index += 1
            scan = min(a_endpoints[a_index], b_endpoints[b_index])
        return np.asarray(res).reshape((-1, 2))