Skip to the content.

:heavy_check_mark: include/all.hpp

Depends on

Verified with

Code

#pragma once

#include "include/actions.hpp"
#include "include/adaptors.hpp"
#include "include/algebraic.hpp"
#include "include/convolutions.hpp"
#include "include/data_structures.hpp"
#include "include/geometries.hpp"
#include "include/graph_theory.hpp"
#include "include/hashes.hpp"
#include "include/iterable.hpp"
#include "include/numeric.hpp"
#include "include/snippets.hpp"
#include "include/views.hpp"

#include "random/adaptor.hpp"
#include "random/engine.hpp"

#include "utility/functional.hpp"
#include "utility/restrictor.hpp"
#include "utility/string.hpp"
#include "utility/timer.hpp"

#include "global/constants.hpp"

#include "structure/graph.hpp"
#include "structure/grid.hpp"
#line 2 "include/all.hpp"

#line 2 "include/actions.hpp"

#line 2 "action/base.hpp"


#include <cstddef>
#include <concepts>


#line 2 "internal/dev_env.hpp"


#ifdef LOCAL_JUDGE
    inline constexpr bool DEV_ENV = true;
    inline constexpr bool NO_EXCEPT = false;
#else
    inline constexpr bool DEV_ENV = false;
    inline constexpr bool NO_EXCEPT = true;
#endif // LOCAL_JUDGE


#if __cplusplus >= 202100L
    #define CPP20 true
    #define CPP23 true
#elif __cplusplus >= 202002L
    #define CPP20 true
    #define CPP23 false
#else
    #define CPP20 false
    #define CPP23 false
#endif
#line 2 "internal/types.hpp"

#include <cstdint>

namespace uni {

namespace internal {


using size_t = std::int64_t;

using int128_t = __int128_t;
using uint128_t = __uint128_t;


} // namesapce internal

} // namespace uni
#line 2 "internal/dummy.hpp"


namespace uni {

namespace internal {


struct dummy {};


} // namespace internal

} // namespace uni
#line 11 "action/base.hpp"

#line 2 "algebraic/internal/concepts.hpp"


#include <type_traits>
#line 6 "algebraic/internal/concepts.hpp"


#line 2 "internal/concepts.hpp"


#line 6 "internal/concepts.hpp"
#include <ranges>
#include <limits>
#include <functional>


namespace uni {

namespace internal {


template<class R, class T>
concept convertibel_range = std::convertible_to<std::ranges::range_value_t<R>, T>;


template<class T, class V>
concept item_or_convertible_range = std::convertible_to<T, V> || convertibel_range<T, V>;


template<class Structure>
concept available =
    requires () {
        typename Structure;
    };

template<
    template<class...> class Structure,
    class... TemplateParameters
>
concept available_with = available<Structure<TemplateParameters...>>;


template<class T> concept arithmetic = std::is_arithmetic_v<T>;
template<class T> concept pointer = std::is_pointer_v<T>;
template<class T> concept structural = std::is_class_v<T>;


template<class Large, class Small>
concept has_double_digits_of = (std::numeric_limits<Large>::digits == 2 * std::numeric_limits<Small>::digits);


template<class Large, class Small>
concept has_more_digits_than = (std::numeric_limits<Large>::digits > std::numeric_limits<Small>::digits);

template<class Large, class Small>
concept has_or_more_digits_than = (std::numeric_limits<Large>::digits >= std::numeric_limits<Small>::digits);


template<class T>
concept has_static_zero = requires { T::zero; };

template<class T>
concept has_static_one = requires { T::one; };


template<class L, class R = L>
concept weakly_bitand_calcurable = requires (L lhs, R rhs) { lhs & rhs; };

template<class L, class R = L>
concept weakly_bitor_calcurable = requires (L lhs, R rhs) { lhs | rhs; };

template<class L, class R = L>
concept weakly_bitxor_calcurable = requires (L lhs, R rhs) { lhs ^ rhs; };

template<class L, class R = L>
concept weakly_addable = requires (L lhs, R rhs) { lhs + rhs; };

template<class L, class R = L>
concept weakly_subtractable = requires (L lhs, R rhs) { lhs - rhs; };

template<class L, class R = L>
concept weakly_multipliable = requires (L lhs, R rhs) { lhs * rhs; };

template<class L, class R = L>
concept weakly_divisable = requires (L lhs, R rhs) { lhs / rhs; };

template<class L, class R = L>
concept weakly_remainder_calculable = requires (L lhs, R rhs) { lhs % rhs; };


template<class L, class R = L>
concept weakly_bitand_assignable = requires (L lhs, R rhs) { lhs += rhs; };

template<class L, class R = L>
concept weakly_bitor_assignable = requires (L lhs, R rhs) { lhs |= rhs; };

template<class L, class R = L>
concept weakly_bitxor_assignable = requires (L lhs, R rhs) { lhs ^= rhs; };

template<class L, class R = L>
concept weakly_addition_assignable = requires (L lhs, R rhs) { lhs += rhs; };

template<class L, class R = L>
concept weakly_subtraction_assignable = requires (L lhs, R rhs) { lhs -= rhs; };

template<class L, class R = L>
concept weakly_multipliation_assignalbe = requires (L lhs, R rhs) { lhs *= rhs; };

template<class L, class R = L>
concept weakly_division_assignable = requires (L lhs, R rhs) { lhs /= rhs; };

template<class L, class R = L>
concept weakly_remainder_assignable = requires (L lhs, R rhs) { lhs /= rhs; };


template<class L, class R = L>
concept bitand_calculable =
    weakly_bitand_calcurable<L, R> &&
    weakly_bitand_calcurable<std::invoke_result_t<std::bit_and<>&, L, R>, R> &&
    weakly_bitand_calcurable<L, std::invoke_result_t<std::bit_and<>&, L, R>> &&
    weakly_bitand_calcurable<std::invoke_result_t<std::bit_and<>&, L, R>, std::invoke_result_t<std::bit_and<>&, L, R>>;

template<class L, class R = L>
concept bitor_calculable =
    weakly_bitor_calcurable<L, R> &&
    weakly_bitor_calcurable<std::invoke_result_t<std::bit_or<>&, L, R>, R> &&
    weakly_bitor_calcurable<L, std::invoke_result_t<std::bit_or<>&, L, R>> &&
    weakly_bitor_calcurable<std::invoke_result_t<std::bit_or<>&, L, R>, std::invoke_result_t<std::bit_or<>&, L, R>>;

template<class L, class R = L>
concept bitxor_calculable =
    weakly_bitxor_calcurable<L, R> &&
    weakly_bitxor_calcurable<std::invoke_result_t<std::bit_xor<>&, L, R>, R> &&
    weakly_bitxor_calcurable<L, std::invoke_result_t<std::bit_xor<>&, L, R>> &&
    weakly_bitxor_calcurable<std::invoke_result_t<std::bit_xor<>&, L, R>, std::invoke_result_t<std::bit_xor<>&, L, R>>;

template<class L, class R = L>
concept addable =
    weakly_addable<L, R> &&
    weakly_addable<std::invoke_result_t<std::plus<>&, L, R>, R> &&
    weakly_addable<L, std::invoke_result_t<std::plus<>&, L, R>> &&
    weakly_addable<std::invoke_result_t<std::plus<>&, L, R>, std::invoke_result_t<std::plus<>&, L, R>>;

template<class L, class R = L>
concept subtractable =
    weakly_subtractable<L, R> &&
    weakly_subtractable<std::invoke_result_t<std::minus<>&, L, R>, R> &&
    weakly_subtractable<L, std::invoke_result_t<std::minus<>&, L, R>> &&
    weakly_subtractable<std::invoke_result_t<std::minus<>&, L, R>, std::invoke_result_t<std::minus<>&, L, R>>;

template<class L, class R = L>
concept multipliable =
    weakly_multipliable<L, R> &&
    weakly_multipliable<std::invoke_result_t<std::multiplies<>&, L, R>, R> &&
    weakly_multipliable<L, std::invoke_result_t<std::multiplies<>&, L, R>> &&
    weakly_multipliable<std::invoke_result_t<std::multiplies<>&, L, R>, std::invoke_result_t<std::multiplies<>&, L, R>>;

template<class L, class R = L>
concept divisable =
    weakly_divisable<L, R> &&
    weakly_divisable<std::invoke_result_t<std::divides<>&, L, R>, R> &&
    weakly_divisable<L, std::invoke_result_t<std::divides<>&, L, R>> &&
    weakly_divisable<std::invoke_result_t<std::divides<>&, L, R>, std::invoke_result_t<std::divides<>&, L, R>>;

template<class L, class R = L>
concept remainder_calculable =
    weakly_remainder_calculable<L, R> &&
    weakly_remainder_calculable<std::invoke_result_t<std::modulus<>&, L, R>, R> &&
    weakly_remainder_calculable<L, std::invoke_result_t<std::modulus<>&, L, R>> &&
    weakly_remainder_calculable<std::invoke_result_t<std::modulus<>&, L, R>, std::invoke_result_t<std::modulus<>&, L, R>>;


template<class L, class R = L>
concept bitand_assignable =
    weakly_bitand_assignable<L, R> &&
    weakly_bitand_assignable<std::invoke_result_t<std::bit_and<>&, L, R>, R> &&
    weakly_bitand_assignable<L, std::invoke_result_t<std::bit_and<>&, L, R>> &&
    weakly_bitand_assignable<std::invoke_result_t<std::bit_and<>&, L, R>, std::invoke_result_t<std::bit_and<>&, L, R>>;

template<class L, class R = L>
concept bitor_assignable =
    weakly_bitor_calcurable<L, R> &&
    weakly_bitor_calcurable<std::invoke_result_t<std::bit_or<>&, L, R>, R> &&
    weakly_bitor_calcurable<L, std::invoke_result_t<std::bit_or<>&, L, R>> &&
    weakly_bitor_calcurable<std::invoke_result_t<std::bit_or<>&, L, R>, std::invoke_result_t<std::bit_or<>&, L, R>>;

template<class L, class R = L>
concept bitxor_assignable =
    weakly_bitxor_calcurable<L, R> &&
    weakly_bitxor_calcurable<std::invoke_result_t<std::bit_xor<>&, L, R>, R> &&
    weakly_bitxor_calcurable<L, std::invoke_result_t<std::bit_xor<>&, L, R>> &&
    weakly_bitxor_calcurable<std::invoke_result_t<std::bit_xor<>&, L, R>, std::invoke_result_t<std::bit_xor<>&, L, R>>;

template<class L, class R = L>
concept addition_assignable =
    weakly_addition_assignable<L, R> &&
    weakly_addition_assignable<std::remove_cvref_t<std::invoke_result_t<std::plus<>&, L, R>>, R> &&
    weakly_addition_assignable<L, std::invoke_result_t<std::plus<>&, L, R>> &&
    weakly_addition_assignable<std::remove_cvref_t<std::invoke_result_t<std::plus<>&, L, R>>, std::invoke_result_t<std::plus<>&, L, R>>;

template<class L, class R = L>
concept subtraction_assignable =
    weakly_subtraction_assignable<L, R> &&
    weakly_subtraction_assignable<std::remove_cvref_t<std::invoke_result_t<std::minus<>&, L, R>>, R> &&
    weakly_subtraction_assignable<L, std::invoke_result_t<std::minus<>&, L, R>> &&
    weakly_subtraction_assignable<std::remove_cvref_t<std::invoke_result_t<std::minus<>&, L, R>>, std::invoke_result_t<std::minus<>&, L, R>>;

template<class L, class R = L>
concept multipliation_assignalbe =
    weakly_multipliation_assignalbe<L, R> &&
    weakly_multipliation_assignalbe<std::remove_cvref_t<std::invoke_result_t<std::multiplies<>&, L, R>>, R> &&
    weakly_multipliation_assignalbe<L, std::invoke_result_t<std::multiplies<>&, L, R>> &&
    weakly_multipliation_assignalbe<std::remove_cvref_t<std::invoke_result_t<std::multiplies<>&, L, R>>, std::invoke_result_t<std::multiplies<>&, L, R>>;

template<class L, class R = L>
concept division_assignable =
    weakly_division_assignable<L, R> &&
    weakly_division_assignable<std::remove_cvref_t<std::invoke_result_t<std::divides<>&, L, R>>, R> &&
    weakly_division_assignable<L, std::invoke_result_t<std::divides<>&, L, R>> &&
    weakly_division_assignable<std::remove_cvref_t<std::invoke_result_t<std::divides<>&, L, R>>, std::invoke_result_t<std::divides<>&, L, R>>;

template<class L, class R = L>
concept remainder_assignable =
    weakly_remainder_assignable<L, R> &&
    weakly_remainder_assignable<std::remove_cvref_t<std::invoke_result_t<std::modulus<>&, L, R>>, R> &&
    weakly_remainder_assignable<L, std::invoke_result_t<std::modulus<>&, L, R>> &&
    weakly_remainder_assignable<std::remove_cvref_t<std::invoke_result_t<std::modulus<>&, L, R>>, std::invoke_result_t<std::modulus<>&, L, R>>;


template<class T>
concept weakly_incrementable =
    std::movable<T> &&
    requires (T v) {
        { ++v } -> std::same_as<T&>;
        v++;
    };

template<class T>
concept weakly_decrementable =
    std::movable<T> &&
    requires (T v) {
        { --v } -> std::same_as<T&>;
        v--;
    };


template<class T>
concept incrementable =
    std::regular<T> &&
    weakly_incrementable<T> &&
    requires (T v) {
        { v++ } -> std::same_as<T>;
    };

template<class T>
concept decrementable =
    std::regular<T> &&
    weakly_decrementable<T> &&
    requires (T v) {
        { v-- } -> std::same_as<T>;
    };


template<class L, class R = L>
concept weakly_arithmetic_operable =
    weakly_addable<L, R> &&
    weakly_subtractable<L, R> &&
    weakly_multipliable<L, R> &&
    weakly_divisable<L, R>;

template<class L, class R = L>
concept weakly_arithmetic_operation_assignable =
    weakly_addition_assignable<L, R> &&
    weakly_subtraction_assignable<L, R> &&
    weakly_multipliation_assignalbe<L, R> &&
    weakly_division_assignable<L, R>;

template<class L, class R = L>
concept arithmetic_operable =
    weakly_arithmetic_operable<L, R> &&
    addable<L, R> &&
    subtractable<L, R> &&
    multipliable<L, R> &&
    divisable<L, R>;

template<class L, class R = L>
concept arithmetic_operation_assignable =
    weakly_arithmetic_operation_assignable<L, R> &&
    addition_assignable<L, R> &&
    subtraction_assignable<L, R> &&
    multipliation_assignalbe<L, R> &&
    division_assignable<L, R>;


template<class T>
concept unary_addable =
    requires (T v) {
        { +v } -> std::same_as<T>;
    };

template<class T>
concept unary_subtractable =
    requires (T v) {
        { -v } -> std::same_as<T>;
    };


template<class T>
concept numeric =
    std::regular<T> &&
    arithmetic_operable<T> &&
    arithmetic_operation_assignable<T> &&
    weakly_incrementable<T> &&
    unary_addable<T> &&
    unary_subtractable<T>;


} // namespace internal

} // namespace uni
#line 9 "algebraic/internal/concepts.hpp"

#line 2 "algebraic/base.hpp"


#include <utility>
#line 6 "algebraic/base.hpp"


#line 2 "numeric/arithmetic.hpp"


#include <cassert>
#include <cstring>
#line 7 "numeric/arithmetic.hpp"
#include <string>
#line 10 "numeric/arithmetic.hpp"
#include <optional>
#include <algorithm>
#line 13 "numeric/arithmetic.hpp"
#include <bit>


#include <atcoder/math>


#line 2 "snippet/aliases.hpp"


#line 6 "snippet/aliases.hpp"
#include <vector>
#line 8 "snippet/aliases.hpp"


#line 2 "snippet/internal/types.hpp"

#line 4 "snippet/internal/types.hpp"

namespace uni {


using i16 = std::int16_t;
using u16 = std::uint16_t;

using i32 = std::int32_t;
using u32 = std::uint32_t;

using i64 = std::int64_t;
using u64 = std::uint64_t;

#ifdef __GNUC__

using i128 = __int128_t;
using u128 = __uint128_t;

using f128 = __float128;

#endif

using uint = unsigned;
using ll = long long;
using ull = unsigned long long;
using ld = long double;


} // namespace uni
#line 12 "snippet/aliases.hpp"


#define until(...) while(!(__VA_ARGS__))

#define CONTINUE(...) { __VA_ARGS__; continue; }
#define BREAK(...) { __VA_ARGS__; break; }

#define ALL(x) std::ranges::begin((x)),std::ranges::end((x))
#define RALL(x) std::ranges::rbegin((x)),std::ranges::rend((x))


#define $F first
#define $S second


namespace uni {


constexpr char LN = '\n';
constexpr char SPC = ' ';


constexpr std::pair<int,int> DIRS4[] = { { -1, 0 }, { 0, 1 }, { 1, 0 }, { 0, -1 } };
constexpr std::pair<int,int> DIRS4P[] = { { -1, 0 }, { 0, 1 }, { 1, 0 }, { 0, -1 }, { 0, 0 } };
constexpr std::pair<int,int> DIRS8[] = { { -1, 0 }, { -1, 1 }, { 0, 1 }, { 1, 1 }, { 1, 0 }, { 1, -1 }, { 0, -1 }, { -1, -1 } };
constexpr std::pair<int,int> DIRS8P[] = { { -1, 0 }, { -1, 1 }, { 0, 1 }, { 1, 1 }, { 1, 0 }, { 1, -1 }, { 0, -1 }, { -1, -1 }, { 0, 0 } };


template<class T> using spair = std::pair<T,T>;


}  // namespace uni


namespace std {

using bit_reference = std::vector<bool>::reference;

bit_reference operator |= (bit_reference a, const bool b) noexcept(NO_EXCEPT) { return a = a | b; }
bit_reference operator &= (bit_reference a, const bool b) noexcept(NO_EXCEPT) { return a = a & b; }

}
#line 2 "snippet/iterations.hpp"

#line 2 "macro/overload.hpp"

#define $OVERLOAD2(arg0, arg1, cmd, ...) cmd
#define $OVERLOAD3(arg0, arg1, arg2, cmd, ...) cmd
#define $OVERLOAD4(arg0, arg1, arg2, arg3, cmd, ...) cmd
#define $OVERLOAD5(arg0, arg1, arg2, arg3, arg4, cmd, ...) cmd
#define $OVERLOAD6(arg0, arg1, arg2, arg3, arg4, arg5, cmd, ...) cmd
#line 2 "macro/basic.hpp"

#define TO_STRING_AUX(x) #x
#define TO_STRING(x) TO_STRING_AUX(x)

#define CONCAT_AUX(x, y) x##y
#define CONCAT(x, y) CONCAT_AUX(x, y)

#define UNPAREN_AUX(...) __VA_ARGS__
#define UNPAREN(...) __VA_ARGS__
#line 6 "snippet/iterations.hpp"


#define LOOP(n) REPI(CONCAT(_$, __COUNTER__), n)

#define REPI(i,n) for(std::remove_cvref_t<decltype(n)> i=0, CONCAT(i, $)=(n); i<CONCAT(i, $); ++i)
#define REPF(i,l,r) for(std::common_type_t<std::remove_cvref_t<decltype(l)>,std::remove_cvref_t<decltype(r)>> i=(l), CONCAT(i, $)=(r); i<CONCAT(i, $); ++i)
#define REPIS(i,l,r,s) for(std::common_type_t<std::remove_cvref_t<decltype(l)>,std::remove_cvref_t<decltype(r)>,std::remove_cvref_t<decltype(s)>> i=(l), CONCAT(i, $)=(r); i<CONCAT(i, $); i+=(s))

#define REPR(i,n) for(auto i=(n); --i>=0;)
#define REPB(i,l,r) for(std::common_type_t<std::remove_cvref_t<decltype(l)>,std::remove_cvref_t<decltype(r)>> i=(r), CONCAT(i, $)=(l); --i>=CONCAT(i, $);)
#define REPRS(i,l,r,s) for(std::common_type_t<std::remove_cvref_t<decltype(l)>,std::remove_cvref_t<decltype(r)>,std::remove_cvref_t<decltype(s)>> i=(l)+((r)-(l)-1)/(s)*(s), CONCAT(i, $)=(l); i>=CONCAT(i, $); (i-=(s)))

#define REP(...) $OVERLOAD4(__VA_ARGS__, REPIS, REPF, REPI, LOOP)(__VA_ARGS__)
#define REPD(...) $OVERLOAD4(__VA_ARGS__, REPRS, REPB, REPR)(__VA_ARGS__)

#define FORO(i,n) for(int i=0, CONCAT(i, $)=static_cast<int>(n); i<=CONCAT(i, $); ++i)
#define FORI(i,l,r) for(std::common_type_t<std::remove_cvref_t<decltype(l)>,std::remove_cvref_t<decltype(r)>> i=(l), CONCAT(i, $)=(r); i<=CONCAT(i, $); ++i)
#define FORIS(i,l,r,s) for(std::common_type_t<std::remove_cvref_t<decltype(l)>,std::remove_cvref_t<decltype(r)>,std::remove_cvref_t<decltype(s)>> i=(l), CONCAT(i, $)=(r); i<=CONCAT(i, $); i+=(s))

#define FORRO(i,n) for(auto i=(n); i>=0; --i)
#define FORR(i,l,r) for(std::common_type_t<std::remove_cvref_t<decltype(l)>,std::remove_cvref_t<decltype(r)>> i=(r), CONCAT(i, $)=(l); i>=CONCAT(i, $); --i)
#define FORRS(i,l,r,s) for(std::common_type_t<std::remove_cvref_t<decltype(l)>,std::remove_cvref_t<decltype(r)>,std::remove_cvref_t<decltype(s)>> i=(l)+((r)-(l))/(s)*(s), CONCAT(i, $)=(l); i>=CONCAT(i, $); i-=(s))

#define FOR(...) $OVERLOAD4(__VA_ARGS__, FORIS, FORI, FORO)(__VA_ARGS__)
#define FORD(...) $OVERLOAD4(__VA_ARGS__, FORRS, FORR, FORRO)(__VA_ARGS__)

#define ITR1(e0,v) for(const auto &e0 : (v))
#define ITRP1(e0,v) for(auto e0 : (v))
#define ITRR1(e0,v) for(auto &e0 : (v))

#define ITR2(e0,e1,v) for(const auto [e0, e1] : (v))
#define ITRP2(e0,e1,v) for(auto [e0, e1] : (v))
#define ITRR2(e0,e1,v) for(auto &[e0, e1] : (v))

#define ITR3(e0,e1,e2,v) for(const auto [e0, e1, e2] : (v))
#define ITRP3(e0,e1,e2,v) for(auto [e0, e1, e2] : (v))
#define ITRR3(e0,e1,e2,v) for(auto &[e0, e1, e2] : (v))

#define ITR4(e0,e1,e2,e3,v) for(const auto [e0, e1, e2, e3] : (v))
#define ITRP4(e0,e1,e2,e3,v) for(auto [e0, e1, e2, e3] : (v))
#define ITRR4(e0,e1,e2,e3,v) for(auto &[e0, e1, e2, e3] : (v))

#define ITR5(e0,e1,e2,e3,e4,v) for(const auto [e0, e1, e2, e3, e4] : (v))
#define ITRP5(e0,e1,e2,e3,e4,v) for(auto [e0, e1, e2, e3, e4] : (v))
#define ITRR5(e0,e1,e2,e3,e4,v) for(auto &[e0, e1, e2, e3, e4] : (v))

#define ITR(...) $OVERLOAD6(__VA_ARGS__, ITR5, ITR4, ITR3, ITR2, ITR1)(__VA_ARGS__)
#define ITRP(...) $OVERLOAD6(__VA_ARGS__, ITRP5, ITRP4, ITRP3, ITRP2, ITRP1)(__VA_ARGS__)
#define ITRR(...) $OVERLOAD6(__VA_ARGS__, ITRR5, ITRR4, ITRR3, ITRR2, ITRR1)(__VA_ARGS__)
#line 21 "numeric/arithmetic.hpp"

#line 25 "numeric/arithmetic.hpp"

#line 2 "utility/internal/functional_base.hpp"


namespace uni {


template<class P>
    requires
        requires(P p) {
            p.first;
            p.second;
        }
inline P swapped(P& pair) {
    return P{ pair.second, pair.first };
}


} // namespace uni
#line 27 "numeric/arithmetic.hpp"

#line 2 "numeric/internal/number_base.hpp"


#line 6 "numeric/internal/number_base.hpp"
#include <string_view>
#line 14 "numeric/internal/number_base.hpp"


#line 18 "numeric/internal/number_base.hpp"

#line 2 "adaptor/string.hpp"


#line 6 "adaptor/string.hpp"

#line 2 "adaptor/internal/advanced_container.hpp"


#line 8 "adaptor/internal/advanced_container.hpp"

#line 11 "adaptor/internal/advanced_container.hpp"

#line 15 "adaptor/internal/advanced_container.hpp"

#line 2 "numeric/internal/mod.hpp"


#line 6 "numeric/internal/mod.hpp"


namespace uni {


template<class T, class R>
    requires
        internal::remainder_calculable<T, R> &&
        internal::subtractable<T, R> &&
        internal::unary_subtractable<T>
inline T mod(T x, const R& r) noexcept(NO_EXCEPT) {
    if(x >= 0) return x % r;
    x = -x % r;
    if(x != 0) x = r - x;
    return x;
}


} // namespace uni
#line 2 "iterable/internal/operation_base.hpp"


#line 5 "iterable/internal/operation_base.hpp"
#include <iterator>
#include <sstream>
#include <numeric>


#line 11 "iterable/internal/operation_base.hpp"


namespace uni {


template<std::input_iterator I, std::sentinel_for<I> S>
std::string join(I first, S last, const char* sep = "") noexcept(NO_EXCEPT) {
    if(first == last) return "";
    std::ostringstream res;
    while(true) {
        res << *first;
        std::ranges::advance(first, 1);
        if(first == last) break;
        res << sep;
    }
    return res.str();
}


template<std::ranges::input_range R>
std::string join(R&& range, const char* sep = "") noexcept(NO_EXCEPT) {
    return join(ALL(range), sep);
}


template<class I, class T = std::iter_value_t<I>>
    requires std::sentinel_for<I, I>
T sum(I first, I last, const T& base = T()) noexcept(NO_EXCEPT) {
    return std::accumulate(first, last, base);
}

template<std::ranges::input_range R, class T = std::ranges::range_value_t<R>>
auto sum(R&& range, T base = T()) noexcept(NO_EXCEPT) {
    auto&& r = range | std::views::common;
    return sum(ALL(r), base);
}


} // namesapce uni
#line 18 "adaptor/internal/advanced_container.hpp"


#define UNI_ADVANCED_CONTAINER_OPERATOR(op_assign, op, concepts) \
    auto& operator op_assign(const value_type& v) noexcept(NO_EXCEPT) \
        requires concepts<value_type> \
    { \
        if constexpr(concepts<Base, value_type>) { \
            this->Base::operator op_assign(v); \
        } \
        else { \
            REP(itr, ALL(*this)) *itr op_assign v; \
        } \
        return *this; \
    } \
    \
    auto& operator op_assign(const advanced_container& rhs) noexcept(NO_EXCEPT) \
        requires concepts<value_type> \
    { \
        if constexpr(concepts<Base>) { \
            this->Base::operator op_assign(*rhs._base()); \
        } \
        else { \
            auto itr = std::ranges::begin(*this), rhs_itr = std::ranges::begin(rhs); \
            auto end = std::ranges::end(*this); \
            for(; itr != end; ++itr, ++rhs_itr) { \
                *itr op_assign *rhs_itr; \
            } \
        } \
        return *this; \
    } \
    \
    template<class T = value_type> \
        requires \
            concepts<value_type> && \
            (std::convertible_to<T, value_type> || std::same_as<T, advanced_container>) \
    friend auto operator op(advanced_container lhs, const T& rhs) noexcept(NO_EXCEPT) { \
        return lhs op_assign rhs; \
    } \
    \
    template<class T = value_type> \
        requires \
            concepts<value_type> && std::convertible_to<T, value_type> \
    friend auto operator op(const T& lhs, advanced_container rhs) noexcept(NO_EXCEPT) { \
        return advanced_container(rhs.size(), lhs) op_assign rhs; \
    }


namespace uni {

namespace internal {


template<class Base>
struct advanced_container : Base {
  private:
    inline Base* _base() noexcept(NO_EXCEPT) {
        return static_cast<Base*>(this);
    }
    inline const Base* _base() const noexcept(NO_EXCEPT) {
        return static_cast<const Base*>(this);
    }

  public:
    using Base::Base;

    advanced_container(const Base& base) : Base(base) {}

    using size_type = decltype(std::ranges::size(std::declval<Base>()));
    using value_type = Base::value_type;

    inline auto ssize() const noexcept(NO_EXCEPT) { return std::ranges::ssize(*this->_base()); }


    inline const auto& operator[](internal::size_t p) const noexcept(NO_EXCEPT) {
        p = p < 0 ? p + this->size() : p;
        assert(0 <= p && p < this->ssize());
        return this->Base::operator[](p);
    }

    inline auto& operator[](internal::size_t p) noexcept(NO_EXCEPT) {
        p = p < 0 ? p + this->size() : p;
        assert(0 <= p && p < this->ssize());
        return this->Base::operator[](p);
    }


    inline auto& fill(const value_type& v) noexcept(NO_EXCEPT) {
        std::ranges::fill(*this, v);
        return *this;
    }

    inline auto& swap(const size_type i, const size_type j) noexcept(NO_EXCEPT) {
        std::swap(this->operator[](i), this->operator[](j));
        return *this;
    }

    inline auto& sort() noexcept(NO_EXCEPT) {
        std::ranges::sort(*this);
        return *this;
    }

    template<class F>
    inline auto& sort(F&& f) noexcept(NO_EXCEPT) {
        std::ranges::sort(*this, std::forward<F>(f));
        return *this;
    }

    inline auto& stable_sort() noexcept(NO_EXCEPT) {
        std::ranges::stable_sort(*this);
        return *this;
    }

    template<class F>
    inline auto& stable_sort(F&& f) noexcept(NO_EXCEPT) {
        std::ranges::stable_sort(*this, std::forward<F>(f));
        return *this;
    }

    inline auto& reverse() noexcept(NO_EXCEPT) {
        std::ranges::reverse(*this);
        return *this;
    }

    inline auto count(const value_type& v) const noexcept(NO_EXCEPT) {
        return std::ranges::count(*this, v);
    }

    template<class F>
    inline auto count_if(F&& f) const noexcept(NO_EXCEPT) {
        return std::ranges::count_if(*this, std::forward<F>(f));
    }

    inline auto& resize(const size_type k) noexcept(NO_EXCEPT) {
        this->Base::resize(k);
        return *this;
    }
    inline auto& resize(const size_type k, const value_type v) noexcept(NO_EXCEPT) {
        this->Base::resize(k, v);
        return *this;
    }

    template<class F>
    inline auto& shuffle(F&& f) noexcept(NO_EXCEPT) {
        std::ranges::shuffle(*this, std::forward<F>(f));
        return *this;
    }

    inline auto& unique() noexcept(NO_EXCEPT) {
        const auto rest = std::ranges::unique(*this);
        this->erase(ALL(rest));
        return *this;
    }

    template<class T>
    inline auto binary_search(const T& v) noexcept(NO_EXCEPT) {
        return std::ranges::binary_search(*this, v);
    }

    template<class T>
    inline auto lower_bound(const T& v) noexcept(NO_EXCEPT) {
        return std::ranges::lower_bound(*this, v);
    }

    template<class T>
    inline auto upper_bound(const T& v) noexcept(NO_EXCEPT) {
        return std::ranges::upper_bound(*this, v);
    }

    inline auto join(const char* sep = "") noexcept(NO_EXCEPT) {
        return uni::join(*this, sep);
    }


    inline auto sum() const noexcept(NO_EXCEPT) { return uni::sum(*this); }


    inline auto max() const noexcept(NO_EXCEPT) { return std::ranges::max(*this->_base()); }
    inline auto min() const noexcept(NO_EXCEPT) { return std::ranges::min(*this); }


    inline auto begin() noexcept(NO_EXCEPT) { return std::ranges::begin(*this->_base()); }
    inline auto begin() const noexcept(NO_EXCEPT) { return std::ranges::begin(*this->_base()); }

    inline auto end() noexcept(NO_EXCEPT) { return std::ranges::end(*this->_base()); }
    inline auto end() const noexcept(NO_EXCEPT) { return std::ranges::end(*this->_base()); }


    UNI_ADVANCED_CONTAINER_OPERATOR(+=, +, internal::weakly_addition_assignable)
    UNI_ADVANCED_CONTAINER_OPERATOR(-=, -, internal::weakly_subtraction_assignable)
    UNI_ADVANCED_CONTAINER_OPERATOR(*=, *, internal::weakly_multipliation_assignalbe)
    UNI_ADVANCED_CONTAINER_OPERATOR(/=, /, internal::weakly_division_assignable)
    UNI_ADVANCED_CONTAINER_OPERATOR(%=, %, internal::weakly_remainder_assignable)
    UNI_ADVANCED_CONTAINER_OPERATOR(&=, &, internal::weakly_bitand_assignable)
    UNI_ADVANCED_CONTAINER_OPERATOR(|=, |, internal::weakly_bitor_assignable)
    UNI_ADVANCED_CONTAINER_OPERATOR(^=, ^, internal::weakly_bitxor_assignable)
};


} // namespace internal

} // namespace uni

#undef UNI_ADVANCED_CONTAINER_OPERATOR
#line 8 "adaptor/string.hpp"


namespace uni {


using string = internal::advanced_container<std::string>;


} // namespace uni


namespace std {


template<>
struct hash<uni::string> {
    inline auto operator()(const uni::string& key) const noexcept(NO_EXCEPT) {
        return std::hash<std::string>{}(static_cast<std::string>(key));
    }
};



}
#line 2 "adaptor/vector.hpp"


#line 6 "adaptor/vector.hpp"


#line 9 "adaptor/vector.hpp"


namespace uni {


template<class... Args>
using vector = internal::advanced_container<std::vector<Args...>>;


} // namespace uni
#line 21 "numeric/internal/number_base.hpp"


namespace uni {


template<std::size_t B, class T>
uni::string to_base_n_string(T v) noexcept(NO_EXCEPT) {
    constexpr std::string_view CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    static_assert(0 < B and B <= std::ranges::size(CHARS));
    assert(0 <= v);

    uni::string res;
    while(v > 0) {
        res += CHARS[v%B];
        v /= B;
    }
    std::reverse(ALL(res));

    return res;
}


template<class T>
uni::string to_base_n_string(T v, const uni::internal::size_t b) noexcept(NO_EXCEPT) {
    constexpr std::string_view CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    assert(1 < b && b <= std::ranges::ssize(CHARS));
    assert(0 <= v);

    if(v == 0) return "0";

    uni::string res;

    while(v > 0) {
        res += CHARS[v % b];
        v /= b;
    }
    std::reverse(ALL(res));

    return res;
}

template<class T>
uni::vector<T> to_base_n_vector(T v, const uni::internal::size_t b) noexcept(NO_EXCEPT) {
    assert(1 < b);
    assert(0 <= v);

    uni::vector<T> res;

    while(v > 0) {
        res.push_back(v%b);
        v /= b;
    }


    return res;
}

template<std::bidirectional_iterator I, class T = typename std::iterator_traits<I>::value_type>
T from_base_n_sequence(I begin, I end, const uni::internal::size_t b) noexcept(NO_EXCEPT) {
    assert(1 < b);

    if(begin == end) return 0;

    T res = 0;
    for(auto itr=end; itr-- != begin; ) {
        res *= b;
        res += *itr;
    }

    return res;
}

template<class T, std::forward_iterator I>
T from_base_n_string(I begin, I end, const uni::internal::size_t b) noexcept(NO_EXCEPT) {
    assert(1 < b);

    if(begin == end) return 0;

    T sgn = 1;
    if(*begin == '-') {
        sgn = -1;
        ++begin;
    }

    T res = 0;
    for(auto itr=begin; itr != end; ++itr) {
        res *= b;
        if('0' <= *itr && *itr <= '9') {
            res += *itr - '0';
        }
        else if('a' <= *itr && *itr <= 'z') {
            res += *itr - 'a' + 10;
        }
        else if('A' <= *itr && *itr <= 'Z'){
            res += *itr - 'A' + 10;
        }
        else {
            assert(false);
        }
    }

    return res * sgn;
}


template<std::ranges::bidirectional_range R, class T = std::ranges::range_value_t<R>>
    requires std::ranges::common_range<R>
T from_base_n_sequence(R range, const uni::internal::size_t b) noexcept(NO_EXCEPT) {
    return from_base_n_sequence(std::ranges::begin(range), std::ranges::end(range), b);
}

template<class T, std::ranges::bidirectional_range R>
    requires std::ranges::common_range<R>
T from_base_n_string(R range, const uni::internal::size_t b) noexcept(NO_EXCEPT) {
    return from_base_n_string<T>(std::ranges::begin(range), std::ranges::end(range), b);
}



} // namespace uni
#line 29 "numeric/arithmetic.hpp"

#line 2 "iterable/operation.hpp"


#line 6 "iterable/operation.hpp"
#include <initializer_list>
#line 9 "iterable/operation.hpp"
#include <valarray>
#line 17 "iterable/operation.hpp"


#line 21 "iterable/operation.hpp"

#line 2 "internal/type_traits.hpp"


#include <iostream>
#line 9 "internal/type_traits.hpp"


#line 12 "internal/type_traits.hpp"


namespace uni {

namespace internal {


template<class... Ts> struct tuple_or_pair { using type = std::tuple<Ts...>; };
template<class T, class U> struct tuple_or_pair<T,U> { using type = std::pair<T, U>; };
template <class... Ts> using tuple_or_pair_t = typename tuple_or_pair<Ts...>::type;

template<class T>
constexpr std::underlying_type_t<T> to_underlying(const T& v) noexcept(NO_EXCEPT) {
    return static_cast<std::underlying_type_t<T>>(v);
}


template<class T, class... Ts>
using are_same = std::conjunction<std::is_same<T, Ts>...>;

template<class T, class... Ts>
inline constexpr bool are_same_v = are_same<T, Ts...>::value;


template<class T, class... Ts>
using is_same_as_any_of = std::disjunction<std::is_same<T, Ts>...>;

template<class T, class... Ts>
inline constexpr bool is_same_as_any_of_v = is_same_as_any_of<T, Ts...>::value;

template<class T, class... Ts>
concept same_as_any_of = is_same_as_any_of_v<T, Ts...>;


template<class Base, class... Derived>
using is_base_of_all = std::conjunction<std::is_base_of<Base, Derived>...>;

template<class Base, class... Derived>
inline constexpr bool is_base_of_all_v = is_base_of_all<Base, Derived...>::value;


template<class Base, class... Derived>
using is_base_of_any = std::disjunction<std::is_base_of<Base, Derived>...>;

template<class Base, class... Derived>
inline constexpr bool is_base_of_any_v = is_base_of_any<Base, Derived...>::value;


template<class T> struct remove_cvref {
  using type = typename std::remove_cv_t<std::remove_reference_t<T>>;
};

template<class T> using remove_cvref_t = typename remove_cvref<T>::type;


template<class T> struct literal_operator { static constexpr const char* value = ""; };

template<> struct literal_operator<unsigned> { static constexpr const char* value = "U"; };
template<> struct literal_operator<long> { static constexpr const char* value = "L"; };
template<> struct literal_operator<unsigned long> { static constexpr const char* value = "UL"; };
template<> struct literal_operator<long long> { static constexpr const char* value = "LL"; };
template<> struct literal_operator<unsigned long long> { static constexpr const char* value = "ULL"; };


template<> struct literal_operator<float> { static constexpr const char* value = "F"; };
template<> struct literal_operator<double> { static constexpr const char* value = "D"; };
template<> struct literal_operator<long double> { static constexpr const char* value = "LD"; };

#ifdef __SIZEOF_INT128__

template<> struct literal_operator<__int128_t> { static constexpr const char* value = "LLL"; };
template<> struct literal_operator<__uint128_t> { static constexpr const char* value = "ULLL"; };

#endif

template<class T> inline constexpr auto literal_operator_v = literal_operator<T>::value;


template <std::size_t N, typename... Types>
struct nth_type {};

template <class Head, class... Tail>
struct nth_type<0, Head, Tail...> {
	using type = Head;
};

template <std::size_t N, class Head, class... Tail>
struct nth_type<N, Head, Tail...> : public nth_type<N - 1, Tail...> {};

template <std::size_t N, typename... Types>
using nth_type_t = typename nth_type<N, Types...>::type;


template<template <class...> class, class> struct is_template_of : std::false_type {};
template<template <class...> class Template, class... Args> struct is_template_of<Template, Template<Args...>> : std::true_type {};

template<template <class...> class Template, class Type>
inline constexpr bool is_template_of_v = is_template_of<Template, Type>::value;

template<class Type, template <class...> class Template>
concept substituted_from = is_template_of_v<Template, Type>;

template<template <class...> class Base, class Derived>
struct _is_basic_tempalte_of
{
    template<class... Ts>
    static constexpr std::true_type  test(const Base<Ts...> *);

    static constexpr std::false_type test(...);

    using type = decltype(test(std::declval<Derived*>()));
};


template<template <class...> class Base, class Derived>
using is_basic_tempalte_of = _is_basic_tempalte_of<Base, Derived>::type;

template<template <class...> class Base, class Derived>
inline constexpr bool is_basic_tempalte_of_v = is_basic_tempalte_of<Base, Derived>::value;

template<class Derived, template <class...> class Base>
concept derived_from_template = is_basic_tempalte_of_v<Base, Derived>;


template<class T> struct is_loggable {
    template<class U>
    static constexpr auto External(U &&v) -> decltype(_debug(v), std::true_type());
    static constexpr std::false_type External(...);

    template<class U>
    static constexpr auto Member(U &&v) -> decltype(v._debug(), std::true_type());
    static constexpr std::false_type Member(...);

    static constexpr bool value = (
      decltype(External(std::declval<T>()))::value ||
      decltype(Member(std::declval<T>()))::value
    );

};

template<class T>
inline constexpr auto is_loggable_v = is_loggable<T>::value;

template<class T>
concept loggable = is_loggable_v<T>;


template<class T> struct _has_iterator {
    template<class U>
    static constexpr auto ADL(U &&v) -> decltype(begin(v), end(v), std::true_type());
    static constexpr std::false_type ADL(...);

    template<class U>
    static constexpr auto STL(U &&v) -> decltype(std::begin(v), std::end(v), std::true_type());
    static constexpr std::false_type STL(...);

    template<class U>
    static constexpr auto Member(U &&v) -> decltype(v.begin(), v.end(), std::true_type());
    static constexpr std::false_type Member(...);
};

template<class T> struct has_iterator {
    struct ADL : decltype(_has_iterator<T>::ADL(std::declval<T>())) {};
    struct STL : decltype(_has_iterator<T>::STL(std::declval<T>())) {};
    struct Member : decltype(_has_iterator<T>::Member(std::declval<T>())) {};

    static constexpr auto adl_v = ADL::value;
    static constexpr auto stl_v = STL::value;
    static constexpr auto member_v = Member::value;
};


template<class T>
struct is_iterable {
    static constexpr bool value =  has_iterator<T>::adl_v || has_iterator<T>::stl_v || has_iterator<T>::member_v;
};

template<class T>
inline constexpr auto is_iterable_v = is_iterable<T>::value;

template<class T>
concept iterable = is_iterable_v<T>;

namespace iterator_resolver {


template<class T>
inline constexpr auto begin(T&& v) noexcept(NO_EXCEPT) {
    static_assert(is_iterable_v<T>);
    if constexpr(has_iterator<T>::member_v) {
        return v.begin();
    }
    else {  // ADL
        using std::begin;
        return begin(std::forward<T>(v));
    }
}

template<class T>
inline constexpr auto end(T&& v) noexcept(NO_EXCEPT) {
    static_assert(is_iterable_v<T>);
    if constexpr(has_iterator<T>::member_v) {
        return v.end();
    }
    else {  // ADL
        using std::end;
        return end(std::forward<T>(v));
    }
}


};


template<class C> using iterator_t = decltype(iterator_resolver::begin(std::declval<C&>()));

template<class C> using container_size_t = decltype(std::size(std::declval<C&>()));


template<bool Const, class T>
using maybe_const_t = std::conditional_t<Const, const T, T>;


template<class T> using with_ref = T&;
template<class T> concept can_reference = requires { typename with_ref<T>; };


} // namespace internal

}  // namespace uni
#line 2 "internal/exception.hpp"


namespace uni {

namespace internal {


template<class... T> inline constexpr bool EXCEPTION_ON_TYPE = false;
template<auto T> inline constexpr bool EXCEPTION_ON_VALUE = false;


} // namespace internal

} // namespace uni
#line 2 "internal/iterator.hpp"


#line 7 "internal/iterator.hpp"
#include <variant>
#include <compare>
#line 10 "internal/iterator.hpp"


#line 13 "internal/iterator.hpp"

#line 16 "internal/iterator.hpp"


namespace uni {

namespace internal {


template<class T>
struct iterator_interface {
    using iterator_category = std::output_iterator_tag;

    using difference_type = size_t;
    using value_type = T;

    using pointer = T*;
    using reference = T&;

    // virtual T operator*() const noexcept(NO_EXCEPT) { return 0; };
};

template<class T>
struct forward_iterator : iterator_interface<T> {
    using iterator_category = std::forward_iterator_tag;

    // virtual bidirectional_iterator_interface& operator++() = 0;
};

template<class T>
struct bidirectional_iterator_interface : forward_iterator<T> {
    using iterator_category = std::bidirectional_iterator_tag;

    // virtual bidirectional_iterator_interface& operator--() = 0;
};

template<class T>
struct random_access_iterator_base : bidirectional_iterator_interface<T> {
    using iterator_category = std::random_access_iterator_tag;
    using difference_type = typename bidirectional_iterator_interface<T>::difference_type;

  public:
    // virtual random_access_iterator_base& operator+=(const difference_type count) = 0;
    // virtual random_access_iterator_base& operator-=(const difference_type count) = 0;

    friend inline random_access_iterator_base operator+(random_access_iterator_base itr, const difference_type count) noexcept(NO_EXCEPT) { return itr += count, itr; }
    friend inline random_access_iterator_base operator-(random_access_iterator_base itr, const difference_type count) noexcept(NO_EXCEPT) { return itr -= count, itr; }

};

template<class T, class Container, class Derived>
struct container_iterator_interface : random_access_iterator_base<T> {
    using difference_type = std::make_signed_t<typename Container::size_type>;

  private:
    using derived = std::remove_cvref_t<Derived>;

    Container* _ref;
    difference_type _pos;

    static_assert(std::three_way_comparable<difference_type>);

    inline auto* _derived() noexcept(NO_EXCEPT) {
        return static_cast<derived*>(this);
    }
    inline const auto* _derived() const noexcept(NO_EXCEPT) {
        return static_cast<const derived*>(this);
    }

  public:
    container_iterator_interface() noexcept = default;
    container_iterator_interface(Container *const ref, const difference_type pos) noexcept(NO_EXCEPT) : _ref(ref), _pos(pos) {}

    inline auto ref() const noexcept(NO_EXCEPT) { return this->_ref; }

    inline auto pos() const noexcept(NO_EXCEPT) { return this->_pos; }
    inline auto& pos() { return this->_pos; }

    inline auto& operator++() noexcept(NO_EXCEPT) { return ++this->_pos, *this->_derived(); }
    inline auto& operator--() noexcept(NO_EXCEPT) { return --this->_pos, *this->_derived(); }

    inline auto operator++(int) noexcept(NO_EXCEPT) { auto res = *this->_derived(); return ++this->_pos, res; }
    inline auto operator--(int) noexcept(NO_EXCEPT) { auto res = *this->_derived(); return --this->_pos, res; }

    inline auto& operator+=(const difference_type count) noexcept(NO_EXCEPT) { return this->_pos += count, *this->_derived(); }
    inline auto& operator-=(const difference_type count) noexcept(NO_EXCEPT) { return this->_pos -= count, *this->_derived(); }

    inline auto operator*() const noexcept(NO_EXCEPT) { return this->ref()->get(this->_pos); }
    inline auto operator[](const difference_type count) const noexcept(NO_EXCEPT) { return *(*this->_derived() + count); }

    inline auto operator-(const derived& other) const noexcept(NO_EXCEPT) { return this->_pos - other._pos; }


    friend inline bool operator==(const derived& lhs, const derived& rhs) noexcept(NO_EXCEPT) {
        if(lhs.ref() == rhs.ref()) return lhs._pos == rhs._pos;
        return false;
    }

    friend inline std::partial_ordering operator<=>(const derived& lhs, const derived& rhs) noexcept(NO_EXCEPT) {
        if(lhs.ref() != rhs.ref()) return std::partial_ordering::unordered;
        return lhs._pos <=> rhs._pos;
    }
};


namespace iterator_impl {


template<class... Tags>
using is_all_random_access_iterator = is_base_of_all<std::random_access_iterator_tag,Tags...>;

template<class... Tags>
using is_all_bidirectional_iterator = is_base_of_all<std::bidirectional_iterator_tag,Tags...>;

template<class... Tags>
using is_all_forward_iterator = is_base_of_all<std::forward_iterator_tag,Tags...>;

template<class... Tags>
using is_all_input_iterator = is_base_of_all<std::input_iterator_tag,Tags...>;


template<class... Tags>
constexpr auto _most_primitive_iterator_tag() {
    if constexpr(is_all_random_access_iterator<Tags...>::value) {
        return std::random_access_iterator_tag{};
    }
    else if constexpr(is_all_bidirectional_iterator<Tags...>::value) {
        return std::bidirectional_iterator_tag{};
    }
    else if constexpr(is_all_forward_iterator<Tags...>::value) {
        return std::forward_iterator_tag{};
    }
    else {
        return std::input_iterator_tag{};
    }
}


} // namespace iterator_impl


template<class... Tags>
using most_primitive_iterator_tag = decltype(iterator_impl::_most_primitive_iterator_tag<Tags...>());


template<class T, class = void>
struct is_iterator {
   static constexpr bool value = false;
};

template<class T>
struct is_iterator<T, typename std::enable_if<!std::is_same<typename std::iterator_traits<T>::value_type, void>::value>::type> {
   static constexpr bool value = true;
};

template<class T>
inline constexpr bool is_iterator_v = is_iterator<T>::value;

template<class T>
using is_iterator_t = std::enable_if_t<is_iterator_v<T>>;

template<class T>
using iota_diff_t = std::make_signed_t<T>;


} // namespace internal

} // namespace uni
#line 2 "internal/ranges.hpp"


#line 6 "internal/ranges.hpp"
#include <tuple>


#line 11 "internal/ranges.hpp"


namespace uni {

namespace internal {


template<class Range>
concept resizable_range
  = std::ranges::range<Range> &&
    requires (Range& r) { r.resize(0); };

template<class range>
concept simple_view
  = std::ranges::view<range> && std::ranges::range<const range> &&
    std::same_as<std::ranges::iterator_t<range>, std::ranges::iterator_t<const range>> &&
    std::same_as<std::ranges::sentinel_t<range>, std::ranges::sentinel_t<const range>>;


template<class... Ranges>
concept zip_is_common = (sizeof...(Ranges) == 1 && (std::ranges::common_range<Ranges> && ...))
    || (!(std::ranges::bidirectional_range<Ranges> && ...) && (std::ranges::common_range<Ranges> && ...))
    || ((std::ranges::random_access_range<Ranges> && ...) && (std::ranges::sized_range<Ranges> && ...));


template<bool Const, class... Views>
concept all_contiguous = (std::ranges::contiguous_range<maybe_const_t<Const, Views>> && ...);

template<bool Const, class... Views>
concept all_random_access = (std::ranges::random_access_range<maybe_const_t<Const, Views>> && ...);

template<bool Const, class... Views>
concept all_bidirectional = (std::ranges::bidirectional_range<maybe_const_t<Const, Views>> && ...);

template<bool Const, class... Views>
concept all_forward = (std::ranges::forward_range<maybe_const_t<Const, Views>> && ...);


template<bool Const, class... Views> struct zip_view_iterator_category {};

template<bool Const, class... Views>
    requires all_forward<Const, Views...>
struct zip_view_iterator_category<Const, Views...> {
    using iterator_category = std::input_iterator_tag;
};


template<bool Const, class... Views>
static auto _most_primitive_iterator_concept() noexcept(NO_EXCEPT) {
    if constexpr(all_random_access<Const, Views...>)
        return std::random_access_iterator_tag{};
    else if constexpr(all_bidirectional<Const, Views...>)
        return std::bidirectional_iterator_tag{};
    else if constexpr(all_forward<Const, Views...>)
        return std::forward_iterator_tag{};
    else
        return std::input_iterator_tag{};
}

template<bool Const, class... Views>
using most_primitive_iterator_concept = decltype(_most_primitive_iterator_concept<Const, Views...>());


template<class Range, bool Const>
using range_iterator_category = typename std::iterator_traits<
        std::ranges::iterator_t<maybe_const_t<Const, Range>>
    >::iterator_category;



template<class Range>
static constexpr auto _iterator_concept() noexcept(NO_EXCEPT) {
    if constexpr(std::ranges::random_access_range<Range>)
        return std::random_access_iterator_tag{};
    else if constexpr(std::ranges::bidirectional_range<Range>)
        return std::bidirectional_iterator_tag{};
    else if constexpr(std::ranges::forward_range<Range>)
        return std::forward_iterator_tag{};
    else
        return std::input_iterator_tag{};
}

template<class Range>
using iterator_concept = decltype(_iterator_concept<Range>());



template<std::ranges::range Range> struct cached_position {
    constexpr bool has_value() const { return false; }

    constexpr std::ranges::iterator_t<Range> get(const Range&) const {
        __builtin_unreachable();
    }

    constexpr void set(const Range &, const std::ranges::iterator_t<Range> &) const {}
};

template<std::ranges::forward_range Range>
struct cached_position<Range> : protected std::optional<std::ranges::iterator_t<Range>> {
    using std::optional<std::ranges::iterator_t<Range>>::optioanl;
    using std::optional<std::ranges::iterator_t<Range>>::has_value;

    constexpr std::ranges::iterator_t<Range> get(const Range&) const {
        assert(this->has_value());
        return **this;
    }

    constexpr void set(const Range&, const std::ranges::iterator_t<Range>& itr) {
        assert(!this->has_value());
        this->emplace(*itr);
    }
};


template<std::ranges::random_access_range Range>
    requires(sizeof(std::ranges::range_difference_t<Range>) <= sizeof(std::ranges::iterator_t<Range>))
struct cached_position<Range> {
  private:
    std::ranges::range_difference_t<Range> _offset = -1;

  public:
    cached_position() = default;

    constexpr cached_position(const cached_position &) = default;

    constexpr cached_position(cached_position &&other) noexcept {
        *this = std::move(other);
    }

    constexpr cached_position &operator=(const cached_position &) = default;

    constexpr cached_position &operator=(cached_position &&other) noexcept {
        // Propagate the cached offset, but invalidate the source.
        this->_offset = other._offset;
        other._offset = -1;
        return *this;
    }

    constexpr bool has_value() const { return this->_offset >= 0; }

    constexpr std::ranges::iterator_t<Range> get(Range& range) const {
        assert(this->has_value());
        return std::ranges::begin(range) + this->_offset;
    }

    constexpr void set(Range &range, const std::ranges::iterator_t<Range> &itr) {
        assert(!this->has_value());
        this->_offset = itr - std::ranges::begin(range);
    }
};


template<typename T, int Disc>
struct absent { };

template<bool PRESENT, class T, int Disc = 0>
using maybe_present_t = std::conditional_t<PRESENT, T, absent<T, Disc>>;


} // namespace internal


namespace views::adaptor {


template<class Adaptor, class... Args>
concept adaptor_invocable = requires { std::declval<Adaptor>()(std::declval<Args>()...); };

template<class Adaptor, class... Args>
concept adaptor_partial_app_viable =
    (Adaptor::arity > 1) && (sizeof...(Args) == Adaptor::arity - 1) &&
    (std::constructible_from<std::remove_cvref_t<Args>, Args> && ...);

template<class Adaptor, class... Args> struct partial;

template<class, class> struct pipe;


template<class Derived> struct range_adaptor_closure {};


template<class T, class U>
    requires(!std::same_as<T, range_adaptor_closure<U>>)
void is_range_adaptor_closure_fn(const T &, const range_adaptor_closure<U> &);


template<class T>
concept is_range_adaptor_closure = requires(T t) { adaptor::is_range_adaptor_closure_fn(t, t); };


template<class Self, class Range>
    requires is_range_adaptor_closure<Self> && adaptor_invocable<Self, Range>
constexpr auto operator|(Range&& range, Self&& self) {
    return std::forward<Self>(self)(std::forward<Range>(range));
}


template<class Lhs, class Rhs>
    requires is_range_adaptor_closure<Lhs> && is_range_adaptor_closure<Rhs>
constexpr auto operator|(Lhs&& lhs, Rhs&& rhs) {
    return pipe<std::remove_cvref_t<Lhs>, std::remove_cvref_t<Rhs>>{ std::forward<Lhs>(lhs), std::forward<Rhs>(rhs)};
}


template<class Derived> struct range_adaptor {
    template<class... Args>
        requires adaptor_partial_app_viable<Derived, Args...>
    inline constexpr auto operator()(Args&& ..._args) const noexcept(NO_EXCEPT) {
        return partial<Derived, std::remove_cvref_t<Args>...>{
            std::forward<Args>(_args)...
        };
    }
};

template<class Adaptor>
concept closure_has_simple_call_op = Adaptor::has_simple_call_op;

template<class Adaptor, class... Args>
concept adaptor_has_simple_extra_args =
    Adaptor::has_simple_extra_args ||
    Adaptor::template has_simple_extra_args<Args...>;

template<class Adaptor, class... Args>
struct partial : range_adaptor_closure<partial<Adaptor, Args...>> {
    std::tuple<Args...> args;

    constexpr partial(Args... _args) noexcept(NO_EXCEPT) : args(std::move(_args)...) {}

    template<class Range>
        requires adaptor_invocable<Adaptor, Range, const Args &...>
    inline constexpr auto operator()(Range&& range) const & noexcept(NO_EXCEPT) {
        const auto forwarder = [&range](const auto &..._args) constexpr noexcept(NO_EXCEPT) {
            return Adaptor{}(std::forward<Range>(range), _args...);
        };
        return std::apply(forwarder, this->args);
    }

    template<class Range>
        requires adaptor_invocable<Adaptor, Range, Args...>
    inline constexpr auto operator()(Range&& range) && noexcept(NO_EXCEPT) {
        const auto forwarder = [&range](auto &..._args) constexpr noexcept(NO_EXCEPT) {
            return Adaptor{}(std::forward<Range>(range), std::move(_args)...);
        };
        return std::apply(forwarder, this->args);
    }

    template<class Range>
    inline constexpr auto operator()(Range&& range) const && = delete;
};

template<class Adaptor, class Arg>
struct partial<Adaptor, Arg> : range_adaptor_closure<partial<Adaptor, Arg>> {
    Arg arg;

    constexpr partial(Arg _arg) noexcept(NO_EXCEPT) : arg(std::move(_arg)) {}

    template<class Range>
        requires adaptor_invocable<Adaptor, Range, const Arg &>
    inline constexpr auto operator()(Range&& range) const & noexcept(NO_EXCEPT) {
        return Adaptor{}(std::forward<Range>(range), this->arg);
    }

    template<class Range>
        requires adaptor_invocable<Adaptor, Range, Arg>
    inline constexpr auto operator()(Range&& range) && noexcept(NO_EXCEPT) {
        return Adaptor{}(std::forward<Range>(range), std::move(this->arg));
    }

    template<class Range>
    inline constexpr auto operator()(Range&& range) const && = delete;
};

template<class Adaptor, class... Args>
    requires adaptor_has_simple_extra_args<Adaptor, Args...> && (std::is_trivially_copyable_v<Args> && ...)
struct partial<Adaptor, Args...> : range_adaptor_closure<partial<Adaptor, Args...>> {
    std::tuple<Args...> args;

    constexpr partial(Args... _args) noexcept(NO_EXCEPT) : args(std::move(_args)...) {}

    template<class Range>
        requires adaptor_invocable<Adaptor, Range, const Args &...>
    inline constexpr auto operator()(Range&& range) const noexcept(NO_EXCEPT) {
        const auto forwarder = [&range](const auto &..._args) constexpr noexcept(NO_EXCEPT) {
            return Adaptor{}(std::forward<Range>(range), _args...);
        };
        return std::apply(forwarder, this->args);
    }

    static constexpr bool has_simple_call_op = true;
};

template<class Adaptor, class Arg>
    requires adaptor_has_simple_extra_args<Adaptor, Arg> &&
             std::is_trivially_copyable_v<Arg>
struct partial<Adaptor, Arg> : range_adaptor_closure<partial<Adaptor, Arg>> {
    Arg arg;

    constexpr partial(Arg _arg) noexcept(NO_EXCEPT) : arg(std::move(_arg)) {}

    template<class Range>
        requires adaptor_invocable<Adaptor, Range, const Arg &>
    inline constexpr auto operator()(Range&& range) const noexcept(NO_EXCEPT) {
        return Adaptor{}(std::forward<Range>(range), this->arg);
    }

    static constexpr bool has_simple_call_op = true;
};

template<class Lhs, class Rhs, class Range>
concept pipe_invocable = requires {
    std::declval<Rhs>()(std::declval<Lhs>()(std::declval<Range>()));
};

template<class Lhs, class Rhs> struct pipe : range_adaptor_closure<pipe<Lhs, Rhs>> {
    [[no_unique_address]] Lhs lhs;
    [[no_unique_address]] Rhs rhs;

    constexpr pipe(Lhs _lhs, Rhs _rhs) noexcept(NO_EXCEPT) : lhs(std::move(_lhs)), rhs(std::move(_rhs)) {}

    template<class Range>
        requires pipe_invocable<const Lhs &, const Rhs &, Range>
    inline constexpr auto operator()(Range&& range) const & noexcept(NO_EXCEPT) {
        return rhs(lhs(std::forward<Range>(range)));
    }

    template<class Range>
        requires pipe_invocable<Lhs, Rhs, Range>
    inline constexpr auto operator()(Range&& range) && noexcept(NO_EXCEPT) {
        return std::move(rhs)(std::move(lhs)(std::forward<Range>(range)));
    }

    template<class Range>
    inline constexpr auto operator()(Range&& range) const && = delete;
};


template<class Lhs, class Rhs>
    requires closure_has_simple_call_op<Lhs> && closure_has_simple_call_op<Rhs>
struct pipe<Lhs, Rhs> : range_adaptor_closure<pipe<Lhs, Rhs>> {
    [[no_unique_address]] Lhs lhs;
    [[no_unique_address]] Rhs rhs;

    constexpr pipe(Lhs _lhs, Rhs _rhs) noexcept(NO_EXCEPT) : lhs(std::move(_lhs)), rhs(std::move(_rhs)) {}

    template<class Range>
        requires pipe_invocable<const Lhs &, const Rhs &, Range>
    inline constexpr auto operator()(Range&& range) const noexcept(NO_EXCEPT) {
        return rhs(lhs(std::forward<Range>(range)));
    }

    static constexpr bool has_simple_call_op = true;
};


} // namespace views::adaptor


} // namespace uni
#line 28 "iterable/operation.hpp"

#line 2 "iterable/z_array.hpp"


#line 6 "iterable/z_array.hpp"


#line 9 "iterable/z_array.hpp"

#line 2 "adaptor/valarray.hpp"


#line 11 "adaptor/valarray.hpp"

#line 14 "adaptor/valarray.hpp"

#line 16 "adaptor/valarray.hpp"


namespace uni {


template<class T> struct valarray : internal::advanced_container<std::valarray<T>> {
  private:
    using base = internal::advanced_container<std::valarray<T>>;

  public:
    using size_type = internal::size_t;

    using iterator = T*;
    using const_iterator = const T*;

  protected:
    inline bool _validate_index_in_right_open([[maybe_unused]] const size_type p) const noexcept(NO_EXCEPT) {
        return 0 <= p and p < this->size();
    }
    inline bool _validate_index_in_closed([[maybe_unused]] const size_type p) const noexcept(NO_EXCEPT) {
        return 0 <= p and p <= this->size();
    }
    inline bool _validate_rigth_open_interval([[maybe_unused]] const size_type l, [[maybe_unused]] const size_type r) const noexcept(NO_EXCEPT) {
        return 0 <= l and l <= r and r <= this->size();
    }

    inline size_type _positivize_index(const size_type p) const noexcept(NO_EXCEPT) {
        return p < 0 ? this->size() + p : p;
    }

  public:
    valarray() noexcept(NO_EXCEPT) {}

    explicit valarray(const std::size_t length, const T& val = T{}) noexcept(NO_EXCEPT) : base(val, length) {}

    template<std::input_iterator I, std::sentinel_for<I> S>
    valarray(I first, S last) noexcept(NO_EXCEPT) : base(std::ranges::distance(first, last)) { std::ranges::copy(first, last, std::ranges::begin(*this)); }

    template<class U> valarray(const U* pointer, const size_t n) noexcept(NO_EXCEPT) : base(pointer, n) {};

    valarray(const std::slice_array<T>& arr) noexcept(NO_EXCEPT) : base(arr) {};
    valarray(const std::gslice_array<T>& arr) noexcept(NO_EXCEPT) : base(arr) {};
    valarray(const std::mask_array<T>& arr) noexcept(NO_EXCEPT) : base(arr) {};
    valarray(const std::indirect_array<T>& arr) noexcept(NO_EXCEPT) : base(arr) {};
    valarray(const std::initializer_list<T>& init) noexcept(NO_EXCEPT) : base(init) {}
    valarray(const internal::advanced_container<std::valarray<T>>& arr) noexcept(NO_EXCEPT) : base(arr) {}

  #ifdef __GNUC__
    template<class Dom> valarray(const std::_Expr<Dom,T>& expr) noexcept(NO_EXCEPT) : base(expr) {}
  #endif

    inline auto size() const noexcept(NO_EXCEPT) { return static_cast<size_type>(this->base::size()); }

    inline void reserve(const size_type) noexcept(NO_EXCEPT) { /* do nothing */ }

    template<std::input_iterator I, std::sentinel_for<I> S>
    inline void assign(I first, S last) noexcept(NO_EXCEPT) {
        this->resize(std::ranges::distance(first, last));
        std::ranges::copy(first, last, std::ranges::begin(*this));
    }

    inline void assign(const std::size_t length, const T& val = T{}) noexcept(NO_EXCEPT) {
        this->base::resize(length, val);
    }

    inline void resize(const std::size_t length, const T& val = T{}) noexcept(NO_EXCEPT) {
        base temp = *this;
        this->assign(length, val);
        std::move(std::begin(temp), std::min(std::end(temp), std::next(std::begin(temp), length)), std::begin(*this));
    }

    inline const T& operator[](size_type pos) const noexcept(NO_EXCEPT) {
        pos = this->_positivize_index(pos), assert(this->_validate_index_in_right_open(pos));
        return this->base::operator[](pos);
    }
    inline T& operator[](size_type pos) noexcept(NO_EXCEPT) {
        pos = this->_positivize_index(pos), assert(this->_validate_index_in_right_open(pos));
        return this->base::operator[](pos);
    }

    inline const T& back() const noexcept(NO_EXCEPT) { return *std::prev(this->end()); }
    inline T& back() noexcept(NO_EXCEPT) { return *std::prev(this->end()); }

    inline const T& front() const noexcept(NO_EXCEPT) { return *this->begin(); }
    inline T& front() noexcept(NO_EXCEPT) { return *this->begin(); }

    inline auto rbegin() noexcept(NO_EXCEPT) { return std::make_reverse_iterator(std::ranges::end(*this)); }
    inline auto rend() noexcept(NO_EXCEPT) { return std::make_reverse_iterator(std::ranges::begin(*this)); }

    inline auto rbegin() const noexcept(NO_EXCEPT) { return std::make_reverse_iterator(std::ranges::end(*this)); }
    inline auto rend() const noexcept(NO_EXCEPT) { return std::make_reverse_iterator(std::ranges::begin(*this)); }
};


} // namespace uni
#line 11 "iterable/z_array.hpp"


namespace uni {


// Thanks to: atcoder::z_algorithm
template<class SizeType = internal::size_t, class Container = valarray<SizeType>>
struct z_array : Container {
    using size_type = SizeType;

    template<std::input_iterator I, std::sentinel_for<I> S>
    z_array(I first, S last) : Container(std::ranges::distance(first, last), {}) {
        const size_type n = static_cast<size_type>(std::ranges::distance(first, last));
        if(n == 0) return;
        for(size_type i = 1, j = 0; i < n; ++i) {
            size_type& k = this->operator[](i);
            k = (j + this->operator[](j) <= i) ? 0 : std::ranges::min(j + this->operator[](j) - i, this->operator[](i - j));
            while(i + k < n and first[k] == first[i + k]) ++k;
            if(j + this->operator[](j) < i + this->operator[](i)) j = i;
        }
        *this->begin() = n;
    }

    template<std::ranges::input_range R>
    explicit z_array(R&& range) : z_array(ALL(range)) {}
};


} // namespace uni
#line 31 "iterable/operation.hpp"

#line 2 "view/concat.hpp"


#line 11 "view/concat.hpp"


#line 18 "view/concat.hpp"



namespace uni {

namespace internal {

namespace view_impl {


template<std::ranges::input_range V0, std::ranges::input_range V1>
    requires std::ranges::view<V0> && std::ranges::view<V1>
struct concat_view : std::ranges::view_interface<concat_view<V0, V1>> {
  private:
    V0 _b0;
    V1 _b1;

    template<bool Const> using B0 = internal::maybe_const_t<Const, V0>;
    template<bool Const> using B1 = internal::maybe_const_t<Const, V1>;

    template<bool Const> struct iterator_tag {};

    template<bool Const>
        requires std::ranges::forward_range<B0<Const>> && std::ranges::forward_range<B1<Const>>
    struct iterator_tag<Const> {
      public:
        using iterator_category = uni::internal::most_primitive_iterator_tag<
            typename std::iterator_traits<std::ranges::iterator_t<B0<Const>>>::iterator_category,
            typename std::iterator_traits<std::ranges::iterator_t<B1<Const>>>::iterator_category
        >;
    };

  public:
    template<bool> class iterator;

    constexpr explicit concat_view(V0 v0, V1 v1) noexcept(NO_EXCEPT)
      : _b0(std::move(v0)), _b1(std::move(v1))
    {}

    inline constexpr std::pair<V0, V1> base() const & noexcept(NO_EXCEPT)
        requires std::copy_constructible<V0> && std::copy_constructible<V0>
    {
        return { this->_b0, this->_b1 };
    }

    inline constexpr std::pair<V0,V1> base() && noexcept(NO_EXCEPT) {
        return { std::move(this->_b0), std::move(this->_b1) };
    }

    inline constexpr auto begin() noexcept(NO_EXCEPT)
        requires (!internal::simple_view<V0> && !internal::simple_view<V1>)
    {
        return iterator<false>(this, std::ranges::begin(this->_b0), std::ranges::begin(this->_b1), 0);
    }

    inline constexpr auto begin() const noexcept(NO_EXCEPT)
        requires std::ranges::range<const V0> && std::ranges::range<const V1>
    {
        return iterator<true>(this, std::ranges::begin(this->_b0), std::ranges::begin(this->_b1), 0);
    }

    inline constexpr auto end() noexcept(NO_EXCEPT)
        requires (!internal::simple_view<V0> && !internal::simple_view<V1>)
    {
        if constexpr(std::ranges::common_range<V0> && std::ranges::common_range<V1>) {
            return iterator<false>(this, std::ranges::end(this->_b0), std::ranges::end(this->_b1), 1);
        }
        else {
            return std::default_sentinel;
        }
    }

    inline constexpr auto end() const noexcept(NO_EXCEPT)
        requires std::ranges::range<const V0> && std::ranges::range<const V1>
    {
        if constexpr(std::ranges::common_range<const V0> && std::ranges::common_range<const V1>) {
            return iterator<true>(this, std::ranges::end(this->_b0), std::ranges::end(this->_b1), 1);
        }
        else {
            return std::default_sentinel;
        }
    }

    inline constexpr auto size() noexcept(NO_EXCEPT)
        requires std::ranges::sized_range<V0> && std::ranges::sized_range<V1>
    {
        return static_cast<std::size_t>(std::ranges::distance(this->_b0) + std::ranges::distance(this->_b1));
    }

    inline constexpr auto size() const noexcept(NO_EXCEPT)
        requires std::ranges::sized_range<const V0> && std::ranges::sized_range<const V1>
    {
        return static_cast<std::size_t>(std::ranges::distance(this->_b0) + std::ranges::distance(this->_b1));
    }
};

template<std::ranges::input_range V0, std::ranges::input_range V1>
    requires std::ranges::view<V0> && std::ranges::view<V1>
template<bool Const>
struct concat_view<V0, V1>::iterator : iterator_tag<Const> {
  private:
    using Parent = internal::maybe_const_t<Const, concat_view>;

    using B0 = concat_view::B0<Const>;
    using B1 = concat_view::B1<Const>;

    std::ranges::iterator_t<B0> _c0 = std::ranges::iterator_t<B0>();
    std::ranges::iterator_t<B0> _b0 = std::ranges::iterator_t<B0>();
    std::ranges::sentinel_t<B0> _e0 = std::ranges::sentinel_t<B0>();

    std::ranges::iterator_t<B1> _c1 = std::ranges::iterator_t<B1>();
    std::ranges::iterator_t<B1> _b1 = std::ranges::iterator_t<B1>();
    std::ranges::sentinel_t<B1> _e1 = std::ranges::sentinel_t<B1>();

    int _block = 0;

    constexpr iterator(Parent *const parent, const std::ranges::iterator_t<B0> c0, const std::ranges::iterator_t<B1> c1, const int block) noexcept(NO_EXCEPT)
      : _c0(std::move(c0)), _b0(std::ranges::begin(parent->_b0)), _e0(std::ranges::end(parent->_b0)),
        _c1(std::move(c1)), _b1(std::ranges::begin(parent->_b1)), _e1(std::ranges::end(parent->_b1)),
        _block(block || std::ranges::empty(parent->_b0))
    {}

    friend concat_view;

  public:
    using difference_type = std::common_type_t<std::ranges::range_difference_t<B0>, std::ranges::range_difference_t<B1>>;

    using value_type = std::common_type_t<std::ranges::range_value_t<B0>, std::ranges::range_value_t<B1>>;
    using reference_type = std::common_reference_t<std::ranges::range_reference_t<B0>, std::ranges::range_reference_t<B1>>;

    using iterator_concept = most_primitive_iterator_concept<Const, V0, V1>;

    iterator() noexcept(NO_EXCEPT)
        requires std::default_initializable<std::ranges::iterator_t<B0>> &&
                 std::default_initializable<std::ranges::iterator_t<B0>>
    = default;

    constexpr iterator(iterator<!Const> itr) noexcept(NO_EXCEPT)
        requires
            Const &&
            std::convertible_to<std::ranges::iterator_t<V0>, std::ranges::iterator_t<B0>> &&
            std::convertible_to<std::ranges::sentinel_t<V0>, std::ranges::sentinel_t<B0>> &&
            std::convertible_to<std::ranges::iterator_t<V1>, std::ranges::iterator_t<B1>> &&
            std::convertible_to<std::ranges::sentinel_t<V1>, std::ranges::sentinel_t<B1>>
      : _c0(std::move(itr._c0)), _b0(std::move(itr._b0)), _e0(std::move(itr._e0)),
        _c1(std::move(itr._c0)), _b1(std::move(itr._b0)), _e1(std::move(itr._e1)),
        _block(itr._block)
    {}

    inline constexpr std::variant<std::ranges::iterator_t<B0>, std::ranges::iterator_t<B1>>
    base() && noexcept(NO_EXCEPT) {
        if(this->_block == 0) return std::move(this->_c0);
        else return std::move(this->_C1);
    }

    inline constexpr
        std::variant<
            std::reference_wrapper<const std::ranges::iterator_t<B0>>,
            std::reference_wrapper<const std::ranges::iterator_t<B1>>
        >
    base() const & noexcept {
        if(this->_block == 0) return std::move(this->_c0);
        else return std::move(this->_c1);
    }

    inline constexpr reference_type operator*() const noexcept(NO_EXCEPT)
    {

        if(this->_block == 0) return *this->_c0;
        else return *this->_c1;
    }

    inline constexpr iterator& operator++() noexcept(NO_EXCEPT)
    {
        assert(this->_c0 != this->_e0 or this->_c1 != this->_e1);

        if(this->_block == 0) {
            if(++this->_c0 == this->_e0) {
                this->_block = 1;
                assert(this->_c1 == this->_b1);
            }
        }
        else {
            ++this->_c1;
        }

        return *this;
    }

    inline constexpr void operator++(int) noexcept(NO_EXCEPT) { ++*this; }

    inline constexpr iterator operator++(int) noexcept(NO_EXCEPT)
        requires std::ranges::forward_range<B0> && std::ranges::forward_range<B1>
    {
        const auto res = *this; ++*this; return res;
    }

    inline constexpr iterator& operator--() noexcept(NO_EXCEPT)
        requires
            std::ranges::bidirectional_range<B0> && std::ranges::bidirectional_range<B1> &&
            std::bidirectional_iterator<std::ranges::sentinel_t<B0>>
    {
        if(this->_block == 1) {
            if(this->_c1 == this->_b1) {
                this->_block = 0;
                this->_c0 = std::ranges::prev(this->_e0);
            }
            else {
                --this->_c1;
            }
        }
        else {
            --this->_c0;
        }

        return *this;
    }

    inline constexpr iterator operator--(int) noexcept(NO_EXCEPT)
        requires std::ranges::bidirectional_range<B0> && std::ranges::bidirectional_range<B1>
    {
        const auto res = *this; --*this; return res;
    }

    inline constexpr iterator& operator+=(const difference_type diff) noexcept(NO_EXCEPT)
        requires
            std::ranges::random_access_range<B0> && std::ranges::random_access_range<B1>
    {
        if(diff > 0) {
            if(this->_block == 0) {
                const auto missing = std::ranges::advance(this->_c0, diff, this->_e0);
                if(this->_c0 == this->_e0) {
                    this->_block = 1;
                    assert(this->_c1 == this->_b1);
                    std::ranges::advance(this->_c1, missing, this->_e1);
                }
            }
            else {
                std::ranges::advance(this->_c1, diff, this->_e1);
            }
        }
        if(diff < 0) {
            if(this->_block == 1) {
                const auto missing = std::ranges::advance(this->_c1, diff, this->_b1);
                if(missing < 0) {
                    this->_block = 0;
                    assert(this->_c0 == this->_e0);
                    std::ranges::advance(this->_c0, missing, this->_b0);
                }
            }
            else {
                std::ranges::advance(this->_c0, diff, this->_b0);
            }
        }

        return *this;
    }

    inline constexpr iterator& operator-=(const difference_type diff) noexcept(NO_EXCEPT)
        requires std::ranges::random_access_range<B0> && std::ranges::random_access_range<B1>
    {
        return *this += -diff;
    }

    inline constexpr decltype(auto) operator[](const difference_type diff) const noexcept(NO_EXCEPT)
        requires std::ranges::random_access_range<B0> && std::ranges::random_access_range<B1>
    {
        return *(*this + diff);
    }

    friend inline constexpr bool operator==(const iterator& lhs, std::default_sentinel_t) noexcept(NO_EXCEPT)
    {
        if(lhs._block == 0) return false;
        if(lhs._block == 1) return lhs._c1 == lhs._e1;
        assert(false);
    }

    friend inline constexpr bool operator==(const iterator& lhs, const iterator& rhs) noexcept(NO_EXCEPT)
        requires
            std::equality_comparable<std::ranges::iterator_t<B0>> &&
            std::equality_comparable<std::ranges::iterator_t<B1>>
    {
        if(lhs._block != rhs._block) return false;
        return lhs._block == 0 ? lhs._c0 == rhs._c0 : lhs._c1 == rhs._c1;
    }

    friend inline constexpr auto operator<=>(const iterator& lhs, const iterator& rhs) noexcept(NO_EXCEPT)
        requires std::ranges::random_access_range<B0> && std::ranges::random_access_range<B1>
    {
        if(lhs._block != rhs._block) return lhs._block <=> rhs._block;
        return lhs._block == 0 ? lhs._c0 <=> rhs._c0 : lhs._c1 <=> rhs._c1;
    }

    friend inline constexpr iterator operator+(const iterator& itr, const difference_type diff) noexcept(NO_EXCEPT)
        requires std::ranges::random_access_range<B0> && std::ranges::random_access_range<B1>
    {
        auto res = itr; res += diff; return res;
    }

    friend inline constexpr iterator operator+(const difference_type diff, const iterator& itr) noexcept(NO_EXCEPT)
        requires std::ranges::random_access_range<B0> && std::ranges::random_access_range<B1>
    {
        return itr + diff;
    }

    friend inline constexpr iterator operator-(const iterator& itr, const difference_type diff) noexcept(NO_EXCEPT)
        requires std::ranges::random_access_range<B0> && std::ranges::random_access_range<B1>
    {
        auto res = itr; res -= diff; return res;
    }

    friend inline constexpr const difference_type operator-(const iterator& lhs, const iterator& rhs) noexcept(NO_EXCEPT)
        requires
            std::sized_sentinel_for<std::ranges::iterator_t<B0>, std::ranges::iterator_t<B0>> &&
            std::sized_sentinel_for<std::ranges::iterator_t<B1>, std::ranges::iterator_t<B1>>
    {
        if(lhs._block == rhs._block) {
            return lhs._block == 0 ? std::ranges::distance(rhs._c0, lhs._c0) : std::ranges::distance(rhs._c1, lhs._c1);
        }
        if(lhs._block > rhs._block) return std::ranges::distance(rhs._c0, rhs._e0) + std::ranges::distance(lhs._b1, lhs._c1);
        if(lhs._block < rhs._block) return -(rhs - lhs);
        assert(false);
    }

    friend inline constexpr const difference_type operator-(std::default_sentinel_t, const iterator& rhs) noexcept(NO_EXCEPT)
        requires
            std::sized_sentinel_for<std::ranges::sentinel_t<B0>, std::ranges::iterator_t<B0>> &&
            std::sized_sentinel_for<std::ranges::sentinel_t<B1>, std::ranges::iterator_t<B1>>
    {
        if(rhs._block == 0) return std::ranges::distance(rhs._c0, rhs._e0) + std::ranges::distance(rhs._b1, rhs._e1);
        if(rhs._block == 1) return std::ranges::distance(rhs._c1, rhs._e1);
        assert(false);
    }

    friend inline constexpr const difference_type operator-(const iterator& lhs, std::default_sentinel_t rhs) noexcept(NO_EXCEPT)
        requires
            std::sized_sentinel_for<std::ranges::sentinel_t<B0>, std::ranges::iterator_t<B0>> &&
            std::sized_sentinel_for<std::ranges::sentinel_t<B1>, std::ranges::iterator_t<B1>>
    {
        return -(rhs - lhs);
    }

    friend inline constexpr
    std::common_reference_t<
        std::ranges::range_rvalue_reference_t<B0>,
        std::ranges::range_rvalue_reference_t<B1>
    >
    iter_move(const iterator& itr) noexcept(NO_EXCEPT)
    {
        if(itr._block == 0) return std::ranges::iter_move(itr._c0);
        if(itr._block == 1) return std::ranges::iter_move(itr._c1);
        assert(false);
    }

    friend inline constexpr void iter_swap(const iterator& lhs, const iterator& rhs) noexcept(NO_EXCEPT)
        requires
            std::indirectly_swappable<std::ranges::iterator_t<B0>> &&
            std::indirectly_swappable<std::ranges::iterator_t<B1>> &&
            std::indirectly_swappable<std::ranges::iterator_t<B0>, std::ranges::iterator_t<B1>>
    {
        if(lhs._block == 0 && rhs._block == 0) std::ranges::iter_swap(lhs._c0, rhs._c0);
        if(lhs._block == 0 && rhs._block == 1) std::ranges::iter_swap(lhs._c0, rhs._c1);
        if(lhs._block == 1 && rhs._block == 0) std::ranges::iter_swap(lhs._c1, rhs._c0);
        if(lhs._block == 1 && rhs._block == 1) std::ranges::iter_swap(lhs._c1, rhs._c1);
        assert(false);
    }
};


} // namespace view_impl

} // namespace internal


template<class...> struct concat_view;

template<class T>
struct concat_view<T> : std::views::all_t<T> {
    using std::views::all_t<T>::all_t;
};

template<class T0, class T1>
struct concat_view<T0, T1> : internal::view_impl::concat_view<std::views::all_t<T0>, std::views::all_t<T1>> {
    explicit concat_view(T0&& v0, T1&& v1) noexcept(NO_EXCEPT)
      : internal::view_impl::concat_view<std::views::all_t<T0>, std::views::all_t<T1>>(std::forward<T0>(v0), std::forward<T1>(v1))
    {}
};

template<class T0, class T1, class... Ts>
struct concat_view<T0, T1, Ts...> : concat_view<concat_view<T0, T1>, Ts...> {
    explicit concat_view(T0&& v0, T1&& v1, Ts&&... vs) noexcept(NO_EXCEPT)
      : concat_view<concat_view<T0, T1>, Ts...>(
            concat_view<T0, T1>(std::forward<T0>(v0), std::forward<T1>(v1)), std::forward<Ts>(vs)...
        )
    {}
};

namespace views {

namespace internal {


template<class... Ts>
concept can_concat_view = requires { concat_view<Ts...>(std::declval<Ts>()...); };


} // namespace internal


struct Concat {
    template<class... Ts>
        requires (sizeof...(Ts) == 0 || internal::can_concat_view<Ts...>)
    inline constexpr auto operator() [[nodiscard]] (Ts&&... vs) const {
        if constexpr(sizeof...(Ts) == 0) return std::views::empty<std::nullptr_t>;
        else return concat_view<std::views::all_t<Ts>...>(std::forward<Ts>(vs)...);
    }
};


inline constexpr Concat concat;


} // namespace views

} // namespace uni.


namespace std::ranges {


template<class... Views>
inline constexpr bool enable_borrowed_range<uni::concat_view<Views...>> = (enable_borrowed_range<Views> && ...);


}
#line 2 "global/constants.hpp"


#line 7 "global/constants.hpp"
#include <cmath>


#line 11 "global/constants.hpp"

#line 14 "global/constants.hpp"

#line 2 "numeric/limits.hpp"


#line 6 "numeric/limits.hpp"


#line 9 "numeric/limits.hpp"

#line 11 "numeric/limits.hpp"


namespace uni {


template<class T>
struct numeric_limits : std::numeric_limits<T> {
    static constexpr long double FLOAT_EPSILON = 1E-14;

    static constexpr T arithmetic_infinity() noexcept(NO_EXCEPT) {
        return std::numeric_limits<T>::max() / 2 - 1;
    }

    static constexpr T arithmetic_negative_infinity() noexcept(NO_EXCEPT) {
        return std::numeric_limits<T>::lowest() / 2 + 1;
    }

    static constexpr T arithmetic_epsilon() noexcept(NO_EXCEPT) {
        if constexpr(std::is_floating_point_v<T>) {
            return numeric_limits::FLOAT_EPSILON;
        }
        else {
            return 0;
        }
    }
};


constexpr i32 INF32 = numeric_limits<i32>::arithmetic_infinity();
constexpr i64 INF64 = numeric_limits<i64>::arithmetic_infinity();

template<class T>
constexpr T INF = numeric_limits<T>::arithmetic_infinity();

template<class T>
constexpr T EPSILON = numeric_limits<T>::arithmetic_epsilon();


} // namespace uni
#line 16 "global/constants.hpp"


namespace uni {


namespace internal {
    template<class T>
    consteval auto get_pi() {
        if constexpr(std::integral<T>) {
            return static_cast<T>(3);
        }
        else if constexpr(std::same_as<T, float>) {
            return M_PIf;
        }
        else if constexpr(std::same_as<T, double>) {
            return M_PI;
        }
        else if constexpr(std::same_as<T, ld>) {
            return M_PIl;
        }
        else {
            static_assert(EXCEPTION_ON_TYPE<T>);
        }
    }
} // namespace internal


template<class T = ld>
constexpr auto PI = internal::get_pi<T>();


enum class comparison : std::uint8_t {
    equal_to,
    not_equal_to,

    equals = equal_to,
    eq = equal_to,

    under,
    over,
    or_under,
    or_over,

    less = under,
    more = over,

    less_than = under,
    more_than = over,
    not_less_than = or_over,
    not_more_than = or_under,

    leq = or_under,
    geq = or_over
};


enum class interval_notation : std::uint8_t {
    right_open,
    left_open,
    open,
    closed,
};


enum class replacement_policy : std::uint8_t {
    insert_sync,
    overwrite_sync,
    overwrite_async
};


enum class rotation : std::int8_t {
    clockwise,

    counter_clockwise,
    anti_clockwise = counter_clockwise,
};


enum class positional_relation : std::int8_t {
    clockwise,

    counter_clockwise,
    anti_clockwise = counter_clockwise,

    backward,
    forward,

    in,
    on,
    out,

    included = in,
    inscribed,
    intersecting,
    circumscribed,
    distant,
};


enum class alignment : std::int8_t {
    left,
    center,
    right
};


} // namespace uni
#line 35 "iterable/operation.hpp"


namespace uni {


template<std::ranges::input_range R0, std::ranges::input_range R1>
    requires std::constructible_from<
        R0, std::common_type_t<std::ranges::range_size_t<R0>,std::ranges::range_size_t<R1>>
    >
R0 concat(R0&& r0, R1&& r1) noexcept(NO_EXCEPT) {
    R0 res(std::ranges::size(r0) + std::ranges::size(r1));
    std::ranges::copy(r0, std::ranges::begin(res));
    std::ranges::copy(r1, std::ranges::next(std::ranges::begin(res), std::ranges::size(r0)));
    return res;
}

template<std::ranges::input_range R, std::ranges::input_range... Rs>
R concat(R&& range, Rs&&... tails) noexcept(NO_EXCEPT) {
    return uni::concat(range, uni::concat(tails...));
}


template<std::ranges::input_range R>
    requires
        requires(R r) {
            r.erase(std::ranges::unique(ALL(r)), std::ranges::end(r));
        }
inline auto unique(R range) noexcept(NO_EXCEPT) {
    std::ranges::sort(range);
    range.erase(std::ranges::unique(ALL(range)), std::ranges::end(range));
    return range;
}


template<
    std::input_iterator I,
    std::sentinel_for<I> S,
    class T = std::iter_value_t<I>
>
T mex(I first, S last, const T& base = T()) noexcept(NO_EXCEPT) {
    std::vector<T> val(first, last);
    std::ranges::sort(val);
    {
        auto range = std::ranges::unique(val);
        val.erase(ALL(range));
    }
    val.erase(val.begin(), std::ranges::lower_bound(val, base));

    T i = 0;
    while(i < std::ranges::ssize(val) && val[i] == i + base) ++i;

    return T{i} + base;
}

template<std::ranges::input_range R>
auto mex(R&& range, const std::ranges::range_value_t<R>& base = std::ranges::range_value_t<R>()) noexcept(NO_EXCEPT) {
    return mex(ALL(range), base);
}

template<class T>
auto mex(const std::initializer_list<T> v, const T& base = T()) noexcept(NO_EXCEPT) {
    return mex(ALL(v), base);
}


template<std::input_iterator I, std::sentinel_for<I> S, class T>
inline constexpr auto gcd(I first, S last) noexcept(NO_EXCEPT) {
    T res = T{0};
    for(auto itr=first; itr!=last; ++itr) res = std::gcd(res, *itr);
    return res;
}

template<std::input_iterator I, std::sentinel_for<I> S, class T>
inline constexpr auto lcm(I first, S last) noexcept(NO_EXCEPT) {
    T res = T{1};
    for(auto itr=first; itr!=last; ++itr) res = std::lcm(res, *itr);
    return res;
}


template<std::ranges::input_range R, class T = std::ranges::range_value_t<R>>
auto mex(R&& range, const T& base) noexcept(NO_EXCEPT) {
    return mex(ALL(range), base);
}


template<std::ranges::input_range R>
auto gcd(R&& range) noexcept(NO_EXCEPT) {
    return gcd(ALL(range));
}

template<std::ranges::input_range R>
auto lcm(R&& range) noexcept(NO_EXCEPT) {
    return lcm(ALL(range));
}


template<class R, std::input_iterator I, std::sentinel_for<I> S, class D>
    requires
        requires (R r, I itr) {
            r.emplace_back(itr, itr);
        }
auto split(I first, S last, const D& delim = ' ') noexcept(NO_EXCEPT) {
    R res;

    for(auto itr=first, fnd=first; ; itr=std::ranges::next(fnd)) {
        fnd = std::find(itr, last, delim);
        res.emplace_back(itr, fnd);
        if(fnd == last) break;
    }

    return res;
}


template<class R, std::ranges::input_range V, class D>
    requires (!std::ranges::input_range<D>)
auto split(V&& v, D&& d) noexcept(NO_EXCEPT) { return split<R>(ALL(v), d); }


template<class R, std::ranges::input_range V, std::ranges::input_range Ds>
auto split(V&& v, Ds&& ds) noexcept(NO_EXCEPT) {
    R res = { v };
    ITR(d, ds) {
        R tmp;
        ITR(p, res) tmp = concat(tmp, split<R>(p, d));
        res = std::move(tmp);
    }
    return res;
}


template<class R, std::ranges::input_range V, class T>
auto split(V&& v, const std::initializer_list<T> ds) noexcept(NO_EXCEPT){
    return split<R,V>(v, std::vector<T>(ALL(ds)));
}


template<std::ranges::sized_range Source, std::ranges::sized_range Qeury>
auto find(Source&& source,  Qeury&& query) noexcept(NO_EXCEPT) {
    z_array z_arr(views::concat(query, source));
    const auto query_size = std::ranges::ssize(query);

    vector<std::ranges::iterator_t<Source>> res;
    {
        auto itr = std::ranges::begin(source);
        REP(i, query_size, std::ranges::size(z_arr)) {
            if(z_arr[i] >= query_size) res.push_back(itr);
            ++itr;
        }
    }

    return res;
}


template<
    replacement_policy POLICY,
    std::ranges::sized_range R,
    std::ranges::sized_range From,
    std::ranges::sized_range To
>
auto replaced(R&& source, From&& from, To&& to) noexcept(NO_EXCEPT) {
    std::remove_cvref_t<R> res;

    if constexpr(POLICY == replacement_policy::insert_sync) {
        const auto found = find(source, from);
        auto itr = std::ranges::begin(source);
        ITRR(fn, found) {
            std::ranges::copy(itr, fn, std::back_inserter(res));
            std::ranges::copy(ALL(to), std::back_inserter(res));
            itr = std::ranges::next(fn, std::ranges::size(from));
        }
        std::ranges::copy(itr, std::ranges::end(source), std::back_inserter(res));
    }
    else {
        res = source;
        res.resize(std::ranges::size(source) + std::ranges::size(to));

        const auto found = find(res, from);
        auto prev = std::ranges::begin(res);
        ITRR(fn, found) {
            if constexpr(POLICY == replacement_policy::overwrite_sync) {
                if(prev <= fn) prev = std::ranges::copy(to, fn);
            }
            else {
                std::ranges::copy(to, fn);
            }
        }

        res.resize(std::ranges::size(source));
    }

    return res;
}

template<
    std::ranges::sized_range R,
    std::ranges::sized_range From,
    std::ranges::sized_range To
>
inline auto replaced(R&& source, From&& from, To&& to) noexcept(NO_EXCEPT) {
    return replaced<replacement_policy::insert_sync, R, From, To>(std::forward<R>(source), std::forward<From>(from), std::forward<To>(to));
}


template<alignment ALIGNMENT, internal::resizable_range R, class T = std::ranges::range_value_t<R>>
auto align(R&& source, const internal::size_t size, const T& v = T()) noexcept(NO_EXCEPT) {
    if(std::ssize(source) >= size) return source;

    if(ALIGNMENT == alignment::left) {
        R left, right;
        left = source;
        right.resize(size - std::size(left), v);
        return R(ALL(uni::views::concat(left, right)));
    }

    if(ALIGNMENT == alignment::center) {
        R left, center, right;
        center = source;
        left.resize((size - std::size(center)) / 2, v);
        right.resize(size - std::size(center) - std::size(left), v);
        return R(ALL(uni::views::concat(left, center, right)));
    }

    if(ALIGNMENT == alignment::right) {
        R left, right;
        right = source;
        left.resize(size - std::size(right), v);
        return R(ALL(uni::views::concat(left, right)));
    }
    assert(false);
}


template<internal::resizable_range R, class T = std::ranges::range_value_t<R>>
auto ljust(R&& source, const internal::size_t size, const T& v = T()) noexcept(NO_EXCEPT) {
    return align<alignment::left>(source, size, v);
}

template<internal::resizable_range R, class T = std::ranges::range_value_t<R>>
auto cjust(R&& source, const internal::size_t size, const T& v = T()) noexcept(NO_EXCEPT) {
    return align<alignment::center>(source, size, v);
}

template<internal::resizable_range R, class T = std::ranges::range_value_t<R>>
auto rjust(R&& source, const internal::size_t size, const T& v = T()) noexcept(NO_EXCEPT) {
    return align<alignment::right>(source, size, v);
}


template<
    class Res,
    std::ranges::random_access_range Target,
    std::ranges::forward_range Order
>
    requires std::ranges::output_range<Res, std::ranges::range_value_t<Target>>
Res ordered_by(Target&& target, Order&& order) noexcept(NO_EXCEPT) {
    const auto target_size = std::ranges::ssize(target);
    const auto order_size = std::ranges::ssize(order);
    Res res(order_size);

    {
        auto res_itr = std::ranges::begin(res);
        auto order_itr = std::ranges::begin(order);
        const auto order_end = std::ranges::end(std::forward<Order>(order));

        for(; order_itr != order_end; ++res_itr, ++order_itr) {
            if constexpr(std::signed_integral<std::ranges::range_value_t<Order>>) assert(0 <= *order_itr);
            assert(*order_itr < target_size);
            *res_itr = target[*order_itr];
        }
    }

    return res;
}


template<
    std::ranges::random_access_range Target,
    std::ranges::forward_range Order
>
auto ordered_by(Target&& target, Order&& order) noexcept(NO_EXCEPT) {
    return ordered_by<std::remove_cvref_t<Target>, Target, Order>(std::forward<Target>(target), std::forward<Order>(order));
}


template<std::ranges::input_range Target, std::ranges::input_range Source>
    requires std::equality_comparable_with<std::ranges::range_value_t<Target>, std::ranges::range_value_t<Source>>
auto is_subsequence_of(Target&& target, Source&& source) noexcept(NO_EXCEPT) {
    auto target_itr = std::ranges::begin(source);
    auto source_itr = std::ranges::begin(source);

    const auto target_end = std::ranges::end(source);
    const auto source_end = std::ranges::end(source);

    for(; source_itr != source_end; ++source_itr) {
        if(*target_itr == *source_itr) ++target_itr;
    }

    return target_itr == target_end;
}


template<std::ranges::input_range Target, std::ranges::input_range Source>
    requires std::equality_comparable_with<std::ranges::range_value_t<Target>, std::ranges::range_value_t<Source>>
auto is_continuous_subsequence_of(Target&& target, Source&& source) noexcept(NO_EXCEPT) {
    auto found = find(source, target);
    return found.size() > 0;
}


} // namespace uni
#line 31 "numeric/arithmetic.hpp"


namespace uni {


template<class T>
inline constexpr T div_floor(const T& x, const T& d) noexcept(NO_EXCEPT) {
    if constexpr(std::is_integral_v<T>) {
        return x / d - (x % d && ((x < 0) ^ (d < 0)));
    }
    else {
        return std::floor(x / d);
    }
}

template<class T>
inline constexpr T div_ceil(const T& x, const T& d) noexcept(NO_EXCEPT) {
    if constexpr(std::is_integral_v<T>) {
        return div_floor(x + d - 1, d);
    }
    else {
        return std::ceil(x / d);
    }
}

template<class T>
inline constexpr T div_round(const T& x, const T& d) noexcept(NO_EXCEPT) {
    if constexpr(std::is_integral_v<T>) {
        return div_round<ld>(x, d);
    }
    else {
        return std::round(x / d);
    }
}


template<class T>
inline constexpr std::make_signed_t<T> to_signed(const T& x) noexcept(NO_EXCEPT) {
    return std::bit_cast<std::make_signed_t<T>>(x);
}

template<class T>
inline constexpr std::make_unsigned_t<T> to_unsigned(const T& x) noexcept(NO_EXCEPT) {
    return std::bit_cast<std::make_unsigned_t<T>>(x);
}


namespace internal {


template<class T>
inline constexpr auto perm(const T& n, const T& r) noexcept(NO_EXCEPT) {
    T res = 1;
    REP(i, r) res *= n - i;
    return res;
}

template<class T>
inline constexpr auto comb(const T& n, T r) noexcept(NO_EXCEPT) {
    if(n < 2 * r) r = n - r;

    T p = 1, q = 1;
    REP(i, r) p *= n - i, q *= r - i;

    return p / q;
}


} // namespace internal


template<class T0, std::common_with<T0> T1>
inline constexpr auto perm(const T0& n, const T1& r) noexcept(NO_EXCEPT) {
    assert(n >= 0), assert(r >= 0);
    using T = std::common_type_t<T0, T1>;
    if(n < r) return static_cast<T>(0);
    return internal::perm<T>(n, r);
}

template<class T0, std::common_with<T0> T1>
inline constexpr auto comb(const T0& n, const T1& r) noexcept(NO_EXCEPT) {
    assert(n >= 0), assert(r >= 0);
    using T = std::common_type_t<T0, T1>;
    if(n < r) return static_cast<T>(0);
    if(n == r) return static_cast<T>(1);
    return internal::comb<T>(n, r);
}



template<class T, class U, std::invocable<T, T> F = std::multiplies<>>
constexpr T pow(T x, U n, F mul = F(), T one = static_cast<T>(1)) noexcept(NO_EXCEPT) {
    if(n == 0) return one;
    if(n == 1 || x == one) return x;

    T res = one;

    while(true) {
        if(n & 1) res = mul(res, x);
        x = mul(x, x);
        if(n == 0) return res;
        n >>= 1;
    }

    assert(false);
}


using atcoder::pow_mod;
using atcoder::inv_mod;
using atcoder::crt;


template<class T> inline constexpr T sign(const T& x) noexcept(NO_EXCEPT) {
    if(x == 0) return 0;
    return (x > 0) ? 1 : -1;
}

template<class T, T FROM_MIN, T FROM_MAX, T TO_MIN, T TO_MAX> inline constexpr T mapping(const T x) {
    return (x - FROM_MIN) * (TO_MAX - TO_MIN) / (FROM_MAX - FROM_MIN) + TO_MIN;
}
template<class T> inline constexpr T mapping(const T x, const T from_min, const T from_max, const T to_min, const T to_max) {
    return (x - from_min) * (to_max - to_min) / (from_max - from_min) + to_min;
}

template<class... Args>
inline constexpr std::common_type_t<Args...> min(const Args&... args) noexcept(NO_EXCEPT) {
    return std::min({ static_cast<std::common_type_t<Args...>>(args)... });
}

template<class... Args>
inline constexpr std::common_type_t<Args...> max(const Args&... args) noexcept(NO_EXCEPT) {
    return std::max({ static_cast<std::common_type_t<Args...>>(args)... });
}


template<class T>
inline constexpr T gcd(const std::initializer_list<T> args) noexcept(NO_EXCEPT) {
    return gcd(ALL(args));
}

template<class... Args>
inline constexpr std::common_type_t<Args...> gcd(const Args&... args) noexcept(NO_EXCEPT) {
    return gcd({ static_cast<std::common_type_t<Args...>>(args)... });
}


template<class T>
inline constexpr T lcm(const std::initializer_list<T> args) noexcept(NO_EXCEPT) {
    return lcm(ALL(args));
}

template<class... Args>
inline constexpr std::common_type_t<Args...> lcm(const Args&... args) noexcept(NO_EXCEPT) {
    return lcm({ static_cast<std::common_type_t<Args...>>(args)... });
}


template<std::integral T0, std::integral T1>
inline constexpr std::optional<std::common_type_t<T0, T1>> add_overflow(const T0& a, const T1& b) noexcept(NO_EXCEPT) {
    std::common_type_t<T0, T1> res;
    if(__builtin_add_overflow(a, b, &res)) return {};
    return res;
}

template<std::integral T0, std::integral T1>
inline constexpr std::optional<std::common_type_t<T0, T1>> sub_overflow(const T0& a, const T1& b) noexcept(NO_EXCEPT) {
    std::common_type_t<T0, T1> res;
    if(__builtin_sub_overflow(a, b, &res)) return {};
    return res;
}

template<std::integral T0, std::integral T1>
inline constexpr std::optional<std::common_type_t<T0, T1>> mul_overflow(const T0& a, const T1& b) noexcept(NO_EXCEPT) {
    std::common_type_t<T0, T1> res;
    if(__builtin_mul_overflow(a, b, &res)) return {};
    return res;
}

template<std::integral T0, std::integral T1, std::integral Limit>
inline auto add_clamp(const T0 x, const T1 y, const Limit inf, const Limit sup) noexcept(NO_EXCEPT) {
    using Common = std::common_type_t<T0, T1, Limit>;
    const auto res = add_overflow<Common>(x, y);
    if(!res) {
        if(x < 0 && y < 0) return inf;
        if(x > 0 && y > 0) return sup;
        assert(false);
    }
    return std::clamp<Common>(*res, inf, sup);
}

template<std::integral T0, std::integral T1, std::integral Limit>
inline auto sub_clamp(const T0 x, const T1 y, const Limit inf, const Limit sup) noexcept(NO_EXCEPT) {
    using Common = std::common_type_t<T0, T1, Limit>;
    const auto res = sub_overflow<Common>(x, y);
    if(!res) {
        if(x < 0 && y > 0) return inf;
        if(x > 0 && y < 0) return sup;
        assert(false);
    }
    return std::clamp<Common>(*res, inf, sup);
}

template<std::integral T0, std::integral T1, std::integral Limit>
inline auto mul_clamp(const T0 x, const T1 y, const Limit inf, const Limit sup) noexcept(NO_EXCEPT) {
    using Common = std::common_type_t<T0, T1, Limit>;
    const auto res = mul_overflow<Common>(x, y);
    if(!res) {
        if((x > 0) xor (y > 0)) return inf;
        else return sup;
        assert(false);
    }
    return std::clamp<Common>(*res, inf, sup);
}


template<class T>
inline constexpr T sqrt_floor(const T x) noexcept(NO_EXCEPT) {
    return static_cast<T>(std::sqrt(static_cast<long double>(x)));
}

template<class T>
inline constexpr T sqrt_ceil(const T x) noexcept(NO_EXCEPT) {
    T res = sqrt_floor(x);

    if constexpr(std::is_floating_point_v<T>) {
        while(res * res < x) res += 1;
    }
    else {
        while(mul_overflow(res, res).value_or(std::numeric_limits<T>::max()) < x) ++res;
    }

    return res;
}

template<class T, std::integral K>
inline constexpr T kth_root_floor(T x, const K k) noexcept(NO_EXCEPT) {
    assert(x >= 0);
    if(std::signed_integral<K>) assert(k > 0);

    if(x <= 1 or k == 1) return x;

    constexpr auto DIGITS = std::numeric_limits<T>::digits;
    if(k >= DIGITS) return T{1};
    if(k == 2) return sqrt_floor(x);

    constexpr auto MAX = std::numeric_limits<T>::max();
    if(x == MAX) --x;

    auto pow = [&](T t, i64 p) {
        if(p == 0) return T{1};
        T res = 1;
        while(p) {
            if(p & 1) {
                res = mul_overflow(res, t).value_or(MAX);
            }
            t = mul_overflow(t, t).value_or(MAX);
            p >>= 1;
        }
        return res;
    };

    auto res = static_cast<T>(std::pow(x, std::nextafter(1 / static_cast<double>(k), 0)));
    while(pow(res + 1, k) <= x) ++res;

    return res;
}


template<std::integral T>
T inline constexpr extended_gcd(const T& a, const T& b, T& x, T& y) noexcept {
    if(b == 0) {
        x = 1;
        y = 0;
        return a;
    }

    const T d = extended_gcd(b, a%b, y, x);

    y -= a / b * x;
    return d;
};

template<std::integral T>
std::pair<T, spair<T>> inline constexpr extended_gcd(const T& a, const T& b) noexcept {
    T x, y;
    const T d = extended_gcd(a, b, x, y);
    return { d, spair<T>{ x, y } };
};


template<std::integral T>
std::optional<spair<T>> inline constexpr bezout_equation(const T& a, const T& b, const T& c) noexcept {
    if(a == 0) {
        if(b == 0) {
            if(c == 0) return spair<T>{ 0, 0 };
            else { };
        }
        if(c % b == 0) return spair<T>{ 0, c / b };
        return {};
    }

    if(b == 0) {
        const auto ans = bezout_equation(b, a, c);
        if(ans.has_value()) return swapped(ans.value());
        return {};
    }

    T x, y;
    const T gcd = extended_gcd(a, b, x, y);

    if(c % gcd != 0) return {};

    const T p = c / gcd;
    return spair<T>{ x * p, y * p };
};


} // namespace uni
#line 10 "algebraic/base.hpp"


namespace uni {

namespace algebraic {


template<class Derived>
struct scalar_multipliable {
    struct identity {
        template<std::integral Scalar>
        friend inline Derived operator*(const Scalar, const Derived& val) noexcept(NO_EXCEPT) {
            return val;
        }
    };


    struct automatic {
        template<std::integral Scalar>
        friend inline Derived operator*(const Scalar k, const Derived& val) noexcept(NO_EXCEPT) {
            return uni::pow<Derived, Scalar, std::plus<Derived>>(val, k, {}, {});
        }
    };
};



template<class T>
struct base {
    using value_type = T;

  protected:
    value_type _value;

  public:
    template<class... Args>
        requires std::constructible_from<value_type, Args...>
    base(Args&&... args) noexcept(NO_EXCEPT) : _value(std::forward<Args>(args)...) {}

    inline explicit operator value_type() const noexcept(NO_EXCEPT) { return this->_value; }
    inline auto val() const noexcept(NO_EXCEPT) { return this->_value; };

    inline const value_type* operator->() const noexcept(NO_EXCEPT) { return &this->_value; };
    inline value_type* operator->() noexcept(NO_EXCEPT) { return &this->_value; };


    friend inline auto operator<=>(const base& lhs, const base& rhs) noexcept(NO_EXCEPT) {
        return lhs._value <=> rhs._value;
    };

    friend inline bool operator==(const base& lhs, const base& rhs) noexcept(NO_EXCEPT) {
        return lhs._value == rhs._value;
    }
};

struct associative {};

struct commutative {};


} // namespace algebraic

} // namespace uni
#line 11 "algebraic/internal/concepts.hpp"


namespace uni {

namespace algebraic {

namespace internal {


template<class T>
concept magma =
    uni::internal::addable<T> &&
    requires {
        typename T::value_type;
    };


template<class T>
concept associative = std::is_base_of_v<algebraic::associative, T>;

template<class T>
concept commutative = std::is_base_of_v<algebraic::commutative, T>;

template<class T>
concept invertible = uni::internal::unary_subtractable<T>;


template<class T>
concept semigroup = magma<T> && associative<T>;

template<class T>
concept monoid = semigroup<T> && std::default_initializable<T>;

template<class T>
concept group = monoid<T> && invertible<T>;


} // namespace internal

} // namespace algebraic

} // namespace uni
#line 13 "action/base.hpp"


namespace uni {

namespace actions {


template<class operation = uni::internal::dummy>
    requires algebraic::internal::monoid<operation> || std::same_as<operation, uni::internal::dummy>
struct base {
    static operation power(const operation& x, const uni::internal::size_t) noexcept(NO_EXCEPT) { return x; }
};


namespace internal {


template<class T>
concept operatable_action = algebraic::internal::magma<typename T::operand>;

template<class T>
concept effective_action =
    algebraic::internal::magma<typename T::operation> &&
    requires (const typename T::operation& f, const uni::internal::size_t length) {
        { T::power(f, length) } -> std::same_as<typename T::operation>;
    };

template<class T>
concept operand_only_action = operatable_action<T> && (!effective_action<T>);

template<class T>
concept effect_only_action = effective_action<T> && (!operatable_action<T>);

template<class T>
concept full_action =
    operatable_action<T> && effective_action<T> &&
    requires (typename T::operation f, typename T::operand v) {
        { T::mapping(f, v) } -> std::same_as<typename T::operand>;
    };

template<class T>
concept action = operatable_action<T> || effective_action<T>;


} // namespace internal

} // namespace actions

} // namespace uni
#line 2 "action/helpers.hpp"

#line 5 "action/helpers.hpp"


#line 2 "algebraic/null.hpp"


#line 5 "algebraic/null.hpp"


#line 9 "algebraic/null.hpp"

#line 12 "algebraic/null.hpp"


namespace uni {

namespace algebraic {


template<class T = uni::internal::dummy>
struct null : base<T>, scalar_multipliable<null<T>>::identity, associative, commutative {
    using base<T>::base;

    friend inline null operator+(const null& lhs, const null& rhs) noexcept(NO_EXCEPT) {
        if(lhs == null()) return rhs;
        return lhs;
    }

    inline null operator-() const noexcept(NO_EXCEPT)
        requires internal::invertible<T>
    {
        return -*this;
    }
};


} // namespace algebraic

} // namespace uni
#line 2 "algebraic/helper.hpp"


#line 7 "algebraic/helper.hpp"


namespace uni {

namespace algebraic {


template<class T, auto op, auto e, class... Tags>
struct helper : uni::algebraic::base<T>, uni::algebraic::scalar_multipliable<helper<T, op, e, Tags...>>::automatic, Tags... {
    static_assert(std::same_as<std::invoke_result_t<decltype(op), T, T>, T>);
    static_assert(std::same_as<std::invoke_result_t<decltype(e)>, T>);

    using uni::algebraic::base<T>::base;

    helper() : helper(e()) {}

    friend inline helper operator+(const helper& lhs, const helper& rhs) noexcept(NO_EXCEPT) {
        return op(lhs.val(), rhs.val());
    }
};


template<class T, auto op, auto e>
using monoid_helper = helper<T, op, e, associative>;


template<class T>
struct make_magma {
    using type = null<T>;

    static_assert(internal::magma<type>);
};


template<internal::magma T>
struct make_magma<T> {
    using type = T;
};

template<class T>
using make_magma_t = typename make_magma<T>::type;



} // namespace algebraic

} // namespace uni
#line 2 "action/null.hpp"


#line 6 "action/null.hpp"

#line 8 "action/null.hpp"

#line 2 "algebraic/addition.hpp"


#line 7 "algebraic/addition.hpp"


namespace uni {

namespace algebraic {


template<class T>
struct addition : base<T>, associative, commutative {
    using base<T>::base;

    friend inline addition operator+(const addition& lhs, const addition& rhs) noexcept(NO_EXCEPT) {
        return lhs.val() + rhs.val();
    }

    template<std::integral Scalar>
    friend inline addition operator*(const Scalar k, const addition& rhs) noexcept(NO_EXCEPT) {
        return k * rhs.val();
    }

    inline addition operator-() const noexcept(NO_EXCEPT)
        requires internal::invertible<T>
    {
        return -this->val();
    }
};


} // namespace algebraic

} // namespace uni
#line 11 "action/null.hpp"


namespace uni {

namespace actions {


template<class T>
struct null : base<algebraic::null<T>> {
    using operand = algebraic::null<T>;
    using operation = algebraic::null<T>;

    static operand mapping(const operation&, const operand& x) noexcept(NO_EXCEPT) { return x; }
};


} // namespace actions

} // namespace uni
#line 11 "action/helpers.hpp"

namespace uni {

namespace actions {


template<class S, auto op, auto e, class F, auto _mapping, auto composition, auto id, auto _power = nullptr>
struct helper {
    static_assert(std::same_as<std::invoke_result_t<decltype(_mapping), F, S>, S>);
    // static_assert(std::same_as<std::invoke_result_t<decltype(_power), F, uni::internal::size_t>, F>);

    using operand = algebraic::monoid_helper<S, op, e>;
    using operation = algebraic::monoid_helper<F, composition, id>;

    static operand mapping(const operation& f, const operand& x) noexcept(NO_EXCEPT) {
        return _mapping(f.val(), x.val());
    }

    static operation power(const operation& x, [[maybe_unused]] const uni::internal::size_t length) noexcept(NO_EXCEPT) {
        if constexpr(_power == nullptr) return x;
        else return _power(x.val(), length);
    }
};


template<class S, class F, auto _mapping, auto _power = nullptr>
struct mixer {
    static_assert(std::same_as<std::invoke_result_t<decltype(_mapping), F, S>, S>);
    static_assert(std::same_as<std::invoke_result_t<decltype(_power), F, uni::internal::size_t>, F>);

    using operand = S;
    using operation = F;

    static operand mapping(const operation& f, const operand& x) noexcept(NO_EXCEPT) {
        return _mapping(f.val(), x.val());
    }
    static operation power(const operation& x, [[maybe_unused]] const uni::internal::size_t length) noexcept(NO_EXCEPT) {
        if constexpr(_power == nullptr) return x;
        return _power(x.val(), length);
    }
};



template<class S>
struct amplifier {
    using operand = S;
    using operation = S;

    static operand mapping(const operation& f, const operand& x) noexcept(NO_EXCEPT) {
        return f + x;
    }

    static operation power(const operation& x, [[maybe_unused]] const uni::internal::size_t length) noexcept(NO_EXCEPT) {
        return length * x;
    }
};


template<algebraic::internal::magma Magma>
struct make_operatable {
    struct type {
        using operand = Magma;
    };

    static_assert(internal::operatable_action<type>);
};

template<class T>
using make_operatable_t = typename make_operatable<T>::type;


template<algebraic::internal::magma Magma>
struct make_effective {
    struct type : base<Magma> {
        using operation = Magma;
    };

    static_assert(internal::effective_action<type>);
};

template<class T>
using make_effective_t = typename make_effective<T>::type;


template<class T>
struct make_full {
    using type = null<T>;

    static_assert(internal::full_action<type>);
};

template<algebraic::internal::magma Magma>
struct make_full<Magma> {
    using type = make_full<make_operatable_t<Magma>>::type;
};

template<internal::full_action Action>
struct make_full<Action> {
    using type = Action;
};

template<internal::operand_only_action Action>
struct make_full<Action> {
    using base = Action;
    struct type : actions::base<algebraic::null<typename base::operand::value_type>> {
        using operand = typename base::operand;
        using operation = algebraic::null<typename base::operand::value_type>;

        using actions::base<algebraic::null<typename base::operand::value_type>>::base;

        static operand mapping(const operation&, const operand& x) noexcept(NO_EXCEPT) { return x; }
    };

    static_assert(internal::full_action<type>);
};

template<internal::effect_only_action Action>
struct make_full<Action> {
    using base = Action;

    struct type : base {
        using operand = typename base::operation;
        using operation = typename base::operation;

        using base::base;

        static operand mapping(const operation& f, const operand& x) noexcept(NO_EXCEPT) { return f + x; }
    };

    static_assert(internal::full_action<type>);
};


template<class T>
using make_full_t = typename make_full<T>::type;


} // namespace actions

} // namespace uni
#line 2 "action/range_add.hpp"


#line 6 "action/range_add.hpp"

#line 8 "action/range_add.hpp"


namespace uni {

namespace actions {



template<class T>
struct range_add : base<algebraic::addition<T>> {
    using operand = algebraic::null<T>;
    using operation = algebraic::addition<T>;

    static operand mapping(const operation& f, const operand& x) noexcept(NO_EXCEPT) {
        return f.val() + x.val();
    }
};

static_assert(internal::full_action<range_add<int>>);


} // namesapce actions

} // namespace uni
#line 2 "action/range_add_range_max.hpp"


#line 5 "action/range_add_range_max.hpp"

#line 7 "action/range_add_range_max.hpp"

#line 2 "algebraic/maximum.hpp"


#line 6 "algebraic/maximum.hpp"

#line 9 "algebraic/maximum.hpp"


namespace uni {

namespace algebraic {


template<class T>
struct maximum : base<T>, scalar_multipliable<maximum<T>>::identity, associative, commutative {
    using base<T>::base;

    maximum() noexcept(NO_EXCEPT) : maximum(std::numeric_limits<T>::lowest()) {};

    friend inline maximum operator+(const maximum& lhs, const maximum& rhs) noexcept(NO_EXCEPT) {
        return std::max(lhs.val(), rhs.val());
    }
};


} // namespace algebraic

} // namespace uni
#line 10 "action/range_add_range_max.hpp"



namespace uni {

namespace actions {


template<class T>
struct range_add_range_max : base<algebraic::addition<T>> {
    using operand = algebraic::maximum<T>;
    using operation = algebraic::addition<T>;

    static operand mapping(const operation& f, const operand& x) noexcept(NO_EXCEPT) {
        return f.val() + x.val();
    }
};


static_assert(internal::full_action<uni::actions::range_add_range_max<int>>);


} // namespace actions

} // namespace uni
#line 2 "action/range_add_range_min.hpp"


#line 5 "action/range_add_range_min.hpp"

#line 7 "action/range_add_range_min.hpp"

#line 2 "algebraic/minimum.hpp"


#line 6 "algebraic/minimum.hpp"

#line 9 "algebraic/minimum.hpp"


namespace uni {

namespace algebraic {


template<class T>
struct minimum : base<T>, scalar_multipliable<minimum<T>>::identity, associative, commutative {
    using base<T>::base;

    minimum() noexcept(NO_EXCEPT) : minimum(std::numeric_limits<T>::max()) {};

    friend inline minimum operator+(const minimum& lhs, const minimum& rhs) noexcept(NO_EXCEPT) {
        return std::min(lhs.val(), rhs.val());
    }
};


} // namespace algebraic

} // namespace uni
#line 10 "action/range_add_range_min.hpp"


namespace uni {

namespace actions {


template<class T>
struct range_add_range_min : base<algebraic::addition<T>> {
    using operand = algebraic::minimum<T>;
    using operation = algebraic::addition<T>;

    static operand mapping(const operation& f, const operand& x) noexcept(NO_EXCEPT) {
        return f.val() + x.val();
    }
};

static_assert(internal::full_action<uni::actions::range_add_range_min<int>>);


} // namespace actions

} // namespace uni
#line 2 "action/range_add_range_sum.hpp"


#line 5 "action/range_add_range_sum.hpp"

#line 7 "action/range_add_range_sum.hpp"

#line 9 "action/range_add_range_sum.hpp"


namespace uni {

namespace actions {


template<class T>
using range_add_range_sum = amplifier<algebraic::addition<T>>;

static_assert(internal::full_action<range_add_range_sum<int>>);


} // namespace actions

} // namespace uni
#line 2 "action/range_affine_range_minmax.hpp"


#line 5 "action/range_affine_range_minmax.hpp"

#line 7 "action/range_affine_range_minmax.hpp"

#line 2 "algebraic/minmax.hpp"


#line 7 "algebraic/minmax.hpp"

#line 10 "algebraic/minmax.hpp"


namespace uni {

namespace algebraic {


template<class T>
struct minmax : base<std::pair<T, T>>, scalar_multipliable<minmax<T>>::identity, associative, commutative {
    using base<std::pair<T, T>>::base;

    minmax() noexcept(NO_EXCEPT)
      : minmax(std::numeric_limits<T>::max(), std::numeric_limits<T>::lowest())
    {};

    minmax(const T& v) noexcept(NO_EXCEPT) : minmax(v, v) {};


    friend inline minmax operator+(const minmax& lhs, const minmax& rhs) noexcept(NO_EXCEPT) {
        return minmax({ std::min(lhs.val().first, rhs->first), std::max(lhs.val().second, rhs->second) });
    }
};


} // namespace algebraic

} // namespace uni
#line 2 "algebraic/affine.hpp"

#line 4 "algebraic/affine.hpp"

#line 7 "algebraic/affine.hpp"

namespace uni {

namespace algebraic {


template<class T, bool REVERSE = false>
struct affine : base<std::pair<T, T>>, scalar_multipliable<affine<T, REVERSE>>::automatic, associative {
    using base<std::pair<T, T>>::base;

    affine() noexcept(NO_EXCEPT) : affine({ 1, 0 }) {};

    friend inline affine operator+(const affine& lhs, const affine& rhs) noexcept(NO_EXCEPT) {
        if constexpr(REVERSE) return affine({ lhs->first * rhs->first, lhs(rhs->second) });
        return affine({ rhs->first * lhs->first, rhs(lhs->second) });
    }

    inline auto operator()(const T& x) const noexcept(NO_EXCEPT) {
        return this->val().first * x + this->val().second;
    }
};


} // namespace algebraic

} // namespace uni
#line 10 "action/range_affine_range_minmax.hpp"



namespace uni {


namespace actions {


template<class T, bool REVERSE = false>
struct range_affine_range_minmax : base<algebraic::affine<T, !REVERSE>> {
    using operand = algebraic::minmax<T>;
    using operation = algebraic::affine<T, !REVERSE>;

    static auto mapping(const operation& f, const operand& x) noexcept(NO_EXCEPT) {
        auto res = operand({ f(x->first), f(x->second) });
        if (f->first < 0) std::swap(res->first, res->second);
        return res;
    }
};

static_assert(internal::full_action<range_affine_range_minmax<int>>);


} // namespace actions

} // namespace uni
#line 2 "action/range_affine_range_sum.hpp"


#line 5 "action/range_affine_range_sum.hpp"

#line 7 "action/range_affine_range_sum.hpp"

#line 10 "action/range_affine_range_sum.hpp"



namespace uni {

namespace actions {


template<class T, bool REVERSE = false>
struct range_affine_range_sum {
    using operand = algebraic::addition<T>;
    using operation = algebraic::affine<T, !REVERSE>;

    static operand mapping(const operation& f, const operand& x) noexcept(NO_EXCEPT) {
        return f(x.val());
    }

    static auto power(const operation& f, const uni::internal::size_t length) noexcept(NO_EXCEPT) {
        return operation({ f->first, f->second * length });
    }
};

static_assert(internal::full_action<range_affine_range_sum<int>>);


} // namespace actions

} // namespace uni
#line 2 "action/range_bitxor.hpp"


#line 5 "action/range_bitxor.hpp"

#line 8 "action/range_bitxor.hpp"

#line 2 "algebraic/bit_xor.hpp"

#line 5 "algebraic/bit_xor.hpp"

namespace uni {

namespace algebraic {


template<class T>
struct bit_xor : base<T>, associative, commutative {
    using base<T>::base;

    friend inline bit_xor operator+(const bit_xor& lhs, const bit_xor& rhs) noexcept(NO_EXCEPT) {
        return lhs.val() xor rhs.val();
    }

    template<std::integral Scalar>
    friend inline bit_xor operator*(const Scalar k, const bit_xor& val) noexcept(NO_EXCEPT) {
        return k % 2 == 0 ? bit_xor{} : val;
    }

    inline bit_xor operator-() const noexcept(NO_EXCEPT) {
        return this->val();
    }
};


} // namespace algebraic

} // namespace uni
#line 10 "action/range_bitxor.hpp"



namespace uni {

namespace actions {


template<class T>
using range_bitxor = make_operatable_t<uni::algebraic::bit_xor<T>>;

static_assert(internal::operand_only_action<range_bitxor<int>>);



} // namespace actions

} // namespace uni
#line 2 "action/range_chgcd_range_gcd.hpp"


#line 2 "algebraic/gcd.hpp"

#line 4 "algebraic/gcd.hpp"

#line 7 "algebraic/gcd.hpp"


namespace uni {

namespace algebraic {


template<class T>
struct gcd : base<T>, scalar_multipliable<gcd<T>>::identity, associative, commutative {
    using base<T>::base;

    gcd() noexcept(NO_EXCEPT) : gcd() {};

    friend inline gcd operator+(const gcd& lhs, const gcd& rhs) noexcept(NO_EXCEPT) {
        return std::gcd(lhs.val(), rhs.val());
    }
};


} // namespace algebraic

} // namespace uni
#line 5 "action/range_chgcd_range_gcd.hpp"

#line 7 "action/range_chgcd_range_gcd.hpp"


namespace uni {

namespace actions {


template<class T>
using range_chgcd_range_gcd = amplifier<uni::algebraic::gcd<T>>;

static_assert(internal::full_action<range_chgcd_range_gcd<int>>);


} // namespace actions

} // namespace uni
#line 2 "action/range_chmax_range_max.hpp"


#line 5 "action/range_chmax_range_max.hpp"

#line 7 "action/range_chmax_range_max.hpp"


namespace uni {

namespace actions {


template<class T>
using range_chmax_range_max = amplifier<algebraic::maximum<T>>;

static_assert(internal::full_action<range_chmax_range_max<int>>);


} // namespace actions

} // namespace uni
#line 2 "action/range_chmin_range_min.hpp"


#line 5 "action/range_chmin_range_min.hpp"

#line 7 "action/range_chmin_range_min.hpp"


namespace uni {

namespace actions {


template<class T>
using range_chmin_range_min = amplifier<algebraic::maximum<T>>;

static_assert(internal::full_action<range_chmin_range_min<int>>);


} // namespace actions

} // namespace uni
#line 2 "action/range_chminchmax_range_minmax.hpp"


#line 5 "action/range_chminchmax_range_minmax.hpp"

#line 7 "action/range_chminchmax_range_minmax.hpp"


namespace uni {

namespace actions {


template<class T>
using range_chminchmax_range_minmax = amplifier<algebraic::minmax<T>>;

static_assert(internal::full_action<range_chminchmax_range_minmax<int>>);


} // namespace actions

} // namespace uni
#line 2 "action/range_composition.hpp"


#line 6 "action/range_composition.hpp"

#line 8 "action/range_composition.hpp"



namespace uni {

namespace actions {


template<class T, bool REVERSE = false>
using range_composition = make_operatable_t<uni::algebraic::affine<T, REVERSE>>;

static_assert(internal::operand_only_action<range_composition<int>>);


} // namespace actions

} // namespace uni
#line 2 "action/range_flip_range_bitxor.hpp"


#line 5 "action/range_flip_range_bitxor.hpp"

#line 7 "action/range_flip_range_bitxor.hpp"

#line 9 "action/range_flip_range_bitxor.hpp"


namespace uni {

namespace actions {


template<class T>
using range_flip_range_bitxor = amplifier<uni::algebraic::bit_xor<T>>;

static_assert(internal::full_action<range_flip_range_bitxor<int>>);


} // namespace actions

} // namespace uni
#line 2 "action/range_gcd.hpp"


#line 6 "action/range_gcd.hpp"

#line 8 "action/range_gcd.hpp"



namespace uni {

namespace actions {


template<class T>
using range_gcd = make_operatable_t<uni::algebraic::gcd<T>>;

static_assert(internal::operand_only_action<range_gcd<int>>);


} // namespace actions

} // namespace uni
#line 2 "action/range_max.hpp"


#line 6 "action/range_max.hpp"

#line 8 "action/range_max.hpp"



namespace uni {

namespace actions {


template<class T>
using range_max = make_operatable_t<uni::algebraic::maximum<T>>;

static_assert(internal::operand_only_action<range_max<int>>);


} // namespace actions

} // namespace uni
#line 2 "action/range_min.hpp"


#line 6 "action/range_min.hpp"

#line 8 "action/range_min.hpp"



namespace uni {

namespace actions {


template<class T>
using range_min = make_operatable_t<uni::algebraic::minimum<T>>;

static_assert(internal::operand_only_action<range_min<int>>);


} // namespace actions

} // namespace uni
#line 2 "action/range_sequence_hash.hpp"


#line 5 "action/range_sequence_hash.hpp"

#line 8 "action/range_sequence_hash.hpp"

#line 2 "algebraic/rolling_hash.hpp"


#line 5 "algebraic/rolling_hash.hpp"


#line 8 "algebraic/rolling_hash.hpp"

#line 10 "algebraic/rolling_hash.hpp"

#line 12 "algebraic/rolling_hash.hpp"

#line 2 "numeric/fast_prime.hpp"


#line 6 "numeric/fast_prime.hpp"


#line 2 "adaptor/set.hpp"


#include <set>
#include <unordered_set>
#line 11 "adaptor/set.hpp"


#line 15 "adaptor/set.hpp"

#line 2 "utility/functional.hpp"


#line 8 "utility/functional.hpp"

#line 11 "utility/functional.hpp"

#line 13 "utility/functional.hpp"

#line 16 "utility/functional.hpp"

#line 18 "utility/functional.hpp"


namespace uni {

namespace internal {


template<class T> constexpr T plus(const T a, const T b) noexcept(NO_EXCEPT) { return std::plus<T>{}(a, b); }
template<class T> constexpr T minus(const T a, const T b) noexcept(NO_EXCEPT) { return std::minus<T>{}(a, b); }

template<class T> constexpr T bit_xor(const T a, const T b) noexcept(NO_EXCEPT) { return a xor b; }


} // namespace internal


template<class T, class U> inline auto to_optional_if_equal(const T& v, const U& ill) noexcept(NO_EXCEPT) -> std::optional<T> {
    return v == ill ? std::optional<T>{} : std::optional<T>(v);
}
template<class T, class U> inline auto to_optional_if_over(const T& v, const U& ill) noexcept(NO_EXCEPT) -> std::optional<T> {
    return v > ill ? std::optional<T>{} : std::optional<T>(v);
}
template<class T, class U> inline auto to_optional_if_or_over(const T& v, const U& ill) noexcept(NO_EXCEPT) -> std::optional<T> {
    return v >= ill ? std::optional<T>{} : std::optional<T>(v);
}
template<class T, class U> inline auto to_optional_if_under(const T& v, const U& ill) noexcept(NO_EXCEPT) -> std::optional<T> {
    return v < ill ? std::optional<T>{} : std::optional<T>(v);
}
template<class T, class U> inline auto to_optional_if_or_under(const T& v, const U& ill) noexcept(NO_EXCEPT) -> std::optional<T> {
    return v <= ill ? std::optional<T>{} : std::optional<T>(v);
}

template<class T, class F> inline auto to_optional_if(const T& v, F&& f) noexcept(NO_EXCEPT) -> decltype(f(v), std::optional<T>{}){
    return f(v) ? std::optional<T>{} : std::optional<T>(v);
}

template<class T, class U> inline bool chmin(T &a, const U& b) noexcept(NO_EXCEPT) { return (a>b ? a=b, true : false); }
template<class T, class U> inline bool chmax(T &a, const U& b) noexcept(NO_EXCEPT) { return (a<b ? a=b, true : false); }

template<class T, class... Ts> inline bool chmin(T &a, Ts... b) noexcept(NO_EXCEPT) { return chmin(a, min(b...)); }
template<class T, class... Ts> inline bool chmax(T &a, Ts... b) noexcept(NO_EXCEPT) { return chmax(a, max(b...)); }

template<class... Ts>
inline constexpr std::common_type_t<Ts...> tuple_sum(const std::tuple<Ts...>& tuple, const std::common_type_t<Ts...>& base = std::common_type_t<Ts...>()) noexcept(NO_EXCEPT) {
    std::common_type_t<Ts...> res = base;
    tuple_for_each(tuple, [&](const auto& v) constexpr { res += v; });
    return res;
}

template<class... Ts>
inline constexpr std::common_type_t<Ts...> min_element(const std::tuple<Ts...>& tuple) noexcept(NO_EXCEPT) {
    return std::apply([&](auto&&... v) constexpr { return min(v...); }, tuple);
}


template<class... Ts>
inline constexpr std::common_type_t<Ts...> max_element(const std::tuple<Ts...>& tuple) noexcept(NO_EXCEPT) {;
    return std::apply([&](auto&&... v) constexpr { return max(v...); }, tuple);
}


template<interval_notation INTERVAL, class T0, class T1, class T2>
inline constexpr bool in_range(const T0& x, const T1& l, const T2& r) noexcept(NO_EXCEPT) {
    if constexpr(INTERVAL == interval_notation::right_open) return l <= x and x < r;
    else if constexpr(INTERVAL == interval_notation::left_open) return l < x and x <= r;
    else if constexpr(INTERVAL == interval_notation::open) return l < x and x < r;
    return l <= x and x <= r;
}

template<class F, class Tuple>
constexpr void tuple_for_each(F&& f, Tuple&& tuple) {
    std::apply(
        [&]<class... Ts>(Ts&&... elems) {
            (std::invoke(f, std::forward<Ts>(elems)), ...);
        },
        std::forward<Tuple>(tuple)
    );
}


template<class F, class Tuple>
constexpr auto tuple_transform(F&& f, Tuple&& tuple) {
    return std::apply(
        [&]<class...Ts>(Ts&&... elems) {
            return internal::tuple_or_pair_t<std::invoke_result_t<F&,Ts>...>(
                std::invoke(f, std::forward<Ts>(elems))...
            );
        },
        std::forward<Tuple>(tuple)
    );
}


} // namespace uni
#line 17 "adaptor/set.hpp"


namespace uni {

namespace internal {


template<class Set>
struct set_wrapper : Set {
    using Set::Set;
    using value_type = typename Set::value_type;
    using size_type = internal::size_t;

    template<class Key>
    auto remove(Key&& key) noexcept(NO_EXCEPT) { return this->extract(std::forward<Key>(key)); }

    inline auto ssize() const noexcept(NO_EXCEPT) { return std::ranges::ssize(*this); }

    inline auto min_element() const noexcept(NO_EXCEPT) { return this->begin(); }
    inline auto max_element() const noexcept(NO_EXCEPT) { return std::ranges::prev(this->end()); }

    inline auto min() const noexcept(NO_EXCEPT) { return *this->begin(); }
    inline auto max() const noexcept(NO_EXCEPT) { return *std::ranges::prev(this->end()); }

    inline auto& pop_min() noexcept(NO_EXCEPT) { this->erase(this->begin()); return *this; }
    inline auto& pop_max() noexcept(NO_EXCEPT) { this->erase(std::ranges::prev(this->end())); return *this; }


    inline auto kth_smallest_element(const size_type k) const noexcept(NO_EXCEPT) {
        return std::ranges::next(this->begin(), k);
    }

    inline auto kth_largest_element(const size_type k) const noexcept(NO_EXCEPT) {
        return std::ranges::prev(this->end(), k + 1);
    }


    inline auto kth_smallest(const size_type k) const noexcept(NO_EXCEPT) {
        return *std::ranges::next(this->begin(), k);
    }

    inline auto kth_largest(const size_type k) const noexcept(NO_EXCEPT) {
        return *std::ranges::prev(this->end(), k + 1);
    }


    inline auto& pop_kth_smallest(const size_type k) const noexcept(NO_EXCEPT) {
        return this->erase(std::ranges::next(this->begin(), k));
        return *this;
    }

    inline auto& pop_kth_largest(const size_type k) const noexcept(NO_EXCEPT) {
        return this->erase(std::ranges::prev(this->end(), k + 1));
        return *this;
    }


    auto next_element(const typename Set::key_type& key, const size_type _count = 0) const noexcept(NO_EXCEPT) {
        size_type count = std::abs(_count);
        auto itr = this->lower_bound(key);
        const auto begin = this->begin(), end = this->end();
        if(itr == end) return this->end();
        if(itr == begin) return this->begin();
        while(count--) {
            if(_count < 0) if(itr-- == begin) return this->begin();
            if(_count > 0) if(++itr == end) return this->end();
        }
        return itr;
    }

    auto prev_element(const typename Set::key_type& key, const size_type _count = 0) const noexcept(NO_EXCEPT) {
        size_type count = std::abs(_count);
        auto itr = this->upper_bound(key);
        const auto begin = this->begin(), end = this->end();
        if(itr == end) return this->end();
        if(itr-- == begin) return this->begin();
        while(count--) {
            if(_count < 0) if(itr-- == begin) return this->begin();
            if(_count > 0) if(++itr == end) return this->end();
        }
        return itr;
    }


    std::optional<typename Set::value_type> next(const typename Set::key_type& key, size_type count = 0) const noexcept(NO_EXCEPT) {
        if(this->empty()) return {};
        auto itr = this->lower_bound(key);
        const auto end = this->end();
        if(itr == end) return {};
        while(count--) if(++itr == end) return {};
        return { *itr };
    }

    std::optional<typename Set::value_type> prev(const typename Set::key_type& key, size_type count = 0) const noexcept(NO_EXCEPT) {
        if(this->empty()) return {};
        auto itr = this->upper_bound(key);
        const auto begin = this->begin();
        if(itr-- == begin) return {};
        while(count--) if(itr-- == begin) return {};
        return { *itr };
    }


    template<class Rhs>
    inline set_wrapper& operator|=(Rhs&& rhs) noexcept(NO_EXCEPT) {
        set_wrapper res;
        std::ranges::set_union(*this, std::forward<Rhs>(rhs), std::inserter(res, res.end()));
        this->swap(res);
        return *this;
    }

    template<class Rhs>
    inline set_wrapper& operator&=(Rhs&& rhs) noexcept(NO_EXCEPT) {
        set_wrapper res;
        std::ranges::set_intersection(*this, std::forward<Rhs>(rhs), std::inserter(res, res.end()));
        this->swap(res);
        return *this;
    }

    template<class Rhs>
    inline set_wrapper& operator^=(Rhs&& rhs) noexcept(NO_EXCEPT) {
        set_wrapper res;
        std::ranges::set_symmetric_difference(*this, std::forward<Rhs>(rhs), std::inserter(res, res.end()));
        this->swap(res);
        return *this;
    }

    template<class... Args>
    inline set_wrapper operator|(set_wrapper<Args...> rhs) noexcept(NO_EXCEPT) {
        return rhs |= *this;
    }

    template<class... Args>
    inline set_wrapper operator&(set_wrapper<Args...> rhs) noexcept(NO_EXCEPT) {
        return rhs &= *this;
    }

    template<class... Args>
    inline set_wrapper operator^(set_wrapper<Args...> rhs) noexcept(NO_EXCEPT) {
        return rhs ^= *this;
    }


    template<class... Args>
    inline auto operator<=>(const set_wrapper<Args...>& rhs) const noexcept(NO_EXCEPT) {
        const bool leq = this->size() <= rhs.size() && std::ranges::includes(rhs, *this);
        const bool geq = rhs.size() <= this->size() && std::ranges::includes(*this, rhs);

        if(leq) {
            if(geq) return std::partial_ordering::equivalent;
            return std::partial_ordering::less;
        }

        if(geq) return std::partial_ordering::greater;

        return std::partial_ordering::unordered;
    }
};


} //namespace internal


template<class... Args> using set = internal::set_wrapper<std::set<Args...>>;
template<class... Args> using unordered_set = internal::set_wrapper<std::unordered_set<Args...>>;
template<class... Args> using multiset = internal::set_wrapper<std::multiset<Args...>>;
template<class... Args> using unordered_multiset = internal::set_wrapper<std::unordered_multiset<Args...>>;


} // namespace uni
#line 2 "adaptor/map.hpp"


#include <map>
#include <unordered_map>
#line 7 "adaptor/map.hpp"


#line 11 "adaptor/map.hpp"

#line 2 "adaptor/gnu/hash_table.hpp"


#line 5 "adaptor/gnu/hash_table.hpp"
#include <stdexcept>

#include <ext/pb_ds/assoc_container.hpp>


#line 11 "adaptor/gnu/hash_table.hpp"



namespace uni {

namespace gnu {


template<class Base>
struct hash_table : Base {
    using key_type = typename Base::key_type;
    using value_type = typename Base::value_type;
    using mapped_type = typename Base::mapped_type;

    inline bool contains(const key_type& key) const noexcept(NO_EXCEPT) {
        return this->Base::find(key) != this->Base::end();
    }

    template<class K, class T>
    inline decltype(auto) emplace(K&& key, T&& val) noexcept(NO_EXCEPT) {
        return this->Base::insert({ std::forward<K>(key), std::forward<T>(val) });
    }

    mapped_type& at(const key_type& key) {
        auto itr = this->Base::find(key);
        if(itr == this->Base::end()) throw std::out_of_range("hash_table::at()");
        return itr->second;
    };

    const mapped_type& at(const key_type & key) const {
        auto itr = this->Base::find(key);
        if(itr == this->Base::end()) throw std::out_of_range("hash_table::at()");
        return itr->second;
    };
};


template<class Key, class T, class Hash = void>
struct cc_hash_table : hash_table<__gnu_pbds::cc_hash_table<Key, T, Hash>> {
    using hash_table<__gnu_pbds::cc_hash_table<Key, T, Hash>>::hash_table;
};

template<class Key, class T>
struct cc_hash_table<Key, T, void> : hash_table<__gnu_pbds::cc_hash_table<Key, T>> {
    using hash_table<__gnu_pbds::cc_hash_table<Key, T>>::hash_table;
};


template<class Key, class T, class Hash = void>
struct gp_hash_table : hash_table<__gnu_pbds::gp_hash_table<Key, T, Hash>> {
    using hash_table<__gnu_pbds::gp_hash_table<Key, T, Hash>>::hash_table;
};

template<class Key, class T>
struct gp_hash_table<Key, T, void> : hash_table<__gnu_pbds::gp_hash_table<Key, T>> {
    using hash_table<__gnu_pbds::gp_hash_table<Key, T>>::hash_table;
};


} // namespace gnu

} // namespace uni
#line 14 "adaptor/map.hpp"


namespace uni {

namespace internal {


template<class Map>
using map_wrapper_base = set_wrapper<Map>;


template<class Map> struct map_wrapper : map_wrapper_base<Map> {
  private:
    using base = map_wrapper_base<Map>;

  public:
    using base::base;
    using mapped_type = typename base::mapped_type;
    using key_type = typename base::key_type;

  protected:
    using default_func_noarg_type = std::function<mapped_type(void)>;
    using default_func_type = std::function<mapped_type(key_type)>;

    int _default_type = 0;
    mapped_type _default_val = mapped_type();
    default_func_noarg_type _default_func_noarg;
    default_func_type _default_func;

    inline mapped_type _get_default(const key_type& key) const noexcept(NO_EXCEPT) {
        if(this->_default_type == 0) return this->_default_val;
        if(this->_default_type == 1) return this->_default_func_noarg();
        if(this->_default_type == 2) return this->_default_func(key);
        else assert(false);
    }

  public:
    inline auto& set_default(const mapped_type& val) noexcept(NO_EXCEPT) {
        this->_default_val = val;
        this->_default_type = 0;
        return *this;
    }

    inline auto& set_default(const default_func_noarg_type func) noexcept(NO_EXCEPT) {
        this->_default_func_noarg = func;
        this->_default_type = 1;
        return *this;
    }

    inline auto& set_default(const default_func_type func) noexcept(NO_EXCEPT) {
        this->_default_func = func;
        this->_default_type = 2;
        return *this;
    }


    inline auto& operator[](const key_type& key) noexcept(NO_EXCEPT) {
        auto found = this->base::find(key);
        if(found == this->base::end()) return this->base::emplace(key, this->_get_default(key)).first->second;
        return found->second;
    }

    inline auto& operator()(const key_type& key) noexcept(NO_EXCEPT) {
        return this->base::operator[](key);
    }


    inline std::optional<mapped_type> get(const key_type& key) const noexcept(NO_EXCEPT) {
        const auto found = this->base::find(key);
        if(found == this->base::end()) return {};
        return found->second;
    }
};


} // namespace internal


template<class... Args> using map = internal::map_wrapper<std::map<Args...>>;
template<class... Args> using unordered_map = internal::map_wrapper<std::unordered_map<Args...>>;
template<class... Args> using multimap = internal::map_wrapper<std::multimap<Args...>>;
template<class... Args> using unordered_multimap = internal::map_wrapper<std::unordered_multimap<Args...>>;

template<class... Args> using cc_hash_table = internal::map_wrapper<gnu::cc_hash_table<Args...>>;
template<class... Args> using gp_hash_table = internal::map_wrapper<gnu::gp_hash_table<Args...>>;


} // namespace uni
#line 11 "numeric/fast_prime.hpp"

#line 2 "numeric/internal/primality_test.hpp"

#line 7 "numeric/internal/primality_test.hpp"

#line 10 "numeric/internal/primality_test.hpp"

#line 2 "numeric/modular/modint_interface.hpp"


#line 6 "numeric/modular/modint_interface.hpp"


#line 9 "numeric/modular/modint_interface.hpp"

#line 11 "numeric/modular/modint_interface.hpp"

#line 2 "numeric/modular/builtin_reduction.hpp"


#line 5 "numeric/modular/builtin_reduction.hpp"


#line 8 "numeric/modular/builtin_reduction.hpp"

#line 10 "numeric/modular/builtin_reduction.hpp"

#line 12 "numeric/modular/builtin_reduction.hpp"


namespace uni {

namespace internal {


template<std::unsigned_integral Value, std::unsigned_integral Large>
    requires has_double_digits_of<Large, Value>
struct builtin_reduction {
    using value_type = Value;
    using large_type = Large;

  private:
    value_type _mod;

  public:
    static constexpr int digits = std::numeric_limits<value_type>::digits;
    static constexpr value_type max() noexcept { return std::numeric_limits<value_type>::max(); }

    inline constexpr value_type mod() const noexcept(NO_EXCEPT) { return this->_mod; }

    constexpr builtin_reduction() noexcept = default;

    constexpr builtin_reduction(const value_type mod) noexcept(NO_EXCEPT) : _mod(mod) {
        assert(0 < mod && mod < builtin_reduction::max());
    }


    inline constexpr value_type reduce(const large_type v) const noexcept(NO_EXCEPT) { return v % this->_mod; }


    inline constexpr value_type add(value_type x, const value_type y) const noexcept(NO_EXCEPT) {
        if(x >= this->_mod - y) x -= this->_mod;
        x += y;
        return x;
    }

    inline constexpr value_type subtract(value_type x, const value_type y) const noexcept(NO_EXCEPT) {
        if(x < y) x += this->_mod;
        x -= y;
        return x;
    }


    inline constexpr value_type multiply(const value_type x, const value_type y) const noexcept(NO_EXCEPT) {
        return this->reduce(static_cast<large_type>(x) * static_cast<large_type>(y));
    }

    template<std::integral K>
    inline constexpr value_type pow(const value_type v, const K p) const noexcept(NO_EXCEPT) {
        if constexpr(std::signed_integral<K>) assert(p >= 0);

        if(this->_mod == 0) return 0;
        return uni::pow(v, p, [this](const value_type x, const value_type y) { return this->multiply(x, y); });
    }


    inline constexpr auto compare(const value_type x, const value_type y) const noexcept(NO_EXCEPT) {
        return x <=> y;
    }


    constexpr value_type convert_raw(const value_type v) const noexcept(NO_EXCEPT) { return v; }

    template<std::integral T>
    constexpr value_type convert(T v) const noexcept(NO_EXCEPT) {
        using common_type = std::common_type_t<T, value_type>;
        const common_type mod = static_cast<common_type>(this->_mod);

        if(std::is_constant_evaluated()) {
            v %= mod;

            if constexpr(std::signed_integral<T>) {
                if(v < 0) v += mod;
            }
        }
        else {
            if(v > 0 && static_cast<common_type>(v) >= mod) {
                v %= mod;
            }

            if constexpr(std::signed_integral<T>) {
                if(v < 0) {
                    if(static_cast<common_type>(-v) <= mod) v += mod;
                    else {
                        v %= mod;
                        if(v != 0) v += mod;
                    }
                }
            }
        }

        return static_cast<value_type>(v);
    }

    constexpr value_type revert(const value_type v) const noexcept(NO_EXCEPT) { return this->_mod == 1 ? 0 : v; }
};


} // namespace internal


using builtin_reduction_32bit = internal::builtin_reduction<u32, u64>;
using builtin_reduction_64bit = internal::builtin_reduction<u64, u128>;


} // namespace uni
#line 2 "numeric/modular/binary_reduction.hpp"


#line 7 "numeric/modular/binary_reduction.hpp"


#line 10 "numeric/modular/binary_reduction.hpp"

#line 13 "numeric/modular/binary_reduction.hpp"

#line 2 "numeric/bit.hpp"


#include <immintrin.h>

#line 13 "numeric/bit.hpp"


#line 16 "numeric/bit.hpp"

#line 18 "numeric/bit.hpp"


namespace uni {


template<std::unsigned_integral T>
constexpr T multiply_high(const T x, const T y) noexcept(NO_EXCEPT) {
    constexpr int digits = std::numeric_limits<T>::digits;

    if constexpr(digits <= 16) {
        return static_cast<T>((static_cast<u32>(x) * static_cast<u32>(y)) >> digits);
    }
    else if constexpr(digits <= 32) {
        return static_cast<T>((static_cast<u64>(x) * static_cast<u64>(y)) >> digits);
    }
    else if constexpr(digits <= 64) {
        return static_cast<T>((static_cast<u128>(x) * static_cast<u128>(y)) >> digits);
    }
    else {
        constexpr int h_digits = digits / 2;
        constexpr T mask = (T{ 1 } << h_digits) - 1;

        const T xh = x >> h_digits, yh = y >> h_digits;
        const T xl = x & mask, yl = y & mask;
        const T ph = xh * yh, pl = xl * yl;

        return (((pl >> h_digits) + (xh + xl) * (yh + yl) - (ph + pl)) >> h_digits) + ph;
    }
}


template<std::unsigned_integral T>
inline constexpr int highest_bit_pos(const T v) noexcept(NO_EXCEPT) {
    return (int)std::bit_width(v) - 1; // cast to int for GCC12
}

template<std::unsigned_integral T>
inline constexpr int lowest_bit_pos(const T v) noexcept(NO_EXCEPT) {
    if(v == 0) return -1;
    return std::countr_zero(v);
}


template<std::unsigned_integral T, std::integral I = int>
__attribute__((target("bmi2")))
inline constexpr T clear_higher_bits(const T v, const I p) {
    if constexpr(std::signed_integral<I>) assert(0 <= p);

    constexpr int DIGITS = std::numeric_limits<T>::digits;
    assert(p <= DIGITS);

    if constexpr(DIGITS <= 32) return _bzhi_u32(v, static_cast<u32>(p));
    if constexpr(DIGITS <= 64) return _bzhi_u64(v, static_cast<u64>(p));
    else {
        static_assert(DIGITS <= 128);

        constexpr std::uint64_t MAX64 = std::numeric_limits<std::uint64_t>::max();

        const std::uint64_t high = v >> 64;
        const std::uint64_t low = v & MAX64;

        if(p < 64) return _bzhi_u64(low, p);
        return low | (T{_bzhi_u64(high, p - 64)} << 64);
    }
}


template<std::unsigned_integral T, std::integral I = int> constexpr T shiftl(const T, const I = 1);
template<std::unsigned_integral T, std::integral I = int> constexpr T shiftr(const T, const I = 1);

template<std::unsigned_integral T, std::integral I>
constexpr T shiftl(const T x, const I n) {
    constexpr int DIGITS = std::numeric_limits<T>::digits;
    if constexpr(std::signed_integral<I>) {
        if(n < 0) return shiftr(x, -n);
    }
    if(n >= DIGITS) return 0;
    return x << n;
}

template<std::unsigned_integral T, std::integral I>
constexpr T shiftr(const T x, const I n) {
    constexpr int DIGITS = std::numeric_limits<T>::digits;
    if constexpr(std::signed_integral<I>) {
        if(n < 0) return shiftl(x, -n);
    }
    if(n >= DIGITS) return 0;
    return x >> n;
}


template<std::unsigned_integral T, std::integral I = int>
inline constexpr bool bit(const T x, const I p) {
    if constexpr(std::signed_integral<I>) assert(0 <= p);
    assert(p < std::numeric_limits<T>::digits);

    return shiftr(x, p) & T{1};
}


template<std::unsigned_integral T, std::integral I = int>
inline constexpr auto reset_bit(const T x, const I p) {
    if constexpr(std::signed_integral<I>) assert(0 <= p);
    assert(p < std::numeric_limits<T>::digits);

    return x & ~(T{1} << p);
}


template<std::unsigned_integral T, std::integral I = int>
inline constexpr auto set_bit(const T x, const I p, const bool bit = true) {
    if constexpr(std::signed_integral<I>) assert(0 <= p);
    assert(p < std::numeric_limits<T>::digits);

    if(!bit) return reset_bit(x, p);
    return x | (T{1} << p);
}


template<std::unsigned_integral T, std::integral I = int>
inline constexpr T lower_bits(const T x, const I digits) {
    if constexpr(std::signed_integral<I>) assert(0 <= digits);
    assert(digits <= std::numeric_limits<T>::digits);

    return x & (uni::shiftl(x, digits) - 1);
}


// Thanks to: https://noshi91.github.io/Library/other/select64.cpp
constexpr int select64(const u64 x0, u32 k) {
    const u64 x1 = (x0 & UINT64_C(0x5555555555555555)) + (x0 >> 1 & UINT64_C(0x5555555555555555));
    const u64 x2 = (x1 & UINT64_C(0x3333333333333333)) + (x1 >> 2 & UINT64_C(0x3333333333333333));
    const u64 x3 = (x2 & UINT64_C(0x0F0F0F0F0F0F0F0F)) + (x2 >> 4 & UINT64_C(0x0F0F0F0F0F0F0F0F));
    const u64 x4 = (x3 & UINT64_C(0x00FF00FF00FF00FF)) + (x3 >> 8 & UINT64_C(0x00FF00FF00FF00FF));
    const u64 x5 = (x4 & UINT64_C(0x0000FFFF0000FFFF)) + (x4 >> 16 & UINT64_C(0x0000FFFF0000FFFF));

    int res = 0;

    u32 t;

    t = x5 & 0xFFFFFFFF;
    if(t <= k) k -= t, res += 32;

    t = x4 >> res & 0xFFFF;
    if(t <= k) k -= t, res += 16;

    t = x3 >> res & 0xFF;
    if(t <= k) k -= t, res += 8;

    t = x2 >> res & 0xF;
    if(t <= k) k -= t, res += 4;

    t = x1 >> res & 0x3;
    if(t <= k) k -= t, res += 2;

    t = x0 >> res & 0x1;
    if(t <= k) k -= t, res += 1;

    return res;
}


namespace internal {


template<std::unsigned_integral T>
constexpr T binary_gcd(T a, T b) noexcept(NO_EXCEPT) {
    if(!a || !b) return a | b;
    T t, s = std::countr_zero(a | b);
    a >>= std::countr_zero(a);
    do {
        b >>= std::countr_zero(b);
        if(a > b) t = a, a = b, b = t;
        b -= a;
    } while(b);
    return a << s;
}


template<std::signed_integral T>
inline constexpr T binary_gcd(const T a, const T b) noexcept(NO_EXCEPT) {
    return binary_gcd(a < 0 ? -a : a, b < 0 ? -b : b);
}


} // namespace internal


template<std::integral T0, std::integral T1>
inline constexpr auto binary_gcd(T0 v0, T1 v1) noexcept(NO_EXCEPT) {
    using common_type = std::common_type_t<T0, T1>;
    return internal::binary_gcd(static_cast<common_type>(v0), static_cast<common_type>(v1));
}


template<std::unsigned_integral T, std::unsigned_integral S>
inline constexpr bool is_subset_of(T target, S superset) noexcept(NO_EXCEPT) {
    return (target & ~superset) == 0;
}

template<std::unsigned_integral T, std::unsigned_integral S>
inline constexpr bool is_superset_of(T target, S subset) noexcept(NO_EXCEPT) {
    return (~target & subset) == 0;
}


template<std::unsigned_integral S0, std::unsigned_integral S1>
inline constexpr auto comapre_as_bitset(S0 s0, S1 s1) noexcept(NO_EXCEPT) {
    if(s0 == s1) return std::partial_ordering::equivalent;
    if(is_subset_of(s0, s1)) return std::partial_ordering::less;
    if(is_superset_of(s0, s1)) return std::partial_ordering::greater;
    return std::partial_ordering::unordered;
}


} // namespace uni
#line 16 "numeric/modular/binary_reduction.hpp"


namespace uni {

namespace internal {


template<std::unsigned_integral Value>
struct binary_reduction {
    using value_type = Value;

  private:
    value_type _mask;

  public:
    static constexpr int digits = std::numeric_limits<value_type>::digits;
    static constexpr value_type max() noexcept { return std::numeric_limits<value_type>::max(); }

    inline constexpr value_type mod() const noexcept(NO_EXCEPT) { return this->_mask + 1; }

    constexpr binary_reduction() noexcept = default;

    constexpr explicit inline binary_reduction(const value_type mod) noexcept(NO_EXCEPT) : _mask(mod - 1) {
        assert(std::has_single_bit(mod));
    }

    inline constexpr value_type reduce(const value_type v) const noexcept(NO_EXCEPT) { return v; }


    inline constexpr value_type add(const value_type x, const value_type y) const noexcept(NO_EXCEPT) {
        return x + y;
    }

    inline constexpr value_type subtract(const value_type x, const value_type y) const noexcept(NO_EXCEPT) {
        return x - y;
    }


    inline constexpr value_type multiply(const value_type x, const value_type y) const noexcept(NO_EXCEPT) {
        return x * y;
    }

    template<std::integral K>
    inline constexpr value_type pow(const value_type v, const K p) const noexcept(NO_EXCEPT) {
        if constexpr(std::signed_integral<K>) assert(p >= 0);

        if(this->_mask == 0) return 0;
        return uni::pow(v, p);
    }


    inline constexpr auto compare(const value_type x, const value_type y) const noexcept(NO_EXCEPT) {
        return this->revert(x) <=> this->revert(y);
    }


    constexpr value_type convert_raw(const value_type v) const noexcept(NO_EXCEPT) {
        return v;
    }

    template<std::integral T>
    constexpr value_type convert(T v) const noexcept(NO_EXCEPT) {
        return static_cast<value_type>(v);
    }


    constexpr value_type revert(const value_type v) const noexcept(NO_EXCEPT) {
        return v & this->_mask;
    }
};


} // namespace internal


using binary_reduction_32bit = internal::binary_reduction<u32>;
using binary_reduction_64bit = internal::binary_reduction<u64>;
using binary_reduction_128bit = internal::binary_reduction<u128>;


} // namespace uni
#line 2 "numeric/modular/barrett_reduction.hpp"


#line 8 "numeric/modular/barrett_reduction.hpp"


#line 11 "numeric/modular/barrett_reduction.hpp"

#line 14 "numeric/modular/barrett_reduction.hpp"

#line 2 "template/debug.hpp"


#ifdef LOCAL_JUDGE

#define DEBUGGER_ENABLED
#define DEBUGGER_COLORED_OUTPUT 1

#endif

#line 2 "debugger/debug.hpp"


#line 9 "debugger/debug.hpp"
#include <array>
#line 13 "debugger/debug.hpp"
#include <bitset>
#include <deque>
#include <queue>
#include <stack>
#line 22 "debugger/debug.hpp"
#include <iomanip>
#line 26 "debugger/debug.hpp"


#line 2 "numeric/int128.hpp"


#include <cctype>
#line 9 "numeric/int128.hpp"

#line 12 "numeric/int128.hpp"

#line 14 "numeric/int128.hpp"


namespace std {


template<class C, class S>
auto& operator>>(std::basic_istream<C, S>& in, uni::i128& v) noexcept(NO_EXCEPT) {
    std::string str; in >> str;
    v = 0;
    bool negative = (str[0] == '-');
    REP(d, std::ranges::next(str.begin(), negative), str.end()) {
        assert(std::isdigit(*d));
        v = v * 10 + *d - '0';
    }
    if(negative) v *= -1;
    return in;
}


template<class C, class S>
auto& operator>>(std::basic_istream<C, S>& in, uni::u128& v) noexcept(NO_EXCEPT) {
    std::string str; in >> str;
    v = 0U;
    assert(str[0] != '-');
    REP(d, str.begin(), str.end()) {
        assert(std::isdigit(*d));
        v = v * 10U + *d - '0';
    }
    return in;
}

template<class C, class S>
auto& operator<<(std::basic_ostream<C, S>& out, uni::i128 v) noexcept(NO_EXCEPT) {
    if(v == 0) return out << 0;
    if(v < 0) out << '-', v *= -1;
    std::string str;
    while(v > 0) str += static_cast<char>(v%10) + '0', v /= 10;
    std::reverse(str.begin(), str.end());
    return out << str;
}

template<class C, class S>
auto& operator<<(std::basic_ostream<C, S>& out, uni::u128 v) noexcept(NO_EXCEPT) {
    if(v == 0) return out << 0U;
    std::string str;
    while(v > 0) str += static_cast<char>(v%10U) + '0', v /= 10U;
    std::reverse(str.begin(), str.end());
    return out << str;
}


}
#line 29 "debugger/debug.hpp"

#line 2 "internal/resolving_rank.hpp"


namespace uni {

namespace internal {


template<int P> struct resolving_rank : resolving_rank<P-1> {};
template<> struct resolving_rank<0> {};


} // namespace internal

} // namespace uni
#line 34 "debugger/debug.hpp"

#include <typeinfo>
#include <cxxabi.h>


namespace debugger {


template<class T>
auto _debug (T&& val) -> decltype(val._debug()) {
    return val._debug();
}


std::ostream *cdebug = &std::clog;


#ifdef DEBUGGER_COLORED_OUTPUT

constexpr std::string COLOR_LINE = "\033[3;35m";
constexpr std::string COLOR_IDENTIFIER = "\033[32m";
constexpr std::string COLOR_INIT = "\033[m";
constexpr std::string COLOR_STRING = "\033[33m";
constexpr std::string COLOR_TYPE = "\033[34m";
constexpr std::string COLOR_NUMERIC = "\033[36m";
constexpr std::string COLOR_LITERAL_OPERATOR = "\033[31m";

#else

constexpr std::string COLOR_LINE = "";
constexpr std::string COLOR_IDENTIFIER = "";
constexpr std::string COLOR_INIT = "";
constexpr std::string COLOR_STRING = "";
constexpr std::string COLOR_TYPE = "";
constexpr std::string COLOR_NUMERIC = "";
constexpr std::string COLOR_LITERAL_OPERATOR = "";

#endif

using Brackets = std::pair<std::string, std::string>;


template<class T>
std::string dump(T&&);


template<class T>
const std::string get_type_name(T&& val) {
    const char* const name = typeid(std::forward<T>(val)).name();
    int status = -4;
    char* const demangled_name = abi::__cxa_demangle(name, NULL, NULL, &status);
    std::string res{name};
    if (status == 0) {
        res = std::string(demangled_name);
        free(demangled_name);
    }

    return COLOR_TYPE + res + COLOR_INIT;
}

struct debug_t : std::string {
    using std::string::string;
    debug_t(const std::string& str) {
        this->assign(str);
    }
};


template<size_t N, class T>
void dump_tuple_impl([[maybe_unused]] T&& val, std::stringstream &res) {
    if constexpr(N < std::tuple_size_v<std::remove_cvref_t<T>>) {
        res << dump(std::get<N>(val));
        if constexpr(N < std::tuple_size_v<std::remove_cvref_t<T>> - 1) res << ", ";
        dump_tuple_impl<N + 1>(std::forward<T>(val), res);
    }
}


template<std::ranges::input_range R>
std::string dump_range_impl(R&& range, const Brackets& brcs = { "[", "]" }, const std::string& spl = ", ") {
    std::stringstream res;

    res << brcs.first << " ";

    auto itr = std::ranges::begin(range);
    auto end = std::ranges::end(std::forward<R>(range));

    while(itr != end) {
        if(std::ranges::next(itr) == end) res << dump(*itr) << " ";
        else res << dump(*itr) << spl;
        ++itr;
    }

    res << brcs.second ;

    return res.str();
}


std::string dump_debug_t(debug_t info) {
    return info;
}


struct dump_primitive_like {
    std::string operator()(std::nullptr_t) const {
        return COLOR_INIT;
    }

    template<uni::internal::pointer T>
    std::string operator()(const T ptr) const {
        return dump(*ptr);
    }

    template<class T>
        requires uni::internal::derived_from_template<std::remove_cvref_t<T>, std::basic_string>
    std::string operator()(T&& val) const {
        std::stringstream res;
        res << COLOR_STRING << "`" << val << "`" << COLOR_INIT;
        return res.str();
    }

    std::string operator()(const char val) const {
        std::stringstream res;
        res << COLOR_STRING << "\'" << val << "\'" << COLOR_INIT;
        return res.str();
    }

    std::string operator()(const char val[]) const {
        std::stringstream res;
        res << COLOR_STRING << "\"" << val << "\"" <<  COLOR_INIT;
        return res.str();
    }

    std::string operator()(const unsigned char val) const {
        std::stringstream res;
        res << COLOR_NUMERIC << static_cast<int>(val) << COLOR_INIT;
        return res.str();
    }


    std::string operator()(const bool val) const {
        std::stringstream res;
        res << COLOR_NUMERIC << (val ? "true" : "false" ) << COLOR_INIT;
        return res.str();
    }


    template<uni::internal::arithmetic T>
    std::string operator()(const T val) const {
        std::stringstream res;
        res << std::setprecision(std::numeric_limits<T>::digits10) << val;

        auto str = res.str();

        std::string dst = "";
        while(str.length() > 3) {
            dst = ',' + str.substr(str.length() - 3, 3) + dst;
            str = str.substr(0, str.length() - 3);
        }

        return COLOR_NUMERIC + str + dst + COLOR_LITERAL_OPERATOR + uni::internal::literal_operator_v<T> + COLOR_INIT;
    };

    template<class T>
        requires uni::internal::derived_from_template<std::remove_cvref_t<T>, std::optional>
    std::string operator()(T&& val) const {
        if(val.has_value()) return dump(*val);
        return COLOR_TYPE + "invalid" + COLOR_INIT;
    }
};


struct dump_bitset {
    template<std::size_t N>
    std::string operator()(const std::bitset<N>& val) const {
        std::stringstream res;
        res << COLOR_NUMERIC << val.to_string() << COLOR_INIT;
        return res.str();
    }
};


struct dump_has_val {
    template<class T>
        requires requires (T val) { val.val(); }
    std::string operator()(T&& val) const {
        return dump(val.val());
    }
};


struct dump_iterator {
    template<std::input_or_output_iterator I>
    std::string operator()(I&& itr) const {
        return COLOR_TYPE + "<iterator> " + COLOR_INIT+ dump(*itr);
    }
};


struct dump_wrapper {
    template<class T>
        requires uni::internal::derived_from_template<std::remove_cvref_t<T>, std::map>
    std::string operator()(T&& val) const {
        return dump_range_impl(val, Brackets("{", "}"));
    }

    template<class T>
        requires uni::internal::derived_from_template<std::remove_cvref_t<T>, std::multimap>
    std::string operator()(T&& val) const {
        return dump_range_impl(val, Brackets("{", "}"));
    }

    template<class T>
        requires uni::internal::derived_from_template<std::remove_cvref_t<T>, std::unordered_map>
    std::string operator()(T&& val) const {
        return dump_range_impl(val, Brackets("{", "}"));
    }

    template<class T>
        requires uni::internal::derived_from_template<std::remove_cvref_t<T>, std::unordered_multimap>
    std::string operator()(T&& val) const {
        return dump_range_impl(val, Brackets("{", "}"));
    }

    template<class T>
        requires uni::internal::derived_from_template<std::remove_cvref_t<T>, std::set>
    std::string operator()(T&& val) const {
        return dump_range_impl(val, Brackets("{", "}"));
    }

    template<class T>
        requires uni::internal::derived_from_template<std::remove_cvref_t<T>, std::multiset>
    std::string operator()(T&& val) const {
        return dump_range_impl(val, Brackets("{", "}"));
    }

    template<class T>
        requires uni::internal::derived_from_template<std::remove_cvref_t<T>, std::unordered_set>
    std::string operator()(T&& val) const {
        return dump_range_impl(val, Brackets("{", "}"));
    }

    template<class T>
        requires uni::internal::derived_from_template<std::remove_cvref_t<T>, std::unordered_multiset>
    std::string operator()(T&& val) const {
        return dump_range_impl(val, Brackets("{", "}"));
    }

    template<class T>
        requires uni::internal::derived_from_template<std::remove_cvref_t<T>, std::valarray>
    std::string operator()(T&& val) const {
        return dump_range_impl(val, Brackets("[", "]"));
    }

    template<class T>
        requires uni::internal::derived_from_template<std::remove_cvref_t<T>, std::vector>
    std::string operator()(T&& val) const {
        return dump_range_impl(val, Brackets("[", "]"));
    }

    template<class T>
        requires uni::internal::derived_from_template<std::remove_cvref_t<T>, std::deque>
    std::string operator()(T&& val) const {
        return dump_range_impl(val, Brackets("[", "]"));
    }


    template<uni::internal::derived_from_template<std::queue> T>
    std::string operator()(T val) const {
        std::vector<typename T::value_type> vec;

        while(!val.empty()) vec.emplace_back(val.front()), val.pop();

        return dump_range_impl(vec, Brackets("<", ">"));
    }

    template<uni::internal::derived_from_template<std::stack> T>
    std::string operator()(T val) const {
        std::vector<typename T::value_type> vec;

        while(!val.empty()) vec.emplace_back(val.top()), val.pop();
        std::ranges::reverse(vec);

        return dump_range_impl(vec, Brackets("<", ">"));
    }

    template<uni::internal::derived_from_template<std::priority_queue> T>
    std::string operator()(T val) const {
        std::vector<typename T::value_type> vec;

        while(!val.empty()) vec.emplace_back(val.top()), val.pop();

        return dump_range_impl(vec, Brackets("<", ">"));
    }


    template<class T>
        requires uni::internal::derived_from_template<std::remove_cvref_t<T>, std::pair>
    std::string operator()(T&& val) const {
        std::stringstream res;
        res << "( " << dump(val.first) << ", " << dump(val.second) << " )";
        return res.str();
    }

    template<class T>
        requires uni::internal::derived_from_template<std::remove_cvref_t<T>, std::tuple>
    std::string operator()(T&& val) const {
        std::stringstream res;
        res << "( ";
        dump_tuple_impl<0>(val, res);
        res << " )";
        return res.str();
    }
};


struct dump_range {
    template<std::ranges::input_range T>
    std::string operator()(T&& val) const {
        return dump_range_impl(val);
    }
};


struct dump_loggable {
    template<uni::internal::loggable T>
    std::string operator()(T&& val) const {
        auto res = _debug(val);

        if constexpr(std::same_as<decltype(res), debug_t>) {
            return res;
        }
        else {
            return dump(res);
        }
    }
};


template<class T>
std::string dump(T&& val) {
    if constexpr(std::same_as<std::remove_cvref_t<T>, debug_t>) {
        // return "debug_t";
        return dump_debug_t(std::forward<T>(val));
    }

    if constexpr(std::invocable<dump_primitive_like, T>) {
        // return "primitive";
        return dump_primitive_like{}(std::forward<T>(val));
    }
    if constexpr(std::invocable<dump_loggable, T>) {
        // return "loggable";
        return dump_loggable{}(std::forward<T>(val));
    }
    if constexpr(std::invocable<dump_has_val, T>) {
        // return "has val";
        return dump_has_val{}(std::forward<T>(val));
    }

    if constexpr(std::invocable<dump_bitset, T>) {
        // return "bitset";
        return dump_bitset{}(std::forward<T>(val));
    }
    if constexpr(std::invocable<dump_iterator, T>) {
        // return "iterator";
        return dump_iterator{}(std::forward<T>(val));
    }

    if constexpr(std::invocable<dump_wrapper, T>) {
        // return "wrapper";
        return dump_wrapper{}(std::forward<T>(val));
    }

    if constexpr(std::invocable<dump_range, T>) {;
        // return "range";
        return dump_range{}(std::forward<T>(val));
    }

    return "== dump error ==";
}


template<class T> void debug(T&& val, const std::string& endl) {
    *cdebug << dump(val) << endl << std::flush;
}


constexpr std::string_view WHITESPACES = " \n\r\t\f\v";

std::string ltrim(const std::string &s)
{
    size_t start = s.find_first_not_of(WHITESPACES);
    return (start == std::string::npos) ? "" : s.substr(start);
}

std::string rtrim(const std::string &s)
{
    size_t end = s.find_last_not_of(WHITESPACES);
    return (end == std::string::npos) ? "" : s.substr(0, end + 1);
}

std::string trim(const std::string &s) {
    return rtrim(ltrim(s));
}

std::vector<std::string> split(const std::string& str) {
    static constexpr char SEPARATOR = ',';
    static constexpr char ESCAPE = '\\';
    static constexpr std::string_view QUOTATIONS = "\"\'";
    static constexpr std::string_view PARENTHESES = "()[]{}<>";
    static constexpr auto PARENTHESES_KINDS = std::ranges::size(PARENTHESES);
    static_assert(PARENTHESES_KINDS % 2 == 0);

    std::vector<std::string> res = { "" };

    bool quoted = false;
    std::array<int,(PARENTHESES_KINDS / 2)> enclosed = { 0 };

    for(auto itr = std::ranges::begin(str); itr != std::ranges::end(str); ++itr) {
        if(std::ranges::find(QUOTATIONS, *itr) != std::ranges::end(QUOTATIONS)) {
            if(itr == std::ranges::begin(str) or *std::ranges::prev(itr) != ESCAPE) {
                quoted ^= true;
            }
        }

        if(const auto found = std::ranges::find(PARENTHESES, *itr); found != std::ranges::end(PARENTHESES)) {
            if(not quoted) {
                auto& target = enclosed[std::ranges::distance(std::begin(PARENTHESES), found) / 2];
                target = std::max(0, target - static_cast<int>((std::ranges::distance(std::begin(PARENTHESES), found) % 2) * 2) + 1);

            }
        }

        if(
            not quoted
            and static_cast<std::size_t>(std::ranges::count(enclosed, 0)) == std::ranges::size(enclosed)
            and *itr == SEPARATOR
        ) {
            res.push_back("");
        }
        else {
            res.back() += *itr;
        }
    }

    for(auto&& v : res) v = trim(v);

    return res;
}

template<class Arg> void raw(std::nullptr_t, Arg&& arg) { *cdebug << std::forward<Arg>(arg) << std::flush; }
template<class Arg> void raw(Arg&& arg) { *cdebug << dump(std::forward<Arg>(arg)) << std::flush; }

void debug(const std::vector<std::string>, const size_t, const int, const std::string) { debug(nullptr, COLOR_INIT + "\n"); }


std::map<std::pair<std::string, int>, int> count;

template<class Head, class... Tail>
void debug(
    const std::vector<std::string> args, const size_t idx,
    const int line, const std::string path,
    Head&& H, Tail&&... T
) {
    if(idx == 0) {
        std::string file = path.substr(path.find_last_of("/") + 1);
        debug(nullptr, COLOR_LINE + file + " #" + std::to_string(line) + " (" + std::to_string(count[{ file, line }]++) + ")" + COLOR_INIT);
    }
    debug(nullptr, "\n - ");


    const std::string content = dump(H);
    const std::string type_name = get_type_name(std::forward<Head>(H));


    debug(nullptr, COLOR_IDENTIFIER + args[idx]  + COLOR_INIT + " : ");
    debug(nullptr, content);

    if(type_name.size() + content.size() >= 300) debug(nullptr, "\n   ");

    debug(nullptr, " " + type_name);

    debug(args, idx + 1, 0, path, std::forward<Tail>(T)...);
}


} // namespace debugger
#line 13 "template/debug.hpp"


#ifdef DEBUGGER_ENABLED


#define debug(...) debugger::debug(debugger::split(#__VA_ARGS__), 0, __LINE__, __FILE__, __VA_ARGS__)
#define debug_(...) do { const std::string file = __FILE__; debugger::raw(nullptr, debugger::COLOR_LINE + file.substr(file.find_last_of("/") + 1) + " #" + std::to_string(__LINE__) + debugger::COLOR_INIT + "  "); debugger::raw(__VA_ARGS__); debugger::raw(nullptr, debugger::COLOR_INIT + "\n"); } while(0);
#define DEBUG if constexpr(true)


#else


#define debug(...) ({ ; })
#define debug_(...) ({ ; })
#define DEBUG if constexpr(false)


#endif
#line 18 "numeric/modular/barrett_reduction.hpp"

namespace uni {

namespace internal {


template<std::unsigned_integral Value, std::unsigned_integral Large>
    requires has_double_digits_of<Large, Value>
struct barrett_reduction {
    using value_type = Value;
    using large_type = Large;

  private:
    large_type _mod = 0, _mi;

    inline constexpr std::pair<large_type,value_type> _reduce(const large_type v) const noexcept(NO_EXCEPT) {
        large_type x = multiply_high(v, this->_mi);
        return { x, static_cast<value_type>(v - x * this->_mod) };
    }

  public:
    static constexpr int digits = std::numeric_limits<value_type>::digits - 1;
    static constexpr value_type max() noexcept { return (value_type{ 1 } << barrett_reduction::digits) - 1; }

    inline constexpr value_type mod() const noexcept(NO_EXCEPT) { return this->_mod; }

    constexpr barrett_reduction() noexcept = default;

    constexpr explicit inline barrett_reduction(const value_type mod)
      : _mod(mod), _mi(std::numeric_limits<large_type>::max() / mod + 1)
    {
        assert(0 < mod && mod <= barrett_reduction::max());
    }


    inline constexpr large_type quotient(const large_type v) const noexcept(NO_EXCEPT) {
        const auto [ x, r ] = this->_reduce(v);
        return static_cast<large_type>(this->_mod <= r ? x - 1 : x);
    }

    inline constexpr value_type reduce(const large_type v) const noexcept(NO_EXCEPT) {
        const auto [ x, r ] = this->_reduce(v);
        return static_cast<value_type>(this->_mod <= r ? r + this->_mod : r);
    }

    inline constexpr std::pair<large_type,value_type> divide(const large_type v) const noexcept(NO_EXCEPT) {
        const auto [ x, r ] = this->_reduce(v);
        if(this->_mod <= r) return { static_cast<large_type>(x - 1), static_cast<value_type>(r + this->_mod) };
        return { static_cast<large_type>(x), static_cast<value_type>(r) };
    }


    inline constexpr value_type add(value_type x, const value_type y) const noexcept(NO_EXCEPT) {
        x += y;
        if(x >= this->_mod) x -= this->_mod;
        return x;
    }

    inline constexpr value_type subtract(value_type x, const value_type y) const noexcept(NO_EXCEPT) {
        if(x < y) x += this->_mod;
        x -= y;
        return x;
    }


    inline constexpr value_type multiply(const value_type x, const value_type y) const noexcept(NO_EXCEPT) {
        return this->reduce(static_cast<large_type>(x) * static_cast<large_type>(y));
    }

    template<std::integral K>
    inline constexpr value_type pow(const large_type v, const K p) const noexcept(NO_EXCEPT) {
        if constexpr(std::signed_integral<K>) assert(p >= 0);

        if(this->_mod == 1) return 0;
        return uni::pow(
            this->reduce(v), p,
            [&](const value_type x, const value_type y) noexcept(NO_EXCEPT) { return this->multiply(x, y); }
        );
    }


    inline constexpr auto compare(const value_type x, const value_type y) const noexcept(NO_EXCEPT) {
        return x <=> y;
    }


    constexpr value_type convert_raw(const value_type v) const noexcept(NO_EXCEPT) { return v; }

    template<std::integral T>
    constexpr value_type convert(T v) const noexcept(NO_EXCEPT) {
        using common_type = std::common_type_t<T, value_type>;
        const common_type mod = static_cast<common_type>(this->_mod);

        if(v > 0 && static_cast<common_type>(v) >= mod) {
            if(static_cast<common_type>(v) <= barrett_reduction::max()) v = this->reduce(v);
            else v %= mod;
        }

        if constexpr(std::signed_integral<T>) {
            if(v < 0) {
                if(static_cast<common_type>(-v) <= mod) v += mod;
                else if(static_cast<common_type>(-v) <= barrett_reduction::max()) {
                    v = mod - this->reduce(static_cast<value_type>(-v - 1)) - 1;
                }
                else {
                    v %= mod;
                    if(v != 0) v += mod;
                }
            }
        }

        return static_cast<value_type>(v);
    }

    constexpr value_type revert(const value_type v) const noexcept(NO_EXCEPT) { return this->reduce(v); }
};


} // namespace internal


using barrett_reduction_32bit = internal::barrett_reduction<u32, u64>;
using barrett_reduction_64bit = internal::barrett_reduction<u64, u128>;


} // namespace uni
#line 2 "numeric/modular/montgomery_reduction.hpp"


#line 7 "numeric/modular/montgomery_reduction.hpp"


#line 10 "numeric/modular/montgomery_reduction.hpp"

#line 16 "numeric/modular/montgomery_reduction.hpp"


namespace uni {

namespace internal {


template<std::unsigned_integral Value, std::unsigned_integral Large>
    requires has_double_digits_of<Large, Value>
struct montgomery_reduction {
    using value_type = Value;
    using large_type = Large;

  private:
    value_type _mod = 0, _r2, _mp;

    constexpr value_type _inv() const noexcept(NO_EXCEPT) {
        value_type res = this->_mod;
        while(this->_mod * res != 1) res *= value_type{ 2 } - this->_mod * res;
        return res;
    }

  public:

    static constexpr int digits = std::numeric_limits<value_type>::digits - 2;
    static constexpr value_type max() noexcept { return (value_type{ 1 } << montgomery_reduction::digits) - 1; }

    inline constexpr value_type mod() const noexcept(NO_EXCEPT) { return this->_mod; }


    value_type zero = 0;
    value_type one;


    constexpr montgomery_reduction() noexcept = default;

    constexpr montgomery_reduction(const value_type mod) noexcept(NO_EXCEPT)
      : _mod(mod), _r2(static_cast<value_type>(-static_cast<large_type>(mod) % mod)),
        _mp(-this->_inv()), one(this->reduce(this->_r2))
    {
        assert((mod & 1) == 1);
        assert(mod <= montgomery_reduction::max());
    }


    constexpr value_type reduce(const large_type v) const noexcept(NO_EXCEPT) {
        return
            static_cast<value_type>(
                (
                    v + static_cast<large_type>(static_cast<value_type>(v) * this->_mp) * this->_mod
                ) >> std::numeric_limits<value_type>::digits
            );
    }


    inline constexpr value_type add(value_type x, const value_type y) const noexcept(NO_EXCEPT) {
        x += y;
        if(x >= (this->_mod << 1)) x -= (this->_mod << 1);
        return x;
    }

    inline constexpr value_type subtract(value_type x, const value_type y) const noexcept(NO_EXCEPT) {
        if(x < y) x += (this->_mod << 1);
        x -= y;
        return x;
    }


    inline constexpr value_type multiply(const value_type x, const value_type y) const noexcept(NO_EXCEPT) {
        return this->reduce(static_cast<large_type>(x) * static_cast<large_type>(y));
    }

    template<std::integral K>
    inline constexpr value_type pow(const large_type v, const K p) const noexcept(NO_EXCEPT) {
        if constexpr(std::signed_integral<K>) assert(p >= 0);

        if(this->_mod == 1) return 0;
        return uni::pow(
            v, p,
            [&](const value_type x, const value_type y) noexcept(NO_EXCEPT) { return this->multiply(x, y); },
            static_cast<large_type>(this->one)
        );
    }


    inline constexpr value_type normalize(const value_type v) const noexcept(NO_EXCEPT) {
        assert(0 <= v && v < (this->_mod << 1));
        if(v < this->_mod) return v;
        return v - this->_mod;
    }

    inline constexpr auto compare(const value_type x, const value_type y) const noexcept(NO_EXCEPT) {
        return this->normalize(x) <=> this->normalize(y);
    }


    inline constexpr value_type convert_raw(const value_type v) const noexcept(NO_EXCEPT) {
        if(v == 1) return this->one;
        return this->multiply(v, this->_r2);
    }

    template<std::integral T>
    constexpr value_type convert(T v) const noexcept(NO_EXCEPT) {
        if(v == 1) return this->one;

        using common_type = std::common_type_t<T, value_type>;
        const common_type mod2 = static_cast<common_type>(this->_mod << 1);

        if(v > 0 && static_cast<common_type>(v) >= mod2) {
            v %= mod2;
        }

        if constexpr(std::is_signed_v<T>) {
            if(v < 0 && static_cast<common_type>(-v) >= mod2) {
                v %= mod2;
                if(v != 0) v += mod2;
            }
        }

        return this->multiply(v, this->_r2);
    }


    constexpr value_type revert(const value_type v) const noexcept(NO_EXCEPT) {
        return this->normalize(this->reduce(v));
    }
};

// Thanks to: https://www.mathenachia.blog/even-mod-montgomery-impl/
template<std::unsigned_integral Value, std::unsigned_integral Large>
    requires has_double_digits_of<Large, Value>
struct arbitrary_montgomery_reduction {
    using value_type = Value;
    using large_type = Large;

  private:
    using context = arbitrary_montgomery_reduction;
    static constexpr int width = std::numeric_limits<value_type>::digits;

    value_type _mod = 0;
    int _tz;
    value_type _m0;
    large_type _m0i, _mask;
    value_type _r2;

    constexpr large_type _inv() const noexcept(NO_EXCEPT) {
        large_type res = this->_m0;
        while(((this->_m0 * res) & this->_mask) != 1) res *= large_type{ 2 } - this->_m0 * res;
        return res & this->_mask;
    }

    constexpr value_type _m0ip() const noexcept(NO_EXCEPT) {
        if(this->_tz == 0) return 0;
        value_type res = this->_m0;
        const value_type mask = (value_type{ 1 } << this->_tz) - 1;
        while(((this->_m0 * res) & mask) != 1) res *= value_type{ 2 } - this->_m0 * res;
        return res & mask;
    }

  public:
    static constexpr int digits = std::numeric_limits<value_type>::digits - 2;
    static constexpr value_type max() noexcept { return (value_type{ 1 } << context::digits) - 1; }

    inline constexpr value_type mod() const noexcept(NO_EXCEPT) { return this->_mod; }

    value_type one;


    constexpr arbitrary_montgomery_reduction() noexcept = default;

    constexpr arbitrary_montgomery_reduction(value_type m) noexcept(NO_EXCEPT) {
        assert(0 < m);

        if(this->_mod == m) return;

        this->_mod = m;
        this->_tz = std::countr_zero(m);
        this->_m0 = m >> this->_tz;

        assert(this->_mod < context::max());

        this->_mask = (large_type{ 1 } << (context::width + this->_tz)) - 1;
        this->_m0i = this->_inv();

        {
            const value_type x = (std::numeric_limits<large_type>::max() % this->_m0) + 1;
            const value_type mask = (value_type{ 1 } << this->_tz) - 1;
            this->_r2 = (x + ((((large_type{ 1 } - x) * this->_m0ip()) & mask) * this->_m0));
        }

        this->one = this->reduce(this->_r2);
    }


    constexpr value_type reduce(const large_type v) const noexcept(NO_EXCEPT) {
        const value_type res =
            static_cast<value_type>(
                (
                    v +
                    this->_m0 *
                    ((((v << std::numeric_limits<value_type>::digits) - v) * this->_m0i) & this->_mask)
                ) >> std::numeric_limits<value_type>::digits
            );
        return res;
    }


    inline constexpr value_type add(value_type x, const value_type y) const noexcept(NO_EXCEPT) {
        x += y;
        if(x >= (this->_mod << 1)) x -= (this->_mod << 1);
        return x;
    }

    inline constexpr value_type subtract(value_type x, const value_type y) const noexcept(NO_EXCEPT) {
        if(x < y) x += (this->_mod << 1);
        x -= y;
        return x;
    }



    inline constexpr value_type multiply(const value_type x, const value_type y) const noexcept(NO_EXCEPT) {
        return this->reduce(static_cast<large_type>(x) * static_cast<large_type>(y));
    }

    template<std::integral K>
    inline constexpr value_type pow(const large_type v, K p) const noexcept(NO_EXCEPT) {
        if constexpr(std::signed_integral<K>) assert(p >= 0);

        if(this->_mod == 1) return 0;
        return uni::pow(
            v, p,
            [&](const value_type x, const value_type y) noexcept(NO_EXCEPT) { return this->multiply(x, y); },
            static_cast<large_type>(this->one)
        );
    }

    inline constexpr value_type normalize(const value_type v) const noexcept(NO_EXCEPT) {
        assert(0 <= v && v < (this->_mod << 1));
        if(v < this->_mod) return v;
        return v - this->_mod;
    }

    inline constexpr auto compare(const large_type x, const large_type y) const noexcept(NO_EXCEPT) {
        return this->normalize(x) <=> this->normalize(y);
    }


    inline constexpr value_type convert_raw(const value_type v) const noexcept(NO_EXCEPT) {
        if(v == 1) return this->one;
        return this->multiply(v, this->_r2);
    }

    template<std::integral T>
    constexpr value_type convert(T v) const noexcept(NO_EXCEPT) {
        if(v == 1) return this->one;

        using common_type = std::common_type_t<T, value_type>;
        const common_type mod2 = static_cast<common_type>(this->_mod << 1);

        if(v > 0 && static_cast<common_type>(v) >= mod2) {
            v %= mod2;
        }

        if constexpr(std::signed_integral<T>) {
            if(v < 0) {
                if(static_cast<common_type>(-v) >= mod2) v %= mod2;
                if(v < 0) v += mod2;
            }
        }

        return this->multiply(v, this->_r2);
    }


    constexpr value_type revert(const value_type v) const noexcept(NO_EXCEPT) {
        return this->normalize(this->reduce(v));
    }
};


} // namespace internal


using montgomery_reduction_32bit = internal::montgomery_reduction<u32, u64>;
using montgomery_reduction_64bit = internal::montgomery_reduction<u64, u128>;

using arbitrary_montgomery_reduction_32bit = internal::arbitrary_montgomery_reduction<u32, u64>;
using arbitrary_montgomery_reduction_64bit = internal::arbitrary_montgomery_reduction<u64, u128>;

} // namespace uni
#line 16 "numeric/modular/modint_interface.hpp"


namespace uni {

namespace internal {


template<class T>
concept modint_family =
    numeric<T> &&
    has_static_one<T> && has_static_zero<T> &&
    requires (T v, i64 p, typename T::value_type x) {
        { v.pow(p) } -> std::same_as<T>;
        { v.inv() } -> std::same_as<T>;
        { T::raw(x) } -> std::same_as<T>;

        { v.val() } -> std::same_as<typename T::value_type>;
        { T::mod() } -> std::same_as<typename T::value_type>;
        { T::max() } -> std::same_as<typename T::value_type>;
        T::digits;

        T::context::dynamic;
    };


template<class T>
concept dynamic_modint_family =
    modint_family<T> &&
    T::context::dynamic &&
    requires (typename T::value_type v) {
        T::set_mod(v);
    };


template<class T>
concept static_modint_family =
    modint_family<T> &&
    (!T::context::dynamic); //&&
    // requires {
    //     T::is_prime;
    // };


template<class T>
concept modular_reduction =
    std::default_initializable<T> &&
    std::constructible_from<T, typename T::value_type> &&
    requires (T v, typename T::value_type x, i64 p) {
        typename T::value_type;

        T::digits;
        { T::max() } -> std::same_as<typename T::value_type>;
        { v.mod() } -> std::same_as<typename T::value_type>;

        { v.reduce(x) } -> std::same_as<typename T::value_type>;

        { v.add(x, x) } -> std::same_as<typename T::value_type>;
        { v.subtract(x, x) } -> std::same_as<typename T::value_type>;
        { v.multiply(x, x) } -> std::same_as<typename T::value_type>;
        { v.multiply(x, x) } -> std::same_as<typename T::value_type>;
        { v.pow(x, p) } -> std::same_as<typename T::value_type>;

        { v.convert_raw(x) } -> std::same_as<typename T::value_type>;
        { v.convert(x) } -> std::same_as<typename T::value_type>;
        { v.revert(x) } -> std::same_as<typename T::value_type>;

        v.compare(x, x);
    };


template<class T>
concept modular_context =
    requires {
        typename T::reductor;
        typename T::value_type;
        T::reduction;
    };


} // namespace internal


template<internal::modular_reduction Reduction, typename Reduction::value_type Mod>
struct static_modular_context {
    using reductor = Reduction;
    using value_type = typename reductor::value_type;

    static constexpr bool dynamic = false;

    static constexpr reductor reduction = reductor(Mod);

  private:
    using context = static_modular_context;
};


template<internal::modular_reduction Reduction, i64 Id>
struct dynamic_modular_context {
    using reductor = Reduction;
    using value_type = typename reductor::value_type;

    static constexpr bool dynamic = true;

    static inline reductor reduction;

  private:
    using context = dynamic_modular_context;

  public:
    static constexpr void set_mod(const value_type mod) noexcept(NO_EXCEPT) { context::reduction = reductor(mod); }
};


template<internal::modular_context> struct modint;


template<u32 Mod> using static_builtin_modular_context_32bit = static_modular_context<builtin_reduction_32bit, Mod>;
template<u64 Mod> using static_builtin_modular_context_64bit = static_modular_context<builtin_reduction_64bit, Mod>;

template<u32 Mod> using static_barrett_modular_context_32bit = static_modular_context<barrett_reduction_32bit, Mod>;
template<u64 Mod> using static_barrett_modular_context_64bit = static_modular_context<barrett_reduction_64bit, Mod>;

template<u32 Mod> using static_montgomery_modular_context_32bit = static_modular_context<montgomery_reduction_32bit, Mod>;
template<u64 Mod> using static_montgomery_modular_context_64bit = static_modular_context<montgomery_reduction_64bit, Mod>;

template<u32 Mod> using static_arbitrary_montgomery_modular_context_32bit = static_modular_context<arbitrary_montgomery_reduction_32bit, Mod>;
template<u64 Mod> using static_arbitrary_montgomery_modular_context_64bit = static_modular_context<arbitrary_montgomery_reduction_64bit, Mod>;

template<u32 Mod> using static_binary_modular_context_32bit = static_modular_context<binary_reduction_32bit, Mod>;
template<u64 Mod> using static_binary_modular_context_64bit = static_modular_context<binary_reduction_64bit, Mod>;
template<u128 Mod> using static_binary_modular_context_128bit = static_modular_context<binary_reduction_128bit, Mod>;


template<u32 Mod> using static_builtin_modint_32bit = modint<static_builtin_modular_context_32bit<Mod>>;
template<u64 Mod> using static_builtin_modint_64bit = modint<static_builtin_modular_context_64bit<Mod>>;

template<u32 Mod> using static_barrett_modint_32bit = modint<static_barrett_modular_context_32bit<Mod>>;
template<u64 Mod> using static_barrett_modint_64bit = modint<static_barrett_modular_context_64bit<Mod>>;

template<u32 Mod> using static_montgomery_modint_32bit = modint<static_montgomery_modular_context_32bit<Mod>>;
template<u64 Mod> using static_montgomery_modint_64bit = modint<static_montgomery_modular_context_64bit<Mod>>;

template<u32 Mod> using static_arbitrary_montgomery_modint_32bit = modint<static_arbitrary_montgomery_modular_context_32bit<Mod>>;
template<u64 Mod> using static_arbitrary_montgomery_modint_64bit = modint<static_arbitrary_montgomery_modular_context_64bit<Mod>>;

template<u32 Mod> using static_binary_modint_32bit = modint<static_binary_modular_context_32bit<Mod>>;
template<u64 Mod> using static_binary_modint_64bit = modint<static_binary_modular_context_64bit<Mod>>;
template<u128 Mod> using static_binary_modint_128bit = modint<static_binary_modular_context_128bit<Mod>>;


template<i64 Id> using dynamic_builtin_modular_context_32bit = dynamic_modular_context<builtin_reduction_32bit, Id>;
template<i64 Id> using dynamic_builtin_modular_context_64bit = dynamic_modular_context<builtin_reduction_64bit, Id>;

template<i64 Id> using dynamic_barrett_modular_context_32bit = dynamic_modular_context<barrett_reduction_32bit, Id>;
template<i64 Id> using dynamic_barrett_modular_context_64bit = dynamic_modular_context<barrett_reduction_64bit, Id>;

template<i64 Id> using dynamic_montgomery_modular_context_32bit = dynamic_modular_context<montgomery_reduction_32bit, Id>;
template<i64 Id> using dynamic_montgomery_modular_context_64bit = dynamic_modular_context<montgomery_reduction_64bit, Id>;

template<i64 Id> using dynamic_arbitrary_montgomery_modular_context_32bit = dynamic_modular_context<arbitrary_montgomery_reduction_32bit, Id>;
template<i64 Id> using dynamic_arbitrary_montgomery_modular_context_64bit = dynamic_modular_context<arbitrary_montgomery_reduction_64bit, Id>;

template<i64 Id> using dynamic_binary_modular_context_32bit = dynamic_modular_context<binary_reduction_32bit, Id>;
template<i64 Id> using dynamic_binary_modular_context_64bit = dynamic_modular_context<binary_reduction_64bit, Id>;
template<i64 Id> using dynamic_binary_modular_context_128bit = dynamic_modular_context<binary_reduction_128bit, Id>;


template<i64 Id> using dynamic_builtin_modint_32bit = modint<dynamic_builtin_modular_context_32bit<Id>>;
template<i64 Id> using dynamic_builtin_modint_64bit = modint<dynamic_builtin_modular_context_64bit<Id>>;

template<i64 Id> using dynamic_barrett_modint_32bit = modint<dynamic_barrett_modular_context_32bit<Id>>;
template<i64 Id> using dynamic_barrett_modint_64bit = modint<dynamic_barrett_modular_context_64bit<Id>>;

template<i64 Id> using dynamic_montgomery_modint_32bit = modint<dynamic_montgomery_modular_context_32bit<Id>>;
template<i64 Id> using dynamic_montgomery_modint_64bit = modint<dynamic_montgomery_modular_context_64bit<Id>>;

template<i64 Id> using dynamic_arbitrary_montgomery_modint_32bit = modint<dynamic_arbitrary_montgomery_modular_context_32bit<Id>>;
template<i64 Id> using dynamic_arbitrary_montgomery_modint_64bit = modint<dynamic_arbitrary_montgomery_modular_context_64bit<Id>>;

template<i64 Id> using dynamic_binary_modint_32bit = modint<dynamic_binary_modular_context_32bit<Id>>;
template<i64 Id> using dynamic_binary_modint_64bit = modint<dynamic_binary_modular_context_64bit<Id>>;
template<i64 Id> using dynamic_binary_modint_128bit = modint<dynamic_binary_modular_context_128bit<Id>>;


template<u32 Mod> using static_modint_32bit = static_builtin_modint_32bit<Mod>;
template<u64 Mod> using static_modint_64bit = static_builtin_modint_64bit<Mod>;


using modint998244353 = static_modint_32bit<998244353>;
using modint1000000007 = static_modint_32bit<1000000007>;

using modint_32 = dynamic_barrett_modint_32bit<-1>;
using modint_64 = dynamic_barrett_modint_64bit<-1>;


template<const unsigned Val, const unsigned Mod = 998244353>
const uni::static_modint_32bit<Mod> MINT = Val;

template<const unsigned Val, const unsigned Mod = 998244353>
const unsigned INV = uni::static_modint_32bit<Mod>{ Val }.inv().val();

template<const unsigned Val, const unsigned Mod = 998244353>
const int SINV = uni::static_modint_32bit<Mod>{ Val }.inv().val();


} // namespace uni
#line 13 "numeric/internal/primality_test.hpp"


namespace uni {

namespace internal {

//Thanks to: https://github.com/NyaanNyaan/library/blob/master/prime/fast-factorize.hpp
namespace fast_factorize_impl {

namespace internal {


// Miller-Rabin primality test
template<modint_family Mint>
constexpr bool primality_test(const u64 n, const std::vector<u64>& ws) noexcept(NO_EXCEPT) {
    if constexpr(dynamic_modint_family<Mint>) Mint::set_mod(n);
    assert(Mint::mod() == n);

    const u64 d = (n - 1) >> std::countr_zero(n - 1);

    const Mint rev = n - 1;
    for(u64 w : ws) {
        Mint x = w;
        if(x == Mint::zero) continue;
        x = x.pow(d);
        if(x == Mint::one || x == rev) continue;
        u64 t = d;
        while(t != n - 1 && x != Mint::one && x != rev) x *= x, t <<= 1;
        if(x != rev) return false;
    }

    return true;
}


// Thanks to: https://miller-rabin.appspot.com/
template<modint_family Small, modint_family Large = Small>
inline constexpr bool is_prime(const u64 n) noexcept(NO_EXCEPT) {
    if(n == 0 || n == 1) return false;
    if(~n & 1UL) return n == 2UL;

    auto bases = [&]() constexpr noexcept(NO_EXCEPT) -> vector<u64> {
        if(n < 341531UL) return { 9345883071009581737UL };
        else if(n < 1050535501UL) return { 336781006125UL, 9639812373923155UL };
        else if(n < 350269456337UL) return { 4230279247111683200UL, 14694767155120705706UL, 16641139526367750375UL };
        else if(n < 55245642489451UL) return { 2UL, 141889084524735UL, 1199124725622454117UL, 11096072698276303650UL };
        else if(n < 7999252175582851UL) return { 2UL, 4130806001517UL, 149795463772692060UL, 186635894390467037UL, 3967304179347715805UL };
        else if(n < 585226005592931977UL) return { 2UL, 123635709730000UL, 9233062284813009UL, 43835965440333360UL, 761179012939631437UL, 1263739024124850375UL };
        else return { 2UL, 325UL, 9375UL, 28178UL, 450775UL, 9780504UL, 1795265022UL };
    };

    if(n <= Small::max()) return primality_test<Small>(n, bases());
    else return primality_test<Large>(n, bases());
}


} // namespace internal

} // namespace fast_factorize_impl


using fast_factorize_impl::internal::is_prime;


} // namespace internal

} // namespace uni
#line 2 "numeric/internal/factorize.hpp"


#line 10 "numeric/internal/factorize.hpp"
#include <random>
#line 12 "numeric/internal/factorize.hpp"


#line 15 "numeric/internal/factorize.hpp"

#line 17 "numeric/internal/factorize.hpp"

#line 21 "numeric/internal/factorize.hpp"

#line 2 "random/engine.hpp"


#line 7 "random/engine.hpp"

#line 9 "random/engine.hpp"


#line 12 "random/engine.hpp"

#line 14 "random/engine.hpp"

#line 2 "hash/general_hasher.hpp"


#line 7 "hash/general_hasher.hpp"


#line 11 "hash/general_hasher.hpp"

#line 13 "hash/general_hasher.hpp"


namespace uni {


template<std::unsigned_integral R, std::integral T>
constexpr R shrink(T x) noexcept(NO_EXCEPT) {
    constexpr int DIGITS_R = std::numeric_limits<R>::digits;
    constexpr int DIGITS_T = std::numeric_limits<R>::digits;

    REPD(digits, DIGITS_R, DIGITS_T, DIGITS_R) {
        x = (x >> digits) ^ uni::lower_bits(x, digits);
    }

    return x;
}


// Thanks to: https://gist.github.com/badboy/6267743
template<class T>
constexpr u32 hash32(T x) {
    if constexpr(std::integral<T>) {
        if constexpr(std::signed_integral<T>) return hash32(to_unsigned(x));

        constexpr int DIGITS_T = std::numeric_limits<T>::digits;

        if constexpr(DIGITS_T <= 32) {
            auto h = static_cast<u32>(x);

            h = ~h + (h << 15);
            h ^= (h >> 12);
            h += (h << 2);
            h ^= (h >> 4);
            h *= 2057;
            h ^= (h >> 16);

            return h;
        }
        else if constexpr(DIGITS_T <= 64) {
            auto h = static_cast<u64>(x);

            h = (~h) + (h << 18);
            h ^= (h >> 31);
            h *= 21;
            h ^= (h >> 11);
            h += (h << 6);
            h ^= (h >> 22);

            return static_cast<u32>(h);
        }
        else {
            return hash32(hash64(x));
        }
    }
    else {
        return hash32(std::hash<T>{}(x));
    }
}


template<class T>
constexpr u64 hash64(T x) {
    if constexpr(std::integral<T>) {
        if constexpr(std::signed_integral<T>) return hash64(to_unsigned(x));

        constexpr int DIGITS_T = std::numeric_limits<T>::digits;

        if constexpr(DIGITS_T <= 64) {
            auto h = static_cast<u64>(x);

            h = (~h) + (h << 21);
            h ^= (h >> 24);
            h *= 265;
            h ^= (h >> 14);
            h *= 21;
            h ^= (h >> 28);
            h += h << 31;

            return h;
        }
        else {
            return hash64(shrink<u64>(x));
        }
    }
    else {
        return hash64(std::hash<T>{}(x));
    }
}


template<class T>
struct hash {
    inline constexpr auto operator()(const T& key) const noexcept(NO_EXCEPT) {
        return static_cast<std::size_t>(uni::hash64(key));
    }
};


} // namespace uni
#line 16 "random/engine.hpp"


// Thanks to: https://prng.di.unimi.it/
namespace uni {


namespace internal {


template<class Derived, class ResultType>
struct random_engine {
    using result_type = ResultType;

    static constexpr result_type MIN = std::numeric_limits<result_type>::min();
    static constexpr result_type MAX = std::numeric_limits<result_type>::max();

    static constexpr result_type min() noexcept(NO_EXCEPT) { return MIN; }
    static constexpr result_type max() noexcept(NO_EXCEPT) { return MAX; }


    template<std::unsigned_integral T = result_type>
    constexpr random_engine(const T _seed = 0) noexcept(NO_EXCEPT) {
        static_cast<Derived*>(this)->seed(_seed);
    };


    inline constexpr result_type operator()() noexcept(NO_EXCEPT) {
        return static_cast<Derived*>(this)->next();
    }
};


const i64 INTERNAL_RANDOM_GENERATOR_ID = -(1UL << 60);


};  // namespace internal


constexpr float to_float(const std::uint32_t x) noexcept(NO_EXCEPT) {
        return float(x >> 8) * 0x1.0p-24f;
}

constexpr double to_double(const std::uint64_t x) noexcept(NO_EXCEPT) {
    return double(x >> 11) * 0x1.0p-53;
}


struct mulberry32 : internal::random_engine<mulberry32, std::uint32_t> {
    using internal::random_engine<mulberry32, std::uint32_t>::random_engine;

  private:
    std::uint32_t _x;

  public:
    template<std::unsigned_integral T>
    inline constexpr void seed(const T x) noexcept(NO_EXCEPT) { this->_x = x; }

    inline constexpr std::uint32_t next() noexcept(NO_EXCEPT) {
        std::uint32_t z = (this->_x += 0x6D2B79F5U);
        z = (z ^ (z >> 15)) * (z | 1U);
        z ^= z + (z ^ (z >> 7)) * (z | 61U);
        return static_cast<std::uint32_t>(z ^ (z >> 14));
    }
};


struct splitmix64 : internal::random_engine<splitmix64, std::uint64_t> {
    using internal::random_engine<splitmix64, std::uint64_t>::random_engine;

  private:
    std::uint64_t _x;

  public:
    template<std::unsigned_integral T>
    inline constexpr void seed(const T x) noexcept(NO_EXCEPT) { this->_x = x; }

    inline constexpr std::uint64_t next() noexcept(NO_EXCEPT) {
        std::uint64_t z = (this->_x += 0x9e3779b97f4a7c15);
        z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
        z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
        return z ^ (z >> 31);
    }
};



// xoroshiro64**
struct xoroshiro64ss : internal::random_engine<xoroshiro64ss, std::uint32_t> {
    using internal::random_engine<xoroshiro64ss, std::uint32_t>::random_engine;

  private:
    std::uint32_t s[2];

  public:
    template<std::unsigned_integral T>
    inline constexpr void seed(const T _seed) noexcept(NO_EXCEPT) {
        mulberry32 gen32(hash32(_seed));
        this->s[0] = gen32();
        this->s[1] = gen32();
    }

    inline constexpr std::uint32_t next() noexcept(NO_EXCEPT) {
        const std::uint32_t s0 = this->s[0];
        std::uint32_t s1 = this->s[1];

        const std::uint32_t res = std::rotl(s0 * 0x9E3779BBU, 5) * 5;

        s1 ^= s0;
        this->s[0] = std::rotl(s0, 26) ^ s1 ^ (s1 << 9);
        this->s[1] = std::rotl(s1, 13);

        return res;
    }
};



struct xoroshiro128ss : internal::random_engine<xoroshiro128ss, std::uint64_t> {
    using internal::random_engine<xoroshiro128ss, std::uint64_t>::random_engine;

  private:
    std::uint64_t s[2];

  public:
    template<std::unsigned_integral T>
    inline constexpr void seed(const T _seed) noexcept(NO_EXCEPT) {
        splitmix64 gen64(hash32(_seed));
        this->s[0] = gen64();
        this->s[1] = gen64();
    }

    inline constexpr std::uint64_t next() noexcept(NO_EXCEPT) {
        const uint64_t s0 = this->s[0];
        uint64_t s1 = this->s[1];
        const uint64_t res = std::rotl(s0 * 5, 7) * 9;

        s1 ^= s0;
        this->s[0] = std::rotl(s0, 24) ^ s1 ^ (s1 << 16);
        this->s[1] = std::rotl(s1, 37);

        return res;
    }
};


struct xoroshiro128pp : internal::random_engine<xoroshiro128pp, std::uint64_t> {
    using internal::random_engine<xoroshiro128pp, std::uint64_t>::random_engine;

  private:
    std::uint64_t s[2];

  public:
    template<std::unsigned_integral T>
    inline constexpr void seed(const T _seed) noexcept(NO_EXCEPT) {
        splitmix64 gen64(hash32(_seed));
        this->s[0] = gen64();
        this->s[1] = gen64();
    }

    inline constexpr std::uint64_t next() noexcept(NO_EXCEPT) {
        const std::uint64_t s0 = this->s[0];
        std::uint64_t s1 = this->s[1];
        const std::uint64_t res = std::rotl(s0 + s1, 17) + s0;

        s1 ^= s0;
        this->s[0] = std::rotl(s0, 49) ^ s1 ^ (s1 << 21); // a, b
        this->s[1] = std::rotl(s1, 28); // c

        return res;
    }
};


// xoroshiro128+
struct xoroshiro128p : internal::random_engine<xoroshiro128p, std::uint64_t> {
    using internal::random_engine<xoroshiro128p, std::uint64_t>::random_engine;

  private:
    std::uint64_t s[2];

  public:
    template<std::unsigned_integral T>
    inline constexpr void seed(const T _seed) noexcept(NO_EXCEPT) {
        splitmix64 gen64(hash64(_seed));
        this->s[0] = gen64();
        this->s[1] = gen64();
    }

    inline constexpr std::uint64_t next() noexcept(NO_EXCEPT) {
        const std::uint64_t s0 = this->s[0];
        std::uint64_t s1 = this->s[1];
        const std::uint64_t res = s0 + s1;

        s1 ^= s0;
        this->s[0] = std::rotl(s0, 24) ^ s1 ^ (s1 << 16);
        this->s[1] = std::rotl(s1, 37);

        return res;
    }
};


struct xoroshiro64s : internal::random_engine<xoroshiro64s, std::uint32_t> {
    using internal::random_engine<xoroshiro64s, std::uint32_t>::random_engine;

  private:
    std::uint32_t s[2];

  public:
    template<std::unsigned_integral T>
    inline constexpr void seed(const T _seed) noexcept(NO_EXCEPT) {
        mulberry32 gen32(hash32(_seed));
        this->s[0] = gen32();
        this->s[1] = gen32();
    }

    inline constexpr std::uint32_t next() noexcept(NO_EXCEPT) {
        const std::uint32_t s0 = s[0];
        std::uint32_t s1 = s[1];
        const std::uint32_t res = s0 * 0x9E3779BB;

        s1 ^= s0;
        s[0] = std::rotl(s0, 26) ^ s1 ^ (s1 << 9);
        s[1] = std::rotl(s1, 13);

        return res;
    }
};


using random_engine_32bit = xoroshiro64ss;

using random_engine_64bit = xoroshiro128pp;

using random_engine_float = xoroshiro64s;

using random_engine_double = xoroshiro128p;



random_engine_32bit randi32;
random_engine_64bit randi64;

float randf() {
    static random_engine_float gen;
    return to_float(gen());
}

double randd() {
    static random_engine_double gen;
    return to_double(gen());
}


} // namespace uni
#line 23 "numeric/internal/factorize.hpp"


namespace uni {

namespace internal {


//Thanks to: https://github.com/NyaanNyaan/library/blob/master/prime/fast-factorize.hpp
namespace fast_factorize_impl {

namespace internal {


// Pollard's rho algorithm
template<modint_family Mint, class T>
T find_factor(const T n) noexcept(NO_EXCEPT) {
    if(~n & 1) return 2;
    if(is_prime<Mint>(n)) return n;

    assert(static_cast<u64>(Mint::mod()) == n);
    Mint rr;

    auto f = [&](const Mint& x) noexcept(NO_EXCEPT) { return x * x + rr; };

    static random_engine_64bit rand(std::random_device{}());
    auto rand_ = [&]() noexcept(NO_EXCEPT) { return rand() % (n - 2) + 2; };

    while(true) {
        Mint x, y, ys, q = Mint::one;
        rr = rand_(), y = rand_();
        T g = 1;
        constexpr int m = 128;

        for(int r = 1; g == 1; r <<= 1) {
            x = y;
            for(int i = 0; i < r; ++i) y = f(y);
            for(int k = 0; g == 1 && k < r; k += m) {
                ys = y;
                for(int i = 0; i < m && i < r - k; ++i) q *= x - (y = f(y));
                g = uni::binary_gcd(q.val(), n);
            }
        }

        if(g == n) {
            do {
                g = uni::binary_gcd((x - (ys = f(ys))).val(), n);
            } while(g == 1);
        }
        if(g != n) return g;
    }

    assert(false);
}


template<modint_family Small, modint_family Large, class R>
void factorize(const u64 n, R *const res) noexcept(NO_EXCEPT) {
    if(n <= 1) return;

    u64 p;
    if constexpr(std::same_as<Small, Large>) p = find_factor<Small, typename Small::value_type>(n);
    else {
        if(n <= Small::max()) p = find_factor<Small, typename Small::value_type>(n);
        else p = find_factor<Large, typename Large::value_type>(n);
    }

    if(p == static_cast<u64>(n)) {
        res->emplace_back(p);
        return;
    }

    factorize<Small, Large>(p, res);
    factorize<Small, Large>(n / p, res);
}


} // namespace internal

} // namespace fast_factorize_impl


using fast_factorize_impl::internal::factorize;


} // namespace internal

} // namespace uni
#line 2 "numeric/internal/divisors.hpp"


#line 8 "numeric/internal/divisors.hpp"


#line 12 "numeric/internal/divisors.hpp"


namespace uni {

namespace internal {


//Thanks to: https://github.com/NyaanNyaan/library/blob/master/prime/fast-factorize.hpp
template<modint_family Small, modint_family Large, class R>
void divisors(const u64 n, R *const res) noexcept(NO_EXCEPT) {
    if(n == 0) return;

    std::vector<u64> facts; factorize<Small, Large>(n, &facts);
    std::ranges::sort(facts);

    std::vector<std::pair<u64, int>> v;
    for(auto &p : facts) {
        if(v.empty() || v.back().first != p) {
            v.emplace_back(p, 1);
        } else {
            v.back().second++;
        }
    }

    using value_type = std::ranges::range_value_t<R>;

    const auto size = std::ranges::ssize(v);
    auto f = [&](auto rc, int i, value_type x) noexcept(NO_EXCEPT) -> void {
        if(i == size) {
            res->push_back(x);
            return;
        }
        for(int j = v[i].second; ; --j) {
            rc(rc, i + 1, x);
            if(j == 0) break;
            x *= static_cast<value_type>(v[i].first);
        }
    };
    f(f, 0, 1);
}


} // namespace internal

} // namespace uni
#line 2 "numeric/internal/primitive_root.hpp"


#line 8 "numeric/internal/primitive_root.hpp"


#line 11 "numeric/internal/primitive_root.hpp"

#line 13 "numeric/internal/primitive_root.hpp"

#line 16 "numeric/internal/primitive_root.hpp"

#line 18 "numeric/internal/primitive_root.hpp"


namespace uni {

namespace internal {


// Thanks to: https://37zigen.com/primitive-root/
template<modint_family Small, modint_family Large, modint_family Mint, std::unsigned_integral T>
T primitive_root(const T p) noexcept(NO_EXCEPT) {
    std::vector<T> pows;
    factorize<Small, Large>(p - 1, &pows);
    {
        std::ranges::sort(pows);
        const auto rest = std::ranges::unique(pows);
        pows.erase(ALL(rest));
    }

    ITRR(pow, pows) pow = (p - 1) / pow;

    if constexpr(dynamic_modint_family<Mint>) Mint::set_mod(p);
    assert(Mint::mod() == p);

    static random_engine_64bit rand;
    while(true) {
        const Mint x = rand();
        if(x == Mint::zero) continue;

        bool ok = true;
        ITR(pow, pows) {
            if(x.pow(pow) == Mint::one) {
                ok = false;
                break;
            }
        }
        if(ok) return x.val();
    }

    return 0;
}


// Thanks to: atcoder::internal::primitive_root_constexpr
template<static_modint_family Mint>
constexpr u32 primitive_root_constexpr(u32 m) {
    assert(Mint::mod() == m);

    u32 divs[20]{}; divs[0] = 2;
    u32 cnt = 1;

    u64 x = (m - 1) / 2;
    while(x % 2 == 0) x /= 2;

    for(u64 i = 3; i * i <= x; i += 2) {
        if(x % i == 0) {
            divs[cnt++] = i;
            while(x % i == 0) x /= i;
        }
    }

    if(x > 1) divs[cnt++] = x;

    for(u32 g = 2; ; g++) {
        bool ok = true;

        REP(i, cnt) {
            if(Mint{ g }.pow((m - 1) / divs[i]) == 1) {
                ok = false;
                break;
            }
        }

        if(ok) return g;
    }
}


template<modint_family Small, modint_family Large = Small, std::integral Res = u64, bool FORCE_RANDOM = false>
constexpr Res primitive_root(const u64 p) noexcept(NO_EXCEPT) {
    if constexpr(!FORCE_RANDOM) {
        if(p == 2) return 1;
        if(p == 167772161) return 3;
        if(p == 469762049) return 3;
        if(p == 754974721) return 11;
        if(p == 998244353) return 3;
        if(p == (UINT64_C(1) << 61) - 1) return 37;
    }


    if(std::is_constant_evaluated()) {
        if constexpr(static_modint_family<Small> && std::same_as<Small, Large> && Small::mod() < (1U << 31)) {
            assert(p <= std::numeric_limits<u32>::max());
            return primitive_root_constexpr<Small>(p);
        }
        assert(false);
    }
    else {
        if(p <= Small::max()) return primitive_root<Small, Large, Small, typename Small::value_type>(p);
        else return primitive_root<Small, Large, Large, typename Large::value_type>(p);
    }
}


} // namespace internal

} // namespace uni
#line 2 "numeric/modular/modint.hpp"


#line 7 "numeric/modular/modint.hpp"


#line 10 "numeric/modular/modint.hpp"

#line 13 "numeric/modular/modint.hpp"

#line 15 "numeric/modular/modint.hpp"

#line 17 "numeric/modular/modint.hpp"


namespace uni {


namespace internal {


template<class, bool>
struct modint_base {};


template<class Mint>
struct modint_base<Mint, false> {
    static constexpr Mint zero = Mint::_raw(0);
    static constexpr Mint one = Mint::_one();
};


template<class Mint>
struct modint_base<Mint, true> {
    static constexpr Mint zero = Mint::_raw(0);
    static inline Mint one = Mint::_one();
};


} // internal



template<internal::modular_context Context>
struct modint : internal::modint_base<modint<Context>, Context::dynamic> {
    using value_type = typename Context::value_type;
    using context = Context;

  private:
    using base = internal::modint_base<modint, context::dynamic>;

    friend base;

    value_type _val = 0;


    static constexpr auto _raw(const value_type v) noexcept(NO_EXCEPT) {
        modint res;
        res._val = v;
        return res;
    }


    static constexpr auto _one() noexcept(NO_EXCEPT)
        requires internal::has_static_one<typename modint::context::reductor>
    {
        return modint::_raw(modint::context::reduction.one);
    }

    static constexpr auto _one() noexcept(NO_EXCEPT)
        requires (!internal::has_static_one<typename modint::context::reductor>)
    {
        return modint::_raw(1);
    }

  public:
    static constexpr int digits = modint::context::reductor::digits;
    static constexpr value_type max() noexcept { return modint::context::reductor::max(); }


    static constexpr void set_mod(const value_type mod) noexcept(NO_EXCEPT)
        requires requires(value_type mod) { modint::context::set_mod(mod); }
    {
        modint::context::set_mod(mod);
        modint::one = modint::_one();
    }


    static constexpr auto mod() noexcept(NO_EXCEPT) { return modint::context::reduction.mod(); }

    static constexpr auto raw(const value_type v) noexcept(NO_EXCEPT)
    {
        modint res;
        res._val = modint::context::reduction.convert_raw(v);
        return res;
    };


    constexpr modint() noexcept = default;

    template<std::integral T>
    constexpr modint(const T v) noexcept(NO_EXCEPT) : _val(modint::context::reduction.convert(v)) {}


    inline constexpr auto val() const noexcept(NO_EXCEPT) {
        return modint::context::reduction.revert(this->_val);
    }

    inline constexpr explicit operator value_type() const noexcept(NO_EXCEPT) { return this->_val; }


    inline constexpr auto& operator+=(const modint& rhs) noexcept(NO_EXCEPT) {
        this->_val = modint::context::reduction.add(this->_val, rhs._val);
        return *this;
    }

    inline constexpr auto& operator-=(const modint& rhs) noexcept(NO_EXCEPT) {
        this->_val = modint::context::reduction.subtract(this->_val, rhs._val);
        return *this;
    }


    inline constexpr auto& operator*=(const modint& rhs) noexcept(NO_EXCEPT) {
        this->_val = modint::context::reduction.multiply(this->_val, rhs._val);
        return *this;
    }

    inline constexpr auto& operator/=(const modint& rhs) noexcept(NO_EXCEPT) { return *this *= rhs.inv(); }


    template<std::integral K>
    constexpr auto pow(const K n) const noexcept(NO_EXCEPT) {
        if constexpr(std::signed_integral<K>) assert(n >= 0);

        return modint::_raw(modint::context::reduction.pow(this->_val, n));
    }


    constexpr auto inv() const noexcept(NO_EXCEPT) {
        using signed_value_type = std::make_signed_t<value_type>;

        signed_value_type x = this->val(), y = modint::mod(), u = 1, v = 0;

        while(y > 0) {
            signed_value_type t = x / y;
            std::swap(x -= t * y, y);
            std::swap(u -= t * v, v);
        }

        assert(x == 1);

        if(u < 0) u += v / x;
        return modint::raw(u);
    }


    friend inline constexpr auto operator<=>(const modint& lhs, const modint& rhs) noexcept(NO_EXCEPT) {
        return modint::context::reduction.compare(lhs._val, rhs._val);
    }

    friend inline constexpr bool operator==(const modint& lhs, const modint& rhs) noexcept(NO_EXCEPT) {
        return lhs <=> rhs == 0;
    }


    inline constexpr auto& operator++() noexcept(NO_EXCEPT) { return *this += modint::one; }
    inline constexpr auto& operator--() noexcept(NO_EXCEPT) { return *this -= modint::one; }

    inline constexpr auto operator++(int) noexcept(NO_EXCEPT) { const modint res = *this; return ++*this, res; }
    inline constexpr auto operator--(int) noexcept(NO_EXCEPT) { const modint res = *this; return --*this, res; }

    inline constexpr auto operator+() const noexcept(NO_EXCEPT) { return *this; }
    inline constexpr auto operator-() const noexcept(NO_EXCEPT) { return modint::zero - *this; }

    friend inline constexpr auto operator+(modint lhs, const modint& rhs) noexcept(NO_EXCEPT) { return lhs += rhs; }
    friend inline constexpr auto operator-(modint lhs, const modint& rhs) noexcept(NO_EXCEPT) { return lhs -= rhs; }
    friend inline constexpr auto operator*(modint lhs, const modint& rhs) noexcept(NO_EXCEPT) { return lhs *= rhs; }
    friend inline constexpr auto operator/(modint lhs, const modint& rhs) noexcept(NO_EXCEPT) { return lhs /= rhs; }
};


} // namespace uni
#line 17 "numeric/fast_prime.hpp"


namespace uni {

namespace internal {


constexpr i64 INTERNAL_MODINT_ID = -(1L << 62);


inline constexpr bool is_prime(const i64 n) noexcept(NO_EXCEPT) {
    assert(n >= 0);
    return is_prime<uni::dynamic_montgomery_modint_32bit<INTERNAL_MODINT_ID>, uni::dynamic_montgomery_modint_64bit<INTERNAL_MODINT_ID>>(n);
}

inline auto factorize(const i64 n) noexcept(NO_EXCEPT) {
    assert(n >= 0);
    vector<i64> res;
    factorize<uni::dynamic_montgomery_modint_32bit<INTERNAL_MODINT_ID>, uni::dynamic_montgomery_modint_64bit<INTERNAL_MODINT_ID>>(n, &res);
    return res;
}

inline auto divisors(const i64 n) noexcept(NO_EXCEPT) {
    assert(n >= 0);
    vector<i64> res;
    divisors<uni::dynamic_montgomery_modint_32bit<INTERNAL_MODINT_ID>, uni::dynamic_montgomery_modint_64bit<INTERNAL_MODINT_ID>>(n, &res);
    std::ranges::sort(res);
    return res;
}

template<bool FORCE_RANDOM = false>
inline auto primitive_root(const i64 n) noexcept(NO_EXCEPT) {
    assert(n >= 0);
    return primitive_root<uni::dynamic_montgomery_modint_32bit<INTERNAL_MODINT_ID>, uni::dynamic_montgomery_modint_64bit<INTERNAL_MODINT_ID>, i64, FORCE_RANDOM>(n);
}


} // namespace internal


using internal::is_prime;
using internal::divisors;
using internal::primitive_root;


inline vector<i64> factorize(const i64 n) noexcept(NO_EXCEPT) {
    assert(n >= 0);
    auto res = internal::factorize(n);
    std::ranges::sort(res);
    return res;
}

inline set<i64> prime_factors(const i64 n) noexcept(NO_EXCEPT) {
    assert(n >= 0);
    const auto factors = factorize(n);
    set<i64> res(ALL(factors));
    return res;
}

inline map<i64,i64> count_factors(const i64 n) noexcept(NO_EXCEPT) {
    assert(n >= 0);
    map<i64,i64> mp;
    for(auto &x : internal::factorize(n)) mp[x]++;
    return mp;
}


} // namespace uni
#line 15 "algebraic/rolling_hash.hpp"

#line 17 "algebraic/rolling_hash.hpp"


namespace uni {

namespace algebraic {


template<uni::internal::modint_family ValueType, typename ValueType::value_type BASE>
struct rolling_hash_impl {
    using value_type = ValueType;
    inline static value_type base;

  private:
    value_type _value = 0, _power = 1;

  public:
    rolling_hash_impl(const value_type& value, const value_type& power) noexcept(NO_EXCEPT)
      : _value(value), _power(power)
    {
        if(rolling_hash_impl::base == 0) {
            if constexpr(BASE == 0) {
                rolling_hash_impl::base = uni::primitive_root<true>(value_type::mod());
            }
            else if constexpr(BASE < 0) {
                random_engine_64bit random(std::random_device{}());
                rolling_hash_impl::base = static_cast<value_type>(random() % value_type::mod());
            }
            else {
                rolling_hash_impl::base = BASE;
            }
        }
    }

    rolling_hash_impl(const value_type& value) noexcept(NO_EXCEPT) : rolling_hash_impl(value, 0) {
        this->_power = rolling_hash_impl::base;
    };

    rolling_hash_impl() noexcept = default;


    inline auto power() const noexcept(NO_EXCEPT) { return this->_power; }
    inline auto val() const noexcept(NO_EXCEPT) { return this->_value; }


    friend inline bool operator==(const rolling_hash_impl& lhs, const rolling_hash_impl& rhs) noexcept(NO_EXCEPT) {
        return lhs._power == rhs._power && lhs._value == rhs._value;
    }

    friend inline auto operator<=>(const rolling_hash_impl& lhs, const rolling_hash_impl& rhs) noexcept(NO_EXCEPT) {
        const auto comp_power = lhs._power <=> rhs._power;
        if(comp_power != 0) return comp_power;
        return lhs._value <=> rhs._value;
    }
};


template<
    bool REVERSE = false,
    uni::internal::modint_family T = uni::static_modint_64bit<(1UL << 61) - 1>,
    typename T::value_type BASE = 0
>
struct rolling_hash : base<rolling_hash_impl<T, BASE>>, scalar_multipliable<rolling_hash<REVERSE, T, BASE>>::automatic, associative {
    using base<rolling_hash_impl<T, BASE>>::base;


    rolling_hash(const T& v) : base<rolling_hash_impl<T, BASE>>(v) {}

    template<class U>
        requires (
            (!std::same_as<std::remove_cvref_t<U>, T>) &&
            (!std::constructible_from<rolling_hash_impl<T, BASE>, U>)
        )
    rolling_hash(U&& v) : base<rolling_hash_impl<T, BASE>>(hash64(std::forward<U>(v))) {}


    friend inline auto operator+(const rolling_hash& lhs, const rolling_hash& rhs) noexcept(NO_EXCEPT) {
        const auto power = lhs->power() * rhs->power();
        if constexpr(REVERSE) return rolling_hash({ lhs->val() * rhs->power() + rhs->val(), power });
        return rolling_hash({ lhs->val() + rhs->val() * lhs->power(), power });
    }

    inline auto operator-() noexcept(NO_EXCEPT) {
        const auto power_inv = this->val().power().inv();
        return rolling_hash({ -this->val().val() * power_inv, power_inv });
    }
};


} // namespace algebraic

} // namespace uni
#line 10 "action/range_sequence_hash.hpp"



namespace uni {

namespace actions {


template<
    bool REVERSE = false,
    uni::internal::modint_family T = uni::static_modint_64bit<(1UL << 61) - 1>,
    typename T::value_type BASE = 0
>
using range_sequence_hash = make_operatable_t<uni::algebraic::rolling_hash<REVERSE, T, BASE>>;

static_assert(internal::operand_only_action<range_sequence_hash<false>>);
static_assert(internal::operand_only_action<range_sequence_hash<true>>);


} // namespace actions

} // namespace uni
#line 2 "action/range_set.hpp"


#line 6 "action/range_set.hpp"

#line 2 "algebraic/assignment.hpp"

#line 4 "algebraic/assignment.hpp"

#line 7 "algebraic/assignment.hpp"

namespace uni {

namespace algebraic {


template<class T>
struct assignment : base<std::optional<T>>, scalar_multipliable<assignment<T>>::identity, associative {
    using base<std::optional<T>>::base;

    friend inline assignment operator+(const assignment& lhs, const assignment& rhs) noexcept(NO_EXCEPT) {
        if(lhs->has_value()) return lhs;
        return rhs;
    }
};


} // namespace algebraic

} // namespace uni
#line 9 "action/range_set.hpp"


namespace uni {

namespace actions {


template<class T>
struct range_set : base<algebraic::assignment<T>> {
    using operand = algebraic::null<T>;
    using operation = algebraic::assignment<T>;

    static operand mapping(const operation& f, const operand& x) noexcept(NO_EXCEPT) {
        return f->value_or(x.val());
    }
};

static_assert(internal::full_action<range_set<int>>);


} // namesapce actions

} // namespace uni
#line 2 "action/range_set_range_composition.hpp"


#line 5 "action/range_set_range_composition.hpp"


#line 9 "action/range_set_range_composition.hpp"

#line 12 "action/range_set_range_composition.hpp"



namespace uni {

namespace actions {


template<class T, bool REVERSE = false>
struct range_set_range_composition : base<algebraic::assignment<std::pair<T, T>>> {
    using base<algebraic::assignment<std::pair<T, T>>>::base;

    using operand = algebraic::affine<T, REVERSE>;
    using operation = algebraic::assignment<std::pair<T, T>>;

    static operand mapping(const operation& f, const operand& x) noexcept(NO_EXCEPT) {
        return f->value_or(std::make_pair(x->first, x->second));
    }
};

static_assert(internal::full_action<range_set_range_composition<int>>);


} // namespace actions

} // namespace uni
#line 2 "action/range_set_range_max.hpp"


#line 5 "action/range_set_range_max.hpp"

#line 7 "action/range_set_range_max.hpp"

#line 10 "action/range_set_range_max.hpp"


namespace uni {

namespace actions {


template<class T>
struct range_set_range_max : base<algebraic::assignment<T>>  {
    using operand = algebraic::maximum<T>;
    using operation = algebraic::assignment<T>;

    static operand mapping(const operation& f, const operand& x) noexcept(NO_EXCEPT) {
        return f->value_or(x.val());
    }
};

static_assert(internal::full_action<range_set_range_max<int>>);


} // namespace actions

} // namespace uni
#line 2 "action/range_set_range_min.hpp"


#line 5 "action/range_set_range_min.hpp"

#line 7 "action/range_set_range_min.hpp"

#line 10 "action/range_set_range_min.hpp"


namespace uni {

namespace actions {


template<class T>
struct range_set_range_min : base<algebraic::assignment<T>> {
    using operand = algebraic::minimum<T>;
    using operation = algebraic::assignment<T>;

    static operand mapping(const operation& f, const operand& x) noexcept(NO_EXCEPT) {
        return f->value_or(x.val());
    }
};

static_assert(internal::full_action<range_set_range_min<int>>);


} // namespace actions

} // namespace uni
#line 2 "action/range_set_range_sum.hpp"


#line 5 "action/range_set_range_sum.hpp"

#line 7 "action/range_set_range_sum.hpp"

#line 10 "action/range_set_range_sum.hpp"


namespace uni {

namespace actions {


template<class T>
struct range_set_range_sum {
    using operand = algebraic::addition<T>;
    using operation = algebraic::assignment<T>;

    static operand mapping(const operation& f, const operand& x) noexcept(NO_EXCEPT) {
        return f->value_or(x.val());
    }

    static auto power(const operation& x, const uni::internal::size_t length) noexcept(NO_EXCEPT) {
        if(x->has_value()) return operation(x->operator*() * length);
        return x;
    }
};

static_assert(internal::full_action<range_set_range_sum<int>>);


} // namespace actions

} // namespace uni
#line 2 "action/range_sum.hpp"


#line 6 "action/range_sum.hpp"

#line 8 "action/range_sum.hpp"


namespace uni {

namespace actions {


template<class T>
using range_sum = make_operatable_t<uni::algebraic::addition<T>>;

static_assert(internal::operand_only_action<range_sum<int>>);


} // namespace actions

} // namespace uni
#line 2 "include/adaptors.hpp"

#line 4 "include/adaptors.hpp"

#line 2 "adaptor/array.hpp"


#line 6 "adaptor/array.hpp"


#line 9 "adaptor/array.hpp"


namespace uni {


template<class T, int N>
using array = internal::advanced_container<std::array<T,N>>;


} // namespace uni
#line 2 "adaptor/auto_expander.hpp"


#line 7 "adaptor/auto_expander.hpp"


#line 11 "adaptor/auto_expander.hpp"


namespace uni {


template<class Container>
struct auto_expander : Container {
    using size_type = Container::size_type;

  public:
    template<class... Args>
    explicit auto_expander(Args&&... args) noexcept(NO_EXCEPT) : Container(std::forward<Args>(args)...) {}

    inline auto& operator[](const size_type pos) noexcept(NO_EXCEPT) {
        if(this->size() <= pos) this->Container::resize(pos + 1);
        return this->Container::operator[](pos);
    }
};


}
#line 2 "adaptor/deque_by_stack.hpp"


#line 9 "adaptor/deque_by_stack.hpp"


#line 12 "adaptor/deque_by_stack.hpp"

#line 14 "adaptor/deque_by_stack.hpp"


namespace uni {


template<class Front, class Back = Front>
struct deque_by_stack {
    static_assert(std::same_as<typename Front::value_type, typename Back::value_type>);
    static_assert(std::common_reference_with<typename Front::size_type, typename Back::size_type>);

    using value_type = Front::value_type;
    using size_type = std::common_type_t<typename Front::size_type, typename Back::size_type>;

  protected:
    Front _front;
    Back _back;

  private:
    template<std::ptrdiff_t OFFSET>
    inline void _distribute() noexcept(NO_EXCEPT) {
        if(this->empty()) return;

        std::vector<value_type> temp;
        temp.reserve(this->size());

        if(this->_front.empty()) {
            while(!this->_back.empty()) {
                temp.push_back(this->_back.top());
                this->_back.pop();
            }
            std::ranges::reverse(temp);
        }
        else if(this->_back.empty()) {
            while(!this->_front.empty()) {
                temp.push_back(this->_front.top());
                this->_front.pop();
            }
        }
        else {
            return;
        }

        assert(this->empty());

        const auto size = std::ranges::ssize(temp);
        const auto mid = (size + OFFSET) / 2;

        REPD(i, mid) this->_front.push(temp[i]);
        REP(i, mid, size) this->_back.push(temp[i]);
    }

  public:
    deque_by_stack() noexcept = default;

    inline bool empty() const noexcept(NO_EXCEPT) {
        return this->_front.empty() && this->_back.empty();
    }

    inline auto size() const noexcept(NO_EXCEPT) {
        return this->_front.size() + this->_back.size();
    }


    inline decltype(auto) front() const noexcept(NO_EXCEPT) {
        this->_distribute<1>();
        assert(!this->_front.empty());
        return this->_front.top();
    }

    inline decltype(auto) back() const noexcept(NO_EXCEPT) {
        this->_distribute<0>();
        assert(!this->_back.empty());
        return this->_back.top();
    }


    template<std::convertible_to<value_type> T = value_type>
        requires std::is_move_constructible_v<T>
    inline decltype(auto) front_or(T&& val) const noexcept(NO_EXCEPT) {
        if(this->empty()) return static_cast<value_type>(std::forward<T>(val));
        else return this->front();
    }

    template<std::convertible_to<value_type> T = value_type>
        requires std::is_move_constructible_v<T>
    inline decltype(auto) back_or(T&& val) const noexcept(NO_EXCEPT) {
        if(this->empty()) return static_cast<value_type>(std::forward<T>(val));
        else return this->back();
    }


    inline auto& clear() noexcept(NO_EXCEPT) {
        this->_front.clear(), this->_back.clear();
        return *this;
    }


    template<std::convertible_to<value_type> T = value_type>
    inline auto& push_front(T&& val) noexcept(NO_EXCEPT) {
        this->_front.push(std::forward<T>(val));
        return *this;
    }

    template<std::convertible_to<value_type> T = value_type>
    inline auto& push_back(T&& val) noexcept(NO_EXCEPT) {
        this->_back.push(std::forward<T>(val));
        return *this;
    }


    template<class... Args>
    inline decltype(auto) emplace_front(Args&&... args) noexcept(NO_EXCEPT) {
        return this->_front.emplace(std::forward<Args>(args)...);
    }

    template<class... Args>
    inline decltype(auto) emplace_back(Args&&... args) noexcept(NO_EXCEPT) {
        return this->_back.emplace(std::forward<Args>(args)...);
    }


    auto& pop_front() noexcept(NO_EXCEPT) {
        this->_distribute<1>();
        assert(!this->_front.empty());

        this->_front.pop();
        return *this;
    }

    auto& pop_back() noexcept(NO_EXCEPT) {
        this->_distribute<0>();
        assert(!this->_back.empty());

        this->_back.pop();
        return *this;
    }
};



} // namespace uni
#line 2 "adaptor/io.hpp"

#include <regex>

#line 2 "adaptor/internal/input.hpp"


#line 12 "adaptor/internal/input.hpp"


#line 15 "adaptor/internal/input.hpp"

#line 18 "adaptor/internal/input.hpp"

#line 20 "adaptor/internal/input.hpp"

#line 22 "adaptor/internal/input.hpp"

#line 24 "adaptor/internal/input.hpp"


namespace uni {


template<std::derived_from<std::ios_base> Source = std::istream>
struct input_adaptor {
    using source_type = Source;

  private:
    template<class T>
        requires std::derived_from<T, std::valarray<typename T::value_type>>
    auto _set(uni::internal::resolving_rank<6>, T& val) noexcept(NO_EXCEPT) -> int {
        this->operator()(ALL(val));
        return 0;
    }

    template<class T>
        requires
            requires (source_type& in, T& val) {
                in >> val;
            }
    int _set(uni::internal::resolving_rank<5>, T& val) noexcept(NO_EXCEPT) {
        *this->in >> val;
        return 0;
    }

    template<std::ranges::range T>
    int _set(uni::internal::resolving_rank<4>, T& val) noexcept(NO_EXCEPT) {
        this->operator()(std::ranges::begin(val), std::ranges::end(val));
        return 0;
    }

    template<class T>
        requires
            requires (T& val) {
                val.first;
                val.second;
            }
    int _set(uni::internal::resolving_rank<3>, T& val) noexcept(NO_EXCEPT) {
        *this >> val.first >> val.second;
        return 0;
    }

    template<class T>
        requires
            requires (T& val) {
                std::get<0>(val);
            }
    int _set(uni::internal::resolving_rank<2>, T& val) noexcept(NO_EXCEPT) {
        tuple_for_each([this](auto&& v) { *this >> v; }, val);
        return 0;
    }

    template<uni::internal::modint_family T>
    int _set(uni::internal::resolving_rank<1>, T& val) noexcept(NO_EXCEPT) {
        std::int64_t v; std::cin >> v;
        val = { v };
        return 0;
    }

    template<class T>
        requires
            requires {
                typename T::value_type;
            }
    int _set(uni::internal::resolving_rank<0>, T& val) noexcept(NO_EXCEPT) {
        typename T::value_type v; *this >> v;
        val = { v };
        return 0;
    }

  protected:
    template<class T>
    source_type *set(T& val) noexcept(NO_EXCEPT) {
        this->_set(uni::internal::resolving_rank<10>{}, val);
        return this->in;
    }

    template<class T>
    source_type *set(T&& _val) noexcept(NO_EXCEPT) {
        T val = _val;
        this->_set(uni::internal::resolving_rank<10>{}, val);
        return this->in;
    }

  public:
    using char_type = typename source_type::char_type;

    source_type *in;

    input_adaptor(source_type *_in = &std::cin) noexcept(NO_EXCEPT) : in(_in) {}

    template<class T>
    inline input_adaptor& operator>>(T&& s) noexcept(NO_EXCEPT) {
        this->set(std::forward<T>(s));
        return *this;
    }

    template<class T>
    inline T one() noexcept(NO_EXCEPT) {
        T val; *this >> val;
        return val;
    }

    template<class T>
    inline auto& operator()(T& val) noexcept(NO_EXCEPT) {
        *this >> val;
        return *this;
    }

    template<class T, class... Args>
    inline auto& operator()(T& head, Args&... tail) noexcept(NO_EXCEPT) {
        *this >> head;
        this->operator()(tail...);
        return *this;
    }

    template<std::input_or_output_iterator I, std::sentinel_for<I> S>
    inline auto& operator()(I first, S last) noexcept(NO_EXCEPT) {
        for(I itr=first; itr!=last; ++itr) *this >> *itr;
        return *this;
    }

    explicit operator bool() const noexcept(NO_EXCEPT) { return (bool)*this->in; }
};


} // namespace uni
#line 2 "adaptor/internal/output.hpp"


#line 11 "adaptor/internal/output.hpp"


#line 15 "adaptor/internal/output.hpp"


namespace uni {


template<class Destination = std::ostream>
struct output_adaptor {
    using destination_type = Destination;

  private:
    template<class T>
        requires
            requires (destination_type& out, T val) {
                out << val;
            }
    int _put(uni::internal::resolving_rank<5>, T&& val) noexcept(NO_EXCEPT) {
        *this->out << std::forward<T>(val);
        return 0;
    }

    template<class T>
        requires
            requires (T&& val) {
                val.val();
            }
    int _put(uni::internal::resolving_rank<4>, T&& val) noexcept(NO_EXCEPT) {
        this->put(val.val());
        return 0;
    }

    template<std::ranges::input_range T>
    int _put(uni::internal::resolving_rank<3>, T&& val) noexcept(NO_EXCEPT) {
        (*this)(std::ranges::begin(val), std::ranges::end(val), false);
        return 0;
    }

    template<class T>
        requires
            requires (T&& val) {
                val.first;
                val.second;
            }
    int _put(uni::internal::resolving_rank<2>, T&& val) noexcept(NO_EXCEPT) {
        *this << val.first, this->put_separator();
        *this << val.second;
        return 0;
    }

    template<class T>
        requires
            requires (T&& val) {
                std::get<0>(val);
            }
    auto _put(uni::internal::resolving_rank<1>, T&& val) noexcept(NO_EXCEPT) {
        std::apply([this](const auto&... args) constexpr { ((*this << args, this->put_separator()), ...); }, std::forward<T>(val));
        return 0;
    }

    template<std::input_or_output_iterator T>
    int _put(uni::internal::resolving_rank<0>, T&& val) noexcept(NO_EXCEPT) {
        (*this)(*std::forward<T>(val));
        return 0;
    }


  protected:
    template<class T>
    destination_type* put(T&& val) noexcept(NO_EXCEPT){
        this->_put(uni::internal::resolving_rank<10>{}, std::forward<T>(val));
        return this->out;
    }

  public:
    using char_type = typename destination_type::char_type;

    static constexpr auto sendl = std::endl<char_type,std::char_traits<char_type>>;
    static constexpr auto sflush = std::flush<char_type,std::char_traits<char_type>>;

  protected:
    using sfunc_type = std::remove_const_t<decltype(output_adaptor::sendl)>;

  public:
    using separator_type = std::variant<std::string,sfunc_type>;

    destination_type *out;
    separator_type endline;
    separator_type separator;

  protected:
    void put_separator() noexcept(NO_EXCEPT) {
        if(this->separator.index() == 0) *this->out << std::get<std::string>(this->separator);
        if(this->separator.index() == 1) *this->out << std::get<sfunc_type>(this->separator);
    }
    void put_endline() noexcept(NO_EXCEPT) {
        if(this->endline.index() == 0) *this->out << std::get<std::string>(this->endline);
        if(this->endline.index() == 1) *this->out << std::get<sfunc_type>(this->endline);
    }

  public:
    template<class Terminator = std::string, class Separator = std::string>
    output_adaptor(destination_type *des = &std::cout, Terminator endl = "\n", Separator sep = " ") noexcept(NO_EXCEPT)
      : out(des), endline(endl), separator(sep)
    {
        *this << std::fixed << std::setprecision(20);
    }

    inline auto& seekp(const typename destination_type::off_type off, const std::ios_base::seekdir dir = std::ios_base::cur) noexcept(NO_EXCEPT) {
        this->out->seekp(off, dir); return *this;
    };

    template<class T> inline output_adaptor& operator<<(T&& s) noexcept(NO_EXCEPT){
        this->put(std::forward<T>(s));
        return *this;
    }

    template<class T = std::string>
    inline auto& operator()(T&& val = "") noexcept(NO_EXCEPT){
        *this << std::forward<T>(val), this->put_endline();
        return *this;
    }

    template<class T, class ...Args>
    inline auto& operator()(T&& head, Args&& ...tail) noexcept(NO_EXCEPT){
        *this << std::forward<T>(head), this->put_separator();
        (*this)(std::forward<Args>(tail)...);
        return *this;
    }

    template<std::forward_iterator I, std::sentinel_for<I> S>
    inline auto& operator()(I first, S last, const bool terminate = true) noexcept(NO_EXCEPT) {
        for(I itr=first; itr!=last;) {
            *this << *itr;
            if(++itr == last) {
                if(terminate) this->put_endline();
            }
            else this->put_separator();
        }

        return *this;
    }

    template<class T>
    inline auto& operator()(const std::initializer_list<T> vals) noexcept(NO_EXCEPT) {
        std::vector wrapped(vals.begin(), vals.end());
        (*this)(wrapped.begin(), wrapped.end());
        return *this;
    }

    template<class T0, class T1>
    inline auto& conditional(const bool cond, const T0& a, const T1& b) noexcept(NO_EXCEPT) {
        if(cond) (*this)(a);
        else (*this)(b);
        return *this;
    }

    inline auto& yesno(const bool cond) noexcept(NO_EXCEPT) {
        if(cond) this->yes();
        else this->no();
        return *this;
    }

    inline auto yes() noexcept(NO_EXCEPT) {
        *this->out << "Yes";
        this->put_endline();
        return *this;
    }

    inline auto no() noexcept(NO_EXCEPT) {
        *this->out << "No";
        this->put_endline();
        return *this;
    }


    inline auto flush() noexcept(NO_EXCEPT) {
        *this->out << std::flush;
        return *this;
    }
};


} // namespace uni
#line 7 "adaptor/io.hpp"


namespace uni {


uni::input_adaptor _input;
uni::output_adaptor _print;


}


#define input uni::_input
#define print uni::_print
#line 2 "adaptor/multi_container.hpp"


#line 7 "adaptor/multi_container.hpp"

#line 9 "adaptor/multi_container.hpp"


#line 12 "adaptor/multi_container.hpp"

#line 15 "adaptor/multi_container.hpp"

#line 18 "adaptor/multi_container.hpp"


namespace uni {

namespace internal {

namespace multi_container_impl {


template<class Holder> struct base : Holder {
    using Holder::Holder;

  protected:
    template<std::integral T>
    constexpr auto _positivize_index(const T _x) const noexcept(NO_EXCEPT) {
        auto x = static_cast<internal::size_t>(_x);
        return x < 0 ? this->size() + x : x;
    }
};


} // namespace multi_contatiner_impl

} // namespace internal


template<class T, unsigned int RANK, template<class...> class Holder = vector, template<class...> class Container = vector>
struct multi_container : internal::multi_container_impl::base<Holder<multi_container<T, RANK - 1, Holder, Container>>> {
  private:
    using base = internal::multi_container_impl::base<Holder<multi_container<T, RANK - 1, Holder, Container>>>;

  public:
    using base::base;

    template<std::integral Head, class... Tail>
    constexpr multi_container(const Head head, Tail&&... tail) noexcept(NO_EXCEPT)
      : base(head, multi_container<T, RANK - 1, Holder, Container>(std::forward<Tail>(tail)...))
    {
        assert(head >= 0);
    }

    template<std::integral Head, class... Tail>
    constexpr T& operator()(Head _head, Tail&&... tail) noexcept(NO_EXCEPT) {
        static_assert(std::is_integral_v<Head>, "index must be integral");

        const auto index = this->_positivize_index(_head);
        assert(0 <= index && index < std::ranges::ssize(*this));

        return (*this)[index](std::forward<Tail>(tail)...);
    }

    template<std::integral Head, class... Tail>
    constexpr  T& operator()(Head _head, Tail&&... tail) const noexcept(NO_EXCEPT) {
        static_assert(std::is_integral_v<Head>, "index must be integral");

        const auto index = this->_positivize_index(_head);
        assert(0 <= index && index < std::ranges::ssize(*this));

        return (*this)[index](std::forward<Tail>(tail)...);
    }
};

template<class T, template<class...> class Holder, template<class...> class Container>
struct multi_container<T, 1, Holder, Container> : internal::multi_container_impl::base<Container<T>> {
    using internal::multi_container_impl::base<Container<T>>::base;

    template<class... Args>
    constexpr multi_container(const Args&... args) noexcept(NO_EXCEPT) : internal::multi_container_impl::base<Container<T>>(args...)
    {}

    template<class Index>
    constexpr T& operator()(Index&& _index) noexcept(NO_EXCEPT) {
        const auto index = this->_positivize_index(std::forward<T>(_index));
        assert(0 <= index && index < std::ranges::ssize(*this));

        return (*this)[index];
    }

    template<class Index>
    constexpr T& operator()(Index&& _index) const noexcept(NO_EXCEPT) {
        const auto index = this->_positivize_index(std::forward<T>(_index));
        assert(0 <= index && index < std::ranges::ssize(*this));

        return (*this)[index];
    }
};


template<class T, template<class...> class Holder, template<class...> class Container>
struct multi_container<T, 0, Holder, Container> {
    static_assert(internal::EXCEPTION_ON_TYPE<T>, "invalid rank: 0, should be 1 or more");
};


} // namespace uni
#line 2 "adaptor/queue_by_stack.hpp"


#line 6 "adaptor/queue_by_stack.hpp"


#line 9 "adaptor/queue_by_stack.hpp"


namespace uni {


template<class In, class Out = In>
struct queue_by_stack {
    static_assert(std::same_as<typename In::value_type, typename Out::value_type>);
    static_assert(std::common_reference_with<typename In::size_type, typename Out::size_type>);

    using value_type = In::value_type;
    using size_type = std::common_type_t<typename In::size_type, typename Out::size_type>;

  protected:
    In _in;
    Out _out;

  private:
    inline void _shift() noexcept(NO_EXCEPT) {
        if(!this->_out.empty()) return;

        while(!this->_in.empty()) {
            this->_out.push(this->_in.top());
            this->_in.pop();
        }
    }

  public:
    queue_by_stack() noexcept = default;

    inline bool empty() const noexcept(NO_EXCEPT) {
        return this->_in.empty() && this->_out.empty();
    }

    inline auto size() const noexcept(NO_EXCEPT) {
        return this->_in.size() + this->_out.size();
    }


    inline decltype(auto) front() noexcept(NO_EXCEPT) {
        this->_shift();
        assert(!this->_out.empty());
        return this->_out.top();
    }

    template<std::convertible_to<value_type> T = value_type>
        requires std::is_move_constructible_v<T>
    inline decltype(auto) front_or(T&& val) const noexcept(NO_EXCEPT) {
        if(this->empty()) return static_cast<value_type>(std::forward<T>(val));
        else return this->front();
    }


    inline auto& clear() noexcept(NO_EXCEPT) {
        this->_in.clear(), this->_out.clear();
        return *this;
    }


    template<std::convertible_to<value_type> T = value_type>
    inline auto& push(T&& val) noexcept(NO_EXCEPT) {
        this->_in.push(std::forward<T>(val));
        return *this;
    }

    template<class... Args>
    inline decltype(auto) emplace(Args&&... args) noexcept(NO_EXCEPT) {
        return this->_in.emplace(std::forward<Args>(args)...);
    }


    auto& pop() noexcept(NO_EXCEPT) {
        this->_shift();
        assert(!this->_out.empty());

        this->_out.pop();
        return *this;
    }
};



} // namespace uni
#line 2 "adaptor/range_extractor.hpp"


#line 7 "adaptor/range_extractor.hpp"


#line 10 "adaptor/range_extractor.hpp"


namespace uni {


template<class Container>
struct range_extractor : Container {
    using size_type = typename Container::size_type;
    using value_type = typename Container::value_type;

  protected:
    using default_func_noarg_type = std::function<value_type(void)>;
    using default_func_type = std::function<value_type(size_type)>;

    size_type _begin = 0;
    size_type _end;

    int _default_type = 0;
    value_type _default_val = value_type();
    default_func_noarg_type _default_func_noarg;
    default_func_type _default_func;
    inline static value_type _tmp;

    inline value_type _get_default(const size_type key) const noexcept(NO_EXCEPT) {
        if(this->_default_type == 0) return this->_default_val;
        if(this->_default_type == 1) return this->_default_func_noarg();
        if(this->_default_type == 2) return this->_default_func(key);
        else assert(false);
    }

  public:
    template<class... Args>
    explicit range_extractor(Args&&... args) noexcept(NO_EXCEPT) : Container(std::forward<Args>(args)...) {
        this->_begin = 0;
        this->_end = this->size();
    }

    inline auto& extract(const size_type begin, const size_type end) noexcept(NO_EXCEPT) {
        assert(begin <= end);
        this->_begin = begin, this->_end = end;
        return *this;
    }


    inline auto& set_default(const value_type& val) noexcept(NO_EXCEPT) {
        this->_default_val = val;
        this->_default_type = 0;
        return *this;
    }

    inline auto& set_default(const default_func_noarg_type func) noexcept(NO_EXCEPT) {
        this->_default_func_noarg = func;
        this->_default_type = 1;
        return *this;
    }

    inline auto& set_default(const default_func_type func) noexcept(NO_EXCEPT) {
        this->_default_func = func;
        this->_default_type = 2;
        return *this;
    }


    inline auto& operator[](const size_type pos) noexcept(NO_EXCEPT) {
        if(pos < this->_begin or this->_end <= pos) return range_extractor::_tmp = this->_get_default(pos);
        return this->Container::operator[](pos);
    }

    inline const auto& operator[](const size_type pos) const noexcept(NO_EXCEPT) {
        if(pos < this->_begin or this->_end <= pos) return range_extractor::_tmp = this->_get_default(pos);
        return this->Container::operator[](pos);
    }

    inline auto& operator()(const size_type pos) noexcept(NO_EXCEPT) {
        return this->Container::operator[](pos);
    }

    inline const auto& operator()(const size_type pos) const noexcept(NO_EXCEPT) {
        return this->Container::operator[](pos);
    }

    inline std::optional<value_type> get(const size_type pos) const noexcept(NO_EXCEPT) {
        if(pos < this->_begin or this->_end <= pos) return {};
        return this->Container::operator[](pos);
    }
};


}
#line 2 "adaptor/stack.hpp"


#line 6 "adaptor/stack.hpp"


namespace uni {


template<class T, class Allocator = std::allocator<T>>
using stack = std::stack<T, std::vector<T, Allocator>>;


} // namespace uni
#line 2 "adaptor/virtual_map.hpp"

#line 5 "adaptor/virtual_map.hpp"

#line 7 "adaptor/virtual_map.hpp"


namespace uni {


template<class> struct virtual_combined_map {};

template<class Mapped, class... Keys>
struct virtual_combined_map<Mapped(Keys...)> {
    using key_type = std::tuple<Keys...>;
    using mapped_type = Mapped;
    using value_type = std::pair<key_type,mapped_type>;

  protected:
    std::function<Mapped(Keys...)> _f;

  public:
    virtual_combined_map() = default;

    template<class F>
    explicit virtual_combined_map(F&& f) noexcept(NO_EXCEPT) : _f(f) {};

    inline const auto* get_functor() const noexcept(NO_EXCEPT) { return this->_f; }
    inline auto* get_functor() noexcept(NO_EXCEPT) { return this->_f; }

    template<class F>
    inline auto& set_functor(F&& f) const noexcept(NO_EXCEPT) { return this->_f = f; }

    inline mapped_type operator()(const Keys&... key) const noexcept(NO_EXCEPT) {
        return this->_f(key...);
    }

    inline mapped_type operator[](const key_type& key) const noexcept(NO_EXCEPT) {
        return std::apply(this->_f, key);
    }
};

template<class Key, class Mapped>
struct virtual_map : virtual_combined_map<Mapped(Key)> {
    using key_type = Key;
    using mapped_type = Mapped;
    using value_type = std::pair<key_type,mapped_type>;

    using virtual_combined_map<mapped_type(key_type)>::virtual_combined_map;

    inline mapped_type operator[](const key_type& key) const noexcept(NO_EXCEPT) {
        return this->_f(key);
    }
};

}; // namesapce uni
#line 2 "include/algebraic.hpp"

#line 2 "algebraic/bit_and.hpp"

#line 6 "algebraic/bit_and.hpp"

namespace uni {

namespace algebraic {


template<class T>
struct bit_and : base<T>, associative, scalar_multipliable<bit_and<T>>::identity, commutative {
    using base<T>::base;

    bit_and() noexcept(NO_EXCEPT) : base<T>(uni::numeric_limits<T>::max()) {};

    friend inline bit_and operator+(const bit_and& lhs, const bit_and& rhs) noexcept(NO_EXCEPT) {
        return lhs.val() bitand rhs.val();
    }
};


} // namespace algebraic

} // namespace uni
#line 2 "algebraic/bit_or.hpp"

#line 5 "algebraic/bit_or.hpp"

namespace uni {

namespace algebraic {


template<class T>
struct bit_or : base<T>, scalar_multipliable<bit_or<T>>::identity, associative, commutative {
    using base<T>::base;

    friend inline bit_or operator+(const bit_or& lhs, const bit_or& rhs) noexcept(NO_EXCEPT) {
        return lhs.val() bitor rhs.val();
    }
};


} // namespace algebraic

} // namespace uni
#line 2 "algebraic/combined.hpp"


#line 6 "algebraic/combined.hpp"


#line 9 "algebraic/combined.hpp"

#line 12 "algebraic/combined.hpp"


namespace uni {

namespace algebraic {


template<
    internal::magma M0,
    internal::magma M1
>
struct combined
  : base<std::pair<M0, M1>>,
    std::conditional_t<internal::associative<M0> && internal::associative<M1>, associative, uni::internal::dummy>,
    std::conditional_t<internal::commutative<M0> && internal::commutative<M1>, commutative, uni::internal::dummy>
{
    using base<std::pair<M0, M1>>::base;


    template<class T>
        requires std::convertible_to<T, M0> && std::convertible_to<T, M1>
    combined(const T& v) : combined(v, v) {};


    friend inline combined operator+(const combined& lhs, const combined& rhs) noexcept(NO_EXCEPT) {
        return { lhs->first + rhs->first, lhs->second + rhs->second };
    }


    template<std::integral Scalar>
    friend inline combined&& operator*(const Scalar k, const combined& val) noexcept(NO_EXCEPT) {
        return { k * val->first, k * val->second };
    }


    friend inline combined operator-(const combined& val) noexcept(NO_EXCEPT)
        requires internal::invertible<M0> && internal::invertible<M1>
    {
        return { -val->first, -val->second };
    }
};


} // namespace algebraic

} // namespace uni
#line 2 "algebraic/opposite.hpp"


#line 6 "algebraic/opposite.hpp"


#line 9 "algebraic/opposite.hpp"

#line 12 "algebraic/opposite.hpp"


namespace uni {

namespace algebraic {


template<internal::magma M>
struct opposite
  :
    std::conditional_t<internal::associative<M>, associative, uni::internal::dummy>,
    std::conditional_t<internal::commutative<M>, commutative, uni::internal::dummy>
{
    using value_type = M::value_type;

  private:
    M _value;

  public:
    template<std::convertible_to<M> T>
    opposite(const T& v) : _value(v) {};


    template<class... Args>
        requires std::constructible_from<value_type, Args...>
    opposite(Args&&... args) noexcept(NO_EXCEPT) : _value(std::forward<Args>(args)...) {}


    inline explicit operator value_type() const noexcept(NO_EXCEPT) { return this->_value.val(); }
    inline auto val() const noexcept(NO_EXCEPT) { return this->_value.val(); };

    inline const value_type* operator->() const noexcept(NO_EXCEPT) { return this->_value.operator->(); };
    inline value_type* operator->() noexcept(NO_EXCEPT) { return this->_value.operator->(); };


    friend inline auto operator<=>(const opposite& lhs, const opposite& rhs) noexcept(NO_EXCEPT) {
        return lhs._value <=> rhs._value;
    };

    friend inline bool operator==(const opposite& lhs, const opposite& rhs) noexcept(NO_EXCEPT) {
        return lhs._value == rhs._value;
    }


    friend inline opposite operator+(const opposite& lhs, const opposite& rhs) noexcept(NO_EXCEPT) {
        return rhs._value + lhs._value;
    }


    friend inline opposite operator-(const opposite& val) noexcept(NO_EXCEPT)
        requires internal::invertible<M>
    {
        return -val._value;
    }
};



template<internal::magma M>
struct make_opposite;


template<internal::magma M>
struct make_opposite<opposite<M>> {
    using type = M;
};

template<internal::magma M>
    requires internal::commutative<M>
struct make_opposite<M> {
    using type = M;
};


template<internal::magma M>
    requires (!internal::commutative<M>)
struct make_opposite<M> {
    using type = opposite<M>;
};


template<internal::magma M>
using make_opposite_t = make_opposite<M>::type;


} // namespace algebraic

} // namespace uni
#line 2 "include/convolutions.hpp"

#line 2 "convolution/gcd.hpp"


#line 6 "convolution/gcd.hpp"


#line 9 "convolution/gcd.hpp"

#line 2 "numeric/divisor_multiple_transform.hpp"


#line 5 "numeric/divisor_multiple_transform.hpp"

#line 2 "numeric/prime_enumerator.hpp"


#line 10 "numeric/prime_enumerator.hpp"


#line 13 "numeric/prime_enumerator.hpp"

#line 15 "numeric/prime_enumerator.hpp"

#line 18 "numeric/prime_enumerator.hpp"

#line 22 "numeric/prime_enumerator.hpp"


namespace uni {


// Thanks to: https://qiita.com/peria/items/e0ab38f95d16a5f7cc58

template<class T>
struct prime_enumerator : std::ranges::view_interface<prime_enumerator<T>> {
    using value_type = T;
    using size_type = internal::size_t;

  protected:
    using impl_type = std::uint32_t;
    impl_type _n = 0;

    using small_bit_type = std::uint8_t;
    using large_bit_type = std::uint64_t;


    static constexpr impl_type SEGMENT_SIZE = 1'000'000;

    static constexpr impl_type  MOD30[8] = { 1, 7, 11, 13, 17, 19, 23, 29 };

    static constexpr small_bit_type MASK[8][8] = {
        { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f },
        { 0xfd, 0xdf, 0xef, 0xfe, 0x7f, 0xf7, 0xfb, 0xbf },
        { 0xfb, 0xef, 0xfe, 0xbf, 0xfd, 0x7f, 0xf7, 0xdf },
        { 0xf7, 0xfe, 0xbf, 0xdf, 0xfb, 0xfd, 0x7f, 0xef },
        { 0xef, 0x7f, 0xfd, 0xfb, 0xdf, 0xbf, 0xfe, 0xf7 },
        { 0xdf, 0xf7, 0x7f, 0xfd, 0xbf, 0xfe, 0xef, 0xfb },
        { 0xbf, 0xfb, 0xf7, 0x7f, 0xfe, 0xef, 0xdf, 0xfd },
        { 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe },
    };

    static constexpr impl_type C1[8] = { 6, 4, 2, 4, 2, 4, 6, 2 };
    static constexpr impl_type C0[8][8] = {
        { 0, 0, 0, 0, 0, 0, 0, 1 }, { 1, 1, 1, 0, 1, 1, 1, 1 },
        { 2, 2, 0, 2, 0, 2, 2, 1 }, { 3, 1, 1, 2, 1, 1, 3, 1 },
        { 3, 3, 1, 2, 1, 3, 3, 1 }, { 4, 2, 2, 2, 2, 2, 4, 1 },
        { 5, 3, 1, 4, 1, 3, 5, 1 }, { 6, 4, 2, 4, 2, 4, 6, 1 },
    };

    size_type _size;

    impl_type _sqrt_n = 0, _sqrt_ni = 0, _quart_n = 0;

    std::valarray<small_bit_type> _small;
    std::valarray<large_bit_type> _large;
    std::vector<impl_type> _indecies;

    small_bit_type* _flag = nullptr;

    inline void _init(const value_type n, const impl_type size) noexcept(NO_EXCEPT) {
        const size_type blocks = (size + 7) >> 3;
        this->_large.resize(blocks + 1, ~0UL);
        this->_flag = reinterpret_cast<small_bit_type*>(&(this->_large[0]));

        this->_flag[0] = 0xfe;

        value_type r = n % 30;
        if(r <= 1) this->_flag[size - 1] = 0x0;
        else if(r <= 7) this->_flag[size - 1] = 0x1;
        else if(r <= 11) this->_flag[size - 1] = 0x3;
        else if(r <= 13) this->_flag[size - 1] = 0x7;
        else if(r <= 17) this->_flag[size - 1] = 0xf;
        else if(r <= 19) this->_flag[size - 1] = 0x1f;
        else if(r <= 23) this->_flag[size - 1] = 0x3f;
        else if(r <= 29) this->_flag[size - 1] = 0x7f;

        if(n < 30) this->_flag[0] &= 0xfe;

        this->_large[blocks - 1] <<= 64 - ((size & 7) << 3);
        this->_large[blocks - 1] >>= 64 - ((size & 7) << 3);
        this->_large[blocks] = 0;

        // for(auto x : this->_large) debug(std::bitset<64>(x));
    }

    inline void _gen_small() noexcept(NO_EXCEPT) {
        const impl_type quart_ni = this->_quart_n / 30 + 1;

        this->_small.resize(this->_sqrt_ni, 0xff);
        this->_small[0] = 0xfe;

        REP(i, quart_ni) {
            for(small_bit_type flags = this->_small[i]; flags; flags &= flags - 1) {
                const int ibit = lowest_bit_pos(flags);
                const impl_type m = prime_enumerator::MOD30[ibit];
                const impl_type pm = 30 * i + 2 * m;
                for(
                    impl_type j = i * pm + (m * m) / 30, k = ibit;
                    j < this->_sqrt_ni;
                    j += i * prime_enumerator::C1[k] + prime_enumerator::C0[ibit][k], k = (k + 1) & 7
                ) {
                    this->_small[j] &= prime_enumerator::MASK[ibit][k];
                }
            }
        }

        REP(i, this->_sqrt_ni) {
            for(small_bit_type flags = this->_small[i]; flags; flags &= flags - 1) {
                const int ibit = lowest_bit_pos(flags);
                const impl_type m = prime_enumerator::MOD30[ibit];
                impl_type j = i * (30 * i + 2 * m) + (m * m) / 30;
                this->_indecies.emplace_back(((j + prime_enumerator::SEGMENT_SIZE) << 3) | ibit);
            }
        }
    }

    inline void _gen_core(small_bit_type *const flags, const impl_type size) noexcept(NO_EXCEPT) {
        auto p_index = this->_indecies.begin();
        REP(i, this->_sqrt_ni) {
            for(small_bit_type primes = this->_small[i]; primes; primes &= primes - 1) {
                const int ibit = lowest_bit_pos(primes);
                impl_type j = (*p_index >> 3) - prime_enumerator::SEGMENT_SIZE;
                impl_type k = *p_index & 7;
                for(; j < size; j += i * prime_enumerator::C1[k] + prime_enumerator::C0[ibit][k], k = (k + 1) & 7) {
                    flags[j] &= prime_enumerator::MASK[ibit][k];
                }
                *p_index = ((j << 3) | k);
                ++p_index;
            }
        }
    }

    using iterator_interface = internal::bidirectional_iterator_interface<const value_type>;

  public:
    struct iterator;
    using const_iterator = iterator;

    prime_enumerator() noexcept {};

    prime_enumerator(const value_type n) noexcept(NO_EXCEPT) : _n(n) {
        assert(n >= 0);
        assert(std::endian::native == std::endian::little);

        this->_sqrt_n = static_cast<impl_type>(sqrt_ceil(this->_n + 1));
        this->_sqrt_ni = this->_sqrt_n / 30 + 1;
        this->_quart_n = static_cast<impl_type>(sqrt_ceil(this->_sqrt_n));

        this->_gen_small();

        impl_type size = (this->_n + 1) / 30 + 1;
        this->_init(this->_n + 1, size);

        for(small_bit_type* seg = this->_flag; ; seg += prime_enumerator::SEGMENT_SIZE) {
            if(size < prime_enumerator::SEGMENT_SIZE) {
                this->_gen_core(seg, size);
                break;
            };
            this->_gen_core(seg, prime_enumerator::SEGMENT_SIZE);
            size -= prime_enumerator::SEGMENT_SIZE;
        }

        this->_size = (this->_n >= 2) + (this->_n >= 3) + (this->_n >= 5);
        for(const large_bit_type f : this->_large) this->_size += std::popcount(f);
    }

    inline size_type size() const noexcept(NO_EXCEPT) { return this->_size; }

    inline size_type count(const T x) const noexcept(NO_EXCEPT) {
        assert(0 <= x and x <= this->_n);

        size_type res = (x >= 2) + (x >= 3) + (x >= 5);
        T count = 0;

        constexpr int large_bit_width = std::numeric_limits<large_bit_type>::digits;
        constexpr int large_bit_size = (30 * large_bit_width) >> 3;

        for(const large_bit_type f : this->_large) {
            if(count + large_bit_size > x) {
                REP(i, large_bit_width) {
                    if(count + prime_enumerator::MOD30[i & 7] > x) break;
                    if((f >> i) & 1) res++;
                    if(((i + 1) & 7) == 0) count += 30;
                }
                break;
            }
            res += std::popcount(f);
            count += large_bit_size;
        }

        return res;
    }

    inline size_type count(const T l, const T r) const noexcept(NO_EXCEPT) {
        assert(l <= r);
        return this->count(r) - this->count(l - 1);
    }

    inline bool is_prime(const T v) const noexcept(NO_EXCEPT) {
        assert(0 <= v and v <= this->_n);

        if(v == 0 or v == 1) return false;
        if(v == 2 or v == 3 or v == 5) return true;
        if((v & 1) == 0 or v % 3 == 0 or v % 5 == 0) return false;

        REP(i, 8) {
            if(prime_enumerator::MOD30[i] == v % 30) {
                return static_cast<bool>((this->_flag[v / 30] >> i) & 1);
            }
        }

        assert(false);
    }

    inline auto begin() const noexcept(NO_EXCEPT) { return iterator(this, 0); }
    inline auto end() const noexcept(NO_EXCEPT) { return iterator(this, -1); }

    inline auto rbegin() const noexcept(NO_EXCEPT) { return std::make_reverse_iterator(this->end()); }
    inline auto rend() const noexcept(NO_EXCEPT) { return std::make_reverse_iterator(this->begin()); }

    struct iterator : iterator_interface {
      protected:
        value_type _n = 0;
        size_type _index = 0;
        const std::valarray<large_bit_type>* _flags = nullptr;
        size_type _block = -1, _flag_size;
        int _bit = 0;

        inline value_type _value() const noexcept(NO_EXCEPT) {
            if(this->_bit < 0) return numeric_limits<value_type>::arithmetic_infinity();
            if(this->_block < 0) {
                if(this->_bit == 0) return 2;
                if(this->_bit == 1) return 3;
                if(this->_bit == 2) return 5;
            }
            return (
                value_type{30} * ((this->_block << 3) + (this->_bit >> 3)) +
                prime_enumerator::MOD30[this->_bit & 7]
            );
        }

      public:
        iterator() noexcept = default;
        iterator(const prime_enumerator *const super, const int bit) noexcept(NO_EXCEPT)
          : _n(super->_n), _flags(&super->_large), _flag_size(static_cast<size_type>(super->_large.size())), _bit(bit) {
            if(bit < 0) {
                this->_index = super->size();
                this->_block = static_cast<size_type>(super->_large.size()) - 1;
            }
        }

        inline size_type index() const noexcept(NO_EXCEPT) { return this->_index; }

        inline value_type operator*() const noexcept(NO_EXCEPT) {
            const value_type res = this->_value();
            return (res > this->_n ? -1 : res);
        }

        inline iterator& operator++() noexcept(NO_EXCEPT) {
            if(this->_value() > this->_n) return *this;
            ++this->_index;

            if(this->_block < 0) {
                ++this->_bit;
                if(this->_bit > 2) this->_block = 0, this->_bit = 1;
                return *this;
            }

            int next;
            while(true) {
                const large_bit_type mask = this->_bit >= 63 ? 0UL : ~((1UL << (this->_bit + 1)) - 1);
                next = lowest_bit_pos(this->_flags->operator[](this->_block) & mask);
                if(next >= 0) break;
                this->_block++;
                this->_bit = -1;
                if(this->_block >= this->_flag_size) break;
            }
            this->_bit = next;

            return *this;
        }

        inline iterator& operator--() noexcept(NO_EXCEPT) {
            if(this->_block < 0) {
                if(this->_bit > 0) --this->_bit, --this->_index;
                return *this;
            }
            --this->_index;

            int prev = -1;
            while(true) {
                if(0 < this->_bit) {
                    const large_bit_type mask = this->_bit >= 64 ? ~0UL : ((1UL << this->_bit) - 1);
                    prev = highest_bit_pos(this->_flags->operator[](this->_block) & mask);
                }
                if(prev >= 0) break;
                --this->_block;
                this->_bit = 64;
                if(this->_block < 0) {
                    this->_bit = (this->_n >= 3) + (this->_n >= 5);
                    return *this;
                }
            }

            this->_bit = prev;

            return *this;
        }

        inline iterator operator++(int) noexcept(NO_EXCEPT) { const auto res = *this; ++(*this); return res; }
        inline iterator operator--(int) noexcept(NO_EXCEPT) { const auto res = *this; --(*this); return res; }

        friend inline bool operator==(const iterator& lhs, const iterator& rhs) noexcept(NO_EXCEPT) { return lhs._index == rhs._index; }
        friend inline auto operator<=>(const iterator& lhs, const iterator& rhs) noexcept(NO_EXCEPT) { return lhs._index <=> rhs._index; }
        friend inline auto operator-(const iterator& lhs, const iterator& rhs) { return lhs._index - rhs._index; }
    };
};


} // namespace uni


namespace std::ranges {

template<class T>
inline constexpr bool enable_borrowed_range<uni::prime_enumerator<T>> = true;

} // namespace std::ranges
#line 10 "numeric/divisor_multiple_transform.hpp"


// Thanks to: https://nyaannyaan.github.io/library/multiplicative-function/divisor-multiple-transform.hpp.html
namespace uni {

namespace divisor_transform {


using size_type = internal::size_t;


template<std::size_t OFFSET, std::ranges::sized_range R>
    requires (!requires { typename R::mapped_type; })
auto zeta(R&& range) noexcept(NO_EXCEPT) {
    const auto n = std::ranges::ssize(range) + OFFSET - 1;
    ITR(p, uni::prime_enumerator(n)) {
        for(size_type k=1; k*p <= n; ++k) range[k*p - OFFSET] += range[k - OFFSET];
    }
}

template<std::size_t OFFSET, std::ranges::sized_range R>
    requires (!requires { typename R::mapped_type; })
auto mobius(R&& range) noexcept(NO_EXCEPT) {
    const auto n = std::ranges::ssize(range) + OFFSET - 1;
    ITR(p, uni::prime_enumerator(n)) {
        for(size_type k=n/p; k>0; --k) range[k*p - OFFSET] -= range[k - OFFSET];
    }
}


template<std::ranges::sized_range R>
auto zeta(R&& range) noexcept(NO_EXCEPT) { return zeta<0>(range); }

template<std::ranges::sized_range R>
auto mobius(R&& range) noexcept(NO_EXCEPT) { return mobius<0>(range); }


template<std::ranges::input_range R>
    requires requires { typename R::mapped_type; }
auto zeta(R&& range) noexcept(NO_EXCEPT) {
    auto begin = std::ranges::begin(range);
    auto end = std::ranges::end(range);
    for(auto itr1 = end; itr1-- != begin; ) {
        for(auto itr2 = begin; itr2 != end; ++itr2) {
            if(itr1->first == itr2->first) break;
            if(itr1->first % itr2->first == 0) itr1->second += itr2->second;
        }
    }
}

template<std::ranges::input_range R>
    requires requires { typename R::mapped_type; }
auto mobius(R&& range) noexcept(NO_EXCEPT) {
    auto begin = std::ranges::begin(range);
    auto end = std::ranges::end(range);
    for(auto itr2 = begin; itr2 != end; ++itr2) {
        for(auto itr1 = end; (itr1--) != begin; ) {
            if(itr1->first == itr2->first) break;
            if(itr1->first % itr2->first == 0) itr1->second -= itr2->second;
        }
    }
}


} // namespace divisor_transform


namespace multiple_transform  {


using size_type = internal::size_t;


template<std::size_t OFFSET, std::ranges::sized_range R>
    requires (!requires { typename R::mapped_type; })
auto zeta(R&& range) noexcept(NO_EXCEPT) {
    const auto n = std::ranges::ssize(range) + OFFSET - 1;
    ITR(p, uni::prime_enumerator(n)) {
        for(size_type k=n/p; k>0; --k) range[k - OFFSET] += range[k*p - OFFSET];
    }
}

template<std::size_t OFFSET, std::ranges::sized_range R>
    requires (!requires { typename R::mapped_type; })
auto mobius(R&& range) noexcept(NO_EXCEPT) {
    const auto n = std::ranges::ssize(range) + OFFSET - 1;
    ITR(p, uni::prime_enumerator(n)) {
        for(size_type k=1; k*p <= n; ++k) range[k - OFFSET] -= range[k*p - OFFSET];
    }
}


template<std::ranges::sized_range R>
auto zeta(R&& range) noexcept(NO_EXCEPT) { return zeta<0>(range); }

template<std::ranges::sized_range R>
auto mobius(R&& range) noexcept(NO_EXCEPT) { return mobius<0>(range); }


template<std::ranges::input_range R>
    requires requires { typename R::mapped_type; }
auto zeta(R&& range) noexcept(NO_EXCEPT) {
    auto begin = std::ranges::begin(range);
    auto end = std::ranges::end(range);
    for(auto itr2 = begin; itr2 != end; ++itr2) {
        for(auto itr1 = end; --itr1 != itr2; ) {
            if(itr1->first % itr2->first == 0) itr2->second += itr1->second;
        }
    }
}

template<std::ranges::input_range R>
    requires requires { typename R::mapped_type; }
auto mobius(R&& range) noexcept(NO_EXCEPT) {
    auto begin = std::ranges::begin(range);
    auto end = std::ranges::end(range);
    for(auto itr2 = end; itr2-- != begin; ) {
        for(auto itr1 = end; --itr1 != itr2; ) {
            if(itr1->first % itr2->first == 0) itr2->second -= itr1->second;
        }
    }
}


} // namespace multiple_transform

} // namespace uni
#line 11 "convolution/gcd.hpp"

#line 13 "convolution/gcd.hpp"


namespace uni {


template<std::ranges::range Res, std::size_t OFFSET, std::ranges::sized_range R0, std::ranges::sized_range R1>
Res gcd_convolution(R0 v0, R1 v1) {
    assert(std::ranges::size(v0) == std::ranges::size(v1));

    multiple_transform::zeta<OFFSET>(v0), multiple_transform::zeta<OFFSET>(v1);
    REP(i, std::ranges::size(v0)) v0[i] *= v1[i];
    multiple_transform::mobius<OFFSET>(v0);

    if constexpr(std::convertible_to<R0, Res>) return v0;
    else return Res(ALL(v0));
}


template<std::size_t OFFSET, std::ranges::sized_range R0, std::ranges::sized_range R1>
    requires std::common_with<std::ranges::range_value_t<R0>, std::ranges::range_value_t<R1>>
auto gcd_convolution(R0&& v0, R1&& v1) {
    using common_type = std::common_type_t<std::ranges::range_value_t<R0>, std::ranges::range_value_t<R1>>;
    return gcd_convolution<valarray<common_type>, OFFSET>(v0, v1);
}


template<std::ranges::range Res, std::ranges::sized_range R0, std::ranges::sized_range R1>
    requires std::common_with<std::ranges::range_value_t<R0>, std::ranges::range_value_t<R1>>
auto gcd_convolution(R0&& v0, R1&& v1) { return gcd_convolution<Res, 0>(v0, v1); }


template<std::ranges::sized_range R0, std::ranges::sized_range R1>
    requires std::common_with<std::ranges::range_value_t<R0>, std::ranges::range_value_t<R1>>
auto gcd_convolution(R0&& v0, R1&& v1) { return gcd_convolution<0>(v0, v1); }


} // namespace uni
#line 2 "convolution/lcm.hpp"


#line 6 "convolution/lcm.hpp"


#line 9 "convolution/lcm.hpp"

#line 11 "convolution/lcm.hpp"

#line 13 "convolution/lcm.hpp"


namespace uni {


template<std::ranges::range Res, std::size_t OFFSET, std::ranges::sized_range R0, std::ranges::sized_range R1>
Res lcm_convolution(R0 v0, R1 v1) {
    assert(std::ranges::size(v0) == std::ranges::size(v1));

    divisor_transform::zeta<OFFSET>(v0), divisor_transform::zeta<OFFSET>(v1);
    REP(i, std::ranges::size(v0)) v0[i] *= v1[i];
    divisor_transform::mobius<OFFSET>(v0);

    if constexpr(std::convertible_to<R0, Res>) return v0;
    else return Res(ALL(v0));
}


template<std::size_t OFFSET, std::ranges::sized_range R0, std::ranges::sized_range R1>
    requires std::common_with<std::ranges::range_value_t<R0>, std::ranges::range_value_t<R1>>
auto lcm_convolution(R0&& v0, R1&& v1) {
    using common_type = std::common_type_t<std::ranges::range_value_t<R0>, std::ranges::range_value_t<R1>>;
    return lcm_convolution<valarray<common_type>, OFFSET>(v0, v1);
}


template<std::ranges::range Res, std::ranges::sized_range R0, std::ranges::sized_range R1>
    requires std::common_with<std::ranges::range_value_t<R0>, std::ranges::range_value_t<R1>>
auto lcm_convolution(R0&& v0, R1&& v1) { return lcm_convolution<Res, 0>(v0, v1); }


template<std::ranges::sized_range R0, std::ranges::sized_range R1>
    requires std::common_with<std::ranges::range_value_t<R0>, std::ranges::range_value_t<R1>>
auto lcm_convolution(R0&& v0, R1&& v1) { return lcm_convolution<0>(v0, v1); }


} // namespace uni
#line 2 "convolution/sum.hpp"


#line 7 "convolution/sum.hpp"


#line 2 "convolution/internal/butterfly.hpp"


#line 13 "convolution/internal/butterfly.hpp"


#line 16 "convolution/internal/butterfly.hpp"

#line 19 "convolution/internal/butterfly.hpp"

#line 21 "convolution/internal/butterfly.hpp"

#line 23 "convolution/internal/butterfly.hpp"


namespace uni {

namespace internal {


// Thanks to: atocder/convolution
template<uni::internal::modint_family mint>
struct fft_info {
    static constexpr mint g = primitive_root<mint>(mint::mod());
    static constexpr auto rank2 = std::countr_zero(mint::mod() - 1);

    std::array<mint, rank2 + 1> root;
    std::array<mint, rank2 + 1> iroot;

    std::array<mint, std::max(0, rank2 - 2 + 1)> rate2;
    std::array<mint, std::max(0, rank2 - 2 + 1)> irate2;

    std::array<mint, std::max(0, rank2 - 3 + 1)> rate3;
    std::array<mint, std::max(0, rank2 - 3 + 1)> irate3;

    consteval fft_info() {
        this->root[rank2] = g.pow((mint::mod() - 1) >> this->rank2);
        this->iroot[rank2] = this->root[this->rank2].inv();

        REPD(i, rank2) {
            this->root[i] = this->root[i + 1] * this->root[i + 1];
            this->iroot[i] = this->iroot[i + 1] * this->iroot[i + 1];
        }

        {
            mint prod = mint::one, iprod = mint::one;
            REP(i, rank2 - 1) {
                this->rate2[i] = this->root[i + 2] * prod;
                this->irate2[i] = this->iroot[i + 2] * iprod;
                prod *= this->iroot[i + 2];
                iprod *= this->root[i + 2];
            }
        }
        {
            mint prod = mint::one, iprod = mint::one;
            REP(i, rank2 - 2) {
                this->rate3[i] = this->root[i + 3] * prod;
                this->irate3[i] = this->iroot[i + 3] * iprod;
                prod *= this->iroot[i + 3];
                iprod *= this->root[i + 3];
            }
        }
    }
};


}  // namespace internal


template<std::ranges::sized_range R>
    requires internal::static_modint_family<std::ranges::range_value_t<R>>
void butterfly(R& v1) {
    using mint = std::ranges::range_value_t<R>;

    const auto n = std::ranges::ssize(v1);
    const auto h = to_signed(std::countr_zero(to_unsigned(n)));

    static constexpr internal::fft_info<mint> info;

    internal::size_t len = 0;
    while(len < h) {
        if(h - len == 1) {
            const internal::size_t p = 1 << (h - len - 1);
            mint rot = mint::one;

            REP(s, 1 << len) {
                const internal::size_t offset = s << (h - len);
                REP(i, p) {
                    const auto l = v1[i + offset];
                    const auto r = v1[i + offset + p] * rot;
                    v1[i + offset] = l + r;
                    v1[i + offset + p] = l - r;
                }
                if(s + 1 != (1 << len)) {
                    rot *= info.rate2[std::countr_zero(~to_unsigned(s))];
                }
            }

            ++len;
        }
        else {
            const internal::size_t p = 1 << (h - len - 2);
            const mint imag = info.root[2];
            mint rot = mint::one;

            REP(s, 1 << len) {
                const mint rot2 = rot * rot;
                const mint rot3 = rot2 * rot;
                const internal::size_t offset = s << (h - len);

                REP(i, p) {
                    const auto mod2 = 1ULL * mint::mod() * mint::mod();
                    const auto a0 = 1ULL * v1[i + offset].val();
                    const auto a1 = 1ULL * v1[i + offset + p].val() * rot.val();
                    const auto a2 = 1ULL * v1[i + offset + 2 * p].val() * rot2.val();
                    const auto a3 = 1ULL * v1[i + offset + 3 * p].val() * rot3.val();

                    const auto a1na3imag = 1ULL * mint{ a1 + mod2 - a3 }.val() * imag.val();

                    const auto na2 = mod2 - a2;

                    v1[i + offset] = a0 + a2 + a1 + a3;
                    v1[i + offset + 1 * p] = a0 + a2 + (2 * mod2 - (a1 + a3));
                    v1[i + offset + 2 * p] = a0 + na2 + a1na3imag;
                    v1[i + offset + 3 * p] = a0 + na2 + (mod2 - a1na3imag);
                }

                if(s + 1 != (1 << len)) rot *= info.rate3[std::countr_zero(~to_unsigned(s))];
            }

            len += 2;
        }
    }
}


template<std::ranges::sized_range R>
    requires internal::static_modint_family<std::ranges::range_value_t<R>>
void butterfly_inv(R& v1) {
    using mint = std::ranges::range_value_t<R>;

    const auto n = std::ranges::ssize(v1);
    const auto h = std::countr_zero(to_unsigned(n));

    static constinit internal::fft_info<mint> info;

    internal::size_t len = h;
    while(len > 0) {
        if(len == 1) {
            const internal::size_t p = 1 << (h - len);
            mint irot = mint::one;

            REP(s, 1 << (len - 1)) {
                const internal::size_t offset = s << (h - len + 1);
                REP(i, p) {
                    const auto l = v1[i + offset];
                    const auto r = v1[i + offset + p];
                    v1[i + offset] = l + r;
                    v1[i + offset + p] = to_unsigned(mint::mod() + l.val() - r.val()) * irot.val();
                }
                if(s + 1 != (1 << (len - 1))) irot *= info.irate2[std::countr_zero(~to_unsigned(s))];
            }

            --len;
        }
        else {
            const auto p = 1 << (h - len);
            const mint iimag = info.iroot[2];
            mint irot = mint::one;

            REP(s, 1 << (len - 2)) {
                const mint irot2 = irot * irot;
                const mint irot3 = irot2 * irot;
                const internal::size_t offset = s << (h - len + 2);
                REP(i, p) {
                    const auto a0 = 1ULL * v1[i + offset + 0 * p].val();
                    const auto a1 = 1ULL * v1[i + offset + 1 * p].val();
                    const auto a2 = 1ULL * v1[i + offset + 2 * p].val();
                    const auto a3 = 1ULL * v1[i + offset + 3 * p].val();

                    const auto a2na3iimag = 1ULL * mint{ (mint::mod() + a2 - a3) * iimag.val() }.val();

                    v1[i + offset] = a0 + a1 + a2 + a3;
                    v1[i + offset + 1 * p] = (a0 + (mint::mod() - a1) + a2na3iimag) * irot.val();
                    v1[i + offset + 2 * p] = (a0 + a1 + (mint::mod() - a2) + (mint::mod() - a3)) * irot2.val();
                    v1[i + offset + 3 * p] = (a0 + (mint::mod() - a1) + (mint::mod() - a2na3iimag)) * irot3.val();
                }

                if(s + 1 != (1 << (len - 2))) irot *= info.irate3[std::countr_zero(~to_unsigned(s))];
            }

            len -= 2;
        }
    }
}


template<class Res, std::ranges::sized_range R0, std::ranges::sized_range R1>
    requires
        std::same_as<std::ranges::range_value_t<R0>, std::ranges::range_value_t<R1>> &&
        internal::static_modint_family<std::ranges::range_value_t<R0>>
Res convolution_naive(R0&& v0, R1&& v1) {
    const auto n = std::ranges::ssize(v0);
    const auto m = std::ranges::ssize(v1);

    Res ans(n + m - 1);

    if(n < m) {
        REP(j, m) REP(i, n) ans[i + j] += v0[i] * v1[j];
    }
    else {
        REP(i, n) REP(j, m) ans[i + j] += v0[i] * v1[j];
    }

    return ans;
}


template<class Res, std::ranges::sized_range R0, std::ranges::sized_range R1>
    requires
        std::same_as<std::ranges::range_value_t<R0>, std::ranges::range_value_t<R1>> &&
        internal::static_modint_family<std::ranges::range_value_t<R0>> &&
        internal::resizable_range<R0> && internal::resizable_range<R1> &&
        std::convertible_to<std::ranges::range_value_t<R0>, std::ranges::range_value_t<Res>>
Res convolution_fft(R0 v0, R1 v1) {
    using mint = std::ranges::range_value_t<R0>;

    const auto n = std::ranges::ssize(v0);
    const auto m = std::ranges::ssize(v1);

    const auto z = to_signed(std::bit_ceil(to_unsigned(n + m - 1)));

    v0.resize(z);
    butterfly(v0);

    v1.resize(z);
    butterfly(v1);

    REP(i, z) v0[i] *= v1[i];

    butterfly_inv(v0);
    v0.resize(n + m - 1);

    const mint iz = mint{ z }.inv();
    REP(i, n + m - 1) v0[i] *= iz;

    if constexpr(std::convertible_to<R0, Res>) return v0;
    else return Res(ALL(v0));
}


}  // namespace uni
#line 10 "convolution/sum.hpp"

#line 12 "convolution/sum.hpp"


namespace uni {


template<class Res, std::ranges::sized_range R0, std::ranges::sized_range R1>
    requires
        std::same_as<std::ranges::range_value_t<R0>, std::ranges::range_value_t<R1>> &&
        internal::static_modint_family<std::ranges::range_value_t<R0>> &&
        std::convertible_to<std::ranges::range_value_t<R0>, std::ranges::range_value_t<Res>>
Res convolution(R0&& v0, R1&& v1) {
    using mint = std::ranges::range_value_t<R0>;

    const auto n = std::ranges::ssize(v0);
    const auto m = std::ranges::ssize(v1);

    if(!n || !m) return {};

    const auto z = to_signed(std::bit_ceil(to_unsigned(n + m - 1)));
    assert((mint::mod() - 1) % z == 0);

    // if(uni::min(n, m) <= 60) return convolution_naive<Res>(v0, v1);
    return convolution_fft<Res>(v0, v1);
}


template<
    u32 Mod = 998244353,
    class Res,
    std::ranges::sized_range R0, std::ranges::sized_range R1
>
    requires
        std::convertible_to<std::ranges::range_value_t<R0>, static_modint_32bit<Mod>> &&
        std::convertible_to<std::ranges::range_value_t<R1>, static_modint_32bit<Mod>> &&
        std::convertible_to<std::ranges::range_value_t<R0>, std::ranges::range_value_t<Res>>
Res convolution(R0&& v0, R1&& v1) {
    using mint = static_modint_32bit<Mod>;

    const auto n = std::ranges::ssize(v0);
    const auto m = std::ranges::ssize(v1);

    if(!n || !m) return {};

    const auto z = to_signed(std::bit_ceil(to_unsigned(n + m - 1)));
    assert((mint::mod() - 1) % z == 0);

    std::vector<mint> a2(n), b2(m);

    REP(i, n) a2[i] = mint{ v0[i] };
    REP(i, m) b2[i] = mint{ v1[i] };

    const auto c1 = convolution(a2, b2);

    Res c(n + m - 1);
    REP(i, n + m - 1) c[i] = c1[i].val();

    return c;
}


template<class Res, std::ranges::sized_range R0, std::ranges::sized_range R1>
    requires
        std::common_with<std::ranges::range_value_t<R0>, std::ranges::range_value_t<R1>> &&
        std::integral<std::common_type_t<std::ranges::range_value_t<R0>, std::ranges::range_value_t<R1>>> &&
        (
            std::integral<std::ranges::range_value_t<Res>> ||
            internal::modint_family<std::ranges::range_value_t<Res>>
        ) &&
        std::convertible_to<std::ranges::range_value_t<R0>, std::ranges::range_value_t<Res>>
Res convolution(R0&& v0, R1&& v1) {
    using res_value_type = std::ranges::range_value_t<Res>;

    const auto n = std::ranges::ssize(v0);
    const auto m = std::ranges::ssize(v1);

    if(!n || !m) return {};

    static constexpr i64 MOD0 = 167772161;
    static constexpr i64 MOD1 = 469762049;
    static constexpr i64 MOD2 = 754974721;

    static constexpr auto M0 = res_value_type{ MOD0 };
    static constexpr auto M1 = res_value_type{ MOD1 };
    static constexpr auto M2 = res_value_type{ MOD2 };
    static constexpr auto M0M1 = M0 * M1;
    static constexpr auto M0M2 = M0 * M2;
    static constexpr auto M1M2 = M1 * M2;
    static constexpr auto M0M1M2 = M0 * M1 * M2;

    static constexpr u64 r0 = atcoder::internal::inv_gcd(MOD1 * MOD2, MOD0).second;
    static constexpr u64 r1 = atcoder::internal::inv_gcd(MOD0 * MOD2, MOD1).second;
    static constexpr u64 r2 = atcoder::internal::inv_gcd(MOD0 * MOD1, MOD2).second;

    static constexpr i64 i01 = atcoder::internal::inv_gcd(MOD0, MOD1).second;
    static constexpr i64 i02 = atcoder::internal::inv_gcd(MOD0, MOD2).second;
    static constexpr i64 i12 = atcoder::internal::inv_gcd(MOD1, MOD2).second;
    static constexpr i64 i02i12 = (i02 * i12) % MOD2;

    static constexpr size_t MAX_AB_BIT = 24;

    static_assert(MOD0 % (1ull << MAX_AB_BIT) == 1, "MOD0 isn't enough to support an array length of 2^24.");
    static_assert(MOD1 % (1ull << MAX_AB_BIT) == 1, "MOD1 isn't enough to support an array length of 2^24.");
    static_assert(MOD2 % (1ull << MAX_AB_BIT) == 1, "MOD2 isn't enough to support an array length of 2^24.");

    assert(n + m - 1 <= (1 << MAX_AB_BIT));

    const auto c0 = convolution<MOD0, std::remove_cvref_t<R0>>(v0, v1);
    const auto c1 = convolution<MOD1, std::remove_cvref_t<R0>>(v0, v1);
    const auto c2 = convolution<MOD2, std::remove_cvref_t<R0>>(v0, v1);

    Res c(n + m - 1);

    REP(i, n + m - 1) {
        if constexpr(internal::modint_family<res_value_type>) {
            const auto c01 = ((c1[i] + MOD1 - c0[i]) * i01) % MOD1;
            const auto c012 = ((c2[i] + MOD2 - c0[i]) * i02i12 + (MOD2 - c01) * i12) % MOD2;
            c[i] = c0[i] + c01 * M0 + c012 * M0M1;
        }
        else {
            res_value_type x = 0;
            x += (c0[i] * r0) % MOD0 * M1M2;
            x += (c1[i] * r1) % MOD1 * M0M2;
            x += (c2[i] * r2) % MOD2 * M0M1;

            auto diff = c2[i] - uni::mod(to_signed(x), to_signed(MOD2));
            if (diff < 0) diff += MOD2;

            static constexpr res_value_type offset[5] = { 0, 0, M0M1M2, 2 * M0M1M2, 3 * M0M1M2 };
            x -= offset[diff % 5];
            c[i] = x;
        }
    }

    return c;
}


template<std::ranges::range R0, std::ranges::range R1>
    requires
        std::common_with<std::ranges::range_value_t<R0>, std::ranges::range_value_t<R1>> &&
        internal::modint_family<std::common_type_t<std::ranges::range_value_t<R0>, std::ranges::range_value_t<R1>>>
auto convolution(R0&& v0, R1&& v1) {
    using common_type = std::common_type_t<std::ranges::range_value_t<R0>, std::ranges::range_value_t<R1>>;
    return convolution<valarray<common_type>>(v0, v1);
}


template<u32 Mod = 998244353, std::ranges::range R0, std::ranges::range R1>
    requires
        std::common_with<std::ranges::range_value_t<R0>, std::ranges::range_value_t<R1>> &&
        std::integral<std::common_type_t<std::ranges::range_value_t<R0>, std::ranges::range_value_t<R1>>> &&
        (
            std::numeric_limits<
                std::common_type_t<std::ranges::range_value_t<R0>, std::ranges::range_value_t<R1>>
            >::digits <= 64
        )
auto convolution(R0&& v0, R1&& v1) {
    using common_type = std::common_type_t<std::ranges::range_value_t<R0>, std::ranges::range_value_t<R1>>;
    return convolution<Mod, valarray<common_type>>(v0, v1);
}


} // namespace uni
#line 2 "include/data_structures.hpp"

#line 2 "data_structure/adaptor/set.hpp"


#line 10 "data_structure/adaptor/set.hpp"


#line 15 "data_structure/adaptor/set.hpp"

#line 17 "data_structure/adaptor/set.hpp"

#line 2 "data_structure/segment_tree.hpp"


#line 11 "data_structure/segment_tree.hpp"


#line 14 "data_structure/segment_tree.hpp"

#line 2 "internal/point_reference.hpp"


#line 6 "internal/point_reference.hpp"


#line 9 "internal/point_reference.hpp"

#line 11 "internal/point_reference.hpp"


namespace uni {

namespace internal {


template<class Super, std::integral SizeType = typename Super::size_type>
struct point_reference {
    using size_type = SizeType;
    using iterator = typename Super::iterator;

  protected:
    Super *const _super;
    const size_type _pos;

    point_reference(Super *const super, const size_type pos) noexcept(NO_EXCEPT) : _super(super), _pos(pos) {}

    inline auto index() noexcept(NO_EXCEPT) { return this->_pos; }
};


} // namespace internal

} // namespace uni
#line 2 "internal/range_reference.hpp"


#line 8 "internal/range_reference.hpp"


#line 11 "internal/range_reference.hpp"

#line 13 "internal/range_reference.hpp"


namespace uni {

namespace internal {


template<class Super, std::integral SizeType = typename Super::size_type>
struct range_reference {
    using size_type = SizeType;
    using iterator = Super::iterator;

  protected:
    Super *const _super;
    const size_type _begin, _end;

    range_reference(Super *const super, const size_type begin, const size_type end) noexcept(NO_EXCEPT) : _super(super), _begin(begin), _end(end) {}

  public:
    inline auto begin() const noexcept(NO_EXCEPT) { return std::ranges::next(std::ranges::begin(*this->_super), this->_begin); }
    inline auto end() const noexcept(NO_EXCEPT) { return std::ranges::next(std::ranges::begin(*this->_super), this->_end); }

    inline auto size() const noexcept(NO_EXCEPT) { return this->_end - this->_begin; }

    inline auto interval() const noexcept(NO_EXCEPT) { return std::make_pair(this->_begin, this->_end); }

  protected:
    inline auto sub_range(size_type l, size_type r) const noexcept(NO_EXCEPT) {
        l = _super->_positivize_index(l), r = _super->_positivize_index(r);
        assert(0 <= l and l <= r and r <= this->size());

        return range_reference(_super, this->_begin + l, this->_begin + r);
    }

  public:
    template<uni::interval_notation rng = uni::interval_notation::right_open>
    inline auto range(const size_type l, const size_type r) const noexcept(NO_EXCEPT) {
        if constexpr(rng == uni::interval_notation::right_open) return this->sub_range(l, r);
        if constexpr(rng == uni::interval_notation::left_open) return this->sub_range(l+1, r+1);
        if constexpr(rng == uni::interval_notation::open) return this->sub_range(l+1, r);
        if constexpr(rng == uni::interval_notation::closed) return this->sub_range(l, r+1);
    }
    inline auto range() const noexcept(NO_EXCEPT) { return range_reference(this->_begin, this->_end); }

    inline auto operator()(const size_type l, const size_type r) const noexcept(NO_EXCEPT) { return this->sub_range(l, r); }

    inline auto subseq(const size_type p, const size_type c) const noexcept(NO_EXCEPT) { return this->sub_range(p, p+c); }
    inline auto subseq(const size_type p) const noexcept(NO_EXCEPT) { return this->sub_range(p, this->size()); }
};


} // namespace internal

} // namespace uni
#line 2 "internal/unconstructible.hpp"


namespace uni {

namespace internal {


struct unconstructible  {
  private:
    template<class... Args>
    unconstructible(Args...) = delete;
};


} // namespace internal

} // namespace uni
#line 21 "data_structure/segment_tree.hpp"

#line 25 "data_structure/segment_tree.hpp"


namespace uni {

namespace internal {

namespace segment_tree_impl {


// Thanks to: atcoder::segtree
template<algebraic::internal::monoid Monoid>
struct core {
    using size_type = internal::size_t;

    using operand = Monoid;

  protected:
    size_type _n = 0, _size = 0, _depth = 0;
    std::valarray<operand> _data;

    inline void _pull(const size_type k) noexcept(NO_EXCEPT) {
        this->_data[k] = this->_data[k << 1] + this->_data[k << 1 | 1];
    }

  public:
    core() noexcept = default;

    explicit core(const size_type n) noexcept(NO_EXCEPT)
      : _n(n), _size(std::bit_ceil(uni::to_unsigned(n))), _depth(std::countr_zero(uni::to_unsigned(this->_size))),
        _data(this->_size << 1)
    {}


    inline size_type size() const noexcept(NO_EXCEPT) { return this->_n; }
    inline size_type allocated() const noexcept(NO_EXCEPT) { return this->_values.size(); }
    inline size_type depth() const noexcept(NO_EXCEPT) { return this->_depth; }


    inline operand fold_all() const noexcept(NO_EXCEPT) { return this->_data[1]; }


    template<std::input_iterator I, std::sentinel_for<I> S>
    inline void assign(I first, S last) noexcept(NO_EXCEPT) {
        if constexpr(std::sized_sentinel_for<S, I>) {
            assert(std::ranges::distance(first, last) == this->_n);
        }
        {
            size_type p = 0;
            for(auto itr=first; itr!=last; ++itr, ++p) this->_data[this->_size + p] = static_cast<operand>(*itr);
        }
        REPD(p, 1, this->_size) this->_pull(p);
    }

    inline void fill(const operand& v = operand()) noexcept(NO_EXCEPT) {
        REP(p, this->_n) this->_data[this->_size + p] = v;
        REPD(p, 1, this->_size) this->_pull(p);
    }


    inline void add(size_type p, const operand& x) noexcept(NO_EXCEPT) {
        this->set(p, this->_data[p + this->_size] + x);
    }

    inline void set(size_type p, const operand& x) noexcept(NO_EXCEPT) {
        p += this->_size;
        this->_data[p] = x;
        FOR(i, 1, this->_depth) this->_pull(p >> i);
    }

    inline operand get(size_type p) const noexcept(NO_EXCEPT) {
        return this->_data[p + this->_size];
    }

    inline operand fold(size_type l, size_type r) const noexcept(NO_EXCEPT) {
        operand sml, smr;
        l += this->_size;
        r += this->_size;

        while(l < r) {
            if(l & 1) sml = sml + this->_data[l++];
            if(r & 1) smr = this->_data[--r] + smr;
            l >>= 1;
            r >>= 1;
        }
        return sml + smr;
    }


    template<class F>
    inline size_type max_right(size_type l, F&& f) const noexcept(NO_EXCEPT) {
        assert(0 <= l && l <= this->_n);
        assert(f(operand{}));

        if(l == this->_n) return this->_n;

        l += this->_size;
        operand acc;
        do {
            while((l & 1) == 0) l >>= 1;

            if(!f(acc + this->_data[l])) {
                while(l < this->_size) {
                    l <<= 1;

                    if(f(acc + this->_data[l])) {
                        acc = acc + this->_data[l];
                        ++l;
                    }
                }

                return l - this->_size;
            }

            acc = acc + this->_data[l];
            ++l;
        } while((l & -l) != l);

        return this->_n;
    }

    template<class F>
    inline size_type min_left(size_type r, F&& f) const noexcept(NO_EXCEPT) {
        assert(0 <= r && r <= this->_n);
        assert(f(operand{}));

        if (r == 0) return 0;

        r += this->_size;
        operand acc;

        do {
            --r;
            while(r > 1 && (r & 1)) r >>= 1;

            if(!f(this->_data[r] + acc)) {
                while(r < this->_size) {

                    r = (r << 1 | 1);
                    if(f(this->_data[r] + acc)) {
                        acc = this->_data[r] + acc;
                        --r;
                    }
                }

                return r + 1 - this->_size;
            }

            acc = this->_data[r] + acc;
        } while((r & -r) != r);

        return 0;
    }
};



} // namespace segment_tree_impl

} // namespace internal


template<class T>
struct segment_tree : internal::unconstructible {};


template<algebraic::internal::monoid Monoid>
struct segment_tree<Monoid> {
  private:
    using core = typename internal::segment_tree_impl::core<Monoid>;

    core _impl;

  public:
    using value_type = Monoid;
    using size_type = typename core::size_type;

  private:
    inline auto _positivize_index(const size_type p) const noexcept(NO_EXCEPT) {
        return p < 0 ? this->_impl.size() + p : p;
    }

  public:
    segment_tree() noexcept(NO_EXCEPT) : _impl() {};
    explicit segment_tree(const size_type n, const value_type& v = value_type()) noexcept(NO_EXCEPT) : _impl(n) { this->_impl.fill(v); }

    template<std::convertible_to<value_type> T>
    segment_tree(const std::initializer_list<T>& init_list) noexcept(NO_EXCEPT) : segment_tree(ALL(init_list)) {}

    template<std::input_iterator I, std::sized_sentinel_for<I> S>
    segment_tree(I first, S last) noexcept(NO_EXCEPT)
      : segment_tree(static_cast<size_type>(std::ranges::distance(first, last)))
    { this->assign(first, last); }

    template<std::ranges::input_range R>
    explicit segment_tree(R&& range) noexcept(NO_EXCEPT) : segment_tree(ALL(range)) {}


    inline auto size() const noexcept(NO_EXCEPT) { return this->_impl.size(); }
    inline auto allocated() const noexcept(NO_EXCEPT) { return this->_impl.allocated(); }
    inline auto depth() const noexcept(NO_EXCEPT) { return this->_impl.depth(); }


    template<std::convertible_to<value_type> T>
    inline auto& assign(const std::initializer_list<T>& init_list) noexcept(NO_EXCEPT) { return this->assign(ALL(init_list)); }

    template<std::input_iterator I, std::sentinel_for<I> S>
    inline auto& assign(I first, S last) noexcept(NO_EXCEPT) {
        this->_impl.assign(first, last);
        return *this;
    }

    template<std::ranges::input_range R>
    inline auto& assign(R&& range) noexcept(NO_EXCEPT) { return this->assign(ALL(range)); }

    inline auto& fill(const value_type& v = value_type()) noexcept(NO_EXCEPT) {
        this->_impl.fill(v);
        return *this;
    }

    inline bool empty() const noexcept(NO_EXCEPT) { return this->_impl.size() == 0; }

    struct point_reference : internal::point_reference<segment_tree> {
        point_reference(segment_tree *const super, const size_type p) noexcept(NO_EXCEPT)
          : internal::point_reference<segment_tree>(super, super->_positivize_index(p))
        {
            assert(0 <= this->_pos && this->_pos < this->_super->size());
        }

        operator value_type() const noexcept(NO_EXCEPT) { return this->_super->get(this->_pos); }
        auto val() const noexcept(NO_EXCEPT) { return this->_super->get(this->_pos); }

        inline auto& operator=(const value_type& v) noexcept(NO_EXCEPT) {
            this->_super->set(this->_pos, v);
            return *this;
        }

        inline auto& operator+=(const value_type& v) noexcept(NO_EXCEPT) {
            this->_super->add(this->_pos, v);
            return *this;
        }
    };

    struct range_reference : internal::range_reference<segment_tree> {
        range_reference(segment_tree *const super, const size_type l, const size_type r) noexcept(NO_EXCEPT)
          : internal::range_reference<segment_tree>(super, super->_positivize_index(l), super->_positivize_index(r))
        {
            assert(0 <= this->_begin && this->_begin <= this->_end && this->_end <= this->_super->size());
        }

        inline auto fold() noexcept(NO_EXCEPT) {
            if(this->_begin == 0 and this->_end == this->_super->size()) return this->_super->fold();
            return this->_super->fold(this->_begin, this->_end);
        }
    };


    inline auto& add(const size_type p, const value_type& x) noexcept(NO_EXCEPT) {
        assert(0 <= p && p < this->_impl.size());
        this->_impl.add(p, x);
         return *this;
    }

    inline auto& set(const size_type p, const value_type& x) noexcept(NO_EXCEPT) {
        assert(0 <= p && p < this->_impl.size());
        this->_impl.set(p, x);
         return *this;
    }

    inline auto get(const size_type p) const noexcept(NO_EXCEPT) {
        assert(0 <= p && p < this->_impl.size());
        return this->_impl.fold(p, p+1);
    }

    inline auto operator[](const size_type p) noexcept(NO_EXCEPT) { return point_reference(this, p); }
    inline auto operator()(const size_type l, const size_type r) noexcept(NO_EXCEPT) { return range_reference(this, l, r); }

    inline auto fold(const size_type l, const size_type r) const noexcept(NO_EXCEPT) {
        assert(0 <= l && l <= r && r <= this->_impl.size());
        return this->_impl.fold(l, r);
    }
    inline auto fold(const size_type r) const noexcept(NO_EXCEPT) {
        assert(0 <= r && r <= this->_impl.size());
        return this->_impl.fold(0, r);
    }
    inline auto fold() const noexcept(NO_EXCEPT) {
        return this->_impl.fold_all();
    }


    template<bool (*f)(value_type)>
    inline auto max_right(const size_type l) const noexcept(NO_EXCEPT) {
        return this->_impl.max_right(l, [](value_type x) { return f(x); });
    }

    template<class F>
    inline auto max_right(const size_type l, F&& f) const noexcept(NO_EXCEPT) {
        return this->_impl.max_right(l, std::forward<F>(f));
    }


    template<bool (*f)(value_type)>
    inline auto min_left(const size_type r) const noexcept(NO_EXCEPT) {
        return this->_impl.min_left(r, [](value_type x) { return f(x); });
    }

    template<class F>
    inline auto min_left(const size_type r, F&& f) const noexcept(NO_EXCEPT) {
        return this->_impl.min_left(r, std::forward<F>(f));
    }


    struct iterator;

  protected:
    using iterator_interface = internal::container_iterator_interface<value_type, const segment_tree, iterator>;

  public:
    struct iterator : iterator_interface {
        using iterator_interface::iterator_interface;
    };

    inline auto begin() const noexcept(NO_EXCEPT) { return iterator(this, 0); }
    inline auto end() const noexcept(NO_EXCEPT) { return iterator(this, this->_impl.size()); }

    inline auto rbegin() const noexcept(NO_EXCEPT) { return std::make_reverse_iterator(this->end()); }
    inline auto rend() const noexcept(NO_EXCEPT) { return std::make_reverse_iterator(this->begin()); }
};


template<actions::internal::operatable_action Action>
struct segment_tree<Action> : segment_tree<typename Action::operand> {
    using segment_tree<typename Action::operand>::segment_tree;
};


} // namespace uni
#line 26 "data_structure/adaptor/set.hpp"


namespace uni {


namespace internal {


template<
    template<class...> class Tree,
    template<class...> class Action
>
    requires actions::internal::action<Action<internal::size_t>>
struct set_adaptor_impl {
    using size_type = internal::size_t;
    using key_type = internal::size_t;
    using value_type = internal::size_t;

  protected:
    using impl_data_type = algebraic::combined<algebraic::addition<value_type>, algebraic::minimum<value_type>>;

    using impl_tree =
        Tree<
            std::conditional_t<
                internal::available_with<
                    Tree,
                    Action<impl_data_type>
                >,
                Action<impl_data_type>,
                actions::range_sum<impl_data_type>
            >
        >;

    impl_tree _data;
    size_type _elem = 0;

  public:
    set_adaptor_impl(const size_type sup) noexcept(NO_EXCEPT) : _data(sup) {};

    inline size_type size() const noexcept(NO_EXCEPT) { return this->_data.fold(); }
    inline bool empty() const noexcept(NO_EXCEPT) { return this->size() == 0; }

    inline size_type count(const key_type& k) const noexcept(NO_EXCEPT) { return this->_data.get(k).val()->first.val(); }
    inline bool contains(const key_type& k) const noexcept(NO_EXCEPT) { return this->_data.get(k).val()->first.val() > 0; }

    inline value_type mex(const key_type& base = 0) const noexcept(NO_EXCEPT) {
        return this->_data.max_right(base, [](const auto& p) { return p.val()->second.val() > 0; });
    }

    inline std::optional<value_type> next(const key_type& k, const size_type count = 0) const noexcept(NO_EXCEPT) {
        const auto v = this->_data.max_right(k, [count](const auto& p) { return p.val()->first.val() <= count; });
        if(v == this->_data.size()) return {};
        return { v };
    }
    inline std::optional<value_type> prev(const key_type& k, const size_type count = 0) const noexcept(NO_EXCEPT) {
        const auto v = this->_data.min_left(k + 1, [count](const auto& p) { return p.val()->first.val() <= count; });
        if(v == 0) return {};
        return { v - 1 };
    }

    inline auto kth_smallest(const size_type k) const noexcept(NO_EXCEPT) { return this->next(0, k); }
    inline auto kth_largest(const size_type k) const noexcept(NO_EXCEPT) { return this->prev(this->_data.size()-1, k); }

    inline value_type min() const noexcept(NO_EXCEPT) { return this->kth_smallest(0); }
    inline value_type max() const noexcept(NO_EXCEPT) { return this->kth_largest(0); }

    inline size_type count_under(const value_type& v) const noexcept(NO_EXCEPT) { return this->_data.fold(0, v).val()->first.val(); }
    inline size_type count_over(const value_type& v) const noexcept(NO_EXCEPT) { return this->_data.fold(v+1, this->_data.size()).val()->first.val(); }
    inline size_type count_or_under(const value_type& v) const noexcept(NO_EXCEPT) { return this->_data.fold(0, v+1).val()->first.val(); }
    inline size_type count_or_over(const value_type& v) const noexcept(NO_EXCEPT) { return this->_data.fold(v, this->_data.size()).val()->first.val(); }

    template<comparison com = comparison::equal_to>
    inline size_type count(const value_type& v) const noexcept(NO_EXCEPT) {
        if constexpr(com == comparison::eq) return this->count(v);
        if constexpr(com == comparison::under) return this->count_under(v);
        if constexpr(com == comparison::over) return this->count_over(v);
        if constexpr(com == comparison::or_under) return this->count_or_under(v);
        if constexpr(com == comparison::or_over) return this->count_or_over(v);
        assert(false);
    }

    inline const auto& _debug() const noexcept(NO_EXCEPT) { return this->_data; }
};


};


template<template<class...> class Tree = uni::segment_tree>
struct set_adaptor : internal::set_adaptor_impl<Tree, actions::range_set_range_sum> {
    using size_type = internal::size_t;
    using key_type = internal::size_t;
    using value_type = size_type;

  protected:
    using Base = internal::set_adaptor_impl<Tree, actions::range_set_range_sum>;
    using impl_data_type = typename Base::impl_data_type;

  public:
    set_adaptor() noexcept(NO_EXCEPT) = default;

    set_adaptor(const size_type sup) noexcept(NO_EXCEPT) : Base(sup) {};

    template<std::input_iterator I, std::sentinel_for<I> S>
    set_adaptor(I first, S last) noexcept(NO_EXCEPT) : set_adaptor(*std::ranges::max_element(first, last) + 1) {
        valarray<bool> bits(this->_data.size());
        REP(itr, first, last) {
            assert(0 <= *itr && *itr < this->_data.size());
            bits[*itr] = true;
        }
        this->build_from_bits(ALL(bits));
    };

    template<std::ranges::input_range R>
    set_adaptor(R&& range) noexcept(NO_EXCEPT) : set_adaptor(ALL(range)) {}

    template<std::input_iterator I, std::sentinel_for<I> S>
    inline auto& build_from_bits(I first, S last) noexcept(NO_EXCEPT) {
        if constexpr(std::sized_sentinel_for<S, I>) {
            assert(std::ranges::distance(first, last) == this->_data.size());
        }
        this->_data.assign(first, last);
        return *this;
    };

    template<std::ranges::input_range R>
    inline auto& build_from_bits(R&& range) noexcept(NO_EXCEPT) {
        return this->build_from_bits(ALL(range));
    }

    inline bool insert(const key_type& k) noexcept(NO_EXCEPT) {
        assert(0 <= k && k < this->_data.size());
        const bool res = !this->_data.get(k).val()->first.val();
        if(res) this->_data.set(k, impl_data_type{ 1 });
        return res;
    }

    inline bool remove(const key_type& k) noexcept(NO_EXCEPT) {
        assert(0 <= k && k < this->_data.size());
        const bool res = this->_data.get(k).val()->first.val();
        if(res) this->_data.set(k, impl_data_type{ 0 });
        return res;
    }
};


template<template<class...> class Tree = uni::segment_tree, std::integral Size = std::int64_t>
struct multiset_adaptor : internal::set_adaptor_impl<Tree, actions::range_add_range_sum> {
    using size_type = Size;
    using key_type = internal::size_t;
    using value_type = key_type;

  private:
    using Base = internal::set_adaptor_impl<Tree, actions::range_add_range_sum>;
    using impl_data_type = typename Base::impl_data_type;


  public:
    multiset_adaptor(const size_type sup) noexcept(NO_EXCEPT) : Base(sup) {};

    template<std::input_iterator I, std::sentinel_for<I> S>
    multiset_adaptor(I first, S last) noexcept(NO_EXCEPT) : Base(*std::ranges::max_element(first, last) + 1) {
        vector<size_type> cnts(this->_data.size());
        REP(itr, first, last) {
            assert(0 <= *itr && *itr < this->_data.size());
            cnts[*itr]++;
        }
        this->build_from_histogram(ALL(cnts));
    };

    template<std::ranges::input_range R>
    multiset_adaptor(R&& range) noexcept(NO_EXCEPT) : multiset_adaptor(ALL(range)) {}

    template<std::input_iterator I, std::sentinel_for<I> S>
    inline auto& build_from_histogram(I first, S last) noexcept(NO_EXCEPT) {
        if constexpr(std::sized_sentinel_for<S, I>) {
            assert(std::ranges::distance(first, last) == this->_data.size());
        }
        this->_data.assign(first, last);
        return *this;
    };

    template<std::ranges::input_range R>
    inline auto& build_from_histogram(R&& range) noexcept(NO_EXCEPT) {
        return this->build_from_histogram(ALL(range));
    }


    inline void insert(const key_type& k, const size_type count = 1) noexcept(NO_EXCEPT) {
        assert(0 <= k && k < this->_data.size());
        assert(0 <= count);
        const auto cur = this->_data.get(k);
        const auto num = cur.val()->first.val();
        this->_data.set(k, impl_data_type{ num + count });
        this->_elem += count;
    }

    inline void remove(const key_type& k, const size_type count = 1) noexcept(NO_EXCEPT) {
        assert(0 <= k && k < this->_data.size());
        const auto cur = this->_data.get(k);
        const auto num = cur.val()->first.val();
        assert(0 <= count && count <= num);
        this->_data.set(k, impl_data_type{ num - count });
    }
};


} // namespace uni
#line 4 "include/data_structures.hpp"

#line 2 "data_structure/bit_vector.hpp"


#line 9 "data_structure/bit_vector.hpp"


#line 14 "data_structure/bit_vector.hpp"

#line 16 "data_structure/bit_vector.hpp"


namespace uni {


// Thanks to: https://github.com/NyaanNyaan/library/blob/master/data-structure-2d/wavelet-matrix.hpp
struct bit_vector {
    using size_type = std::uint_fast32_t;

  private:
    static constexpr size_type WORDSIZE = 64;
    std::vector<std::uint64_t> _block;
    std::vector<size_type> _count;
    size_type _n, _zeros;

  public:
    bit_vector(const size_type n = 0) noexcept(NO_EXCEPT) { this->init(n); }

    template<std::input_iterator I, std::sentinel_for<I> S>
    bit_vector(I first, S last) noexcept(NO_EXCEPT)
      : bit_vector(std::ranges::distance(first, last))
    {
        size_type pos = 0;
        for(auto itr=first; itr != last; ++pos, ++itr) if(*itr) this->set(pos);
    }

    template<std::ranges::input_range R>
    bit_vector(R&& range) noexcept(NO_EXCEPT) : bit_vector(ALL(range)) {}

    template<class T> bit_vector(const std::initializer_list<T>& init_list) noexcept(NO_EXCEPT)
      : bit_vector(ALL(init_list))
    {}

    inline constexpr size_type size() const noexcept(NO_EXCEPT) { return this->_n; }

    inline constexpr size_type zeros() const noexcept(NO_EXCEPT) { return this->_zeros; }
    inline constexpr size_type ones() const noexcept(NO_EXCEPT) { return this->_n - this->_zeros; }

    inline void set(const size_type k) noexcept(NO_EXCEPT) { this->_block[k / WORDSIZE] |= (1LL << (k % WORDSIZE)); }
    inline bool get(const size_type k) const noexcept(NO_EXCEPT) {
        return 1U & static_cast<std::uint32_t>(this->_block[k / WORDSIZE] >> (k % WORDSIZE));
    }

    __attribute__((optimize("O3", "unroll-loops")))
    inline void init(const size_type n) noexcept(NO_EXCEPT) {
        this->_n = this->_zeros = n;
        this->_block.resize(this->_n / WORDSIZE + 1, 0);
        this->_count.resize(this->_block.size(), 0);
    }

    inline void build() noexcept(NO_EXCEPT) {
        for(auto k = 1UL; k < this->_block.size(); ++k) {
            this->_count[k] = this->_count[k-1] + static_cast<size_type>(std::popcount(this->_block[k-1]));
        }
        this->_zeros = this->rank0(this->_n);
    }


    inline size_type rank1(const size_type k) const noexcept(NO_EXCEPT) {
        return
            this->_count[k / WORDSIZE] +
            static_cast<size_type>(std::popcount(uni::clear_higher_bits(this->_block[k / WORDSIZE], k % WORDSIZE)));
    }

    inline size_type rank0(const size_type k) const noexcept(NO_EXCEPT) { return k - this->rank1(k); }


    template<bool BIT>
    inline size_type rank(const size_type k) const noexcept(NO_EXCEPT) {
        if constexpr(BIT) return this->rank0(k);
        else return this->rank1(k);
    }

    template<bool BIT>
    inline size_type select(const size_type rank) const noexcept(NO_EXCEPT) {
        if constexpr(BIT) {
            if(rank >= this->ones()) return this->_n;
        }
        else {
            if(rank >= this->zeros()) return this->_n;
        }

        size_type index = 0;
        {
            size_type ng = static_cast<size_type>(this->_count.size());
            while(ng - index > 1) {
                size_type mid = (ng + index) / 2;

                size_type cnt = this->_count[mid];
                if constexpr(!BIT) cnt = mid * WORDSIZE - cnt;

                (cnt <= rank ? index : ng) = mid;
            }
        }

        const size_type base = index * WORDSIZE;

        if constexpr(BIT) {
            return base + select64(this->_block[index], rank - this->_count[index]);
        }
        else {
            return base + select64(~this->_block[index], rank - (base - this->_count[index]));
        }
    }


    inline size_type select0(const size_type k) const noexcept(NO_EXCEPT) { return this->select<false>(k); }
    inline size_type select1(const size_type k) const noexcept(NO_EXCEPT) { return this->select<true>(k); }

    struct iterator;

  private:
    using iterator_interface = internal::container_iterator_interface<bool, const bit_vector, iterator>;

  public:
    struct iterator : iterator_interface {
        iterator() noexcept = default;
        iterator(const bit_vector *const ref, const size_type pos) noexcept(NO_EXCEPT) : bit_vector::iterator_interface(ref, static_cast<difference_type>(pos)) {}

        inline bool operator*() const noexcept(NO_EXCEPT) { return this->ref()->get(this->pos()); }
    };

    inline auto begin() const noexcept(NO_EXCEPT) { return iterator(this, 0); }
    inline auto end() const noexcept(NO_EXCEPT) { return iterator(this, this->size()); }
};


} // namespace uni
#line 2 "data_structure/disjoint_set.hpp"


#line 8 "data_structure/disjoint_set.hpp"


#line 12 "data_structure/disjoint_set.hpp"

#line 15 "data_structure/disjoint_set.hpp"

#line 17 "data_structure/disjoint_set.hpp"


namespace uni {

//Thanks to: atcoder::disjoint_set
struct disjoint_set {
    using size_type = internal::size_t;

  private:
    size_type _n = 0, _group_count = 0;
    // root node: -1 * component size
    // otherwise: parent
    std::vector<size_type> _parent_or_size;

  public:
    disjoint_set() noexcept = default;
    explicit disjoint_set(const size_type n) noexcept(NO_EXCEPT) : _n(n), _group_count(n), _parent_or_size(n, -1) {}

    inline auto size() const noexcept(NO_EXCEPT) { return this->_n; }
    inline auto group_count() const noexcept(NO_EXCEPT) { return this->_group_count; }

    inline auto merge(const size_type a, const size_type b) noexcept(NO_EXCEPT) {
        assert(0 <= a && a < _n);
        assert(0 <= b && b < _n);

        size_type x = this->leader(a), y = this->leader(b);
        if (x == y) return x;

        --this->_group_count;

        if (-this->_parent_or_size[x] < -this->_parent_or_size[y]) std::swap(x, y);

        this->_parent_or_size[x] += this->_parent_or_size[y];
        this->_parent_or_size[y] = x;

        return x;
    }

    inline bool same(const size_type a, const size_type b) noexcept(NO_EXCEPT) {
        assert(0 <= a && a < _n);
        assert(0 <= b && b < _n);
        return this->leader(a) == this->leader(b);
    }

    inline size_type leader(const size_type a) noexcept(NO_EXCEPT) {
        assert(0 <= a && a < _n);
        if(this->_parent_or_size[a] < 0) return a;
        return this->_parent_or_size[a] = this->leader(this->_parent_or_size[a]);
    }

    inline auto size(const size_type a) noexcept(NO_EXCEPT) {
        assert(0 <= a && a < _n);
        return -this->_parent_or_size[this->leader(a)];
    }

    inline auto groups() noexcept(NO_EXCEPT) {
        vector<size_type> leader_buf(_n), group_size(_n);

        REP(i, this->_n) {
            leader_buf[i] = this->leader(i);
            group_size[leader_buf[i]]++;
        }

        vector<vector<size_type>> result(_n);
        REP(i, this->_n) result[i].reserve(group_size[i]);

        REP(i, this->_n) result[leader_buf[i]].push_back(i);

        {
            const auto range = std::ranges::remove_if(result, [&](const auto& v) { return v.empty(); });
            result.erase(ALL(range));
        }

        return result;
    }
};


} // namespace uni
#line 2 "data_structure/disjoint_sparse_table.hpp"


#line 12 "data_structure/disjoint_sparse_table.hpp"


#line 19 "data_structure/disjoint_sparse_table.hpp"

#line 21 "data_structure/disjoint_sparse_table.hpp"

#line 24 "data_structure/disjoint_sparse_table.hpp"


namespace uni {

namespace internal {

namespace disjoint_sparse_table_impl {


// Thanks to: https://noshi91.hatenablog.com/entry/2018/05/08/183946
template<algebraic::internal::semigroup Operand>
struct core {
    using size_type = internal::size_t;
    using operand = Operand;

    using iterator = std::vector<std::vector<Operand>>;

    size_type _n = 0, _depth = 0;
    bool _built = false;

  protected:
    std::vector<std::vector<operand>> _table = {};

  public:
    explicit core(const size_type n = 0) noexcept(NO_EXCEPT) : _n(n) {
        this->_depth = std::bit_width<std::make_unsigned_t<size_type>>(n);
        this->_table.resize(this->_depth+1, std::vector<operand>(n));
    }


    template<std::input_iterator I, std::sized_sentinel_for<I> S>
    core(I first, S last) noexcept(NO_EXCEPT)
      : core(static_cast<size_type>(std::ranges::distance(first, last)))
    {
        std::ranges::copy(first, last, this->_table.begin()->begin());
    }


    template<bool FORCE = false>
    inline auto& build() noexcept(NO_EXCEPT) {
        if(!FORCE and this->_built) return *this;

        FOR(i, 2, this->_depth) {
            const size_type len = 1 << i;

            for(size_type l = 0, m = (len >> 1); m < this->_n; l += len, m = l + (len >> 1)) {
                this->_table[i - 1][m - 1] = this->_table.front()[m - 1];
                REPD(j, l, m-1) {
                    this->_table[i - 1][j] = this->_table.front()[j] + this->_table[i - 1][j + 1];
                }

                this->_table[i - 1][m] = this->_table.front()[m];
                REP(j, m + 1, std::min(l + len, this->_n)) {
                    this->_table[i - 1][j] = this->_table[i - 1][j - 1] + this->_table.front()[j];
                }
            }
        }

        this->_built = true;

        return *this;
    }

    inline auto& raw() noexcept(NO_EXCEPT) {
        this->_built = false;
        return this->_table.front();
    }

    inline const auto& raw() const noexcept(NO_EXCEPT) { return this->_table.front(); }

    inline auto& data() noexcept(NO_EXCEPT) { return this->_table; }
    inline const auto& data() const noexcept(NO_EXCEPT) { return this->_table; }

    size_type size() const noexcept(NO_EXCEPT) { return this->_n; }

    operand fold(const size_type l, size_type r) {
        if(l == r) return operand{};
        if(l == --r) return this->_table.front()[l];

        this->build();

        const size_type p = highest_bit_pos<std::make_unsigned_t<size_type>>(l ^ r);
        return this->_table[p][l] + this->_table[p][r];
    }
};


} // namespace disjoint_sparse_table_impl

} // namespace internal




template<class> struct disjoint_sparse_table : internal::unconstructible {};


template<algebraic::internal::semigroup Semigroup>
struct disjoint_sparse_table<Semigroup> {
  private:
    using core = internal::disjoint_sparse_table_impl::core<Semigroup>;
    using iterator = core::iterator;

    core _impl;

  public:
    using value_type = Semigroup;
    using size_type = core::size_type;

  protected:
    inline auto _positivize_index(const size_type p) const noexcept(NO_EXCEPT) {
        return p < 0 ? this->_impl.size() + p : p;
    }

  public:
    explicit disjoint_sparse_table(const size_type n, const value_type& val = value_type()) noexcept(NO_EXCEPT) : _impl(n) {
        this->_impl.data().begin()->assign(n, val);
    }

    template<std::input_iterator I, std::sized_sentinel_for<I> S>
    disjoint_sparse_table(I first, S last) noexcept(NO_EXCEPT) : _impl(first, last) {}

    template<std::ranges::input_range R>
    explicit disjoint_sparse_table(R&& range) noexcept(NO_EXCEPT)
      : _impl(std::ranges::begin(range), std::ranges::end(range))
    {}


    inline auto& raw() noexcept(NO_EXCEPT) { return this->_impl.raw(); }
    inline const auto& raw() const noexcept(NO_EXCEPT) { return this->_impl.raw(); }
    inline const auto& data() const noexcept(NO_EXCEPT) { return this->impl.data(); }

    inline auto size() const noexcept(NO_EXCEPT) { return this->_impl.size(); }


    friend internal::range_reference<disjoint_sparse_table>;

    struct range_reference : internal::range_reference<disjoint_sparse_table> {
        range_reference(disjoint_sparse_table *const super, const size_type l, const size_type r) noexcept(NO_EXCEPT)
          : internal::range_reference<disjoint_sparse_table>(super, super->_positivize_index(l), super->_positivize_index(r))
        {
            assert(0 <= this->_begin && this->_begin <= this->_end && this->_end <= this->_super->size());
        }

        inline auto fold() noexcept(NO_EXCEPT) {
            return this->_super->fold(this->_begin, this->_end);
        }
    };


    inline auto fold(size_type l, size_type r) noexcept(NO_EXCEPT) {
        l = this->_positivize_index(l), r = this->_positivize_index(r);
        assert(0 <= l && l <= r && r <= this->size());
        return this->_impl.fold(l, r);
    }
    inline auto fold() noexcept(NO_EXCEPT) { return this->fold(0, this->size()); }

    inline auto operator[](const size_type index) const noexcept(NO_EXCEPT) { return this->_impl.data().front()[index]; }
    inline auto operator()(const size_type l, const size_type r) noexcept(NO_EXCEPT) { return range_reference(this, l, r); }

    inline auto begin() const noexcept(NO_EXCEPT) { return this->_impl.data().begin()->begin(); }
    inline auto end() const noexcept(NO_EXCEPT) { return this->_impl.data().begin()->end(); }

    inline auto rbegin() const noexcept(NO_EXCEPT) { return this->_impl.data().begin()->rbegin(); }
    inline auto rend() const noexcept(NO_EXCEPT) { return this->_impl.data().begin()->rend(); }
};


template<actions::internal::operatable_action Action>
struct disjoint_sparse_table<Action> : disjoint_sparse_table<typename Action::operand> {
    using disjoint_sparse_table<typename Action::operand>::disjoint_sparse_table;
};


} // namespace uni
#line 2 "data_structure/dynamic_segment_tree.hpp"


#include <memory_resource>
#line 6 "data_structure/dynamic_segment_tree.hpp"
#include <memory>
#line 13 "data_structure/dynamic_segment_tree.hpp"


#line 16 "data_structure/dynamic_segment_tree.hpp"

#line 23 "data_structure/dynamic_segment_tree.hpp"

#line 2 "data_structure/internal/node_handler.hpp"


#line 5 "data_structure/internal/node_handler.hpp"

#line 7 "data_structure/internal/node_handler.hpp"


namespace uni {

namespace node_handlers {

namespace internal {


template<class Allocator, class NodeType>
struct base_handler {
    using allocator_type = Allocator;

  protected:
    using allocator_traits = std::allocator_traits<allocator_type>;

    using node_allocator_type = allocator_traits::template rebind_alloc<NodeType>;
    using node_allocator_traits = std::allocator_traits<node_allocator_type>;

    [[no_unique_address]] node_allocator_type _allocator;

  public:
    base_handler(const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT)
        : _allocator(allocator)
    {}

    base_handler(const base_handler& source) noexcept(NO_EXCEPT)
        : _allocator(node_allocator_traits::select_on_container_copy_construction(source._allocator))
    {}

    base_handler(base_handler&& source) noexcept = default;

    auto& operator=(const base_handler& source) noexcept(NO_EXCEPT) {
        if(&source != this) {
            if constexpr(allocator_traits::propagate_on_container_copy_assignment::value) {
                this->_allocator = source._allocator;
            }
        }
        return *this;
    }

    auto& operator=(base_handler&& source) noexcept(NO_EXCEPT) {
        if(&source != this) {
            if constexpr(allocator_traits::propagate_on_container_move_assignment::value) {
                this->_allocator = source._allocator;
            }
        }
        return *this;
    }
};


} // namespace internal


template<class Allocator>
struct cloneable {
    template<class NodeType>
    struct handler : internal::base_handler<Allocator, NodeType> {
        using internal::base_handler<Allocator, NodeType>::base_handler;

        using node_type = NodeType;
        using node_pointer = std::shared_ptr<node_type>;

        inline static node_pointer nil = std::make_shared<node_type>();

        template<class... Args>
        inline auto create(Args&&... args) noexcept(NO_EXCEPT) {
            return std::allocate_shared<node_type>(this->_allocator, std::forward<Args>(args)...);
        }

        inline auto clone(const node_pointer& ptr) noexcept(NO_EXCEPT) {
            return this->create(*ptr);
        }

        inline constexpr bool disposable(const node_pointer&) const noexcept { return false; }
        inline constexpr void dispose(const node_pointer&) const noexcept {}
    };
};


template<class Allocator>
struct reusing {
    template<class NodeType>
    struct handler : internal::base_handler<Allocator, NodeType> {
        using node_type = NodeType;
        using node_pointer = std::add_pointer_t<node_type>;

      private:
        using base = internal::base_handler<Allocator, NodeType>;
        using node_allocator_traits = typename base::node_allocator_traits;

        inline static int _instance_count = 0;

      public:
        using base::base;

        using allocator_type = typename base::allocator_type;


        inline static node_pointer nil;


        handler(const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT) : base(allocator) {
            if(handler::_instance_count++ == 0) {
                handler::nil = new node_type{};
            }
        }

        ~handler() noexcept {
            if(--handler::_instance_count == 0) {
                delete handler::nil;
            }
        }


        template<class... Args>
        inline auto create(Args&&... args) noexcept(NO_EXCEPT) {
            node_pointer node = node_allocator_traits::allocate(this->_allocator, 1);
            node_allocator_traits::construct(this->_allocator, node, std::forward<Args>(args)...);

            return node;
        }

        inline auto clone(const node_pointer ptr) const noexcept { return ptr; }

        inline bool disposable(const node_pointer node) const noexcept(NO_EXCEPT) {
            return node != handler::nil;
        }

        inline void dispose(const node_pointer node) noexcept(NO_EXCEPT) {
            node_allocator_traits::destroy(this->_allocator, node);
            node_allocator_traits::deallocate(this->_allocator, node, 1);
        }
    };
};


} // namespace node_handlers

} // namespace uni
#line 25 "data_structure/dynamic_segment_tree.hpp"

#line 28 "data_structure/dynamic_segment_tree.hpp"

#line 30 "data_structure/dynamic_segment_tree.hpp"


namespace uni {

namespace internal {


namespace dynamic_segment_tree_impl {


// Thanks to: atcoder::segtree
template<algebraic::internal::monoid Monoid, class NodeHandler>
struct core {
    using size_type = internal::size_t;
    using operand = Monoid;

    struct node_type;
    using node_handler = NodeHandler::template handler<node_type>;

    using allocator_type = typename node_handler::allocator_type;
    using node_pointer = typename node_handler::node_pointer;

  protected:
    [[no_unique_address]] node_handler _node_handler;

  public:
    explicit core(const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT) : _node_handler(allocator) {}

    core(const core&, const allocator_type& allocator) noexcept(NO_EXCEPT) : _node_handler(allocator) {}
    core(core&&, const allocator_type& allocator) noexcept(NO_EXCEPT) : _node_handler(allocator) {}


    struct node_type {
        size_type index;
        operand val, acc;

        node_pointer left = node_handler::nil, right = node_handler::nil;

        node_type() noexcept = default;

        node_type(const size_type _index, const operand& _val) noexcept(NO_EXCEPT)
          : index(_index), val(_val), acc(_val)
        {}
    };

  protected:
    inline void pull(const node_pointer& tree) const noexcept(NO_EXCEPT) {
        tree->acc = tree->left->acc + tree->val + tree->right->acc;
    }


    inline void dispose(const node_pointer& tree) noexcept(NO_EXCEPT) {
        if(this->_node_handler.disposable(tree)) {
            this->dispose(tree->left);
            this->dispose(tree->right);

            this->_node_handler.dispose(tree);
        }
    }

  public:
    template<std::random_access_iterator I>
    node_pointer build(const size_type lower, const size_type upper, const size_type l, const size_type r, I first) noexcept(NO_EXCEPT) {
        const size_type middle = (lower + upper) >> 1;
        const auto itr = std::ranges::next(first, middle);

        if(middle < l || r <= middle) return node_handler::nil;

        node_pointer node = this->_node_handler.create(middle, *itr);

        node->left = this->build(lower, middle, l, middle, first);
        node->right = this->build(middle, upper, middle + 1, r, first);

        this->pull(node);

        return node;
    }

    template<std::random_access_iterator I, std::sentinel_for<I> S>
    node_pointer build(I first, S last) noexcept(NO_EXCEPT) {
        const size_type size = std::ranges::distance(first, last);
        return this->build(0, size, 0, size, first);
    }


    void set(node_pointer& tree, const size_type lower, const size_type upper, size_type pos, operand val) noexcept(NO_EXCEPT) {
        if(tree == node_handler::nil) {
            tree = this->_node_handler.create(pos, val);
            return;
        }

        tree = this->_node_handler.clone(tree);

        if(tree->index == pos) {
            tree->val = val;
            this->pull(tree);
            return;
        }

        const size_type middle = (lower + upper) >> 1;

        if(pos < middle) {
            if(tree->index < pos) std::swap(tree->index, pos), std::swap(tree->val, val);
            this->set(tree->left, lower, middle, pos, val);
        }
        else {
            if(pos < tree->index) std::swap(tree->index, pos), std::swap(tree->val, val);
            this->set(tree->right, middle, upper, pos, val);
        }

        this->pull(tree);
    }


    operand get(const node_pointer& tree, const size_type lower, const size_type upper, const size_type pos) const noexcept(NO_EXCEPT) {
        if(tree == node_handler::nil) return {};
        if(tree->index == pos) return tree->val;

        const size_type middle = (lower + upper) >> 1;

        if(pos < middle) return this->get(tree->left, lower, middle, pos);
        else return this->get(tree->right, middle, upper, pos);
    }


    operand fold(const node_pointer& tree, const size_type lower, const size_type upper, const size_type l, const size_type r) const noexcept(NO_EXCEPT) {
        if(tree == node_handler::nil || upper <= l || r <= lower) return {};
        if(l <= lower && upper <= r) return tree->acc;

        const size_type middle = (lower + upper) >> 1;

        operand val = this->fold(tree->left, lower, middle, l, r);
        if(l <= tree->index && tree->index < r) val = val + tree->val;

        return val + this->fold(tree->right, middle, upper, l, r);
    }


    void clear(const node_pointer& tree, const size_type lower, const size_type upper, const size_type l, const size_type r) const noexcept(NO_EXCEPT) {
        if(tree == node_handler::nil || upper <= l || r <= lower) return;

        if(l <= lower && upper <= r) {
            this->dispose(tree);
            tree = node_handler::nil;
            return;
        }

        const size_type middle = (lower + upper) >> 1;

        this->clear(tree->left, lower, middle, l, r);
        this->clear(tree->right, middle, upper, l, r);

        this->pull(tree);
    }


    template<class F>
    size_type max_right(const node_pointer& tree, const size_type lower, const size_type upper, const size_type l, F&& f, operand& acc) const {
        if(tree == node_handler::nil || upper <= l) return -1;

        if(f(acc + tree->acc)) {
            acc = acc + tree->acc;
            return -1;
        }

        const size_type middle = (lower + upper) >> 1;
        const size_type res = this->max_right(tree->left, lower, middle, l, f, acc);

        if(res != -1) return res;

        if(l <= tree->index && !f(acc = acc + tree->val)) return tree->index;

        return this->max_right(tree->right, middle, upper, l, std::forward<F>(f), acc);
    }

    template<class F>
    size_type min_left(const node_pointer& tree, const size_type lower, const size_type upper, const size_type r, F&& f, operand& acc) const {
        if(tree == node_handler::nil || r <= lower) return 0;

        if(f(tree->acc + acc)) {
            acc = tree->acc + acc;
            return 0;
        }

        const size_type middle = (lower + upper) >> 1;
        const size_type res = this->min_left(tree->right, middle, upper, r, f, acc);

        if(res != 0) return res;

        if(tree->index < r && !f(acc = tree->val + acc)) {
            return tree->index + 1;
        }

        return this->min_left(tree->left, lower, middle, r, std::forward<F>(f), acc);
    }

  public:
    debugger::debug_t dump_rich(const node_pointer& tree, const std::string prefix = "   ", const int dir = 0) const {
        if(!tree || tree == node_handler::nil) return prefix + "\n";

        const auto left = this->dump_rich(tree->left, prefix + (dir == 1 ? "| " : "  "), -1);
        const auto here = prefix + "--+ " + debugger::dump(tree->index) + " : " + debugger::dump(tree->val) + "\n";

        const auto right = this->dump_rich(tree->right, prefix + (dir == -1 ? "| " : "  "), 1);

        return left + here + right;
    }

    debugger::debug_t _debug(const node_pointer tree) const {
        if(!tree || tree == node_handler::nil) return "";

        return
            "(" +
            this->_debug(tree->left) + " " +
            debugger::dump(tree->index) + " : " + debugger::dump(tree->val) +
            this->_debug(tree->right) +
            ")";
    }
};


} // namespace dynamic_segment_tree_impl

} // namespace internal


template<class T, class = node_handlers::reusing<std::allocator<T>>>
struct dynamic_segment_tree : internal::unconstructible {};


template<actions::internal::operatable_action Action, class NodeHandler>
struct dynamic_segment_tree<Action, NodeHandler>
  : private internal::dynamic_segment_tree_impl::core<typename Action::operand, NodeHandler>
{
  private:
    using core = typename internal::dynamic_segment_tree_impl::core<typename Action::operand, NodeHandler>;

  public:
    using value_type = typename core::operand;
    using size_type = typename core::size_type;

    using node_handler = typename core::node_handler;
    using allocator_type = typename core::allocator_type;

    using node_type = typename core::node_type;
    using node_pointer = typename core::node_pointer;

  private:
    inline auto _positivize_index(const size_type p) const noexcept(NO_EXCEPT) {
        return p < 0 ? this->_n + p : p;
    }

    size_type _n = 0;
    node_pointer _root = node_handler::nil;

  public:
    ~dynamic_segment_tree() { this->dispose(this->_root); }

    dynamic_segment_tree(const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT) : core(allocator) {};

    dynamic_segment_tree(const dynamic_segment_tree& source, const allocator_type& allocator) noexcept(NO_EXCEPT)
      : core(allocator), _n(source._n), _root(source._root)
    {}

    dynamic_segment_tree(dynamic_segment_tree&& source, const allocator_type& allocator) noexcept(NO_EXCEPT)
      : core(allocator), _n(source._n), _root(source._root)
    {}

    explicit dynamic_segment_tree(const size_type n, const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT)
      : core(allocator), _n(n)
    {}

    template<std::convertible_to<value_type> T>
    dynamic_segment_tree(const std::initializer_list<T>& init_list, const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT)
      : dynamic_segment_tree(init_list, allocator)
    {}

    template<std::input_iterator I, std::sized_sentinel_for<I> S>
    dynamic_segment_tree(I first, S last, const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT) : dynamic_segment_tree(allocator) {
        this->assign(first, last);
    }

    template<std::ranges::input_range R>
        requires (!std::same_as<std::remove_cvref_t<R>, dynamic_segment_tree>)
    dynamic_segment_tree(R&& range, const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT)
      : dynamic_segment_tree(ALL(range), allocator)
    {}


    inline auto clone() const noexcept(NO_EXCEPT) { return *this; }

    inline auto size() const noexcept(NO_EXCEPT) { return this->_n; }


    inline auto& clear() noexcept(NO_EXCEPT) {
        this->dispose(this->_root);
        this->_n = 0;
        this->_root = node_handler::nil;
        return *this;
    }


    template<std::convertible_to<value_type> T>
    inline auto& assign(const std::initializer_list<T>& init_list) noexcept(NO_EXCEPT) { return this->assign(init_list); }

    template<std::input_iterator I, std::sized_sentinel_for<I> S>
    inline auto& assign(I first, S last) noexcept(NO_EXCEPT) {
        this->_n = std::ranges::distance(first, last);
        this->_root = this->build(first, last);
        return *this;
    }

    template<std::ranges::input_range R>
    inline auto& assign(R&& range) noexcept(NO_EXCEPT) { return this->assign(ALL(range)); }


    inline auto& set(const size_type pos, value_type val) noexcept(NO_EXCEPT) {
        assert(pos < this->_n);
        this->core::set(this->_root, 0, this->_n, pos, val);
        return *this;
    }


    inline auto get(const size_type pos) const noexcept(NO_EXCEPT) {
        assert(pos < this->_n);
        return this->core::get(this->_root, 0, this->_n, pos);
    }


    inline auto& add(const size_type pos, const value_type&  val) noexcept(NO_EXCEPT) {
        assert(0 <= pos && pos < this->_n);
        this->set(pos, this->get(pos) + val);
        return *this;
    }


    inline auto fold(const size_type l, const size_type r) const noexcept(NO_EXCEPT) {
        assert(0 <= l && l <= r && r <= this->_n);
        return this->core::fold(this->_root, 0, this->_n, l, r);
    }

    inline auto fold() const noexcept(NO_EXCEPT) { return this->_root->acc; }


    inline auto& clear(const size_type l, const size_type r) noexcept(NO_EXCEPT) {
        assert(0 <= l && l <= r && r <= this->_n);
        this->core::clear(this->_root, 0, this->_n, l, r);
        return *this;
    }


    template<bool (*f)(value_type)>
    inline auto max_right(const size_type l) const noexcept(NO_EXCEPT) {
        return this->max_right(l, [](const value_type&  val) { return f(val); });
    }

    template<class F>
    inline auto max_right(const size_type l, const F &f) const noexcept(NO_EXCEPT) {
        assert(0 <= l && l <= this->_n);
        value_type acc;
        assert(f(acc));
        const auto res = this->core::max_right(this->_root, 0, this->_n, l, f, acc);
        return res == -1 ? this->_n : res;
    }


    template<bool (*f)(value_type)>
    inline auto min_left(const size_type r) const noexcept(NO_EXCEPT) {
        return this->min_left(r, [](const value_type&  val) noexcept(NO_EXCEPT) { return f(val); });
    }

    template<class F>
    inline auto min_left(const size_type r, const F &f) const noexcept(NO_EXCEPT) {
        assert(0 <= r && r <= this->_n);
        value_type acc;
        assert(f(acc));
        return this->core::min_left(this->_root, 0, this->_n, r, f, acc);
    }


    struct point_reference : internal::point_reference<dynamic_segment_tree> {
        point_reference(dynamic_segment_tree *const super, const size_type p) noexcept(NO_EXCEPT)
          : internal::point_reference<dynamic_segment_tree>(super, super->_positivize_index(p))
        {
            assert(0 <= this->_pos && this->_pos < this->_super->_n);
        }

        inline operator value_type() const noexcept(NO_EXCEPT) { return this->_super->get(this->_pos); }
        inline auto val() const noexcept(NO_EXCEPT) { return this->_super->get(this->_pos); }

        inline auto& operator=(const value_type& v) noexcept(NO_EXCEPT) {
            this->_super->set(this->_pos, v);
            return *this;
        }

        inline auto& operator+=(const value_type& v) noexcept(NO_EXCEPT) {
            this->_super->add(this->_pos, v);
            return *this;
        }
    };

    struct range_reference : internal::range_reference<dynamic_segment_tree> {
        range_reference(dynamic_segment_tree *const super, const size_type l, const size_type r) noexcept(NO_EXCEPT)
          : internal::range_reference<dynamic_segment_tree>(super, super->_positivize_index(l), super->_positivize_index(r))
        {
            assert(0 <= this->_begin && this->_begin <= this->_end && this->_end <= this->_super->_n);
        }

        inline auto fold() noexcept(NO_EXCEPT) {
            return this->_super->fold(this->_begin, this->_end);
        }
    };


    inline auto operator[](const size_type p) noexcept(NO_EXCEPT) { return point_reference(this, p); }
    inline auto operator()(const size_type l, const size_type r) noexcept(NO_EXCEPT) { return range_reference(this, l, r); }


  public:
    struct iterator;

  protected:
    using iterator_interface = internal::container_iterator_interface<value_type, const dynamic_segment_tree, iterator>;

  public:
    struct iterator : iterator_interface {
        using iterator_interface::iterator_interface;
    };

    inline auto begin() const noexcept(NO_EXCEPT) { return iterator(this, 0); }
    inline auto end() const noexcept(NO_EXCEPT) { return iterator(this, this->_n); }

    inline auto rbegin() const noexcept(NO_EXCEPT) { return std::make_reverse_iterator(this->end()); }
    inline auto rend() const noexcept(NO_EXCEPT) { return std::make_reverse_iterator(this->begin()); }


    using core::dump_rich;
    using core::_debug;


    debugger::debug_t dump_rich(const std::string prefix = "   ") const {
        return "\n" + this->dump_rich(this->_root, prefix);
    }

    debugger::debug_t _debug() const {
        return "[ " + this->_debug(this->_root) + " ]";
    }
};


template<class Action, class Allocator = std::allocator<Action>>
using persistent_dynamic_segment_tree = dynamic_segment_tree<Action, node_handlers::cloneable<Allocator>>;


namespace pmr {


template<class Action>
using dynamic_segment_tree = uni::dynamic_segment_tree<Action, std::pmr::polymorphic_allocator<Action>>;

template<class Action>
using persistent_dynamic_segment_tree = uni::persistent_dynamic_segment_tree<Action, std::pmr::polymorphic_allocator<Action>>;


}; // namespace pmr

} // namespace uni
#line 2 "data_structure/dynamic_sequence.hpp"


#line 12 "data_structure/dynamic_sequence.hpp"

#line 15 "data_structure/dynamic_sequence.hpp"

#line 2 "internal/uncopyable.hpp"


namespace uni {

namespace internal {


struct uncopyable {
    uncopyable() noexcept {}
    uncopyable(const uncopyable&) = delete;
    uncopyable& operator=(const uncopyable&) = delete;
};


} // namespace internal

} // namespace uni
#line 22 "data_structure/dynamic_sequence.hpp"

#line 25 "data_structure/dynamic_sequence.hpp"

#line 27 "data_structure/dynamic_sequence.hpp"

#line 2 "data_structure/internal/basic_tree_concept.hpp"


#line 6 "data_structure/internal/basic_tree_concept.hpp"

#line 8 "data_structure/internal/basic_tree_concept.hpp"


namespace uni {

namespace internal {


template<class T>
concept basic_tree =
    std::default_initializable<T> &&
    std::integral<typename T::size_type> &&
    requires (T base, typename T::size_type key, typename T::node_pointer tree, const typename T::node_pointer const_tree) {
        base.split(const_tree, key, tree, tree);
        base.merge(tree, const_tree, const_tree);
    };


} // namespace internal


} // namespace name
#line 2 "data_structure/internal/tree_dumper.hpp"


#line 5 "data_structure/internal/tree_dumper.hpp"


#line 9 "data_structure/internal/tree_dumper.hpp"


namespace uni {

namespace internal {


template<class Derived, class Core, bool LEAF_ONLY>
struct dumpable_tree {
  private:
    using node_handler = Core::node_handler;
    using node_pointer = Core::node_pointer;

    using size_type = Core::size_type;

    inline auto _push(const node_pointer& tree) {
        return static_cast<Derived*>(this)->_impl.push(tree);
        // return static_cast<Derived*>(this)->push(tree);
    }

  public:
    debugger::debug_t dump_rich(node_pointer tree, const std::string prefix, const int dir, size_type& index)
        requires (!LEAF_ONLY)
    {
        if(!tree || tree == node_handler::nil) return prefix + "\n";

        this->_push(tree);

        // debug(tree->priority >= tree->left->priority, tree->priority, tree->left->priority);
        // debug(tree->priority >= tree->right->priority, tree->priority, tree->right->priority);
        assert(tree->priority >= tree->left->priority);
        assert(tree->priority >= tree->right->priority);

        const auto left = this->dump_rich(tree->left, prefix + (dir == 1 ? "| " : "  "), -1, index);
        const auto here =
            prefix + "--+ [" +
            debugger::dump(index) + ", " + debugger::dump(index + tree->length) + ") : " +
            "<" + debugger::dump(tree->priority) + "> " +
            debugger::dump(tree->data) + " [" + debugger::dump(tree->length) + "]\n";
        index += tree->length;

        const auto right = this->dump_rich(tree->right, prefix + (dir == -1 ? "| " : "  "), 1, index);

        return left + here + right;
    }

    debugger::debug_t dump_rich(node_pointer tree, const std::string prefix, const int dir, size_type& index)
        requires
            (
                LEAF_ONLY &&
                requires {
                    typename Core::node_colors;
                }
            )
    {
        if(!tree || tree == node_handler::nil) return prefix + "\n";

        this->_push(tree);

        const auto left = this->dump_rich(tree->left, prefix + (dir == 1 ? "| " : "  "), -1, index);
        const auto right = this->dump_rich(tree->right, prefix + (dir == -1 ? "| " : "  "), 1, index);


        const auto color = tree->color == Core::node_colors::BLACK ? "<->" : "<+>";

        const auto here = [&]() -> std::string {
            if(tree->is_leaf()) {
                index += tree->size;

                return
                    prefix + "--+ [" +
                    debugger::dump(index - tree->size) + ", " + debugger::dump(index) + ") : " +
                    debugger::COLOR_STRING + color + debugger::COLOR_INIT + " " +
                    debugger::dump(tree->data) + " [" + debugger::dump(tree->size) + "]\n";
            }
            return "";
        }();

        return left + here + right;
    }


    inline debugger::debug_t dump_rich(const node_pointer& tree, const std::string prefix = "   ", const int dir = 0) {
        size_type index = 0;
        return this->dump_rich(tree, prefix, dir, index);
    }


    debugger::debug_t _debug(node_pointer tree)
        requires (!LEAF_ONLY)
    {
        if(!tree || tree == node_handler::nil) return "";

        this->_push(tree);

        return
            "(" +
            this->_debug(tree->left) + " " +
            debugger::dump(tree->data) + " [" +
            debugger::dump(tree->length) + "] " +
            this->_debug(tree->right) +
            ")";
    }

    debugger::debug_t _debug(node_pointer tree)
        requires LEAF_ONLY
    {
        if(!tree || tree == node_handler::nil) return "";

        this->_push(tree);

        return
            "(" +
            this->_debug(tree->left) + " " +
            (
                tree->is_leaf()
                    ?
                        debugger::dump(tree->data) + " [" +
                        debugger::dump(tree->size) + "] "
                    :
                        ""
            ) +
            this->_debug(tree->right) +
            ")";
    }
};


} // namespace internal


} // namespace uni
#line 2 "data_structure/internal/dynamic_tree.hpp"


#line 6 "data_structure/internal/dynamic_tree.hpp"


#line 9 "data_structure/internal/dynamic_tree.hpp"

#line 12 "data_structure/internal/dynamic_tree.hpp"

#line 15 "data_structure/internal/dynamic_tree.hpp"

#line 17 "data_structure/internal/dynamic_tree.hpp"




namespace uni {

namespace internal {

namespace dynamic_tree_impl {

namespace internal {



template<class T>
consteval auto to_val() {
    if constexpr(actions::internal::operatable_action<T>) return typename T::operand{};
    else return T{};
}

template<class T>
consteval auto to_acc() {
    if constexpr(actions::internal::operatable_action<T>) return typename T::operand{};
    else return dummy{};
}

template<class T>
consteval auto to_lazy() {
    if constexpr(actions::internal::effective_action<T>) return typename T::operation{};
    else return dummy{};
}


template<class T, bool LEAF_ONLY, bool MAY_BE_LAZY = true>
struct data_type {
    using val_t = decltype(to_val<T>());
    using acc_t = decltype(to_acc<T>());
    using lazy_t = decltype(to_lazy<T>());

    val_t val;
    [[no_unique_address]] acc_t acc;
    [[no_unique_address]] std::conditional_t<MAY_BE_LAZY, lazy_t, dummy> lazy;

    bool rev = false;

    data_type() noexcept = default;
    data_type(const val_t& _val) noexcept(NO_EXCEPT) : val(_val) {}

    auto _debug() const { return this->val; }


    friend bool operator==(const data_type& lhs, const data_type& rhs) noexcept(NO_EXCEPT) {
        return lhs.val == rhs.val;
    }

    friend auto operator<=>(const data_type& lhs, const data_type& rhs) noexcept(NO_EXCEPT) {
        return lhs.val <=> rhs.val;
    }
};



template<class ActionOrValue, class Derived, class Context>
struct basic_core
  : Context::substance<Derived, internal::data_type<ActionOrValue, Context::LEAF_ONLY>>
{
    using data_type = internal::data_type<ActionOrValue, Context::LEAF_ONLY>;

  private:
    using base = typename Context::substance<Derived, data_type>;
    static_assert(basic_tree<base>);

  public:
    using base::base;

    using node_handler = typename base::node_handler;
    using node_pointer = typename base::node_pointer;

    using size_type = typename base::size_type;

    using operand = data_type::val_t;
    using operation = data_type::lazy_t;


    inline auto val(const node_pointer& node) const noexcept(NO_EXCEPT) {
        if constexpr(Context::LEAF_ONLY) {
            if(node->is_leaf()) return node->size * node->data.val;
            return node->data.val;
        }
        else {
            return node->data.acc;
        }
    }


    using base::split;
    using base::merge;


    inline void split(const node_pointer tree, const size_type l, const size_type r, node_pointer& t0, node_pointer& t1, node_pointer& t2) noexcept(NO_EXCEPT) {
        // See: https://twitter.com/KakurenboUni/status/1784576244321018209
        this->split(tree, l, t0, t1);
        this->split(t1, r - l, t1, t2);
    }

    inline void split(
        const node_pointer tree,
        const size_type l, const size_type m, const size_type r,
        node_pointer& t0, node_pointer& t1, node_pointer& t2, node_pointer& t3
    ) noexcept(NO_EXCEPT) {
        // See: https://twitter.com/KakurenboUni/status/1784576244321018209
        this->split(tree, l, m, t0, t1, t2);
        this->split(t2, r - m, t2, t3);
    }

    inline void merge(node_pointer& tree, node_pointer t0, const node_pointer t1, const node_pointer t2) noexcept(NO_EXCEPT) {
        this->merge(t0, t0, t1);
        this->merge(tree, t0, t2);
    }



    void erase(node_pointer& tree, const size_type l, const size_type r) noexcept(NO_EXCEPT) {
        assert(l <= r);
        node_pointer t0, t1, t2;

        this->split(tree, l, r, t0, t1, t2);
        this->dispose(t1);
        this->merge(tree, t0, t2);
    }


    auto pop(node_pointer& tree, const size_type pos, const size_type count = 1) noexcept(NO_EXCEPT) {
        assert(0 <= count);

        if(count == 0) return operand{};

        node_pointer t0, t1, t2;

        this->split(tree, pos, pos + count, t0, t1, t2);

        const auto res = this->val(t1);

        this->dispose(t1);
        this->merge(tree, t0, t2);

        return res;
    }


    operand get(node_pointer tree, const size_type pos) noexcept(NO_EXCEPT) {
        if(tree == node_handler::nil || pos < 0 || pos >= tree->size) return {};

        this->base::push(tree);

        const auto lower_bound = tree->left->size;
        const auto upper_bound = tree->size - tree->right->size;

        if(pos < lower_bound) {
            return this->get(tree->left, pos);
        }
        else if(pos >= upper_bound) {
            return this->get(tree->right, pos - upper_bound);
        }
        else {
            return tree->data.val;
        }
    }



    template<std::forward_iterator I>
        requires std::output_iterator<I, operand>
    void enumerate(node_pointer tree, I& itr) noexcept(NO_EXCEPT) {
        if(tree == node_handler::nil) return;

        this->base::push(tree);

        this->enumerate(tree->left, itr);

        if constexpr(Context::LEAF_ONLY) {
            if(tree->is_leaf()) {
                REP(tree->size) *(itr++) = tree->data.val;
            }
        }
        else {
            REP(tree->length) *(itr++) = tree->data.val;
        }

        this->enumerate(tree->right, itr);
    }

    auto fold(node_pointer& tree, size_type l, size_type r) noexcept(NO_EXCEPT) {
        assert(l <= r);
        if(l == r) return operand{};

        node_pointer t0, t1, t2;

        this->split(tree, l, r, t0, t1, t2);

        const operand res = this->val(t1);

        this->merge(tree, t0, t1, t2);

        return res;
    }
};


} // namespace internal

} // namespace dynamic_tree_impl

} // namespace internal

} // namespace uni
#line 31 "data_structure/dynamic_sequence.hpp"

#line 2 "data_structure/treap.hpp"


#line 13 "data_structure/treap.hpp"


#line 17 "data_structure/treap.hpp"

#line 23 "data_structure/treap.hpp"

#line 25 "data_structure/treap.hpp"

#line 27 "data_structure/treap.hpp"

#line 29 "data_structure/treap.hpp"


#line 32 "data_structure/treap.hpp"


namespace uni {

namespace internal {


// Thanks to: https://github.com/xuzijian629/library2/blob/master/treap/implicit_treap.cpp
template<class Allocator, class Derived, std::integral SizeType, class ValueType, i64 Id>
struct treap_impl : private uncopyable {
    using size_type = SizeType;
    using value_type = ValueType;

    struct node_type;
    using node_handler = typename uni::node_handlers::reusing<Allocator>::template handler<node_type>;

    using allocator_type = typename node_handler::allocator_type;
    using node_pointer = typename node_handler::node_pointer;

  private:
    using derived = Derived;

    inline auto* _derived() noexcept(NO_EXCEPT) {
        return static_cast<derived*>(this);
    }
    inline const auto* _derived() const noexcept(NO_EXCEPT) {
        return static_cast<const derived*>(this);
    }

    [[no_unique_address]] node_handler _node_handler;


    static inline random_engine_32bit _rand;

    using priority_type = random_engine_32bit::result_type;

  public:
    void pull(const node_pointer tree) noexcept(NO_EXCEPT) {
        if(tree == node_handler::nil) return;
        tree->size = tree->left->size + tree->length + tree->right->size;
        this->_derived()->pull(tree);
    }

    void push(const node_pointer tree) noexcept(NO_EXCEPT) {
        if(tree == node_handler::nil) return;
        this->_derived()->push(tree);
    }


    node_pointer create(const value_type& val, const size_type size) noexcept(NO_EXCEPT) {
        if(size == 0) return node_handler::nil;
        return this->_node_handler.create(val, size);
    }

    void dispose(node_pointer tree) noexcept(NO_EXCEPT) {
        if(this->_node_handler.disposable(tree)) {
            this->dispose(tree->left);
            this->dispose(tree->right);

            this->_node_handler.dispose(tree);
        }
    }

    template<class... Args>
    inline void constexpr clone(Args&&...) const noexcept {}

  private:
    void _rotate_right(node_pointer& tree) noexcept(NO_EXCEPT) {  // push ommitted
        auto t = tree->left;

        tree->left = t->right;
        this->pull(tree);

        t->right = tree;
        this->pull(t);

        tree = std::move(t);
    }


    void _rectify(const node_pointer tree) const noexcept(NO_EXCEPT) {
        if(tree->size == 0) return;

        std::vector<priority_type> priorities(tree->size);
        std::ranges::generate(priorities, treap_impl::_rand);
        std::ranges::make_heap(priorities);

        std::queue<node_pointer> queue;
        queue.push(tree);

        auto itr = std::ranges::begin(priorities);
        while(!queue.empty()) {
            node_pointer node = queue.front();
            queue.pop();

            node->priority = *(itr++);

            if(node->left != node_handler::nil) queue.push(node->left);
            if(node->right != node_handler::nil) queue.push(node->right);
        }
    }


    template<std::random_access_iterator I, std::sized_sentinel_for<I> S>
        requires std::constructible_from<value_type, std::iter_value_t<I>>
    node_pointer _build(I first, S last) noexcept(NO_EXCEPT) {
        if(first == last) return node_handler::nil;

        const auto length = std::ranges::distance(first, last);
        const auto middle = std::ranges::next(first, length >> 1);

        node_pointer tree = this->create(value_type{ *middle }, 1);
        tree->left = this->_build(first, middle);
        tree->right = this->_build(std::ranges::next(middle), last);

        this->pull(tree);

        return tree;
    }


    template<std::random_access_iterator I, std::sized_sentinel_for<I> S>
        requires
            std::constructible_from<value_type, typename std::iter_value_t<I>::first_type> &&
            std::integral<typename std::iter_value_t<I>::second_type>
    node_pointer _build(I first, S last) noexcept(NO_EXCEPT) {
        if(first == last) return node_handler::nil;

        const auto length = std::ranges::distance(first, last);
        const auto middle = std::ranges::next(first, length >> 1);

        node_pointer tree = this->create(value_type{ middle->first }, middle->second );
        tree->left = this->_build(first, middle);
        tree->right = this->_build(std::ranges::next(middle), last);

        this->pull(tree);

        return tree;
    }

    void _split(node_pointer tree, const size_type pos, node_pointer& left, node_pointer& right) noexcept(NO_EXCEPT) {
        if(tree == node_handler::nil) {
            left = right = node_handler::nil;
            return;
        }

        this->push(tree);

        const auto lower_bound = tree->left->size;
        const auto upper_bound = tree->size - tree->right->size;

        if(pos <= lower_bound) {
            node_pointer t;
            this->split(tree->left, pos, left, t);
            tree->left = t;

            if(tree->priority < t->priority) this->_rotate_right(tree);

            right = std::move(tree);
            this->pull(right);
        }
        else if(pos >= upper_bound) {
            this->split(tree->right, pos - upper_bound, tree->right, right);

            left = std::move(tree);
            this->pull(left);
        }
        else {
            tree->length = pos - lower_bound;
            this->merge(tree->right, this->create(tree->data, upper_bound - pos), tree->right);

            this->split(tree->right, 0, tree->right, right), left = std::move(tree);
            this->pull(left);
        }
    }

  public:
    explicit treap_impl(const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT) : _node_handler(allocator) {}

    template<std::random_access_iterator I, std::sized_sentinel_for<I> S>
    node_pointer build(I first, S last) {
        const auto tree = this->_build(first, last);
        this->_rectify(tree);
        return tree;
    }

    struct node_type {
        priority_type priority = std::numeric_limits<priority_type>::lowest();

        node_pointer left = node_handler::nil, right = node_handler::nil;

        size_type length, size;
        [[no_unique_address]] value_type data;

        node_type() noexcept = default;

        node_type(const value_type& _data, const size_type _size) noexcept(NO_EXCEPT)
            : priority(treap_impl::_rand()), length(_size), size(_size), data(_data)
        {}
    };


    template<bool STRICT = false, bool RETURN_EXISTENCE = false>
    void split(const node_pointer tree, const value_type& val, node_pointer& left, node_pointer& right, bool* exist = nullptr) noexcept(NO_EXCEPT) {
        if(tree == node_handler::nil) {
            left = right = node_handler::nil;
            return;
        }

        this->push(tree);

        if constexpr(RETURN_EXISTENCE) *exist |= val == tree->data;

        if(val < tree->data || (!STRICT && val == tree->data)) {
            this->template split<STRICT, RETURN_EXISTENCE>(tree->left, val, left, tree->left, exist);

            right = std::move(tree);
            this->pull(right);
        }
        else {
            this->template split<STRICT, RETURN_EXISTENCE>(tree->right, val, tree->right, right, exist);

            left = std::move(tree);
            this->pull(left);
        }
    }


    void split(const node_pointer tree, const size_type pos, node_pointer& left, node_pointer& right) noexcept(NO_EXCEPT) {
        if(pos <= 0) {
            left = node_handler::nil;
            this->merge(right, this->create(value_type{}, -pos), std::move(tree));
        }
        else if(tree->size <= pos) {
            right = node_handler::nil;
            this->merge(left, std::move(tree), this->create(value_type{}, pos - tree->size));
        }
        else {
            this->_split(std::move(tree), pos, left, right);
        }
    }


    void merge(node_pointer& tree, const node_pointer left, const node_pointer right) noexcept(NO_EXCEPT) {
        this->push(left);
        this->push(right);

        if(left == node_handler::nil || right == node_handler::nil) {
            tree = left == node_handler::nil ? right : left;
        }
        else if(left->priority < right->priority) {
            this->merge(right->left, left, right->left), tree = std::move(right);
        }
        else {
            this->merge(left->right, left->right, right), tree = std::move(left);
        }

        this->pull(tree);
    }
};


} // namespace internal


template<std::integral SizeType = i64, class Allocator = std::allocator<SizeType>, i64 Id = -1>
struct treap_context {
    static constexpr bool LEAF_ONLY = false;

    template<class Derived, class ValueType = internal::dummy>
    using substance = internal::treap_impl<Allocator, Derived, SizeType, ValueType, Id>;
};


namespace pmr {


template<std::integral SizeType = i64, i64 Id = -1>
using treap_context = uni::treap_context<SizeType, std::pmr::polymorphic_allocator<SizeType>, Id>;


} // namespace pmr


} // namespace uni
#line 33 "data_structure/dynamic_sequence.hpp"

#line 35 "data_structure/dynamic_sequence.hpp"

#line 38 "data_structure/dynamic_sequence.hpp"

#line 40 "data_structure/dynamic_sequence.hpp"


namespace uni {

namespace internal {

namespace dynamic_tree_impl {


template<class ActionOrValue, class Context>
struct sequence_core
  : internal::basic_core<ActionOrValue, sequence_core<ActionOrValue, Context>, Context>
//   ,
    // dumpable_tree<
    //     sequence_core<ActionOrValue, Context>,
    //     internal::basic_core<ActionOrValue, sequence_core<ActionOrValue, Context>, Context>,
    //     Context::LEAF_ONLY
    // >
{
  private:
    using base = typename internal::basic_core<ActionOrValue, sequence_core, Context>;

  public:
    static constexpr bool ACC = actions::internal::operatable_action<ActionOrValue>;
    static constexpr bool LAZY = actions::internal::effective_action<ActionOrValue>;

    using base::base;

    using data_type = base::data_type;

    using operand = base::operand;
    using operation = base::operation;


    using node_handler = typename base::node_handler;

    using node_type = typename base::node_type;
    using node_pointer = typename base::node_pointer;


    using size_type = typename base::size_type;


    inline void pull(const node_pointer& tree) const noexcept(NO_EXCEPT) {
        if constexpr(ACC) {
            if constexpr(Context::LEAF_ONLY) {
                tree->data.val = this->val(tree->left) + this->val(tree->right);
            }
            else {
                tree->data.acc = tree->left->data.acc + tree->length * tree->data.val + tree->right->data.acc;
            }
        }
    }

    inline void push(const node_pointer& tree) noexcept(NO_EXCEPT) {
        if(tree->data.rev) {
            tree->data.rev = false;

            std::swap(tree->left, tree->right);

            if(tree->left != node_handler::nil) {
                this->clone(tree->left);
                tree->left->data.rev ^= 1;
            }
            if(tree->right != node_handler::nil) {
                this->clone(tree->right);
                tree->right->data.rev ^= 1;
            }
        }

        if constexpr(LAZY) {
            if(tree->data.lazy != operation{}) {
                if constexpr(Context::LEAF_ONLY) {
                    if(tree->left != node_handler::nil) {
                        this->clone(tree->left);
                        if(tree->left->is_leaf()) {
                            tree->left->data.val = ActionOrValue::mapping(tree->data.lazy, tree->left->data.val);
                        }
                        else {
                            tree->left->data.lazy = tree->data.lazy + tree->left->data.lazy;
                            tree->left->data.val = ActionOrValue::mapping(ActionOrValue::power(tree->data.lazy, tree->left->size), tree->left->data.val);
                        }
                    }

                    if(tree->right != node_handler::nil) {
                        this->clone(tree->right);
                        if(tree->right->is_leaf()) {
                            tree->right->data.val = ActionOrValue::mapping(tree->data.lazy, tree->right->data.val);
                        }
                        else {
                            tree->right->data.lazy = tree->data.lazy + tree->right->data.lazy;
                            tree->right->data.val = ActionOrValue::mapping(ActionOrValue::power(tree->data.lazy, tree->right->size), tree->right->data.val);
                        }
                    }
                }
                else {
                    if(tree->left != node_handler::nil) {
                        tree->left->data.lazy = tree->data.lazy + tree->left->data.lazy;
                        tree->left->data.acc = ActionOrValue::mapping(ActionOrValue::power(tree->data.lazy, tree->left->size), tree->left->data.acc);
                    }

                    if(tree->right != node_handler::nil) {
                        tree->right->data.lazy = tree->data.lazy + tree->right->data.lazy;
                        tree->right->data.acc = ActionOrValue::mapping(ActionOrValue::power(tree->data.lazy, tree->right->size), tree->right->data.acc);
                    }
                }

                tree->data.val = ActionOrValue::mapping(tree->data.lazy, tree->data.val);
                tree->data.lazy = operation{};
            }
        }
    }


    inline void update(node_pointer& tree) noexcept(NO_EXCEPT) {
        if(tree == node_handler::nil) return;
        this->base::push(tree);
        this->base::pull(tree);
    }



    void insert(node_pointer& tree, const size_type pos, const operand& val, const size_type count = 1) noexcept(NO_EXCEPT) {
        assert(count >= 0);
        if(count == 0) return;

        node_pointer t0, t1;

        this->split(tree, pos, t0, t1);
        this->merge(tree, t0, this->create(val, count), t1);
    }

    template<std::input_iterator I, std::sized_sentinel_for<I> S>
    void insert(node_pointer& tree, const size_type pos, I first, S last) noexcept(NO_EXCEPT) {
        node_pointer t0, t1;

        this->split(tree, pos, t0, t1);
        this->merge(tree, t0, this->build(first, last), t1);
    }


    void add(node_pointer& tree, const size_type pos, const operand& val) noexcept(NO_EXCEPT) {
        node_pointer t0, t1, t2;

        this->split(tree, pos, t0, t1);
        this->split(t1, 1, t1, t2);

        const auto prev = this->val(t1);
        this->dispose(t1);
        t1 = this->create(data_type{ prev + val }, 1);

        this->merge(tree, t0, t1, t2);
    }


    void fill(node_pointer& tree, const size_type l, const size_type r, const operand& val) noexcept(NO_EXCEPT) {
        assert(l <= r);
        if(l == r) return;

        node_pointer t0, t1, t2;
        this->split(tree, l, r, t0, t1, t2);

        // this->split(tree, l, r, t0, t1, t2);

        // this->split(tree, l, t0, t1);
        // debug(this->dump_rich(t0), this->dump_rich(t1));

        // this->split(t1, r - l, t1, t2);
        // debug(this->dump_rich(t1), this->dump_rich(t2));

        this->dispose(t1);
        t1 = this->create(val, r - l);

        this->merge(tree, t0, t1, t2);

        // this->merge(t0, t0, t1);
        // debug(this->dump_rich(t0));

        // this->merge(tree, t0, t2);
        // debug(this->dump_rich(tree));
    }

    template<std::input_iterator I, std::sized_sentinel_for<I> S>
    void fill(node_pointer& tree, const size_type pos, I first, S last) noexcept(NO_EXCEPT) {
        node_pointer t0, t1, t2;

        this->split(tree, pos, pos + std::ranges::distance(first, last), t0, t1, t2);
        this->dispose(t1);
        this->merge(tree, t0, this->build(first, last), t2);
    }


    void apply(node_pointer& tree, const size_type l, const size_type r, const operation& val) noexcept(NO_EXCEPT)
        requires LAZY
    {
        assert(l <= r);
        if(l == r) return;

        node_pointer t0, t1, t2;

        this->split(tree, l, r, t0, t1, t2);

        if(t1 == node_handler::nil) t1 = this->create(data_type{}, r - l);
        t1->data.lazy = val + t1->data.lazy;

        this->merge(tree, t0, t1, t2);
    }

    void reverse(node_pointer& tree, const size_type l, const size_type r) noexcept(NO_EXCEPT) {
        assert(l <= r);
        if(l == r) return;

        node_pointer t0, t1, t2;

        this->split(tree, l, r, t0, t1, t2);

        if(t1 != node_handler::nil) t1->data.rev ^= 1;

        this->merge(tree, t0, t1, t2);
    }


    void shift_left(node_pointer& tree, const size_type l, const size_type r, const size_type count = 1) noexcept(NO_EXCEPT) {
        assert(l <= r);

        if(count < 0) return this->shift_right(tree, l, r, -count);

        if(count == 0) return;
        if(count >= r - l) return this->fill(tree, l, r, {});

        node_pointer t0, t1, t2, t3;

        this->split(tree, l, l + count, r, t0, t1, t2, t3);

        this->dispose(t1);

        this->merge(t2, t2, this->create({}, count));
        this->merge(tree, t0, t2, t3);
    }

    void shift_right(node_pointer& tree, const size_type l, const size_type r, const size_type count = 1) noexcept(NO_EXCEPT) {
        assert(l <= r);

        if(count < 0) return this->shift_left(tree, l, r, -count);

        if(count == 0) return;
        if(count >= r - l) return this->fill(tree, l, r, {});

        node_pointer t0, t1, t2, t3;

        this->split(tree, l, r - count, r, t0, t1, t2, t3);

        this->dispose(t2);

        this->merge(t1, this->create({}, count), t1);
        this->merge(tree, t0, t1, t3);
    }

    void rotate(node_pointer& tree, const size_type l, const size_type m, const size_type r) noexcept(NO_EXCEPT) {
        assert(l <= m && m < r);
        if(l == m) return;

        node_pointer t0, t1, t2, t3;

        this->split(tree, l, m, r, t0, t1, t2, t3);
        this->merge(t2, t2, t1);
        this->merge(tree, t0, t2, t3);
    }


    template<bool LEFT>
    size_type find(const node_pointer& tree, operand& val, const size_type offset) noexcept(NO_EXCEPT) {
        if(tree->data.acc + val == val) {
            return -1;
        }

        if constexpr(LEFT) {
            if(tree->left != node_handler::nil and tree->left->data.acc + val != val) {
                return this->find<true>(tree->left, val, offset);
            }
            else {
                return tree->data.val + val != val ? offset + tree->left->size : this->find<true>(tree->right, val, offset + tree->left->size + 1);
            }
        }
        else {
            if(tree->right != node_handler::nil and tree->right->data.acc + val != val) {
                return this->find<false>(tree->right, val, offset + tree->left->size + 1);
            }
            else {
                return tree->data.val + val != val ? offset + tree->left->size : this->find<false>(tree->left, val, offset);
            }
        }
    }

    template<bool LEFT>
    inline size_type find(node_pointer& tree, const size_type l, const size_type r, const operand& val) noexcept(NO_EXCEPT) {
        if(l == r) return -1;

        node_pointer t0, t1, t2;

        this->split(tree, l, r, t0, t1, t2);

        const size_type res = this->find<LEFT>(t1, val, l);

        this->merge(tree, t0, t1, t2);

        return res;
    }
};



} // namespace dynamic_tree_impl

} // namespace internal


template<class ActionOrValue, class Context = treap_context<>>
    requires internal::available_with<internal::dynamic_tree_impl::sequence_core, ActionOrValue, Context>
struct dynamic_sequence
  : private internal::dumpable_tree<
        dynamic_sequence<ActionOrValue, Context>,
        internal::dynamic_tree_impl::sequence_core<ActionOrValue, Context>,
        Context::LEAF_ONLY
    >
{
  private:
    using sequence_core = internal::dynamic_tree_impl::sequence_core<ActionOrValue, Context>;

    template<class T>
    static consteval auto _to_operator() {
        if constexpr(requires { typename T::value_type; }) return typename T::value_type{};
        else return T{};
    }

  public:
    using operand = typename sequence_core::operand;
    using operation = typename sequence_core::operation;

    using value_type = operand;
    using operator_type = decltype(_to_operator<operation>());

    using node_handler = typename sequence_core::node_handler;
    using allocator_type = typename sequence_core::allocator_type;

    using node_type = typename sequence_core::node_type;
    using node_pointer = typename sequence_core::node_pointer;

    using size_type = typename sequence_core::size_type;

  private:
    using dumper = internal::dumpable_tree<dynamic_sequence, sequence_core, Context::LEAF_ONLY>;
    friend dumper;

    sequence_core _impl;

    node_pointer _root = node_handler::nil;

    size_type _offset = 0;


    template<std::same_as<size_type>... SizeTypes>
    inline void _normalize_index(SizeTypes&... indices) noexcept(NO_EXCEPT) {
        const auto min_index = std::min({ indices... });
        ((indices -= this->_offset), ...);
        if(min_index < this->_offset) this->_offset = min_index;
    }


  public:
    ~dynamic_sequence() { this->_impl.dispose(this->_root); }

    dynamic_sequence(const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT) : _impl(allocator) {};

    dynamic_sequence(const node_pointer& root, const size_type offset = 0, const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT)
      : _impl(allocator), _root(root), _offset(offset)
    {};

    template<std::input_iterator I, std::sized_sentinel_for<I> S>
    dynamic_sequence(I first, S last, const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT)
      : _impl(allocator)
    {
        this->assign(first, last);
    }


    explicit dynamic_sequence(const size_type size, const value_type& val, const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT)
      : _impl(allocator)
    {
        this->assign(size, val);
    }

    explicit dynamic_sequence(const size_type size, const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT)
      : dynamic_sequence(size, value_type{}, allocator)
    {}

    template<std::ranges::input_range R>
        requires (!std::same_as<std::remove_cvref_t<R>, dynamic_sequence>)
    explicit dynamic_sequence(R&& range, const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT)
      : dynamic_sequence(ALL(range), allocator)
    {}

    template<std::convertible_to<value_type> T>
    dynamic_sequence(const std::initializer_list<T>& values, const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT)
      : dynamic_sequence(values, allocator)
    {}

    inline auto offset() const noexcept(NO_EXCEPT) { return this->_offset; }

    inline auto& root() noexcept(NO_EXCEPT) { return this->_root; }
    inline const auto& root() const noexcept(NO_EXCEPT) { return this->_root; }

    inline auto size() const noexcept(NO_EXCEPT) { return this->_root->size; }

    inline bool empty() const noexcept(NO_EXCEPT) { return this->size() == 0; }


    template<internal::resizable_range Container>
    inline auto to() noexcept(NO_EXCEPT) {
        Container res;
        res.resize(this->size());

        auto itr = std::ranges::begin(res);
        this->_impl.enumerate(this->_root, itr);

        return res;
    }


    inline void clear() noexcept(NO_EXCEPT) {
        this->_impl.dispose(this->_root);
        this->_root = node_handler::nil;
        this->_offset = 0;
    }


    inline auto clone() const noexcept { return *this; }

    inline auto clone(size_type l, size_type r) noexcept(NO_EXCEPT) {
        this->_normalize_index(l, r);
        node_pointer t0, t1, t2;
        this->_impl.split(this->_root, l, r, t0, t1, t2);
        this->_impl.merge(this->_root, t0, t1, t2);
        return dynamic_sequence(t1, this->_offset);
    }

    inline auto split(size_type pos) noexcept(NO_EXCEPT) {
        this->_normalize_index(pos);
        node_pointer t0, t1;
        this->_impl.split(this->_root, pos, t0, t1);
        return std::make_pair(dynamic_sequence(t0, this->_offset), dynamic_sequence(t1, this->_offset));
    }

    inline auto extract(size_type l, size_type r) noexcept(NO_EXCEPT) {
        this->_normalize_index(l, r);
        node_pointer t0, t1, t2;
        this->_impl.split(this->_root, l, r, t0, t1, t2);
        this->_impl.merge(this->_root, t0, t2);
        return dynamic_sequence(t1, this->_offset);
    }

    inline auto& insert(size_type pos, const dynamic_sequence& other) noexcept(NO_EXCEPT) {
        this->_normalize_index(pos);
        node_pointer t0, t1;
        this->_impl.split(this->_root, pos, t0, t1);
        this->_impl.merge(this->_root, t0, other._root, t1);
        return *this;
    }

    inline auto& replace(size_type l, size_type r, const dynamic_sequence& other) noexcept(NO_EXCEPT) {
        this->_normalize_index(l, r);
        node_pointer t0, t1, t2;
        this->_impl.split(this->_root, l, r, t0, t1, t2);
        this->_impl.merge(this->_root, t0, other._root, t2);
        return *this;
    }

    inline auto& merge(const dynamic_sequence& other) noexcept(NO_EXCEPT) {
        this->_impl.merge(this->_root, this->_root, other._root);
        return *this;
    }


    template<std::input_iterator I, std::sized_sentinel_for<I> S>
    inline auto& assign(I first, S last) noexcept(NO_EXCEPT) {
        this->clear();
        this->_root = this->_impl.build(first, last);
        return *this;
    }

    inline auto& assign(const size_type size, const value_type& val = value_type{}) noexcept(NO_EXCEPT) {
        this->clear();
        this->_impl.insert(this->_root, 0, val, size);
        return *this;
    }

    template<std::ranges::input_range R>
    inline auto& assign(R&& range) noexcept(NO_EXCEPT) {
        return this->assign(ALL(range));
    }

    template<std::convertible_to<value_type> T>
    inline auto& assign(const std::initializer_list<T>& values) noexcept(NO_EXCEPT) {
        return this->assign(values);
    }


    inline auto& resize(const size_type size, const value_type& val = value_type{}) noexcept(NO_EXCEPT) {
        if(this->size() > size) this->_impl.erase(this->_root, size, this->size());
        if(this->size() < size) this->push_back(val, size - this->size());
        return *this;
    }


    inline auto& expand(size_type l, size_type r) noexcept(NO_EXCEPT) {
        this->_normalize_index(l, r);
        node_pointer t0, t1, t2;
        this->_impl.split(this->_root, l, r, t0, t1, t2);
        this->_impl.merge(this->_root, t0, t1, t2);
        return *this;
    }

    inline auto& expand(size_type pos) noexcept(NO_EXCEPT) {
        this->_normalize_index(pos);
        node_pointer t0, t1;
        this->_impl.split(this->_root, pos, t0, t1);
        this->_impl.merge(this->_root, t0, t1);
        return *this;
    }


    inline auto& fill(const value_type& val) noexcept(NO_EXCEPT) {
        this->_impl.fill(this->_root, 0, this->size(), val);
        return *this;
    }

    inline auto fold() noexcept(NO_EXCEPT) {
        return this->_impl.val(this->_root);
    }

    inline auto& apply(const operator_type& val) noexcept(NO_EXCEPT) {
        this->_root->data.lazy = this->_root->data.lazy + val;
        this->update(this->_root);
        return *this;
    }

    inline auto front() noexcept(NO_EXCEPT) {
        return this->_impl.fold(this->_root, 0, 1);
    }

    inline auto back() noexcept(NO_EXCEPT) {
        return this->_impl.fold(this->_root, this->size() - 1, this->size());
    }


    inline auto& push_front(const value_type& val, const size_type count = 1) noexcept(NO_EXCEPT) {
        this->_impl.insert(this->_root, 0, val, count);
        return *this;
    }

    inline auto& push_back(const value_type& val, const size_type count = 1) noexcept(NO_EXCEPT) {
        this->_impl.insert(this->_root, this->size(), val, count);
        return *this;
    }

    inline auto& reverse() noexcept(NO_EXCEPT) {
        this->_root->data.rev ^= 1;
        this->_impl.update(this->_root);
        return *this;
    }

    inline auto& shift_left(const size_type count = 1) noexcept(NO_EXCEPT) {
        this->_impl.shift_left(this->_root, 0, this->size(), count);
        return *this;
    }

    inline auto& shift_right(const size_type count = 1) noexcept(NO_EXCEPT) {
        this->_impl.shift_right(this->_root, 0, this->size(), count);
        return *this;
    }

    // Same usage as: std::rotate(:m:)
    inline auto& rotate(size_type m) noexcept(NO_EXCEPT) {
        this->_normalize_index(m);
        this->_impl.rotate(this->_root, 0, m, this->size());
        return *this;
    }

    // Same usage as: std::rotate(:m:)
    inline auto& rotate_left(const size_type count = 1) noexcept(NO_EXCEPT) {
        assert(!this->empty());
        this->_impl.rotate(this->_root, 0, uni::mod(count, this->size()), this->size());
        return *this;
    }

    // Same usage as: std::rotate(:m:)
    inline auto& rotate_right(const size_type count = 1) noexcept(NO_EXCEPT) {
        assert(!this->empty());
        this->_impl.rotate(this->_root, 0, uni::mod(-count, this->size()), this->size());
        return *this;
    }


    template<std::input_iterator I, std::sized_sentinel_for<I> S>
    inline auto& insert(size_type pos, I first, S last) noexcept(NO_EXCEPT) {
        this->_normalize_index(pos);
        this->_impl.insert(this->_root, pos, first, last);
        return *this;
    }

    inline auto& insert(size_type pos, const operand& val, const size_type count = 1) noexcept(NO_EXCEPT) {
        this->_normalize_index(pos);
        this->_impl.insert(this->_root, pos, val, count);
        return *this;
    }

    inline auto& erase(size_type l, size_type r) noexcept(NO_EXCEPT) {
        this->_normalize_index(l, r);
        this->_impl.erase(this->_root, l, r);
        return *this;
    }

    inline auto& erase(const size_type pos) noexcept(NO_EXCEPT) {
        return this->erase(pos, pos + 1);
    }

    inline auto pop(size_type pos, const size_type count = 1) noexcept(NO_EXCEPT) {
        this->_normalize_index(pos);
        return this->_impl.pop(this->_root, pos, count);
    }

    inline auto get(size_type pos) noexcept(NO_EXCEPT) {
        this->_normalize_index(pos);
        return this->_impl.get(this->_root, pos);
    }

    inline auto& add(size_type pos, const value_type& val) noexcept(NO_EXCEPT) {
        this->_normalize_index(pos);
        this->_impl.add(this->_root, pos, val);
        return *this;
    }

    inline auto& fill(size_type l, size_type r, const value_type& val) noexcept(NO_EXCEPT) {
        this->_normalize_index(l, r);
        this->_impl.fill(this->_root, l, r, val);
        return *this;
    }

    inline auto fold(size_type l, size_type r) noexcept(NO_EXCEPT) {
        this->_normalize_index(l, r);
        return this->_impl.fold(this->_root, l, r);
    }

    inline auto& apply(size_type l, size_type r, const operation& val) noexcept(NO_EXCEPT) {
        this->_normalize_index(l, r);
        this->_impl.apply(this->_root, l, r, val);
        return *this;
    }

    inline auto& reverse(size_type l, size_type r) noexcept(NO_EXCEPT) {
        this->_normalize_index(l, r);
        this->_impl.reverse(this->_root, l, r);
        return *this;
    }

    inline auto& rotate(size_type l, size_type m, size_type r) noexcept(NO_EXCEPT) {
        this->_normalize_index(l, m, r);
        this->_impl.rotate(this->_root, l, m, r);
        return *this;
    }

    inline auto& shift_left(size_type l, size_type r, const size_type count = 1) noexcept(NO_EXCEPT) {
        this->_normalize_index(l, r);
        this->_impl.shift_left(this->_root, l, r, count);
        return *this;
    }

    inline auto& shift_right(size_type l, size_type r, const size_type count = 1) noexcept(NO_EXCEPT) {
        this->_normalize_index(l, r);
        this->_impl.shift_right(this->_root, l, r, count);
        return *this;
    }

    inline auto pop_front(const size_type count = 1) noexcept(NO_EXCEPT) {
        return this->_impl.pop(this->_root, 0, count);
    }

    inline auto pop_back(const size_type count = 1) noexcept(NO_EXCEPT) {
        return this->_impl.pop(this->_root, this->size() - count, count);
    }


    template<std::ranges::input_range R>
        requires (!std::same_as<std::remove_cvref_t<R>, dynamic_sequence>)
    inline auto& insert(const size_type pos, R&& range) noexcept(NO_EXCEPT) {
        return this->insert(pos, ALL(range));
    }


    inline auto& set(const size_type pos, const value_type& val) noexcept(NO_EXCEPT) {
        return this->fill(pos, pos + 1, val);
    }


    inline auto& apply(const size_type pos, const operator_type& val) noexcept(NO_EXCEPT) {
        return this->apply(pos, pos + 1, val);
    }


    inline auto& rotate_left(const size_type l, const size_type r, const size_type count = 1) noexcept(NO_EXCEPT) {
        assert(l < r);
        return this->rotate(l, l + uni::mod(count, r - l), r);
    }

    inline auto& rotate_right(const size_type l, const size_type r, const size_type count = 1) noexcept(NO_EXCEPT) {
        assert(l < r);
        return this->rotate(l, l + uni::mod(-count, r - l), r);
    }


    // Find the min / max k in [l, r) that satisfies (this[k] + x) != x.
    // If no such k is found, return -1.
    template<bool LEFT = true>
    inline auto find(const size_type l, const size_type r, const value_type& val) noexcept(NO_EXCEPT) {
        return this->template find<LEFT>(l, r - 1, r);
    }

    // Find the min / max k in whole that satisfies (this[k] + x) != x.
    // If no such k is found, return -1.
    template<bool LEFT = true>
    inline auto find(const value_type& val) noexcept(NO_EXCEPT) {
        return this->find<LEFT>(0, this->size(), val);
    }


    struct point_reference : internal::point_reference<dynamic_sequence, size_type> {
        point_reference(dynamic_sequence *const super, const size_type pos) noexcept(NO_EXCEPT)
          : internal::point_reference<dynamic_sequence, size_type>(super, pos)
        {}

        operator value_type() noexcept(NO_EXCEPT) { return this->_super->get(this->_pos); }
        auto val() noexcept(NO_EXCEPT) { return this->_super->get(this->_pos); }


        inline auto& operator=(const value_type& val) noexcept(NO_EXCEPT) {
            this->_super->set(this->_pos, val);
            return *this;
        }

        inline auto& operator+=(const value_type& val) noexcept(NO_EXCEPT) {
            this->_super->add(this->_pos, val);
            return *this;
        }

        inline auto& operator*=(const operator_type& val) noexcept(NO_EXCEPT) {
            this->_super->apply(this->_pos, val);
            return *this;
        }
    };


    struct range_reference : internal::range_reference<dynamic_sequence, size_type> {
        range_reference(dynamic_sequence *const super, const size_type l, const size_type r) noexcept(NO_EXCEPT)
          : internal::range_reference<dynamic_sequence, size_type>(super, l, r)
        {}

        inline auto clone() noexcept(NO_EXCEPT) {
            return this->_super->clone(this->_begin, this->_end);
        }

        inline auto fold() noexcept(NO_EXCEPT) {
            return this->_super->fold(this->_begin, this->_end);
        }

        inline auto& operator=(const value_type& val) noexcept(NO_EXCEPT) {
            this->_super->fill(this->_begin, this->_end, val);
            return *this;
        }

        inline auto& operator*=(const operator_type& val) noexcept(NO_EXCEPT) {
            this->_super->apply(this->_begin, this->_end, val);
            return *this;
        }

        // Find the min / max k in [l, r) that satisfies (this[k] + x) != x.
        // If no such k is found, return -1.
        template<bool LEFT = true>
        inline auto find(const value_type& val) noexcept(NO_EXCEPT) {
            return this->_super->template find<LEFT>(this->_begin, this->_end, val);
        }
    };


    inline auto operator[](const size_type pos) noexcept(NO_EXCEPT) { return point_reference(this, pos); }
    inline auto operator()(const size_type l, const size_type r) noexcept(NO_EXCEPT) { return range_reference(this, l, r); }


    struct iterator;

  protected:
    using iterator_interface = internal::container_iterator_interface<value_type, dynamic_sequence, iterator>;

  public:
    struct iterator : iterator_interface {
        using iterator_interface::iterator_interface;
    };

    inline auto begin() noexcept(NO_EXCEPT) { return iterator(this, 0); }
    inline auto end() noexcept(NO_EXCEPT) { return iterator(this, this->size()); }

    inline auto rbegin() noexcept(NO_EXCEPT) { return std::make_reverse_iterator(this->end()); }
    inline auto rend() noexcept(NO_EXCEPT) { return std::make_reverse_iterator(this->begin()); }

    inline auto traverse() const noexcept(NO_EXCEPT) { return typename sequence_core::traverser(this->_root); }


    using dumper::dump_rich;
    using dumper::_debug;


    debugger::debug_t dump_rich(const std::string prefix = "   ") {
        return "\n" + this->dump_rich(this->_root, prefix);
    }


    debugger::debug_t _debug() {
        return "[ " + this->_debug(this->_root) + " ]";
    }

};


} // namespace uni
#line 2 "data_structure/dynamic_set.hpp"


#line 12 "data_structure/dynamic_set.hpp"

#line 15 "data_structure/dynamic_set.hpp"

#line 22 "data_structure/dynamic_set.hpp"

#line 25 "data_structure/dynamic_set.hpp"

#line 27 "data_structure/dynamic_set.hpp"

#line 31 "data_structure/dynamic_set.hpp"

#line 33 "data_structure/dynamic_set.hpp"

#line 35 "data_structure/dynamic_set.hpp"

#line 38 "data_structure/dynamic_set.hpp"

#line 40 "data_structure/dynamic_set.hpp"


namespace uni {

namespace internal {

namespace dynamic_tree_impl {



template<class ActionOrValue, class Context>
    requires (!Context::LEAF_ONLY)
struct set_core :  internal::basic_core<ActionOrValue, set_core<ActionOrValue, Context>, Context> {
  private:
    using base = internal::basic_core<ActionOrValue, set_core, Context>;

  public:
    using base::base;


    using data_type = base::data_type;

    using operand = base::operand;


    using node_handler = typename base::node_handler;

    using node_type = typename base::node_type;
    using node_pointer = typename base::node_pointer;


    using size_type = typename base::size_type;


    inline void pull(const node_pointer tree) const noexcept(NO_EXCEPT) {
        tree->data.acc = tree->left->data.acc + tree->length * tree->data.val + tree->right->data.acc;
    }

    inline constexpr void push(const node_pointer) const noexcept(NO_EXCEPT) { /* do nothing */ }


    template<std::random_access_iterator I, std::sized_sentinel_for<I> S>
    node_pointer build(I first, S last) {
        std::vector<i64> val;
        val.assign(first, last);
        std::ranges::sort(val);

        return this->base::build(ALL(val));
    }


    void insert(node_pointer& tree, const operand& val, const size_type count = 1) noexcept(NO_EXCEPT) {
        if(count == 0) return;
        if(count < 0) return this->erase(tree, val, -count);

        node_pointer t0, t1;

        this->split(tree, { val }, t0, t1);
        this->merge(tree, t0, this->create(val, count), t1);
    }

    void insert_unique(node_pointer& tree, const operand& val, const size_type count = 1) noexcept(NO_EXCEPT) {
        if(count == 0) return;
        if(count < 0) return this->erase(tree, val, -count);

        node_pointer t0, t1;
        bool exist = false;

        this->template split<false, true>(tree, { val }, t0, t1, &exist);

        if(exist) this->merge(tree, t0, t1);
        else this->merge(tree, t0, this->create(val, count), t1);
    }


    void erase(node_pointer& tree, const operand& val, const size_type count = 1) noexcept(NO_EXCEPT) {
        if(count == 0) return;
        if(count < 0) return this->insert(tree, val, -count);

        node_pointer t0, t1, t2;

        this->split(tree, { val }, t0, t1);
        this->split(t1, count, t1, t2);

        this->dispose(t1);
        this->merge(tree, t0, t2);
    }

    void erase_limit(node_pointer& tree, const operand& val, size_type count = 1) noexcept(NO_EXCEPT) {
        if(count == 0) return;
        if(count < 0) return this->insert(tree, val, -count);

        node_pointer t0, t1, t2, t3;

        this->split(tree, { val }, t0, t1);
        this->template split<true>(t1, { val }, t1, t3);

        if(count >= t1->size) count = t1->size;
        this->split(t1, count, t1, t2);

        this->dispose(t1);
        this->merge(t2, t0, t2);
        this->merge(tree, t2, t3);
    }


    auto fold(node_pointer tree, const size_type l, const size_type r) noexcept(NO_EXCEPT) {
        assert(0 <= l && l <= r && r <= tree->size);
        return this->base::fold(tree, l, r);
    }

    void erase(node_pointer& tree, const size_type l, const size_type r) noexcept(NO_EXCEPT) {
        assert(0 <= l && l <= r && r <= tree->size);
        this->base::erase(tree, l, r);
    }


    auto pop(node_pointer& tree, const size_type pos, const size_type count = 1) noexcept(NO_EXCEPT) {
        assert(0 <= pos && 0 <= count && pos + count <= tree->size);
        return this->base::pop(tree, pos, count);
    }

    auto get(node_pointer tree, const size_type pos) noexcept(NO_EXCEPT) {
        assert(0 <= pos && pos < tree->size);
        return this->base::get(tree, pos);
    }

    template<bool STRICT = false>
    auto find(node_pointer& tree, const operand& val) noexcept(NO_EXCEPT) {
        node_pointer t0, t1;

        this->template split<STRICT>(tree, { val }, t0, t1);

        const auto res = t0->size;

        this->merge(tree, t0, t1);

        return res;
    }

    auto equal_range(node_pointer& tree, const operand& val) noexcept(NO_EXCEPT) {
        node_pointer t0, t1, t2;

        this->template split<true>(tree, { val }, t1, t2);
        this->split(t1, { val }, t0, t1);

        const auto lower = t0->size;

        this->merge(t1, t0, t1);

        const auto upper = t1->size;

        this->merge(tree, t1, t2);

        return std::make_pair(std::move(lower), std::move(upper));
    }
};



} // namespace dynamic_tree_impl

} // namespace internal


template<class Value, class Context = treap_context<>>
struct dynamic_set : dynamic_set<actions::make_full_t<Value>, Context> {
    using dynamic_set<actions::make_full_t<Value>, Context>::dynamic_set;
};


template<actions::internal::full_action ActionOrValue, class Context>
    requires internal::available_with<internal::dynamic_tree_impl::set_core, ActionOrValue, Context>
struct dynamic_set<ActionOrValue, Context>
  : private internal::dumpable_tree<
        dynamic_set<ActionOrValue, Context>,
        internal::dynamic_tree_impl::set_core<ActionOrValue, Context>,
        Context::LEAF_ONLY
    >
{
  public:
    using action = ActionOrValue;
    using operand = typename action::operand;

    using value_type = operand;

    using set_core = internal::dynamic_tree_impl::set_core<ActionOrValue, Context>;

    using node_handler = typename set_core::node_handler;
    using allocator_type = typename set_core::allocator_type;

    using node_type = typename set_core::node_type;
    using node_pointer = typename set_core::node_pointer;

    using size_type = typename set_core::size_type;

  private:
    using dumper = internal::dumpable_tree<dynamic_set, set_core, Context::LEAF_ONLY>;
    friend dumper;

    set_core _impl;

    node_pointer _root = node_handler::nil;

    size_type _offset = 0;


  public:
    ~dynamic_set() { this->_impl.dispose(this->_root); }

    dynamic_set(const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT) : _impl(allocator) {};

    template<std::input_iterator I, std::sized_sentinel_for<I> S>
    dynamic_set(I first, S last, const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT)
      : _impl(allocator)
    {
        this->assign(first, last);
    }


    explicit dynamic_set(const size_type size, const value_type& val, const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT)
      : _impl(allocator)
    {
        this->assign(size, val);
    }

    explicit dynamic_set(const size_type size, const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT)
      : dynamic_set(size, value_type{}, allocator)
    {}

    template<std::ranges::input_range R>
    explicit dynamic_set(R&& range, const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT)
      : dynamic_set(ALL(range), allocator)
    {}

    template<std::convertible_to<value_type> T>
    dynamic_set(const std::initializer_list<T>& values, const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT)
      : dynamic_set(values, allocator)
    {}


    inline node_pointer& root() noexcept(NO_EXCEPT) { return this->_root; }
    inline const node_pointer& root() const noexcept(NO_EXCEPT) { return this->_root; }

    size_type size() const noexcept(NO_EXCEPT) { return this->_root->size; }

    bool empty() const noexcept(NO_EXCEPT) { return this->size() == 0; }


    template<internal::resizable_range Container>
    inline auto to() noexcept(NO_EXCEPT) {
        Container res;
        res.resize(this->size());

        auto itr = std::ranges::begin(res);
        this->_impl.enumerate(this->_root, itr);

        return res;
    }


    inline void clear() noexcept(NO_EXCEPT) {
        this->_impl.dispose(this->_root);
        this->_root = node_handler::nil;
    }


    template<bool UNIQUE = false, std::input_iterator I, std::sized_sentinel_for<I> S>
    inline auto& assign(I first, S last) noexcept(NO_EXCEPT) {
        this->clear();
        this->insert<UNIQUE>(first, last);
        return *this;
    }

    template<bool UNIQUE = false>
    inline auto& assign(const size_type size, const value_type& val = value_type{}) noexcept(NO_EXCEPT) {
        this->clear();
        this->insert<UNIQUE>(val, size);
        return *this;
    }

    template<bool UNIQUE = false, std::ranges::input_range R>
    inline auto& assign(R&& range) noexcept(NO_EXCEPT) {
        return this->assign<UNIQUE>(ALL(range));
    }

    template<bool UNIQUE = false, std::convertible_to<value_type> T>
    inline auto& assign(const std::initializer_list<T>& values) noexcept(NO_EXCEPT) {
        return this->assign<UNIQUE>(values);
    }


    template<bool UNIQUE = false>
    inline auto& insert(const operand& val, const size_type count = 1) noexcept(NO_EXCEPT) {
        if constexpr(UNIQUE) this->_impl.insert_unique(this->_root, val, count);
        else this->_impl.insert(this->_root, val, count);

        return *this;
    }

    template<bool UNIQUE = false, std::input_iterator I, std::sized_sentinel_for<I> S>
    inline auto& insert(I first, S last) noexcept(NO_EXCEPT) {
        for(; first != last; ++first) this->template insert<UNIQUE>(*first);
        return *this;
    }

    template<bool UNIQUE = false, std::ranges::input_range R>
    inline auto& insert(R&& range) noexcept(NO_EXCEPT) {
        return this->template insert<UNIQUE>(ALL(range));
    }

    inline auto& fill(const value_type& val) noexcept(NO_EXCEPT) {
        const size_type size = this->size();
        this->clear();
        this->insert(val, size);
        return *this;
    }


    template<bool LIMIT = true>
    inline auto& erase(const value_type& val, const size_type count = 1) noexcept(NO_EXCEPT) {
        if constexpr(LIMIT) this->_impl.erase_limit(this->_root, val, count);
        else this->_impl.erase(this->_root, val, count);

        return *this;
    }

    inline auto& erase(const size_type l, const size_type r) noexcept(NO_EXCEPT) {
        this->_impl.erase(this->_root, l, r);
        return *this;
    }


    inline value_type pop(const size_type pos, const size_type count = 1) noexcept(NO_EXCEPT) {
        return this->_impl.pop(this->_root, pos, count);
    }

    inline value_type pop_min(const size_type count = 1) noexcept(NO_EXCEPT) {
        return this->pop(0, count);
    }

    inline value_type pop_max(const size_type count = 1) noexcept(NO_EXCEPT) {
        return this->pop(this->size() - count, count);
    }


    inline operand fold(const size_type l, const size_type r) noexcept(NO_EXCEPT) {
        return this->_impl.fold(this->_root, l, r);
    }

    inline value_type get(const size_type k) noexcept(NO_EXCEPT) {
        return this->_impl.get(this->_root, k);
    }

    inline operand median(const size_type l, const size_type r) noexcept(NO_EXCEPT) {
        return this->get((r - l) >> 1);
    }

    inline value_type min() noexcept(NO_EXCEPT) {
        return this->get(0);
    }

    inline value_type median() noexcept(NO_EXCEPT) {
        return this->get(this->size() >> 1);
    }

    inline value_type max() noexcept(NO_EXCEPT) {
        return this->get(this->size() - 1);
    }

    inline auto fold() noexcept(NO_EXCEPT) {
        return this->_root->data.acc;
    }


    inline value_type operator[](const size_type k) noexcept(NO_EXCEPT) {
        return this->get(k);
    }

    inline value_type operator()(const size_type l, const size_type r) noexcept(NO_EXCEPT) {
        return this->fold(l, r);
    }


    struct iterator;


    inline auto lower_bound(const value_type& val) noexcept(NO_EXCEPT) {
        return iterator{ this, this->_impl.template find<false>(this->_root, val) };
    }

    inline auto upper_bound(const value_type& val) noexcept(NO_EXCEPT) {
        return iterator{ this, this->_impl.template find<true>(this->_root, val) };
    }

    inline auto equal_range(const value_type& val) noexcept(NO_EXCEPT) {
        const auto [ lower, upper ] = this->_impl.equal_range(this->_root, val);
        return std::make_pair(iterator{ this, lower }, iterator{ this, upper });
    }


    inline size_type count(const value_type& val) noexcept(NO_EXCEPT) {
        const auto [ lower, upper ] = this->_impl.equal_range(this->_root, val);
        return upper - lower;
    }

    inline bool contains(const value_type& val) noexcept(NO_EXCEPT) {
        return this->count(val) == 1;
    }


    inline auto& erase(const iterator& itr) noexcept(NO_EXCEPT) {
        return this->erase(itr.pos(), itr.pos() + 1);
    }

    inline auto& erase(const iterator& l, const iterator& r) noexcept(NO_EXCEPT) {
        return this->erase(l.pos(), r.pos());
    }


  protected:
    using iterator_interface = internal::container_iterator_interface<value_type,dynamic_set,iterator>;

  public:
    struct iterator : iterator_interface {
        using iterator_interface::iterator_interface;
    };

    inline auto begin() noexcept(NO_EXCEPT) { return iterator{ this, 0 }; }
    inline auto end() noexcept(NO_EXCEPT) { return iterator{ this, this->size() }; }

    inline auto rbegin() const noexcept(NO_EXCEPT) { return std::make_reverse_iterator(this->end()); }
    inline auto rend() const noexcept(NO_EXCEPT) { return std::make_reverse_iterator(this->begin()); }


    using dumper::dump_rich;
    using dumper::_debug;


    debugger::debug_t dump_rich(const std::string prefix = "   ") {
        return "\n" + this->dump_rich(this->_root, prefix);
    }


    debugger::debug_t _debug() {
        return "[ " + this->_debug(this->_root) + " ]";
    }
};


} // namespace uni
#line 2 "data_structure/fenwick_tree.hpp"


#line 12 "data_structure/fenwick_tree.hpp"


#line 21 "data_structure/fenwick_tree.hpp"

#line 24 "data_structure/fenwick_tree.hpp"

#line 27 "data_structure/fenwick_tree.hpp"


namespace uni {

namespace internal {

namespace fenwick_tree_impl {


// Thanks to: atcoder::fenwick_tree
template<algebraic::internal::monoid Operand>
struct core {
    using operand = Operand;
    using size_type = internal::size_t;

  private:
    size_type _n = 0, _bit_ceil = 0;
    std::vector<operand> _data;

    inline void _init() noexcept(NO_EXCEPT) {
        FOR(i, 1, this->_n) {
            size_type j = i + (i & -i);
            if(j <= this->_n) this->_data[j-1] = this->_data[j-1] + this->_data[i-1];
        }
    }

  public:
    core() noexcept(NO_EXCEPT) {}

    explicit core(const size_type n) noexcept(NO_EXCEPT)
      : _n(n), _bit_ceil(std::bit_ceil<std::make_unsigned_t<size_type>>(n)), _data(n, operand{})
    {}

    inline size_type size() const noexcept(NO_EXCEPT) { return this->_n; }


    template<std::input_iterator I, std::sentinel_for<I> S>
    inline void assign(I first, S last) noexcept(NO_EXCEPT) {
        if constexpr(std::sized_sentinel_for<S, I>) {
            assert(std::ranges::distance(first, last) == this->size());
        }
        for(size_type i = 0; first < last; ++i, ++first) this->_data[i] = *first;
        this->_init();
    }


    inline void add(size_type p, const operand& x) noexcept(NO_EXCEPT) {
        for(p++; p<=this->_n; p += p & -p) this->_data[p-1] = this->_data[p-1] + x;
    }

    inline void set(const size_type p, const operand& x) noexcept(NO_EXCEPT) {
        assert(this->get(p) == this->fold(p, p+1));
        this->add(p, x + -this->get(p));
    }

    inline operand fold(size_type r) const noexcept(NO_EXCEPT) {
        operand s = operand{};
        for(; r>0; r -= r & -r) s = s + this->_data[r-1];
        return s;
    }
    inline operand fold(size_type l, size_type r) const noexcept(NO_EXCEPT) {
        operand s = operand{};
        for(; l < r; r -= r & -r) s = s + this->_data[r-1];
        for(; r < l; l -= l & -l) s = s + -this->_data[l-1];
        return s;
    }

    inline operand get(size_type p) const noexcept(NO_EXCEPT) {
        return this->fold(p, p+1);
    }

    template<class F>
    inline size_type max_right(size_type l, F&& f) const noexcept(NO_EXCEPT)
        requires algebraic::internal::invertible<operand>
    {
        assert(0 <= l && l <= this->_n);
        assert(f(operand{}));
        if(l == this->_n) return this->_n;
        operand inv = -this->fold(l);
        size_type p = 0, q = this->_bit_ceil;
        for(size_type k=q; k>0; k >>= 1) {
            if(p+k <= this->_n and f(this->_data[p+k-1] + inv)) {
                inv = inv + this->_data[(p+=k)-1];
            }
        }
        return p;
    }

    template<class F> inline size_type min_left(size_type r, F&& f) const noexcept(NO_EXCEPT)
        requires algebraic::internal::invertible<operand>
    {
        assert(0 <= r && r <= this->_n);
        assert(f(operand{}));
        if(r == 0) return 0;
        operand acc = this->fold(r);
        size_type p = 0, q = std::bit_ceil<std::make_unsigned_t<size_type>>(r);
        for(size_type k=q; k>0; k >>= 1) {
            if(p+k < r and !f(acc + -this->_data[p+k-1])) {
                acc = acc + -this->_data[(p+=k)-1];
            }
        }
        if(p == 0 and f(acc)) return 0;
        return p + 1;
    }
};


} // namespace fenwick_tree_impl

} // namespace internal


template<class Value>
struct fenwick_tree : internal::unconstructible {};


template<algebraic::internal::monoid Monoid>
struct fenwick_tree<Monoid> : internal::fenwick_tree_impl::core<Monoid> {
    static_assert(algebraic::internal::commutative<Monoid>);

  private:
    using core = typename internal::fenwick_tree_impl::core<Monoid>;

    core _impl;

  public:
    using value_type = typename core::operand;
    using size_type = typename core::size_type;

  protected:
    inline size_type _positivize_index(const size_type p) const noexcept(NO_EXCEPT) {
        return p < 0 ? this->_impl.size() + p : p;
    }

  public:
    fenwick_tree() noexcept(NO_EXCEPT) : _impl() {}

    explicit fenwick_tree(const size_type n) noexcept(NO_EXCEPT) : _impl(n) {}
    explicit fenwick_tree(const size_type n, const value_type& v) noexcept(NO_EXCEPT) : _impl(n) { this->_impl.fill(v); }

    template<std::convertible_to<value_type> T>
    fenwick_tree(const std::initializer_list<T>& init_list) noexcept(NO_EXCEPT) : fenwick_tree(ALL(init_list)) {}

    template<std::input_iterator I, std::sized_sentinel_for<I> S>
    explicit fenwick_tree(I first, S last) noexcept(NO_EXCEPT)
      : fenwick_tree(static_cast<size_type>(std::ranges::distance(first, last)))
    { this->assign(first, last); }

    template<std::ranges::input_range R>
    explicit fenwick_tree(R&& range) noexcept(NO_EXCEPT) : fenwick_tree(ALL(range)) {}


    template<std::convertible_to<value_type> T>
    inline auto& assign(const std::initializer_list<T>& init_list) noexcept(NO_EXCEPT){ return this->assign(ALL(init_list)); }

    template<std::input_iterator I, std::sentinel_for<I> S>
    inline auto& assign(I first, S last) noexcept(NO_EXCEPT) {
        this->_impl.assign(first, last);
        return *this;
    }

    template<std::ranges::input_range R>
    inline auto& assign(R&& range) noexcept(NO_EXCEPT) { return this->assign(ALL(range)); }

    inline auto& fill(const value_type& v = value_type()) noexcept(NO_EXCEPT) {
        std::fill(this->data(), this->data() + this->_impl.size(), v);
        this->_init();
        return *this;
    }

    inline auto size() const noexcept(NO_EXCEPT) { return this->_impl.size(); }
    inline bool empty() const noexcept(NO_EXCEPT) { return this->_impl.size() == 0; }

    struct point_reference : internal::point_reference<fenwick_tree> {
        point_reference(fenwick_tree *const super, const size_type p) noexcept(NO_EXCEPT)
          : internal::point_reference<fenwick_tree>(super, super->_positivize_index(p))
        {
            assert(0 <= this->_pos && this->_pos < this->_super->size());
        }

        operator value_type() const noexcept(NO_EXCEPT) { return this->_super->get(this->_pos); }
        auto val() const noexcept(NO_EXCEPT) { return this->_super->get(this->_pos); }

        inline auto& operator=(const value_type& v) noexcept(NO_EXCEPT) {
            this->_super->set(this->_pos, v);
            return *this;
        }

        inline auto& operator+=(const value_type& v) noexcept(NO_EXCEPT) {
            this->_super->add(this->_pos, v);
            return *this;
        }
    };

    struct range_reference : internal::range_reference<fenwick_tree> {
        range_reference(fenwick_tree *const super, const size_type l, const size_type r) noexcept(NO_EXCEPT)
          : internal::range_reference<fenwick_tree>(super, super->_positivize_index(l), super->_positivize_index(r))
        {
            assert(0 <= this->_begin && this->_begin <= this->_end && this->_end <= this->_super->size());
        }

        inline auto fold() noexcept(NO_EXCEPT) {
            if(this->_begin == 0 and this->_end == this->_super->size()) return this->_super->fold();
            if(this->_begin == 0) return this->_super->fold(this->_end);
            return this->_super->fold(this->_begin, this->_end);
        }
    };


    inline auto& add(const size_type p, const value_type& x) noexcept(NO_EXCEPT) {
        assert(0 <= p && p < this->_impl.size());
        this->_impl.add(p, x);
         return *this;
    }

    inline auto& set(const size_type p, const value_type& x) noexcept(NO_EXCEPT)
        requires algebraic::internal::invertible<value_type>
    {
        assert(0 <= p && p < this->_impl.size());
        this->_impl.set(p, x);
         return *this;
    }

    inline value_type get(const size_type p) const noexcept(NO_EXCEPT)
        requires algebraic::internal::invertible<value_type>
    {
        assert(0 <= p && p < this->_impl.size());
        return this->_impl.get(p);
    }

    inline auto operator[](const size_type p) noexcept(NO_EXCEPT) { return point_reference(this, p); }

    inline const auto operator()(const size_type l, const size_type r) const noexcept(NO_EXCEPT) {
        return range_reference(this, l, r);
    }

    inline auto operator()(const size_type l, const size_type r) noexcept(NO_EXCEPT) {
        return range_reference(this, l, r);
    }

    inline auto fold(const size_type l, const size_type r) const noexcept(NO_EXCEPT)
        requires algebraic::internal::invertible<value_type>
    {
        assert(0 <= l && l <= r && r <= this->_impl.size());
        return this->_impl.fold(l, r);
    }

    inline auto fold(const size_type r) const noexcept(NO_EXCEPT) {
        assert(0 <= r && r <= this->_impl.size());
        return this->_impl.fold(r);
    }

    inline auto fold() const noexcept(NO_EXCEPT) {
        return this->_impl.fold(this->_impl.size());
    }

    struct iterator;

  protected:
    using iterator_interface = internal::container_iterator_interface<value_type, const fenwick_tree, iterator>;

  public:
    struct iterator : iterator_interface {
        using iterator_interface::iterator_interface;
    };

    inline auto begin() const noexcept(NO_EXCEPT) { return iterator(this, 0); }
    inline auto end() const noexcept(NO_EXCEPT) { return iterator(this, this->_impl.size()); }

    inline auto rbegin() const noexcept(NO_EXCEPT) { return std::make_reverse_iterator(this->end()); }
    inline auto rend() const noexcept(NO_EXCEPT) { return std::make_reverse_iterator(this->begin()); }
};


template<actions::internal::operatable_action Action>
struct fenwick_tree<Action> : fenwick_tree<typename Action::operand> {
    using fenwick_tree<typename Action::operand>::fenwick_tree;
};


} // namespace uni
#line 2 "data_structure/foldable_deque.hpp"


#line 6 "data_structure/foldable_deque.hpp"

#line 9 "data_structure/foldable_deque.hpp"

#line 12 "data_structure/foldable_deque.hpp"

#line 14 "data_structure/foldable_deque.hpp"

#line 2 "data_structure/foldable_stack.hpp"


#line 6 "data_structure/foldable_stack.hpp"


#line 10 "data_structure/foldable_stack.hpp"

#line 14 "data_structure/foldable_stack.hpp"

#line 17 "data_structure/foldable_stack.hpp"

#line 19 "data_structure/foldable_stack.hpp"


namespace uni {



template<class, template<class...> class = stack>
struct foldable_stack : internal::unconstructible {};


template<algebraic::internal::monoid Monoid, template<class...> class Stack>
struct foldable_stack<Monoid, Stack> {
    using fold_type = Monoid;
    using value_type = Monoid::value_type;

    using size_type = Stack<Monoid>::size_type;

    Stack<value_type> _val;
    Stack<fold_type> _acc;


    inline bool empty() const noexcept(NO_EXCEPT) { return this->_val.empty(); }
    inline auto size() const noexcept(NO_EXCEPT) { return this->_val.size(); }


    inline decltype(auto) top() const noexcept(NO_EXCEPT) {
        assert(!this->empty());
        return this->_val.top();
    }

    template<std::convertible_to<value_type> T = value_type>
        requires std::is_move_constructible_v<T>
    inline decltype(auto) top_or(T&& val) const noexcept(NO_EXCEPT) {
        if(this->empty()) return static_cast<value_type>(std::forward<T>(val));
        else return this->top();
    }


    inline auto fold() const noexcept(NO_EXCEPT) {
        if(this->empty()) return fold_type();
        return this->_acc.top();
    }


    template<std::convertible_to<fold_type> T = value_type>
    auto& push(T&& x) noexcept(NO_EXCEPT) {
        const auto acc = this->fold();
        this->_val.push(x);
        this->_acc.push(acc + std::forward<T>(x));
        return *this;
    }

    template<class... Args>
    decltype(auto) emplace(Args&&... args) noexcept(NO_EXCEPT) {
        const auto acc = this->fold();
        decltype(auto) res = this->_val.emplace(std::forward<Args>(args)...);
        this->_acc.push(acc + res);
        return res;
    }

    inline auto& pop() noexcept(NO_EXCEPT) {
        this->_val.pop(), this->_acc.pop();
        return *this;
    }
};


template<actions::internal::operatable_action Action, template<class...> class Stack>
struct foldable_stack<Action, Stack> : foldable_stack<typename Action::operand> {
    using foldable_stack<typename Action::operand>::foldable_stack;
};


} // namespace uni
#line 16 "data_structure/foldable_deque.hpp"


namespace uni {


namespace internal {


template<algebraic::internal::monoid Monoid, template<class...> class Stack>
using foldable_deque_base = deque_by_stack<foldable_stack<algebraic::make_opposite_t<Monoid>, Stack>, foldable_stack<Monoid, Stack>>;


} // namespace internal


template<class, template<class...> class = stack>
struct foldable_deque : internal::unconstructible {};


template<algebraic::internal::monoid Monoid, template<class...> class Stack>
struct foldable_deque<Monoid, Stack> : internal::foldable_deque_base<Monoid, Stack> {
    using internal::foldable_deque_base<Monoid, Stack>::foldable_deque_base;

    inline auto fold() const noexcept(NO_EXCEPT) {
        return Monoid(this->_front.fold()) + this->_back.fold();
    }
};


template<actions::internal::operatable_action Action, template<class...> class Stack>
struct foldable_deque<Action, Stack> : foldable_deque<typename Action::operand> {
    using foldable_deque<typename Action::operand>::foldable_deque;
};


} // namespace uni
#line 2 "data_structure/foldable_queue.hpp"


#line 6 "data_structure/foldable_queue.hpp"

#line 9 "data_structure/foldable_queue.hpp"

#line 12 "data_structure/foldable_queue.hpp"

#line 14 "data_structure/foldable_queue.hpp"

#line 16 "data_structure/foldable_queue.hpp"


namespace uni {


namespace internal {


template<algebraic::internal::monoid Monoid, template<class...> class Stack>
using foldable_queue_base = queue_by_stack<foldable_stack<Monoid, Stack>, foldable_stack<algebraic::make_opposite_t<Monoid>, Stack>>;


} // namespace internal


template<class, template<class...> class = stack>
struct foldable_queue : internal::unconstructible {};


template<algebraic::internal::monoid Monoid, template<class...> class Stack>
struct foldable_queue<Monoid, Stack> : internal::foldable_queue_base<Monoid, Stack> {
    using internal::foldable_queue_base<Monoid, Stack>::foldable_queue_base;

    inline auto fold() const noexcept(NO_EXCEPT) {
        return Monoid(this->_out.fold()) + this->_in.fold();
    }
};


template<actions::internal::operatable_action Action, template<class...> class Stack>
struct foldable_queue<Action, Stack> : foldable_queue<typename Action::operand> {
    using foldable_queue<typename Action::operand>::foldable_queue;
};


} // namespace uni
#line 2 "data_structure/kth_element.hpp"


#line 11 "data_structure/kth_element.hpp"


#line 15 "data_structure/kth_element.hpp"


namespace uni {


// Thanks to: https://qiita.com/drken/items/1b7e6e459c24a83bb7fd
template<
    class T,
    std::ranges::output_range<T> Container = std::vector<T>,
    std::strict_weak_order<T, T> Comparer = std::less<T>,
    std::strict_weak_order<T, T> RevComparer = std::greater<T>,
    std::integral Size = internal::size_t
>
struct kth_element {
    using value_type = T;
    using size_type = Size;

  protected:
    size_type _k;
    std::priority_queue<T, Container, Comparer> _small;
    std::priority_queue<T, Container, RevComparer> _large;

  public:
    kth_element(const size_type k = 0) noexcept(NO_EXCEPT) : _k(k + 1) { assert(k >= 0); }

    inline bool has() const noexcept(NO_EXCEPT) { return std::ssize(this->_small) == this->_k; }

    inline value_type value() const noexcept(NO_EXCEPT) { return this->_small.top(); }

    inline std::optional<value_type> get() const noexcept(NO_EXCEPT) {
        if(this->has()) return this->value();
        return {};
    }

    template<std::convertible_to<T> U = T>
    inline auto value_or(U&& v) const noexcept(NO_EXCEPT) {
        return this->get().value_or(std::forward<U>(v));
    }

    inline void push(const value_type& v) noexcept(NO_EXCEPT) {
        if(std::ssize(this->_small) < this->_k) {
            this->_small.push(v);
            return;
        }

        const auto kth = this->_small.top();

        if(Comparer{}(v, kth)) {
            this->_small.pop();
            this->_small.push(v);
            this->_large.push(kth);
        }
        else {
            this->_large.push(v);
        }
    }

    inline void pop() noexcept(NO_EXCEPT) {
        assert(this->has());

        this->_small.pop();

        if(this->_large.empty()) return;

        const auto v = this->_large.top();

        this->_large.pop();
        this->_small.push(v);
    }
};


} // namespace uni
#line 2 "data_structure/lazy_segment_tree.hpp"


#line 12 "data_structure/lazy_segment_tree.hpp"


#line 15 "data_structure/lazy_segment_tree.hpp"

#line 21 "data_structure/lazy_segment_tree.hpp"

#line 24 "data_structure/lazy_segment_tree.hpp"

#line 26 "data_structure/lazy_segment_tree.hpp"

#line 29 "data_structure/lazy_segment_tree.hpp"


namespace uni {

namespace internal {

namespace lazy_segment_tree_impl {

// Thanks to: atcoder::lazy_segtree
template<actions::internal::full_action Action>
    requires
        algebraic::internal::monoid<typename Action::operand> &&
        algebraic::internal::monoid<typename Action::operation>
struct core {
    using size_type = internal::size_t;

    using action = Action;
    using operand = typename Action::operand;
    using operation = typename Action::operation;

 private:
    size_type _n = 0, _size = 0, _depth = 0;
    std::valarray<size_type> _lengths;
    std::valarray<operand> _values;
    std::valarray<operation> _lazy;


    inline void _pull(const size_type p) noexcept(NO_EXCEPT) {
        this->_values[p] = this->_values[p << 1] + this->_values[p << 1 | 1];
    }

    inline void _all_apply(const size_type p, const operation& f) noexcept(NO_EXCEPT) {
        this->_values[p] = action::mapping(action::power(f, this->_lengths[p]), this->_values[p]);
        if(p < this->_size) this->_lazy[p] = f + this->_lazy[p];
    }

    inline void _push(const size_type p) noexcept(NO_EXCEPT) {
        this->_all_apply(p << 1, this->_lazy[p]);
        this->_all_apply(p << 1 | 1, this->_lazy[p]);
        this->_lazy[p] = operation{};
    }

    inline void _init() noexcept(NO_EXCEPT) {
        REPD(p, 1, this->_size) {
            this->_lengths[p] = this->_lengths[p << 1] + this->_lengths[p << 1 | 1];
            this->_pull(p);
        }
    }

  public:
    core() noexcept = default;

    explicit core(const size_type n) noexcept(NO_EXCEPT)
      : _n(n), _size(std::bit_ceil(uni::to_unsigned(n))), _depth(std::countr_zero(uni::to_unsigned(this->_size))),
        _lengths(this->_size << 1), _values(this->_size << 1), _lazy(this->_size)
    {}


    inline size_type size() const noexcept(NO_EXCEPT) { return this->_n; }
    inline size_type allocated() const noexcept(NO_EXCEPT) { return this->_values.size(); }
    inline size_type depth() const noexcept(NO_EXCEPT) { return this->_depth; }


    inline operand fold_all() const noexcept(NO_EXCEPT) { return this->_values[1]; }


    inline void fill( const operand& v = operand()) noexcept(NO_EXCEPT) {
        REP(p, 0, this->_n) {
            this->_lengths[this->_size + p] = 1, this->_values[this->_size + p] = v;
        }
        this->_init();
    }

    template<std::input_iterator I, std::sentinel_for<I> S>
    inline void assign(I first, S last) noexcept(NO_EXCEPT) {
        if constexpr(std::sized_sentinel_for<operand, I>) {
            assert(std::ranges::distance(first, last) == this->_n);
        }
        size_type p = 0;
        for(auto itr=first; itr!=last; ++itr, ++p) {
            this->_lengths[this->_size + p] = 1, this->_values[this->_size + p] = static_cast<operand>(*itr);
        }
        this->_init();
    }


    inline void set(size_type p, const operand& x) noexcept(NO_EXCEPT) {
        p += this->_size;
        FORD(i, 1, this->_depth) this->_push(p >> i);
        this->_values[p] = x;
        FOR(i, 1, this->_depth) this->_pull(p >> i);
    }

    inline void add(size_type p, const operand& x) noexcept(NO_EXCEPT) {
        p += this->_size;
        FORD(i, 1, this->_depth) this->_push(p >> i);
        this->_values[p] = this->_values[p] + x;
        FOR(i, 1, this->_depth) this->_pull(p >> i);
    }

    inline operand get(size_type p) noexcept(NO_EXCEPT) {
        p += this->_size;
        FORD(i, 1, this->_depth) this->_push(p >> i);
        return this->_values[p];
    }

    inline operand fold(size_type l, size_type r) noexcept(NO_EXCEPT) {
        if(l == r) return {};

        l += this->_size;
        r += this->_size;

        FORD(i, 1, this->_depth) {
            if(((l >> i) << i) != l) this->_push(l >> i);
            if(((r >> i) << i) != r) this->_push((r - 1) >> i);
        }

        operand sml = operand{}, smr = operand{};
        while(l < r) {
            if(l & 1) sml = sml + this->_values[l++];
            if(r & 1) smr = this->_values[--r] + smr;
            l >>= 1;
            r >>= 1;
        }

        return sml + smr;
    }


    inline void apply(size_type p, const operation& f) noexcept(NO_EXCEPT) {
        p += this->_size;
        FORD(i, 1, this->_depth) this->_push(p >> i);
        this->_values[p] = action::mapping(action::power(f, this->_lengths[p]), this->_values[p]);
        FOR(i, 1, this->_depth) this->_pull(p >> i);
    }

    inline void apply(size_type l, size_type r, const operation& f) noexcept(NO_EXCEPT) {
        if(l == r) return;

        l += this->_size;
        r += this->_size;

        FORD(i, 1, this->_depth) {
            if(((l >> i) << i) != l) this->_push(l >> i);
            if(((r >> i) << i) != r) this->_push((r - 1) >> i);
        }

        {
            size_type l2 = l, r2 = r;
            while(l < r) {
                if(l & 1) this->_all_apply(l++, f);
                if(r & 1) this->_all_apply(--r, f);
                l >>= 1;
                r >>= 1;
            }
            l = l2;
            r = r2;
        }

        FOR(i, 1, this->_depth) {
            if(((l >> i) << i) != l) this->_pull(l >> i);
            if(((r >> i) << i) != r) this->_pull((r - 1) >> i);
        }
    }


    template<class F>
    inline size_type max_right(size_type l, F&& f) noexcept(NO_EXCEPT) {
        assert(0 <= l && l <= _n);
        assert(f(operand{}));
        if(l == _n) return _n;
        l += this->_size;
        FORD(i, 1, this->_depth) this->_push(l >> i);
        operand sm;
        do {
            while(l % 2 == 0) l >>= 1;
            if(!f(sm + this->_values[l])) {
                while(l < this->_size) {
                    this->_push(l);
                    l = (2 * l);
                    if(f(sm + this->_values[l])) {
                        sm = sm + this->_values[l];
                        l++;
                    }
                }
                return l - this->_size;
            }
            sm = sm + this->_values[l];
            l++;
        } while((l & -l) != l);
        return _n;
    }


    template<class F>
    inline size_type min_left(size_type r, F&& f) noexcept(NO_EXCEPT) {
        assert(0 <= r && r <= _n);
        assert(f(operand{}));
        if(r == 0) return 0;
        r += this->_size;
        FORD(i, 1, this->_depth) this->_push((r - 1) >> i);
        operand sm;
        do {
            r--;
            while(r > 1 && (r % 2)) r >>= 1;
            if(!f(this->_values[r] + sm)) {
                while(r < this->_size) {
                    this->_push(r);
                    r = (2 * r + 1);
                    if(f(this->_values[r] + sm)) {
                        sm = this->_values[r] + sm;
                        r--;
                    }
                }
                return r + 1 - this->_size;
            }
            sm = this->_values[r] + sm;
        } while((r & -r) != r);
        return 0;
    }
};


} // namespace lazy_segment_tree_impl

} // namespace internal


template<class T>
struct lazy_segment_tree : lazy_segment_tree<actions::make_full_t<T>> {
    using lazy_segment_tree<actions::make_full_t<T>>::lazy_segment_tree;
};


template<actions::internal::full_action Action>
    requires internal::available<internal::lazy_segment_tree_impl::core<Action>>
struct lazy_segment_tree<Action> {
    using action = Action;
    using operand = Action::operand;
    using operation = Action::operation;

  private:
    using core = internal::lazy_segment_tree_impl::core<action>;

    core _impl;

  public:
    using value_type = operand;
    using action_type = operation::value_type;

    using size_type = core::size_type;

    inline auto size() const noexcept(NO_EXCEPT) { return this->_impl.size(); }
    inline auto allocated() const noexcept(NO_EXCEPT) { return this->_impl.allocated(); }
    inline auto depth() const noexcept(NO_EXCEPT) { return this->_impl.depth(); }

  protected:
    inline size_type _positivize_index(const size_type p) const noexcept(NO_EXCEPT) {
        return p < 0 ? this->_impl.size() + p : p;
    }

  public:
    lazy_segment_tree() noexcept(NO_EXCEPT) : _impl() {}

    explicit lazy_segment_tree(const size_type n, const value_type& v = value_type()) noexcept(NO_EXCEPT) : _impl(n) { this->_impl.fill(v); }

    template<std::convertible_to<value_type> T>
    lazy_segment_tree(const std::initializer_list<T>& init_list) noexcept(NO_EXCEPT) : lazy_segment_tree(ALL(init_list)) {}

    template<std::input_iterator I, std::sized_sentinel_for<I> S>
    lazy_segment_tree(I first, S last) noexcept(NO_EXCEPT)
      : _impl(static_cast<size_type>(std::ranges::distance(first, last)))
    { this->assign(first, last); }

    template<std::ranges::input_range R>
    explicit lazy_segment_tree(R&& range) noexcept(NO_EXCEPT) : lazy_segment_tree(ALL(range)) {}

    template<std::convertible_to<value_type> T>
    inline auto& assign(const std::initializer_list<T>& init_list) noexcept(NO_EXCEPT)
    {
        return this->assign(ALL(init_list));
    }

    template<std::input_iterator I, std::sentinel_for<I> S>
    inline auto& assign(I first, S last) noexcept(NO_EXCEPT) {
        this->_impl.assign(first, last);
        return *this;
    }

    template<std::ranges::input_range R>
    inline auto& assign(R&& range) noexcept(NO_EXCEPT) { return this->assign(ALL(range)); }

    inline auto& fill( const value_type& v = value_type()) noexcept(NO_EXCEPT) {
        this->impl.fill(v);
        return *this;
    }

    bool empty() const noexcept(NO_EXCEPT) { return this->_impl.size() == 0; }

    struct point_reference : internal::point_reference<lazy_segment_tree> {
        point_reference(lazy_segment_tree *const super, const size_type p) noexcept(NO_EXCEPT)
          : internal::point_reference<lazy_segment_tree>(super, super->_positivize_index(p))
        {
            assert(0 <= this->_pos && this->_pos < this->_super->size());
        }

        operator value_type() noexcept(NO_EXCEPT) { return this->_super->get(this->_pos); }
        auto val() noexcept(NO_EXCEPT) { return this->_super->get(this->_pos); }

        inline auto& operator=(const value_type& v) noexcept(NO_EXCEPT) {
            this->_super->set(this->_pos, v);
            return *this;
        }

        inline auto& operator+=(const value_type& v) noexcept(NO_EXCEPT) {
            this->_super->add(this->_pos, v);
            return *this;
        }

        inline auto& operator*=(const action_type& v) noexcept(NO_EXCEPT) {
            this->_super->apply(this->_pos, v);
            return *this;
        }
    };

    struct range_reference : internal::range_reference<lazy_segment_tree> {
        range_reference(lazy_segment_tree *const super, const size_type l, const size_type r) noexcept(NO_EXCEPT)
          : internal::range_reference<lazy_segment_tree>(super, super->_positivize_index(l), super->_positivize_index(r))
        {
            assert(0 <= this->_begin && this->_begin <= this->_end && this->_end <= this->_super->size());
        }

        inline auto& operator*=(const action_type& v) noexcept(NO_EXCEPT) {
            this->_super->apply(this->_begin, this->_end, v);
            return *this;
        }

        inline auto fold() noexcept(NO_EXCEPT) {
            if(this->_begin == 0 && this->_end == this->_super->size()) return this->_super->fold();
            return this->_super->fold(this->_begin, this->_end);
        }
    };


    inline auto& set(size_type p, const value_type& v) noexcept(NO_EXCEPT) {
        p = this->_positivize_index(p), assert(0 <= p && p < this->_impl.size());
        this->_impl.set(p, v);
         return *this;
    }

    inline auto& add(size_type p, const value_type& v) noexcept(NO_EXCEPT) {
        p = this->_positivize_index(p), assert(0 <= p && p < this->_impl.size());
        this->_impl.add(p, v);
         return *this;
    }


    inline auto& apply(size_type l, size_type r, const action_type& v) noexcept(NO_EXCEPT) {
        l = this->_positivize_index(l), r = this->_positivize_index(r);
        assert(0 <= l && l <= r && r <= this->_impl.size());
        this->_impl.apply(l, r, v);
        return *this;
    }

    inline auto& apply(const size_type p, const action_type& v) noexcept(NO_EXCEPT) {
        this->apply(p, p + 1, v);
        return *this;
    }

    inline auto& apply(const action_type& v) noexcept(NO_EXCEPT) { this->apply(0, this->_impl.size(), v);  return *this; }


    inline auto get(size_type p) noexcept(NO_EXCEPT) {
        p = this->_positivize_index(p), assert(0 <= p && p < this->_impl.size());
        return this->_impl.get(p);
    }

    inline auto operator[](const size_type p) noexcept(NO_EXCEPT) { return point_reference(this, p); }
    inline auto operator()(const size_type l, const size_type r) noexcept(NO_EXCEPT) { return range_reference(this, l, r); }


    inline auto fold(size_type l, size_type r) noexcept(NO_EXCEPT) {
        l = this->_positivize_index(l), r = this->_positivize_index(r);
        assert(0 <= l && l <= r && r <= this->_impl.size());
        return this->_impl.fold(l, r);
    }
    inline auto fold() noexcept(NO_EXCEPT) { return this->_impl.fold_all(); }



    template<bool (*f)(value_type)>
    inline auto max_right(const size_type l) noexcept(NO_EXCEPT) {
        return this->max_right(l, [](operand x) { return f(x); });
    }

    template<class F>
    inline auto max_right(const size_type l, F&& f) noexcept(NO_EXCEPT) {
        return this->_impl.max_right(l, std::forward<F>(f));
    }


    template<bool (*f)(value_type)>
    inline auto min_left(const size_type r) noexcept(NO_EXCEPT) {
        return min_left(r, [](operand x) { return f(x); });
    }

    template<class F>
    inline auto min_left(const size_type r, F&& f) noexcept(NO_EXCEPT) {
        return this->_impl.min_left(r, std::forward<F>(f));
    }

    struct iterator;

  protected:
    using iterator_interface = internal::container_iterator_interface<value_type, lazy_segment_tree, iterator>;

  public:
    struct iterator : iterator_interface {
        using iterator_interface::iterator_interface;
    };

    inline auto begin() noexcept(NO_EXCEPT) { return iterator(this, 0); }
    inline auto end() noexcept(NO_EXCEPT) { return iterator(this, this->_impl.size()); }

    inline auto rbegin() noexcept(NO_EXCEPT) { return std::make_reverse_iterator(this->end()); }
    inline auto rend() noexcept(NO_EXCEPT) { return std::make_reverse_iterator(this->begin()); }
};


} // namespace uni
#line 2 "data_structure/persistent_queue.hpp"


#line 9 "data_structure/persistent_queue.hpp"


#line 12 "data_structure/persistent_queue.hpp"

#line 16 "data_structure/persistent_queue.hpp"


namespace uni {


// Thanks to: https://tk0-math.hatenablog.com/entry/2020/03/27/194150
template<class ValueType, u32 BUFFER_DEPTH = 20, class Allocator = std::allocator<ValueType>>
struct persistent_queue {
    using value_type = ValueType;
    using size_type = internal::size_t;


    struct node_type;
    using node_handler = node_handlers::cloneable<Allocator>::template handler<node_type>;

    using node_pointer = typename node_handler::node_pointer;
    using allocator_type = typename node_handler::allocator_type;

    struct node_type {
        value_type value;
        node_pointer prev[BUFFER_DEPTH];
    };

  private:
    size_type _size = 0;
    node_pointer _head, _tail;

    [[no_unique_address]] node_handler _node_handler;

  public:
    explicit persistent_queue(const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT) : _node_handler(allocator) {}


    persistent_queue(const persistent_queue& source, const allocator_type& allocator) noexcept(NO_EXCEPT)
      : _size(source._size), _head(source._head), _tail(source._tail), _node_handler(allocator)
    {}

    persistent_queue(persistent_queue&& source, const allocator_type& allocator) noexcept(NO_EXCEPT)
      : _size(source._size), _head(source._head), _tail(source._tail), _node_handler(allocator)
    {}


    inline auto clone() const noexcept(NO_EXCEPT) { return *this; }


    inline bool empty() const noexcept(NO_EXCEPT) { return this->_size == 0; }
    inline size_type size() const noexcept(NO_EXCEPT) { return this->_size; }


    inline value_type front() const noexcept(NO_EXCEPT) {
        assert(!this->empty());
        return this->_head->value;
    }

    template<std::convertible_to<value_type> T = value_type>
        requires std::is_move_constructible_v<T>
    inline value_type front_or(T&& v) const noexcept(NO_EXCEPT) {
        if(this->empty()) return static_cast<value_type>(std::forward<T>(v));
        else return this->front();
    }


    inline value_type back() const noexcept(NO_EXCEPT) {
        assert(!this->empty());
        return this->_tail->value;
    }

    template<std::convertible_to<value_type> T = value_type>
        requires std::is_move_constructible_v<T>
    inline value_type back_or(T&& v) const noexcept(NO_EXCEPT) {
        if(this->empty()) return static_cast<value_type>(std::forward<T>(v));
        else return this->back();
    }


    inline auto& clear() noexcept(NO_EXCEPT) {
        this->_head.reset(), this->_tail.reset();
        this->_size = 0;
        return *this;
    }


    template<std::convertible_to<value_type> T = value_type>
    auto& push(T&& x) noexcept(NO_EXCEPT) {
        node_pointer node = this->_node_handler.create(x);

        node->prev[0] = this->_tail;

        REP(i, 1, BUFFER_DEPTH) {
            node_pointer prev = node->prev[i - 1];
            if(prev) node->prev[i] = prev->prev[i - 1];
            else break;
        }

        if(!this->_head) this->_head = node;
        this->_tail = node;

        ++this->_size;

        return *this;
    }


    auto& pop() noexcept(NO_EXCEPT) {
        assert(!this->empty());

        if(!this->_head || !this->_tail || this->_size == 1) {
            this->clear();
            return *this;
        }

        auto index = to_unsigned(this->_size - 2);
        node_pointer node = this->_tail;

        while(index != 0) {
            const size_type msb = uni::highest_bit_pos(index);
            index -= 1 << msb;
            node = node->prev[msb];
        }

        this->_head = node;
        --this->_size;

        return *this;
    }
};


namespace pmr {


template<class T, u32 BUFFER_DEPTH = 20>
using persistent_queue = uni::persistent_queue<T, BUFFER_DEPTH, std::pmr::polymorphic_allocator<T>>;


} // namesapce pmr


} // namespace uni
#line 2 "data_structure/persistent_stack.hpp"


#line 7 "data_structure/persistent_stack.hpp"


#line 10 "data_structure/persistent_stack.hpp"

#line 13 "data_structure/persistent_stack.hpp"


namespace uni {


template<class ValueType, class Allocator = std::allocator<ValueType>>
struct persistent_stack {
    using value_type = ValueType;
    using size_type = internal::size_t;


    struct node_type;
    using node_handler = node_handlers::cloneable<Allocator>::template handler<node_type>;

    using allocator_type = typename node_handler::allocator_type;
    using node_pointer = typename node_handler::node_pointer;

    struct node_type {
        value_type value;
        node_pointer next;

        node_type(node_pointer _next, value_type _value) noexcept(NO_EXCEPT)
          : value(_value), next(_next)
        {}

        template<class... Args>
        node_type(node_pointer _next, Args&&... args) noexcept(NO_EXCEPT)
          : value(std::forward<Args>(args)...), next(_next)
        {}
    };

  private:
    size_type _size = 0;
    node_pointer _head;

    [[no_unique_address]] node_handler _node_handler;

  public:
    explicit persistent_stack(const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT) : _node_handler(allocator) {};


    persistent_stack(const persistent_stack& source, const allocator_type& allocator) noexcept(NO_EXCEPT)
      : _size(source._size), _head(source._head), _node_handler(allocator)
    {};

    persistent_stack(persistent_stack&& source, const allocator_type& allocator) noexcept(NO_EXCEPT)
      : _size(source._size), _head(source._head), _node_handler(allocator)
    {};


    inline auto clone() const noexcept(NO_EXCEPT) { return *this; }


    inline bool empty() const noexcept(NO_EXCEPT) { return !this->_head; }
    inline size_type size() const noexcept(NO_EXCEPT) { return this->_size; }

    inline value_type top() const noexcept(NO_EXCEPT) {
        assert(!this->empty());
        return this->_head->value;
    }

    template<std::convertible_to<value_type> T = value_type>
        requires std::is_move_constructible_v<T>
    inline value_type top_or(T&& v) const noexcept(NO_EXCEPT) {
        if(this->empty()) return static_cast<value_type>(std::forward<T>(v));
        else return this->top();
    }


    inline auto& clear() noexcept(NO_EXCEPT) {
        this->_head.reset();
        this->_size = 0;
        return *this;
    }


    template<std::convertible_to<value_type> T = value_type>
    inline auto& push(T&& x) noexcept(NO_EXCEPT) {
        this->_head = this->_node_handler.create(this->_head, std::forward<T>(x));
        ++this->_size;
        return *this;
    }

    template<class... Args>
    inline auto& emplace(Args&&... args) noexcept(NO_EXCEPT) {
        this->_head = this->_node_handler.create(this->_head, std::forward<Args>(args)...);
        ++this->_size;
        return this->_head->value;
    }


    inline auto& pop() noexcept(NO_EXCEPT) {
        assert(!this->empty());
        this->_head = this->_head->next;
        --this->_size;
        return *this;
    }
};


namespace pmr {


template<class T>
using persistent_stack = uni::persistent_stack<T, std::pmr::polymorphic_allocator<T>>;


} // namesapce pmr


} // namespace uni
#line 2 "data_structure/red_black_tree.hpp"


#line 13 "data_structure/red_black_tree.hpp"


#line 17 "data_structure/red_black_tree.hpp"

#line 23 "data_structure/red_black_tree.hpp"

#line 25 "data_structure/red_black_tree.hpp"

#line 27 "data_structure/red_black_tree.hpp"

#line 29 "data_structure/red_black_tree.hpp"


#line 32 "data_structure/red_black_tree.hpp"


namespace uni {

namespace internal {


// Thanks to: http://blog.mitaki28.info/1447078746296/
template<class NodeHandler, class Derived, std::integral SizeType, class ValueType>
struct red_black_tree_impl {
    using size_type = SizeType;
    using rank_type = int;
    using value_type = ValueType;

    enum class node_colors : std::int8_t { RED, BLACK };

    struct node_type;
    using node_handler = typename NodeHandler::handler<node_type>;

    using allocator_type = typename node_handler::allocator_type;
    using node_pointer = typename node_handler::node_pointer;

    struct node_type {
        node_pointer left = node_handler::nil, right = node_handler::nil;

        node_colors color = node_colors::BLACK;
        size_type size = 0;
        rank_type rank = 0;

        inline constexpr bool is_leaf() const noexcept(NO_EXCEPT) {
            return this->left == node_handler::nil && this->right == node_handler::nil;
        }

        [[no_unique_address]] value_type data;

        node_type() noexcept = default;

        node_type(const value_type& _data, const size_type _size) noexcept(NO_EXCEPT)
            : size(_size), data(_data)
        {}

        node_type(const node_colors _color, const node_pointer& _left, const node_pointer& _right) noexcept(NO_EXCEPT)
          : left(_left), right(_right), color(_color)
        {}
    };

  private:
    using derived = Derived;

    inline auto* _derived() noexcept(NO_EXCEPT) {
        return static_cast<derived*>(this);
    }
    inline const auto* _derived() const noexcept(NO_EXCEPT) {
        return static_cast<const derived*>(this);
    }

    [[no_unique_address]] node_handler _node_handler;

  public:
    void pull(const node_pointer& tree) const noexcept(NO_EXCEPT) {
        if(tree == node_handler::nil) return;
        if(tree->is_leaf()) return;
        tree->size = tree->left->size + tree->right->size;
        tree->rank = tree->left->rank + (tree->left->color == node_colors::BLACK);
        this->_derived()->pull(tree);
    }

    void push(node_pointer& tree) noexcept(NO_EXCEPT) {
        if(tree == node_handler::nil) return;
        this->clone(tree);
        this->_derived()->push(tree);
        this->pull(tree);
    }

    inline void clone(node_pointer& tree) noexcept(NO_EXCEPT) {
        tree = this->_node_handler.clone(tree);
    }


    node_pointer create(const value_type& val, const size_type size) noexcept(NO_EXCEPT) {
        if(size == 0) return node_handler::nil;
        return this->_node_handler.create(val, size);
    }

    node_pointer create(const node_colors color, node_pointer left, node_pointer right) noexcept(NO_EXCEPT) {
        this->push(left);
        this->push(right);
        return this->_node_handler.create(color, std::move(left), std::move(right));
    }


    void dispose(const node_pointer& tree) noexcept(NO_EXCEPT) {
        if(this->_node_handler.disposable(tree)) {
            this->dispose(tree->left);
            this->dispose(tree->right);

            this->_node_handler.dispose(tree);
        }
    }

  private:
    void _as_root(node_pointer& node) {
        this->clone(node);
        if(node->color == node_colors::RED) node->color = node_colors::BLACK;
        this->push(node);
    }

    void _merge(node_pointer& tree, node_pointer left, node_pointer right) noexcept(NO_EXCEPT) {
        if(left->rank < right->rank) {
            this->push(right);
            this->_merge(tree, left, right->left);

            if(right->color == node_colors::BLACK && tree->color == node_colors::RED && tree->left->color == node_colors::RED) {
                tree->color = node_colors::BLACK;

                if(right->right->color == node_colors::BLACK) {
                    this->clone(right);
                    right->color = node_colors::RED;
                    right->left = tree->right;
                    this->pull(right);

                    this->clone(tree);
                    tree->right = std::move(right);
                }
                else {
                    this->clone(right->right);
                    right->right->color = node_colors::BLACK;

                    this->clone(right);
                    right->left = tree;
                    right->color = node_colors::RED;

                    tree = std::move(right);
                }
            }
            else {
                this->clone(right);
                right->left = tree;

                tree = std::move(right);
            }
        }
        else if(left->rank > right->rank) {
            this->push(left);
            this->_merge(tree, left->right, right);

            if(left->color == node_colors::BLACK && tree->color == node_colors::RED && tree->right->color == node_colors::RED) {
                tree->color = node_colors::BLACK;

                if(left->left->color == node_colors::BLACK) {
                    this->clone(left);
                    left->color = node_colors::RED;
                    left->right = tree->left;
                    this->pull(left);

                    this->clone(tree);
                    tree->left = std::move(left);
                }
                else {
                    this->clone(left->left);
                    left->left->color = node_colors::BLACK;

                    this->clone(left);
                    left->right = tree;
                    left->color = node_colors::RED;

                    tree = std::move(left);
                }
            }
            else {
                this->clone(left);
                left->right = tree;

                tree = std::move(left);
            }
        }
        else {
            tree = this->create(node_colors::RED, left, right);
        }

        this->pull(tree);
    }

    void _split(node_pointer tree, const size_type pos, node_pointer& left, node_pointer& right) {
        if(tree == node_handler::nil) {
            left = right = node_handler::nil;
            return;
        }

        this->push(tree);

        if(tree->is_leaf()) {
            left = this->create(tree->data, pos);
            right = this->create(tree->data, tree->size - pos);
            return;
        }

        auto l = std::move(tree->left), r = std::move(tree->right);
        this->_node_handler.dispose(tree);

        if(pos < l->size) {
            this->_split(std::move(l), pos, left, right);
            this->_as_root(r);
            this->merge(right, right, std::move(r));
            this->_as_root(left);
            return;
        }
        if(pos > l->size) {
            this->_split(std::move(r), pos - l->size, left, right);
            this->_as_root(l);
            this->merge(left, std::move(l), left);
            this->_as_root(right);
            return;
        }

        left = std::move(l), right = std::move(r);
        this->_as_root(left), this->_as_root(right);
    }

  public:
    explicit red_black_tree_impl(const allocator_type& allocator = allocator_type()) noexcept(NO_EXCEPT) : _node_handler(allocator) {}


    template<std::random_access_iterator I, std::sized_sentinel_for<I> S>
        requires std::constructible_from<value_type, std::iter_value_t<I>>
    node_pointer build(I first, S last) noexcept(NO_EXCEPT) {
        if(first == last) return node_handler::nil;
        if(std::ranges::next(first) == last) return this->create(value_type{ *first }, 1);

        const auto length = std::ranges::distance(first, last);
        const auto middle = std::ranges::next(first,  std::bit_floor(to_unsigned(length - 1)));

        node_pointer tree;
        this->merge(tree, this->build(std::move(first), middle), this->build(middle, std::move(last)));

        return tree;
    }


    template<std::random_access_iterator I, std::sized_sentinel_for<I> S>
        requires
            std::constructible_from<value_type, typename std::iter_value_t<I>::first_type> &&
            std::integral<typename std::iter_value_t<I>::second_type>
    node_pointer build(I first, S last) noexcept(NO_EXCEPT) {
        if(first == last) return node_handler::nil;
        if(std::ranges::next(first) == last) return this->create(value_type{ first->first }, first->second);

        const auto length = std::ranges::distance(first, last);
        const auto middle = std::ranges::next(first, std::bit_floor(to_unsigned(length - 1)));

        node_pointer tree;
        this->merge(tree, this->build(std::move(first), middle), this->build(middle, std::move(last)));

        return tree;
    }

    void split(const node_pointer& tree, const size_type pos, node_pointer& left, node_pointer& right) noexcept(NO_EXCEPT) {
        if(pos <= 0) {
            left = node_handler::nil;
            this->merge(right, this->create(value_type{}, -pos), tree);
        }
        else if(tree->size <= pos) {
            right = node_handler::nil;
            this->merge(left, tree, this->create(value_type{}, pos - tree->size));
        }
        else {
            this->_split(tree, pos, left, right);
        }
    }


    void merge(node_pointer& tree, const node_pointer& left, const node_pointer& right) noexcept(NO_EXCEPT) {
        if(left == node_handler::nil) {
            tree = right;
            this->push(tree);
        }
        else if(right == node_handler::nil) {
            tree = left;
            this->push(tree);
        }
        else {
            this->_merge(tree, left, right);
            tree->color = node_colors::BLACK;
        }

        this->pull(tree);
    }
};


} // namespace internal


template<std::integral SizeType = i64, class NodeHandler = uni::node_handlers::reusing<std::allocator<SizeType>>>
struct red_black_tree_context {
    static constexpr bool LEAF_ONLY = true;

    template<class Derived, class ValueType = internal::dummy>
    using substance = internal::red_black_tree_impl<NodeHandler, Derived, SizeType, ValueType>;
};

template<std::integral SizeType = i64, class Allocator = std::allocator<SizeType>>
struct persistent_red_black_tree_context {
    static constexpr bool LEAF_ONLY = true;

    template<class Derived, class ValueType = internal::dummy>
    using substance = internal::red_black_tree_impl<uni::node_handlers::cloneable<Allocator>, Derived, SizeType, ValueType>;
};


namespace pmr {


template<std::integral SizeType = i64>
using red_black_tree_context = uni::red_black_tree_context<SizeType, std::pmr::polymorphic_allocator<SizeType>>;


template<std::integral SizeType = i64>
using persistent_red_black_tree_context = uni::persistent_red_black_tree_context<SizeType, std::pmr::polymorphic_allocator<SizeType>>;


} // namespace pmr


} // namespace uni
#line 2 "data_structure/removable_priority_queue.hpp"


#line 8 "data_structure/removable_priority_queue.hpp"


#line 12 "data_structure/removable_priority_queue.hpp"

namespace uni {


namespace internal {


template<class T, class... Ts>
concept can_removable_priority_queue =
    sizeof...(Ts) == 0 &&
    requires (T pq, typename T::value_type v) {
        { pq.size() } -> std::same_as<typename T::size_type>;
        { pq.empty() } -> std::same_as<bool>;

        pq.top();
        pq.pop();

        pq.push(v);
        pq.emplace(v);
    };

} // namespace internal


template<class... Ts>
struct removable_priority_queue {};

template<class ValueType, class... Args>
    requires
        (!internal::can_removable_priority_queue<ValueType, Args...>) &&
        requires () {
            typename std::priority_queue<ValueType, Args...>;
        }
struct removable_priority_queue<ValueType, Args...> : removable_priority_queue<std::priority_queue<ValueType, Args...>> {
    using removable_priority_queue<std::priority_queue<ValueType, Args...>>::removable_priority_queue;
};

template<internal::can_removable_priority_queue PriorityQueue>
struct removable_priority_queue<PriorityQueue>
  : removable_priority_queue<PriorityQueue, internal::dummy>
{
    using removable_priority_queue<PriorityQueue, internal::dummy>::removable_priority_queue;
};

template<
    internal::can_removable_priority_queue PriorityQueue,
    class Multiset
>
struct removable_priority_queue<PriorityQueue, Multiset> : PriorityQueue {
    using base_type = PriorityQueue;
    using multiset_type = Multiset;

    using size_type = typename PriorityQueue::size_type;
    using value_type = typename PriorityQueue::value_type;
    using const_reference = typename PriorityQueue::const_reference;

  private:
    using self = removable_priority_queue<PriorityQueue, Multiset>;

    base_type _deleted;
    multiset_type _elements;

    static constexpr bool CHECK_EXISTANCE = !std::same_as<multiset_type, internal::dummy>;

    void _delete() noexcept(NO_EXCEPT) {
        while(!this->_deleted.empty() && this->_deleted.top() == this->base_type::top()) {
            this->base_type::pop();
            this->_deleted.pop();
        }
    }

  public:
    using base_type::base_type;


    size_type size() noexcept(NO_EXCEPT) {
        if constexpr(!self::CHECK_EXISTANCE) {
            assert(this->base_type::size() >= this->_deleted.size());
        }
        return this->base_type::size() - this->_deleted.size();
    }

    size_type empty() noexcept(NO_EXCEPT) {
        if constexpr(!self::CHECK_EXISTANCE) {
            assert(this->base_type::size() >= this->_deleted.size());
        }
        return this->base_type::size() == this->_deleted.size();
    }


    void push(const value_type& v) noexcept(NO_EXCEPT) {
        if constexpr(self::CHECK_EXISTANCE) this->_elements.insert(v);
        return this->base_type::push(v);
    }

    void push(value_type&& v) noexcept(NO_EXCEPT) {
        if constexpr(self::CHECK_EXISTANCE) this->_elements.insert(std::move(v));
        return this->base_type::push(std::move(v));
    }

    template<class... Args>
    decltype(auto) emplace(Args&&... args) noexcept(NO_EXCEPT) {
        if constexpr(self::CHECK_EXISTANCE) this->_elements.emplace(args...);
        return this->base_type::emplace(std::forward<Args>(args)...);
    }


    std::conditional_t<self::CHECK_EXISTANCE, bool, void> remove(const value_type& v) noexcept(NO_EXCEPT) {
        if constexpr(self::CHECK_EXISTANCE) {
            if(!this->_elements.contains(v)) return false;
        }

        this->_deleted.push(v);

        if constexpr(self::CHECK_EXISTANCE) return true;
    }

    std::conditional_t<self::CHECK_EXISTANCE, bool, void> remove(value_type&& v) noexcept(NO_EXCEPT) {
        if constexpr(self::CHECK_EXISTANCE) {
            if(!this->_elements.contains(v)) return false;
        }

        this->_deleted.push(std::move(v));

        if constexpr(self::CHECK_EXISTANCE) return true;
    }

    template<class... Args>
    std::conditional_t<self::CHECK_EXISTANCE, bool, void> eliminate(Args&&... args) noexcept(NO_EXCEPT) {
        if constexpr(self::CHECK_EXISTANCE) {
            if(!this->_elements.contains({ args... })) return false;
        }

        this->_deleted.emplace(std::forward<Args>(args)...);

        if constexpr(self::CHECK_EXISTANCE) return true;
    }


    const_reference top() noexcept(NO_EXCEPT) {
        this->_delete();
        return this->base_type::top();
    }


    void pop() noexcept(NO_EXCEPT) {
        this->_delete();
        this->base_type::pop();
    }
};


} // namespace uni
#line 2 "data_structure/restorable_stack.hpp"

#line 6 "data_structure/restorable_stack.hpp"

#line 8 "data_structure/restorable_stack.hpp"

namespace uni {

template<class T, class ID = int, template<class,class> class storage = std::unordered_map>
struct restorable_stack {
    using value_type = T;
    using key_type = ID;

  protected:
    struct node;
    using node_ptr = std::shared_ptr<node>;

    struct node {
        std::optional<value_type> val = std::nullopt;
        node_ptr parent;
    };

    node_ptr _current;
    storage<key_type, node_ptr> _storage;

  public:
    restorable_stack() noexcept(NO_EXCEPT) { this->clear(); };

    inline bool empty() const noexcept(NO_EXCEPT) {
        return !this->_current->val.has_value();
    }

    inline bool stored(const key_type& x) const noexcept(NO_EXCEPT) {
        return this->_storage.count(x);
    }


    inline const value_type& top() const noexcept(NO_EXCEPT) {
        return this->_current->val.value();
    }

    inline auto get() const noexcept(NO_EXCEPT) {
        return this->_current.val;
    }


    template<std::convertible_to<T> U = T>
    inline auto top_or(U &&v) const noexcept(NO_EXCEPT) {
        return this->_current->val.value_or(std::forward<U>(v));
    }


    inline auto& push(const value_type& x) noexcept(NO_EXCEPT) {
        this->_current.reset(new node{ x, this->_current });
        return *this;
    }

    inline auto& pop() noexcept(NO_EXCEPT) {
        this->_current = this->_current->parent;
        return *this;
    }


    inline auto& save(const key_type& x) noexcept(NO_EXCEPT) {
        this->_storage[x] = this->_current;
        return *this;
    }

    inline auto& load(const key_type& x) noexcept(NO_EXCEPT) {
        assert(this->stored(x));
        this->_current = this->_storage[x];
        return *this;
    }

    inline auto& clear() noexcept(NO_EXCEPT) {
        this->_current.reset(new node{});
        return *this;
    }

    inline auto& load_or_clear(const key_type& x) noexcept(NO_EXCEPT) {
        if(this->stored(x)) this->load(x);
        else this->clear();
        return *this;
    }
};

} // namespace uni
#line 2 "data_structure/segment_tree_rooter.hpp"


#line 5 "data_structure/segment_tree_rooter.hpp"


#line 9 "data_structure/segment_tree_rooter.hpp"


namespace uni {


template<std::integral SizeType>
struct segment_tree_rooter {
    using size_type = SizeType;

  private:
    size_type _n = 0;

  public:
    segment_tree_rooter() noexcept = default;

    explicit segment_tree_rooter(const size_type n) noexcept(NO_EXCEPT) : _n(n) {};

    inline size_type size() const noexcept(NO_EXCEPT) { return this->_n; }
    inline size_type allocated() const noexcept(NO_EXCEPT) { return (this->_n << 1) - 1; }

    template<std::invocable<size_type> F>
    void range_to_nodes(size_type l, size_type r, F&& f) noexcept(NO_EXCEPT) {
        l += this->_n;
        r += this->_n;

        while(l < r) {
            if(l & 1) f(l++ - 1);
            if(r & 1) f(--r - 1);
            l >>= 1;
            r >>= 1;
        }
    }

    size_type point_to_node(const size_type p) noexcept(NO_EXCEPT) { return this->_n + p - 1; }

    template<std::invocable<size_type> F>
    void point_to_path(size_type p, F&& f) noexcept(NO_EXCEPT) {
        p += this->_n;
        while(p > 0) f(p - 1), p >>= 1;
    }
};

}
#line 2 "data_structure/wavelet_matrix.hpp"


#line 19 "data_structure/wavelet_matrix.hpp"


#line 22 "data_structure/wavelet_matrix.hpp"

#line 27 "data_structure/wavelet_matrix.hpp"

#line 29 "data_structure/wavelet_matrix.hpp"

#line 31 "data_structure/wavelet_matrix.hpp"

#line 2 "iterable/compressed.hpp"


#line 10 "iterable/compressed.hpp"


#line 15 "iterable/compressed.hpp"

#line 17 "iterable/compressed.hpp"


namespace uni {

template<class T, class Container = vector<internal::size_t>>
struct compressed : Container {
    using size_type = internal::size_t;
    using value_type = T;

    std::vector<value_type> values;

  public:
    compressed() noexcept(NO_EXCEPT) = default;

    template<std::input_iterator I, std::sized_sentinel_for<I> S>
    compressed(I first, S last) noexcept(NO_EXCEPT) {
        this->values.assign(first, last);

        std::ranges::sort(ALL(this->values));

        this->values.erase(std::unique(ALL(this->values)), std::ranges::end(this->values));

        this->resize(std::ranges::distance(first, last));
        {
            auto itr = std::ranges::begin(*this);
            auto e = first;
            for(; e!=last; ++itr, ++e) *itr = this->rank(*e);
        }
    }

    template<std::ranges::input_range R>
    explicit compressed(R&& range) noexcept(NO_EXCEPT) : compressed(ALL(range)) {}

    inline size_type rank_sup() const { return static_cast<size_type>(this->values.size()); }

    inline size_type rank(const value_type& val) const noexcept(NO_EXCEPT) {
        return static_cast<size_type>(
            std::ranges::distance(std::ranges::begin(this->values), std::ranges::lower_bound(this->values, val))
        );
    }

    inline size_type rank2(const value_type& val) const noexcept(NO_EXCEPT) {
        return static_cast<size_type>(
            std::ranges::distance(std::ranges::begin(this->values), std::ranges::upper_bound(this->values, val))
        ) - 1;
    }

    inline value_type value(const size_type rank) const noexcept(NO_EXCEPT) {
        assert(0 <= rank && rank < this->rank_sup());
        return this->values[rank];
    }
};

template<std::input_iterator I, std::sized_sentinel_for<I> S>
explicit compressed(I, S) -> compressed<typename std::iterator_traits<I>::value_type>;

template<std::ranges::input_range R>
explicit compressed(R&&) -> compressed<typename std::ranges::range_value_t<R>>;


} // namespace uni
#line 33 "data_structure/wavelet_matrix.hpp"

#line 35 "data_structure/wavelet_matrix.hpp"

#line 38 "data_structure/wavelet_matrix.hpp"


namespace uni {

namespace internal {

namespace wavelet_matrix_impl {


// Thanks to: https://github.com/NyaanNyaan/library/blob/master/data-structure-2d/wavelet-matrix.hpp
template<std::unsigned_integral T, class MapType>
    requires std::same_as<T, typename MapType::key_type>
struct base {
    using size_type = internal::size_t;
    using impl_type = T;

  private:
    size_type _n;
    int _bits;

    std::vector<bit_vector> _index;
    std::vector<std::vector<impl_type>> _sum;

    MapType _first_pos;

    impl_type _max = 0;

  public:
    base() = default;

    template<std::ranges::input_range R>
    explicit base(R&& range) noexcept(NO_EXCEPT) : base(ALL(range)) {}

    template<std::input_iterator I, std::sentinel_for<I> S>
    base(I first, S last) noexcept(NO_EXCEPT) { this->build(first, last); }

    template<std::convertible_to<impl_type> U>
    base(const std::initializer_list<U>& init_list) noexcept(NO_EXCEPT) : base(ALL(init_list)) {}

    inline size_type size() const noexcept(NO_EXCEPT) { return this->_n; }
    inline size_type bits() const noexcept(NO_EXCEPT) { return this->_bits; }

    template<std::ranges::input_range R>
    inline void build(R&& range) noexcept(NO_EXCEPT) { this->build(ALL(range)); }

    template<std::input_iterator I, std::sized_sentinel_for<I> S>
        __attribute__((optimize("O3")))
    void build(I first, S last) noexcept(NO_EXCEPT) {
        this->_n = static_cast<size_type>(std::ranges::distance(first, last));
        this->_max = first == last ? -1 : *std::ranges::max_element(first, last);
        this->_bits = std::bit_width(this->_max + 1);

        this->_index.assign(this->_bits, this->_n);

        std::vector<impl_type> bit(first, last), nxt(this->_n);

        this->_sum.assign(this->_bits + 1, std::vector<impl_type>(this->_n + 1));

        {
            size_type i = 0;
            for(auto itr=first; itr!=last; ++i, ++itr) {
                assert(*itr >= 0);
                this->_sum[this->_bits][i + 1] = this->_sum[this->_bits][i] + *itr;
            }
        }

        REPD(h, this->_bits) {
            std::vector<size_type> vals;

            for(size_type i = 0; i < this->_n; ++i) {
                if((bit[i] >> h) & 1) this->_index[h].set(i);
            }
            this->_index[h].build();

            std::array<typename std::vector<impl_type>::iterator, 2> itrs{
                std::ranges::begin(nxt), std::ranges::next(std::ranges::begin(nxt), this->_index[h].zeros())
            };

            REP(i, this->_n) *itrs[this->_index[h].get(i)]++ = bit[i];

            REP(i, this->_n) this->_sum[h][i + 1] = this->_sum[h][i] + nxt[i];

            std::swap(bit, nxt);
        }

        REPD(i, this->_n) this->_first_pos[bit[i]] = static_cast<MapType::mapped_type>(i);
    }

  protected:
    inline auto get(const size_type k) const noexcept(NO_EXCEPT) {
        return this->_sum[this->_bits][k + 1] - this->_sum[this->_bits][k];
    }

    auto select(const impl_type& v, const size_type rank) const noexcept(NO_EXCEPT) {
        if(v > this->_max) return this->_n;
        if(not this->_first_pos.contains(v)) return this->_n;

        size_type pos = this->_first_pos.at(v) + rank;
        REP(h, this->_bits) {
            if(uni::bit(v, h)) pos = this->_index[h].select1(pos - this->_index[h].zeros());
            else pos = this->_index[h].select0(pos);
        }

        return pos;
    }


    auto kth_smallest(size_type *const l, size_type *const r, size_type *const k) const noexcept(NO_EXCEPT) {
        impl_type val = 0;

        for(size_type h = this->_bits - 1; h >= 0; --h) {
            size_type l0 = this->_index[h].rank0(*l), r0 = this->_index[h].rank0(*r);
            if(*k < r0 - l0) {
                *l = l0, *r = r0;
            }
            else {
                *k -= r0 - l0;
                val |= impl_type{1} << h;
                *l += this->_index[h].zeros() - l0;
                *r += this->_index[h].zeros() - r0;
            }
        }

        return val;
    }

    inline auto kth_smallest(size_type l, size_type r, size_type k) const noexcept(NO_EXCEPT) {
        return this->kth_smallest(&l, &r, &k);
    }

    auto kth_smallest_index(size_type l, size_type r, size_type k) const noexcept(NO_EXCEPT) {
       const impl_type val = this->kth_smallest(&l, &r, &k);

        size_type left = 0;
        REPD(h, this->_bits) {
            if(uni::bit(val, h)) left = this->_index[h].rank1(left) + this->_index[h].zeros();
            else  left = this->_index[h].rank0(left);
        }

        return this->select(val, l + k - left);
    }

    inline auto kth_largest(const size_type l, const size_type r, const size_type k) const noexcept(NO_EXCEPT) {
        return this->kth_smallest(l, r, r - l - k - 1);
    }
    inline auto kth_largest_index(const size_type l, const size_type r, const size_type k) const noexcept(NO_EXCEPT) {
        return this->kth_smallest_index(l, r, r - l - k - 1);
    }


    inline auto succ0(const size_type l, const size_type r, const size_type h) const noexcept(NO_EXCEPT) {
        return std::make_pair(this->_index[h].rank0(l), this->_index[h].rank0(r));
    }
    inline auto succ1(const size_type l, const size_type r, const size_type h) const noexcept(NO_EXCEPT) {
        const size_type l0 = this->_index[h].rank0(l);
        const size_type r0 = this->_index[h].rank0(r);
        const size_type vals = this->_index[h].zeros();
        return std::make_pair(l + vals - l0, r + vals - r0);
    }


    impl_type sum_in_range(
        const size_type l, const size_type r,
        const impl_type& x, const impl_type& y,
        const impl_type& cur, const size_type bit
    ) const noexcept(NO_EXCEPT)
    {
        if(l == r) return 0;

        if(bit == -1) {
            if(x <= cur && cur <= y) return cur * (r - l);
            return 0;
        }

        const impl_type nxt = (impl_type{1} << bit) | cur;
        const impl_type ones = ((impl_type{1} << bit) - 1) | nxt;

        if(ones < x || y < cur) return 0;

        if(x <= cur && ones <= y) return this->_sum[bit + 1][r] - this->_sum[bit + 1][l];

        const size_type l0 = this->_index[bit].rank0(l), r0 = this->_index[bit].rank0(r);
        const size_type l1 = l - l0, r1 = r - r0;

        return
            this->sum_in_range(l0, r0, x, y, cur, bit - 1) +
            this->sum_in_range(this->_index[bit].zeros() + l1, this->_index[bit].zeros() + r1, x, y, nxt, bit - 1);
    }

    inline auto sum_in_range(const size_type l, const size_type r, const impl_type& x, const impl_type& y) const noexcept(NO_EXCEPT) {
        return this->sum_in_range(l, r, x, y, 0, this->_bits - 1);
    }
    inline auto sum_under(const size_type l, const size_type r, const impl_type& v) const noexcept(NO_EXCEPT) {
        return this->sum_in_range(l, r, 0, v - 1);
    }
    inline auto sum_over(const size_type l, const size_type r, const impl_type& v) const noexcept(NO_EXCEPT) {
        return this->sum_in_range(l, r, v + 1, std::numeric_limits<impl_type>::max());
    }
    inline auto sum_or_under(const size_type l, const size_type r, const impl_type& v) const noexcept(NO_EXCEPT) {
        return this->sum_in_range(l, r, 0, v);
    }
    inline auto sum_or_over(const size_type l, const size_type r, const impl_type& v) const noexcept(NO_EXCEPT) {
        return this->sum_in_range(l, r, v, std::numeric_limits<impl_type>::max());
    }
    inline auto sum(const size_type l, const size_type r) const noexcept(NO_EXCEPT) {
        return this->_sum[this->_bits][r] - this->_sum[this->_bits][l];
    }

    auto count_under(size_type l, size_type r, const impl_type& y) const noexcept(NO_EXCEPT) {
        if(y >= (impl_type{1} << this->_bits)) return r - l;

        size_type res = 0;
        REPD(h, this->_bits) {
            bool f = (y >> h) & 1;
            size_type l0 = this->_index[h].rank0(l), r0 = this->_index[h].rank0(r);
            if(f) {
                res += r0 - l0;
                l += this->_index[h].zeros() - l0;
                r += this->_index[h].zeros() - r0;
            } else {
                l = l0;
                r = r0;
            }
        }

        return res;
    }

    inline auto count_or_under(const size_type l, const size_type r, const impl_type& v) const noexcept(NO_EXCEPT) {
        return this->count_under(l, r, v + 1);
    }
    inline auto count_or_over(const size_type l, const size_type r, const impl_type& v) const noexcept(NO_EXCEPT) {
        return r - l - this->count_under(l, r, v);
    }
    inline auto count_over(const size_type l, const size_type r, const impl_type& v) const noexcept(NO_EXCEPT) {
        return this->count_or_over(l, r, v + 1);
    }
    inline auto count_in_range(const size_type l, const size_type r, const impl_type& x, const impl_type& y) const noexcept(NO_EXCEPT) {
        return this->count_or_under(l, r, y) - this->count_under(l, r, x);
    }
    inline auto count_equal_to(const size_type l, const size_type r, const impl_type& v) const noexcept(NO_EXCEPT) {
        return this->count_in_range(l, r, v, v);
    }

    inline std::optional<impl_type> next(const size_type l, const size_type r, const impl_type& v, const size_type k) const noexcept(NO_EXCEPT) {
        const size_type rank = this->count_under(l, r, v) + k;
        if(rank < 0 || rank >= r - l) return {};
        return { this->kth_smallest(l, r, rank) };
    }

    inline std::optional<impl_type> prev(const size_type l, const size_type r, const impl_type& v, const size_type k) const noexcept(NO_EXCEPT) {
        const size_type rank = this->count_over(l, r, v) + k;
        if(rank < 0 || rank >= r - l) return {};
        return this->kth_largest(l, r, rank);
    }
};


} // namespace wavelet_matrix_impl

} // namespace internal


template<std::integral T, template<class...> class MapTemplate = gnu::gp_hash_table>
struct compressed_wavelet_matrix;


template<std::integral T, template<class...> class MapTemplate = gnu::gp_hash_table>
struct wavelet_matrix : internal::wavelet_matrix_impl::base<std::make_unsigned_t<T>, MapTemplate<std::make_unsigned_t<T>, u32>> {
    using value_type = T;
    using impl_type = std::make_unsigned_t<T>;

    using map_type = MapTemplate<impl_type, u32>;
    using size_type = internal::size_t;

    using compressed = compressed_wavelet_matrix<value_type, MapTemplate>;

  private:
    using base = internal::wavelet_matrix_impl::base<impl_type, map_type>;

  public:
  protected:
    inline size_type _positivize_index(const size_type p) const noexcept(NO_EXCEPT) {
        return p < 0 ? this->size() + p : p;
    }

  public:
    using base::base;

    inline bool empty() const noexcept(NO_EXCEPT) { return this->size() == 0; }

    inline value_type get(size_type p) const noexcept(NO_EXCEPT) {
        p = this->_positivize_index(p), assert(0 <= p && p < this->size());
        return this->base::get(p);
    }
    inline auto operator[](const size_type p) const noexcept(NO_EXCEPT) { return this->get(p); }

    inline auto select(const value_type& v, const size_type p) const noexcept(NO_EXCEPT) {
        return this->base::select(v, p);
    }

    struct iterator;
    struct range_reference;

    template<uni::interval_notation rng = uni::interval_notation::right_open>
    inline auto range(const size_type l, const size_type r) const noexcept(NO_EXCEPT) {
        if constexpr(rng == uni::interval_notation::right_open) return range_reference(this, l, r);
        if constexpr(rng == uni::interval_notation::left_open) return range_reference(this, l + 1, r + 1);
        if constexpr(rng == uni::interval_notation::open) return range_reference(this, l + 1, r);
        if constexpr(rng == uni::interval_notation::closed) return range_reference(this, l, r + 1);
    }
    inline auto range() const noexcept(NO_EXCEPT) { return range_reference(this, 0, this->size()); }
    inline auto operator()(const size_type l, const size_type r) const noexcept(NO_EXCEPT) { return range_reference(this, l, r); }

    inline auto subseq(const size_type p, const size_type c) const noexcept(NO_EXCEPT) { return range_reference(this, p, p+c); }
    inline auto subseq(const size_type p) const noexcept(NO_EXCEPT) { return range_reference(this, p, this->size()); }


    struct range_reference : internal::range_reference<const wavelet_matrix> {
        range_reference(const wavelet_matrix *const super, const size_type l, const size_type r) noexcept(NO_EXCEPT)
          : internal::range_reference<const wavelet_matrix>(super, super->_positivize_index(l), super->_positivize_index(r))
        {
            assert(0 <= this->_begin && this->_begin <= this->_end && this->_end <= this->_super->size());
        }

        inline auto get(const size_type k) const noexcept(NO_EXCEPT) {
            k = this->_super->_positivize_index(k);
            assert(0 <= k && k < this->size());

            return this->_super->get(this->_begin + k);
        }
        inline auto operator[](const size_type k) const noexcept(NO_EXCEPT) { return this->get(k); }


        inline value_type kth_smallest(const size_type k) const noexcept(NO_EXCEPT) {
            assert(0 <= k && k < this->size());
            return this->_super->base::kth_smallest(this->_begin, this->_end, k);
        }
        inline auto kth_smallest_element(const size_type k) const noexcept(NO_EXCEPT) {
            if(k == this->size()) return this->end();
            assert(0 <= k && k < this->size());
            return std::ranges::next(this->_super->begin(), this->_super->base::kth_smallest_index(this->_begin, this->_end, k));
        }

        inline value_type kth_largest(const size_type k) const noexcept(NO_EXCEPT) {
            assert(0 <= k && k < this->size());
            return this->_super->base::kth_largest(this->_begin, this->_end, k);
        }
        inline auto kth_largest_element(const size_type k) const noexcept(NO_EXCEPT) {
            if(k == this->size()) return this->end();
            assert(0 <= k && k < this->size());
            return std::ranges::next(this->_super->begin(), this->_super->base::kth_largest_index(this->_begin, this->_end, k));
        }

        inline auto min() const noexcept(NO_EXCEPT) { return this->kth_smallest(0); }
        inline auto max() const noexcept(NO_EXCEPT) { return this->kth_largest(0); }


        // (r-l)/2 th smallest (0-origin)
        inline auto median() const noexcept(NO_EXCEPT) { return this->kth_smallest(this->size() / 2); }

        inline value_type sum_in_range(const value_type& x, const value_type& y) const noexcept(NO_EXCEPT) { return this->_super->base::sum_in_range(this->_begin, this->_end, x, y); }

        inline value_type sum_under(const value_type& v) const noexcept(NO_EXCEPT) { return this->_super->base::sum_under(this->_begin, this->_end, v); }
        inline value_type sum_over(const value_type& v) const noexcept(NO_EXCEPT) { return this->_super->base::sum_over(this->_begin, this->_end, v); }
        inline value_type sum_or_under(const value_type& v) const noexcept(NO_EXCEPT) { return this->_super->base::sum_or_under(this->_begin, this->_end, v); }
        inline value_type sum_or_over(const value_type& v) const noexcept(NO_EXCEPT) { return this->_super->base::sum_or_over(this->_begin, this->_end, v); }

        inline value_type sum(const value_type& x, const value_type& y) const noexcept(NO_EXCEPT) { return this->_super->base::sum_in_range(this->_begin, this->_end, x, y); }
        inline value_type sum() const noexcept(NO_EXCEPT) { return this->_super->base::sum(this->_begin, this->_end); }

        template<comparison com>
        inline auto sum(const value_type& v) const noexcept(NO_EXCEPT) {
            if constexpr(com == comparison::under) return this->sum_under(v);
            if constexpr(com == comparison::over) return this->sum_over(v);
            if constexpr(com == comparison::or_under) return this->sum_or_under(v);
            if constexpr(com == comparison::or_over) return this->sum_or_over(v);
            assert(false);
        }


        inline auto count_in_range(const value_type& x, const value_type& y) const noexcept(NO_EXCEPT) {
            return this->_super->base::count_in_range(this->_begin, this->_end, x, y);
        }

        inline auto count_equal_to(const value_type& v) const noexcept(NO_EXCEPT) { return this->_super->base::count_equal_to(this->_begin, this->_end, v); }
        inline auto count_under(const value_type& v) const noexcept(NO_EXCEPT) { return this->_super->base::count_under(this->_begin, this->_end, v); }
        inline auto count_over(const value_type& v) const noexcept(NO_EXCEPT) { return this->_super->base::count_over(this->_begin, this->_end, v); }
        inline auto count_or_under(const value_type& v) const noexcept(NO_EXCEPT) { return this->_super->base::count_or_under(this->_begin, this->_end, v); }
        inline auto count_or_over(const value_type& v) const noexcept(NO_EXCEPT) { return this->_super->base::count_or_over(this->_begin, this->_end, v); }

        template<comparison com = comparison::equal_to>
        inline auto count(const value_type& v) const noexcept(NO_EXCEPT) {
            if constexpr(com == comparison::equal_to) return this->count_equal_to(v);
            if constexpr(com == comparison::under) return this->count_under(v);
            if constexpr(com == comparison::over) return this->count_over(v);
            if constexpr(com == comparison::or_under) return this->count_or_under(v);
            if constexpr(com == comparison::or_over) return this->count_or_over(v);
            assert(false);
        }

        inline auto next_element(const value_type& v, const size_type k = 0) const noexcept(NO_EXCEPT) {
            return this->kth_smallest_element(std::clamp(this->count_under(v) + k, size_type{ 0 }, this->size()));
        }
        inline auto prev_element(const value_type& v, const size_type k = 0) const noexcept(NO_EXCEPT) {
            return this->kth_largest_element(std::clamp(this->count_over(v) - k, size_type{ 0 }, this->size()));
        }

        inline std::optional<value_type> next(const value_type& v, const size_type k = 0) const noexcept(NO_EXCEPT) {
            return this->_super->base::next(this->_begin, this->_end, v, k);
        }
        inline std::optional<value_type> prev(const value_type& v, const size_type k = 0) const noexcept(NO_EXCEPT) {
            return this->_super->base::prev(this->_begin, this->_end, v, k);
        }
    };

    inline auto kth_smallest(const size_type k) const noexcept(NO_EXCEPT) { return this->range().kth_smallest(k); }
    inline auto kth_smallest_element(const size_type k) const noexcept(NO_EXCEPT) { return this->range().kth_smallest_element(k); }

    inline auto kth_largest(const size_type k) const noexcept(NO_EXCEPT) { return this->range().kth_largest(k); }
    inline auto kth_largest_element(const size_type k) const noexcept(NO_EXCEPT) { return this->range().kth_largest_element(k); }

    inline auto min() const noexcept(NO_EXCEPT) { return this->range().kth_smallest(0); }
    inline auto max() const noexcept(NO_EXCEPT) { return this->range().kth_largest(0); }

    // (size)/2 th smallest (0-origin)
    inline auto median() const noexcept(NO_EXCEPT) { return this->range().median(); }

    inline auto sum_in_range(const value_type& x, const value_type& y) const noexcept(NO_EXCEPT) { return this->range().sum_in_range(x, y); }

    inline auto sum_under(const value_type& v) const noexcept(NO_EXCEPT) { return this->range().sum_under(v); }
    inline auto sum_over(const value_type& v) const noexcept(NO_EXCEPT) { return this->range().sum_over(v); }
    inline auto sum_or_under(const value_type& v) const noexcept(NO_EXCEPT) { return this->range().sum_or_under(v); }
    inline auto sum_or_over(const value_type& v) const noexcept(NO_EXCEPT) { return this->range().sum_or_over(v); }

    inline auto sum(const value_type& x, const value_type& y) const noexcept(NO_EXCEPT) { return this->range().sum_in_range(x, y); }
    inline auto sum() const noexcept(NO_EXCEPT) { return this->range().sum(); }

    template<comparison com>
    inline auto sum(const value_type& v) const noexcept(NO_EXCEPT) { return this->range().template sum<com>(v); }


    inline auto count_in_range(const value_type& x, const value_type& y) const noexcept(NO_EXCEPT) { return this->range().count_in_range(x, y); }

    inline auto count_equal_to(const value_type& v) const noexcept(NO_EXCEPT) { return this->range().count_equal_to(v); }
    inline auto count_under(const value_type& v) const noexcept(NO_EXCEPT) { return this->range().count_under(v); }
    inline auto count_over(const value_type& v) const noexcept(NO_EXCEPT) { return this->range().count_over(v); }
    inline auto count_or_under(const value_type& v) const noexcept(NO_EXCEPT) { return this->range().count_or_under(v); }
    inline auto count_or_over(const value_type& v) const noexcept(NO_EXCEPT) { return this->range().count_or_over(v); }

    template<comparison com = comparison::equal_to>
    inline auto count(const value_type& v) const noexcept(NO_EXCEPT) { return this->range().template count<com>(v); }


    inline auto next_element(const value_type& v) const noexcept(NO_EXCEPT) { return this->range().next_element(v); }
    inline auto prev_element(const value_type& v) const noexcept(NO_EXCEPT) { return this->range().prev_element(v); }

    inline auto next(const value_type& v, const size_type k = 0) const noexcept(NO_EXCEPT) { return this->range().next(v, k); }
    inline auto prev(const value_type& v, const size_type k = 0) const noexcept(NO_EXCEPT) { return this->range().prev(v, k); }

    struct iterator;

  protected:
    using iterator_interface = internal::container_iterator_interface<value_type, const wavelet_matrix, const iterator>;

  public:
    struct iterator : iterator_interface {
        using iterator_interface::iterator_interface;
    };

    inline auto begin() const noexcept(NO_EXCEPT) { return iterator(this, 0); }
    inline auto end() const noexcept(NO_EXCEPT) { return iterator(this, this->size()); }

    inline auto rbegin() const noexcept(NO_EXCEPT) { return std::make_reverse_iterator(this->end()); }
    inline auto rend() const noexcept(NO_EXCEPT) { return std::make_reverse_iterator(this->begin()); }
};


template<std::integral T, template<class...> class MapTemplate>
struct compressed_wavelet_matrix : protected wavelet_matrix<u32, MapTemplate> {
    using value_type = T;
    using size_type = internal::size_t;

  protected:
    using core = wavelet_matrix<u32, MapTemplate>;
    using compresser = compressed<value_type, valarray<u32>>;

    compresser _comp;

  public:
    compressed_wavelet_matrix() = default;

    template<std::ranges::input_range R>
    explicit compressed_wavelet_matrix(R&& range) noexcept(NO_EXCEPT) : compressed_wavelet_matrix(ALL(range)) {}

    template<std::input_iterator I, std::sentinel_for<I> S>
    compressed_wavelet_matrix(I first, S last) noexcept(NO_EXCEPT) { this->build(first, last); }

    template<std::input_iterator I, std::sentinel_for<I> S>
    inline void build(I first, S last) noexcept(NO_EXCEPT) {
        this->_comp = compresser(first, last);
        this->core::build(ALL(this->_comp));
    }

    inline auto get(const size_type k) const noexcept(NO_EXCEPT) { return this->_comp.value(this->core::get(k)); }
    inline auto operator[](const size_type k) const noexcept(NO_EXCEPT) { return this->_comp.value(this->core::get(k)); }


    struct iterator;
    struct range_reference;

    template<uni::interval_notation rng = uni::interval_notation::right_open>
    inline auto range(const size_type l, const size_type r) const noexcept(NO_EXCEPT) {
        if constexpr(rng == uni::interval_notation::right_open) return range_reference(this, l, r);
        if constexpr(rng == uni::interval_notation::left_open) return range_reference(this, l + 1, r + 1);
        if constexpr(rng == uni::interval_notation::open) return range_reference(this, l + 1, r);
        if constexpr(rng == uni::interval_notation::closed) return range_reference(this, l, r + 1);
    }
    inline auto range() const noexcept(NO_EXCEPT) { return range_reference(this, 0, this->size()); }
    inline auto operator()(const size_type l, const size_type r) const noexcept(NO_EXCEPT) { return range_reference(this, l, r); }

    inline auto subseq(const size_type p, const size_type c) const noexcept(NO_EXCEPT) { return range_reference(this, p, p+c); }
    inline auto subseq(const size_type p) const noexcept(NO_EXCEPT) { return range_reference(this, p, this->size()); }


    struct range_reference : internal::range_reference<const compressed_wavelet_matrix> {
        range_reference(const compressed_wavelet_matrix *const super, const size_type l, const size_type r) noexcept(NO_EXCEPT)
          : internal::range_reference<const compressed_wavelet_matrix>(super, super->_positivize_index(l), super->_positivize_index(r))
        {
            assert(0 <= this->_begin && this->_begin <= this->_end && this->_end <= this->_super->size());
        }

      private:
        inline auto _range() const noexcept(NO_EXCEPT) { return this->_super->core::range(this->_begin, this->_end); }

      public:
        inline auto get(const size_type k) const noexcept(NO_EXCEPT) { return this->_super->_comp.value(this->_range().get(k)); }
        inline auto operator[](const size_type k) const noexcept(NO_EXCEPT) { return this->get(k); }


        inline auto kth_smallest(const size_type k) const noexcept(NO_EXCEPT) { return this->_super->_comp.value(this->_range().kth_smallest(k)); }
        inline auto kth_smallest_element(const size_type k) const noexcept(NO_EXCEPT) {
            return std::ranges::next(this->_super->begin(), std::ranges::distance(this->_super->core::begin(), this->_range().kth_smallest_element(k)));
        }

        inline auto kth_largest(const size_type k) const noexcept(NO_EXCEPT) { return this->_super->_comp.value(this->_range().kth_largest(k));}
        inline auto kth_largest_element(const size_type k) const noexcept(NO_EXCEPT) {
            return std::ranges::next(this->_super->begin(), std::ranges::distance(this->_super->core::begin(), this->_range().kth_largest_element(k)));
        }

        inline auto min() const noexcept(NO_EXCEPT) { return this->kth_smallest(0); }
        inline auto max() const noexcept(NO_EXCEPT) { return this->kth_largest(0); }


        // (r-l)/2 th smallest (0-origin)
        inline auto median() const noexcept(NO_EXCEPT) { return this->kth_smallest(this->size() / 2); }


        inline auto count_in_range(const value_type& x, const value_type& y) const noexcept(NO_EXCEPT) {
            return this->_range().count_in_range(this->_super->_comp.rank(x), this->_super->_comp.rank2(y));
        }

        inline size_type count_equal_to(const value_type& v) const noexcept(NO_EXCEPT) {
            const auto p = this->_super->_comp.rank(v);
            const auto q = this->_super->_comp.rank2(v);
            if(p != q) return 0;
            return this->_range().count_equal_to(p);
        }

        inline auto count_under(const value_type& v) const noexcept(NO_EXCEPT) { return this->_range().count_under(this->_super->_comp.rank(v)); }
        inline auto count_over(const value_type& v) const noexcept(NO_EXCEPT) { return this->_range().count_over(this->_super->_comp.rank2(v)); }
        inline auto count_or_under(const value_type& v) const noexcept(NO_EXCEPT) { return this->_range().count_or_under(this->_super->_comp.rank2(v)); }
        inline auto count_or_over(const value_type& v) const noexcept(NO_EXCEPT) { return this->_range().count_or_over(this->_super->_comp.rank(v)); }

        template<comparison com = comparison::equal_to>
        inline auto count(const value_type& v) const noexcept(NO_EXCEPT) {
            if constexpr(com == comparison::equal_to) return this->count_equal_to(v);
            if constexpr(com == comparison::under) return this->count_under(v);
            if constexpr(com == comparison::over) return this->count_over(v);
            if constexpr(com == comparison::or_under) return this->count_or_under(v);
            if constexpr(com == comparison::or_over) return this->count_or_over(v);
            assert(false);
        }


        inline auto next_element(const value_type& v, const size_type k = 0) const noexcept(NO_EXCEPT) {
            return this->kth_smallest_element(std::clamp(this->_range().count_under(this->_super->_comp.rank(v) + k), size_type{ 0 }, this->size()));
        }
        inline auto prev_element(const value_type& v, const size_type k = 0) const noexcept(NO_EXCEPT) {
            return this->kth_largest_element(std::clamp(this->_range().count_over(this->_super->_comp.rank2(v) + k), size_type{ 0 }, this->size()));
        }

        inline std::optional<value_type> next(const value_type& v, const size_type k = 0) const noexcept(NO_EXCEPT) {
            const auto res = this->_range().next(this->_super->_comp.rank(v), k);
            if(res.has_value()) return this->_super->_comp.value(res.value());
            return {};
        }
        inline std::optional<value_type> prev(const value_type& v, const size_type k = 0) const noexcept(NO_EXCEPT) {
            const auto res = this->_range().prev(this->_super->_comp.rank2(v), k);
            if(res.has_value()) return this->_super->_comp.value(res.value());
            return {};
        }
    };

    inline auto kth_smallest(const size_type k) const noexcept(NO_EXCEPT) { return this->range().kth_smallest(k); }
    inline auto kth_smallest_element(const size_type k) const noexcept(NO_EXCEPT) { return this->range().kth_smallest_element(k); }

    inline auto kth_largest(const size_type k) const noexcept(NO_EXCEPT) { return this->range().kth_largest(k); }
    inline auto kth_largest_element(const size_type k) const noexcept(NO_EXCEPT) { return this->range().kth_largest_element(k); }

    inline auto min() const noexcept(NO_EXCEPT) { return this->range().kth_smallest(0); }
    inline auto max() const noexcept(NO_EXCEPT) { return this->range().kth_largest(0); }

    inline auto median() const noexcept(NO_EXCEPT) { return this->range().median(); }

    inline auto count_in_range(const value_type& x, const value_type& y) const noexcept(NO_EXCEPT) { return this->range().count_in_range(x, y); }
    inline auto count_equal_to(const value_type& v) const noexcept(NO_EXCEPT) { return this->range().count_equal_to(v); }
    inline auto count_under(const value_type& v) const noexcept(NO_EXCEPT) { return this->range().count_under(v); }
    inline auto count_over(const value_type& v) const noexcept(NO_EXCEPT) { return this->range().count_over(v); }
    inline auto count_or_under(const value_type& v) const noexcept(NO_EXCEPT) { return this->range().count_or_under(v); }
    inline auto count_or_over(const value_type& v) const noexcept(NO_EXCEPT) { return this->range().count_or_over(v); }

    template<comparison com = comparison::equal_to>
    inline auto count(const value_type& v) const noexcept(NO_EXCEPT) { return this->range().template count<com>(v); }

    inline auto next_element(const value_type& v) const noexcept(NO_EXCEPT) { return this->range().next_element(v); }
    inline auto prev_element(const value_type& v) const noexcept(NO_EXCEPT) { return this->range().prev_element(v); }

    inline auto next(const value_type& v, const size_type k = 0) const noexcept(NO_EXCEPT) { return this->range().next(v, k); }
    inline auto prev(const value_type& v, const size_type k = 0) const noexcept(NO_EXCEPT) { return this->range().prev(v, k); }

    struct iterator;

  protected:
    using iterator_interface = internal::container_iterator_interface<value_type, const compressed_wavelet_matrix, const iterator>;

  public:
    struct iterator : iterator_interface {
        using iterator_interface::iterator_interface;
    };

    inline auto begin() const noexcept(NO_EXCEPT) { return iterator(this, 0); }
    inline auto end() const noexcept(NO_EXCEPT) { return iterator(this, this->size()); }

    inline auto rbegin() const noexcept(NO_EXCEPT) { return std::make_reverse_iterator(this->end()); }
    inline auto rend() const noexcept(NO_EXCEPT) { return std::make_reverse_iterator(this->begin()); }
};


template<std::ranges::input_range R>
explicit wavelet_matrix(R&&) -> wavelet_matrix<std::ranges::range_value_t<R>>;

template<std::input_iterator I, std::sentinel_for<I> S>
explicit wavelet_matrix(I, S) -> wavelet_matrix<std::iter_value_t<I>>;


template<std::ranges::input_range R>
explicit compressed_wavelet_matrix(R&&) -> compressed_wavelet_matrix<std::ranges::range_value_t<R>>;

template<std::input_iterator I, std::sentinel_for<I> S>
explicit compressed_wavelet_matrix(I, S) -> compressed_wavelet_matrix<std::iter_value_t<I>>;


} // namespace uni
#line 2 "include/geometries.hpp"

#line 2 "geometry/arrow.hpp"


#line 5 "geometry/arrow.hpp"

#line 7 "geometry/arrow.hpp"

#line 2 "geometry/point.hpp"


#include <complex>
#line 9 "geometry/point.hpp"


#line 12 "geometry/point.hpp"

#line 14 "geometry/point.hpp"

#line 18 "geometry/point.hpp"

#line 2 "numeric/float.hpp"


#line 6 "numeric/float.hpp"


#line 10 "numeric/float.hpp"


namespace uni {


template<class T>
inline std::int32_t compare(const T x, const T y, const T tolerance) {
    if(x > y + tolerance) return 1;
    if(y > x + tolerance) return -1;
    return 0;
}


template<class T>
inline std::int32_t compare(const T x, const T y = 0) {
    if constexpr(std::is_floating_point_v<T>) {
        return compare(x, y, max(1, x, y) * numeric_limits<T>::arithmetic_epsilon());
    }
    else {
        if(x > y) return 1;
        if(x < y) return -1;
        return 0;
    }
}


} // namespace uni
#line 2 "view/cyclic.hpp"

#line 8 "view/cyclic.hpp"

#line 12 "view/cyclic.hpp"

#line 15 "view/cyclic.hpp"


namespace uni {


template<std::ranges::input_range View>
    requires std::ranges::view<View>
struct cyclic_view : std::ranges::view_interface<cyclic_view<View>> {
  private:
    View _base;

    template<bool Const> using Base = internal::maybe_const_t<Const, View>;

    template<bool Const> struct iterator_tag {};

    template<bool Const>
        requires std::ranges::forward_range<Base<Const>>
    struct iterator_tag<Const> {
      private:
        static constexpr auto _iterator_category() noexcept {
            using category = typename std::iterator_traits<std::ranges::iterator_t<Base<Const>>>::iterator_category;
            if constexpr(std::derived_from<category, std::random_access_iterator_tag>)
                return std::random_access_iterator_tag{};
            else
                return category{};
        }

      public:
        using iterator_category = decltype(_iterator_category());
    };

  public:
    template<bool> class iterator;

    constexpr explicit cyclic_view(View base) noexcept(NO_EXCEPT) : _base(std::move(base)) {}

    inline constexpr View base() const & noexcept(NO_EXCEPT) requires std::copy_constructible<View>
    {
        return this->_base;
    }

    inline constexpr View base() && noexcept(NO_EXCEPT) { return std::move(this->_base); }

    inline constexpr auto begin() noexcept(NO_EXCEPT)
        requires(!internal::simple_view<View>)
    {
        return iterator<false>(this, std::ranges::begin(this->_base));
    }

    inline constexpr auto begin() const noexcept(NO_EXCEPT)
        requires std::ranges::range<const View>
    {
        return iterator<true>(this, std::ranges::begin(this->_base));
    }

    inline constexpr auto end() noexcept(NO_EXCEPT)
        requires(!internal::simple_view<View>)
    {
        return std::unreachable_sentinel;
    }

    inline constexpr auto end() const noexcept(NO_EXCEPT)
        requires std::ranges::range<const View>
    {
        return std::unreachable_sentinel;
    }
};

template<class Range>
cyclic_view(Range &&) -> cyclic_view<std::views::all_t<Range>>;


template<std::ranges::input_range View>
    requires std::ranges::view<View>
template<bool Const>
struct cyclic_view<View>::iterator : iterator_tag<Const> {
  private:
    using Parent = internal::maybe_const_t<Const, cyclic_view>;
    using Base = cyclic_view::Base<Const>;

    std::ranges::iterator_t<Base> _current = std::ranges::iterator_t<Base>();
    std::ranges::iterator_t<Base> _begin = std::ranges::iterator_t<Base>();
    std::ranges::sentinel_t<Base> _end = std::ranges::sentinel_t<Base>();

    constexpr iterator(Parent *const parent, const std::ranges::iterator_t<Base> current) noexcept(NO_EXCEPT)
      : _current(std::move(current)), _begin(std::ranges::begin(parent->_base)), _end(std::ranges::end(parent->_base))
    {}

    friend cyclic_view;

  public:
    using difference_type = std::ranges::range_difference_t<Base>;
    using value_type = std::ranges::range_value_t<Base>;
    using iterator_concept = typename internal::iterator_concept<Base>;

  private:
    difference_type _index = 0;

  public:
    iterator() noexcept(NO_EXCEPT) requires std::default_initializable<std::ranges::iterator_t<Base>> = default;

    constexpr iterator(iterator<!Const> itr) noexcept(NO_EXCEPT)
        requires
            Const && std::convertible_to<std::ranges::iterator_t<View>, std::ranges::iterator_t<Base>> &&
            std::convertible_to<std::ranges::sentinel_t<View>, std::ranges::sentinel_t<Base>>
      : _current(std::move(itr._current)), _begin(std::move(itr._begin)), _end(std::move(itr._end)), _index(std::move(itr._index))
    {}

    inline constexpr std::ranges::iterator_t<Base> base() && noexcept(NO_EXCEPT) { return std::move(this->_current); }

    inline constexpr const std::ranges::iterator_t<Base> &base() const & noexcept { return this->_current; }

    inline constexpr decltype(auto) operator*() const noexcept(NO_EXCEPT) { return *this->_current; }

    inline constexpr iterator& operator++() noexcept(NO_EXCEPT)
    {
        assert(this->_current != _end);
        ++this->_index;

        ++this->_current;
        if(this->_current == this->_end) this->_current = this->_begin;

        return *this;
    }

    inline constexpr void operator++(int) noexcept(NO_EXCEPT) { ++*this; }

    inline constexpr iterator operator++(int) noexcept(NO_EXCEPT)
        requires std::ranges::forward_range<Base>
    {
        const auto res = *this; ++*this; return res;
    }

    inline constexpr iterator& operator--() noexcept(NO_EXCEPT)
        requires std::ranges::bidirectional_range<Base>
    {
        --this->_index;

        if(this->_current == this->_begin) this->_current = std::ranges::prev(this->_end);
        else --this->_current;

        return *this;
    }

    inline constexpr iterator operator--(int) noexcept(NO_EXCEPT)
        requires std::ranges::bidirectional_range<Base>
    {
        const auto res = *this; --*this; return res;
    }

    inline constexpr iterator& operator+=(const difference_type diff) noexcept(NO_EXCEPT)
        requires std::ranges::random_access_range<Base>
    {
        this->_index += diff;

        if(diff > 0) {
            auto missing = std::ranges::advance(this->_current, diff, this->_end);
            if constexpr(std::ranges::sized_range<Base>) missing %= std::ranges::distance(this->_begin, this->_end);
            while(this->_current == this->_end) {
                this->_current = this->_begin;
                missing = std::ranges::advance(this->_current, missing, this->_end);
            }
        }
        else if(diff < 0) {
            auto missing = std::ranges::advance(this->_current, diff, this->_begin);
            if constexpr(std::ranges::sized_range<Base>) missing %= std::ranges::distance(this->_begin, this->_end);
            while(missing < 0) {
                this->_current = this->_end;
                missing = std::ranges::advance(this->_current, missing, this->_begin);
            }
        }

        return *this;
    }

    inline constexpr iterator& operator-=(const difference_type diff) noexcept(NO_EXCEPT)
        requires std::ranges::random_access_range<Base>
    {
        return *this += -diff;
    }

    inline constexpr decltype(auto) operator[](const difference_type diff) const noexcept(NO_EXCEPT)
        requires std::ranges::random_access_range<Base>
    {
        return *(*this + diff);
    }

    friend inline constexpr bool operator==(const iterator& lhs, const iterator& rhs) noexcept(NO_EXCEPT)
        requires std::equality_comparable<std::ranges::iterator_t<Base>>
    {
        return lhs._index == rhs._index;
    }

    friend inline constexpr auto operator<=>(const iterator& lhs, const iterator& rhs) noexcept(NO_EXCEPT)
        requires std::ranges::random_access_range<Base> && std::three_way_comparable<std::ranges::iterator_t<Base>>
    {
        return rhs._index <=> lhs._index;
    }

    friend inline constexpr iterator operator+(const iterator& itr, const difference_type diff) noexcept(NO_EXCEPT)
        requires std::ranges::random_access_range<Base>
    {
        auto res = itr; res += diff; return res;
    }

    friend inline constexpr iterator operator+(const difference_type diff, const iterator& itr) noexcept(NO_EXCEPT)
        requires std::ranges::random_access_range<Base>
    {
        return itr + diff;
    }


    friend inline constexpr iterator operator-(const iterator& itr, const difference_type diff) noexcept(NO_EXCEPT)
        requires std::ranges::random_access_range<Base>
    {
        auto res = itr; res -= diff; return res;
    }

    friend inline constexpr const difference_type operator-(const iterator& lhs, const iterator& rhs) noexcept(NO_EXCEPT)
        requires std::sized_sentinel_for<std::ranges::iterator_t<Base>, std::ranges::iterator_t<Base>>
    {
        return lhs._index - rhs._index;
    }

    friend inline constexpr std::ranges::range_rvalue_reference_t<Base> iter_move(const iterator& itr) noexcept(NO_EXCEPT)
    {
        return std::ranges::iter_move(itr._current);
    }

    friend inline constexpr void iter_swap(const iterator& lhs, const iterator& rhs) noexcept(NO_EXCEPT)
        requires std::indirectly_swappable<std::ranges::iterator_t<Base>>
    {
        std::swap(lhs._index, rhs._index);
        std::ranges::iter_swap(lhs._current, rhs._current);
    }
};


namespace views {

namespace internal {


template<class Range>
concept can_cyclic_view = requires { cyclic_view(std::declval<Range>()); };

}

struct Cyclic : adaptor::range_adaptor_closure<Cyclic> {
    template<std::ranges::viewable_range Range>
        requires internal::can_cyclic_view<Range>
    inline constexpr auto operator() [[nodiscard]] (Range &&res) const
    {
        return cyclic_view(std::forward<Range>(res));
    }

    // using adaptor::range_adaptor_closure<Cyclic>::operator();
    // static constexpr int arity = 1;
    // static constexpr bool has_simple_call_op = true;
};

inline constexpr Cyclic cyclic;


} // namespace views

} // namespace uni


namespace std::ranges {


template<class View>
inline constexpr bool enable_borrowed_range<uni::cyclic_view<View>> = enable_borrowed_range<View>;


} // namespace std::ranges
#line 22 "geometry/point.hpp"


namespace uni {


template <class T>
struct point {
    using value_type = T;

  private:
    value_type _x, _y;

  public:
    constexpr point() : point(0, 0) {}
    constexpr point(const T& x, const T& y) noexcept(NO_EXCEPT) : _x(x), _y(y) {}

    template<class U> constexpr point(const point<U>& p) noexcept(NO_EXCEPT) : _x(p.x()), _y(p.y()) {};

    template<class U>
    constexpr point& operator=(const point<U>& p) & noexcept(NO_EXCEPT) {
        if(&p != this) this->_x = p._x, this->_y = p._y;
        return *this;
    };

    inline constexpr auto& x() noexcept(NO_EXCEPT) { return this->_x; }
    inline constexpr auto& y() noexcept(NO_EXCEPT) { return this->_y; }
    inline constexpr const auto& x() const noexcept(NO_EXCEPT) { return this->_x; }
    inline constexpr const auto& y() const noexcept(NO_EXCEPT) { return this->_y; }

    constexpr auto& rotate_quarter() noexcept(NO_EXCEPT) {
        const auto x = this->_x - this->_y;
        const auto y = this->_x + this->_y;
        this->_x = std::move(x), this->_y = std::move(y);
        return *this;
    }

    constexpr auto& operator+=(const point& v) noexcept(NO_EXCEPT) { this->_x += v._x, this->_y += v._y; return *this; }
    constexpr auto& operator-=(const point& v) noexcept(NO_EXCEPT) { this->_x -= v._x, this->_y -= v._y; return *this; }

    constexpr auto& operator+=(const value_type& v) noexcept(NO_EXCEPT) { this->_x += v, this->_y += v; return *this; }
    constexpr auto& operator-=(const value_type& v) noexcept(NO_EXCEPT) { this->_x -= v, this->_y -= v; return *this; }
    constexpr auto& operator*=(const value_type& v) noexcept(NO_EXCEPT) { this->_x *= v, this->_y *= v; return *this; }
    constexpr auto& operator/=(const value_type& v) noexcept(NO_EXCEPT) { this->_x /= v, this->_y /= v; return *this; }

    friend inline constexpr auto operator+(const point& p) noexcept(NO_EXCEPT) { return { +p._x, +p._y }; }
    friend inline constexpr auto operator-(const point& p) noexcept(NO_EXCEPT) { return { -p._x, -p._y }; }

    friend inline constexpr auto operator+(point a, const point& b) noexcept(NO_EXCEPT) { return a += b; }
    friend inline constexpr auto operator-(point a, const point& b) noexcept(NO_EXCEPT) { return a -= b; }
    friend constexpr auto operator*(const point& a, const point& b) noexcept(NO_EXCEPT) { return a._x * b._x + a._y * b._y; }

    friend inline constexpr auto operator+(point a, const value_type& b) noexcept(NO_EXCEPT) { return a += b; }
    friend inline constexpr auto operator-(point a, const value_type& b) noexcept(NO_EXCEPT) { return a -= b; }
    friend inline constexpr auto operator*(point a, const value_type& b) noexcept(NO_EXCEPT) { return a *= b; }
    friend inline constexpr auto operator/(point a, const value_type& b) noexcept(NO_EXCEPT) { return a /= b; }

    friend inline constexpr auto operator+(const value_type& a, point b) noexcept(NO_EXCEPT) { return b += a; }
    friend inline constexpr auto operator-(const value_type& a, point b) noexcept(NO_EXCEPT) { return b += a; }
    friend inline constexpr auto operator*(const value_type& a, point b) noexcept(NO_EXCEPT) { return b *= a; }
    friend inline constexpr auto operator/(const value_type& a, point b) noexcept(NO_EXCEPT) { return b /= a; }

    friend inline constexpr bool operator==(const point& a, const point& b) noexcept(NO_EXCEPT) { return compare(a._x, b._x) == 0 and compare(a._y, b._y) == 0; }
    friend inline constexpr bool operator!=(const point& a, const point& b) noexcept(NO_EXCEPT) { return !(a == b); }

    friend inline constexpr bool operator<(const point& a, const point& b) noexcept(NO_EXCEPT) { return compare(a._x, b._x) != 0 ? compare(a._x, b._x) < 0 : compare(a._y, b._y) < 0; }
    friend inline constexpr bool operator>(const point& a, const point& b) noexcept(NO_EXCEPT) { return compare(a._x, b._x) != 0 ? compare(a._x, b._x) > 0 : compare(a._y, b._y) > 0; }
    friend inline constexpr bool operator<=(const point& a, const point& b) noexcept(NO_EXCEPT) { return !(a > b); }
    friend inline constexpr bool operator>=(const point& a, const point& b) noexcept(NO_EXCEPT) { return !(a < b); }

    auto _debug() const { return std::make_pair(this->_x, this->_y); }
};


template<size_t I, class T>
inline const auto& get(const point<T>& p) noexcept(NO_EXCEPT) {
    if constexpr(I == 0) { return p.x(); }
    else if constexpr(I == 1) { return p.y(); }
    else static_assert(uni::internal::EXCEPTION_ON_VALUE<I>);
}

template<size_t I, class T>
inline auto& get(point<T>& p) noexcept(NO_EXCEPT) {
    if constexpr(I == 0) return p.x();
    else if constexpr(I == 1) return p.y();
    else static_assert(internal::EXCEPTION_ON_VALUE<I>);
}


} // namespace uni


namespace std {


template<class T>
struct tuple_size<uni::point<T>> : integral_constant<size_t,2> {};

template<size_t I, class T>
struct tuple_element<I,uni::point<T>> {
    using type = typename uni::point<T>::value_type;
};


template<class T>
constexpr auto norm(const uni::point<T>& v) noexcept(NO_EXCEPT) { return v.x() * v.x() + v.y() * v.y(); }

template<class T>
constexpr auto abs(const uni::point<T>& v) noexcept(NO_EXCEPT) {
    if constexpr(is_floating_point_v<T>) {
        return static_cast<T>(std::abs(std::complex<T>(v.x(), v.y())));
    }
    else {
        return static_cast<T>(sqrt(norm(v)));
    }
}


template<class T>
constexpr auto arg(const uni::point<T>& v) noexcept(NO_EXCEPT) {
    return static_cast<T>(std::arg(std::complex<T>(v.x(), v.y())));
}


template<class T, class C, class S>
auto& operator>>(basic_istream<C, S>& in, uni::point<T>& v) noexcept(NO_EXCEPT) {
    T x, y; in >> x >> y;
    v = { x, y };
    return in;
}

template<class T, class C, class S>
auto& operator<<(basic_ostream<C, S>& out, const uni::point<T>& v) noexcept(NO_EXCEPT) {
    out << v.x() << " " << v.y();
    return out;
}


} // namespace std


namespace uni {


template<class T>
constexpr auto distance(const point<T>& a, const point<T>& b) noexcept(NO_EXCEPT) {
    return std::abs(a - b);
}

template<class T>
constexpr auto squared_distance(const point<T>& a, const point<T>& b) noexcept(NO_EXCEPT) {
    return std::norm(a - b);
}


template<class T>
constexpr auto manhattan_distance(const point<T>& a, const point<T>& b) noexcept(NO_EXCEPT) {
    return std::abs(a.x() - b.x()) + std::abs(a.y() - b.y());
}

template<class T>
constexpr auto chebyshev_distance(const point<T>& a, const point<T>& b) noexcept(NO_EXCEPT) {
    return std::max(std::abs(a.x() - b.x()), std::abs(a.y() - b.y()));
}


template<class T>
constexpr auto dot(point<T> a, point<T> b, const point<T>& o = point<T>()) noexcept(NO_EXCEPT) {
    a -= o, b -= o;
    return a * b;
}

template<class T>
constexpr auto cross(point<T> a, point<T> b, const point<T>& o = point<T>()) noexcept(NO_EXCEPT) {
    a -= o, b -= o;
    return a.x() * b.y() - a.y() * b.x();
}


template<class T, class Angle = T>
constexpr point<T> rotate(const point<T>& p, const Angle angle) noexcept(NO_EXCEPT) {
    return {
        std::cos(angle) * p.x() - std::sin(angle) * p.y(),
        std::sin(angle) * p.x() + std::cos(angle) * p.y()
    };
}

template<class T, class Angle = T>
constexpr auto rotate(const point<T>& p, const point<T>& q, const Angle angle) noexcept(NO_EXCEPT) {
    return rotate(p - q, angle) + q;
}


template<class T>
inline constexpr auto relation(const point<T>& p, const point<T>& q) noexcept(NO_EXCEPT) { return relation<T>({ 0, 0 }, p, q); }


template<class T>
auto to_degree(const T& radian) { return radian * 180 / PI<T>; }

template<class T>
auto to_radian(const T& degree) { return degree * PI<T> / 180; }


} // namespace uni
#line 2 "geometry/line.hpp"


#line 7 "geometry/line.hpp"


#line 11 "geometry/line.hpp"


namespace uni {


template<class Point>
struct line {
    using point_type = Point;
    using value_type = typename point_type::value_type;

  protected:
    point_type _p0, _p1;

  public:
    constexpr void normalize() noexcept(NO_EXCEPT) { if(this->_p0 > this->_p1) std::swap(this->_p0, this->_p1); }

    constexpr line() noexcept = default;
    constexpr line(const point_type& p0, const point_type& p1) noexcept(NO_EXCEPT) : _p0(p0), _p1(p1) { this->normalize(); }

    constexpr line(const value_type a, const value_type b, const value_type c) noexcept(NO_EXCEPT) {
        if(compare(a) == 0) this->_p0 = { 0, c / b }, this->_p1 = { 1, c / b };
        else if(compare(b) == 0) this->_p0 = { c / a, 0 }, this->_p1 = { c / a, 1 };
        else this->_p0 = { 0, c / b }, this->_p1 = { c / a, 0 };
        this->normalize();
    }


    inline constexpr auto& p0() noexcept(NO_EXCEPT) { return this->_p0; }
    inline constexpr auto& p1() noexcept(NO_EXCEPT) { return this->_p1; }

    inline constexpr const auto& p0() const noexcept(NO_EXCEPT) { return this->_p0; }
    inline constexpr const auto& p1() const noexcept(NO_EXCEPT) { return this->_p1; }

    constexpr auto vertices() noexcept(NO_EXCEPT) {
        return std::tie(this->_p0, this->_p1);
    }

    const constexpr auto vertices() const noexcept(NO_EXCEPT) {
        return std::make_pair(std::cref(this->_p0), std::cref(this->_p1));
    }

    constexpr const auto to_vector() const noexcept(NO_EXCEPT) { return this->_p1 - this->_p0; }

    constexpr const auto length() const noexcept(NO_EXCEPT) { return uni::distance(this->_p0, this->_p1); }
    constexpr const auto squared_length() const noexcept(NO_EXCEPT) { return uni::squared_distance(this->_p0, this->_p1); }

    constexpr const auto midpoint() const noexcept(NO_EXCEPT) { return tuple_sum(this->vertices()) / 2; }


    constexpr auto projection(const point_type& p) noexcept(NO_EXCEPT) {
        const auto q = this->p0() - this->p1();
        const auto s1 = (p - this->p0()) * q / std::norm(q);
        return this->p0() + q * s1;
    }

    constexpr auto reflection(const point_type& p) noexcept(NO_EXCEPT) {
        return p + (this->projection(p) - p) * 2;
    }


    // implemented in geometry/basic.hpp
    inline constexpr auto relation(const point_type& p) noexcept(NO_EXCEPT);


    auto _debug() const { return std::make_pair(this->_p0, this->_p1); }
};


template<size_t I, class Point>
inline const auto& get(const line<Point>& ln) noexcept(NO_EXCEPT) {
    if constexpr(I == 0) { return ln.p0(); }
    else if constexpr(I == 1) { return ln.p1(); }
    else static_assert(uni::internal::EXCEPTION_ON_VALUE<I>);
}

template<size_t I, class Point>
inline auto& get(line<Point>& ln) noexcept(NO_EXCEPT) {
    if constexpr(I == 0) return ln.p0();
    else if constexpr(I == 1) return ln.p1();
    else static_assert(uni::internal::EXCEPTION_ON_VALUE<I>);
}


} // namespace uni


namespace std {


template<class Point>
struct tuple_size<uni::line<Point>> : integral_constant<size_t, 2> {};


template<size_t I, class Point>
struct tuple_element<I, uni::line<Point>> {
    using type = typename uni::line<Point>::value_type;
};


template<class Point, class C, class S>
auto& operator>>(basic_istream<C, S>& in, uni::line<Point>& v) noexcept(NO_EXCEPT) {
    Point x, y; in >> x >> y;
    v = { x, y };
    return in;
}

template<class Point, class C, class S>
auto& operator<<(basic_ostream<C, S>& out, const uni::line<Point>& v) noexcept(NO_EXCEPT) {
    out << v.p0() << " " << v.p1();
    return out;
}


} // namespace std


namespace uni {


template<class Point>
bool parallel(const line<Point>& p, const line<Point>& q) noexcept(NO_EXCEPT) {
    return compare(p.to_vector() * q.to_vector()) == 0;
}


template<class Point>
bool orthogonal(const line<Point>& p, const line<Point>& q) noexcept(NO_EXCEPT) {
    return compare(cross(p.to_vector(), q.to_vector())) == 0;
}

template<class Point>
constexpr std::optional<Point> intersection(const line<Point>& s, const line<Point>& t) noexcept(NO_EXCEPT) {
    using value_type = typename Point::value_type;

    const Point p = s.to_vector(), q = t.to_vector();

    const value_type d0 = cross(p, q);
    const value_type d1 = cross(p, s.p1() - t.p0());

    if(compare(d0) == 0 and compare(d1) == 0) return {};

    return t.p0() + q * (d1 / d0);
}


namespace internal {


template<class T>
constexpr positional_relation relation(
    const line<point<T>>& ln, const point<T>& p,
    T *const _al = nullptr, T *const _bl  = nullptr
) noexcept(NO_EXCEPT) {
    const point<T> a = ln.to_vector();
    const point<T> b = p - ln.p0();

    T al = std::norm(a), bl = std::norm(b);

    if(_al) *_al = al;
    if(_bl) *_bl = bl;

    const T s1 = al * bl;
    const T dot = a * b;

    if(compare(s1, dot * dot) != 0) return positional_relation::out;
    return positional_relation::in;
}


} // namespace internal


template<class Point>
inline constexpr auto line<Point>::relation(const Point& p) noexcept(NO_EXCEPT) {
    return internal::relation(*this, p);
}
template<class Point>
auto distance(const line<Point>& ln, const Point& p) noexcept(NO_EXCEPT) {
    return std::abs(cross(ln.p1(), p, ln.p0())) / distance(ln.p1(), ln.p0());
}

template<class Point>
inline auto distance(const Point& p, const line<Point>& ln) noexcept(NO_EXCEPT) { return distance(ln, p); }


template<class Point>
auto squared_distance(const line<Point>& ln, const Point& p) noexcept(NO_EXCEPT) {
    const auto r = cross(ln.p1(), p, ln.p0());
    return r * r / squared_distance(ln.p1(), ln.p0());
}

template<class Point>
inline auto squared_distance(const Point& p, const line<Point>& ln) noexcept(NO_EXCEPT) { return squared_distance(ln, p); }


} // namespace uni
#line 2 "geometry/segment.hpp"


#line 5 "geometry/segment.hpp"

#line 7 "geometry/segment.hpp"

#line 10 "geometry/segment.hpp"


namespace uni {


template<class Point>
struct segment : line<Point> {
    using point_type = Point;
    using value_type = typename point_type::value_type;

    constexpr segment() noexcept = default;
    constexpr segment(const point_type& p0, const point_type& p1) noexcept(NO_EXCEPT) : line<Point>(p1) { this->_normalize(); }

    constexpr segment(const line<point_type>& ln) noexcept(NO_EXCEPT) : segment(ln.p0(), ln.p1()) {}

    constexpr auto relation(const point_type& p) noexcept(NO_EXCEPT);
};


template<bool ALLOW_END_POINT, class Point>
bool intersecting(const segment<Point>& s0, const segment<Point>& s1) noexcept(NO_EXCEPT) {
    const auto cp0 = cross(s0.p1(), s1.p0(), s0.p0());
    const auto cp1 = cross(s0.p1(), s1.p1(), s0.p0());
    const auto cp2 = cross(s1.p1(), s0.p0(), s1.p0());
    const auto cp3 = cross(s1.p1(), s0.p1(), s1.p0());

    if(compare(cp0) == 0 and compare(cp1) == 0 and compare(cp2) == 0 and compare(cp3) == 0) {
        return std::max(s0.p0(), s1.p0()) <= std::min(s0.p1(), s1.p1());
    }

    if constexpr(ALLOW_END_POINT) return compare(cp0 * cp1) <= 0 and compare(cp2 * cp3) <= 0;
    else return compare(cp0 * cp1) < 0 and compare(cp2 * cp3) < 0;
}

template<class Point>
bool intersecting(const segment<Point>& s0, const segment<Point>& s1) noexcept(NO_EXCEPT) {
    return intersecting<true>(s0, s1);
}


template<class Point>
inline constexpr std::optional<Point> intersection(const segment<Point>& s0, const segment<Point>& s1) noexcept(NO_EXCEPT) {
    if(!intersecting(s0, s1)) return {};
    return intersection(line<Point>(s0), line<Point>(s1));
}


template<class Point>
constexpr auto segment<Point>::relation(const Point& p) noexcept(NO_EXCEPT) {
    if(p == this->_p0 or p == this->_p1) return positional_relation::on;

    typename Point::value_type al, bl;
    if(internal::relation(p, *this, &al, &bl) == positional_relation::out) {
        return positional_relation::out;
    };

    const auto comp = compare(al, bl);

    if(comp < 0) return positional_relation::out;
    if(comp > 0) return positional_relation::in;

    assert(false);
}


template<class Point>
double distance(const segment<Point>& s0, const segment<Point> &s1) {
    if(intersecting(s0, s1)) return 0;
    return
        min(
            distance(s0, s1.p0()), distance(s0, s1.p1()),
            distance(s1, s0.p0()), distance(s1, s0.p1())
        );
}

template<class Point>
double squared_distance(const segment<Point>& s0, const segment<Point> &s1) {
    if(intersecting(s0, s1)) return 0;
    return
        min(
            squared_distance(s0, s1.p0()), squared_distance(s0, s1.p1()),
            squared_distance(s1, s0.p0()), squared_distance(s1, s0.p1())
        );
}


template<class Point>
auto distance(const segment<Point>& seg, const Point& p) noexcept(NO_EXCEPT) {
    if(compare(dot(seg.p1(), p, seg.p0())) < 0) return distance(p, seg.p0());
    if(compare(dot(seg.p0(), p, seg.p1())) < 0) return distance(p, seg.p1());
    return distance(line<Point>(seg), p);
}

template<class Point>
inline auto distance(const Point& p, const segment<Point>& seg) noexcept(NO_EXCEPT) { return distance(seg, p); }


template<class Point>
auto squared_distance(const segment<Point>& seg, const Point& p) noexcept(NO_EXCEPT) {
    if(compare(dot(seg.p1(), p, seg.p0())) < 0) return squared_distance(p, seg.p0());
    if(compare(dot(seg.p0(), p, seg.p1())) < 0) return squared_distance(p, seg.p1());
    return squared_distance(line<Point>(seg), p);
}

template<class Point>
inline auto squared_distance(const Point& p, const segment<Point>& seg) noexcept(NO_EXCEPT) { return squared_distance(seg, p); }


} // namespace uni
#line 11 "geometry/arrow.hpp"


namespace uni {


template<class Point>
struct arrow : segment<Point> {
    using point_type = Point;
    using value_type = typename point_type::value_type;

    constexpr arrow() noexcept = default;

    // p0 -> p1
    constexpr arrow(const point_type& p0, const point_type& p1) noexcept(NO_EXCEPT) { this->_p0 = p0, this->_p1 = p1; }

    constexpr auto relation(const point_type& p) noexcept(NO_EXCEPT);
};


template<class Point>
constexpr auto arrow<Point>::relation(const Point& p) noexcept(NO_EXCEPT) {
    if(this->_p0 == p || this->_p1 == p) return positional_relation::on;

    const auto q0 = this->_p1 - this->_p0, q1 = p - this->_p0;

    const auto comp_qr = compare(cross(q0, q1));
    if(comp_qr > 0) return positional_relation::counter_clockwise;
    if(comp_qr < 0) return positional_relation::clockwise;
    if(compare(q0 * q1) < 0) return positional_relation::backward;
    if(compare(std::norm(q0), std::norm(q1)) < 0) return positional_relation::forward;
    return positional_relation::in;
}


} // namespace uni


namespace std {


template<class Point, class C, class S>
auto& operator>>(basic_istream<C, S>& in, uni::arrow<Point>& v) noexcept(NO_EXCEPT) {
    Point x, y; in >> x >> y;
    v = { x, y };
    return in;
}


} // namespace std
#line 2 "geometry/circle.hpp"


#line 5 "geometry/circle.hpp"


#line 9 "geometry/circle.hpp"

#line 12 "geometry/circle.hpp"


namespace uni {


template<class Point>
struct circle {
    using point_type = Point;
    using value_type = typename point_type::value_type;

  protected:
    point_type _c;
    value_type _r2;

  public:
    circle() noexcept = default;

    static constexpr auto raw(const point_type& c, const value_type& r2) noexcept(NO_EXCEPT) {
        circle res; res._c = c, res._r2 = r2;
        return res;
    }


    constexpr circle(const point_type& c, const value_type& r) noexcept(NO_EXCEPT) : _c(c), _r2(r * r) {}
    explicit constexpr circle(const value_type& r) noexcept(NO_EXCEPT) : _c({ 0, 0 }), _r2(r * r) {}


    constexpr circle(const point_type& p0, const point_type& p1, const point_type& p2) noexcept(NO_EXCEPT)
      : circle(triangle(p0, p1, p2))
    {};


    explicit constexpr circle(const segment<point_type>& seg) noexcept(NO_EXCEPT)
      : _c(seg.midpoint()), _r2(seg.squared_length() / 4)
    {};


    inline constexpr auto& center() noexcept(NO_EXCEPT) { return this->_c; }
    inline constexpr const auto& center() const noexcept(NO_EXCEPT) { return this->_c; }

    inline auto radius() const noexcept(NO_EXCEPT) { return static_cast<value_type>(std::sqrt(this->_r2)); }

    inline constexpr auto& squared_radius() noexcept(NO_EXCEPT) { return this->_r2; }
    inline constexpr const auto& squared_radius() const noexcept(NO_EXCEPT) { return this->_r2; }


    constexpr auto relation(const point_type& p) noexcept(NO_EXCEPT) {
        const auto dist = uni::squared_distance(this->_c, p);
        const auto comp = compare(dist, this->_r2);
        if(comp > 0) return positional_relation::out;
        if(comp < 0) return positional_relation::in;
        return positional_relation::on;
    }


    auto _debug() const noexcept(NO_EXCEPT) { return std::make_pair(this->center(), this->radius()); }
};


template<class Point>
int count_common_tangent(const circle<Point>& c0, const circle<Point>& c1) {
    const auto dist = distance(c0.center(), c1.center());
    const auto l0 = c0.radius() + c1.radius();
    const auto l1 = std::abs(c0.radius() - c1.radius());
    if(compare(dist, l0) > 0) return 4;
    if(compare(dist, l0) == 0) return 3;
    if(compare(dist, l1) == 0) return 1;
    if(compare(dist, l1) < 0) return 0;
    return 2;
}

template<class Point>
auto relation(const circle<Point>& c0, const circle<Point>& c1) {
    const auto t = count_common_tangent(c0, c1);

    switch(t) {
        case 0: return uni::positional_relation::included;
        case 1: return uni::positional_relation::inscribed;
        case 2: return uni::positional_relation::intersecting;
        case 3: return uni::positional_relation::circumscribed;
        case 4: return uni::positional_relation::distant;
    }

    assert(false);
}


} // namespace uni
#line 2 "geometry/convex_hull.hpp"


#line 7 "geometry/convex_hull.hpp"


#line 10 "geometry/convex_hull.hpp"

#line 2 "geometry/polygon.hpp"


#line 6 "geometry/polygon.hpp"


#line 9 "geometry/polygon.hpp"

#line 13 "geometry/polygon.hpp"

#line 16 "geometry/polygon.hpp"


namespace uni {


template<class Point, class Container = vector<Point>>
struct polygon : Container {
    using point_type = Point;
    using container_type = Container;

    using value_type = point_type::value_type;
    using size_type = Container::size_type;

    static_assert(std::same_as<typename container_type::value_type, point_type>);


    using container_type::container_type;


    auto doubled_area() noexcept(NO_EXCEPT) {
        const auto n = std::ranges::ssize(*this);
        const auto view = uni::views::cyclic(*this);

        value_type res = 0;
        REP(i, n) res += cross(view[i], view[i + 1]);

        return res;
    }

    inline auto area() noexcept(NO_EXCEPT) {
        return this->doubled_area() / 2;
    }


    template<bool = true>
    bool is_convex() noexcept(NO_EXCEPT);


    // implemented in geometry/convex_hull.hpp
    template<bool ALLOW_LINE = true, bool LEAVE_MARGIN = false>
    auto convex_hull() noexcept(NO_EXCEPT);

};


template<class Point, class Container>
struct convex_polygon : polygon<Point, Container> {
    using polygon<Point, Container>::polygon;
};


namespace internal {


template<bool ALLOW_LINE, std::ranges::sized_range R>
    requires std::ranges::forward_range<R>
bool is_convex(R&& range) noexcept(NO_EXCEPT) {
    const auto n = std::ranges::size(range);
    const auto view = uni::views::cyclic(range);

    auto itr0 = std::ranges::begin(view);
    auto itr1 = std::ranges::next(itr0);
    auto itr2 = std::ranges::next(itr1);

    REP(n) {
        const auto r = arrow(*(itr0++), *(itr1++)).relation(*(itr2++));

        if constexpr(ALLOW_LINE) {
            if(r == positional_relation::clockwise) return false;
        }
        else {
            if(r != positional_relation::anti_clockwise) return false;
        }
    }

    return true;
}


} // namespace internal


template<class Point, class Container>
template<bool ALLOW_LINE>
inline bool polygon<Point, Container>::is_convex() noexcept(NO_EXCEPT) {
    return
        (
            internal::is_convex<ALLOW_LINE>(*this) ||
            internal::is_convex<ALLOW_LINE>(std::views::reverse(*this))
        );
}


} // namespace uni
#line 13 "geometry/convex_hull.hpp"



namespace uni {


template<class Point, class Container>
template<bool ALLOW_LINE, bool LEAVE_MARGIN>
auto polygon<Point, Container>::convex_hull() noexcept(NO_EXCEPT) {
    auto remove = [&](const point_type& p, const point_type& q, const point_type& r) -> bool {
        if constexpr(ALLOW_LINE) {
            return compare(cross(p, q, r)) < 0;
        }
        else {
            return compare(cross(p, q, r)) <= 0;
        }
    };

    std::vector<point_type> points(ALL(*this));

    const auto n = std::ranges::ssize(points);
    using ssize_type = std::remove_const_t<decltype(n)>;

    std::ranges::sort(points);

    polygon res(2 * n);
    ssize_type k = 0;

    for(ssize_type i = 0; i < n; res[k++] = points[i++]) {
        while(k >= 2 && remove(points[i], res[k - 2], res[k - 1])) --k;
    }
    for(auto i = n - 2, t = k + 1; i >= 0; res[k++] = points[i--]) {
        while(k >= t && remove(points[i], res[k - 2], res[k - 1])) --k;
    }

    if constexpr(LEAVE_MARGIN) res.resize(k);
    else res.resize(k - 1);

    return res;
}


} // namespace uni
#line 2 "geometry/triangle.hpp"


#line 7 "geometry/triangle.hpp"


#line 11 "geometry/triangle.hpp"

#line 14 "geometry/triangle.hpp"


namespace uni {


template<class Point>
struct triangle {
    using point_type = Point;
    using value_type = typename point_type::value_type;

  private:
    point_type _p0, _p1, _p2;

  protected:
    constexpr void _normalize() noexcept(NO_EXCEPT) {
        std::array<point_type,3> vs = { this->_p0, this->_p1, this->_p2 };
        std::ranges::sort(vs);
        std::tie(this->_p0, this->_p1, this->_p2) = std::tie(vs[0], vs[1], vs[2]);
    }

  public:
    constexpr triangle() noexcept(NO_EXCEPT) {}

    constexpr triangle(const point_type& p0, const point_type& p1, const point_type& p2 = point_type()) noexcept(NO_EXCEPT) : _p0(p0), _p1(p1), _p2(p2)
    {
        this->_normalize();
    }

    inline constexpr auto& p0() noexcept(NO_EXCEPT) { return this->_p0; }
    inline constexpr auto& p1() noexcept(NO_EXCEPT) { return this->_p1; }
    inline constexpr auto& p2() noexcept(NO_EXCEPT) { return this->_p2; }

    inline constexpr const auto& p0() const noexcept(NO_EXCEPT) { return this->_p0; }
    inline constexpr const auto& p1() const noexcept(NO_EXCEPT) { return this->_p1; }
    inline constexpr const auto& p2() const noexcept(NO_EXCEPT) { return this->_p2; }


    inline constexpr auto vertices() noexcept(NO_EXCEPT) { return std::tie(this->_p0, this->_p1, this->_p2); }
    inline constexpr auto vertices() const noexcept(NO_EXCEPT) { return std::make_tuple(std::cref(this->_p0), std::cref(this->_p1), std::cref(this->_p2)); }


    constexpr const auto signed_area() const noexcept(NO_EXCEPT) { return cross(this->_p0, this->_p1, this->_p2) / 2; }
    inline constexpr const auto area() const noexcept(NO_EXCEPT) { return std::abs(this->signed_area()); }


    constexpr auto distances() const noexcept(NO_EXCEPT) {
        return std::make_tuple(
            uni::distance(this->_p1, this->_p2),
            uni::distance(this->_p2, this->_p0),
            uni::distance(this->_p0, this->_p1)
        );
    }

    constexpr auto squared_distances() const noexcept(NO_EXCEPT) {
        return std::make_tuple(
            uni::squared_distance(this->_p1, this->_p2),
            uni::squared_distance(this->_p2, this->_p0),
            uni::squared_distance(this->_p0, this->_p1)
        );
    }

    constexpr auto angles() const noexcept(NO_EXCEPT) {
        const auto [ d0, d1, d2 ] = this->distances();
        return std::make_tuple(
            std::acos((d1 * d1 + d2 * d2 - d0 * d0) / (2 * d1 * d2)),
            std::acos((d2 * d2 + d0 * d0 - d1 * d1) / (2 * d2 * d0)),
            std::acos((d0 * d0 + d1 * d1 - d2 * d2) / (2 * d0 * d1))
        );
    }


    constexpr  point_type barycenter() const noexcept(NO_EXCEPT) { return tuple_sum(this->vertices()) / 3; }

    constexpr auto circumcenter() const noexcept(NO_EXCEPT) {
        const auto [ d0, d1, d2 ] = this->squared_distances();
        const auto t0 = d0 * (d1 + d2 - d0);
        const auto t1 = d1 * (d2 + d0 - d1);
        const auto t2 = d2 * (d0 + d1 - d2);
        return (t0 * this->_p0 + t1 * this->_p1 + t2 * this->_p2) / (t0 + t1 + t2);
    }

    constexpr auto incenter() const noexcept(NO_EXCEPT) {
        const auto [ d0, d1, d2 ] = this->distances();
        return (d0 * this->_p0 + d1 * this->_p1 + d2 * this->_p2) / (d0 + d1 + d2);
    }

    constexpr auto orthocenter() const noexcept(NO_EXCEPT) {
        return tuple_sum(this->vertices()) - 2 * this->circumcenter();
    }

    constexpr triangle excenters() const noexcept(NO_EXCEPT) {
        const auto [ d0, d1, d2 ] = this->distances();
        return {
            (d1 * this->_p1 + d2 * this->_p2 - d0 * this->_p0) / (d1 + d2 - d0),
            (d2 * this->_p1 + d0 * this->_p2 - d1 * this->_p0) / (d2 + d0 - d1),
            (d0 * this->_p1 + d1 * this->_p2 - d2 * this->_p0) / (d0 + d1 - d2)
        };
    }


    // implemented in geometry/basic.hpp
    constexpr auto circumcircle() const noexcept(NO_EXCEPT);
    constexpr auto incircle() const noexcept(NO_EXCEPT);


    auto _debug() const noexcept(NO_EXCEPT) {
        return std::make_tuple(this->_p0, this->_p1, this->_p2);
    }
};


template<size_t I, class T>
inline const auto& get(const triangle<T>& t) noexcept(NO_EXCEPT) {
    if constexpr(I == 0) { return t.p0(); }
    else if constexpr(I == 1) { return t.p1(); }
    else if constexpr(I == 2) { return t.p2(); }
    else static_assert(internal::EXCEPTION_ON_VALUE<I>);
}

template<size_t I, class T>
inline auto& get(triangle<T>& t) noexcept(NO_EXCEPT) {
    if constexpr(I == 0) return t.p0();
    else if constexpr(I == 1) return t.p1();
    else if constexpr(I == 2) return t.p2();
    else static_assert(internal::EXCEPTION_ON_VALUE<I>);
}


} // namespace uni


namespace std {


template<class T>
struct tuple_size<uni::triangle<T>> : integral_constant<size_t,3> {};

template<size_t I, class T>
struct tuple_element<I,uni::triangle<T>> {
    using type = typename uni::triangle<T>::value_type;
};


template<class T, class C, class S>
auto& operator>>(basic_istream<C, S>& in, uni::triangle<T>& v) noexcept(NO_EXCEPT) {
    typename uni::triangle<T>::point_type p, q, r; in >> p >> q >> r;
    v = { p, q, r };
    return in;
}


} // namespace std


namespace uni {


template<class> struct circle;

template<class Point>
constexpr auto triangle<Point>::incircle() const noexcept(NO_EXCEPT) {
    const auto p = this->incenter();
    return circle<Point>::raw(p, squared_distance(p, line(this->_p0, this->_p1)));
}


template<class Point>
constexpr auto triangle<Point>::circumcircle() const noexcept(NO_EXCEPT) {
    const auto p = this->circumcenter();
    return circle<Point>::raw(p, squared_distance(p, this->_p0));
}


} // namespace uni
#line 2 "include/graph_theory.hpp"

#line 2 "graph/centroid_decomposition.hpp"

#line 6 "graph/centroid_decomposition.hpp"

#line 2 "structure/graph.hpp"


#line 8 "structure/graph.hpp"


#line 12 "structure/graph.hpp"

#line 16 "structure/graph.hpp"

#line 21 "structure/graph.hpp"

#line 2 "structure/grid.hpp"


#line 12 "structure/grid.hpp"


#line 16 "structure/grid.hpp"

#line 19 "structure/grid.hpp"

#line 21 "structure/grid.hpp"

#line 24 "structure/grid.hpp"


namespace uni {

namespace internal {

namespace grid_impl {


template<class T>
struct container_base {
    using value_type = T;
    using size_type = internal::size_t;

  private:
    size_type _h, _w;

  protected:
    inline void _validate_index(__attribute__ ((unused)) const size_type i, __attribute__ ((unused)) const size_type j) const noexcept(NO_EXCEPT) {
        assert(0 <= i and i < this->height());
        assert(0 <= j and j < this->width());
    }

    inline size_type _positivize_row_index(const size_type x) const noexcept(NO_EXCEPT) {
        return x < 0 ? this->height() + x : x;
    }
    inline size_type _positivize_col_index(const size_type x) const noexcept(NO_EXCEPT) {
        return x < 0 ? this->width() + x : x;
    }

  public:
    container_base() = default;
    container_base(const size_type h, const size_type w) noexcept(NO_EXCEPT) : _h(h), _w(w) {}

    void resize(const size_type h, const size_type w) noexcept(NO_EXCEPT) {
        this->_h = h, this->_w = w;
    }

    inline size_type height() const noexcept(NO_EXCEPT) { return this->_h; }
    inline size_type width() const noexcept(NO_EXCEPT) { return this->_w; }

    inline size_type id(const size_type i, const size_type j) const noexcept(NO_EXCEPT) {
        const size_type _i = this->_positivize_row_index(i);
        const size_type _j = this->_positivize_col_index(j);
        this->_validate_index(_i, _j);
        return _i * this->width() + _j;
    }

    inline size_type id(const std::pair<size_type,size_type>& p) const noexcept(NO_EXCEPT) {
        return this->id(p.first, p.second);
    }

    inline std::pair<size_type,size_type> pos(const size_type id) const noexcept(NO_EXCEPT) {
        return { id / this->width(), id % this->width() };
    }
};

template<class Base>
struct regular_container : Base, container_base<typename Base::value_type::value_type> {
    using row_type = typename Base::value_type;
    using value_type = typename row_type::value_type;

    using size_type = internal::size_t;

    explicit regular_container(const size_type n = 0) noexcept(NO_EXCEPT) : regular_container(n, n) {}

    regular_container(const size_type h, const size_type w, const value_type &val = value_type()) noexcept(NO_EXCEPT)
      : Base(h, row_type(w, val)), container_base<value_type>(h, w)
    {}

    regular_container(const std::initializer_list<row_type> init_list) noexcept(NO_EXCEPT) : Base(init_list) {
        const auto rows = std::ranges::ssize(init_list);
        const size_type first_cols = init_list.begin()->size();

        if constexpr (DEV_ENV) { ITR(init_row, init_list) assert((size_type)init_row.size() == first_cols); }

        this->container_base<value_type>::resize(rows, first_cols);
    }

    inline void assign(const regular_container &source) noexcept(NO_EXCEPT) {
        this->resize(source.height(), source.width());
        this->Base::assign(ALL(source));
    }

    inline void assign(const size_type h, const size_type w, const value_type &val = value_type()) noexcept(NO_EXCEPT) {
        this->container_base<value_type>::resize(h, w);
        this->Base::resize(h);
        ITRR(row, *this) row.assign(w, val);
    }

    inline void resize(const size_type h, const size_type w) noexcept(NO_EXCEPT) {
        this->container_base<value_type>::resize(h, w);
        this->Base::resize(h);
        ITRR(row, *this) row.resize(w);
    }

    inline auto& operator()(const size_type i, const size_type j) noexcept(NO_EXCEPT) {
        const size_type _i = this->_positivize_row_index(i);
        const size_type _j = this->_positivize_col_index(j);
        this->_validate_index(_i, _j);
        return (*this)[_i][_j];
    }

    inline const auto& operator()(const size_type i, const size_type j) const noexcept(NO_EXCEPT) {
        const size_type _i = this->_positivize_row_index(i);
        const size_type _j = this->_positivize_col_index(j);
        this->_validate_index(_i, _j);
        return (*this)[_i][_j];
    }

    inline auto& operator()(const std::pair<size_type,size_type>& p) noexcept(NO_EXCEPT) {
        return this->operator()(p.first, p.second);
    }

    inline const auto& operator()(const std::pair<size_type,size_type>& p) const noexcept(NO_EXCEPT) {
        return this->operator()(p.first, p.second);
    }
};

template<class Base>
struct unfolded_container : Base, container_base<typename Base::value_type> {
    using value_type = typename Base::value_type;
    using size_type = internal::size_t;

    explicit unfolded_container(size_type n = 0) noexcept(NO_EXCEPT) : unfolded_container(n, n) {}

    unfolded_container(const size_type h, const size_type w, const value_type &val = value_type()) noexcept(NO_EXCEPT)
      : Base(h * w, val), container_base<value_type>(h, w)
    {}

    unfolded_container(std::initializer_list<std::initializer_list<value_type>> init_list) noexcept(NO_EXCEPT) {
        const auto rows = std::ranges::ssize(init_list);
        const auto first_cols = std::ranges::ssize(std::ranges::begin(init_list));

        this->resize(rows, first_cols);

        {
            size_type index = 0;
            for(
                    auto itr = std::ranges::begin(init_list), itr_end = std::ranges::end(init_list);
                    itr!=itr_end;
                    ++itr
            )
            {
                assert((size_type)itr->size() == first_cols);
                for(auto v=itr->begin(), v_end=itr->end(); v!=v_end; ++v) (*this)[index++] = *v;
            }
        }
    }

    inline void assign(const unfolded_container &source) noexcept(NO_EXCEPT) {
        this->resize(source.height(), source.width());
        this->Base::assign(ALL(source));
    }

    inline void assign(const size_type h, const size_type w, const value_type &val = value_type()) noexcept(NO_EXCEPT) {
        this->container_base<value_type>::resize(h, w);
        this->Base::assign(h * w, val);
    }

    inline void resize(const size_type h, const size_type w) noexcept(NO_EXCEPT) {
        this->container_base<value_type>::resize(h, w);
        this->Base::resize(h * w);
    }

    inline value_type& operator()(const size_type i, const size_type j) noexcept(NO_EXCEPT) {
        const size_type _i = this->_positivize_row_index(i);
        const size_type _j = this->_positivize_col_index(j);
        return this->operator[](this->id(_i, _j));
    }

    inline value_type& operator()(const std::pair<size_type,size_type>& p) noexcept(NO_EXCEPT) {
        return this->operator()(this->id(p.first, p.second));
    }

    inline const value_type& operator()(const std::pair<size_type,size_type>& p) const noexcept(NO_EXCEPT) {
        return this->operator()(this->id(p.first, p.second));
    }
};


}  // namespace grid_impl


template<class Container>
struct grid_core : Container {
    using Container::Container;

    using value_type = Container::value_type;
    using size_type = internal::size_t;

    enum class invert_direction { vertical, horizontal };
    enum class rotate_direction { counter_clockwise, clockwise };


    inline bool is_valid(const size_type i, const size_type j) const noexcept(NO_EXCEPT) {
        return 0 <= i and i < this->height() and 0 <= j and j < this->width();
    }

    inline bool is_valid(const std::pair<size_type, size_type>& p) const noexcept(NO_EXCEPT) {
        return this->is_valid(p.first, p.second);
    }


    template<std::input_iterator I, std::sentinel_for<I> S>
    inline auto vicinities(const size_type i, const size_type j, I dirs_first, S dirs_last) const noexcept(NO_EXCEPT) {
        std::vector<std::pair<size_type, size_type>> res;
        REP(itr, dirs_first, dirs_last) {
            const size_type ii = i + itr->first, jj = j + itr->second;
            if(this->is_valid(ii, jj)) res.emplace_back(ii, jj);
        }
        return res;
    }

    template<class I, class C>
    inline auto vicinities(const std::pair<size_type, size_type>& p, const C dirs) const noexcept(NO_EXCEPT) {
        return this->vicinities(p.first, p.second, ALL(dirs));
    }

    inline auto vicinities4(const size_type i, const size_type j) const noexcept(NO_EXCEPT) { return this->vicinities(i, j, ALL(DIRS4)); }
    inline auto vicinities4(const std::pair<size_type, size_type>& p) const noexcept(NO_EXCEPT) { return this->vicinities(p.first, p.second, ALL(DIRS4)); }

    inline auto vicinities8(const size_type i, const size_type j) const noexcept(NO_EXCEPT) { return this->vicinities(i, j, ALL(DIRS8)); }
    inline auto vicinities8(const std::pair<size_type, size_type>& p) const noexcept(NO_EXCEPT) { return this->vicinities(p.first, p.second, ALL(DIRS8)); }


    template<invert_direction DIRECTION = invert_direction::vertical>
    inline grid_core& invert() noexcept(NO_EXCEPT) {
        grid_core res(this->height(), this->width());
        REP(i, this->height()) REP(j, this->width()) {
            if constexpr (DIRECTION == invert_direction::vertical) {
                res(i,j) = (*this)(this->height()-i-1,j);
            }
            else {
                res(i,j) = (*this)(i, this->width()-j-1);
            }
        }
        this->assign(res);
        return *this;
    }

    template<rotate_direction DIRECTION = rotate_direction::clockwise>
    inline grid_core& rotate(const size_type k) noexcept(NO_EXCEPT) {
        grid_core res = *this;
        REP(i, k) { res = res.rotate<DIRECTION>(); }
        this->assign(res);
        return *this;
    }

    template<rotate_direction DIRECTION = rotate_direction::clockwise>
    inline grid_core& rotate() noexcept(NO_EXCEPT) {
        grid_core res(this->width(), this->height());
        REP(i, this->width()) REP(j, this->height()) {
            if constexpr (DIRECTION == rotate_direction::clockwise) {
                res(i,j) = (*this)(this->height()-j-1,i);
            }
            else {
                res(i,j) = (*this)(j,this->width()-i-1);
            }
        }
        this->assign(res);
        return *this;
    }

    inline grid_core& transpose() noexcept(NO_EXCEPT) {
        grid_core res(this->width(), this->height());
        REP(i, this->width()) REP(j, this->height()) {
            res(i,j) = (*this)(j,i);
        }
        this->assign(res);
        return *this;
    }
};


} // namespace internal


template<class T, class row_type = vector<T>, class Base = vector<row_type>>
using grid = internal::grid_core<internal::grid_impl::regular_container<Base>>;

template<class T, class row_type = valarray<T>, class Base = vector<row_type>>
using valgrid = internal::grid_core<internal::grid_impl::regular_container<Base>>;

template<class T, class Base = vector<T>>
using unfolded_grid = internal::grid_core<internal::grid_impl::unfolded_container<Base>>;

template<class T, class Base = valarray<T>>
using unfolded_valgrid = internal::grid_core<internal::grid_impl::unfolded_container<Base>>;


} // namespace uni
#line 24 "structure/graph.hpp"

#line 26 "structure/graph.hpp"

#line 2 "internal/auto_holder.hpp"


#line 5 "internal/auto_holder.hpp"


#line 9 "internal/auto_holder.hpp"

#line 11 "internal/auto_holder.hpp"


namespace uni {

namespace internal {

namespace auto_holder_impl {


template<class T, bool DYNAMIC, class = std::enable_if_t<std::is_integral_v<T> && not DYNAMIC>>
constexpr int _holder_type(resolving_rank<2>) { return 0; }

template<class T, bool>
constexpr auto _holder_type(resolving_rank<1>) -> decltype(std::unordered_set<T>(), 0){ return 1; }

template<class T, bool>
constexpr int _holder_type(resolving_rank<0>) { return 2; }


template<class T, bool DYNAMIC = false>
constexpr int holder_type = _holder_type<T,DYNAMIC>(resolving_rank<10>{});


template<class,class,int> struct holder {};

template<class T, class U>
struct holder<T, U, 0> : vector<U> {
    using vector<U>::vector;
};

template<class T, class U>
struct holder<T, U, 1> : gp_hash_table<T, U> {
    using gp_hash_table<T, U>::gp_hash_table;

    template<class V> inline void assign(const internal::size_t, const V& v) { this->set_default(v); }
};

template<class T, class U>
struct holder<T, U, 2> : map<T, U> {
    using map<T, U>::map;

    template<class V> inline void assign(const internal::size_t, const V& v) { this->set_default(v); }
};


} // namespace auto_holder_impl

} // namespace internal


template<class T, class U> struct auto_holder : internal::auto_holder_impl::holder<T,U,internal::auto_holder_impl::holder_type<T>> {
    using internal::auto_holder_impl::holder<T,U,internal::auto_holder_impl::holder_type<T>>::holder;
};

template<class T, class U> struct dynamic_auto_holder : internal::auto_holder_impl::holder<T,U,internal::auto_holder_impl::holder_type<T,true>> {
    using internal::auto_holder_impl::holder<T,U,internal::auto_holder_impl::holder_type<T,true>>::holder;
};


} // namespace uni
#line 28 "structure/graph.hpp"


namespace uni {

namespace internal {

namespace graph_impl {


template<class Node,class Cost> struct edge {
  private:
    inline static internal::size_t unique() noexcept(NO_EXCEPT) { static internal::size_t id = 0; return id++; }

  public:
    using cost_type = Cost;
    using node_type = Node;
    using size_type = internal::size_t;

    const size_type id = unique();
    const node_type from, to; const Cost cost;
    const size_type index = 0;

    edge(const node_type u, const node_type v, const Cost w = 1, const size_type i = 0) noexcept(NO_EXCEPT)
      : from(u), to(v), cost(w), index(i)
    {}

    operator node_type() const noexcept(NO_EXCEPT) { return this->to; }

    inline node_type opposite(const node_type v) const noexcept(NO_EXCEPT) {
        if(this->from == v) return this->to;
        if(this->to == v) return this->from;
        assert(false);
    }

    auto _debug() const { return std::make_tuple(index, from, to, cost); };

    friend bool operator==(const edge& lhs, const edge& rhs) noexcept(NO_EXCEPT) { return lhs.id == rhs.id; }
    friend bool operator!=(const edge& lhs, const edge& rhs) noexcept(NO_EXCEPT) { return lhs.id != rhs.id; }
};


template<class NodeType, class CostType, class EdgeCollector>
struct regular_base : EdgeCollector {
    using EdgeCollector::EdgeCollector;
    using size_type = internal::size_t;
    using node_type = NodeType;
    using cost_type = CostType;

    inline size_type size() const noexcept(NO_EXCEPT) { return static_cast<size_type>(this->EdgeCollector::size()); }
};

template<class NodeType, class CostType, class Map>
struct virtual_base : Map {
  public:
    using size_type = internal::size_t;
    using node_type = NodeType;
    using cost_type = CostType;

  protected:
    size_type _n = 0;

  public:
    template<class F>
    explicit virtual_base(const size_type n, F&& f) noexcept(NO_EXCEPT)
      : Map(std::forward<F>(f)), _n(n)
    {}

    inline size_type size() const noexcept(NO_EXCEPT) { return this->_n; }
};


template<class NodeType, class CostType, template<class...> class Container>
struct regular_core : regular_base<NodeType,CostType,Container<vector<internal::graph_impl::edge<NodeType,CostType>>>> {
    using size_type = internal::size_t;
    using node_type = NodeType;
    using cost_type = CostType;

    using edge_type = typename internal::graph_impl::edge<node_type,cost_type>;

    enum class edge_kind { undirected, directed };

  private:
    using base = regular_base<NodeType,CostType,Container<vector<edge_type>>>;

    size_type _directed_edge_count = 0, _undirected_edge_count = 0;

    Container<edge_type> _edges;
    Container<size_type> _out_degs, _in_degs;

  protected:
    inline void _add_edge(const size_type u, const size_type v, const cost_type w, const size_type k) noexcept(NO_EXCEPT) {
        this->operator[](u).emplace_back(u, v, w, k);
        ++_out_degs[u], ++_in_degs[v];
        ++this->_directed_edge_count;
    }

  public:
    explicit regular_core() noexcept(NO_EXCEPT) : base() {}
    explicit regular_core(const size_type n = 0) noexcept(NO_EXCEPT)
      : base(n), _out_degs(n), _in_degs(n)
    {}

    auto& clear() noexcept(NO_EXCEPT) {
        this->_directed_edge_count = 0, this->_undirected_edge_count = 0;
        this->base::clear(), this->_edges.clear();
        this->_out_degs.clear(), this->_in_degs.clear();
        return *this;
    }

    auto& resize(const size_type n) noexcept(NO_EXCEPT) {
        this->base::resize(n), this->_out_degs.resize(n), this->_in_degs.resize(n);
        return *this;
    }

    inline const auto& edges() const noexcept(NO_EXCEPT) { return this->_edges; }
    inline const auto& edge(const size_type k) const noexcept(NO_EXCEPT) { return this->_edges[k]; }

    inline const auto& degrees() const noexcept(NO_EXCEPT) { return this->_in_degs; }
    inline const auto& degree(const size_type k) const noexcept(NO_EXCEPT) { return this->_in_degs[k]; }

    inline const auto& in_degrees() const noexcept(NO_EXCEPT) { return this->_in_degs; }
    inline const auto& in_degree(const size_type k) const noexcept(NO_EXCEPT) { return this->_in_degs[k]; }

    inline const auto& out_degrees() const noexcept(NO_EXCEPT) { return this->_out_degs; }
    inline const auto& out_degree(const size_type k) const noexcept(NO_EXCEPT) { return this->_out_degs[k]; }

    inline size_type directed_edges_count() const noexcept(NO_EXCEPT) { return this->_directed_edge_count; }

    template<class R = valgrid<bool>>
    auto make_has_edges() const noexcept(NO_EXCEPT) {
        R res(this->size(), this->size(), false);
        REP(i, this->size()) ITR(j, this->operator[](i)) res[i][j] = true;
        return res;
    }

    template<bool SELF_ZERO = true, class T = cost_type, class R = valgrid<T>>
    auto make_initial_distance_matrix() const noexcept(NO_EXCEPT) {
        R res(this->size(), this->size(), numeric_limits<T>::arithmetic_infinity());
        if constexpr(SELF_ZERO) REP(i, this->size()) res[i][i] = 0;
        REP(i, this->size()) ITR(j, this->operator[](i)) res[i][j] = j.cost;
        return res;
    }

    template<bool SELF_ZERO = true, class T = cost_type, class R = valgrid<T>>
    auto make_distance_matrix() const noexcept(NO_EXCEPT) {
        R res = this->make_initial_distance_matrix<SELF_ZERO,T,R>();
        REP(k, this->size()) REP(i, this->size()) REP(j, this->size()) {
            chmin(res[i][j], res[i][k] + res[k][j]);
        }
        return res;
    }

    template<edge_kind EDGE_TYPE = edge_kind::directed>
    auto add_edge(const node_type u, const node_type v, const cost_type w = 1) noexcept(NO_EXCEPT) {
        assert(0 <= u and u < this->size()), assert(0 <= v and v < this->size());
        const size_type k = this->edges().size();
        this->_edges.emplace_back(u, v, w, k);
        this->_add_edge(u, v, w, k);
        if constexpr(EDGE_TYPE == edge_kind::undirected) this->_add_edge(v, u, w, k);
        return k;
    }

    inline auto add_edge_bidirectionally(const node_type u, const node_type v, const cost_type w = 1) noexcept(NO_EXCEPT) {
        return this->add_edge<edge_kind::undirected>(u, v, w);
    }

    template<bool WEIGHTED = false, bool ONE_ORIGIN = true, const edge_kind EDGE_TYPE = edge_kind::directed, class Stream = input_adaptor<>>
    void read(const size_type edges, Stream *const ist = &_input) noexcept(NO_EXCEPT) {
        REP(edges) {
            node_type u, v; cost_type w = 1; *ist >> u >> v; if(ONE_ORIGIN) --u, --v;
            if(WEIGHTED) *ist >> w;
            this->add_edge<EDGE_TYPE>(u, v, w);
        }
    }

    template<bool WEIGHTED = false, bool ONE_ORIGIN = true, class Stream = input_adaptor<>>
    void read_bidirectionally(const size_type edges, Stream *const ist = &_input) noexcept(NO_EXCEPT) {
        REP(edges) {
            node_type u, v; cost_type w = 1; *ist >> u >> v; if(ONE_ORIGIN) --u, --v;
            if(WEIGHTED) *ist >> w;
            this->add_edge<edge_kind::undirected>(u, v, w);
        }
    }
};


template<class Graph>
struct mixin : Graph {
    using Graph::Graph;
    using size_type = typename Graph::size_type;
    using node_type = typename Graph::node_type;
    using cost_type = typename Graph::cost_type;

    inline size_type vertices() const noexcept(NO_EXCEPT) { return static_cast<size_type>(this->Graph::size()); }


  public:
    // graph/shortest_path.hpp
    template<item_or_convertible_range<node_type> Source, class Dist, class Prev = std::nullptr_t>
    void shortest_path_without_cost(Source&&, Dist *const, Prev *const = nullptr, const node_type& = -1, const node_type& = -2) const noexcept(NO_EXCEPT);

    template<item_or_convertible_range<node_type> Source>
    auto shortest_path_without_cost(Source&&) const noexcept(NO_EXCEPT);

    // graph/dijkstra.hpp
    template<item_or_convertible_range<node_type> Source, class Dist, class Prev = std::nullptr_t>
    void shortest_path_with_01cost(Source&&, Dist *const, Prev *const = nullptr, const node_type& = -1, const node_type& = -2) const noexcept(NO_EXCEPT);

    template<item_or_convertible_range<node_type> Source>
    auto shortest_path_with_01cost(Source&&) const noexcept(NO_EXCEPT);

    // graph/dijkstra.hpp
    template<item_or_convertible_range<node_type> Source, class Dist, class Prev = std::nullptr_t>
    void shortest_path_with_cost(Source&&, Dist *const, Prev *const = nullptr, const node_type& = -1, const node_type& = -2) const noexcept(NO_EXCEPT);

    template<item_or_convertible_range<node_type> Source>
    auto shortest_path_with_cost(Source&&) const noexcept(NO_EXCEPT);

    // graph/topological_sort.hpp
    bool sort_topologically(vector<node_type> *const ) const noexcept(NO_EXCEPT);
    bool sort_topologically() const noexcept(NO_EXCEPT);

    // graph/topological_sort.hpp
    template<class> bool sort_topologically_with_priority(vector<node_type> *const) const noexcept(NO_EXCEPT);
    template<class> bool sort_topologically_with_priority() const noexcept(NO_EXCEPT);

    // graph/minimum_paph_cover.hpp
    size_type minimum_paph_cover_size_as_dag() const noexcept(NO_EXCEPT);

    // graph/spanning_tree_cost.hpp
    auto minimum_spanning_tree(mixin *const = nullptr) const noexcept(NO_EXCEPT);

    // graph/spanning_tree_cost.hpp
    auto maximum_spanning_tree(mixin *const = nullptr) const noexcept(NO_EXCEPT);

    // graph/reachability.hpp
    template<std::ranges::sized_range R>
    auto test_reachability(R&&) const noexcept(NO_EXCEPT);

    // graph/connected_components.hpp
    disjoint_set components() const noexcept(NO_EXCEPT);

    // graph/connected_components.hpp
    bool is_bipartite() const noexcept(NO_EXCEPT);

    // graph/connected_components.hpp
    template<class Colors>
    bool is_bipartite(Colors *const) const noexcept(NO_EXCEPT);

    // graph/parse_grid.hpp
    template<bool = false, class G, class U = char>
    void parse_grid(const G&, U = '.') noexcept(NO_EXCEPT);

    // graph/manhattan_minimum_spanning_tree.hpp
    template<
        std::input_iterator I0, std::input_iterator I1,
        std::sentinel_for<I0> S0, std::sentinel_for<I1> S1
    >
    cost_type build_manhattan_mst(I0, S0, I1, S1) noexcept(NO_EXCEPT);
};


} // namespace graph_impl

} // namespace internal


template<class Cost = std::int64_t, class Node = internal::size_t, template<class...> class Container = vector>
struct graph : internal::graph_impl::mixin<internal::graph_impl::regular_core<Node, Cost, Container>> {
  private:
    using base = internal::graph_impl::mixin<internal::graph_impl::regular_core<Node, Cost, Container>>;

  public:
    using size_type = typename base::size_type;
    using node_type = typename base::node_type;
    using edge = typename internal::graph_impl::edge<node_type,Cost>;

    explicit graph(const size_type n = 0) noexcept(NO_EXCEPT) : base(n) {}
};

template<class Node = internal::size_t, class Cost = std::int64_t, class Edges = virtual_map<Node, vector<typename internal::graph_impl::edge<Node, Cost>>>>
struct virtual_graph : internal::graph_impl::mixin<internal::graph_impl::virtual_base<Node, Cost, Edges>> {
  private:
    using base = internal::graph_impl::mixin<internal::graph_impl::virtual_base<Node, Cost, Edges>>;

  public:
    using size_type = typename base::size_type;
    using edge = typename internal::graph_impl::edge<Node, Cost>;

  private:
    size_type _n = 0;

  public:
    template<class F>
    explicit virtual_graph(F&& f, const size_type n = 0) noexcept(NO_EXCEPT)
      : base(n, std::forward<F>(f)), _n(n)
    {}
};


} // namespace uni
#line 9 "graph/centroid_decomposition.hpp"

namespace uni {


// Thanks to: https://qiita.com/drken/items/4b4c3f1824339b090202
template<class Graph = graph<>>
struct centroid_decomposition {
    using size_type = internal::size_t;

    std::vector<size_type> centroids;

  private:
    const Graph& graph;
    std::vector<size_type> _size, _parent;
    std::vector<bool> _used;

  public:
    centroid_decomposition(const Graph& _graph) noexcept(NO_EXCEPT)
      : graph(_graph),
        _size(graph.vertices()), _parent(graph.vertices()), _used(graph.vertices())
    {}

    inline const auto& sizes() const noexcept(NO_EXCEPT) { return this->_size; }
    inline const auto& parents() const noexcept(NO_EXCEPT) { return this->_parent; }
    inline const auto& used() const noexcept(NO_EXCEPT) { return this->_used; }

    inline size_type size(const size_type v) const noexcept(NO_EXCEPT) {
        assert(0 <= v && v < this->graph.vertices());
        return this->_size[v];
    }
    inline size_type parent(const size_type v) const noexcept(NO_EXCEPT) {
        assert(0 <= v && v < this->graph.vertices());
        return this->_parent[v];
    }
    inline bool used(const size_type v) const noexcept(NO_EXCEPT) {
        assert(0 <= v && v < this->graph.vertices());
        return this->_used[v];
    }

    const std::vector<size_type>& find(const size_type v, const size_type sz, const size_type p = -1) noexcept(NO_EXCEPT) {
        assert(not this->_used[v]);

        this->_size[v] = 1, this->_parent[v] = p;
        bool found = true;
        ITR(e, this->graph[v]) {
            if(e.to == p) continue;
            if(this->_used[e.to]) continue;

            this->find(e.to, sz, v);
            if(this->_size[e.to] > sz / 2) found = false;
            this->_size[v] += this->_size[e.to];
        }
        if(sz - this->_size[v] > sz / 2) found = false;
        if(found) this->centroids.push_back(v);

        return this->centroids;
    }

    auto decompose(const size_type root, const size_type sz) noexcept(NO_EXCEPT) {
    assert(not this->_used[root]);

        std::vector<std::pair<size_type,size_type>> subtrees;

        this->centroids.clear();
        this->find(root, sz);

        const size_type centroid = this->centroids[0];
        this->_used[centroid] = true;

        ITR(e, this->graph[centroid]) {
            if(this->_used[e.to]) continue;
            if(e.to == this->_parent[centroid]) {
                subtrees.emplace_back(e.to, sz - this->_size[centroid]);
            }
            else {
                subtrees.emplace_back(e.to, this->_size[e.to]);
            }
        }

        return std::make_pair(centroid, subtrees);
    }

    auto decompose(const size_type root = 0) noexcept(NO_EXCEPT) {
        return this->decompose(root, this->graph.vertices());
    }
};


} // namespace uni
#line 2 "graph/centroid_path_decomposition.hpp"


#line 7 "graph/centroid_path_decomposition.hpp"

#line 9 "graph/centroid_path_decomposition.hpp"

#line 12 "graph/centroid_path_decomposition.hpp"

#line 14 "graph/centroid_path_decomposition.hpp"

namespace uni {

// Thanks to: https://kazuma8128.hatenablog.com/entry/2018/07/16/010500#fn-96e76557
class centroid_path_decomposition {
    using size_type = internal::size_t;

  private:
    std::vector<std::vector<size_type>> graph;

  public:
    std::vector<size_type> in, out, size, head, parent;

  private:
    size_type _cur = 0;

    void _erase_parent(const size_type v, const size_type p) noexcept(NO_EXCEPT) {
        this->parent[v] = p;
        ITRR(nv, graph[v]) {
            if(nv == this->graph[v].back()) break;
            if(nv == p) std::swap(nv, this->graph[v].back());
            this->_erase_parent(nv, v);
        }
        this->graph[v].pop_back();
    }

    void _race_size(const size_type v) noexcept(NO_EXCEPT) {
        ITRR(nv, this->graph[v]) {
            this->_race_size(nv);
            this->size[v] += this->size[nv];
            if(this->size[nv] > this->size[this->graph[v].front()]) std::swap(nv, this->graph[v].front());
        }
    }

    void _race_path(const size_type v) noexcept(NO_EXCEPT) {
        this->in[v] = this->_cur++;
        ITR(nv, this->graph[v]) {
            this->head[nv] = (nv == this->graph[v].front() ? this->head[v] : nv);
            this->_race_path(nv);
        }
        this->out[v] = this->_cur;
    }

  public:
    template<class Graph>
    centroid_path_decomposition(const Graph& _graph, const size_type root = 0) noexcept(NO_EXCEPT)
      : graph(_graph.size()), in(_graph.size(), -1), out(_graph.size(), -1), size(_graph.size(), 1), head(_graph.size()), parent(_graph.size(), -1)
    {
        REP(v, _graph.size()) ITR(nv, _graph[v]) { this->graph[v].push_back(nv); }
        this->build(root);
    }

    void build(const size_type root = 0) noexcept(NO_EXCEPT) {
        ITR(v, this->graph[root]) this->_erase_parent(v, root);
        this->_race_size(root);
        this->head[root] = root;
        this->_race_path(root);
    }

    size_type id(const size_type v) noexcept(NO_EXCEPT) { return this->in[v]; }

    size_type lca(size_type u, size_type v) const noexcept(NO_EXCEPT) {
        while(true) {
            if(this->in[u] > this->in[v]) std::swap(u, v);
            if(this->head[u] == this->head[v]) return u;
            v = this->parent[this->head[v]];
        }
    }

    template<class F>
    void edges_on_path(size_type u, size_type v, F&& f) noexcept(NO_EXCEPT) {
        while(true) {
            if(this->in[u] > this->in[v]) std::swap(u, v);
            if(this->head[u] != this->head[v]) {
                f(this->in[this->head[v]] - 1, this->in[v]);
                v = this->parent[this->head[v]];
            } else {
                if(u != v) f(this->in[u], this->in[v]);
                break;
            }
        }
    }

    template<class F>
    void nodes_on_path(size_type u, size_type v, F&& f) noexcept(NO_EXCEPT) {
        while (true) {
            if (this->in[u] > this->in[v]) std::swap(u, v);
            f(std::max(this->in[this->head[v]], this->in[u]), this->in[v]);
            if (this->head[u] != this->head[v])
                v = this->parent[this->head[v]];
            else {
                break;
            }
        }
    }

    template<class F>
    void subtree(const size_type v, F&& f) noexcept(NO_EXCEPT) { f(this->in[v], this->out[v]); }
};


} // namespace uni
#line 2 "graph/connected_components.hpp"

#line 5 "graph/connected_components.hpp"

#line 7 "graph/connected_components.hpp"

#line 11 "graph/connected_components.hpp"

template<class Graph>
uni::disjoint_set uni::internal::graph_impl::mixin<Graph>::components() const noexcept(NO_EXCEPT) {
    uni::disjoint_set disjoint_set(this->vertices());
    ITR(edges, *this) ITR(_id, u, v, _w, _idx, edges) {
        disjoint_set.merge(u, v);
    }
    return disjoint_set;
}
#line 2 "graph/is_bipartite.hpp"

#line 6 "graph/is_bipartite.hpp"

#line 8 "graph/is_bipartite.hpp"

#line 11 "graph/is_bipartite.hpp"


template<class Graph>
bool uni::internal::graph_impl::mixin<Graph>::is_bipartite() const noexcept(NO_EXCEPT) {
    valarray<std::int8_t> color(0, this->vertices());
    this->is_bipartite(&color);
    return true;
}


template<class Graph>
template<class Colors>
bool uni::internal::graph_impl::mixin<Graph>::is_bipartite(Colors *const color) const noexcept(NO_EXCEPT) {
    color->assign(this->vertices(), 0);

    REP(s, this->vertices()) {
        if(color->operator[](s) != 0) continue;

        std::stack<size_type> stack;
        stack.push(s);
        color->operator[](s) = 1;

        while(not stack.empty()) {
            auto v = stack.top(); stack.pop();
            auto c = color->operator[](v);

            ITR(nv, this->operator[](v)) {
                if(color->operator[](nv) == c) return false;
                if(color->operator[](nv) == 0) {
                    color->operator[](nv) = -c;
                    stack.push(nv);
                }
            }
        }
    }

    return true;
}
#line 2 "graph/lowest_common_ancestor.hpp"


#line 5 "graph/lowest_common_ancestor.hpp"


#line 8 "graph/lowest_common_ancestor.hpp"

#line 11 "graph/lowest_common_ancestor.hpp"

#line 14 "graph/lowest_common_ancestor.hpp"

#line 16 "graph/lowest_common_ancestor.hpp"


namespace uni {


template<class Graph>
struct lowest_common_ancestor {
    using size_type = internal::size_t;
    using graph_type = Graph;
    using edge_type = typename graph_type::edge_type;
    using cost_type = typename graph_type::cost_type;

    valarray<valarray<size_type>> parent;
    valarray<size_type> depth;
    valarray<cost_type> cost;

  private:
    void dfs(const graph_type &G, const edge_type& e) noexcept(NO_EXCEPT) {
        this->parent[0][e.to] = e.from;
        if(e.from >= 0) {
            this->depth[e.to] = this->depth[e.from] + 1;
            this->cost[e.to] = this->cost[e.from] + e.cost;
        }
        ITR(f, G[e.to]) {
            if(f.to != e.from) dfs(G, f);
        }
    }

  public:
    lowest_common_ancestor(const graph_type &G, const size_type root = 0) noexcept(NO_EXCEPT) { this->init(G, root); }

    void init(const graph_type &G, const size_type root = 0) noexcept(NO_EXCEPT) {
        const size_type n = static_cast<size_type>(G.size());
        const size_type d = std::bit_width<std::make_unsigned_t<size_type>>(n);

        this->parent.assign(d, valarray<size_type>(n, -1));
        this->depth.assign(n, 0), this->cost.assign(n, 0);

        this->dfs(G, edge_type(-1, root, 0));

        REP(k, d-1) REP(v, n) {
            if(this->parent[k][v] < 0) this->parent[k+1][v] = -1;
            else this->parent[k+1][v] = this->parent[k][this->parent[k][v]];
        }
    }

    size_type operator()(const size_type u, const size_type v) const noexcept(NO_EXCEPT) {
        return this->find(u, v);
    }

    size_type find(size_type u, size_type v) const noexcept(NO_EXCEPT) {
        if(this->depth[u] < this->depth[v]) std::swap(u, v);
        size_type d = static_cast<size_type>(this->parent.size());

        REP(k, d) {
            if((this->depth[u] - this->depth[v]) >> k & 1) u = this->parent[k][u];
        }

        if(u == v) return u;

        REPD(k, d) {
            if(this->parent[k][u] != this->parent[k][v]) {
                u = this->parent[k][u];
                v = this->parent[k][v];
            }
        }

        return this->parent[0][u];
    }

    size_type path_length(const size_type u, const size_type v) const noexcept(NO_EXCEPT) {
        return this->depth[u] + this->depth[v] - 2 * this->depth[find(u, v)];
    }

    size_type distance(const size_type u, const size_type v) const noexcept(NO_EXCEPT) {
        return this->cost[u] + this->cost[v] - 2 * this->cost[find(u, v)];
    }
};


} // namespace uni
#line 2 "graph/manhattan_minimum_spanning_tree.hpp"

#line 9 "graph/manhattan_minimum_spanning_tree.hpp"


#line 12 "graph/manhattan_minimum_spanning_tree.hpp"

#line 15 "graph/manhattan_minimum_spanning_tree.hpp"

#line 17 "graph/manhattan_minimum_spanning_tree.hpp"

#line 19 "graph/manhattan_minimum_spanning_tree.hpp"

#line 2 "graph/spanning_tree.hpp"


#line 6 "graph/spanning_tree.hpp"

#line 8 "graph/spanning_tree.hpp"


namespace uni {

namespace internal {

namespace graph_impl {


template<class G, template<class...> class Compare, class Cost, class Size>
std::optional<Cost> kruskal(const G& graph, const Compare<std::tuple<Cost, Size, Size>> compare, G *const mst = nullptr) noexcept(NO_EXCEPT) {
    disjoint_set ds(graph.size());

    std::vector<std::tuple<Cost, Size, Size>> edges;

    REP(u, graph.size()) ITR(e, graph[u]) {
        edges.emplace_back(e.cost, u, e.to);
    }

    std::ranges::sort(edges, compare);

    if(mst) mst->clear(), mst->resize(graph.size());

    Cost res = 0;

    typename G::size_type cnt = 0;
    ITR(w, u, v, edges) {
        if(not ds.same(u, v)) {
            ds.merge(u, v);
            if(mst) mst->add_edge_bidirectionally(u, v, w);
            res += w;
            ++cnt;
        }
    }

    assert(cnt <= graph.size() - 1);
    if(cnt != graph.size() - 1) return {};

    return res;
}


} // namespace graph_impl

} // namespace internal

} // namespace uni


template<class Graph>
inline auto uni::internal::graph_impl::mixin<Graph>::minimum_spanning_tree(internal::graph_impl::mixin<Graph> *const mst) const noexcept(NO_EXCEPT) {
    return
        uni::internal::graph_impl::kruskal<
            uni::internal::graph_impl::mixin<Graph>,
            std::less, cost_type, size_type
        >(*this, {}, mst);
}

template<class Graph>
inline auto uni::internal::graph_impl::mixin<Graph>::maximum_spanning_tree(internal::graph_impl::mixin<Graph> *const mst) const noexcept(NO_EXCEPT) {
    return
        uni::internal::graph_impl::kruskal<
            uni::internal::graph_impl::mixin<Graph>,
            std::less, cost_type, size_type
        >(*this, {}, mst);
}
#line 22 "graph/manhattan_minimum_spanning_tree.hpp"


namespace uni {


// TODO: Vector View
template <
    std::input_iterator I0, std::input_iterator I1,
    std::sentinel_for<I0> S0, std::sentinel_for<I1> S1
>
auto manhattan_mst_candidate_edges(
    I0 x_first, S0 x_last, I1 y_first, S1 y_last
) noexcept(NO_EXCEPT) {
    using size_type = internal::size_t;
    using cost_type = std::common_type_t<std::iter_value_t<I0>, std::iter_value_t<I1>>;

    std::vector<cost_type> xs(x_first, x_last), ys(y_first, y_last);
    assert(xs.size() == ys.size());

    std::vector<size_type> indices(xs.size());
    std::iota(ALL(indices), 0);

    vector<std::tuple<size_type, size_type, cost_type>> res;

    REP(_0, 2) {
        REP(_1, 2) {
            std::ranges::sort(indices, [&](const auto i, const auto j) { return xs[i] + ys[i] < xs[j] + ys[j]; });

            std::map<cost_type,size_type> scan;
            ITR(i, indices) {
                for(auto itr = scan.lower_bound(-ys[i]); itr!=scan.end(); itr=scan.erase(itr)) {
                    const auto j = itr->second;
                    if(xs[i] - xs[j] < ys[i] - ys[j]) break;
                    res.emplace_back(i, j, std::abs(xs[i] - xs[j]) + std::abs(ys[i] - ys[j]));
                }
                scan[-ys[i]] = i;
            }

            std::swap(xs, ys);
        }
        ITRR(x, xs) x *= -1;
    }

    std::ranges::sort(res, [&](const auto& p, const auto& q) { return std::get<2>(p) < std::get<2>(q); });

    return res;
}



template <
    std::input_iterator I0, std::input_iterator I1,
    std::sentinel_for<I0> S0, std::sentinel_for<I1> S1
>
auto manhattan_mst_edges(
    I0 x_first, S0 x_last, I1 y_first, S1 y_last,
    std::common_type_t<std::iter_value_t<I0>, std::iter_value_t<I1>> *const cost_sum = nullptr
) noexcept(NO_EXCEPT) {
    using cost_type = std::common_type_t<std::iter_value_t<I0>, std::iter_value_t<I1>>;
    using size_type = internal::size_t;

    assert(std::ranges::distance(x_first, x_last) == std::ranges::distance(y_first, y_last));

    if(cost_sum) *cost_sum = 0;

    vector<std::tuple<size_type, size_type, cost_type>> res;
    disjoint_set uf(std::ranges::distance(x_first, x_last));

    ITR(u, v, w, (manhattan_mst_candidate_edges<I0,I1>(x_first, x_last, y_first, y_last))) {
        if(not uf.same(u, v)) {
            uf.merge(u, v);
            res.emplace_back(u, v, w);
            if(cost_sum) *cost_sum += w;
        }
    }

    return res;
}


template<class Graph>
template<
    std::input_iterator I0, std::input_iterator I1,
    std::sentinel_for<I0> S0, std::sentinel_for<I1> S1
>
typename Graph::cost_type internal::graph_impl::mixin<Graph>::build_manhattan_mst(
    I0 x_first, S0 x_last, I1 y_first, S1 y_last
) noexcept(NO_EXCEPT)
{
    assert(std::ranges::distance(x_first, x_last) == std::ranges::distance(y_first, y_last));

    cost_type res = 0;

    const auto edges = manhattan_mst_edges<I0, I1, S0, S1>(x_first, x_last, y_first, y_last);

    ITR(u, v, w, edges) {
        this->add_edge_bidirectionally(u, v, w);
    }

    return res;
}


} // namespace uni
#line 2 "graph/maximum_bipartite_matching.hpp"


#include <atcoder/maxflow>


#line 9 "graph/maximum_bipartite_matching.hpp"

#line 12 "graph/maximum_bipartite_matching.hpp"

#line 14 "graph/maximum_bipartite_matching.hpp"


namespace uni {

struct maximum_bipartite_matching {
    // using size_type = internal::size_t;
    using size_type = int;

  protected:
    using MF = atcoder::mf_graph<size_type>;

    size_type _m, _n, _s, _edges = 0;
    MF _mf;

  public:
    explicit maximum_bipartite_matching(const size_type n) noexcept(NO_EXCEPT) : maximum_bipartite_matching(n, n) {}
    maximum_bipartite_matching(const size_type m, const size_type n) noexcept(NO_EXCEPT)
      : _m(m), _n(n), _s(m + n), _mf(m + n + 2)
    {
        REP(i, m) {
            this->_mf.add_edge(this->_s, i, 1);
        }
        REP(i, n) {
            this->_mf.add_edge(m + i, this->_s + 1, 1);
        }
    }

    inline auto& add(const size_type i, const size_type j) noexcept(NO_EXCEPT) {
        assert(0 <= i && i < this->_m);
        assert(0 <= j && j < this->_n);
        this->_mf.add_edge(i, this->_m + j, 1);
        ++this->_edges;
        return *this;
    }

    inline size_type max_matched() noexcept(NO_EXCEPT) {
        return this->_mf.flow(this->_s, this->_s + 1);
    }

    inline auto get_matching() noexcept(NO_EXCEPT) {
        this->max_matched();

        vector<spair<size_type>> res;

        REP(i, this->_edges) {
            const auto edge = this->_mf.get_edge(this->_s + i);
            if(edge.flow == 0) continue;
            res.emplace_back(edge.from, edge.to - this->_m);
        }

        return res;
    }
};

} // namespace uni
#line 2 "graph/minimum_paph_cover.hpp"


#line 5 "graph/minimum_paph_cover.hpp"

#line 8 "graph/minimum_paph_cover.hpp"

#line 11 "graph/minimum_paph_cover.hpp"


template<class Graph>
typename uni::internal::graph_impl::mixin<Graph>::size_type uni::internal::graph_impl::mixin<Graph>::minimum_paph_cover_size_as_dag() const noexcept(NO_EXCEPT) {
    uni::maximum_bipartite_matching bm(this->size());

    REP(i, this->size()) ITR(j, (*this)[i]) {
        bm.add(i, j.to);
    }

    return this->size() - bm.max_matched();
}
#line 2 "graph/parse_grid.hpp"

#line 4 "graph/parse_grid.hpp"

#line 7 "graph/parse_grid.hpp"

template<class Graph>
template<bool REV, class G, class U>
void uni::internal::graph_impl::mixin<Graph>::parse_grid(const G &grid, U available) noexcept(NO_EXCEPT) {
    this->clear();
    this->resize(grid.height() * grid.width());

    REP(i, grid.height()) REP(j, grid.width()) {
        if(REV ^ (grid(i, j) != available)) continue;
        if(i+1 < grid.height() and (REV ^ (grid(i+1, j) == available))) {
            this->template add_edge_bidirectionally(grid.id(i, j), grid.id(i+1, j));
        }
        if(j+1 < grid.width() and (REV ^ (grid(i, j+1) == available))) {
            this->template add_edge_bidirectionally(grid.id(i, j), grid.id(i, j+1));
        }
    }
}
#line 2 "graph/reachability_test.hpp"


#line 6 "graph/reachability_test.hpp"


#line 10 "graph/reachability_test.hpp"

#line 12 "graph/reachability_test.hpp"

#line 2 "graph/topological_sort.hpp"


#line 6 "graph/topological_sort.hpp"

#line 10 "graph/topological_sort.hpp"


template<class Graph>
template<class comparer>
bool uni::internal::graph_impl::mixin<Graph>::sort_topologically_with_priority(uni::vector<node_type> *const sorted) const noexcept(NO_EXCEPT) {
    sorted->clear();

    std::vector<size_type> in_degs(this->size());
    ITR(v, *this) ITR(e, v)  ++in_degs[e.to];

    std::priority_queue<node_type,std::vector<node_type>,comparer> que;
    REP(i, this->size()) if(in_degs[i] == 0) que.push(i);

    while(not que.empty()) {
        const node_type v = que.top(); que.pop();
        ITR(u, (*this)[v]) if(!(--in_degs[u.to])) que.push(u.to);
        sorted->push_back(v);
    }

    return std::ranges::ssize(*sorted) == std::ranges::ssize(*this);
}

template<class Graph>
template<class comparer>
bool uni::internal::graph_impl::mixin<Graph>::sort_topologically_with_priority() const noexcept(NO_EXCEPT) {
    uni::vector<node_type> vs;
    return this->sort_topologically_with_priority<comparer>(&vs);
}


template<class Graph>
bool uni::internal::graph_impl::mixin<Graph>::sort_topologically(uni::vector<node_type> *const sorted) const noexcept(NO_EXCEPT) {
    sorted->clear();

    std::vector<size_type> in_degs(this->size());
    ITR(v, *this) ITR(e, v)  ++in_degs[e.to];

    std::queue<node_type> que;
    REP(i, this->size()) if(in_degs[i] == 0) que.push(i);

    while(not que.empty()) {
        const node_type v = que.front(); que.pop();
        ITR(u, (*this)[v]) if(!(--in_degs[u.to])) que.push(u.to);
        sorted->push_back(v);
    }

    return std::ranges::ssize(*sorted) == std::ranges::ssize(*this);
}

template<class Graph>
bool uni::internal::graph_impl::mixin<Graph>::sort_topologically() const noexcept(NO_EXCEPT) {
    std::vector<node_type> vs;
    return this->sort_topologically(&vs);
}
#line 15 "graph/reachability_test.hpp"

#line 2 "view/chunk.hpp"


#line 6 "view/chunk.hpp"


#line 9 "view/chunk.hpp"

#line 11 "view/chunk.hpp"


namespace uni {


template<std::ranges::view View>
    requires std::ranges::input_range<View>
struct chunk_view : std::ranges::view_interface<chunk_view<View>> {
  private:
    View _base;
    std::ranges::range_difference_t<View> _n;
    std::ranges::range_difference_t<View> _remainder = 0;
    std::optional<std::ranges::iterator_t<View>> _current;

    struct outer_iterator;
    struct inner_iterator;

  public:
    constexpr explicit chunk_view(View base, std::ranges::range_difference_t<View> n)
        : _base(std::move(base)), _n(n) {
        assert(n >= 0);
    }

    constexpr View base() const &
        requires std::copy_constructible<View>
    {
        return this->_base;
    }

    constexpr View base() && { return std::move(this->_base); }

    constexpr outer_iterator begin() {
        this->_current = std::ranges::begin(this->_base);
        this->_remainder = this->_n;
        return outer_iterator(*this);
    }

    constexpr std::default_sentinel_t end() const noexcept {
        return std::default_sentinel;
    }

    constexpr auto size()
        requires std::ranges::sized_range<View>
    {
        return to_unsigned(div_ceil(std::ranges::distance(this->_base), this->_n));
    }

    constexpr auto size() const
        requires std::ranges::sized_range<const View>
    {
        return to_unsigned(div_ceil(std::ranges::distance(this->_base), this->_n));
    }
};

template<class Range>
chunk_view(Range&&, std::ranges::range_difference_t<Range>) -> chunk_view<std::views::all_t<Range>>;


template<std::ranges::view View>
    requires std::ranges::input_range<View>
struct chunk_view<View>::outer_iterator {
  private:
    chunk_view *_parent;

    constexpr explicit outer_iterator(chunk_view &parent) noexcept
      : _parent(std::addressof(parent))
    {}

    friend chunk_view;

  public:
    using iterator_concept = std::input_iterator_tag;
    using difference_type = std::ranges::range_difference_t<View>;

    struct value_type;

    outer_iterator(outer_iterator &&) = default;
    outer_iterator &operator=(outer_iterator &&) = default;

    constexpr value_type operator*() const {
        assert(*this != std::default_sentinel);
        return value_type(*this->_parent);
    }

    constexpr outer_iterator &operator++() {
        assert(*this != std::default_sentinel);
        std::ranges::advance(*this->_parent->_current, this->_parent->_remainder, std::ranges::end(this->_parent->_base));
        this->_parent->_remainder = this->_parent->_n;
        return *this;
    }

    constexpr void operator++(int) { ++*this; }

    friend constexpr bool operator==(const outer_iterator &lhs, std::default_sentinel_t) {
        return *lhs._parent->_current == std::ranges::end(lhs._parent->_base) && lhs._parent->_remainder != 0;
    }

    friend constexpr difference_type operator-(std::default_sentinel_t, const outer_iterator &rhs)
        requires std::sized_sentinel_for<std::ranges::sentinel_t<View>, std::ranges::iterator_t<View>>
    {
        const auto dist = std::ranges::end(rhs._parent->_base) - *rhs._parent->_current;

        if(dist < rhs._parent->_remainder) return dist == 0 ? 0 : 1;
        return 1 + div_ceil(dist - rhs._parent->_remainder, rhs._parent->_n);
    }

    friend constexpr difference_type operator-(const outer_iterator &lhs, std::default_sentinel_t rhs)
        requires std::sized_sentinel_for<std::ranges::sentinel_t<View>, std::ranges::iterator_t<View>>
    {
        return -(rhs - lhs);
    }
};

template<std::ranges::view View>
    requires std::ranges::input_range<View>
struct chunk_view<View>::outer_iterator::value_type : std::ranges::view_interface<value_type> {
  private:
    chunk_view *_parent;

    constexpr explicit value_type(chunk_view &parent) noexcept
      : _parent(std::addressof(parent))
    {}

    friend outer_iterator;

  public:
    constexpr inner_iterator begin() const noexcept {
        return inner_iterator(*this->_parent);
    }

    constexpr std::default_sentinel_t end() const noexcept {
        return std::default_sentinel;
    }

    constexpr auto size() const
        requires std::sized_sentinel_for<std::ranges::sentinel_t<View>, std::ranges::iterator_t<View>>
    {
        return to_unsigned(std::ranges::min(this->_parent->_remainder, std::ranges::end(this->_parent->_base) - *this->_parent->_current));
    }
};

template<std::ranges::view View>
    requires std::ranges::input_range<View>
struct chunk_view<View>::inner_iterator {
  private:
    chunk_view *_parent;

    constexpr explicit inner_iterator(chunk_view &parent) noexcept
      : _parent(std::addressof(parent))
    {}

    friend outer_iterator::value_type;

  public:
    using iterator_concept = std::input_iterator_tag;
    using difference_type = std::ranges::range_difference_t<View>;
    using value_type = std::ranges::range_value_t<View>;

    inner_iterator(inner_iterator &&) = default;
    inner_iterator &operator=(inner_iterator &&) = default;

    constexpr const std::ranges::iterator_t<View> &base() const & {
        return *this->_parent->_current;
    }

    constexpr std::ranges::range_reference_t<View> operator*() const {
        assert(*this != std::default_sentinel);
        return **this->_parent->_current;
    }

    constexpr inner_iterator &operator++() {
        assert(*this != std::default_sentinel);
        ++*this->_parent->_current;

        if(*this->_parent->_current == std::ranges::end(this->_parent->_base)) {
            this->_parent->_remainder = 0;
        }
        else {
            --this->_parent->_remainder;
        }

        return *this;
    }

    constexpr void operator++(int) { ++*this; }

    friend constexpr bool operator==(const inner_iterator &lhs, std::default_sentinel_t) noexcept {
        return lhs._parent->_remainder == 0;
    }

    friend constexpr difference_type operator-(std::default_sentinel_t, const inner_iterator &rhs)
        requires std::sized_sentinel_for<std::ranges::sentinel_t<View>, std::ranges::iterator_t<View>>
    {
        return std::ranges::min(rhs._parent->_remainder, std::ranges::end(rhs._parent->_base) - *rhs._parent->_current);
    }

    friend constexpr difference_type operator-(const inner_iterator &lhs, std::default_sentinel_t rhs)
        requires std::sized_sentinel_for<std::ranges::sentinel_t<View>, std::ranges::iterator_t<View>>
    {
        return -(rhs - lhs);
    }
};

template<std::ranges::view View>
    requires std::ranges::forward_range<View>
struct chunk_view<View> : std::ranges::view_interface<chunk_view<View>> {
  private:
    View _base;
    std::ranges::range_difference_t<View> _n;
    template<bool> struct iterator;

  public:
    constexpr explicit chunk_view(View base, const std::ranges::range_difference_t<View> n)
        : _base(std::move(base)), _n(n)
    {
        assert(n > 0);
    }

    constexpr View base() const &
        requires std::copy_constructible<View>
    {
        return this->_base;
    }

    constexpr View base() && { return std::move(this->_base); }

    constexpr auto begin()
        requires(!internal::simple_view<View>)
    {
        return iterator<false>(this, std::ranges::begin(this->_base));
    }

    constexpr auto begin() const
        requires std::ranges::forward_range<const View>
    {
        return iterator<true>(this, std::ranges::begin(this->_base));
    }

    constexpr auto end()
        requires(!internal::simple_view<View>)
    {
        if constexpr(std::ranges::common_range<View> && std::ranges::sized_range<View>) {
            const auto missing = (this->_n - std::ranges::distance(this->_base) % this->_n) % this->_n;
            return iterator<false>(this, std::ranges::end(this->_base), missing);
        }
        else if constexpr(std::ranges::common_range<View> && !std::ranges::bidirectional_range<View>) {
            return iterator<false>(this, std::ranges::end(this->_base));
        }
        else {
            return std::default_sentinel;
        }
    }

    constexpr auto end() const
        requires std::ranges::forward_range<const View>
    {
        if constexpr(std::ranges::common_range<const View> && std::ranges::sized_range<const View>) {
            auto missing = (this->_n - std::ranges::distance(this->_base) % this->_n) % this->_n;
            return iterator<true>(this, std::ranges::end(this->_base), missing);
        } else if constexpr(std::ranges::common_range<const View> && !std::ranges::bidirectional_range<const View>) {
            return iterator<true>(this, std::ranges::end(this->_base));
        }
        else {
            return std::default_sentinel;
        }
    }

    constexpr auto size()
        requires std::ranges::sized_range<View>
    {
        return to_unsigned(div_ceil(std::ranges::distance(this->_base), this->_n));
    }

    constexpr auto size() const
        requires std::ranges::sized_range<const View>
    {
        return to_unsigned(div_ceil(std::ranges::distance(this->_base), this->_n));
    }
};


template<std::ranges::view View>
    requires std::ranges::forward_range<View>
template<bool CONST>
struct chunk_view<View>::iterator {
  private:
    using Parent = internal::maybe_const_t<CONST, chunk_view>;
    using Base = internal::maybe_const_t<CONST, View>;

    std::ranges::iterator_t<Base> _current = std::ranges::iterator_t<Base>();
    std::ranges::sentinel_t<Base> _end = std::ranges::sentinel_t<Base>();
    std::ranges::range_difference_t<Base> _n = 0;
    std::ranges::range_difference_t<Base> _missing = 0;

    constexpr iterator(Parent *parent, std::ranges::iterator_t<Base> current, const std::ranges::range_difference_t<Base> missing = 0)
      : _current(current), _end(std::ranges::end(parent->_base)), _n(parent->_n), _missing(missing)
    {}

    friend chunk_view;

  public:
    using iterator_category = std::input_iterator_tag;
    using iterator_concept = internal::most_primitive_iterator_concept<false, Base>;

    using value_type = decltype(std::views::take(std::ranges::subrange(_current, _end), _n));
    using difference_type = std::ranges::range_difference_t<Base>;

    iterator() = default;

    constexpr iterator(iterator<!CONST> itr)
        requires
            CONST &&
            std::convertible_to<std::ranges::iterator_t<View>, std::ranges::iterator_t<Base>> &&
            std::convertible_to<std::ranges::sentinel_t<View>, std::ranges::sentinel_t<Base>>
      : _current(std::move(itr._current)), _end(std::move(itr._end)), _n(itr._n), _missing(itr._missing)
    {}

    constexpr std::ranges::iterator_t<Base> base() const { return this->_current; }

    constexpr value_type operator*() const {
        assert(this->_current != this->_end);
        return std::views::take(std::ranges::subrange(this->_current, this->_end), this->_n);
    }

    constexpr iterator &operator++() {
        assert(this->_current != this->_end);
        this->_missing = std::ranges::advance(this->_current, this->_n, this->_end);
        return *this;
    }

    constexpr iterator operator++(int) {
        auto temp = *this;
        return ++*this, temp;
    }

    constexpr iterator &operator--()
        requires std::ranges::bidirectional_range<Base>
    {
        std::ranges::advance(this->_current, this->_missing - this->_n);
        this->_missing = 0;
        return *this;
    }

    constexpr iterator operator--(int)
        requires std::ranges::bidirectional_range<Base>
    {
        auto temp = *this;
        return --*this, temp;
    }

    constexpr iterator &operator+=(difference_type lhs)
        requires std::ranges::random_access_range<Base>
    {
        if(lhs > 0) {
            assert(std::ranges::distance(this->_current, this->_end) > this->_n * (lhs - 1));
            this->_missing = std::ranges::advance(this->_current, this->_n * lhs, this->_end);
        }
        else if(lhs < 0) {
            std::ranges::advance(this->_current, this->_n * lhs + this->_missing);
            this->_missing = 0;
        }

        return *this;
    }

    constexpr iterator &operator-=(difference_type lhs)
        requires std::ranges::random_access_range<Base>
    {
        return *this += -lhs;
    }

    constexpr value_type operator[](difference_type n) const
        requires std::ranges::random_access_range<Base>
    {
        return *(*this + n);
    }

    friend constexpr bool operator==(const iterator &lhs, const iterator &rhs) {
        return lhs._current == rhs._current;
    }

    friend constexpr bool operator==(const iterator &lhs, std::default_sentinel_t) {
        return lhs._current == lhs._end;
    }

    friend constexpr bool operator<(const iterator &lhs, const iterator &rhs)
        requires std::ranges::random_access_range<Base>
    {
        return lhs._current > rhs._current;
    }

    friend constexpr bool operator>(const iterator &lhs, const iterator &rhs)
        requires std::ranges::random_access_range<Base>
    {
        return rhs < lhs;
    }

    friend constexpr bool operator<=(const iterator &lhs, const iterator &rhs)
        requires std::ranges::random_access_range<Base>
    {
        return !(rhs < lhs);
    }

    friend constexpr bool operator>=(const iterator &lhs, const iterator &rhs)
        requires std::ranges::random_access_range<Base>
    {
        return !(lhs < rhs);
    }

    friend constexpr auto operator<=>(const iterator &lhs, const iterator &rhs)
        requires std::ranges::random_access_range<Base> && std::three_way_comparable<std::ranges::iterator_t<Base>>
    {
        return lhs._current <=> rhs._current;
    }

    friend constexpr iterator operator+(const iterator &itr, const difference_type count)
        requires std::ranges::random_access_range<Base>
    {
        auto res = itr;
        return res += count, res;
    }

    friend constexpr iterator operator+(const difference_type count, const iterator &itr)
        requires std::ranges::random_access_range<Base>
    {
        auto res = itr;
        return res += count, res;
    }

    friend constexpr iterator operator-(const iterator &itr, const difference_type count)
        requires std::ranges::random_access_range<Base>
    {
        auto res = itr;
        return res -= count, res;
    }

    friend constexpr difference_type operator-(const iterator &lhs, const iterator &rhs)
        requires std::sized_sentinel_for<std::ranges::iterator_t<Base>, std::ranges::iterator_t<Base>>
    {
        return (lhs._current - rhs._current + lhs._missing - rhs._missing) / lhs._n;
    }

    friend constexpr difference_type operator-(std::default_sentinel_t rhs, const iterator &lhs)
        requires std::sized_sentinel_for<std::ranges::sentinel_t<Base>, std::ranges::iterator_t<Base>>
    {
        return div_ceil(lhs._end - lhs._current, lhs._n);
    }

    friend constexpr difference_type operator-(const iterator &lhs, std::default_sentinel_t rhs)
        requires std::sized_sentinel_for<std::ranges::sentinel_t<Base>, std::ranges::iterator_t<Base>>
    {
        return -(rhs - lhs);
    }
};


namespace views {
namespace internal {


template<class Range, typename Diff>
concept can_chunk_view = requires { chunk_view(std::declval<Range>(), std::declval<Diff>()); };


} // namespace internal


struct Chunk : adaptor::range_adaptor<Chunk> {
    template<std::ranges::viewable_range Range, class Diff = std::ranges::range_difference_t<Range>>
        requires internal::can_chunk_view<Range, Diff>
    constexpr auto operator() [[nodiscard]] (Range &&res, std::type_identity_t<Diff> n) const {
        return chunk_view(std::forward<Range>(res), n);
    }

    using adaptor::range_adaptor<Chunk>::operator();

    static constexpr int arity = 2;
    static constexpr bool has_simple_extra_args = true;
};


inline constexpr Chunk chunk;


} // namespace views

} // namespace uni


namespace std::ranges {


template<class View>
inline constexpr bool enable_borrowed_range<uni::chunk_view<View>> = forward_range<View> && enable_borrowed_range<View>;


} // namespace std::ranges
#line 2 "view/enumerate.hpp"


#line 6 "view/enumerate.hpp"


#line 10 "view/enumerate.hpp"


namespace uni {


namespace internal {


template<class Range>
concept range_with_movable_reference =
    std::ranges::input_range<Range> && std::move_constructible<std::ranges::range_reference_t<Range>> &&
    std::move_constructible<std::ranges::range_rvalue_reference_t<Range>>;


} // namespace internal


template<std::ranges::view View>
    requires internal::range_with_movable_reference<View>
struct enumerate_view : public std::ranges::view_interface<enumerate_view<View>> {
  private:
    View _base = View();

    template<bool Const> class iterator;
    template<bool Const> class sentinel;

  public:
    enumerate_view()
        requires std::default_initializable<View>
    = default;

    constexpr explicit enumerate_view(View base) : _base(std::move(base)) {}

    constexpr auto begin()
        requires(!internal::simple_view<View>)
    {
        return iterator<false>(std::ranges::begin(this->_base), 0);
    }

    constexpr auto begin() const
        requires internal::range_with_movable_reference<const View>
    {
        return iterator<true>(std::ranges::begin(this->_base), 0);
    }

    constexpr auto end()
        requires(!internal::simple_view<View>)
    {
        if constexpr(std::ranges::common_range<View> && std::ranges::sized_range<View>) {
            return iterator<false>(std::ranges::end(_base), std::ranges::distance(this->_base));
        }
        else {
            return sentinel<false>(std::ranges::end(_base));
        }
    }

    constexpr auto end() const
        requires internal::range_with_movable_reference<const View>
    {
        if constexpr(std::ranges::common_range<const View> && std::ranges::sized_range<const View>) {
            return iterator<true>(std::ranges::end(_base), std::ranges::distance(_base));
        }
        else {
            return sentinel<true>(std::ranges::end(_base));
        }
    }

    constexpr auto size()
        requires std::ranges::sized_range<View>
    {
        return std::ranges::size(_base);
    }

    constexpr auto size() const
        requires std::ranges::sized_range<const View>
    {
        return std::ranges::size(_base);
    }

    constexpr View base() const &
        requires std::copy_constructible<View>
    {
        return _base;
    }

    constexpr View base() && { return std::move(_base); }
};


template<class Range>
enumerate_view(Range&& ) -> enumerate_view<std::views::all_t<Range>>;


template<std::ranges::view View>
    requires internal::range_with_movable_reference<View>
template<bool Const>
class enumerate_view<View>::iterator {
    using Base = internal::maybe_const_t<Const, View>;
    friend enumerate_view;

  public:
    using iterator_category = std::iterator_traits<std::ranges::iterator_t<Base>>::iterator_category;

    using iterator_concept = internal::most_primitive_iterator_concept<Const, View>;
    using difference_type = std::ranges::range_difference_t<Base>;
    using value_type = std::tuple<difference_type, std::ranges::range_value_t<Base>>;

  private:
    using rangeeference_type = std::tuple<difference_type, std::ranges::range_reference_t<Base>>;

    std::ranges::iterator_t<Base> _current = std::ranges::iterator_t<Base>();
    difference_type _pos = 0;

    constexpr explicit iterator(std::ranges::iterator_t<Base> current, const difference_type pos)
      : _current(std::move(current)), _pos(pos)
    {}

  public:
    iterator()
        requires std::default_initializable<std::ranges::iterator_t<Base>>
    = default;

    constexpr iterator(iterator<!Const> itr)
        requires Const && std::convertible_to<std::ranges::iterator_t<View>, std::ranges::iterator_t<Base>>
      : _current(std::move(itr._current)), _pos(itr._pos)
    {}

    constexpr const std::ranges::iterator_t<Base>& base() const & noexcept {
        return this->_current;
    }

    constexpr std::ranges::iterator_t<Base> base() && { return std::move(this->_current); }

    constexpr difference_type index() const noexcept { return this->_pos; }

    constexpr auto operator*() const {
        return rangeeference_type(this->_pos, *this->_current);
    }

    constexpr iterator& operator++() {
        ++this->_current;
        ++this->_pos;
        return *this;
    }

    constexpr void operator++(int) { ++*this; }

    constexpr iterator operator++(int)
        requires std::ranges::forward_range<Base>
    {
        auto temp = *this;
        ++*this;
        return temp;
    }

    constexpr iterator& operator--()
        requires std::ranges::bidirectional_range<Base>
    {
        --this->_current;
        --this->_pos;
        return *this;
    }

    constexpr iterator operator--(int)
        requires std::ranges::bidirectional_range<Base>
    {
        auto temp = *this;
        --*this;
        return temp;
    }

    constexpr iterator& operator+=(const difference_type diff)
        requires std::ranges::random_access_range<Base>
    {
        this->_current += diff;
        this->_pos += diff;
        return *this;
    }

    constexpr iterator& operator-=(const difference_type diff)
        requires std::ranges::random_access_range<Base>
    {
        this->_current -= diff;
        this->_pos -= diff;
        return *this;
    }

    constexpr auto operator[](const difference_type diff) const
        requires std::ranges::random_access_range<Base>
    {
        return rangeeference_type(this->_pos + diff, this->_current[diff]);
    }

    friend constexpr bool operator==(const iterator& lhs, const iterator& rhs) noexcept {
        return lhs._pos == rhs._pos;
    }

    friend constexpr std::strong_ordering
    operator<=>(const iterator& lhs, const iterator& rhs) noexcept {
        return lhs._pos <=> rhs._pos;
    }

    friend constexpr iterator operator+(iterator lhs, const difference_type rhs)
        requires std::ranges::random_access_range<Base>
    {
        return (lhs += rhs);
    }

    friend constexpr iterator operator+(const difference_type lhs, const iterator& rhs)
        requires std::ranges::random_access_range<Base>
    {
        return rhs += lhs;
    }

    friend constexpr iterator operator-(iterator& lhs, const difference_type rhs)
        requires std::ranges::random_access_range<Base>
    {
        return lhs -= rhs;
    }

    friend constexpr difference_type operator-(const iterator& lhs, const iterator& rhs) {
        return lhs._pos - rhs._pos;
    }

    friend constexpr auto iter_move(const iterator& itr)
        noexcept(
            noexcept (std::ranges::iter_move(itr._current)) &&
            std::is_nothrow_move_constructible_v<std::ranges::range_rvalue_reference_t<Base>>
        )
    {
            return std::tuple<difference_type, std::ranges::range_rvalue_reference_t<Base>>(
                itr._pos, std::ranges::iter_move(itr._current)
            );
    }
};

template<std::ranges::view View>
    requires internal::range_with_movable_reference<View>
template<bool Const>
class enumerate_view<View>::sentinel {
    using Base = internal::maybe_const_t<Const, View>;

    std::ranges::sentinel_t<Base> _end = std::ranges::sentinel_t<Base>();

    constexpr explicit sentinel(std::ranges::sentinel_t<Base> end) : _end(std::move(end)) {}

    friend enumerate_view;

  public:
    sentinel() = default;

    constexpr sentinel(sentinel<!Const> other)
        requires Const && std::convertible_to<std::ranges::sentinel_t<View>, std::ranges::sentinel_t<Base>>
        : _end(std::move(other._end)) {}

    constexpr std::ranges::sentinel_t<Base> base() const { return this->_end; }

    template<bool Const_>
        requires
            std::sentinel_for<
                std::ranges::sentinel_t<Base>, std::ranges::iterator_t<internal::maybe_const_t<Const_, View>>
            >
    friend constexpr bool operator==(const iterator<Const_>& lhs, const sentinel& rhs) {
        return lhs._current == rhs._end;
    }

    template<bool Const_>
        requires
            std::sized_sentinel_for<
                std::ranges::sentinel_t<Base>, std::ranges::iterator_t<internal::maybe_const_t<Const_, View>>
            >
    friend constexpr std::ranges::range_difference_t<internal::maybe_const_t<Const_, View>>
    operator-(const iterator<Const_>& lhs, const sentinel& rhs) {
        return lhs._current - rhs._end;
    }

    template<bool Const_>
        requires std::sized_sentinel_for<
            std::ranges::sentinel_t<Base>, std::ranges::iterator_t<internal::maybe_const_t<Const_, View>>>
    friend constexpr std::ranges::range_difference_t<internal::maybe_const_t<Const_, View>>
    operator-(const sentinel& lhs, const iterator<Const_>& rhs) {
        return lhs._end - rhs._current;
    }
};


namespace views {

namespace internal {


template<class T>
concept can_enumerate_view =
    requires { enumerate_view<std::views::all_t<T>>(std::declval<T>()); };


} // namespace internal


struct Enumerate : adaptor::range_adaptor_closure<Enumerate> {
    template<std::ranges::viewable_range Range>
        requires internal::can_enumerate_view<Range>
    constexpr auto operator() [[nodiscard]] (Range&& range) const {
        return enumerate_view<std::views::all_t<Range>>(std::forward<Range>(range));
    }
};


inline constexpr Enumerate enumerate;


} // namespace views

} // namespace uni


namespace std::ranges {


template<class T>
inline constexpr bool enable_borrowed_range<uni::enumerate_view<T>> = enable_borrowed_range<T>;


} // namespace std
#line 18 "graph/reachability_test.hpp"


namespace uni {


template<class Graph>
template<std::ranges::sized_range R>
auto uni::internal::graph_impl::mixin<Graph>::test_reachability(R&& queries) const noexcept(NO_EXCEPT) {
    using impl_type = u128;
    constexpr auto CHUNK_SIZE = std::numeric_limits<impl_type>::digits;

    std::vector<bool> res(std::ranges::size(queries));

    uni::vector<node_type> vs;
    this->sort_topologically(&vs);

    debug(queries);

    ITR(i, qs, queries | uni::views::chunk(CHUNK_SIZE) | uni::views::enumerate) {
        debug(qs);
        std::vector<impl_type> bits(this->size());

        ITR(j, p, qs | uni::views::enumerate) {
            bits[p.first] = uni::set_bit(bits[p.first], j);
        }

        ITR(v, vs) ITR(nv, this->operator[](v)) {
            bits[nv] |= bits[v];
        }

        ITR(j, p, qs | uni::views::enumerate) {
            res[i * CHUNK_SIZE + j] = uni::bit(bits[p.second], j);
        }
    }

    return res;
}


} // namespace uni
#line 2 "graph/shortest_path.hpp"


#line 5 "graph/shortest_path.hpp"


#line 2 "graph/internal/bfs.hpp"


#line 6 "graph/internal/bfs.hpp"

#line 9 "graph/internal/bfs.hpp"

#line 11 "graph/internal/bfs.hpp"

#line 14 "graph/internal/bfs.hpp"

#line 17 "graph/internal/bfs.hpp"


template<class Graph>
template<uni::internal::item_or_convertible_range<typename Graph::node_type> Source, class Dist, class Prev>
void uni::internal::graph_impl::mixin<Graph>::shortest_path_without_cost(
    Source&& s, Dist *const dist, Prev *const prev,
    const node_type& unreachable, const node_type& root
) const noexcept(NO_EXCEPT) {
    dist->assign(this->size(), uni::numeric_limits<cost_type>::arithmetic_infinity());
    if constexpr(!std::is_same_v<Prev, std::nullptr_t>) prev->assign(this->size(), unreachable);

    std::queue<node_type> que;

    if constexpr(std::ranges::range<Source>) {
        ITR(v, s) {
            que.push(v), dist->operator[](v) = 0;
            if constexpr(!std::is_same_v<Prev, std::nullptr_t>) prev->operator[](v) = root;
        }
    }
    else {
        que.push(s), dist->operator[](s) = 0;
        if constexpr(!std::is_same_v<Prev, std::nullptr_t>) prev->operator[](s) = root;
    }

    while(!que.empty()) {
        const node_type v = que.front(); que.pop();
        ITR(nv, this->operator[](v)) {
            if(dist->operator[](nv.to) < uni::numeric_limits<cost_type>::arithmetic_infinity()) { continue; }

            dist->operator[](nv.to) = dist->operator[](v) + 1;
            if constexpr(!std::is_same_v<Prev, std::nullptr_t>) prev->operator[](nv.to) = v;

            que.push(nv.to);
        }
    }
}

template<class Graph>
template<uni::internal::item_or_convertible_range<typename Graph::node_type> Source>
auto uni::internal::graph_impl::mixin<Graph>::shortest_path_without_cost(Source&& s) const noexcept(NO_EXCEPT) {
    uni::auto_holder<node_type, cost_type> dist;
    this->shortest_path_without_cost(std::forward<Source>(s), &dist);
    return dist;
}
#line 2 "graph/internal/01bfs.hpp"


#line 7 "graph/internal/01bfs.hpp"

#line 9 "graph/internal/01bfs.hpp"

#line 12 "graph/internal/01bfs.hpp"

#line 15 "graph/internal/01bfs.hpp"

#line 18 "graph/internal/01bfs.hpp"


template<class Graph>
template<uni::internal::item_or_convertible_range<typename Graph::node_type> Source, class Dist, class Prev>
void uni::internal::graph_impl::mixin<Graph>::shortest_path_with_01cost(
    Source&& s, Dist *const dist, Prev *const prev,
    const node_type& unreachable, const node_type& root
) const noexcept(NO_EXCEPT) {
    std::deque<node_type> que;

    dist->assign(this->size(), uni::numeric_limits<cost_type>::arithmetic_infinity());
    if constexpr(!std::is_same_v<Prev, std::nullptr_t>) prev->assign(this->size(), unreachable);

    if constexpr(std::ranges::range<Source>) {
        ITR(v, s) {
            que.push_back(v), dist->operator[](v) = 0;
            if constexpr(!std::is_same_v<Prev, std::nullptr_t>) prev->operator[](v) = root;
        }
    }
    else {
        que.push_back(s), dist->operator[](s) = 0;
        if constexpr(!std::is_same_v<Prev, std::nullptr_t>) prev->operator[](s) = root;
    }

    while(!que.empty()) {
        const auto u = que.front(); que.pop_front();
        const cost_type d = dist->operator[](u);

        ITR(e, (*this)[u]) {
            const node_type v = e.to; const auto cost = e.cost;

            if(dist->operator[](v) <= d + cost) continue;

            dist->operator[](v) = d + cost;
            if constexpr(!std::is_same_v<Prev, std::nullptr_t>) prev->operator[](v) = u;

            if(cost) que.push_back(v);
            else que.push_front(v);
        }
    }
}

template<class Graph>
template<uni::internal::item_or_convertible_range<typename Graph::node_type> Source>
auto uni::internal::graph_impl::mixin<Graph>::shortest_path_with_01cost(Source&& s) const noexcept(NO_EXCEPT) {
    uni::auto_holder<typename uni::internal::graph_impl::mixin<Graph>::node_type, cost_type> dist;
    this->shortest_path_with_01cost(std::forward<Source>(s), &dist);
    return dist;
}
#line 2 "graph/internal/dijkstra.hpp"


#line 7 "graph/internal/dijkstra.hpp"

#line 9 "graph/internal/dijkstra.hpp"

#line 11 "graph/internal/dijkstra.hpp"

#line 13 "graph/internal/dijkstra.hpp"

#line 16 "graph/internal/dijkstra.hpp"


template<class Graph>
template<uni::internal::item_or_convertible_range<typename Graph::node_type> Source, class Dist, class Prev>
void uni::internal::graph_impl::mixin<Graph>::shortest_path_with_cost(
    Source&& s, Dist *const dist, Prev *const prev,
    const node_type& unreachable, const node_type& root
) const noexcept(NO_EXCEPT) {
    using state = std::pair<cost_type, node_type>;
    std::priority_queue<state, std::vector<state>, std::greater<state>> que;

    dist->assign(this->size(), uni::numeric_limits<cost_type>::arithmetic_infinity());
    if constexpr(!std::same_as<Prev, std::nullptr_t>) prev->assign(this->size(), unreachable);

    if constexpr(std::ranges::range<Source>) {
        ITR(v, s) {
            que.emplace(0, v), dist->operator[](v) = 0;
            if constexpr(!std::is_same_v<Prev, std::nullptr_t>) prev->operator[](v) = root;
        }
    }
    else {
        que.emplace(0, s), dist->operator[](s) = 0;
        if constexpr(!std::is_same_v<Prev, std::nullptr_t>) prev->operator[](s) = root;
    }

    while(!que.empty()) {
        const auto [d, u] = que.top(); que.pop();

        if(dist->operator[](u) < d) continue;

        ITR(e, this->operator[](u)) {
            const node_type v = e.to; const auto next = d + e.cost;

            if(dist->operator[](v) <= next) continue;

            dist->operator[](v) = next;
            if constexpr(!std::same_as<Prev, std::nullptr_t>) prev->operator[](v) = u;

            que.emplace(dist->operator[](v), v);
        }
    }
}

template<class Graph>
template<uni::internal::item_or_convertible_range<typename Graph::node_type> Source>
auto uni::internal::graph_impl::mixin<Graph>::shortest_path_with_cost(Source&& s) const noexcept(NO_EXCEPT) {
    uni::auto_holder<node_type, cost_type> dist;
    this->shortest_path_with_cost(std::forward<Source>(s), &dist);
    return dist;
}
#line 10 "graph/shortest_path.hpp"

#line 12 "graph/shortest_path.hpp"


namespace uni {


template<class Node, class Prev, class Res>
void restore_path(Node back, const Prev& prev, Res *const res) {
    res->clear();
    while(back >= 0) {
        res->emplace_back(back);
        back = prev[back];
    }

    std::ranges::reverse(*res);
}


template<class Node, class Prev, class Res = uni::vector<Node>>
uni::vector<Node> restore_path(Node back, const Prev& prev) {
    uni::vector<Node> res;
    restore_path(back, prev, &res);
    return res;
}


}
#line 2 "graph/tree_diamiter.hpp"


#line 6 "graph/tree_diamiter.hpp"

#line 8 "graph/tree_diamiter.hpp"


namespace uni {

namespace internal {


template<class Graph>
std::pair<typename Graph::cost_type, typename Graph::node_type> farthest(const Graph& tree, const typename Graph::node_type v, const typename Graph::node_type p, std::vector<typename Graph::node_type> *const prev = nullptr) {
    std::pair<typename Graph::cost_type, typename Graph::node_type> res = { 0, v };

    for(auto nv : tree[v]) {
        if(nv.to == p) continue;

        auto next = farthest(tree, nv.to, v, prev);
        next.first += nv.cost;

        if(res.first < next.first) {
            if(prev) prev->operator[](nv.to) = v;
            res = next;
        }
    }

    return res;
}


} // namespace internal


template<class Graph>
auto tree_diamiter(const Graph& tree, std::vector<typename Graph::node_type> *const prev = nullptr) {
    const auto p = farthest(tree, 0, -1);
    return farthest(tree, p.second, -1, prev);
}



} // namespace uni
#line 2 "graph/tree_hash.hpp"


#line 6 "graph/tree_hash.hpp"

#line 9 "graph/tree_hash.hpp"


namespace uni {


template<class Graph>
auto tree_centers(const Graph& tree) {
    std::vector<typename Graph::node_type> prev(std::ranges::size(tree), -1);
    auto [ diam, v ] = tree_diamiter(tree, &prev);

    std::vector<typename Graph::node_type> res;

    {
        for(typename Graph::size_type i = 0; i < diam / 2; ++i) {
            v = prev[v];
        }
        res.push_back(v);
        if(diam % 2 == 1) res.push_back(prev[v]);
    }

    {
        auto rest = std::ranges::unique(res);
        res.erase(std::ranges::begin(rest), std::ranges::end(rest));
    }

    return std::make_pair(diam, res);
}


template<class Graph>
std::size_t tree_hash(const Graph& tree, typename Graph::node_type v, typename Graph::node_type p = -1) {
    static std::map<std::vector<typename Graph::node_type>, std::size_t> vals;

    std::vector<typename Graph::node_type> children;

    for(const auto nv : tree[v]) {
        if(nv == p) continue;
        children.emplace_back(tree_hash(tree, nv, v));
    }

    std::ranges::sort(children);

    if(!vals.contains(children)) {
        vals[children] = 0;
        vals[children] = std::ranges::size(vals);
    }

    return vals[children];
}


} // namespace uni
#line 2 "include/hashes.hpp"

#line 2 "hash/multiset_hasher.hpp"


#line 5 "hash/multiset_hasher.hpp"


#line 8 "hash/multiset_hasher.hpp"

#line 11 "hash/multiset_hasher.hpp"

#line 13 "hash/multiset_hasher.hpp"

#line 15 "hash/multiset_hasher.hpp"


namespace uni {


template<class T, std::uint64_t MOD = 0x1fffffffffffffff, int hasher_id = -1>
    requires (MOD < std::numeric_limits<std::make_signed_t<std::uint64_t>>::max())
struct multiset_hasher {
  private:
    using uint128_t = internal::uint128_t;

  public:
    using hash_type = std::uint64_t;
    using size_type = std::uint64_t;

    static constexpr hash_type mod = MOD;

  protected:
    static inline hash_type _id(const T& v) noexcept(NO_EXCEPT) {
        return uni::hash64(v);
    }

    static constexpr hash_type mask(const size_type a) noexcept(NO_EXCEPT) { return (1ULL << a) - 1; }

    static constexpr hash_type mul(hash_type a, hash_type b) noexcept(NO_EXCEPT) {
        #ifdef __SIZEOF_INT128__

        uint128_t res = static_cast<uint128_t>(a) * b;

        #else

        hash_type a31 = a >> 31, b31 = b >> 31;
        a &= multiset_hasher::mask(31);
        b &= multiset_hasher::mask(31);
        hash_type x = a * b31 + b * a31;
        hash_type res = (a31 * b31 << 1) + (x >> 30) + ((x & multiset_hasher::mask(30)) << 31) + a * b;

        #endif

        res = (res >> 61) + (res & multiset_hasher::mod);
        if(res >= multiset_hasher::mod) res -= multiset_hasher::mod;

        return res;
    }

    hash_type _hash = 0;

    inline void _add_hash(const hash_type h, const hash_type count) noexcept(NO_EXCEPT) {
        this->_hash += multiset_hasher::mul(h, count);
        if(this->_hash >= multiset_hasher::mod) this->_hash -= multiset_hasher::mod;
    }
    inline void _remove_hash(const hash_type h, const hash_type count) noexcept(NO_EXCEPT) {
        auto hash = to_signed(this->_hash);
        hash -= multiset_hasher::mul(h, count);
        if(hash < 0) hash += multiset_hasher::mod;
        this->_hash = hash;
    }

  public:
    multiset_hasher() noexcept(NO_EXCEPT) {}

    template<std::input_iterator I, std::sentinel_for<I> S>
    multiset_hasher(I first, S last) noexcept(NO_EXCEPT) : multiset_hasher() {
        for(auto itr=first; itr != last; ++itr) this->insert(*itr);
    }

    template<class U>
    multiset_hasher(const std::initializer_list<U>& init_list) noexcept(NO_EXCEPT) : multiset_hasher(std::begin(init_list), std::end(init_list)) {}

    inline size_type empty() const noexcept(NO_EXCEPT) { return this->get() == 0; }
    inline void clear() noexcept(NO_EXCEPT) { this->_hash = 0; }

    // return: whether inserted newly
    inline void insert(const T& v, size_type count = 1) noexcept(NO_EXCEPT) {
        this->_add_hash(multiset_hasher::_id(v), count);
    }

    // return: iterator of next element erased
    inline void erase(const T& v, const size_type count = 1) noexcept(NO_EXCEPT) {
        this->_remove_hash(multiset_hasher::_id(v), count);
    }

    inline hash_type get() const noexcept(NO_EXCEPT) { return this->_hash; }
    inline hash_type operator()() const noexcept(NO_EXCEPT) { return this->_hash; }

    inline bool operator==(const multiset_hasher& other) const noexcept(NO_EXCEPT) { return this->_hash == other._hash; }
    inline bool operator!=(const multiset_hasher& other) const noexcept(NO_EXCEPT) { return this->_hash != other._hash; }
};


} // namespace uni
#line 2 "hash/sequence_hasher.hpp"


#line 6 "hash/sequence_hasher.hpp"
#include <chrono>
#line 11 "hash/sequence_hasher.hpp"


#line 15 "hash/sequence_hasher.hpp"

#line 18 "hash/sequence_hasher.hpp"

#line 20 "hash/sequence_hasher.hpp"

#line 22 "hash/sequence_hasher.hpp"


namespace uni {


// Thanks to: https://github.com/tatyam-prime/kyopro_library/blob/master/RollingHash.cpp
template<std::uint64_t MOD = 0x1fffffffffffffff, std::uint64_t BASE = 0>
struct sequence_hasher {
  private:
    using uint64_t = std::uint64_t;
    using uint128_t = internal::uint128_t;

  public:
    using size_type = internal::size_t;
    using hash_type = uint64_t;

    static constexpr hash_type mod = MOD;
    inline static hash_type base;

  private:
    size_type _n = 0, _front = 0;
    std::vector<hash_type> _hashed;
    inline static std::vector<hash_type> _powers;

  protected:
    static inline hash_type power(const size_type p) noexcept(NO_EXCEPT) {
        if(static_cast<size_type>(sequence_hasher::_powers.size()) <= p) {
            size_type n = static_cast<size_type>(sequence_hasher::_powers.size());
            sequence_hasher::_powers.resize(p + 1);
            if(n == 0) sequence_hasher::_powers[0] = 1;
            REP(i, std::max(size_type{ 0 }, n-1), p) sequence_hasher::_powers[i + 1] = sequence_hasher::mul(sequence_hasher::_powers[i], sequence_hasher::base);
        }
        return sequence_hasher::_powers[p];
    }

    inline hash_type& hashed(const size_type p) noexcept(NO_EXCEPT) {
        if(static_cast<size_type>(this->_hashed.size()) <= p) this->_hashed.resize(p + 1);
        return this->_hashed[p];
    }
    inline const hash_type& hashed(const size_type p) const noexcept(NO_EXCEPT) { return this->_hashed[p]; }

    static constexpr hash_type mask(const size_type a) noexcept(NO_EXCEPT) { return (1ULL << a) - 1; }

    static constexpr hash_type mul(hash_type a, hash_type b) noexcept(NO_EXCEPT) {
        #ifdef __SIZEOF_INT128__

        uint128_t res = static_cast<uint128_t>(a) * b;

        #else

        hash_type a31 = a >> 31, b31 = b >> 31;
        a &= sequence_hasher::mask(31);
        b &= sequence_hasher::mask(31);
        hash_type x = a * b31 + b * a31;
        hash_type res = (a31 * b31 << 1) + (x >> 30) + ((x & sequence_hasher::mask(30)) << 31) + a * b;

        #endif

        if constexpr(sequence_hasher::mod == 0x1fffffffffffffff) {
            res = (res >> 61) + (res & sequence_hasher::mod);
            if(res >= sequence_hasher::mod) res -= sequence_hasher::mod;
        }
        else {
            res %= sequence_hasher::mod;
        }

        return static_cast<hash_type>(res);
    }

    size_type index(size_type k) const noexcept(NO_EXCEPT) { return this->_front + k; }

  public:
    struct hash {
      private:
        const hash_type _val;
        const size_type _len;

      public:
        hash(const hash_type val, const size_type len) noexcept(NO_EXCEPT) : _val(val), _len(len) {}

        inline hash_type val() const noexcept(NO_EXCEPT) { return this->_val; }
        inline operator hash_type() const noexcept(NO_EXCEPT) { return this->_val; }

        inline size_type size() const noexcept(NO_EXCEPT) { return this->_len; }

        inline bool operator==(const hash& other) const noexcept(NO_EXCEPT) { return this->_val == other._val and this->_len == other._len; }
        inline bool operator!=(const hash& other) const noexcept(NO_EXCEPT) { return this->_val != other._val or this->_len != other._len; }

        inline hash concat(const hash& other) const noexcept(NO_EXCEPT) { return sequence_hasher::concat(*this, other); }
        inline hash operator+(const hash& other) const noexcept(NO_EXCEPT) { return sequence_hasher::concat(*this, other); }
    };

    sequence_hasher(const size_type n = 0) noexcept(NO_EXCEPT) : _n(n) {
        if(sequence_hasher::base <= 0) {
            if constexpr(BASE == 0) {
                sequence_hasher::base = static_cast<hash_type>(uni::primitive_root<true>(sequence_hasher::mod));
            }
            else if constexpr(BASE < 0) {
                random_engine_64bit random(std::random_device{}());
                sequence_hasher::base = static_cast<hash_type>(random() % sequence_hasher::mod);
            }
            else {
                sequence_hasher::base = BASE;
            }
        }
    }

    template<std::input_iterator I, std::sentinel_for<I> S>
    sequence_hasher(I first, S last) noexcept(NO_EXCEPT) : sequence_hasher(static_cast<size_type>(std::ranges::distance(first, last))) {
        this->_hashed.resize(this->_n);
        this->_hashed.assign(this->_n + 1, 0);

        size_type i = 0;
        for(auto itr=first; itr!=last; ++i, ++itr) {
            this->hashed(i + 1) = sequence_hasher::mul(this->hashed(i), sequence_hasher::base) + *itr;
            if(this->hashed(i + 1) >= sequence_hasher::mod) this->hashed(i + 1) -= sequence_hasher::mod;
        }
    }

    template<std::ranges::input_range Range>
    sequence_hasher(Range&& ranges) noexcept(NO_EXCEPT) : sequence_hasher(ALL(ranges)) {}

    inline size_type size() const noexcept(NO_EXCEPT) { return this->_n - this->_front; }

    inline hash get(size_type l, size_type r) const noexcept(NO_EXCEPT) {
        assert(0 <= l and l <= r and r <= this->size());
        l = this->index(l), r = this->index(r);
        hash_type res = this->hashed(r) + sequence_hasher::mod - sequence_hasher::mul(this->hashed(l), sequence_hasher::power(r - l));
        if(res >= sequence_hasher::mod) res -= sequence_hasher::mod;

        return { res, r - l };
    }
    inline hash get() const noexcept(NO_EXCEPT) { return this->get(0, this->size()); }
    inline hash operator()(const size_type l, const size_type r) const noexcept(NO_EXCEPT) { return this->get(l, r); }

    inline hash subseq(const size_type p, const size_type c) const noexcept(NO_EXCEPT) { return this->get(p, p+c); }
    inline hash subseq(const size_type p) const noexcept(NO_EXCEPT) {  return this->get(p, this->size()); }


    static constexpr hash_type concat(const hash_type h0, const hash_type h1, const size_type len1) noexcept(NO_EXCEPT) {
        hash_type res = sequence_hasher::mul(h0, sequence_hasher::power(len1)) + h1;
        if(res >= sequence_hasher::mod) res -= sequence_hasher::mod;

        return res;
    }
    static constexpr hash concat(const hash& h0, const hash& h1) noexcept(NO_EXCEPT) {
        return { sequence_hasher::concat(h0.val(), h1.val(), h1.size()), h0.size() + h1.size() };
    }


    template<class T> inline sequence_hasher& push_back(const T& v) noexcept(NO_EXCEPT) {
        this->_n++;

        this->hashed(this->_n) = sequence_hasher::mul(this->hashed(this->_n-1), sequence_hasher::base) + hash32(v);
        if(this->hashed(this->_n) >= sequence_hasher::mod) this->hashed(this->_n-1) -= sequence_hasher::mod;

        return *this;
    }

    inline sequence_hasher& pop_back() noexcept(NO_EXCEPT) {
        assert(this->_n > 0);
        this->_n--;
        return *this;
    }

    inline sequence_hasher& pop_front() noexcept(NO_EXCEPT) {
        this->_front++;
        assert(this->_front <= this->_n);
        return *this;
    }


    template<std::input_iterator I, std::sentinel_for<I> S>
    inline sequence_hasher& concat(I first, S last) noexcept(NO_EXCEPT) {
        size_type n = this->_n;
        this->_n += std::ranges::distance(first, last);

        size_type i = n;
        for(auto itr=first; itr!=last; ++i, ++itr) {
            this->hashed(i + 1) = sequence_hasher::mul(this->hashed(i), sequence_hasher::base) + *itr;
            if(this->hashed(i + 1) >= sequence_hasher::mod) this->hashed(i + 1) -= sequence_hasher::mod;
        }

        return *this;
    }

    template<class T>inline sequence_hasher& concat(const T& v) noexcept(NO_EXCEPT) { return this->concat(ALL(v)); }

    inline size_type lcp(size_type l0, size_type r0, size_type l1, size_type r1) noexcept(NO_EXCEPT) {
        size_type size = std::min(r0 - l0, r1 - l1);
        size_type low = -1, high = size + 1;

        while(high - low > 1) {
            size_type mid = (low + high) / 2;
            if(this->get(l0, l0 + mid) == this->get(l1, l1 + mid)) low = mid;
            else high = mid;
        }

        return low;
    }
};


} // namespace uni
#line 2 "hash/set_hasher.hpp"


#line 7 "hash/set_hasher.hpp"


#line 10 "hash/set_hasher.hpp"

#line 12 "hash/set_hasher.hpp"


namespace uni {


template<class T, int hasher_id = -1, template<class...> class Set = std::unordered_set>
struct set_hasher : protected Set<T> {
  private:
    using base = Set<T>;

  public:
    using hash_type = std::uint64_t;
    using size_type = typename base::size_type;

  protected:
    hash_type _hash = 0;

    static inline hash_type id(const T& v) noexcept(NO_EXCEPT) {
        return hash64(v);
    }

  public:
    set_hasher() noexcept(NO_EXCEPT) {}

    template<std::input_iterator I, std::sentinel_for<I> S>
    set_hasher(I first, S last) noexcept(NO_EXCEPT) {
        for(auto itr=first; itr != last; ++itr) this->_insert(*itr);
    }

    template<class U>
    set_hasher(const std::initializer_list<U>& init_list) noexcept(NO_EXCEPT) : set_hasher(std::begin(init_list), std::end(init_list)) {}

    inline size_type empty() const noexcept(NO_EXCEPT) { return this->base::empty(); }
    inline size_type size() const noexcept(NO_EXCEPT) { return this->base::size(); }
    inline size_type max_size() const noexcept(NO_EXCEPT) { return this->base::max_size(); }

    inline void clear() noexcept(NO_EXCEPT) { this->_hash = 0, this->base::clear(); }

    using base::count;
    using base::find;
    using base::equal_range;

    inline auto begin() const noexcept(NO_EXCEPT) { return this->base::begin(); }
    inline auto end() const noexcept(NO_EXCEPT) { return this->base::end(); }

    template<class... Args> auto lower_bound(const Args&... args) const noexcept(NO_EXCEPT) { return this->base::lower_bound(args...); }
    template<class... Args> auto upper_bound(const Args&... args) const noexcept(NO_EXCEPT) { return this->base::upper_bound(args...); }

    // return: whether inserted newly
    inline bool insert(const T& v) noexcept(NO_EXCEPT) {
        if(this->base::count(v)) return false;
        this->base::insert(v);
        this->_hash ^= set_hasher::id(v);
        return true;
    }

    // return: number of erased elements (0 or 1)
    inline size_type erase(const T& v) noexcept(NO_EXCEPT) {
        if(not this->base::count(v)) return 0;
        this->base::erase(v);
        this->_hash ^= set_hasher::id(v);
        return 1;
    }

    inline hash_type get() const noexcept(NO_EXCEPT) { return this->_hash; }
    inline hash_type operator()() const noexcept(NO_EXCEPT) { return this->_hash; }

    inline bool operator==(const set_hasher& other) const noexcept(NO_EXCEPT) { return this->_hash == other._hash; }
    inline bool operator!=(const set_hasher& other) const noexcept(NO_EXCEPT) { return this->_hash != other._hash; }
};


} // namespace uni
#line 2 "include/iterable.hpp"

#line 2 "iterable/accumulation.hpp"


#line 11 "iterable/accumulation.hpp"


#line 14 "iterable/accumulation.hpp"

#line 17 "iterable/accumulation.hpp"

#line 19 "iterable/accumulation.hpp"


namespace uni {


template<class T, class Container = vector<T>>
struct accumulation : Container {
    using size_type = internal::size_t;

  protected:
    inline size_type _positivize_index(const size_type x) const noexcept(NO_EXCEPT) {
        return x < 0 ? std::size(*this) + x : x;
    }

  public:
    accumulation() noexcept(NO_EXCEPT) {}

    template<std::ranges::input_range R, class Operator = std::plus<T>>
        requires std::regular_invocable<Operator, T, T>
    explicit accumulation(R&& range, const T& head = T(), Operator&& op = std::plus<T>{})
      : accumulation(ALL(range), head, op)
    {}

    template<
        std::input_iterator I, std::sentinel_for<I> S,
        class Operator = std::plus<T>
    >
    accumulation(I first, S last, const T& head = T(), Operator&& op = std::plus<T>{}) noexcept(NO_EXCEPT) {
        this->resize(std::ranges::distance(first, last) + 1);
        *this->begin() = head;
        for(auto itr = std::ranges::begin(*this); first != last; ++first) {
            const auto prev = itr++;
            *itr = op(*prev, *first);
        }
    }

    template<class Operator = std::minus<T>>
        requires std::regular_invocable<Operator, T, T>
    T operator()(size_type left, size_type right, Operator&& op = std::minus<T>{}) noexcept(NO_EXCEPT) {
        left = _positivize_index(left), right = _positivize_index(right);
        assert(0 <= left and left <= right and right < (size_type)std::size(*this));
        return op((*this)[right], (*this)[left]);
    }

    template<class Operator = std::minus<T>>
        requires std::regular_invocable<Operator, T, T>
    T operator()(size_type left, size_type right, Operator&& op = std::minus<T>{}) const noexcept(NO_EXCEPT) {
        left = _positivize_index(left), right = _positivize_index(right);
        assert(0 <= left and left <= right and right < (size_type)std::size(*this));
        return op(this->at(right), this->at(left));
    }
};

template<std::input_iterator I, std::sentinel_for<I> S>
explicit accumulation(I, S) -> accumulation<typename std::iterator_traits<I>::value_type>;

template<std::ranges::input_range R>
explicit accumulation(R&&) -> accumulation<typename std::ranges::range_value_t<R>>;


template<class T, class Container = vector<vector<T>>, class Operator = std::plus<T>>
struct accumulation_2d : Container {
    using size_type = internal::size_t;

  protected:
    inline size_type _positivize_index(const size_type x) const noexcept(NO_EXCEPT) {
        return x < 0 ? std::size(*this) + x : x;
    }

    Operator _op;

  public:
    accumulation_2d() noexcept(NO_EXCEPT) {}

    template<std::ranges::input_range R>
        requires
            std::ranges::input_range<typename std::ranges::range_value_t<R>> &&
            std::regular_invocable<Operator, T, T>
    explicit accumulation_2d(R&& range, const T& head = T(), Operator&& op = std::plus<T>{})
      : accumulation_2d(ALL(range), head, op)
    {}

    template<std::input_iterator I, std::sentinel_for<I> S>
    accumulation_2d(I first, S last, const T head = T{}, const Operator op = std::plus<T>{}) noexcept(NO_EXCEPT) : _op(op) {
        const auto h = static_cast<size_type>(std::ranges::distance(first, last));
        const auto w = static_cast<size_type>(std::ranges::distance(ALL(*first)));
        {
            auto row = first;
            this->assign(h + 1, {});
            (*this)[0].assign(w + 1, head);
            REP(i, h) {
                assert(w == std::ranges::ssize(*row));
                (*this)[i + 1].assign(w + 1, head);
                REP(j, w) (*this)[i + 1][j + 1] = first[i][j];
                ++row;
            }
        }
        FOR(i, 1, h) FOR(j, w) (*this)[i][j] = op((*this)[i][j], (*this)[i - 1][j]);
        FOR(i, h) FOR(j, 1, w) (*this)[i][j] = op((*this)[i][j], (*this)[i][j - 1]);
    }

    template<class Rev = std::minus<T>>
    inline T operator()(size_type a, size_type b, size_type c, size_type d, const Rev rev = std::minus<T>{}) const noexcept(NO_EXCEPT) {
        a = _positivize_index(a), b = _positivize_index(b);
        c = _positivize_index(c), d = _positivize_index(d);
        assert(0 <= a and a <= b and b < (size_type)std::size(*this));
        assert(0 <= c and c <= d and d < (size_type)std::size((*this)[0]));
        return this->_op(rev((*this)[b][d], this->_op((*this)[a][d], (*this)[b][c])), (*this)[a][c]);
    }

    template<class Rev = std::minus<T>>
    inline T operator()(const std::pair<size_type,size_type> p, const std::pair<size_type,size_type> q, const Rev rev = std::minus<T>{}) const noexcept(NO_EXCEPT) {
        return this->operator()(p.first, p.second, q.first, q.second, rev);
    }
};

template<std::input_iterator I, std::sentinel_for<I> S>
explicit accumulation_2d(I, S) ->
    accumulation_2d<
        typename std::iterator_traits<typename std::ranges::iterator_t<typename std::iterator_traits<I>::value_type>>::value_type
    >;

template<std::input_iterator I, std::sentinel_for<I> S>
explicit accumulation_2d(I, S) ->
    accumulation_2d<
        typename std::iterator_traits<typename uni::internal::iterator_t<typename std::iterator_traits<I>::value_type>>::value_type
    >;

template<std::ranges::input_range R>
    requires std::ranges::input_range<typename std::ranges::range_value_t<R>>
explicit accumulation_2d(R&&) ->
    accumulation_2d<
        typename std::ranges::range_value_t<typename std::ranges::range_value_t<R>>
    >;


} // namespace uni
#line 2 "iterable/adjacent_difference.hpp"


#line 8 "iterable/adjacent_difference.hpp"

#line 11 "iterable/adjacent_difference.hpp"

#line 13 "iterable/adjacent_difference.hpp"


namespace uni {


template<class T, class container = valarray<T>>
struct adjacent_difference : container {
  public:
    explicit adjacent_difference() noexcept(NO_EXCEPT) {}

    template<
        std::input_iterator I, std::sentinel_for<I> S,
        class Operator = std::minus<T>
    >
    explicit adjacent_difference(I first, S last, const bool remove_first = true, const Operator op = std::minus<T>{}) noexcept(NO_EXCEPT) {
        this->resize(std::ranges::distance(first, last));
        std::vector<T> diff(this->size());
        std::adjacent_difference(first, last, std::ranges::begin(diff), op);
        if(remove_first) diff.erase(std::ranges::begin(diff));
        this->assign(std::ranges::begin(diff), std::ranges::end(diff));
    }
};

template<std::input_iterator I, std::sentinel_for<I> S>
explicit adjacent_difference(I, S) -> adjacent_difference<typename std::iterator_traits<I>::value_type>;


} // namespace uni
#line 2 "iterable/applied.hpp"


#line 8 "iterable/applied.hpp"

#line 10 "iterable/applied.hpp"

#line 12 "iterable/applied.hpp"


namespace uni {


template<std::ranges::range R, class F>
inline R applied(R v, F&& func) noexcept(NO_EXCEPT) {
    func(std::ranges::begin(v), std::ranges::end(v));
    return v;
}

template<std::ranges::range R>
inline auto sorted(R&& v) noexcept(NO_EXCEPT) {
    return applied(std::forward<R>(v), std::ranges::sort);
}

template<std::ranges::range R>
inline auto reversed(R&& v) noexcept(NO_EXCEPT) {
    return applied(std::forward<R>(v), std::ranges::reverse);
}


} // namespace uni
#line 2 "iterable/count_inversion.hpp"


#line 7 "iterable/count_inversion.hpp"

#line 9 "iterable/count_inversion.hpp"

#line 12 "iterable/count_inversion.hpp"

#line 14 "iterable/count_inversion.hpp"

#line 17 "iterable/count_inversion.hpp"

namespace uni {

template<const bool STRICT = true, class T = std::int64_t>
struct inversion {
    template<std::input_iterator I, std::sentinel_for<I> S>
    static inline T count(I first, S last) noexcept(NO_EXCEPT) {
        const internal::size_t n = std::distance(first, last);
        const auto [ min, max ] = std::minmax_element(first, last);
        const auto m = *max - *min + 1;

        fenwick_tree<actions::range_sum<T>> cnt(m);

        T res = 0;
        {
            internal::size_t i = 0;
            I itr = first;
            for(; i < n; ++i, ++itr) {
                res += cnt(*itr - *min + STRICT, m).fold().val();
                cnt[*itr - *min] += 1;
            }
        }

        return res;
    }

    template<std::ranges::input_range R>
    static inline T count(R&& range) noexcept(NO_EXCEPT) {
        return inversion::count(ALL(range));
    }

    template<std::input_iterator I, std::sentinel_for<I> S>
    static inline T count_with_compression(I first, S last) noexcept(NO_EXCEPT) {
        compressed<typename std::iterator_traits<I>::value_type> comp(first, last);
        return inversion::count(comp);
    }

    template<std::ranges::input_range R>
    static inline T count_with_compression(R&& range) noexcept(NO_EXCEPT) {
        return inversion::count_with_compression(ALL(range));
    }
};


} // namespace uni
#line 2 "iterable/counter.hpp"

#line 4 "iterable/counter.hpp"

#line 8 "iterable/counter.hpp"

#line 10 "iterable/counter.hpp"


namespace uni {


template<class T, class Container = dynamic_auto_holder<T, internal::size_t>>
struct counter : Container {
    counter() noexcept(NO_EXCEPT) = default;

    template<std::input_iterator I, std::sentinel_for<I> S>
    counter(I first, S last) noexcept(NO_EXCEPT) {
        for(auto itr = first; itr != last; ++itr) ++(*this)[*itr];
    }

    template<std::ranges::input_range R>
    explicit counter(R&& range) noexcept(NO_EXCEPT) : counter(ALL(range)) {}
};


template<std::input_iterator I, std::sentinel_for<I> S>
explicit counter(I, S) -> counter<std::iter_value_t<I>>;

template<std::ranges::input_range R>
explicit counter(R) -> counter<std::ranges::range_value_t<R>>;


} // namespace uni
#line 2 "iterable/inverse.hpp"

#line 6 "iterable/inverse.hpp"

#line 10 "iterable/inverse.hpp"

#line 12 "iterable/inverse.hpp"

#line 14 "iterable/inverse.hpp"


namespace uni {


template<class T, class V = vector<internal::size_t>, class container = dynamic_auto_holder<T, V>>
struct inverse : container {
    explicit inverse() noexcept(NO_EXCEPT) {}

    template<std::ranges::input_range R>
    inverse(R&& range) noexcept(NO_EXCEPT) : inverse(std::ranges::begin(range), std::ranges::end(range)) {}

    template<std::input_iterator I, std::sentinel_for<I> S>
    inverse(I first, S last) noexcept(NO_EXCEPT) {
        typename V::value_type index = 0;
        for(auto itr = first; itr != last; ++itr, ++index) (*this)[*itr].emplace_back(index);
    }
};

template<std::input_iterator I, std::sentinel_for<I> S>
explicit inverse(I, S) -> inverse<typename std::iterator_traits<I>::value_type>;

template<std::ranges::input_range R>
explicit inverse(R&&) -> inverse<std::ranges::range_value_t<R>>;


} // namespace uni
#line 2 "iterable/longest_common_subsequence.hpp"


#line 7 "iterable/longest_common_subsequence.hpp"


#line 10 "iterable/longest_common_subsequence.hpp"

#line 13 "iterable/longest_common_subsequence.hpp"

#line 15 "iterable/longest_common_subsequence.hpp"


namespace uni {


template<class container = grid<internal::size_t>>
struct lcs_sizes : container {
    lcs_sizes() noexcept = default;

    template<std::ranges::input_range R0, std::ranges::input_range R1>
    lcs_sizes(R0&& r0, R1&& r1) noexcept(NO_EXCEPT) : container(ALL(r0), ALL(r1)) {}

    template<
        std::input_iterator I0, std::input_iterator I1,
        std::sentinel_for<I0> S0, std::sentinel_for<I1> S1
    >
    lcs_sizes(I0 first0, S0 last0, I1 first1, S1 last1) noexcept(NO_EXCEPT)
      : container(std::ranges::distance(first0, last0) + 1, std::ranges::distance(first1, last1) + 1)
    {
        internal::size_t pos0 = 0;
        for(auto itr0=first0; itr0!=last0; ++pos0, ++itr0) {
            internal::size_t pos1 = 0;
            for(auto itr1=first1; itr1!=last1; ++pos1, ++itr1) {
                if(*itr0 == *itr1) (*this)(pos0 + 1, pos1 + 1) = (*this)(pos0, pos1) + 1;
                else (*this)(pos0 + 1, pos1 + 1) = std::max((*this)(pos0 + 1, pos1), (*this)(pos0, pos1 + 1));
            }
        }
    }
};


} // namespace uni
#line 2 "iterable/longest_increasing_subsequence.hpp"


#line 6 "iterable/longest_increasing_subsequence.hpp"


#line 9 "iterable/longest_increasing_subsequence.hpp"

#line 12 "iterable/longest_increasing_subsequence.hpp"

#line 14 "iterable/longest_increasing_subsequence.hpp"

#line 16 "iterable/longest_increasing_subsequence.hpp"


namespace uni {


template<bool STRICT, class T, class container = vector<T>>
struct lis : container {
    using size_type = typename internal::size_t;

    std::vector<size_type> indices, positions;

    lis() noexcept = default;

    template<std::ranges::input_range R>
    explicit lis(R&& range) noexcept(NO_EXCEPT) : lis(ALL(range)) {}

    template<std::input_iterator I, std::sentinel_for<I> S>
    lis(I first, S last) noexcept(NO_EXCEPT) : positions(std::ranges::distance(first, last), -1) {
        this->reserve(std::ranges::distance(first, last));

        size_type pos = 0;
        for(auto itr=first; itr!=last; ++pos, ++itr) {
            typename container::iterator bound;

            if constexpr(STRICT) bound = std::ranges::lower_bound(*this, *itr);
            else bound = std::ranges::upper_bound(*this, *itr);

            this->positions[pos] = static_cast<size_type>(std::ranges::distance(std::ranges::begin(*this), bound));

            if(std::ranges::end(*this) == bound) this->emplace_back(*itr);
            else *bound = *itr;
        }

        size_type target = std::ranges::max(this->positions);

        for(size_type i = static_cast<size_type>(this->positions.size()); --i >= 0;){
            if(this->positions[i] == target) {
                this->operator[](target) = *(first + i);
                this->indices.emplace_back(i);
                --target;
            }
        }

        std::ranges::reverse(this->indices);
    }
};


} // namespace uni
#line 2 "iterable/run_length_encoding.hpp"


#line 8 "iterable/run_length_encoding.hpp"


#line 12 "iterable/run_length_encoding.hpp"

#line 14 "iterable/run_length_encoding.hpp"


namespace uni {

template<class T, class container = vector<std::pair<T,internal::size_t>>>
struct run_length : container {
    run_length() noexcept(NO_EXCEPT) = default;

    template<std::input_iterator I, std::sentinel_for<I> S>
    run_length(I first, S last) noexcept(NO_EXCEPT) {
        this->clear();
        typename container::value_type::second_type cnt = 0;
        for(I itr=first, prev=itr; itr!=last; ++itr) {
            if(*prev != *itr) this->emplace_back(*prev, cnt), cnt = 0;
            ++cnt;
            prev = itr;
        }
        this->emplace_back(*std::ranges::prev(last), cnt);
    }

    template<std::ranges::input_range R>
    explicit run_length(R&& range) : run_length(ALL(range)) {};
};

template<std::input_iterator I, std::sentinel_for<I> S>
run_length(I, S) -> run_length<std::iter_value_t<I>>;

template<std::ranges::input_range R>
explicit run_length(R&& range) -> run_length<std::ranges::range_value_t<R>>;


} // namespace uni
#line 2 "include/numeric.hpp"

#line 9 "include/numeric.hpp"

#line 2 "numeric/binomial_coefficient.hpp"


#line 6 "numeric/binomial_coefficient.hpp"


#line 9 "numeric/binomial_coefficient.hpp"


#line 13 "numeric/binomial_coefficient.hpp"

#line 18 "numeric/binomial_coefficient.hpp"


// Thanks to: https://nyaannyaan.github.io/library/modulo/arbitrary-mod-binomial.hpp
namespace uni {

namespace internal {


template<class T, class R = T, class Reduction = barrett_reduction_32bit>
    requires (std::numeric_limits<R>::digits > 30) || modint_family<R>
struct binomial_coefficient_prime_power_mod {
    using value_type = T;
    using mod_type = R;

    static constexpr i64 MOD_SUP = (i64{1} << 30) - 1;
    static constexpr u32 MAX_BUFFER_SIZE = 30'000'000;

  private:
    using self = binomial_coefficient_prime_power_mod;
    using reduction = Reduction;

    u32 _p, _q, _m;
    value_type _max;
    std::valarray<u32> _fact, _inv_fact, _inv;
    u32 _delta;
    barrett_reduction_32bit _barrett_m, _barrett_p;
    reduction _reduction_m;
    u32 _one;

    static constexpr std::pair<u32,u32> _factorize(u32 m) {
        for(u32 i=2; i*i<=m; ++i) {
            if(m % i == 0) {
                u32 cnt = 0;
                while(m % i == 0) m /= i, ++cnt;
                assert(m == 1);
                return { i, cnt };
            }
        }

        return { m, 1 };
    }

    void _init() {
        const u32 size = std::min(this->_m, static_cast<u32>(this->_max) + 1);
        assert(size < self::MAX_BUFFER_SIZE);

        this->_barrett_m = barrett_reduction_32bit(this->_m);
        this->_barrett_p = barrett_reduction_32bit(this->_p);
        this->_reduction_m = self::reduction(this->_m);

        this->_delta = this->_reduction_m.convert_raw((this->_p == 2 && this->_q >= 3) ? 1 : this->_m - 1);
        this->_one = this->_reduction_m.convert_raw(1);

        this->_fact.resize(size);
        this->_inv_fact.resize(size);
        this->_inv.resize(size);

        this->_fact[0] = this->_inv_fact[0] = this->_inv[0] = this->_one;
        this->_fact[1] = this->_inv_fact[1] = this->_inv[1] = this->_one;

        REP(i, 2, size) {
            if(this->_barrett_p.reduce(i) == 0) {
                this->_fact[i] = this->_fact[i - 1];
                this->_fact[i + 1] = this->_reduction_m.multiply(this->_fact[i - 1], this->_reduction_m.convert_raw(this->_barrett_m.reduce(i + 1)));
                ++i;
            }
            else {
                this->_fact[i] = this->_reduction_m.multiply(this->_fact[i - 1], this->_reduction_m.convert_raw(this->_barrett_m.reduce(i)));
            }
        }

        this->_inv_fact[size - 1] = this->_reduction_m.pow(this->_fact[size - 1], this->_m / this->_p * (this->_p - 1) - 1);

        REPD(i, 2, size - 1) {
            this->_inv_fact[i] = this->_reduction_m.multiply(this->_inv_fact[i + 1], this->_reduction_m.convert_raw(this->_barrett_m.reduce(i + 1)));
            if(this->_barrett_p.reduce(i) == 0) {
                this->_inv_fact[i - 1] = this->_inv_fact[i];
                --i;
            }
        }
    }

  public:
    binomial_coefficient_prime_power_mod() noexcept = default;

    explicit binomial_coefficient_prime_power_mod(const value_type max = 20'000'000) noexcept(NO_EXCEPT)
        requires (1 < mod_type::mod() && mod_type::mod() < self::MOD_SUP)
      : _m(mod_type::mod()), _max(max)
    {
        constexpr std::pair<u32,u32> pq = self::_factorize(mod_type::mod());
        std::tie(this->_p, this->_q) = pq;

        this->_init();
    }

    explicit binomial_coefficient_prime_power_mod(const mod_type p, mod_type q = 1, const value_type max = 20'000'000) noexcept(NO_EXCEPT)
        requires (not modint_family<mod_type>)
      : _p(static_cast<u32>(p)), _q(static_cast<u32>(q)), _max(max)
    {
        assert(1 < p && p < self::MOD_SUP);
        assert(0 < q);

        u64 m = 1;
        while(q--) {
            m *= this->_p;
            assert(m < MOD_SUP);
        }
        this->_m = static_cast<u32>(m);

        this->_init();
    }

    inline mod_type mod() const noexcept(NO_EXCEPT) { return this->_m; }

    mod_type lucus(value_type n, value_type r) const noexcept(NO_EXCEPT) {
        assert(0 <= n);
        assert(0 <= r);

        if(n < r) return 0;
        u32 res = this->_one;

        while(n > 0) {
            u32 n0, k0;
            std::tie(n, n0) = this->_barrett_p.divide(n);
            std::tie(r, k0) = this->_barrett_p.divide(r);
            if(n0 < k0) return 0;

            res = this->_reduction_m.multiply(res, this->_fact[n0]);
            res = this->_reduction_m.multiply(res, this->_reduction_m.multiply(this->_inv_fact[n0 - k0], this->_inv_fact[k0]));
        }

        return static_cast<mod_type>(this->_reduction_m.revert(res));
    }

    mod_type comb(value_type n, value_type r) const noexcept(NO_EXCEPT) {
        assert(0 <= n);
        assert(0 <= r);

        if(this->_q == 1) return this->lucus(n, r);
        if(n < r) return 0;

        value_type k = n - r;
        u32 e0 = 0, eq = 0, i = 0;
        u32 res = this->_one;

        while(n > 0) {
            res = this->_reduction_m.multiply(res, this->_fact[this->_barrett_m.reduce(n)]);
            res = this->_reduction_m.multiply(res, this->_inv_fact[this->_barrett_m.reduce(r)]);
            res = this->_reduction_m.multiply(res, this->_inv_fact[this->_barrett_m.reduce(k)]);

            n = this->_barrett_p.quotient(n);
            r = this->_barrett_p.quotient(r);
            k = this->_barrett_p.quotient(k);

            u32 eps = static_cast<u32>(n - r - k);
            e0 += eps;
            if(e0 >= this->_q) return 0;
            if(++i >= this->_q) eq += eps;
        }

        if(eq & 1) res = this->_reduction_m.multiply(res, this->_delta);
        res = this->_reduction_m.multiply(res, this->_reduction_m.pow(this->_reduction_m.convert_raw(this->_p), e0));

        return static_cast<mod_type>(this->_reduction_m.revert(res));
    }
};


} // namespace internal


using internal::binomial_coefficient_prime_power_mod;


// (md < 10^7 && N < 2^30) || (md < 2^30 && N < 2 * 10^7)
template<class T, class R = T>
    requires (std::numeric_limits<R>::digits > 30) || internal::modint_family<R>
struct binomial_coefficient {
    using value_type = T;
    using mod_type = R;

  private:
    template<class reduction = montgomery_reduction_32bit>
    using internal_binomial = internal::binomial_coefficient_prime_power_mod<value_type, long long, reduction>;

    u32 _mod;
    value_type _max;
    std::vector<u32> _mods;
    std::vector<internal_binomial<>> _internals;
    internal_binomial<binary_reduction_32bit> _internal_2p;

    void _init() noexcept(NO_EXCEPT) {
        u32 md = this->_mod;
        if(md == 1) return;

        assert((md < 20'000'000 && this->_max < (1 << 30)) || (md < (1 << 30) && this->_max < 30'000'000));

        assert(1 <= md);
        assert(md <= internal_binomial<>::MOD_SUP);

        for(u32 i=2; i*i<=md; ++i) {
            if(md % i == 0) {
                u32 j = 0, k = 1;
                while(md % i == 0) md /= i, ++j, k *= i;
                this->_mods.push_back(k);
                if(i == 2) {
                    this->_internal_2p = internal_binomial<binary_reduction_32bit>(2, j, this->_max);
                    this->_internals.emplace_back();
                }
                else {
                    this->_internals.emplace_back(i, j, this->_max);
                    assert(this->_mods.back() == this->_internals.back().mod());
                }
            }
        }
        if(md != 1) {
            this->_mods.push_back(static_cast<u32>(md));
            if(md == 2) this->_internal_2p = internal_binomial<binary_reduction_32bit>(2, 1, this->_max);
            else this->_internals.emplace_back(md, 1, this->_max);
        }
    }

  public:
    binomial_coefficient(const value_type max = 20'000'000) noexcept(NO_EXCEPT)
        requires internal::modint_family<mod_type>
      : _mod(static_cast<u32>(mod_type::mod())), _max(max)
    {
        this->_init();
    }

    binomial_coefficient(const mod_type mod, const value_type max = 20'000'000) noexcept(NO_EXCEPT)
        requires (not internal::modint_family<mod_type>)
      : _mod(static_cast<u32>(mod)), _max(max)
    {
        this->_init();
    }

    mod_type comb(const value_type n, const value_type r) const noexcept(NO_EXCEPT) {
        assert(n >= 0), assert(r >= 0);
        if(this->_mod == 1) return 0;
        if(n < r) return 0;

        if(this->_mods.size() == 1) {
            if((this->_mods.back() & 1) == 0) return static_cast<mod_type>(this->_internal_2p.comb(n, r));
            else return static_cast<mod_type>(this->_internals[0].comb(n, r));
        }

        std::vector<long long> rem, div;
        REP(i, 0, std::ranges::ssize(this->_mods)) {
            div.push_back(this->_mods[i]);
            if((this->_mods[i] & 1) == 0) rem.push_back(this->_internal_2p.comb(n, r));
            else {
                rem.push_back(this->_internals[i].comb(n, r));
            }
        }

        return static_cast<mod_type>(atcoder::crt(rem, div).first);
    }
};


} // namespace uni
#line 2 "numeric/boundary_seeker.hpp"


#line 8 "numeric/boundary_seeker.hpp"


#line 11 "numeric/boundary_seeker.hpp"

#line 14 "numeric/boundary_seeker.hpp"

#line 16 "numeric/boundary_seeker.hpp"


namespace uni {

namespace internal {

namespace boundary_seeker_impl {


template<class T>
struct integal {
  protected:
    std::function<bool(T)> _validate;

  public:
    integal(std::function<bool(T)> validate) noexcept(NO_EXCEPT) : _validate(validate) {}

    template<bool INVERT = false>
    T bound(const T _ok, const T _ng) const noexcept(NO_EXCEPT) {
        T ok = _ok, ng = _ng;
        if constexpr(INVERT) std::swap(ng, ok);

        while(std::abs(ok - ng) > 1) {
            T mid = ng + (ok - ng) / 2;
            (INVERT ^ this->_validate(mid) ? ok : ng) = mid;
        }

        return ok;
    }

    template<bool REVERSE = false, bool INVERT = false>
    T bound(const T ok) const noexcept(NO_EXCEPT) {
        assert(INVERT ^ this->_validate(ok));

        T ng = REVERSE ? -1 : 1;
        while(INVERT ^ this->_validate(ok + ng)) ng += ng;
        return this->bound<INVERT>(ok, ok + ng);
    }

    template<bool REVERSE = false, bool INVERT = false>
    T bound() const noexcept(NO_EXCEPT) {
        return this->bound<INVERT>(
            REVERSE ?
            numeric_limits<T>::arithmetic_infinity() / 2 :
            numeric_limits<T>::arithmetic_negative_infinity() / 2
        );
    }

    template<bool INVERT = false>
    T bound_or(const T ok, const T ng, const T proxy) const noexcept(NO_EXCEPT) {
        const T res = this->bound<INVERT>(ok, ng);
        return this->_validate(res) ? res : proxy;
    }

    template<bool REVERSE = false, bool INVERT = false>
    T bound_or(const T ok, const T proxy) const noexcept(NO_EXCEPT) {
        const T res = this->bound<REVERSE, INVERT>(ok);
        return this->_validate(res) ? res : proxy;
    }

    template<bool REVERSE = false, bool INVERT = false>
    T bound_or(const T proxy) const noexcept(NO_EXCEPT) {
        const T res = this->bound<REVERSE, INVERT>();
        return this->_validate(res) ? res : proxy;
    }
};

template<class T>
struct floating_point {
  protected:
    std::function<bool(T)> _validate;

  public:
    floating_point(std::function<bool(T)> validate) noexcept(NO_EXCEPT) : _validate(validate) {}

    template<bool INVERT = false, internal::size_t ITERATIONS = 200>
    T bound(const T _ok, const T _ng) const noexcept(NO_EXCEPT) {
        T ok = _ok, ng = _ng;
        if constexpr(INVERT) std::swap(ng, ok);

        REP(ITERATIONS) {
            T mid = ng + (ok - ng) / 2;
            (INVERT ^ this->_validate(mid) ? ok : ng) = mid;
        }
        return ok;
    }

    template<bool REVERSE = false, bool INVERT = false, internal::size_t ITERATIONS = 200>
    T bound(const T ok) const noexcept(NO_EXCEPT) {
        assert(INVERT ^ this->_validate(ok));

        T ng = REVERSE ? -1 : 1;
        while(INVERT ^ this->_validate(ok + ng)) ng += ng;
        return this->bound<INVERT>(ok, ok + ng);
    }

    template<bool REVERSE = false, bool INVERT = false, internal::size_t ITERATIONS = 200>
    T bound() const noexcept(NO_EXCEPT) {
        return this->bound<INVERT, ITERATIONS>(
            REVERSE ?
            numeric_limits<T>::arithmetic_infinity() / 2 :
            numeric_limits<T>::arithmetic_negative_infinity() / 2
        );
    }

    template<bool INVERT = false, internal::size_t ITERATIONS = 200>
    T bound_or(const T ok, const T ng, const T proxy) const noexcept(NO_EXCEPT) {
        const T res = this->bound<INVERT, ITERATIONS>(ok, ng);
        return this->_validate(res) ? res : proxy;
    }

    template<bool REVERSE = false, bool INVERT = false, internal::size_t ITERATIONS = 200>
    T bound_or(const T ok, const T proxy) const noexcept(NO_EXCEPT) {
        const T res = this->bound<REVERSE, INVERT, ITERATIONS>(ok);
        return this->_validate(res) ? res : proxy;
    }

    template<bool REVERSE = false, bool INVERT = false, internal::size_t ITERATIONS = 200>
    T bound_or(const T proxy) const noexcept(NO_EXCEPT) {
        const T res = this->bound<REVERSE, INVERT, ITERATIONS>();
        return this->_validate(res) ? res : proxy;
    }
};

template<class, bool>
struct seeker {};

template<class T>
struct seeker<T,true> : integal<T> {
    using integal<T>::integal;
};

template<class T>
struct seeker<T,false> : floating_point<T> {
    using floating_point<T>::floating_point;
};


} // namespace boundary_seeker_impl

} // namespace internal


template<class T>
using boundary_seeker = internal::boundary_seeker_impl::seeker<T,std::is_integral_v<T>>;


} // namespace uni
#line 2 "numeric/divisors.hpp"


#line 5 "numeric/divisors.hpp"

#line 8 "numeric/divisors.hpp"

namespace uni {


template<class T>
vector<T> divisors_sieve(const T k) noexcept(NO_EXCEPT) {
    vector<T> res;

    for(T i=1; i*i<=k; ++i) {
        if(k%i == 0) {
            res.emplace_back(i);
            if(i*i < k) res.emplace_back(k/i);
        }
    }

    res.sort();

    return res;
}


} // namespace uni
#line 2 "numeric/extremum_seeker.hpp"


#line 6 "numeric/extremum_seeker.hpp"


#line 10 "numeric/extremum_seeker.hpp"

#line 13 "numeric/extremum_seeker.hpp"

#line 15 "numeric/extremum_seeker.hpp"

#line 17 "numeric/extremum_seeker.hpp"


namespace uni {


template<class Signature>
struct extremum_seeker;


template<class T, std::floating_point Arg>
struct extremum_seeker<T(Arg)> {
    using value_type = T;
    using arg_type = Arg;

  private:
    std::function<T(Arg)> _f;


    template<const internal::size_t ITERATIONS>
    std::pair<arg_type, arg_type> search(arg_type low, arg_type high, const auto comp) const noexcept(NO_EXCEPT) {
        REP(ITERATIONS) {
            const auto p = low + (high - low) / 3;
            const auto q = high - (high - low) / 3;

            if(comp(p, q)) high = q;
            else low = p;
        }

        return { low, high };
    }

  public:
    template<class F>
        requires std::same_as<std::invoke_result_t<F, Arg>, T>
    extremum_seeker(F&& f) noexcept(NO_EXCEPT) : _f(std::forward<F>(f)) {};


    template<const internal::size_t ITERATIONS = 100'000>
    std::pair<arg_type, arg_type> arg_min(
        arg_type low = uni::numeric_limits<arg_type>::arithmetic_negative_infinity(),
        arg_type high = uni::numeric_limits<arg_type>::arithmetic_infinity()
    ) const noexcept(NO_EXCEPT) {
        const auto comp = [&](const arg_type lhs, const arg_type rhs) noexcept(NO_EXCEPT) {
            return this->_f(lhs) < this->_f(rhs);
        };
        return this->search<ITERATIONS>(low, high, comp);
    }

    template<const internal::size_t ITERATIONS = 100'000>
    std::pair<arg_type, arg_type> arg_max(
        arg_type low = uni::numeric_limits<arg_type>::arithmetic_negative_infinity(),
        arg_type high = uni::numeric_limits<arg_type>::arithmetic_infinity()
    ) const noexcept(NO_EXCEPT) {
        const auto comp = [&](const arg_type lhs, const arg_type rhs) noexcept(NO_EXCEPT) {
            return this->_f(lhs) > this->_f(rhs);
        };
        return this->search<ITERATIONS>(low, high, comp);
    }


    template<const internal::size_t ITERATIONS = 100'000>
    auto min(
        const arg_type _low = uni::numeric_limits<arg_type>::arithmetic_negative_infinity(),
        const arg_type _high = uni::numeric_limits<arg_type>::arithmetic_infinity()
    ) const noexcept(NO_EXCEPT) {
        const auto [ low, high ] = this->arg_min<ITERATIONS>(_low, _high);
        auto res = std::min(this->_f(low), this->_f(high));
        FOR(x, low, high) chmin(res, this->_f(x));
        return res;
    }

    template<const internal::size_t ITERATIONS = 100'000>
    auto max(
        const arg_type _low = uni::numeric_limits<arg_type>::arithmetic_negative_infinity(),
        const arg_type _high = uni::numeric_limits<arg_type>::arithmetic_infinity()
    ) const noexcept(NO_EXCEPT) {
        const auto [ low, high ] = this->arg_max<ITERATIONS>(_low, _high);
        auto res = std::max(this->_f(low), this->_f(high));
        FOR(x, low, high) chmax(res, this->_f(x));
        return res;
    }
};


template<class T, std::integral Arg>
struct extremum_seeker<T(Arg)> {
    using value_type = T;
    using arg_type = Arg;

  private:
    std::function<T(Arg)> _f;

    std::vector<arg_type> _fib = { 0, 1 };
    gnu::gp_hash_table<arg_type, value_type> _cache;


    auto _expand(const arg_type size) noexcept(NO_EXCEPT) {
        assert(size >= 0);
        this->_fib.reserve(std::bit_width(to_unsigned(size)));

        if(this->_fib.back() < size) {
            do {
                this->_fib.emplace_back(
                    this->_fib[std::ranges::size(this->_fib) - 1] +
                    this->_fib[std::ranges::size(this->_fib) - 2]
                );
            } while(this->_fib.back() < size);

            return std::ranges::prev(this->_fib.end());
        }

        return std::ranges::lower_bound(this->_fib, size);
    }

    auto _func(const arg_type size) noexcept(NO_EXCEPT) {
        if(this->_cache.contains(size)) return this->_cache[size];
        return this->_cache[size] = this->_f(size);
    }

    auto _search(arg_type low, const arg_type high, const auto comp) noexcept(NO_EXCEPT) {
        if(low == high) return low;

        auto _low = low - 1;
        const auto itr = this->_expand(high - _low + 1);
        auto _high = *itr + _low;
        auto diff = *std::ranges::prev(itr);

        while(true) {
            const auto p = _high - diff;
            const auto q = _low + diff;

            if(p == q) return p;

            if(comp(p, q)) _high = q;
            else _low = p;

            diff = diff - (q - p);
        }
    }

  public:
    template<class F>
        requires std::same_as<std::invoke_result_t<F, Arg>, T>
    extremum_seeker(F&& f, const arg_type init_size = 0) noexcept(NO_EXCEPT)
      : _f(std::forward<F>(f))
    {
        this->_expand(init_size);
    }


    auto arg_min(
        const arg_type low = uni::numeric_limits<arg_type>::arithmetic_negative_infinity(),
        const arg_type high = uni::numeric_limits<arg_type>::arithmetic_infinity()
    ) noexcept(NO_EXCEPT) {
        const auto comp = [&](const arg_type lhs, const arg_type rhs) noexcept(NO_EXCEPT) {
            if(high < rhs) return true;
            return this->_func(lhs) < this->_func(rhs);
        };
        return this->_search(low, high, comp);
    }

    auto arg_max(
        const arg_type low = uni::numeric_limits<arg_type>::arithmetic_negative_infinity(),
        const arg_type high = uni::numeric_limits<arg_type>::arithmetic_infinity()
    ) noexcept(NO_EXCEPT) {
        const auto comp = [&](const arg_type lhs, const arg_type rhs) noexcept(NO_EXCEPT) {
            if(high < rhs) return true;
            return this->_func(lhs) > this->_func(rhs);
        };
        return this->_search(low, high, comp);
    }


    inline auto min(
        const arg_type _low = uni::numeric_limits<arg_type>::arithmetic_negative_infinity(),
        const arg_type high = uni::numeric_limits<arg_type>::arithmetic_infinity()
    ) noexcept(NO_EXCEPT) {
        return this->_func(this->arg_min(_low, high));
    }

    inline auto max(
        const arg_type _low = uni::numeric_limits<arg_type>::arithmetic_negative_infinity(),
        const arg_type high = uni::numeric_limits<arg_type>::arithmetic_infinity()
    ) noexcept(NO_EXCEPT) {
        return this->_func(this->arg_max(_low, high));
    }
};


} // namespace uni
#line 2 "numeric/factorial.hpp"

#line 5 "numeric/factorial.hpp"

#line 7 "numeric/factorial.hpp"

#line 9 "numeric/factorial.hpp"

#line 11 "numeric/factorial.hpp"


namespace uni {


namespace internal {


template<class T>
struct factorial_base {
    using value_type = T;
    using size_type = internal::size_t;

    static constexpr value_type calc(const size_type& n) noexcept(NO_EXCEPT) {
        assert(n >= 0);
        value_type ans = 1;
        FOR(k, 1, n) ans *= k;
        return ans;
    }
};

} // namespace internal



template<class>
struct factorial {};


template<std::integral T>
struct factorial<T> : internal::factorial_base<T> {
    using value_type = T;
    using size_type = internal::size_t;

  private:
    size_type _n;
    std::valarray<value_type> _fact;

  public:
    factorial(const size_type n) noexcept(NO_EXCEPT) : _n(n), _fact(n + 1) {
        this->_fact[0] = this->_fact[1] = 1;
        FOR(i, 2, n) this->_fact[i] = this->_fact[i - 1] * i;
    }

    inline value_type fact(const size_type k) noexcept(NO_EXCEPT) {
        assert(0 <= k and k <= this->_n);
        return this->_fact[k];
    }
    inline value_type operator()(const size_type k) noexcept(NO_EXCEPT) {
        return this->fact(k);
    }

    auto _debug() const { return this->_fact; }
};


template<uni::internal::modint_family T>
struct factorial<T> : internal::factorial_base<T> {
    using value_type = T;
    using size_type = internal::size_t;

  private:
    size_type _n;
    std::valarray<value_type> _fact, _ifact, _inv;

  public:
    factorial(const size_type n) noexcept(NO_EXCEPT) : _n(n), _fact(n + 1), _ifact(n + 1), _inv(n + 1) {
        constexpr auto P = T::mod();

        this->_fact[0] = this->_fact[1] = 1;
        this->_ifact[0] = this->_ifact[1] = 1;
        this->_inv[1] = 1;

        FOR(i, 2, n) {
            this->_inv[i] = -this->_inv[P % i] * (P / i);

            this->_fact[i] = this->_fact[i - 1] * i;
            this->_ifact[i] = this->_ifact[i - 1] * this->_inv[i];
        }
    }

    inline value_type fact(const size_type k) noexcept(NO_EXCEPT) {
        assert(0 <= k and k <= this->_n);
        return this->_fact[k];
    }
    inline value_type operator()(const size_type k) noexcept(NO_EXCEPT) {
        return this->fact(k);
    }

    inline value_type ifact(const size_type k) noexcept(NO_EXCEPT) {
        assert(0 <= k and k <= this->_n);
        return this->_ifact[k];
    }

    inline value_type inv(const size_type k) noexcept(NO_EXCEPT) {
        assert(0 <= k and k <= this->_n);
        return this->_inv[k];
    }

    inline value_type bimom(const size_type n, const size_type r) noexcept(NO_EXCEPT) {
        assert(0 <= r and r <= n and n <= this->_n);
        return this->fact(n) * this->ifact(r) * this->ifact(n - r);
    }

    auto _debug() const { return this->_fact; }
};


} // namespace uni
#line 2 "numeric/hilbert_order.hpp"

#line 4 "numeric/hilbert_order.hpp"

template<class T> T hilbert_order(const T n, T i, T j) {
    T p, q, d = 0;
    for(T t=n>>1; t>0; t>>=1) {
        p = (i&t) > 0, q = (j&t) > 0;
        d += t * t * ((p * 3) ^ q);
        if(q > 0) continue;
        if(p > 0) {
            i = n - i - 1;
            j = n - j - 1;
        }
        std::swap(i, j);
    }
    return d;
}

template<class T> T hilbert_order(const T n,const std::pair<T,T> p) {
    return hilbert_order(n, p.first, p.second);
}
#line 2 "numeric/interval_scanner.hpp"

#line 2 "numeric/internal/two_pointer_technique.hpp"


#line 10 "numeric/internal/two_pointer_technique.hpp"

#line 12 "numeric/internal/two_pointer_technique.hpp"

#line 15 "numeric/internal/two_pointer_technique.hpp"


namespace uni {

namespace internal {

namespace interval_scanner_impl {


template<class T> using interval = std::pair<T, T>;
template<class T> using intervals = std::vector<std::pair<T, T>>;


template<class T>
struct base {
  protected:
    std::function<bool(T)> _validate;

  public:
    base(std::function<bool(T)> validate) : _validate(validate) {}

    void scan(T, T, T) {
        static_assert(internal::EXCEPTION_ON_TYPE<T>, "not implemented: scan()");
    }

    void split(const T first, const T last, intervals<T> *intervals) const {
        std::valarray<bool> _valid(false, last - first);
        for(auto itr=first,index=0; itr!=last; ++itr, ++index) _valid[index] = _validate(itr);

        auto can_begin = [&](const T itr) {
            const auto index = itr - first;
            if(itr == first) return _valid[index];
            if(itr == last) return false;
            if(not _valid[index-1] and _valid[index]) return true;
            return false;
        };

        auto is_end = [&](const T itr) {
            const  auto index = itr - first;
            if(itr == first) return false;
            if(itr == last) return _valid[index-1];
            if(_valid[index-1] and not _valid[index]) return true;
            return false;
        };

        {
            intervals->clear();
            T start = first;
            for(auto itr=first; ; ++itr) {
                if(can_begin(itr)) start = itr;
                if(is_end(itr)) intervals->emplace_back(start, itr);
                if(itr == last) break;
            }
        }
    }

    void scan_all(const T first, const T last) const {
        intervals<T> targets;
        this->split(first, last, &targets);
        ITR(start, end, targets) this->scan(first, start, end);
    }
};


} // namespace interval_scanner_impl

} // namespace internal


template<class T>
struct exclusive_interval_scanner : internal::interval_scanner_impl::base<T> {
  private:
    std::function<void(T)> _init;
    std::function<bool(T)> _can_expand;
    std::function<void(T)> _expand, _contract;
    std::function<void(T, T)> _apply;

  public:
    using interval = internal::interval_scanner_impl::interval<T>;
    using intervals = internal::interval_scanner_impl::intervals<T>;

    exclusive_interval_scanner(
        std::function<bool(T)> validate,
        std::function<void(T)> init,
        std::function<bool(T)> can_expand,
        std::function<void(T)> expand,
        std::function<void(T)> contract,
        std::function<void(T, T)> apply
    )
      : internal::interval_scanner_impl::base<T>(validate), _init(init), _can_expand(can_expand),
        _expand(expand), _contract(contract), _apply(apply)
    {}

    template<const bool FOLLOWING = true>
    void scan(const T start, const T end) const {
        T l_itr=start, r_itr=start;
        while(l_itr < end) {
            if (FOLLOWING and r_itr <= l_itr) {
                r_itr = l_itr+1;
                _init(l_itr);
            }
            while(r_itr < end && _can_expand(r_itr)) {
                _expand(r_itr++);
            }
            _apply(l_itr, r_itr);
            _contract(l_itr++);
        }
    };

    template<const bool FOLLOWING = true>
    void scan_all(const T first, const T last) const {
        intervals targets;
        this->split(first, last, &targets);
        ITR(start, end, targets) this->scan<FOLLOWING>(start, end);
    }
};


template<class T>
struct inclusive_interval_scanner : internal::interval_scanner_impl::base<T> {
  protected:
    std::function<void()> _init;
    std::function<bool()> _valid;
    std::function<void(T)> _expand, _contract;
    std::function<void(T, T)> _apply;

  public:
    using interval = internal::interval_scanner_impl::interval<T>;
    using intervals = internal::interval_scanner_impl::intervals<T>;

    inclusive_interval_scanner(
        std::function<bool(T)> validate,
        std::function<void()> init,
        std::function<bool()> valid,
        std::function<void(T)> expand,
        std::function<void(T)> contract,
        std::function<void(T, T)> apply
    ) : internal::interval_scanner_impl::base<T>(validate), _init(init), _valid(valid), _expand(expand), _contract(contract), _apply(apply) {}

    template<const bool INVERSE = false, const bool FOLLOWING = true, const bool CONFIRMATION = true>
    void scan(const T start, const T end) const {
        T l_itr = start, r_itr = start;
        _init();
        while(l_itr < end) {
            if(FOLLOWING and r_itr < l_itr) {
                r_itr = l_itr;
                _init();
            }
            if(r_itr < end and (INVERSE ^ _valid())) {
                _expand(r_itr++);
            }
            else {
                _contract(l_itr++);
            }
            if(!CONFIRMATION or _valid()) _apply(l_itr, r_itr);
        }
    }

    template<const bool INVERSE = false, const bool FOLLOWING = true, const bool CONFIRMATION = true>
    void scan_all(const T first, const T last) const {
        intervals targets;
        this->split(first, last, &targets);
        ITR(start, end, targets) this->scan<INVERSE,FOLLOWING,CONFIRMATION>(start, end);
    }
};


} // namespace uni
#line 2 "numeric/internal/mo.hpp"


#line 12 "numeric/internal/mo.hpp"


#line 16 "numeric/internal/mo.hpp"

#line 19 "numeric/internal/mo.hpp"

#line 22 "numeric/internal/mo.hpp"

#line 26 "numeric/internal/mo.hpp"


namespace uni {

template<class R, class EF, class PF, class EB = EF, class PB = PF>
class interval_plannner {
    using size_type = internal::size_t;

  public:
    EF _expand_front; EB _expand_back;
    PF _contract_front; PB _contract_back;
    R _evaluate;

    using evaluator_result_t = std::invoke_result_t<R>;

    interval_plannner(
        EF expand_front, EB expand_back,
        PF contract_front, PB contract_back,
        R evaluate
    ) noexcept(NO_EXCEPT)
      : _expand_front(expand_front), _expand_back(expand_back),
        _contract_front(contract_front), _contract_back(contract_back),
        _evaluate(evaluate)
    {}

    interval_plannner(EF expand, PF contract, R evaluate) noexcept(NO_EXCEPT)
      : interval_plannner(expand, expand, contract, contract, evaluate)
    {}


    template<
        std::input_iterator QI, std::sentinel_for<QI> QS,
        std::output_iterator<evaluator_result_t> RI
    >
    void scan(const QI query_first, const QS query_last, const RI res_first) noexcept(NO_EXCEPT) {
        const auto q = std::ranges::distance(query_first, query_last);

        size_type n = 0;
        for(auto query=query_first; query!=query_last; ++query) {
            chmax(n, std::ranges::max(query->first, query->second));
        }
        n = std::bit_ceil(uni::to_unsigned(n));

        std::vector<i64> orders(q);
        {
            auto query = query_first;
            auto order = orders.begin();
            for(; query!=query_last; ++query, ++order) {
                *order = hilbert_order<i64>(n, *query);
            }
        }

        std::vector<size_type> indices(q); std::iota(ALL(indices), 0);
        std::ranges::sort(
            indices,
            [&orders](const size_type i, const size_type j) { return orders[i] < orders[j]; }
        );

        size_type l = 0, r = 0;
        ITR(i, indices) {
            while(l > query_first[i].first) _expand_front(--l);
            while(r < query_first[i].second) _expand_back(r++);
            while(l < query_first[i].first) _contract_front(l++);
            while(r > query_first[i].second) _contract_back(--r);
            res_first[i] = _evaluate();
        }
    }

    template<std::input_iterator QI, std::sentinel_for<QI> QS>
    auto scan(const QI query_first, const QS query_last) noexcept(NO_EXCEPT) {
        valarray<evaluator_result_t> res(std::ranges::distance(query_first, query_last));
        this->scan(query_first, query_last, std::ranges::begin(res));
        return res;
    }

    template<std::ranges::input_range Q>
    auto scan(const Q& queries) noexcept(NO_EXCEPT) {
        valarray<evaluator_result_t> res(std::ranges::distance(queries));
        this->scan(std::ranges::begin(queries), std::ranges::end(queries), std::ranges::begin(res));
        return res;
    }
};


} // namespace uni
#line 2 "numeric/leveler.hpp"


#line 7 "numeric/leveler.hpp"


#line 10 "numeric/leveler.hpp"

#line 13 "numeric/leveler.hpp"

#line 15 "numeric/leveler.hpp"

#line 18 "numeric/leveler.hpp"


namespace uni {


template<class T = internal::size_t>
struct leveler {
    using value_type = T;
    using size_type = internal::size_t;

  private:
    uni::valarray<value_type> _bases;
    size_type _dim;
    value_type _max;

    inline value_type _compute_max() const noexcept(NO_EXCEPT) {
        return std::reduce(std::begin(this->_bases), std::end(this->_bases), 1, std::multiplies<value_type>{});
    }

  public:
    leveler(const std::initializer_list<value_type> bases) noexcept(NO_EXCEPT) : _bases(bases), _dim(std::ranges::size(bases)) {
        this->_max = this->_compute_max();
    }

    template<class I>
    leveler(I first, I last) noexcept(NO_EXCEPT) : _bases(first, last), _dim(std::ranges::distance(first, last)) {
        this->_max = this->_compute_max();
    }

    template<std::ranges::forward_range R>
    leveler(R&& range) noexcept(NO_EXCEPT) : leveler(std::ranges::begin(range), std::ranges::end(range)) {}


    template<std::integral... Values>
    leveler(const Values... bases) noexcept(NO_EXCEPT) : leveler(std::initializer_list<value_type>{ bases... }) {}

    inline size_type dimension() const noexcept(NO_EXCEPT) { return this->_dim; }

    inline value_type sup() const noexcept(NO_EXCEPT) { return this->_max; }

    inline value_type convert(const std::initializer_list<value_type> inds) const noexcept(NO_EXCEPT) {
        return this->convert(inds | std::views::all);
    }

    template<std::ranges::forward_range R>
    inline value_type convert(R&& range) const noexcept(NO_EXCEPT) {
        assert(std::ranges::distance(range) == std::ranges::ssize(this->_bases));

        value_type res = 0;
        {
            auto size = std::ranges::begin(this->_bases);
            ITR(v, range) {
                assert(0 <= v and v < *size);
                res *= *(size++);
                res += v;
            }
        }

        return res;
    }

    template<std::integral... Values>
    inline value_type convert(const Values... inds) const noexcept(NO_EXCEPT) {
        return this->convert({ inds... });
    }

    inline uni::valarray<value_type> revert(value_type id) const noexcept(NO_EXCEPT) {
        assert(0 <= id and id < this->sup());

        uni::valarray<value_type> res(std::size(this->_bases));

        REPD(i, std::size(this->_bases)) {
            res[i] = id % this->_bases[i];
            id /= this->_bases[i];
        }

        return res;
    }

    auto _debug() const { return this->_bases; }
};


}
#line 2 "numeric/matrix.hpp"


#line 6 "numeric/matrix.hpp"


#line 9 "numeric/matrix.hpp"

#line 12 "numeric/matrix.hpp"

#line 14 "numeric/matrix.hpp"

#line 16 "numeric/matrix.hpp"



namespace uni {

namespace internal {


template<class Base>
struct matrix_core : Base {
    using Base::Base;

    using value_type = typename Base::value_type;
    using size_type = typename Base::size_type;

    using vector_type = typename Base::row_type;

    static constexpr auto identity(const size_type n, const value_type& val = 1) noexcept(NO_EXCEPT) {
        matrix_core res(n);
        REP(i, n) res(i, i) = val;
        return res;
    }

    inline constexpr bool square() const noexcept(NO_EXCEPT) { return this->height() == this->width(); }


    constexpr auto& operator+=(const value_type& rhs) noexcept(NO_EXCEPT) {
        REP(i, this->height()) REP(j, this->width()) this->operator()(i, j) += rhs;
        return *this;
    }

    template<class... Ts>
    constexpr auto& operator+=(const matrix_core<Ts...>& rhs) noexcept(NO_EXCEPT) {
        REP(i, this->height()) REP(j, this->width()) this->operator()(i, j) += rhs(i, j);
        return *this;
    }


    template<weakly_addition_assignable<matrix_core> T>
    inline constexpr auto operator+(const T& rhs) const noexcept(NO_EXCEPT) {
        return matrix_core(*this) += rhs;
    }


    constexpr auto& operator-=(const value_type& rhs) noexcept(NO_EXCEPT) {
        REP(i, this->height()) REP(j, this->width()) this->operator()(i, j) -= rhs;
        return *this;
    }

    template<class... Ts>
    constexpr auto& operator-=(const matrix_core<Ts...>& rhs) noexcept(NO_EXCEPT) {
        REP(i, this->height()) REP(j, this->width()) this->operator()(i, j) -= rhs(i, j);
        return *this;
    }


    template<weakly_subtraction_assignable<matrix_core> T>
    inline constexpr auto operator-(const T& rhs) const noexcept(NO_EXCEPT) {
        return matrix_core(*this) -= rhs;
    }


    template<class... Ts>
    constexpr auto operator*(const matrix_core<Ts...>& rhs) const noexcept(NO_EXCEPT) {
        assert(this->width() == rhs.height());
        matrix_core res(this->height(), rhs.width());
        REP(i, this->height()) REP(j, rhs.width()) REP(k, this->width()) {
            res(i, j) += (*this)(i, k) * rhs(k, j);
        }
        return res;
    }

    template<std::ranges::input_range Vector>
        requires
            (!internal::derived_from_template<Vector, matrix_core>) &&
            internal::weakly_multipliable<value_type, std::ranges::range_value_t<Vector>>
    constexpr auto operator*(const Vector& rhs) const noexcept(NO_EXCEPT) {
        debug(*this, rhs);
        assert(this->width() == std::ranges::ssize(rhs));
        Vector res(this->height());
        REP(i, this->height()) REP(j, this->width()) res[i] += this->operator()(i, j) * rhs[j];
        return res;
    }

    template<std::ranges::input_range Vector>
        requires
            (!internal::derived_from_template<Vector, matrix_core>) &&
            internal::weakly_multipliable<std::ranges::range_value_t<Vector>, value_type>
    friend constexpr auto operator*(const Vector& lhs, const matrix_core& rhs) noexcept(NO_EXCEPT) {
        debug(lhs, rhs);
        assert(std::ranges::ssize(lhs) == rhs.height());
        Vector res(rhs.width());
        REP(i, rhs.height()) REP(j, rhs.width()) res[j] += lhs[j] * rhs[i][j];
        return res;
    }

    constexpr auto operator*(const value_type& rhs) noexcept(NO_EXCEPT) {
        auto res = *this;
        REP(i, res.height()) REP(j, res.width()) res(i, j) *= rhs;
        return res;
    }


    template<multipliable<matrix_core> T>
    constexpr auto& operator*=(const T& rhs) noexcept(NO_EXCEPT) {
        matrix_core res = *this * rhs;
        this->assign(res);
        return *this;
    }

    constexpr auto& operator/=(const value_type& rhs) noexcept(NO_EXCEPT) {
        REP(i, this->height()) REP(j, this->width()) this->operator()(i, j) /= rhs;
        return *this;
    }

    inline constexpr auto operator/(const value_type& rhs) const noexcept(NO_EXCEPT) {
        return matrix_core(*this) /= rhs;
    }

    constexpr auto& operator%=(const value_type& rhs) noexcept(NO_EXCEPT) {
        REP(i, this->height()) REP(j, this->width()) this->operator()(i, j) %= rhs;
        return *this;
    }

    inline constexpr auto operator%(const value_type& rhs) const noexcept(NO_EXCEPT) {
        return matrix_core(*this) %= rhs;
    }


    template<std::integral K>
    constexpr auto pow(const K n) const noexcept(NO_EXCEPT) {
        assert(this->height() == this->width());
        if constexpr(std::signed_integral<K>) assert(n >= 0);

        return uni::pow(*this, n, {}, matrix_core::identity(this->height()));
    }


    constexpr auto find_pivot(const size_type rank, const size_type col) const noexcept(NO_EXCEPT) {
        size_type pivot = -1;

        REP(i, rank, this->height()) {
            if(this->operator()(i, col) != 0) {
                pivot = i;
                break;
            }
        }

        return pivot;
    }

    template<bool DIAGONALIZE = false>
    constexpr void sweep(const size_type rank, const size_type col, const size_type pivot) noexcept(NO_EXCEPT)
        requires modint_family<value_type>
    {
        std::swap(this->operator[](pivot), this->operator[](rank));

        if constexpr(DIAGONALIZE) {
            const auto inv = this->operator()(rank, col).inv();
            REP(j, this->width()) this->operator()(rank, j) *= inv;
        }

        REP(i, (DIAGONALIZE ? 0 : rank + 1), this->height()) {
            if(i != rank && this->operator()(i, col) != 0) {
                const auto fac = this->operator()(i, col);
                REP(j, this->width()) this->operator()(i, j) -= this->operator()(rank, j) * fac;
            }
        }
    }


    template<size_type IGNORE_WIDTH = 0, bool DIAGONALIZE = false>
    inline constexpr auto transform_to_upper_triangular() noexcept(NO_EXCEPT)
        requires modint_family<value_type>
    {
        size_type rank = 0;

        REP(j, this->width() - IGNORE_WIDTH) {
            const auto pivot = this->find_pivot(rank, j);
            if(pivot == -1) continue;
            this->template sweep<DIAGONALIZE>(rank++, j, pivot);
        }

        return rank;
    }

    template<size_type IGNORE_WIDTH>
    inline constexpr auto transform_to_lower_triangular() noexcept(NO_EXCEPT)
        requires modint_family<value_type>
    {
        const auto rank = this->template transform_to_upper_triangular<IGNORE_WIDTH>();
        this->transpose();
        return rank;
    }


    template<std::ranges::input_range Vector, class Sol = void, class System = void>
    constexpr std::optional<size_type> solve_linear_equation(
        const Vector& v,
        Sol *const sol = nullptr,
        System *const system = nullptr
    )
        const noexcept(NO_EXCEPT)
        requires modint_family<value_type>
    {
        static_assert(!(std::same_as<Sol, void>) || (std::same_as<System, void>));

        assert(this->height() == std::ranges::ssize(v));

        matrix_core mat(this->height(), this->width() + 1);

        REP(i, this->height()) {
            REP(j, this->width()) mat(i, j) = this->operator()(i, j);
            mat(i, this->width()) = v[i];
        }

        const auto rank = mat.transform_to_upper_triangular<1, true>();

        REP(i, rank, this->height()) if(mat(i, this->width()) != value_type::zero) return {};

        if constexpr(!std::same_as<Sol, void>) {
            static_assert(std::ranges::output_range<Sol, value_type>);
            static_assert(std::ranges::output_range<std::ranges::range_value_t<System>, value_type>);
            assert(!sol || system);

            if(sol) {
                sol->assign(this->width(), value_type::zero);

                std::vector<size_type> pivots(system ? this->width() : 0, -1);

                for(size_type i = 0, j = 0; i < rank; ++i) {
                    while(mat(i, j) == value_type::zero) ++j;

                    sol->operator[](j) = mat(i, this->width());

                    if constexpr(!std::same_as<System, void>) if(system) {
                        pivots[j] = i;
                    }
                }

                if constexpr(!std::same_as<System, void>) if(system) {
                    REP(j, this->width()) {
                        if(pivots[j] != -1) continue;

                        typename System::vector_type x(this->width());
                        x[j] = value_type::one;
                        REP(k, j) if(pivots[k] != -1) x[k] = -mat(pivots[k], j);
                        system->push_back(x);
                    }

                    system->resize(system->size(), this->width());
                }
            }
        }

        return rank;
    }

    value_type determinant() const noexcept(NO_EXCEPT)
        requires modint_family<value_type>
    {
        assert(this->square());

        auto mat = *this;

        value_type det = value_type::one;

        REP(j, this->height()) {
            const auto pivot = mat.find_pivot(j, j);
            if(j < pivot) std::swap(mat[pivot], mat[j]), det = -det;

            if(mat(j, j) == 0) return 0;

            REP(i, j + 1, this->height()) {
                while(mat(i, j) != 0) {
                    const auto c = static_cast<value_type>(-to_signed(mat(j, j).val() / mat(i, j).val()));
                    REP(k, j, this->height()) mat(j, k) += mat(i, k) * c;
                    std::swap(mat[i], mat[j]), det = -det;
                }
            }
        }

        REP(i, mat.height()) det *= mat(i, i);

        return det;
    }
};


} // namespace internal


template<class T, class Base = grid<T>>
using matrix = internal::matrix_core<Base>;

template<class T>
using valmatrix = internal::matrix_core<valgrid<T>>;

template<class T>
using unfolded_matrix = internal::matrix_core<unfolded_grid<T>>;

template<class T>
using unfolded_valmatrix = internal::matrix_core<unfolded_valgrid<T>>;


} // namespace uni
#line 2 "numeric/numerical_sequence.hpp"


#line 6 "numeric/numerical_sequence.hpp"

#line 8 "numeric/numerical_sequence.hpp"


namespace uni {

namespace numerical_sequence {


namespace internal {


using size_t = std::int64_t;


template<class T>
struct single_constant {
    using value_type = T;

  private:
    value_type _val;

  public:
    constexpr single_constant() = default;
    constexpr single_constant(const value_type& val) noexcept(NO_EXCEPT) : _val(val) {}

    inline constexpr const value_type& val() const noexcept(NO_EXCEPT) { return this->_val; }
    inline constexpr operator value_type() const noexcept(NO_EXCEPT) { return this->_val; }
};


} // namespace internl


template<class T>
struct term {
    using size_type = internal::size_t;
    using value_type = T;

  private:
    size_type _index;
    value_type _val;

  public:
    constexpr term() = default;
    constexpr explicit term(const size_type index, const value_type& val) noexcept(NO_EXCEPT) : _index(index), _val(val) {}

    inline constexpr size_type index() const noexcept(NO_EXCEPT) { return this->_index; }
    inline constexpr const value_type& val() const noexcept(NO_EXCEPT) { return this->_val; }

};

template<class T, internal::size_t INDEX>
struct static_term : internal::single_constant<T> {
    using internal::single_constant<T>::single_constant;

    using size_type = internal::size_t;
    using value_type = T;

    inline constexpr size_type index() const noexcept(NO_EXCEPT) { return INDEX; }
    inline constexpr operator term<value_type>() const noexcept(NO_EXCEPT) { return term(INDEX, this->_val); }
};

template<class T>
struct common_difference : internal::single_constant<T> {
    using internal::single_constant<T>::single_constant;
};

template<class T>
struct common_ratio : internal::single_constant<T> {
    using internal::single_constant<T>::single_constant;
};


template<class T>
struct arithmetic {
    using size_type = internal::size_t;
    using value_type = T;

  protected:
    value_type _begin, _diff;

  public:
    constexpr arithmetic() = default;
    constexpr arithmetic(const static_term<value_type,0>& begin, const common_difference<value_type>& diff)
    : _begin(static_cast<value_type>(begin.val())), _diff(diff.val()) {}
    constexpr arithmetic(const common_difference<value_type>& diff, const static_term<value_type,0>& begin) : arithmetic(begin, diff) {}

    constexpr arithmetic(const term<value_type>& p, const common_difference<value_type>& diff) noexcept(NO_EXCEPT)
      : arithmetic(diff, static_cast<value_type>(p.val() - diff * p.index()))
    {}
    constexpr arithmetic(const common_difference<value_type>& diff, const term<value_type>& p) noexcept(NO_EXCEPT) : arithmetic(p, diff) {}

    constexpr arithmetic(const term<value_type> p, const term<value_type> q) noexcept(NO_EXCEPT)
      : arithmetic(p, common_difference(static_cast<value_type>((p.val() - q.val()) / (p.index() - q.index()))))
    {}

    inline constexpr term<value_type> operator[](const size_type k) const noexcept(NO_EXCEPT) {
        return term(k, static_cast<value_type>(this->_begin + this->_diff * k));
    }
    inline constexpr value_type sum(const size_type k) const noexcept(NO_EXCEPT) {
        return static_cast<value_type>((this->_begin * k) + (k - 1) * k / 2 * this->_diff);
    }
    inline constexpr value_type sum(const size_type l, const size_type r) const noexcept(NO_EXCEPT) {
        return this->sum(r) - this->sum(l);
    }
};



template<class T>
struct geometric {
    using size_type = internal::size_t;
    using value_type = T;

  protected:
    value_type _begin, _ratio;

  public:
    constexpr geometric() = default;
    constexpr geometric(const static_term<value_type,0> begin, const common_ratio<T> ratio) noexcept(NO_EXCEPT) : _begin(begin), _ratio(ratio) {};

    inline constexpr term<value_type> operator[](const size_type k) const noexcept(NO_EXCEPT) {
        return term(k, this->_begin * uni::pow(this->_diff, k));
    }
    inline constexpr value_type sum(const size_type k) const noexcept(NO_EXCEPT) {
        if(this->_ratio == 1) return this->_begin * this->k;
        else {
            return this->_begin * (uni::pow(this->_ratio, k) - 1) / (this->_ratio - 1);
        }
        return ;
    }
    inline constexpr value_type sum(const size_type l, const size_type r) const noexcept(NO_EXCEPT) {
        return this->sum(r) - this->sum(l);
    }
};


} // namespace numerical_sequence

} // namespace uni
#line 2 "numeric/prime_counter.hpp"


#line 6 "numeric/prime_counter.hpp"


#line 10 "numeric/prime_counter.hpp"

#line 12 "numeric/prime_counter.hpp"

#line 14 "numeric/prime_counter.hpp"


namespace uni {


static inline i64 float_div(const i64 n, const i64 p) {
    return static_cast<i64>(static_cast<double>(n) / static_cast<double>(p));
};

// Thanks to: https://nyaannyaan.github.io/library/multiplicative-function/prime-counting-faster.hpp
__attribute__((target("avx2"), optimize("O3", "unroll-loops")))
i64 count_primes(const u64 n) noexcept(NO_EXCEPT) {
    if(n == 0 || n == 1) return 0;

    const i64 sqrt_n = uni::sqrt_floor(n);
    const i64 m = float_div(n, sqrt_n);

    std::vector<i64> hl(m);
    REP(i, 1, m) hl[i] = float_div(n, i) - 1;

    std::vector<i32> hs(sqrt_n + 1);
    std::iota(ALL(hs), -1);

    for(i32 x=2, pi=0; x <= sqrt_n; ++x) {
        if(hs[x] == hs[x - 1]) continue;
        const i64 x2 = static_cast<i64>(x) * x;
        const i64 imax = std::min(m, float_div(n, x2) + 1);

        i64 ix = x;
        REP(i, 1, imax) {
            hl[i] -= (ix < m ? hl[ix] : hs[float_div(n, ix)]) - pi;
            ix += x;
        }
        FORD(k, x2, sqrt_n) hs[k] -= hs[float_div(k, x)] - pi;

        ++pi;
    }

    return hl[1];
}


inline i64 count_primes(const i64 l, const i64 r) noexcept(NO_EXCEPT) {
    assert(l <= r);
    return count_primes(r) - count_primes(l - 1);
}


} // namespace uni
#line 2 "numeric/prime_sieve.hpp"


#line 5 "numeric/prime_sieve.hpp"


#line 8 "numeric/prime_sieve.hpp"

#line 11 "numeric/prime_sieve.hpp"

#line 14 "numeric/prime_sieve.hpp"


namespace uni {


template<class container = valarray<bool>> struct prime_flags : container {
    prime_flags(const internal::size_t max) noexcept(NO_EXCEPT) : container(max+1, true) {
        (*this)[0] = (*this)[1] = false;
        for(internal::size_t p=2; p*p<=max; p++) if((*this)[p]) {
            for(internal::size_t i=p*p; i<=max; i+=p) (*this)[i] = false;
        }
    }
};

template<class T, class container = vector<T>> struct prime_sieve : container {
  protected:
    std::vector<bool> is_prime;

  public:
    prime_sieve() noexcept(NO_EXCEPT) {}
    prime_sieve(const T max) noexcept(NO_EXCEPT) : is_prime(max+1, true) {
        is_prime[0] = is_prime[1] = false;
        FOR(p, T{2}, max) {
            if(is_prime[p]) {
                for(T i = mul_overflow(p,p).value_or(max+1); i<=max; i+=p) is_prime[i] = false;
                this->emplace_back(p);
            }
        }
    }
    inline bool operator()(const T index) const noexcept(NO_EXCEPT) {
        return is_prime[index];
    }
};


} // namespace uni
#line 2 "numeric/quotient_enumerator.hpp"


#line 6 "numeric/quotient_enumerator.hpp"

#line 10 "numeric/quotient_enumerator.hpp"

#line 12 "numeric/quotient_enumerator.hpp"


namespace uni {


template<class T, bool CEIL = false>
struct quotient_enumerator {
    using value_type = std::tuple<T,T,T>; // (q, l, r)
    using size_type = T;

  private:
    T _n = 0, _n_impl = 0;
    size_type _size = -1;

  protected:
    using iterator_interface = internal::bidirectional_iterator_interface<const value_type>;

  public:
    // Enumerate tuple of (q, l, r), which means (floor/ceil)(_n/k) == q (l <= k <= r).
    quotient_enumerator(const T n) noexcept(NO_EXCEPT) : _n(n), _n_impl(n - CEIL) { assert(n > 0); }

    struct iterator;
    using const_iterator = iterator;

    inline auto begin() noexcept(NO_EXCEPT) { return iterator(this->_n_impl, 1); }
    inline auto end() noexcept(NO_EXCEPT) { return iterator(this->_n_impl, this->_n + 1); }

    inline auto rbegin() noexcept(NO_EXCEPT) { return std::make_reverse_iterator(this->end()); }
    inline auto rend() noexcept(NO_EXCEPT) { return std::make_reverse_iterator(this->begin()); }

    inline auto size() noexcept(NO_EXCEPT) {
        if(this->_size < 0) {
            size_type r = uni::sqrt_floor(this->_n_impl);
            this->_size = 2 * r - (this->_n_impl < r * (r + 1)) + CEIL;
        }
        return this->_size;
    }

    struct iterator : virtual iterator_interface {
        using value_type = quotient_enumerator::value_type;
        using reference = value_type;

      protected:
        T _n_impl = 0;
        T _q = 0, _l = 0, _r = 0;

        void _set_l(const T l) noexcept(NO_EXCEPT) {
            this->_l = l, this->_q = this->_n_impl / l;
            if(this->_q == 0) {
                if(CEIL) {
                    if(l == this->_n_impl + 1) this->_r = l;
                }
                return;
            }
            this->_r = this->_n_impl / this->_q;
        }
        void _set_r(const T r) noexcept(NO_EXCEPT) {
            this->_r = r, this->_q = this->_n_impl / r;
            this->_l = this->_n_impl / (this->_q + 1) + 1;
        }

      public:
        iterator() noexcept = default;
        iterator(const T n, const T l) noexcept(NO_EXCEPT) : _n_impl(n) { this->_set_l(l); }

        friend inline bool operator==(const iterator& lhs, const iterator& rhs) noexcept(NO_EXCEPT) { return lhs._l == rhs._l; }

        inline value_type operator*() const noexcept(NO_EXCEPT) { return { this->_q + CEIL, this->_l, this->_r }; }

        inline auto& operator++() noexcept(NO_EXCEPT) { this->_set_l(this->_r + 1); return *this; }
        inline auto& operator--() noexcept(NO_EXCEPT) { this->_set_r(this->_l - 1); return *this; }

        inline auto operator++(int) noexcept(NO_EXCEPT) { const auto res = *this; this->_set_l(this->_r + 1); return res; }
        inline auto operator--(int) noexcept(NO_EXCEPT) { const auto res = *this; this->_set_r(this->_l - 1); return res; }
    };

};


} // namespace uni


namespace std::ranges {

template<class T>
inline constexpr bool enable_borrowed_range<uni::quotient_enumerator<T>> = true;

} // namespace std::ranges
#line 2 "numeric/repeater.hpp"


#line 7 "numeric/repeater.hpp"


#line 11 "numeric/repeater.hpp"

#line 13 "numeric/repeater.hpp"


namespace uni {


template<class T, internal::size_t SUP, internal::size_t DEFAULT_DEPTH = 64>
struct repeater {
    using value_type = T;
    using size_type = internal::size_t;

  private:
    std::vector<std::array<T, SUP>> _app;

    inline void _extend(const std::size_t k) noexcept(NO_EXCEPT) {
        const auto size = this->_app.size();
        const auto w = to_unsigned(std::bit_width(k));

        if(w <= size) return;
        this->_app.resize(w);

        REP(d, size, w) {
            REP(n, SUP) {
                this->_app[d][n] = this->_app[d - 1][this->_app[d - 1][n]];
            }
        }
    }

    template<std::unsigned_integral K>
    struct applyer {
      private:
        K _k;
        repeater* _super;

      public:
        applyer(const K k, repeater *const super) noexcept(NO_EXCEPT) : _k(k), _super(super) {}

        inline K times() const noexcept(NO_EXCEPT) { return this->_k; }

        inline value_type operator()(value_type val) const noexcept(NO_EXCEPT) {
            REP(d, this->_super->_app.size()) {
                if(uni::bit(this->_k, d)) val = this->_super->_app[d][val];
            }
            return val;
        }
    };


  public:
    template<class F>
        requires std::convertible_to<std::invoke_result_t<F, T>, T>
    explicit repeater(F&& f) noexcept(NO_EXCEPT) : _app(1) {
        this->_app.reserve(DEFAULT_DEPTH);
        REP(n, SUP) this->_app[0][n] = static_cast<value_type>(f(n));
    };

    template<std::ranges::sized_range R>
    explicit repeater(R&& f) noexcept(NO_EXCEPT) : _app(1) {
        assert(std::ranges::size(f) <= SUP);

        this->_app.reserve(DEFAULT_DEPTH);
        std::ranges::copy(f, std::ranges::begin(this->_app[0]));
    };


    template<std::integral K>
    inline auto operator[](K k) noexcept(NO_EXCEPT) {
        if(std::signed_integral<K>) assert(0 <= k);
        this->_extend(static_cast<std::size_t>(k));
        return applyer{ to_unsigned(k), this };
    }
};


} // namespace uni
#line 2 "numeric/stern_brocot_tree.hpp"


#line 6 "numeric/stern_brocot_tree.hpp"

#line 8 "numeric/stern_brocot_tree.hpp"

#line 10 "numeric/stern_brocot_tree.hpp"

#line 12 "numeric/stern_brocot_tree.hpp"


namespace uni {


// Thanks to: https://maspypy.github.io/library/nt/stern_brocot_tree.hpp
template<
    class Value = i32,
    class Middle = i64,
    class Large = i128,
    class Fraction = spair<Value>, std::ranges::range Path = uni::vector<Value>
>
struct stern_brocot_tree {
    using value_type = Value;
    using middle_type = Middle;
    using large_type = middle_type;
    using path_type = Path;
    using fraction_type = Fraction;

    static constexpr std::tuple<path_type, fraction_type, fraction_type> path_and_rang(const fraction_type x) {
        path_type path;
        fraction_type l = { 0, 1 }, r = { 1, 0 };
        fraction_type m = { 1, 1 };
        middle_type det_l = l.first * x.second - l.second * x.first;
        middle_type det_r = r.first * x.second - r.second * x.first;
        middle_type det_m = det_l + det_r;
        while(true) {
            if(det_m == 0) break;
            middle_type k = uni::div_ceil(-det_m, det_r);
            path.emplace_back(k);
            l = { l.first + k * r.first, l.second + k * r.second };
            m = { l.first + r.first, l.second + r.second };
            det_l += k * det_r;
            det_m += k * det_r;
            if(det_m == 0) break;
            k = uni::div_ceil(det_m, -det_l);
            path.emplace_back(k);
            r = { r.first + k * l.first, r.second + k * l.second };
            m = { l.first + r.first, l.second + r.second };
            det_r += k * det_l;
            det_m += k * det_l;
        }
        return { path, l, r };
    }

    static constexpr path_type path(const fraction_type x) {
        const auto [ path, l, r ] = path_and_rang(x);
        return path;
    }

    static constexpr spair<fraction_type> range(const fraction_type x) {
        const auto [ path, l, r ] = path_and_rang(x);
        return { l, r };
    }

    // x in range(y)
    static constexpr bool in_subtree(const fraction_type x, const fraction_type y) {
        const auto [ l, r ] = range(y);
        const bool ok_l = static_cast<middle_type>(x.first) * l.second - static_cast<middle_type>(x.second) * l.first > 0;
        const bool ok_r = static_cast<middle_type>(r.first) * x.second - static_cast<middle_type>(r.second) * x.first > 0;
        return ok_l && ok_r;
    }

    template<class T = middle_type, class Frac = spair<middle_type>>
    static constexpr Frac from_path(const path_type &p) {
        Frac l = { 0, 1 }, r = { 1, 0 };
        FOR(i, std::ranges::size(p)) {
            middle_type k = p[i];
            if((i & 1) == 0) {
                l.first += static_cast<T>(k) * r.first;
                l.second += static_cast<T>(k) * r.second;
            }
            if((i & 1) == 1) {
                r.first += static_cast<T>(k) * l.first;
                r.second += static_cast<T>(k) * l.second;
            }
        }
        return { l.first + r.first, l.second + r.second };
    }

    static constexpr spair<fraction_type> children(const fraction_type x) {
        const auto [ l, r ] = range(x);
        const fraction_type lc = { l.first + x.first, l.second + x.second };
        const fraction_type rc = { x.first + r.first, x.second + r.second };
        return { lc, rc };
    }

    static constexpr fraction_type lowest_common_ancestor(const fraction_type x, const fraction_type y) {
        const auto px = path(x);
        const auto py = path(y);
        path_type path;
        FOR(i, uni::min(std::ranges::ssize(px), std::ranges::ssize(py))) {
            middle_type k = uni::min(px[i], py[i]);
            path.emplace_back(k);
            if(k < px[i] || k < py[i]) break;
        }
        return from_path(path);
    }

    static constexpr fraction_type ancestor(const fraction_type x, middle_type dep) {
        fraction_type l = { 0, 1 }, r = { 1, 0 };
        fraction_type m = { 1, 1 };
        middle_type det_l = l.first * x.second - l.second * x.first;
        middle_type det_r = r.first * x.second - r.second * x.first;
        middle_type det_m = det_l + det_r;
        while(true) {
            if(det_m == 0 || dep == 0) break;
            middle_type k = uni::min(dep, uni::div_ceil(-det_m, det_r));
            l = { l.first + k * r.first, l.second + k * r.second };
            m = { l.first + r.first, l.second + r.second };
            det_l += k * det_r;
            det_m += k * det_r;
            dep -= k;
            if(det_m == 0 || dep == 0) break;
            k = uni::min(dep, uni::div_ceil(det_m, -det_l));
            r = {r.first + k * l.first, r.second + k * l.second };
            m = { l.first + r.first, l.second + r.second };
            det_r += k * det_l;
            det_m += k * det_l;
            dep -= k;
        }
        if(dep == 0) return m;
        return { -1, -1 };
    }

    static constexpr std::string to_string(const path_type &p) {
        std::string res;
        char c = 'L';
        ITR(x, p) {
            c = 'L' + 'R' - c;
            if(x == 0) continue;
            res += c;
            res += " " + std::to_string(x);
        }
        return res;
    }
};


} // namespace uni
#line 2 "numeric/subset_enumerator.hpp"


#line 6 "numeric/subset_enumerator.hpp"

#line 10 "numeric/subset_enumerator.hpp"

#line 13 "numeric/subset_enumerator.hpp"


namespace uni {


template<std::unsigned_integral T>
struct subset_enumerator {
    using value_type = T;
    using size_type = internal::size_t;

  private:
    T _n = 0;

  protected:
    using iterator_interface = internal::bidirectional_iterator_interface<const value_type>;

  public:
    // Enumerate tuple of (q, l, r), which means (floor/ceil)(_n/k) == q (l <= k <= r).
    subset_enumerator(const T n) noexcept(NO_EXCEPT) : _n(n) { assert(n >= 0); }

    struct iterator;
    using const_iterator = iterator;

    inline auto begin() noexcept(NO_EXCEPT) { return iterator(this->_n, this->_n); }
    inline auto end() noexcept(NO_EXCEPT) { return iterator(this->_n, 0, true); }

    inline auto rbegin() noexcept(NO_EXCEPT) { return std::make_reverse_iterator(this->end()); }
    inline auto rend() noexcept(NO_EXCEPT) { return std::make_reverse_iterator(this->begin()); }

    inline auto size() noexcept(NO_EXCEPT) { return static_cast<size_type>(1) << std::popcount(this->_n); }

    struct iterator : iterator_interface {
      protected:
        value_type _n = 0, _v = 0;
        bool _end = false;

      public:
        iterator() noexcept = default;
        iterator(const T n, const T v, const bool end = false) noexcept(NO_EXCEPT) : _n(n), _v(v), _end(end) {};


        friend inline bool operator==(const iterator& lhs, const iterator& rhs) noexcept(NO_EXCEPT) {
            if(rhs._end) return lhs._end;
            if(lhs._end) return false;

            return lhs._v == rhs._v;
        };

        friend inline auto operator<=>(const iterator& lhs, const iterator& rhs) noexcept(NO_EXCEPT) {
            if(rhs._end) {
                if(lhs._end) return std::partial_ordering::equivalent;
                return std::partial_ordering::less;
            }
            if(lhs._end) {
                return std::partial_ordering::greater;
            }

            return comapre_as_bitset(rhs._v, lhs._v);
        };


        inline auto operator*() const noexcept(NO_EXCEPT) { return this->_v; }

        inline auto& operator++() noexcept(NO_EXCEPT) {
            if(this->_v == 0) {
                this->_end = true;
            }
            else {
                this->_v = (this->_v - 1) & this->_n;
            }

            return *this;
        }

        inline auto& operator--() noexcept(NO_EXCEPT) {
            if(this->_end) {
                this->_end = false;
            }
            else {
                const auto lsb = lowest_bit_pos(this->_n & ~this->_v);
                this->_v = ((this->_v >> lsb) | 1) << lsb;
            }

            return *this;
        }

        inline auto operator++(int) noexcept(NO_EXCEPT) { auto res = *this; ++res; return res; }
        inline auto operator--(int) noexcept(NO_EXCEPT) { auto res = *this; --res; return res; }
    };

};


} // namespace uni


namespace std::ranges {

template<class T>
inline constexpr bool enable_borrowed_range<uni::subset_enumerator<T>> = true;

} // namespace std::ranges
#line 2 "numeric/subset_superset_transform.hpp"


#line 6 "numeric/subset_superset_transform.hpp"

#line 8 "numeric/subset_superset_transform.hpp"


namespace uni {


namespace superset_transform {


template<std::ranges::random_access_range R, std::unsigned_integral Bit = std::uint32_t>
void zeta(R& range) {
    const auto n = std::ranges::size(range);
    assert(std::has_single_bit(n));

    for(Bit i = 1; i < n; i <<= 1) {
        for(Bit j = 0; j < n; ++j) {
            if((j & i) == 0) {
                range[j] += range[j | i];
            }
        }
    }
}



template<std::ranges::random_access_range R, std::unsigned_integral Bit = std::uint32_t>
void mobius(R& range) {
    const auto n = std::ranges::size(range);
    assert(std::has_single_bit(n));

    for(Bit i = 1; i < n; i <<= 1) {
        for(Bit j = 0; j < n; ++j) {
            if((j & i) == 0) {
                range[j] -= range[j | i];
            }
        }
    }
}


} // namespace superset_transform


namespace subset_transform {


template<std::ranges::random_access_range R, std::unsigned_integral Bit = std::uint32_t>
void zeta(R& range) {
    const auto n = std::ranges::size(range);
    assert(std::has_single_bit(n));

    for(Bit i = 1; i < n; i <<= 1) {
        for(Bit j = 0; j < n; ++j) {
            if((j & i) == 0) {
                range[j | i] += range[j];
            }
        }
    }
}



template<std::ranges::random_access_range R, std::unsigned_integral Bit = std::uint32_t>
void mobius(R& range) {
    const auto n = std::ranges::size(range);
    assert(std::has_single_bit(n));

    for(Bit i = 1; i < n; i <<= 1) {
        for(Bit j = 0; j < n; ++j) {
            if((j & i) == 0) {
                range[j | i] -= range[j];
            }
        }
    }
}


} // namespace subset_transform


} // namespace uni
#line 2 "include/snippets.hpp"

#line 2 "snippet/fast_io.hpp"


#line 5 "snippet/fast_io.hpp"

#line 7 "snippet/fast_io.hpp"


#ifdef __GNUC__

__attribute__((constructor)) inline void fast_io() noexcept(NO_EXCEPT) { std::ios::sync_with_stdio(false), std::cin.tie(nullptr); }

#else

inline void fast_io() noexcept(NO_EXCEPT) { std::ios::sync_with_stdio(false), std::cin.tie(nullptr); }

#endif
#line 2 "include/views.hpp"

#line 2 "view/repeat.hpp"


#line 8 "view/repeat.hpp"


#line 12 "view/repeat.hpp"

#line 2 "view/internal/box.hpp"

#line 6 "view/internal/box.hpp"

#line 9 "view/internal/box.hpp"


namespace uni {

namespace internal {


#if CPP23

template<class T>
concept boxable = std::copy_constructible<T> && std::is_object_v<T>;

#else

template<class T>
concept boxable = std::copy_constructible<T> && std::is_object_v<T>;

#endif


template<boxable T> struct box : std::optional<T> {
    using std::optional<T>::optional;

    constexpr box()
        noexcept(std::is_nothrow_default_constructible_v<T>)
        requires std::default_initializable<T>
        : std::optional<T> { std::in_place }
    {}

    box(const box&) = default;
    box(box&&) = default;

    using std::optional<T>::operator=;

    constexpr box& operator=(const box& other) noexcept(
        std::is_nothrow_copy_constructible_v<T>)
        requires(!std::copyable<T>) && std::copy_constructible<T>
    {
        if(this != std::addressof(other)) {
            if((bool)other) this->emplace(*other);
            else this->reset();
        }
        return *this;
    }

    constexpr box& operator=(box&& other) noexcept(std::is_nothrow_move_constructible_v<T>)
        requires(!std::movable<T>)
    {
        if(this != std::addressof(other)) {
            if((bool)other)
                this->emplace(std::move(*other));
            else
                this->reset();
        }
        return *this;
    }
};

template<class T>
concept boxable_copyable =
    std::copy_constructible<T> &&
    (
        std::copyable<T> ||
        (std::is_nothrow_move_constructible_v<T> && std::is_nothrow_copy_constructible_v<T>)
    );

template<class T>
concept boxable_movable =
    (!std::copy_constructible<T>) &&
    (std::movable<T> || std::is_nothrow_move_constructible_v<T>);


template<boxable T>
    requires boxable_copyable<T> || boxable_movable<T>
struct box<T> {
  private:
    [[no_unique_address]] T _value = T();

  public:
    box() requires std::default_initializable<T> = default;

    constexpr explicit box(const T& value) noexcept(std::is_nothrow_copy_constructible_v<T>)
        requires std::copy_constructible<T>
    : _value(value)
    {}

    constexpr explicit box(T&& value) noexcept(std::is_nothrow_move_constructible_v<T>)
    : _value(std::move(value)) {}

    template<class... Args>
        requires std::constructible_from<T, Args...>
    constexpr explicit box(std::in_place_t, Args&&... args) noexcept(std::is_nothrow_constructible_v<T, Args...>)
    : _value(std::forward<Args>(args)...) {}

    box(const box& ) = default;
    box(box&& ) = default;
    box& operator=(const box& ) requires std::copyable<T> = default;
    box& operator=(box&& ) requires std::movable<T> = default;

    constexpr box& operator=(const box& other) noexcept
        requires(!std::copyable<T>) && std::copy_constructible<T>
    {
        static_assert(std::is_nothrow_copy_constructible_v<T>);
        if(this != std::addressof(other)) {
            this->_value.~T();
            std::construct_at(std::addressof(this->_value), *other);
        }
        return *this;
    }

    constexpr box& operator=(box&& other) noexcept
        requires(!std::movable<T>)
    {
        static_assert(std::is_nothrow_move_constructible_v<T>);
        if(this != std::addressof(other)) {
            this->_value.~T();
            std::construct_at(std::addressof(this->_value), std::move(*other));
        }
        return *this;
    }

    constexpr bool has_value() const noexcept { return true; };
    constexpr T& operator*() noexcept { return this->_value; }
    constexpr const T& operator*() const noexcept { return this->_value; }
    constexpr T* operator->() noexcept { return std::addressof(this->_value); }
    constexpr const T* operator->() const noexcept { return std::addressof(this->_value); }
};


}  // namespace internal

} // namespace uni
#line 15 "view/repeat.hpp"

#line 18 "view/repeat.hpp"


namespace uni {


template <std::move_constructible T, std::semiregular Bound = std::unreachable_sentinel_t>
    requires
        std::is_object_v<T> && std::same_as<T, std::remove_cv_t<T>> &&
        (
            std::is_integral_v<Bound> ||
            std::same_as<Bound, std::unreachable_sentinel_t>
        )
struct repeat_view : public std::ranges::view_interface<repeat_view<T, Bound>> {
  private:
    internal::box<T> _value;
    [[no_unique_address]] Bound _bound = Bound();

    struct iterator;

    template <typename Range>
    friend constexpr auto take_of_repeat_view(Range&&, std::ranges::range_difference_t<Range>);

    template <typename Range>
    friend constexpr auto drop_of_repeat_view(Range &&, std::ranges::range_difference_t<Range>);

  public:
    repeat_view() requires std::default_initializable<T> = default;

    constexpr explicit repeat_view(const T& val, Bound bound = Bound())
        requires std::copy_constructible<T> : _value(val), _bound(bound) {
        if constexpr(!std::same_as<Bound, std::unreachable_sentinel_t>) assert(bound >= 0);
    }

    constexpr explicit repeat_view(T&& val, Bound bound = Bound())
      : _value(std::move(val)), _bound(bound)
    {}

    template <typename... Args, typename... BoundArgs>
        requires std::constructible_from<T, Args...> && std::constructible_from<Bound, BoundArgs...>
    constexpr explicit repeat_view(
        std::piecewise_construct_t, std::tuple<Args...> args,
        std::tuple<BoundArgs...> bound_args = std::tuple<>{}
    )
      : _value(std::make_from_tuple<T>(std::move(args))),
        _bound(std::make_from_tuple<Bound>(std::move(bound_args)))
    {}

    constexpr iterator begin() const {
        return iterator(std::addressof(*this->_value));
    }

    constexpr iterator end() const
        requires(!std::same_as<Bound, std::unreachable_sentinel_t>)
    {
        return iterator(std::addressof(*this->_value), this->_bound);
    }

    constexpr std::unreachable_sentinel_t end() const noexcept {
        return std::unreachable_sentinel;
    }

    constexpr auto size() const
        requires(!std::same_as<Bound, std::unreachable_sentinel_t>)
    {
        return to_unsigned(this->_bound);
    }
};

template <typename T, typename Bound>
repeat_view(T, Bound) -> repeat_view<T, Bound>;

template <std::move_constructible T, std::semiregular Bound>
    requires
        std::is_object_v<T> && std::same_as<T, std::remove_cv_t<T>> &&
        (std::is_integral_v<Bound> || std::same_as<Bound, std::unreachable_sentinel_t>)
struct repeat_view<T, Bound>::iterator {
  private:
    using index_type = std::conditional_t<std::same_as<Bound, std::unreachable_sentinel_t>, std::ptrdiff_t, Bound>;

    const T* _value = nullptr;
    index_type _crrent = index_type();

    constexpr explicit iterator(const T* val, index_type bound = index_type())
      : _value(val), _crrent(bound)
    {
        if constexpr(!std::same_as<Bound, std::unreachable_sentinel_t>) assert(bound >= 0);
    }

    friend repeat_view;

  public:
    using iterator_concept = std::random_access_iterator_tag;
    using iterator_category = std::random_access_iterator_tag;
    using value_type = T;
    using difference_type =
        std::conditional_t<
            std::is_integral_v<index_type>,
            index_type,
            internal::iota_diff_t<index_type>
        >;

    iterator() = default;

    constexpr const T& operator*() const noexcept { return *this->_value; }

    constexpr iterator& operator++() {
        ++this->_crrent;
        return *this;
    }

    constexpr iterator operator++(int) {
        auto _tmp = *this;
        ++*this;
        return _tmp;
    }

    constexpr iterator& operator--() {
        if constexpr(!std::same_as<Bound, std::unreachable_sentinel_t>) assert(this->_crrent > 0);
        --this->_crrent;
        return *this;
    }

    constexpr iterator operator--(int) {
        auto _tmp = *this;
        --*this;
        return _tmp;
    }

    constexpr iterator& operator+=(difference_type diff) {
        if constexpr(!std::same_as<Bound, std::unreachable_sentinel_t>) assert(this->_crrent + diff >= 0);
        this->_crrent += diff;
        return *this;
    }

    constexpr iterator& operator-=(difference_type diff) {
        if constexpr(!std::same_as<Bound, std::unreachable_sentinel_t>) assert(this->_crrent - diff >= 0);
        this->_crrent -= diff;
        return *this;
    }

    constexpr const T& operator[](difference_type diff) const noexcept {
        return *(*this + diff);
    }

    friend constexpr bool operator==(const iterator& lhs, const iterator& rhs) {
        return lhs._crrent == rhs._crrent;
    }

    friend constexpr auto operator<=>(const iterator& lhs, const iterator& rhs) {
        return lhs._crrent <=> rhs._crrent;
    }

    friend constexpr iterator operator+(iterator itr, difference_type diff) {
        return itr += diff;
    }

    friend constexpr iterator operator+(difference_type diff, iterator itr) {
        return itr + diff;
    }

    friend constexpr iterator operator-(iterator itr, difference_type diff) {
        return itr -= diff;
    }

    friend constexpr difference_type operator-(const iterator& lhs, const iterator& rhs) {
        return (
            static_cast<difference_type>(lhs._crrent) -
            static_cast<difference_type>(rhs._crrent)
        );
    }
};

namespace views {

namespace internal {


template<typename _Range>
inline constexpr bool is_repeat_view = false;

template <class T, class Bound>
inline constexpr bool is_repeat_view<repeat_view<T, Bound>> = true;

template <class T>
concept can_repeat_view = requires { repeat_view(std::declval<T>()); };

template <class T, class Bound>
concept can_bounded_repeat_view =
    requires { repeat_view(std::declval<T>(), std::declval<Bound>()); };
} // namespace internal


struct Repeat {
    template <class T>
        requires internal::can_repeat_view<T>
    constexpr auto operator() [[nodiscard]] (T&& val) const {
        return repeat_view(std::forward<T>(val));
    }

    template <class T, class Bound>
        requires internal::can_bounded_repeat_view<T, Bound>
    constexpr auto operator()
        [[nodiscard]] (T&& val, Bound bound) const {
        return repeat_view(std::forward<T>(val), bound);
    }
};


inline constexpr Repeat repeat;


namespace internal {


template<class Range>
constexpr auto take_of_repeat_view(Range&& range, std::ranges::range_difference_t<Range> diff) {
    using T = std::remove_cvref_t<Range>;
    static_assert(is_repeat_view<T>);

    if constexpr(std::ranges::sized_range<T>) return views::repeat(*range._value, std::min(std::ranges::distance(range), diff));
    else return views::repeat(*range._value, diff);
}

template<class Range>
constexpr auto drop_of_repeat_view(Range&& range, std::ranges::range_difference_t<Range> diff) {
    using T = std::remove_cvref_t<Range>;
    static_assert(is_repeat_view<T>);

    if constexpr(std::ranges::sized_range<T>) {
        auto size = std::ranges::distance(range);
        return views::repeat(*range._value, size - std::min(size, diff));
    }
    else {
        return range;
    }
}


} // namespace internal

} // namespace views

} // namespace uni
#line 2 "view/slide.hpp"


#line 6 "view/slide.hpp"


#line 9 "view/slide.hpp"

#line 11 "view/slide.hpp"


namespace uni {


namespace internal {


template<class View>
concept slide_caches_nothing = std::ranges::random_access_range<View> && std::ranges::sized_range<View>;

template<class View>
concept slide_caches_last = !slide_caches_nothing<View> && std::ranges::bidirectional_range<View> && std::ranges::common_range<View>;


template<class View>
concept slide_caches_first = !slide_caches_nothing<View> && !slide_caches_last<View>;

} // namespace internal

template<std::ranges::forward_range View>
    requires std::ranges::view<View>
struct slide_view : std::ranges::view_interface<slide_view<View>> {
  private:
    View _base;
    std::ranges::range_difference_t<View> _n;

    [[no_unique_address]] internal::maybe_present_t<internal::slide_caches_first<View>, internal::cached_position<View>, 0> _cache_begin;
    [[no_unique_address]] internal::maybe_present_t<internal::slide_caches_last<View>, internal::cached_position<View>, 1> _cache_end;

    template<bool> struct iterator;
    struct sentinel;

  public:
    constexpr explicit slide_view(View base, std::ranges::range_difference_t<View> n)
      : _base(std::move(base)), _n(n)
    {
        assert(n > 0);
    }

    constexpr auto begin()
        requires(!(internal::simple_view<View> && internal::slide_caches_nothing<const View>))
    {
        if constexpr(internal::slide_caches_first<View>) {
            std::ranges::iterator_t<View> itr;

            if(this->_cache_begin.has_value()) {
                itr = this->_cache_begin.get(this->_base);
            }
            else {
                itr = std::ranges::next(std::ranges::begin(this->_base), this->_n - 1, std::ranges::end(this->_base));
                this->_cache_begin.set(this->_base, itr);
            }

            return iterator<false>(std::ranges::begin(this->_base), std::move(itr), this->_n);
        }
        else {
            return iterator<false>(std::ranges::begin(this->_base), this->_n);
        }
    }

    constexpr auto begin() const
        requires internal::slide_caches_nothing<const View>
    {
        return iterator<true>(std::ranges::begin(this->_base), this->_n);
    }

    constexpr auto end()
        requires (!(internal::simple_view<View> && internal::slide_caches_nothing<const View>))
    {
        if constexpr(internal::slide_caches_nothing<View>) {
            return iterator<false>(std::ranges::begin(this->_base) + std::ranges::range_difference_t<View>(this->size()), this->_n);
        }
        else if constexpr(internal::slide_caches_last<View>) {
            std::ranges::iterator_t<View> itr;

            if(this->_cache_end.has_value()) {
                itr = this->_cache_end.get(this->_base);
            }
            else {
                itr = std::ranges::prev(std::ranges::end(this->_base), this->_n - 1, std::ranges::begin(this->_base));
                this->_cache_end.set(this->_base, itr);
            }

            return iterator<false>(std::move(itr), this->_n);
        }
        else if constexpr(std::ranges::common_range<View>) {
            return iterator<false>(std::ranges::end(this->_base), std::ranges::end(this->_base), this->_n);
        }
        else {
            return sentinel(std::ranges::end(this->_base));
        }
    }

    constexpr auto end() const
        requires internal::slide_caches_nothing<const View>
    {
        return this->begin() + std::ranges::range_difference_t<const View>(this->size());
    }

    constexpr auto size()
        requires std::ranges::sized_range<View>
    {
        auto size = std::ranges::distance(this->_base) - this->_n + 1;
        if(size < 0) size = 0;

        return to_unsigned(size);
    }

    constexpr auto size() const
        requires std::ranges::sized_range<const View>
    {
        auto size = std::ranges::distance(this->_base) - this->_n + 1;
        if(size < 0) size = 0;

        return to_unsigned(size);
    }
};

template<class Range>
slide_view(Range &&, std::ranges::range_difference_t<Range>) -> slide_view<std::views::all_t<Range>>;


template<std::ranges::forward_range View>
    requires std::ranges::view<View>
template<bool CONST>
struct slide_view<View>::iterator {
  private:
    using Base = internal::maybe_const_t<CONST, View>;

    static constexpr bool LAST_PRESENT = internal::slide_caches_first<Base>;

    std::ranges::iterator_t<Base> _current = std::ranges::iterator_t<Base>();

    [[no_unique_address]] internal::maybe_present_t<LAST_PRESENT, std::ranges::iterator_t<Base>> _last = decltype(_last)();
    std::ranges::range_difference_t<Base> _n = 0;

    constexpr iterator(std::ranges::iterator_t<Base> current, std::ranges::range_difference_t<Base> n)
        requires (!LAST_PRESENT)
      : _current(current), _n(n)
    {}

    constexpr iterator(std::ranges::iterator_t<Base> current, std::ranges::iterator_t<Base> last, std::ranges::range_difference_t<Base> n)
        requires (LAST_PRESENT)
        : _current(current), _last(last), _n(n)
    {}


    friend slide_view;
    friend slide_view::sentinel;

  public:
    using iterator_category = std::input_iterator_tag;
    using iterator_concept = internal::most_primitive_iterator_concept<false, Base>;

    using value_type = decltype(std::views::counted(_current, _n));

    using difference_type = std::ranges::range_difference_t<Base>;

    iterator() = default;

    constexpr iterator(iterator<!CONST> itr)
        requires CONST && std::convertible_to<std::ranges::iterator_t<View>, std::ranges::iterator_t<Base>>
      : _current(std::move(itr._current)), _n(itr._n)
    {}

    constexpr auto operator*() const {
        return std::views::counted(_current, _n);
    }

    constexpr iterator &operator++() {
        ++this->_current;
        if constexpr(LAST_PRESENT) ++this->_last;
        return *this;
    }

    constexpr iterator operator++(int) {
        const auto temp = *this;
        return ++*this, temp;
    }

    constexpr iterator &operator--()
        requires std::ranges::bidirectional_range<Base>
    {
        --this->_current;
        if constexpr(LAST_PRESENT) --this->_last;
        return *this;
    }

    constexpr iterator operator--(int)
        requires std::ranges::bidirectional_range<Base>
    {
        auto temp = *this;
        return --*this, temp;
    }

    constexpr iterator &operator+=(const difference_type rhs)
        requires std::ranges::random_access_range<Base>
    {
        this->_current += rhs;
        if constexpr(LAST_PRESENT) this->_last += rhs;
        return *this;
    }

    constexpr iterator &operator-=(const difference_type rhs)
        requires std::ranges::random_access_range<Base>
    {
        this->_current -= rhs;
        if constexpr(LAST_PRESENT) this->_last -= rhs;
        return *this;
    }

    constexpr auto operator[](const difference_type count) const
        requires std::ranges::random_access_range<Base>
    {
        return std::views::counted(this->_current + count, this->_n);
    }

    friend constexpr bool operator==(const iterator &lhs, const iterator &rhs) {
        if constexpr(LAST_PRESENT) return lhs._last == rhs._last;
        else return lhs._current == rhs._current;
    }

    friend constexpr auto operator<=>(const iterator &lhs, const iterator &rhs)
        requires std::ranges::random_access_range<Base> && std::three_way_comparable<std::ranges::iterator_t<Base>>
    {
        return lhs._current <=> rhs._current;
    }

    friend constexpr iterator operator+(iterator itr, const difference_type count)
        requires std::ranges::random_access_range<Base>
    {
        auto res = itr;
        return res += count, res;
    }

    friend constexpr iterator operator+(const difference_type count, const iterator &itr)
        requires std::ranges::random_access_range<Base>
    {
        auto res = itr;
        return res += count, res;
    }

    friend constexpr iterator operator-(const iterator &itr, difference_type count)
        requires std::ranges::random_access_range<Base>
    {
        auto res = itr;
        return res -= count, res;
    }

    friend constexpr difference_type operator-(const iterator &lhs, const iterator &rhs)
        requires std::sized_sentinel_for<std::ranges::iterator_t<Base>, std::ranges::iterator_t<Base>>
    {
        if constexpr(LAST_PRESENT) return lhs._last - rhs._last;
        else return lhs._current - rhs._current;
    }
};


template<std::ranges::forward_range View>
    requires std::ranges::view<View>
struct slide_view<View>::sentinel {
  private:
    std::ranges::sentinel_t<View> _end = std::ranges::sentinel_t<View>();

    constexpr explicit sentinel(std::ranges::sentinel_t<View> end) : _end(end) {}

    friend slide_view;

  public:
    sentinel() = default;

    friend constexpr bool operator==(const iterator<false> &lhs, const sentinel &rhs) {
        return lhs._last == rhs._end;
    }

    friend constexpr std::ranges::range_difference_t<View>
    operator-(const iterator<false> &lhs, const sentinel &rhs)
        requires std::sized_sentinel_for<std::ranges::sentinel_t<View>, std::ranges::iterator_t<View>>
    {
        return lhs._last - rhs._end;
    }

    friend constexpr std::ranges::range_difference_t<View>
    operator-(const sentinel &rhs, const iterator<false> &lhs)
        requires std::sized_sentinel_for<std::ranges::sentinel_t<View>, std::ranges::iterator_t<View>>
    {
        return rhs._end - lhs._last;
    }
};


namespace views {


namespace internal {


template<class Range, class Diff>
concept can_slide_view = requires { slide_view(std::declval<Range>(), std::declval<Diff>()); };


} // namespace internal



struct Slide : adaptor::range_adaptor<Slide> {
    template<std::ranges::viewable_range Range, class Diff = std::ranges::range_difference_t<Range>>
        requires internal::can_slide_view<Range, Diff>

    constexpr auto operator() [[nodiscard]] (Range &&res, std::type_identity_t<Diff> n) const {
        return slide_view(std::forward<Range>(res), n);
    }

    using adaptor::range_adaptor<Slide>::operator();

    static constexpr int arity = 2;
    static constexpr bool has_simple_extra_args = true;
};


inline constexpr Slide slide;


} // namespace views

} // namespace uni


namespace std::ranges {


template<class View>
inline constexpr bool enable_borrowed_range<uni::slide_view<View>> = enable_borrowed_range<View>;


}
#line 2 "view/stride.hpp"

#line 8 "view/stride.hpp"

#line 12 "view/stride.hpp"

#line 14 "view/stride.hpp"

#line 16 "view/stride.hpp"


namespace uni {


template<std::ranges::input_range View>
    requires std::ranges::view<View>
struct stride_view : std::ranges::view_interface<stride_view<View>> {
  private:
    View _base;
    std::ranges::range_difference_t<View> _stride;

    template<bool Const> using Base = internal::maybe_const_t<Const, View>;

    template<bool Const> struct iterator_tag {};

    template<bool Const>
        requires std::ranges::forward_range<Base<Const>>
    struct iterator_tag<Const> {
      private:
        static constexpr auto _iterator_category() noexcept {
            using category = typename std::iterator_traits<std::ranges::iterator_t<Base<Const>>>::iterator_category;
            if constexpr(std::derived_from<category, std::random_access_iterator_tag>)
                return std::random_access_iterator_tag{};
            else
                return category{};
        }

      public:
        using iterator_category = decltype(_iterator_category());
    };

  public:
    template<bool> class iterator;

    constexpr explicit stride_view(View base, const std::ranges::range_difference_t<View> stride) noexcept(NO_EXCEPT)
       : _base(std::move(base)), _stride(stride) { assert(stride > 0); }

    inline constexpr View base() const & noexcept(NO_EXCEPT) requires std::copy_constructible<View>
    {
        return this->_base;
    }

    inline constexpr View base() && noexcept(NO_EXCEPT) { return std::move(this->_base); }

    inline constexpr std::ranges::range_difference_t<View> stride() const noexcept {
        return this->_stride;
    }

    inline constexpr auto begin() noexcept(NO_EXCEPT)
        requires(!internal::simple_view<View>)
    {
        return iterator<false>(this, std::ranges::begin(this->_base));
    }

    inline constexpr auto begin() const noexcept(NO_EXCEPT)
        requires std::ranges::range<const View>
    {
        return iterator<true>(this, std::ranges::begin(this->_base));
    }

    inline constexpr auto end() noexcept(NO_EXCEPT)
        requires(!internal::simple_view<View>)
    {
        if constexpr(std::ranges::common_range<View> && std::ranges::sized_range<View> &&
                     std::ranges::forward_range<View>) {
            const auto missing = (this->_stride - std::ranges::distance(this->_base) % this->_stride) % this->_stride;
            return iterator<false>(this, std::ranges::end(this->_base), missing);
        } else if constexpr(std::ranges::common_range<View> && !std::ranges::bidirectional_range<View>)
            return iterator<false>(this, std::ranges::end(this->_base));
        else
            return std::default_sentinel;
    }

    inline constexpr auto end() const noexcept(NO_EXCEPT)
        requires std::ranges::range<const View>
    {
        if constexpr(std::ranges::common_range<const View> && std::ranges::sized_range<const View> && std::ranges::forward_range<const View>)
        {
            const auto missing = (this->_stride - std::ranges::distance(this->_base) % this->_stride) % this->_stride;
            return iterator<true>(this, std::ranges::end(this->_base), missing);
        }
        else if constexpr(std::ranges::common_range<const View> && !std::ranges::bidirectional_range<const View>)
            return iterator<true>(this, std::ranges::end(this->_base));
        else
            return std::default_sentinel;
    }

    inline constexpr auto size() noexcept(NO_EXCEPT)
        requires std::ranges::sized_range<View>
    {
        return to_unsigned(div_ceil(std::ranges::distance(this->_base), this->_stride));
    }

    inline constexpr auto size() const noexcept(NO_EXCEPT)
        requires std::ranges::sized_range<const View>
    {
        return to_unsigned(div_ceil(std::ranges::distance(this->_base), this->_stride));
    }
};

template<class Range>
stride_view(Range&& , std::ranges::range_difference_t<Range>) -> stride_view<std::views::all_t<Range>>;


template<std::ranges::input_range View>
    requires std::ranges::view<View>
template<bool Const>
struct stride_view<View>::iterator : iterator_tag<Const> {
  private:
    using Parent = internal::maybe_const_t<Const, stride_view>;
    using Base = stride_view::Base<Const>;

    std::ranges::iterator_t<Base> _current = std::ranges::iterator_t<Base>();
    std::ranges::sentinel_t<Base> _end = std::ranges::sentinel_t<Base>();
    std::ranges::range_difference_t<Base> _stride = 0;
    std::ranges::range_difference_t<Base> _missing = 0;

    constexpr iterator(Parent *const parent, const std::ranges::iterator_t<Base> current, const std::ranges::range_difference_t<Base> missing = 0) noexcept(NO_EXCEPT)
      : _current(std::move(current)), _end(std::ranges::end(parent->_base)), _stride(parent->_stride), _missing(missing)
    {}

    friend stride_view;

  public:
    using difference_type = std::ranges::range_difference_t<Base>;
    using value_type = std::ranges::range_value_t<Base>;
    using iterator_concept = typename internal::iterator_concept<Base>;

    iterator() noexcept(NO_EXCEPT) requires std::default_initializable<std::ranges::iterator_t<Base>> = default;

    constexpr iterator(iterator<!Const> itr) noexcept(NO_EXCEPT)
        requires
            Const && std::convertible_to<std::ranges::iterator_t<View>, std::ranges::iterator_t<Base>> &&
            std::convertible_to<std::ranges::sentinel_t<View>, std::ranges::sentinel_t<Base>>
      : _current(std::move(itr._current)), _end(std::move(itr._end)), _stride(itr._stride), _missing(itr._missing)
    {}

    inline constexpr std::ranges::iterator_t<Base> base() && noexcept(NO_EXCEPT) { return std::move(this->_current); }

    inline constexpr const std::ranges::iterator_t<Base>& base() const & noexcept {
        return this->_current;
    }

    inline constexpr decltype(auto) operator*() const noexcept(NO_EXCEPT)
    {
        return *this->_current;
    }

    inline constexpr iterator& operator++() noexcept(NO_EXCEPT)
    {
        assert(this->_current != _end);
        this->_missing = std::ranges::advance(this->_current, this->_stride, this->_end);
        return *this;
    }

    inline constexpr void operator++(int) noexcept(NO_EXCEPT) { ++*this; }

    inline constexpr iterator operator++(int) noexcept(NO_EXCEPT)
        requires std::ranges::forward_range<Base>
    {
        const auto res = *this; ++*this; return res;
    }

    inline constexpr iterator& operator--() noexcept(NO_EXCEPT)
        requires std::ranges::bidirectional_range<Base>
    {
        std::ranges::advance(this->_current, this->_missing - this->_stride);
        this->_missing = 0;
        return *this;
    }

    inline constexpr iterator operator--(int) noexcept(NO_EXCEPT)
        requires std::ranges::bidirectional_range<Base>
    {
        const auto res = *this; --*this; return res;
    }

    inline constexpr iterator& operator+=(const difference_type diff) noexcept(NO_EXCEPT)
        requires std::ranges::random_access_range<Base>
    {
        if(diff > 0) {
            assert(std::ranges::distance(this->_current, this->_end) > this->_stride * (diff - 1));
            this->_missing = std::ranges::advance(this->_current, this->_stride * diff, this->_end);
        }
        if(diff < 0) {
            std::ranges::advance(this->_current, this->_stride * diff + this->_missing);
            this->_missing = 0;
        }
        return *this;
    }

    inline constexpr iterator& operator-=(const difference_type diff) noexcept(NO_EXCEPT)
        requires std::ranges::random_access_range<Base>
    {
        return *this += -diff;
    }

    inline constexpr decltype(auto) operator[](const difference_type diff) const noexcept(NO_EXCEPT)
        requires std::ranges::random_access_range<Base>
    {
        return *(*this + diff);
    }

    friend inline constexpr bool operator==(const iterator& lhs, std::default_sentinel_t) noexcept(NO_EXCEPT)
    {
        return lhs._current == lhs._end;
    }

    friend inline constexpr bool operator==(const iterator& lhs, const iterator& rhs) noexcept(NO_EXCEPT)
        requires std::equality_comparable<std::ranges::iterator_t<Base>>
    {
        return lhs._current == rhs._current;
    }

    friend inline constexpr auto operator<=>(const iterator& lhs, const iterator& rhs) noexcept(NO_EXCEPT)
        requires std::ranges::random_access_range<Base> && std::three_way_comparable<std::ranges::iterator_t<Base>>
    {
        return lhs._current <=> rhs._current;
    }

    friend inline constexpr iterator operator+(const iterator& itr, const difference_type diff) noexcept(NO_EXCEPT)
        requires std::ranges::random_access_range<Base>
    {
        auto res = itr; res += diff; return res;
    }

    friend inline constexpr iterator operator+(const difference_type diff, const iterator& itr) noexcept(NO_EXCEPT)
        requires std::ranges::random_access_range<Base>
    {
        return itr + diff;
    }

    friend inline constexpr iterator operator-(const iterator& itr, const difference_type diff) noexcept(NO_EXCEPT)
        requires std::ranges::random_access_range<Base>
    {
        auto res = itr; res -= diff; return res;
    }

    friend inline constexpr const difference_type operator-(const iterator& lhs, const iterator& rhs) noexcept(NO_EXCEPT)
        requires std::sized_sentinel_for<std::ranges::iterator_t<Base>, std::ranges::iterator_t<Base>>
    {
        const auto diff = lhs._current - rhs._current;
        if constexpr(std::ranges::forward_range<Base>)
            return (diff + lhs._missing - rhs._missing) / lhs._stride;
        else if(diff < 0)
            return -div_ceil(-diff, lhs._stride);
        else
            return div_ceil(diff, lhs._stride);
    }

    friend inline constexpr const difference_type operator-(std::default_sentinel_t, const iterator& rhs) noexcept(NO_EXCEPT)
        requires std::sized_sentinel_for<std::ranges::sentinel_t<Base>, std::ranges::iterator_t<Base>>
    {
        return div_ceil(rhs._end - rhs._current, rhs._stride);
    }

    friend inline constexpr const difference_type operator-(const iterator& lhs, std::default_sentinel_t rhs) noexcept(NO_EXCEPT)
        requires std::sized_sentinel_for<std::ranges::sentinel_t<Base>, std::ranges::iterator_t<Base>>
    {
        return -(rhs - lhs);
    }

    friend inline constexpr std::ranges::range_rvalue_reference_t<Base> iter_move(const iterator& itr) noexcept(NO_EXCEPT)
    {
        return std::ranges::iter_move(itr._current);
    }

    friend inline constexpr void iter_swap(const iterator& lhs, const iterator& rhs) noexcept(NO_EXCEPT)
        requires std::indirectly_swappable<std::ranges::iterator_t<Base>>
    {
        std::ranges::iter_swap(lhs._current, rhs._current);
    }
};


namespace views {

namespace internal {

template<class Range, class T>
concept can_stride_view = requires { stride_view(std::declval<Range>(), std::declval<T>()); };

}

struct Stride : adaptor::range_adaptor<Stride> {
    template<std::ranges::viewable_range Range, class T = std::ranges::range_difference_t<Range>>
        requires internal::can_stride_view<Range, T>
    inline constexpr auto operator() [[nodiscard]] (Range&& res, std::type_identity_t<T> diff) const
    {
        return stride_view(std::forward<Range>(res), diff);
    }

    using adaptor::range_adaptor<Stride>::operator();
    static constexpr int arity = 2;
    static constexpr bool has_simple_call_op = true;
};

inline constexpr Stride stride;


} // namespace views

} // namespace uni


namespace std::ranges {


template<class View>
inline constexpr bool enable_borrowed_range<uni::stride_view<View>> = enable_borrowed_range<View>;


} // namespace std::ranges
#line 2 "view/zip.hpp"


#line 7 "view/zip.hpp"

#line 9 "view/zip.hpp"

#line 14 "view/zip.hpp"


namespace uni {


template<std::ranges::input_range... Views> requires(std::ranges::view<Views> && ...) && (sizeof...(Views) > 0)
struct zip_view : std::ranges::view_interface<zip_view<Views...>> {
  private:
    std::tuple<Views...> _views;

  public:
    template<bool> struct iterator;
    template<bool> struct sentinel;

    zip_view() = default;

    constexpr explicit zip_view(Views... views) noexcept(NO_EXCEPT) : _views(std::move(views)...) {}

    constexpr auto begin() noexcept(NO_EXCEPT) requires(!(internal::simple_view<Views> && ...))
    {
        return iterator<false>(tuple_transform(std::ranges::begin, this->_views));
    }

    constexpr auto begin() const noexcept(NO_EXCEPT) requires(std::ranges::range<const Views> && ...)
    {
        return iterator<true>(tuple_transform(std::ranges::begin, this->_views));
    }

    constexpr auto end() noexcept(NO_EXCEPT) requires(!(internal::simple_view<Views> && ...))
    {
        if constexpr(!internal::zip_is_common<Views...>)
            return sentinel<false>(tuple_transform(std::ranges::end, this->_views));
        else if constexpr((std::ranges::random_access_range<Views> && ...))
            return begin() + std::iter_difference_t<iterator<false>>(this->size());
        else
            return iterator<false>(tuple_transform(std::ranges::end, this->_views));
    }

    constexpr auto end() const noexcept(NO_EXCEPT) requires(std::ranges::range<const Views> && ...)
    {
        if constexpr(!internal::zip_is_common<const Views...>)
            return sentinel<true>(tuple_transform(std::ranges::end, this->_views));
        else if constexpr((std::ranges::random_access_range<const Views> && ...))
            return this->begin() + std::iter_difference_t<iterator<true>>(this->size());
        else
            return iterator<true>(tuple_transform(std::ranges::end, _views));
    }

    constexpr auto size() noexcept(NO_EXCEPT) requires(std::ranges::sized_range<Views> && ...)
    {
        return std::apply(
            [](auto... sizes)
            {
                using size_type = std::make_unsigned_t<std::common_type_t<decltype(sizes)...>>;
                return uni::min(size_type(sizes)...);
            },
           tuple_transform(std::ranges::size, _views)
        );
    }

    constexpr auto size() const noexcept(NO_EXCEPT) requires(std::ranges::sized_range<const Views> && ...)
    {
        return std::apply(
            [](auto... sizes)
            {
                using size_type = std::make_unsigned_t<std::common_type_t<decltype(sizes)...>>;
                return uni::min(size_type(sizes)...);
            },
           tuple_transform(std::ranges::size, _views)
        );
    }
};

template<class... Ranges> zip_view(Ranges &&...) -> zip_view<std::views::all_t<Ranges>...>;

namespace internal {


template<class iterator>
constexpr const typename iterator::iterator_collection& get_current(const iterator& itr) noexcept(NO_EXCEPT);


} // namespace internal


template<std::ranges::input_range... Views> requires(std::ranges::view<Views> && ...) && (sizeof...(Views) > 0)
template<bool Const>
struct zip_view<Views...>::iterator
    : internal::zip_view_iterator_category<Const, Views...> {
    using iterator_collection = internal::tuple_or_pair_t<
            std::ranges::iterator_t<internal::maybe_const_t<Const, Views>>...
        >;

  private:
    friend struct zip_view;
    template<bool> friend struct zip_view::sentinel;

    iterator_collection _current;

    constexpr explicit iterator(decltype(_current) current) : _current(std::move(current)) {}

    // template<std::copy_constructible F, std::ranges::input_range... Vs>
    //     requires
    //         (std::ranges::view<Vs> && ...) && (sizeof...(Vs) > 0) && std::is_object_v<F> &&
    //         std::regular_invocable<F&, std::ranges::range_reference_t<Vs>...> &&
    //         internal::can_reference<std::invoke_result_t<F&, std::ranges::range_reference_t<Vs>...>>
    // friend struct zip_transform_view;


  public:
    using iterator_concept = internal::most_primitive_iterator_concept<Const, Views...>;

    using value_type = internal::tuple_or_pair_t<std::ranges::range_value_t<internal::maybe_const_t<Const, Views>>...>;

    using difference_type = std::common_type_t<std::ranges::range_difference_t<internal::maybe_const_t<Const, Views>>...>;

    iterator() = default;

    constexpr iterator(iterator<!Const> itr) noexcept(NO_EXCEPT)
        requires Const &&
                (
                    std::convertible_to<
                        std::ranges::iterator_t<Views>,
                        std::ranges::iterator_t<internal::maybe_const_t<Const, Views>>
                    > && ...
                )
      : _current(std::move(itr._current))
    {}


    constexpr auto operator*() const noexcept(NO_EXCEPT) {
        const auto f = [](auto &itr) -> decltype(auto) { return *itr; };
        return tuple_transform(f, this->_current);
    }

    constexpr iterator& operator++() noexcept(NO_EXCEPT) {
        tuple_for_each([](auto &itr) { ++itr; }, this->_current);
        return *this;
    }

    constexpr void operator++(int) noexcept(NO_EXCEPT) { ++*this; }

    constexpr iterator operator++(int) noexcept(NO_EXCEPT)
        requires internal::all_forward<Const, Views...>
    {
        const auto res = *this; ++*this; return res;
    }

    constexpr iterator& operator--() noexcept(NO_EXCEPT)
        requires internal::all_bidirectional<Const, Views...>
    {
        tuple_for_each([](auto &itr) { --itr; }, this->_current);
        return *this;
    }

    constexpr iterator operator--(int) noexcept(NO_EXCEPT)
        requires internal::all_bidirectional<Const, Views...>
    {
        const auto res = *this; --*this; return res;
    }

    constexpr iterator& operator+=(const difference_type diff) noexcept(NO_EXCEPT)
        requires internal::all_random_access<Const, Views...>
    {
        const auto f = [&]<class Itr>(Itr& itr) constexpr noexcept(NO_EXCEPT) {
            itr += std::iter_difference_t<Itr>(diff);
        };
        tuple_for_each(f, this->_current);
        return *this;
    }

    constexpr iterator& operator-=(const difference_type diff) noexcept(NO_EXCEPT)
        requires internal::all_random_access<Const, Views...>
    {
        const auto f = [&]<class Itr>(Itr& itr) constexpr noexcept(NO_EXCEPT) {
            itr -= std::iter_difference_t<Itr>(diff);
        };
        tuple_for_each(f, this->_current);
        return *this;
    }

    constexpr auto operator[](const difference_type diff) const noexcept(NO_EXCEPT)
        requires internal::all_random_access<Const, Views...>
    {
        const auto f = [&]<class Itr>(Itr& itr) constexpr noexcept(NO_EXCEPT) -> decltype(auto) {
            return itr[std::iter_difference_t<Itr>(diff)];
        };
        return tuple_transform(f, _current);
    }

    friend constexpr bool operator==(const iterator& lhs, const iterator& rhs) noexcept(NO_EXCEPT)
        requires (
            std::equality_comparable<
                std::ranges::iterator_t<internal::maybe_const_t<Const, Views>>
            > && ...
        )
    {
        if constexpr(internal::all_bidirectional<Const, Views...>)
            return lhs._current == rhs._current;
        else
            return [&]<std::size_t... Is>(std::index_sequence<Is...>) constexpr noexcept(NO_EXCEPT) {
                return (
                    (std::get<Is>(lhs._current) == std::get<Is>(rhs._current)) || ...
                );
            }(std::make_index_sequence<sizeof...(Views)>{});
    }

    friend constexpr auto operator<=>(const iterator& lhs, const iterator& rhs) noexcept(NO_EXCEPT)
        requires internal::all_random_access<Const, Views...>
    {
        return lhs._current <=> rhs._current;
    }

    friend constexpr iterator operator+(const iterator& itr, const difference_type diff) noexcept(NO_EXCEPT)
        requires internal::all_random_access<Const, Views...>
    {
        auto res = itr; res += diff; return res;
    }

    friend constexpr iterator operator+(const difference_type diff, const iterator& itr) noexcept(NO_EXCEPT)
        requires internal::all_random_access<Const, Views...>
    {
        auto res = itr; res += diff; return res;
    }

    friend constexpr iterator operator-(const iterator& itr, const difference_type diff) noexcept(NO_EXCEPT)
        requires internal::all_random_access<Const, Views...>
    {
        auto res = itr; res -= diff; return res;
    }

    friend constexpr difference_type operator-(const iterator& lhs, const iterator& rhs) noexcept(NO_EXCEPT)
        requires (
            std::sized_sentinel_for<
                std::ranges::iterator_t<internal::maybe_const_t<Const, Views>>,
                std::ranges::iterator_t<internal::maybe_const_t<Const, Views>>
            > && ...
        )
    {
        return [&]<std::size_t... Is>(std::index_sequence<Is...>) constexpr noexcept(NO_EXCEPT) {
            return std::ranges::min(
                {
                    difference_type(std::get<Is>(lhs._current) - std::get<Is>(rhs._current)) ...
                },
                std::ranges::less{},
                [](const difference_type diff) constexpr noexcept(NO_EXCEPT) {
                    return to_unsigned(diff < 0 ? -diff : diff);
                }
            );
        }(std::make_index_sequence<sizeof...(Views)>{});
    }

    friend constexpr auto iter_move(const iterator& itr) noexcept(NO_EXCEPT) {
        return tuple_transform(std::ranges::iter_move, itr._current);
    }

    friend constexpr void iter_swap(const iterator& lhs, const iterator& res) noexcept(NO_EXCEPT)
        requires (
            std::indirectly_swappable<
                std::ranges::iterator_t<internal::maybe_const_t<Const, Views>>
            > && ...
        )
    {
        [&]<std::size_t... Is>(std::index_sequence<Is...>) constexpr noexcept(NO_EXCEPT) {
            (
                std::ranges::iter_swap(std::get<Is>(lhs._current), std::get<Is>(res._current)), ...
            );
        }(std::make_index_sequence<sizeof...(Views)>{});
    }

    template<class Itr> friend constexpr const typename Itr::iterator_collection& internal::get_current(const Itr&) noexcept(NO_EXCEPT);
};


template<class iterator>
constexpr const typename iterator::iterator_collection& internal::get_current(const iterator& itr) noexcept(NO_EXCEPT) { return itr._current; };


template<std::ranges::input_range... Views> requires(std::ranges::view<Views> && ...) && (sizeof...(Views) > 0)
template<bool Const>
struct zip_view<Views...>::sentinel {
    friend struct zip_view;
    template<bool> friend struct zip_view::iterator;

    using sentinel_collection = internal::tuple_or_pair_t<
            std::ranges::sentinel_t<internal::maybe_const_t<Const, Views>>...
        >;

    sentinel_collection _end;

    constexpr explicit sentinel(sentinel_collection end) noexcept(NO_EXCEPT) : _end(end) {}

  public:
    sentinel() = default;

    constexpr sentinel(sentinel<!Const> itr) noexcept(NO_EXCEPT)
        requires Const &&
                (
                    std::convertible_to<
                        std::ranges::sentinel_t<Views>,
                        std::ranges::sentinel_t<internal::maybe_const_t<Const, Views>>
                    > && ...
                )
      : _end(std::move(itr._end))
    {}

    template<bool Const_>
        requires (
            std::sentinel_for<
                std::ranges::sentinel_t<internal::maybe_const_t<Const, Views>>,
                std::ranges::iterator_t<internal::maybe_const_t<Const_, Views>>
            > && ...
        )
    friend constexpr bool operator==(const iterator<Const_>& lhs, const sentinel& rhs) noexcept(NO_EXCEPT)
    {
        return [&]<std::size_t... Is>(std::index_sequence<Is...>) constexpr noexcept(NO_EXCEPT) {
            return (
                (std::get<Is>(internal::get_current(lhs)) == std::get<Is>(rhs._end)) || ...);
        }(std::make_index_sequence<sizeof...(Views)>{});
    }

    template<bool Const_>
        requires (
            std::sized_sentinel_for<
                std::ranges::sentinel_t<internal::maybe_const_t<Const, Views>>,
                std::ranges::iterator_t<internal::maybe_const_t<Const_, Views>>
            > && ...
        )
    friend constexpr auto operator-(const iterator<Const_>& lhs, const sentinel& rhs) noexcept(NO_EXCEPT)
    {
        using return_type = std::common_type_t<std::ranges::range_difference_t<internal::maybe_const_t<Const_, Views>>...>;
        return [&]<std::size_t... Is>(std::index_sequence<Is...>) constexpr noexcept(NO_EXCEPT) {
            return std::ranges::min(
                { return_type(std::get<Is>(internal::get_current(lhs)) - std::get<Is>(rhs._end))... },
                std::ranges::less{},
                [](const return_type diff) {
                    return to_unsigned(diff < 0 ? -diff : diff);
                }
            );
        }(std::make_index_sequence<sizeof...(Views)>{});
    }

    template<bool Const_>
        requires (
            std::sized_sentinel_for<
                std::ranges::sentinel_t<internal::maybe_const_t<Const, Views>>,
                std::ranges::iterator_t<internal::maybe_const_t<Const_, Views>>
            > && ...
        )
    friend constexpr auto operator-(const sentinel &lhs, const iterator<Const_>& rhs) noexcept(NO_EXCEPT)
    {
        return -(rhs - lhs);
    }
};


namespace views {

namespace internal {


template<class... Ts>
concept can_zip_view = requires { zip_view<std::views::all_t<Ts>...>(std::declval<Ts>()...); };


} // namespace internal


struct Zip {
    template<class... Ts> requires(sizeof...(Ts) == 0 || internal::can_zip_view<Ts...>)
    constexpr auto operator() [[nodiscard]] (Ts&&... vs) const {
        if constexpr(sizeof...(Ts) == 0) return std::views::empty<std::tuple<>>;
        else return zip_view<std::views::all_t<Ts>...>(std::forward<Ts>(vs)...);
    }
};


inline constexpr Zip zip;


} // namespace views

} // namespace uni.


namespace std::ranges {


template<class... Views>
inline constexpr bool enable_borrowed_range<uni::zip_view<Views...>> = (enable_borrowed_range<Views> && ...);


}
#line 15 "include/all.hpp"

#line 2 "random/adaptor.hpp"


#line 6 "random/adaptor.hpp"

#line 8 "random/adaptor.hpp"


namespace uni {


template<class Engine>
struct random_adaptor {
    using result_type = typename Engine::result_type;
    using signed_result_type = typename std::make_signed_t<result_type>;

  private:
    Engine engine;

  public:
    static constexpr result_type MIN = Engine::min();
    static constexpr result_type MAX = Engine::max();

    static constexpr result_type min() noexcept(NO_EXCEPT) { return MIN; }
    static constexpr result_type max() noexcept(NO_EXCEPT) { return MAX; }

    constexpr random_adaptor(unsigned long seed = 3141592653UL) noexcept(NO_EXCEPT) { this->engine.seed(seed); };

    inline constexpr result_type operator()() noexcept(NO_EXCEPT) {
        return this->engine();
    }

    inline constexpr result_type operator()(const result_type sup) noexcept(NO_EXCEPT) {
        assert(0 < sup);
        return this->engine() % sup;
    }
    inline constexpr signed_result_type operator()(const signed_result_type min, const signed_result_type sup) noexcept(NO_EXCEPT) {
        assert(min < sup);
        return min + (*this)(sup - min);
    };

    template<class T = double>
    inline constexpr auto real() noexcept(NO_EXCEPT) {
        const auto v = static_cast<T>((this->engine() + 0.5) / (1.0 + this->max()));
        return static_cast<T>((this->operator()() + v) / (1.0 + this->max()));
    }
};


} // namespace uni
#line 18 "include/all.hpp"

#line 2 "utility/restrictor.hpp"

#line 4 "utility/restrictor.hpp"

#line 6 "utility/restrictor.hpp"


namespace uni {


template<class T, T INF, T SUP>
struct static_restrictor {
    using restrictor = static_restrictor;

  protected:
    T _v = INF;

    inline void _clamp() noexcept(NO_EXCEPT) { this->_v = std::clamp(this->_v, INF, SUP); }
    inline restrictor& _assign(const T& v) noexcept(NO_EXCEPT) {
        this->_v = std::clamp(v, INF, SUP);
        return *this;
    }
    inline restrictor& _assign_raw(const T& v) noexcept(NO_EXCEPT) {
        this->_v = v;
        return *this;
    }

  public:
    static_restrictor() noexcept(NO_EXCEPT) = default;
    static_restrictor(T v) noexcept(NO_EXCEPT) : _v(v) { this->_clamp(); }

    inline T val() const noexcept(NO_EXCEPT) { return this->_v; }

    static inline static_restrictor raw(const T& v) noexcept(NO_EXCEPT) {
        static_restrictor res;
        res._assign_raw(v);
        return res;
    }

    restrictor& operator++() noexcept(NO_EXCEPT) { return this->_assign(this->_v + 1); }
    restrictor& operator--() noexcept(NO_EXCEPT) { return this->_assign(this->_v - 1); }
    restrictor operator++(int) noexcept(NO_EXCEPT) { auto res = *this; return ++(*this), res; }
    restrictor operator--(int) noexcept(NO_EXCEPT) { auto res = *this; return --(*this), res; }

    restrictor& operator+=(const restrictor& rhs) noexcept(NO_EXCEPT) {
        return this->_assign_raw(add_clamp(this->_v, rhs._v, INF, SUP));
    }
    restrictor& operator-=(const restrictor& rhs) noexcept(NO_EXCEPT) {
        return this->_assign_raw(sub_clamp(this->_v, rhs._v, INF, SUP));
    }
    restrictor& operator*=(const restrictor& rhs) noexcept(NO_EXCEPT) {
        return this->_assign_raw(mul_clamp(this->_v, rhs._v, INF, SUP));
    }
    restrictor& operator/=(const restrictor& rhs) noexcept(NO_EXCEPT) {
        return this->_assign(this->_v / rhs.val());
    }

    restrictor operator+() const noexcept(NO_EXCEPT) { return *this; }
    restrictor operator-() const noexcept(NO_EXCEPT) { return restrictor(-this->_v); }

    friend restrictor operator+(restrictor lhs, const restrictor& rhs) noexcept(NO_EXCEPT) {
        return lhs += rhs;
    }
    friend restrictor operator-(restrictor lhs, const restrictor& rhs) noexcept(NO_EXCEPT) {
        return lhs -= rhs;
    }
    friend restrictor operator*(restrictor lhs, const restrictor& rhs) noexcept(NO_EXCEPT) {
        return lhs *= rhs;
    }
    friend restrictor operator/(restrictor lhs, const restrictor& rhs) noexcept(NO_EXCEPT) {
        return lhs /= rhs;
    }
    friend bool operator==(const restrictor& lhs, const restrictor& rhs) noexcept(NO_EXCEPT) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const restrictor& lhs, const restrictor& rhs) noexcept(NO_EXCEPT) {
        return lhs._v != rhs._v;
    }
    friend bool operator<(const restrictor& lhs, const restrictor& rhs) noexcept(NO_EXCEPT) {
        return lhs._v < rhs._v;
    }
    friend bool operator>(const restrictor& lhs, const restrictor& rhs) noexcept(NO_EXCEPT) {
        return lhs._v > rhs._v;
    }
    friend bool operator<=(const restrictor& lhs, const restrictor& rhs) noexcept(NO_EXCEPT) {
        return lhs._v <= rhs._v;
    }
    friend bool operator>=(const restrictor& lhs, const restrictor& rhs) noexcept(NO_EXCEPT) {
        return lhs._v >= rhs._v;
    }
    friend bool operator<=>(const restrictor& lhs, const restrictor& rhs) noexcept(NO_EXCEPT) {
        return lhs._v <=> rhs._v;
    }
};


} // namespace uni


namespace std {


template<class T, T INF, T SUP>
T abs(const uni::static_restrictor<T,INF,SUP>& v) noexcept(NO_EXCEPT) { return std::abs(v.val()); }


}
#line 2 "utility/string.hpp"


#line 7 "utility/string.hpp"


#line 10 "utility/string.hpp"


namespace uni {


template<std::input_iterator I, std::sentinel_for<I> S, class Res = std::string>
Res to_lower(I first, S last) noexcept(NO_EXCEPT) {
    Res res;
    res.reserve(std::ranges::distance(first, last));
    std::ranges::transform(first, last, std::back_inserter(res), ::tolower);
    return res;
}

template<std::input_iterator I, std::sentinel_for<I> S, class Res = std::string>
Res to_uppwer(I first, S last) noexcept(NO_EXCEPT) {
    Res res;
    res.reserve(std::ranges::distance(first, last));
    std::ranges::transform(first, last, std::back_inserter(res), ::toupper);
    return res;
}


template<class Res = std::string>
Res to_lower(const std::string str) noexcept(NO_EXCEPT) {
    return to_lower<std::string::const_iterator, std::string::const_iterator, Res>(std::begin(str), std::end(str));
}

template<class Res = std::string>
Res to_uppwer(const std::string str) noexcept(NO_EXCEPT) {
    return to_uppwer<std::string::const_iterator, std::string::const_iterator, Res>(std::begin(str), std::end(str));
}


} // namespace uni
#line 2 "utility/timer.hpp"


#line 7 "utility/timer.hpp"


#line 10 "utility/timer.hpp"


namespace uni {


struct timer {
    using time_point = std::chrono::milliseconds::rep;
    using progress_type = long double;

  private:
    time_point _time_limit = 0;
    progress_type progress_duration = 0;

    std::chrono::system_clock::time_point clock_start, clock_end;

  public:
    timer() noexcept = default;

    explicit timer(const time_point time_limit) noexcept(NO_EXCEPT) { this->reset(time_limit); }

    inline time_point limit() noexcept(NO_EXCEPT) { return this->_time_limit; }

    inline timer& reset() noexcept(NO_EXCEPT) {
        this->clock_start = std::chrono::system_clock::now();
        this->clock_end = clock_start + std::chrono::milliseconds(this->_time_limit);
        return *this;
    }

    inline timer& reset(const time_point time_limit) noexcept(NO_EXCEPT) {
        this->_time_limit = time_limit;

        this->progress_duration =
            static_cast<progress_type>(
                std::chrono::duration_cast<std::chrono::system_clock::duration>(
                    std::chrono::milliseconds(time_limit)
                ).count()
            );

        return this->reset();
    }

    inline time_point elapsed() const noexcept(NO_EXCEPT) {
        return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - this->clock_start).count();
    }
    inline time_point remaining() const noexcept(NO_EXCEPT) {
        return _time_limit - this->elapsed();
    }

    inline bool expired() const noexcept(NO_EXCEPT) { return this->elapsed() >= _time_limit; }
    inline progress_type progress() const noexcept(NO_EXCEPT) {
        return std::clamp<progress_type>((std::chrono::system_clock::now() - this->clock_start).count() / this->progress_duration, 0, 1);
    }
};


} // namespace uni
#line 23 "include/all.hpp"

#line 25 "include/all.hpp"

#line 28 "include/all.hpp"
Back to top page