Skip to the content.

:heavy_check_mark: template/standard.hpp

Depends on

Verified with

Code

#pragma once

#pragma GCC target ""
#include "template/debug.hpp"
#include "template/using.hpp"
#line 2 "template/standard.hpp"

#pragma GCC target ""
#line 2 "template/debug.hpp"


#ifdef LOCAL_JUDGE

#define DEBUGGER_ENABLED
#define DEBUGGER_COLORED_OUTPUT 1

#endif

#include <string>
#line 2 "debugger/debug.hpp"


#include <iostream>
#include <limits>
#include <iterator>
#include <string_view>
#include <sstream>
#include <array>
#line 11 "debugger/debug.hpp"
#include <cstring>
#include <vector>
#include <bitset>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <utility>
#include <iomanip>
#include <ranges>
#include <concepts>
#include <type_traits>


#line 2 "numeric/int128.hpp"


#include <cctype>
#include <cassert>
#line 8 "numeric/int128.hpp"
#include <algorithm>

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

#include <cstdint>

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 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 12 "numeric/int128.hpp"

#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 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/type_traits.hpp"


#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/concepts.hpp"


#line 8 "internal/concepts.hpp"
#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 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 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 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 2 "template/using.hpp"

#include <bits/stdc++.h>
#line 2 "include/template.hpp"

#line 2 "include/snippets.hpp"

#line 2 "snippet/aliases.hpp"


#line 8 "snippet/aliases.hpp"


#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/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/chunk.hpp"


#line 6 "view/chunk.hpp"


#line 2 "internal/ranges.hpp"


#line 7 "internal/ranges.hpp"


#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 9 "view/chunk.hpp"

#line 2 "numeric/arithmetic.hpp"


#line 10 "numeric/arithmetic.hpp"
#include <optional>
#line 13 "numeric/arithmetic.hpp"
#include <bit>


#include <atcoder/math>


#line 21 "numeric/arithmetic.hpp"

#line 2 "internal/types.hpp"

#line 4 "internal/types.hpp"

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 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 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 8 "iterable/internal/operation_base.hpp"


#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 17 "iterable/operation.hpp"


#line 21 "iterable/operation.hpp"

#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 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 8 "global/constants.hpp"


#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 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/cyclic.hpp"

#line 8 "view/cyclic.hpp"

#line 12 "view/cyclic.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 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 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 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 2 "include/geometries.hpp"

#line 2 "geometry/arrow.hpp"


#line 5 "geometry/arrow.hpp"

#line 7 "geometry/arrow.hpp"

#line 2 "geometry/point.hpp"


#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 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/adaptors.hpp"

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


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

#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 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"

#line 4 "adaptor/io.hpp"

#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 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 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 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/map.hpp"


#line 7 "adaptor/map.hpp"


#line 11 "adaptor/map.hpp"

#line 2 "adaptor/set.hpp"


#line 11 "adaptor/set.hpp"


#line 15 "adaptor/set.hpp"

#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 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 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 7 "include/template.hpp"

#line 2 "algebraic/helper.hpp"


#line 2 "algebraic/base.hpp"


#line 6 "algebraic/base.hpp"


#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 2 "algebraic/null.hpp"


#line 5 "algebraic/null.hpp"


#line 2 "internal/dummy.hpp"


namespace uni {

namespace internal {


struct dummy {};


} // namespace internal

} // namespace uni
#line 9 "algebraic/null.hpp"

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


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


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

#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 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 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/helpers.hpp"

#line 5 "action/helpers.hpp"


#line 2 "action/base.hpp"


#line 6 "action/base.hpp"


#line 11 "action/base.hpp"

#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/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 10 "include/template.hpp"

#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/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/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/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 2 "iterable/counter.hpp"

#line 4 "iterable/counter.hpp"

#line 8 "iterable/counter.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 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/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 19 "include/template.hpp"

#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 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 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 24 "structure/graph.hpp"

#line 26 "structure/graph.hpp"

#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 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/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/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 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 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 27 "include/template.hpp"

#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/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 2 "numeric/fast_prime.hpp"


#line 6 "numeric/fast_prime.hpp"


#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 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 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 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 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 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/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 36 "include/template.hpp"

#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/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 40 "include/template.hpp"

#line 43 "include/template.hpp"

#line 5 "template/using.hpp"


using namespace std::literals;

using std::cin;
using std::cout;

using std::pair;
using std::tuple;

using std::queue;
using std::stack;
using std::priority_queue;

using std::bitset;

using std::ranges::sort;
using std::ranges::reverse;

using std::ranges::min_element;
using std::ranges::max_element;

using std::make_pair;
using std::make_tuple;


using uni::i32;
using uni::u32;
using uni::i64;
using uni::u64;

#ifdef __GNUC__
using uni::i128;
using uni::u128;
#endif

using uni::uint;
using uni::ll;
using uni::ull;
using uni::ld;

using uni::INF32;
using uni::INF64;
using uni::INF;

using uni::MINT;
using uni::INV;
using uni::SINV;

using uni::LN;
using uni::SPC;

using uni::DIRS4;
using uni::DIRS8;
using uni::DIRS4P;
using uni::DIRS8P;

using uni::input_adaptor;
using uni::output_adaptor;

using uni::pow_mod;
using uni::inv_mod;

using uni::spair;

using uni::multi_container;

using uni::modint998244353;
using uni::modint1000000007;
using uni::modint_32;
using uni::modint_64;

using uni::sorted;
using uni::reversed;

using uni::chmin;
using uni::chmax;

using uni::matrix;

using uni::multiset;
using uni::unordered_set;
using uni::unordered_multiset;

using uni::map;
using uni::multimap;
using uni::unordered_map;
using uni::unordered_multimap;

using uni::valarray;
using uni::vector;
using uni::string;
using uni::array;
#line 6 "template/standard.hpp"
Back to top page