m1une's library

This documentation is automatically generated by online-judge-tools/verification-helper

View on GitHub

:heavy_check_mark: verify/monoid/commutative_flags.test.cpp

Depends on

Code

#define PROBLEM "https://judge.yosupo.jp/problem/aplusb"

#include <iostream>

#include "../../acted_monoid/concept.hpp"
#include "../../acted_monoid/range_add_range_arg_max.hpp"
#include "../../acted_monoid/range_add_range_arg_min.hpp"
#include "../../acted_monoid/range_add_range_max.hpp"
#include "../../acted_monoid/range_add_range_min.hpp"
#include "../../acted_monoid/range_add_range_min_count.hpp"
#include "../../acted_monoid/range_add_range_sum.hpp"
#include "../../acted_monoid/range_affine_range_min_max.hpp"
#include "../../acted_monoid/range_affine_range_sum.hpp"
#include "../../acted_monoid/range_affine_range_sum_of_squares.hpp"
#include "../../acted_monoid/range_ap_add_range_sum.hpp"
#include "../../acted_monoid/range_ap_update_range_min_max.hpp"
#include "../../acted_monoid/range_ap_update_range_sum.hpp"
#include "../../acted_monoid/range_bitwise_and_or_xor_range_sum.hpp"
#include "../../acted_monoid/range_flip_range_binary_inversion.hpp"
#include "../../acted_monoid/range_flip_range_sum.hpp"
#include "../../acted_monoid/range_mul_range_sum.hpp"
#include "../../acted_monoid/range_or_range_sum.hpp"
#include "../../acted_monoid/range_update_range_longest_true.hpp"
#include "../../acted_monoid/range_update_range_max.hpp"
#include "../../acted_monoid/range_update_range_max_subarray.hpp"
#include "../../acted_monoid/range_update_range_min.hpp"
#include "../../acted_monoid/range_update_range_product.hpp"
#include "../../acted_monoid/range_update_range_sum.hpp"
#include "../../acted_monoid/range_xor_range_sum.hpp"
#include "../../acted_monoid/range_xor_range_xor.hpp"
#include "../../acted_monoid/wrapper.hpp"
#include "../../beats_acted_monoid/concept.hpp"
#include "../../beats_acted_monoid/wrapper.hpp"
#include "../../monoid/add.hpp"
#include "../../monoid/affine.hpp"
#include "../../monoid/and.hpp"
#include "../../monoid/arg_max.hpp"
#include "../../monoid/arg_min.hpp"
#include "../../monoid/binary_inversion.hpp"
#include "../../monoid/bottom_k.hpp"
#include "../../monoid/bracket.hpp"
#include "../../monoid/concept.hpp"
#include "../../monoid/gcd.hpp"
#include "../../monoid/longest_same.hpp"
#include "../../monoid/longest_true.hpp"
#include "../../monoid/matrix.hpp"
#include "../../monoid/max.hpp"
#include "../../monoid/max_count.hpp"
#include "../../monoid/max_plus_matrix.hpp"
#include "../../monoid/max_subarray.hpp"
#include "../../monoid/min.hpp"
#include "../../monoid/min_count.hpp"
#include "../../monoid/min_max.hpp"
#include "../../monoid/min_plus_matrix.hpp"
#include "../../monoid/min_subarray.hpp"
#include "../../monoid/mul.hpp"
#include "../../monoid/or.hpp"
#include "../../monoid/permutation.hpp"
#include "../../monoid/rolling_hash.hpp"
#include "../../monoid/strict_max2.hpp"
#include "../../monoid/strict_min2.hpp"
#include "../../monoid/top_k.hpp"
#include "../../monoid/top_k_count.hpp"
#include "../../monoid/update.hpp"
#include "../../monoid/wrapper.hpp"
#include "../../monoid/xor.hpp"

namespace {

struct ContestMonoid {
    using value_type = int;

    static constexpr int id() {
        return 0;
    }
    static constexpr int op(const int& a, const int& b) {
        return a + b;
    }
};

struct ContestActedMonoid {
    using value_type = int;
    using operator_type = int;

    static constexpr int id() {
        return 0;
    }
    static constexpr int op(const int& a, const int& b) {
        return a + b;
    }
    static constexpr int op_id() {
        return 0;
    }
    static constexpr int op_comp(const int& f, const int& g) {
        return f + g;
    }
    static constexpr int mapping(const int& f, const int& x) {
        return f + x;
    }
};

constexpr auto int_add = [](const int& a, const int& b) { return a + b; };
constexpr auto int_zero = [] { return 0; };
constexpr auto int_mapping = [](const int& f, const int& x) { return f + x; };
constexpr auto always_applicable = [](const int&, const int&) { return true; };

using DefaultMonoidWrapper = m1une::monoid::Wrapper<int, int_add, int_zero>;
using CommutativeMonoidWrapper = m1une::monoid::Wrapper<int, int_add, int_zero, true>;
using DefaultActedWrapper =
    m1une::acted_monoid::Wrapper<int, int, int_add, int_zero, int_add, int_zero, int_mapping>;
using CommutativeActedWrapper =
    m1une::acted_monoid::Wrapper<int, int, int_add, int_zero, int_add, int_zero, int_mapping, true>;
using CommutativeOperatorActedWrapper =
    m1une::acted_monoid::Wrapper<int, int, int_add, int_zero, int_add, int_zero, int_mapping, false, true>;
using DefaultBeatsWrapper = m1une::beats_acted_monoid::Wrapper<
    int, int, int_add, int_zero, int_add, int_zero, int_mapping, always_applicable>;
using CommutativeBeatsWrapper = m1une::beats_acted_monoid::Wrapper<
    int, int, int_add, int_zero, int_add, int_zero, int_mapping, always_applicable,
    nullptr, nullptr, nullptr, nullptr, nullptr, true>;
using CommutativeOperatorBeatsWrapper = m1une::beats_acted_monoid::Wrapper<
    int, int, int_add, int_zero, int_add, int_zero, int_mapping, always_applicable,
    nullptr, nullptr, nullptr, nullptr, nullptr, false, true>;

static_assert(m1une::monoid::IsMonoid<ContestMonoid>);
static_assert(m1une::acted_monoid::IsActedMonoid<ContestActedMonoid>);
static_assert(
    m1une::beats_acted_monoid::IsBeatsActedMonoid<DefaultBeatsWrapper>
);

static_assert(m1une::monoid::Add<int>::commutative);
static_assert(m1une::monoid::And<int>::commutative);
static_assert(m1une::monoid::BottomK<int, 2>::commutative);
static_assert(m1une::monoid::Gcd<int>::commutative);
static_assert(m1une::monoid::Max<int>::commutative);
static_assert(m1une::monoid::MaxCount<int>::commutative);
static_assert(m1une::monoid::Min<int>::commutative);
static_assert(m1une::monoid::MinCount<int>::commutative);
static_assert(m1une::monoid::MinMax<int>::commutative);
static_assert(m1une::monoid::Mul<int>::commutative);
static_assert(m1une::monoid::Or<int>::commutative);
static_assert(m1une::monoid::StrictMax2<int>::commutative);
static_assert(m1une::monoid::StrictMin2<int>::commutative);
static_assert(m1une::monoid::TopK<int, 2>::commutative);
static_assert(m1une::monoid::TopKCount<int, 2>::commutative);
static_assert(m1une::monoid::Xor<int>::commutative);
static_assert(CommutativeMonoidWrapper::commutative);

static_assert(!m1une::monoid::Affine<int>::commutative);
static_assert(!m1une::monoid::ArgMax<int>::commutative);
static_assert(!m1une::monoid::ArgMin<int>::commutative);
static_assert(!m1une::monoid::BinaryInversion<int>::commutative);
static_assert(!m1une::monoid::Bracket::commutative);
static_assert(!m1une::monoid::LongestSame<int>::commutative);
static_assert(!m1une::monoid::LongestTrue::commutative);
static_assert(!m1une::monoid::Matrix<int, 2>::commutative);
static_assert(!m1une::monoid::MaxPlusMatrix<int, 2>::commutative);
static_assert(!m1une::monoid::MaxSubarray<int>::commutative);
static_assert(!m1une::monoid::MinPlusMatrix<int, 2>::commutative);
static_assert(!m1une::monoid::MinSubarray<int>::commutative);
static_assert(!m1une::monoid::Permutation<3>::commutative);
static_assert(!m1une::monoid::RollingHash<>::commutative);
static_assert(!m1une::monoid::Update<int>::commutative);
static_assert(!DefaultMonoidWrapper::commutative);

static_assert(m1une::acted_monoid::RangeAddRangeMax<int>::commutative);
static_assert(m1une::acted_monoid::RangeAddRangeMin<int>::commutative);
static_assert(m1une::acted_monoid::RangeAddRangeMinCount<int>::commutative);
static_assert(m1une::acted_monoid::RangeAddRangeSum<int>::commutative);
static_assert(m1une::acted_monoid::RangeAffineRangeMinMax<int>::commutative);
static_assert(m1une::acted_monoid::RangeAffineRangeSum<int>::commutative);
static_assert(m1une::acted_monoid::RangeAffineRangeSumOfSquares<int>::commutative);
static_assert(m1une::acted_monoid::RangeApUpdateRangeMinMax<int>::commutative);
static_assert(m1une::acted_monoid::RangeBitwiseAndOrXorRangeSum<int>::commutative);
static_assert(m1une::acted_monoid::RangeFlipRangeSum<int>::commutative);
static_assert(m1une::acted_monoid::RangeMulRangeSum<int>::commutative);
static_assert(m1une::acted_monoid::RangeOrRangeSum<int>::commutative);
static_assert(m1une::acted_monoid::RangeUpdateRangeMax<int>::commutative);
static_assert(m1une::acted_monoid::RangeUpdateRangeMin<int>::commutative);
static_assert(m1une::acted_monoid::RangeUpdateRangeProduct<m1une::monoid::Add<int>>::commutative);
static_assert(m1une::acted_monoid::RangeUpdateRangeSum<int>::commutative);
static_assert(m1une::acted_monoid::RangeXorRangeSum<int>::commutative);
static_assert(m1une::acted_monoid::RangeXorRangeXor<int>::commutative);
static_assert(CommutativeActedWrapper::commutative);
static_assert(CommutativeBeatsWrapper::commutative);

static_assert(!m1une::acted_monoid::RangeAddRangeArgMax<int>::commutative);
static_assert(!m1une::acted_monoid::RangeAddRangeArgMin<int>::commutative);
static_assert(!m1une::acted_monoid::RangeApAddRangeSum<int>::commutative);
static_assert(!m1une::acted_monoid::RangeApUpdateRangeSum<int>::commutative);
static_assert(!m1une::acted_monoid::RangeFlipRangeBinaryInversion<int>::commutative);
static_assert(!m1une::acted_monoid::RangeUpdateRangeLongestTrue::commutative);
static_assert(!m1une::acted_monoid::RangeUpdateRangeMaxSubarray<int>::commutative);
static_assert(!m1une::acted_monoid::RangeUpdateRangeProduct<m1une::monoid::Affine<int>>::commutative);
static_assert(!m1une::acted_monoid::RangeUpdateRangeProduct<ContestMonoid>::commutative);
static_assert(!DefaultActedWrapper::commutative);
static_assert(!DefaultBeatsWrapper::commutative);

static_assert(m1une::acted_monoid::RangeAddRangeArgMax<int>::operator_commutative);
static_assert(m1une::acted_monoid::RangeAddRangeArgMin<int>::operator_commutative);
static_assert(m1une::acted_monoid::RangeAddRangeMax<int>::operator_commutative);
static_assert(m1une::acted_monoid::RangeAddRangeMin<int>::operator_commutative);
static_assert(m1une::acted_monoid::RangeAddRangeMinCount<int>::operator_commutative);
static_assert(m1une::acted_monoid::RangeAddRangeSum<int>::operator_commutative);
static_assert(m1une::acted_monoid::RangeApAddRangeSum<int>::operator_commutative);
static_assert(m1une::acted_monoid::RangeFlipRangeBinaryInversion<int>::operator_commutative);
static_assert(m1une::acted_monoid::RangeFlipRangeSum<int>::operator_commutative);
static_assert(m1une::acted_monoid::RangeMulRangeSum<int>::operator_commutative);
static_assert(m1une::acted_monoid::RangeOrRangeSum<int>::operator_commutative);
static_assert(m1une::acted_monoid::RangeXorRangeSum<int>::operator_commutative);
static_assert(m1une::acted_monoid::RangeXorRangeXor<int>::operator_commutative);
static_assert(CommutativeOperatorActedWrapper::operator_commutative);
static_assert(CommutativeOperatorBeatsWrapper::operator_commutative);

static_assert(!m1une::acted_monoid::RangeAffineRangeMinMax<int>::operator_commutative);
static_assert(!m1une::acted_monoid::RangeAffineRangeSum<int>::operator_commutative);
static_assert(!m1une::acted_monoid::RangeAffineRangeSumOfSquares<int>::operator_commutative);
static_assert(!m1une::acted_monoid::RangeApUpdateRangeMinMax<int>::operator_commutative);
static_assert(!m1une::acted_monoid::RangeApUpdateRangeSum<int>::operator_commutative);
static_assert(!m1une::acted_monoid::RangeBitwiseAndOrXorRangeSum<int>::operator_commutative);
static_assert(!m1une::acted_monoid::RangeUpdateRangeLongestTrue::operator_commutative);
static_assert(!m1une::acted_monoid::RangeUpdateRangeMax<int>::operator_commutative);
static_assert(!m1une::acted_monoid::RangeUpdateRangeMaxSubarray<int>::operator_commutative);
static_assert(!m1une::acted_monoid::RangeUpdateRangeMin<int>::operator_commutative);
static_assert(
    !m1une::acted_monoid::RangeUpdateRangeProduct<m1une::monoid::Add<int>>::operator_commutative);
static_assert(!m1une::acted_monoid::RangeUpdateRangeSum<int>::operator_commutative);
static_assert(!DefaultActedWrapper::operator_commutative);
static_assert(!DefaultBeatsWrapper::operator_commutative);
static_assert(!CommutativeActedWrapper::operator_commutative);
static_assert(!CommutativeBeatsWrapper::operator_commutative);
static_assert(!CommutativeOperatorActedWrapper::commutative);
static_assert(!CommutativeOperatorBeatsWrapper::commutative);

}  // namespace

int main() {
    int a, b;
    std::cin >> a >> b;
    std::cout << a + b << '\n';
}
#line 1 "verify/monoid/commutative_flags.test.cpp"
#define PROBLEM "https://judge.yosupo.jp/problem/aplusb"

#include <iostream>

#line 1 "acted_monoid/concept.hpp"



#include <concepts>

namespace m1une {
namespace acted_monoid {

// Concept defining the requirements for an Acted Monoid.
template <typename AM>
concept IsActedMonoid = requires(typename AM::value_type a, typename AM::value_type b, typename AM::operator_type f,
                                 typename AM::operator_type g) {
    // 1. Value Monoid
    typename AM::value_type;
    { AM::id() } -> std::same_as<typename AM::value_type>;
    { AM::op(a, b) } -> std::same_as<typename AM::value_type>;

    // 2. Operator Monoid
    typename AM::operator_type;
    { AM::op_id() } -> std::same_as<typename AM::operator_type>;
    { AM::op_comp(f, g) } -> std::same_as<typename AM::operator_type>;  // Composition order: f(g(x))

    // 3. Mapping: Operator x Value -> Value
    { AM::mapping(f, a) } -> std::same_as<typename AM::value_type>;
};

// Concept for acted monoids whose value monoid is a commutative group.
// The value operation must obey commutativity and inverse laws.
template <typename AM>
concept IsCommutativeActedGroup = IsActedMonoid<AM> && requires(typename AM::value_type a) {
    { AM::inv(a) } -> std::same_as<typename AM::value_type>;
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_add_range_arg_max.hpp"



#include <limits>

namespace m1une {
namespace acted_monoid {

template <typename T>
struct RangeAddRangeArgMaxNode {
    T max_val;
    long long size;
    long long ord;
};

// Acted Monoid for Range Addition and Range Maximum Value & Index queries.
template <typename T>
struct RangeAddRangeArgMax {
    using value_type = RangeAddRangeArgMaxNode<T>;
    using operator_type = T;
    static constexpr bool commutative = false;
    static constexpr bool operator_commutative = true;

    static constexpr value_type id() {
        return {std::numeric_limits<T>::lowest(), 0, -1};
    }

    static constexpr value_type op(const value_type& a, const value_type& b) {
        if (a.size == 0) return b;
        if (b.size == 0) return a;
        long long size = a.size + b.size;
        if (a.max_val >= b.max_val) return {a.max_val, size, a.ord};
        return {b.max_val, size, b.ord + a.size};
    }

    static constexpr operator_type op_id() {
        return T(0);
    }

    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        return f + g;
    }

    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        if (x.size == 0) return x;
        return {x.max_val + f, x.size, x.ord};
    }

    static constexpr value_type make(const T& val) {
        return {val, 1, 0};
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_add_range_arg_min.hpp"



#include <functional>
#line 6 "acted_monoid/range_add_range_arg_min.hpp"

#line 1 "monoid/arg_min.hpp"



#line 6 "monoid/arg_min.hpp"

namespace m1une {
namespace monoid {

template <typename T>
struct ArgMinNode {
    T value;
    long long size;
    long long ord;
};

// Monoid for finding the optimal value (minimum by default) and its relative order.
// Ties are broken by choosing the earlier element.
template <typename T, T Id = std::numeric_limits<T>::max(), typename Compare = std::less<T>>
struct ArgMin {
    using value_type = ArgMinNode<T>;
    static constexpr bool commutative = false;

    static constexpr value_type id() {
        return {Id, 0, -1};
    }

    static constexpr value_type op(const value_type& a, const value_type& b) {
        if (a.size == 0) return b;
        if (b.size == 0) return a;
        long long size = a.size + b.size;
        if (Compare()(a.value, b.value)) return {a.value, size, a.ord};
        if (Compare()(b.value, a.value)) return {b.value, size, b.ord + a.size};
        return {a.value, size, a.ord};
    }

    static constexpr value_type make(const T& val) {
        return {val, 1, 0};
    }
};

}  // namespace monoid
}  // namespace m1une


#line 8 "acted_monoid/range_add_range_arg_min.hpp"

namespace m1une {
namespace acted_monoid {

template <typename T, T Id = std::numeric_limits<T>::max(), typename Compare = std::less<T>>
struct RangeAddRangeArgMin {
    using BaseMonoid = m1une::monoid::ArgMin<T, Id, Compare>;
    using value_type = typename BaseMonoid::value_type;
    using operator_type = T;
    static constexpr bool commutative = false;
    static constexpr bool operator_commutative = true;

    // Value Monoid (ArgMin)
    static constexpr value_type id() {
        return BaseMonoid::id();
    }
    static constexpr value_type op(const value_type& a, const value_type& b) {
        return BaseMonoid::op(a, b);
    }

    // Operator Monoid (Add)
    static constexpr operator_type op_id() {
        return T(0);
    }
    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        return f + g;
    }

    // Mapping
    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        if (x.size == 0) return x;
        return {x.value + f, x.size, x.ord};
    }

    // Helper for initializing a leaf node
    static constexpr value_type make(const T& val) {
        return BaseMonoid::make(val);
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_add_range_max.hpp"



#include <algorithm>
#line 6 "acted_monoid/range_add_range_max.hpp"

namespace m1une {
namespace acted_monoid {

template <typename T, T Id = std::numeric_limits<T>::lowest()>
struct RangeAddRangeMax {
    using value_type = T;
    using operator_type = T;
    static constexpr bool commutative = true;
    static constexpr bool operator_commutative = true;

    // Value Monoid (Max)
    static constexpr value_type id() {
        return Id;
    }
    static constexpr value_type op(const value_type& a, const value_type& b) {
        return std::max(a, b);
    }

    // Operator Monoid (Add)
    static constexpr operator_type op_id() {
        return 0;
    }
    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        return f + g;
    }

    // Mapping
    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        if (x == id()) return x;  // Do not apply the operator to the identity element
        return x + f;
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_add_range_min.hpp"



#line 6 "acted_monoid/range_add_range_min.hpp"

namespace m1une {
namespace acted_monoid {

template <typename T, T Id = std::numeric_limits<T>::max()>
struct RangeAddRangeMin {
    using value_type = T;
    using operator_type = T;
    static constexpr bool commutative = true;
    static constexpr bool operator_commutative = true;

    // Value Monoid (Min)
    static constexpr value_type id() {
        return Id;
    }
    static constexpr value_type op(const value_type& a, const value_type& b) {
        return std::min(a, b);
    }

    // Operator Monoid (Add)
    static constexpr operator_type op_id() {
        return 0;
    }
    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        return f + g;
    }

    // Mapping
    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        if (x == id()) return x;  // Do not apply the operator to the identity element
        return x + f;
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_add_range_min_count.hpp"



#line 6 "acted_monoid/range_add_range_min_count.hpp"

#line 1 "monoid/min_count.hpp"



#line 6 "monoid/min_count.hpp"
#include <utility>

namespace m1une {
namespace monoid {

// Monoid for finding the optimal value and its frequency in a range.
// Uses a comparison functor (Compare) to determine the optimal value (default is less, i.e., minimum).
template <typename T, T Id = std::numeric_limits<T>::max(), typename Compare = std::less<T>>
struct MinCount {
    using value_type = std::pair<T, int>;
    static constexpr bool commutative = true;

    // The identity element has the specified Id value and a count of 0.
    static constexpr value_type id() {
        return {Id, 0};
    }

    // Combines two elements, updating the optimal value and summing the counts if they are equal.
    static constexpr value_type op(const value_type& a, const value_type& b) {
        if (Compare()(a.first, b.first)) return a;
        if (Compare()(b.first, a.first)) return b;
        return {a.first, a.second + b.second};
    }

    // Helper to securely create a leaf node from a single value.
    static constexpr value_type make(const T& val, int count = 1) {
        return {val, count};
    }
};

}  // namespace monoid
}  // namespace m1une


#line 8 "acted_monoid/range_add_range_min_count.hpp"

namespace m1une {
namespace acted_monoid {

template <typename T, T Id = std::numeric_limits<T>::max(), typename Compare = std::less<T>>
struct RangeAddRangeMinCount {
    using BaseMonoid = m1une::monoid::MinCount<T, Id, Compare>;
    using value_type = typename BaseMonoid::value_type;  // std::pair<T, int>
    using operator_type = T;
    static constexpr bool commutative = true;
    static constexpr bool operator_commutative = true;

    // Value Monoid (Min Count)
    static constexpr value_type id() {
        return BaseMonoid::id();
    }
    static constexpr value_type op(const value_type& a, const value_type& b) {
        return BaseMonoid::op(a, b);
    }

    // Operator Monoid (Add)
    static constexpr operator_type op_id() {
        return T(0);
    }
    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        return f + g;
    }

    // Mapping
    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        if (x.second == 0) return x;  // Do not apply to the identity element
        return {x.first + f, x.second};
    }

    // Helper for initializing a leaf node
    static constexpr value_type make(const T& val, int count = 1) {
        return BaseMonoid::make(val, count);
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_add_range_sum.hpp"



namespace m1une {
namespace acted_monoid {

template <typename T>
struct RangeAddRangeSumNode {
    T sum;
    long long size;
};

template <typename T>
struct RangeAddRangeSum {
    using value_type = RangeAddRangeSumNode<T>;
    using operator_type = T;
    static constexpr bool commutative = true;
    static constexpr bool operator_commutative = true;

    // Value Monoid (Sum)
    static constexpr value_type id() {
        return {T(0), 0};
    }
    static constexpr value_type op(const value_type& a, const value_type& b) {
        return {a.sum + b.sum, a.size + b.size};
    }
    static constexpr value_type inv(const value_type& x) {
        return {-x.sum, -x.size};
    }

    // Operator Monoid (Add)
    static constexpr operator_type op_id() {
        return 0;
    }
    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        return f + g;
    }

    // Mapping (sum + f * size)
    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        return {x.sum + f * x.size, x.size};
    }

    // Helper for initializing a leaf node
    static constexpr value_type make(const T& val) {
        return {val, 1};
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_affine_range_min_max.hpp"



#line 7 "acted_monoid/range_affine_range_min_max.hpp"

namespace m1une {
namespace acted_monoid {

template <typename T>
struct RangeAffineRangeMinMaxNode {
    T min_val;
    T max_val;
};

template <typename T, T MinId = std::numeric_limits<T>::max(), T MaxId = std::numeric_limits<T>::lowest()>
struct RangeAffineRangeMinMax {
    using value_type = RangeAffineRangeMinMaxNode<T>;
    using operator_type = std::pair<T, T>;
    static constexpr bool commutative = true;
    static constexpr bool operator_commutative = false;

    static constexpr value_type id() {
        return {MinId, MaxId};
    }
    static constexpr value_type op(const value_type& a, const value_type& b) {
        return {std::min(a.min_val, b.min_val), std::max(a.max_val, b.max_val)};
    }

    static constexpr operator_type op_id() {
        return {T(1), T(0)};
    }
    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        return {f.first * g.first, f.first * g.second + f.second};
    }

    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        if (x.min_val == MinId) return x;

        T v1 = f.first * x.min_val + f.second;
        T v2 = f.first * x.max_val + f.second;

        if (f.first < 0) {
            return {v2, v1};
        }
        return {v1, v2};
    }

    static constexpr value_type make(const T& val) {
        return {val, val};
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_affine_range_sum.hpp"



#line 5 "acted_monoid/range_affine_range_sum.hpp"

namespace m1une {
namespace acted_monoid {

template <typename T>
struct RangeAffineRangeSumNode {
    T sum;
    int size;
};

// Designed to accept Modint or similar types as T
template <typename T>
struct RangeAffineRangeSum {
    using value_type = RangeAffineRangeSumNode<T>;
    using operator_type = std::pair<T, T>;  // {a, b} for ax + b
    static constexpr bool commutative = true;
    static constexpr bool operator_commutative = false;

    // Value Monoid
    static constexpr value_type id() {
        return {T(0), 0};
    }
    static constexpr value_type op(const value_type& a, const value_type& b) {
        return {a.sum + b.sum, a.size + b.size};
    }
    static constexpr int size(const value_type& value) {
        return value.size;
    }

    // Operator Monoid (Affine Composition)
    // f(x) = a1*x + b1, g(x) = a2*x + b2
    // f(g(x)) = a1*(a2*x + b2) + b1 = (a1*a2)*x + (a1*b2 + b1)
    static constexpr operator_type op_id() {
        return {T(1), T(0)};
    }
    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        return {f.first * g.first, f.first * g.second + f.second};
    }

    // Mapping
    // \sum (a*x_i + b) = a * \sum x_i + b * size
    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        return {f.first * x.sum + f.second * T(x.size), x.size};
    }

    // Helper for initializing a leaf node
    static constexpr value_type make(const T& val) {
        return {val, 1};
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_affine_range_sum_of_squares.hpp"



#line 5 "acted_monoid/range_affine_range_sum_of_squares.hpp"

namespace m1une {
namespace acted_monoid {

template <typename T>
struct RangeAffineRangeSumOfSquaresNode {
    T sum_sq;
    T sum;
    long long size;
};

// Designed to work with standard scalars or Modint types
template <typename T>
struct RangeAffineRangeSumOfSquares {
    using value_type = RangeAffineRangeSumOfSquaresNode<T>;
    using operator_type = std::pair<T, T>;  // {a, b} for f(x) = a*x + b
    static constexpr bool commutative = true;
    static constexpr bool operator_commutative = false;

    // Value Monoid (Sum of Squares, Sum, Size)
    static constexpr value_type id() {
        return {T(0), T(0), 0};
    }
    static constexpr value_type op(const value_type& a, const value_type& b) {
        return {a.sum_sq + b.sum_sq, a.sum + b.sum, a.size + b.size};
    }

    // Operator Monoid (Affine Composition)
    // f(x) = a1*x + b1, g(x) = a2*x + b2
    // f(g(x)) = a1*(a2*x + b2) + b1 = (a1*a2)*x + (a1*b2 + b1)
    static constexpr operator_type op_id() {
        return {T(1), T(0)};
    }
    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        return {f.first * g.first, f.first * g.second + f.second};
    }

    // Mapping
    // \sum (a*x_i + b)^2 = a^2 \sum x_i^2 + 2ab \sum x_i + b^2 * size
    // \sum (a*x_i + b)   = a \sum x_i + b * size
    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        if (x.size == 0) return x;
        T a = f.first;
        T b = f.second;
        T sz = static_cast<T>(x.size);

        return {a * a * x.sum_sq + T(2) * a * b * x.sum + b * b * sz, a * x.sum + b * sz, x.size};
    }

    // Helper for initializing a leaf node
    static constexpr value_type make(const T& val) {
        return {val * val, val, 1};
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_ap_add_range_sum.hpp"



#line 5 "acted_monoid/range_ap_add_range_sum.hpp"

namespace m1une {
namespace acted_monoid {

template <typename T>
struct RangeApAddRangeSumNode {
    T sum;
    long long size;
    T ord_sum;
};

template <typename T>
struct RangeApAddRangeSum {
    using value_type = RangeApAddRangeSumNode<T>;
    using operator_type = std::pair<T, T>;  // {a, b} for adding a * i + b
    static constexpr bool commutative = false;
    static constexpr bool operator_commutative = true;

    // Value Monoid (Sum)
    static constexpr value_type id() {
        return {T(0), 0, T(0)};
    }
    static constexpr value_type op(const value_type& a, const value_type& b) {
        return {a.sum + b.sum, a.size + b.size, a.ord_sum + b.ord_sum + T(a.size) * T(b.size)};
    }

    // Operator Monoid (Add)
    static constexpr operator_type op_id() {
        return {T(0), T(0)};
    }
    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        return {f.first + g.first, f.second + g.second};
    }

    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        return mapping(f, x, 0);
    }

    static constexpr value_type mapping(const operator_type& f, const value_type& x, long long ord) {
        return {x.sum + f.first * (x.ord_sum + T(ord) * T(x.size)) + f.second * T(x.size), x.size, x.ord_sum};
    }

    static constexpr operator_type op_shift(const operator_type& f, long long ord) {
        return {f.first, f.second + f.first * T(ord)};
    }

    static constexpr operator_type op_reverse(const operator_type& f, long long size) {
        return {-f.first, f.second + f.first * T(size - 1)};
    }

    static constexpr value_type make(const T& val) {
        return {val, 1, T(0)};
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_ap_update_range_min_max.hpp"



#line 6 "acted_monoid/range_ap_update_range_min_max.hpp"
#include <optional>
#line 8 "acted_monoid/range_ap_update_range_min_max.hpp"

namespace m1une {
namespace acted_monoid {

template <typename T>
struct RangeApUpdateRangeMinMaxNode {
    T min_val;
    T max_val;
    long long size;
};

template <typename T, T MinId = std::numeric_limits<T>::max(), T MaxId = std::numeric_limits<T>::lowest()>
struct RangeApUpdateRangeMinMax {
    using value_type = RangeApUpdateRangeMinMaxNode<T>;
    using operator_type = std::optional<std::pair<T, T>>;  // {a, b} for setting to a * i + b
    static constexpr bool commutative = true;
    static constexpr bool operator_commutative = false;

    // Value Monoid (Min & Max)
    static constexpr value_type id() {
        return {MinId, MaxId, 0};
    }

    static constexpr value_type op(const value_type& a, const value_type& b) {
        if (a.size == 0) return b;
        if (b.size == 0) return a;
        return {std::min(a.min_val, b.min_val), std::max(a.max_val, b.max_val), a.size + b.size};
    }

    // Operator Monoid (Update)
    static constexpr operator_type op_id() {
        return std::nullopt;
    }

    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        // Newer operation (f) completely overwrites the older one (g)
        return f.has_value() ? f : g;
    }

    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        return mapping(f, x, 0);
    }

    static constexpr value_type mapping(const operator_type& f, const value_type& x, long long ord) {
        if (!f.has_value() || x.min_val == MinId) return x;

        T a = f.value().first;
        T b = f.value().second;
        T val_left = a * static_cast<T>(ord) + b;
        T val_right = a * static_cast<T>(ord + x.size - 1) + b;

        return {std::min(val_left, val_right), std::max(val_left, val_right), x.size};
    }

    static constexpr operator_type op_shift(const operator_type& f, long long ord) {
        if (!f.has_value()) return f;
        return std::pair<T, T>{f.value().first, f.value().second + f.value().first * T(ord)};
    }

    static constexpr operator_type op_reverse(const operator_type& f, long long size) {
        if (!f.has_value()) return f;
        return std::pair<T, T>{-f.value().first, f.value().second + f.value().first * T(size - 1)};
    }

    static constexpr value_type make(const T& val) {
        return {val, val, 1};
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_ap_update_range_sum.hpp"



#line 6 "acted_monoid/range_ap_update_range_sum.hpp"

namespace m1une {
namespace acted_monoid {

template <typename T>
struct RangeApUpdateRangeSumNode {
    T sum;
    long long size;
    T ord_sum;
};

template <typename T>
struct RangeApUpdateRangeSum {
    using value_type = RangeApUpdateRangeSumNode<T>;
    using operator_type = std::optional<std::pair<T, T>>;  // {a, b} for setting to a * i + b
    static constexpr bool commutative = false;
    static constexpr bool operator_commutative = false;

    // Value Monoid (Sum)
    static constexpr value_type id() {
        return {T(0), 0, T(0)};
    }
    static constexpr value_type op(const value_type& a, const value_type& b) {
        return {a.sum + b.sum, a.size + b.size, a.ord_sum + b.ord_sum + T(a.size) * T(b.size)};
    }

    // Operator Monoid (Update)
    static constexpr operator_type op_id() {
        return std::nullopt;
    }
    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        // Prioritize the newer operation (f) over the older one (g)
        return f.has_value() ? f : g;
    }

    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        return mapping(f, x, 0);
    }

    static constexpr value_type mapping(const operator_type& f, const value_type& x, long long ord) {
        if (!f.has_value() || x.size == 0) return x;
        return {f.value().first * (x.ord_sum + T(ord) * T(x.size)) + f.value().second * T(x.size), x.size,
                x.ord_sum};
    }

    static constexpr operator_type op_shift(const operator_type& f, long long ord) {
        if (!f.has_value()) return f;
        return std::pair<T, T>{f.value().first, f.value().second + f.value().first * T(ord)};
    }

    static constexpr operator_type op_reverse(const operator_type& f, long long size) {
        if (!f.has_value()) return f;
        return std::pair<T, T>{-f.value().first, f.value().second + f.value().first * T(size - 1)};
    }

    static constexpr value_type make(const T& val) {
        return {val, 1, T(0)};
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_bitwise_and_or_xor_range_sum.hpp"



#include <array>
#line 6 "acted_monoid/range_bitwise_and_or_xor_range_sum.hpp"
#include <type_traits>

namespace m1une {
namespace acted_monoid {

template <typename T, int BITS>
struct RangeBitwiseAndOrXorRangeSumNode {
    T sum;
    std::array<long long, BITS> bit_count;
    long long size;
};

// Acted monoid for range bitwise AND, OR, and XOR updates and range sum queries.
template <typename T, int BITS = 30>
struct RangeBitwiseAndOrXorRangeSum {
    static_assert(std::is_integral_v<T> && !std::is_same_v<std::remove_cv_t<T>, bool>);
    static_assert(0 < BITS && BITS <= std::numeric_limits<T>::digits);

    using value_type = RangeBitwiseAndOrXorRangeSumNode<T, BITS>;

    // Represents f(x) = (x & and_mask) ^ xor_mask on the lowest BITS bits.
    struct operator_type {
        T and_mask;
        T xor_mask;
    };

    static constexpr bool commutative = true;
    static constexpr bool operator_commutative = false;

    static constexpr T bit_mask() {
        if constexpr (std::is_unsigned_v<T> && BITS == std::numeric_limits<T>::digits) {
            return ~T(0);
        } else {
            return (T(1) << (BITS - 1)) | ((T(1) << (BITS - 1)) - 1);
        }
    }

    static constexpr value_type id() {
        value_type res;
        res.sum = T(0);
        res.bit_count.fill(0);
        res.size = 0;
        return res;
    }

    static constexpr value_type op(const value_type& a, const value_type& b) {
        value_type res;
        res.sum = a.sum + b.sum;
        res.size = a.size + b.size;
        for (int i = 0; i < BITS; ++i) {
            res.bit_count[i] = a.bit_count[i] + b.bit_count[i];
        }
        return res;
    }

    static constexpr operator_type op_id() {
        return {bit_mask(), T(0)};
    }

    // Returns f(g(x)).
    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        return {f.and_mask & g.and_mask, (g.xor_mask & f.and_mask) ^ f.xor_mask};
    }

    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        value_type res = x;
        res.sum = T(0);
        for (int i = 0; i < BITS; ++i) {
            long long count = ((f.and_mask >> i) & T(1)) ? x.bit_count[i] : 0;
            if ((f.xor_mask >> i) & T(1)) count = x.size - count;
            res.bit_count[i] = count;
            res.sum += static_cast<T>(count) * (T(1) << i);
        }
        return res;
    }

    static constexpr value_type make(const T& value) {
        value_type res;
        res.sum = value;
        res.size = 1;
        for (int i = 0; i < BITS; ++i) {
            res.bit_count[i] = (value >> i) & T(1);
        }
        return res;
    }

    static constexpr operator_type make_and(const T& mask) {
        return {mask & bit_mask(), T(0)};
    }

    static constexpr operator_type make_or(const T& mask) {
        T normalized = mask & bit_mask();
        return {bit_mask() ^ normalized, normalized};
    }

    static constexpr operator_type make_xor(const T& mask) {
        return {bit_mask(), mask & bit_mask()};
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_flip_range_binary_inversion.hpp"



#line 1 "monoid/binary_inversion.hpp"



namespace m1une {
namespace monoid {

template <typename T = long long>
struct BinaryInversionNode {
    long long zeros;
    long long ones;
    T inversions;
};

// Monoid for counting zeros, ones, and inversions (1s before 0s) in a binary array.
template <typename T = long long>
struct BinaryInversion {
    using value_type = BinaryInversionNode<T>;
    static constexpr bool commutative = false;

    // The identity element has 0 zeros, 0 ones, and 0 inversions.
    static constexpr value_type id() {
        return {0, 0, 0};
    }

    // Merges two segments and calculates the new inversions.
    // New inversions = left inversions + right inversions + (ones in left * zeros in right)
    static constexpr value_type op(const value_type& a, const value_type& b) {
        return {a.zeros + b.zeros, a.ones + b.ones, a.inversions + b.inversions + a.ones * b.zeros};
    }

    // Helper to securely create a leaf node from a value (0 or 1).
    static constexpr value_type make(int val) {
        if (val == 0) return {1, 0, 0};
        return {0, 1, 0};
    }
};

}  // namespace monoid
}  // namespace m1une


#line 5 "acted_monoid/range_flip_range_binary_inversion.hpp"

namespace m1une {
namespace acted_monoid {

template <typename T = long long>
struct RangeFlipRangeBinaryInversion {
    using value_type = m1une::monoid::BinaryInversionNode<T>;
    using operator_type = bool;
    static constexpr bool commutative = false;
    static constexpr bool operator_commutative = true;

    static constexpr value_type id() {
        return {0, 0, 0};
    }
    static constexpr value_type op(const value_type& a, const value_type& b) {
        return {a.zeros + b.zeros, a.ones + b.ones, a.inversions + b.inversions + a.ones * b.zeros};
    }

    static constexpr operator_type op_id() {
        return false;
    }
    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        return f ^ g;
    }

    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        if (!f) return x;
        return {x.ones, x.zeros, x.zeros * x.ones - x.inversions};
    }

    static constexpr value_type make(int val) {
        if (val == 0) return {1, 0, 0};
        return {0, 1, 0};
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_flip_range_sum.hpp"



namespace m1une {
namespace acted_monoid {

template <typename T>
struct RangeFlipRangeSumNode {
    T sum;
    long long size;
};

// Acted Monoid for binary arrays (0s and 1s).
// Supports range bit inversion (flip) and range sum queries.
template <typename T = long long>
struct RangeFlipRangeSum {
    using value_type = RangeFlipRangeSumNode<T>;
    using operator_type = bool;  // 'true' means flip the bits in the range
    static constexpr bool commutative = true;
    static constexpr bool operator_commutative = true;

    static constexpr value_type id() {
        return {T(0), 0};
    }

    static constexpr value_type op(const value_type& a, const value_type& b) {
        return {a.sum + b.sum, a.size + b.size};
    }

    static constexpr operator_type op_id() {
        return false;
    }

    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        return f ^ g;
    }

    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        if (!f || x.size == 0) return x;
        // If flipped, the new number of 1s is exactly (Total Elements - Old number of 1s)
        return {static_cast<T>(x.size) - x.sum, x.size};
    }

    // Initialize with a 0 or 1
    static constexpr value_type make(const T& val) {
        return {val, 1};
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_mul_range_sum.hpp"



namespace m1une {
namespace acted_monoid {

// Acted Monoid for Range Multiplication and Range Sum queries.
// Operates natively on scalars or Modint classes without needing to track segment size.
template <typename T>
struct RangeMulRangeSum {
    using value_type = T;
    using operator_type = T;
    static constexpr bool commutative = true;
    static constexpr bool operator_commutative = true;

    // Value Monoid (Sum)
    static constexpr value_type id() {
        return T(0);
    }
    static constexpr value_type op(const value_type& a, const value_type& b) {
        return a + b;
    }

    // Operator Monoid (Multiply)
    static constexpr operator_type op_id() {
        return T(1);
    }
    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        return f * g;
    }

    // Mapping: Distribution Property ( f * (a+b) = f*a + f*b )
    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        return f * x;
    }

    // Helper for initializing a leaf node
    static constexpr value_type make(const T& val) {
        return val;
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_or_range_sum.hpp"



#line 5 "acted_monoid/range_or_range_sum.hpp"

namespace m1une {
namespace acted_monoid {

template <typename T, int BITS = 30>
struct RangeOrRangeSumNode {
    T sum;
    std::array<int, BITS> bit_count;
    long long size;
};

// Acted Monoid for Range OR updates and Range Sum queries.
template <typename T, int BITS = 30>
struct RangeOrRangeSum {
    using value_type = RangeOrRangeSumNode<T, BITS>;
    using operator_type = T;
    static constexpr bool commutative = true;
    static constexpr bool operator_commutative = true;

    static constexpr value_type id() {
        value_type res;
        res.sum = T(0);
        res.bit_count.fill(0);
        res.size = 0;
        return res;
    }

    static constexpr value_type op(const value_type& a, const value_type& b) {
        value_type res;
        res.sum = a.sum + b.sum;
        res.size = a.size + b.size;
        for (int i = 0; i < BITS; ++i) {
            res.bit_count[i] = a.bit_count[i] + b.bit_count[i];
        }
        return res;
    }

    static constexpr operator_type op_id() {
        return T(0);
    }

    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        return f | g;
    }

    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        if (f == T(0) || x.size == 0) return x;
        value_type res = x;
        res.sum = T(0);
        for (int i = 0; i < BITS; ++i) {
            if ((f >> i) & 1) {
                res.bit_count[i] = x.size;  // OR forces the bit to be 1 for all elements
            }
            res.sum += static_cast<T>(res.bit_count[i]) * (T(1) << i);
        }
        return res;
    }

    static constexpr value_type make(const T& val) {
        value_type res;
        res.sum = val;
        res.size = 1;
        for (int i = 0; i < BITS; ++i) {
            res.bit_count[i] = ((val >> i) & 1) ? 1 : 0;
        }
        return res;
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_update_range_longest_true.hpp"



#line 5 "acted_monoid/range_update_range_longest_true.hpp"

#line 1 "monoid/longest_true.hpp"



#line 5 "monoid/longest_true.hpp"

namespace m1une {
namespace monoid {

struct LongestTrueNode {
    int len;
    int max_len;
    int l_len;
    int r_len;
};

// Monoid for finding the maximum length of a contiguous subarray
// where all elements satisfy a certain condition (i.e., are "true").
struct LongestTrue {
    using value_type = LongestTrueNode;
    static constexpr bool commutative = false;

    // The identity element represents an empty array.
    static constexpr value_type id() {
        return {0, 0, 0, 0};
    }

    // Merges two segments.
    static constexpr value_type op(const value_type& a, const value_type& b) {
        if (a.len == 0) return b;
        if (b.len == 0) return a;

        value_type res;
        res.len = a.len + b.len;
        res.max_len = std::max({a.max_len, b.max_len, a.r_len + b.l_len});

        res.l_len = a.l_len;
        if (a.len == a.l_len) res.l_len += b.l_len;

        res.r_len = b.r_len;
        if (b.len == b.r_len) res.r_len += a.r_len;

        return res;
    }

    // Helper to securely create a leaf node from a boolean condition.
    static constexpr value_type make(bool val) {
        return {1, val ? 1 : 0, val ? 1 : 0, val ? 1 : 0};
    }
};

}  // namespace monoid
}  // namespace m1une


#line 7 "acted_monoid/range_update_range_longest_true.hpp"

namespace m1une {
namespace acted_monoid {

struct RangeUpdateRangeLongestTrue {
    using BaseMonoid = m1une::monoid::LongestTrue;
    using value_type = typename BaseMonoid::value_type;
    using operator_type = std::optional<bool>;
    static constexpr bool commutative = false;
    static constexpr bool operator_commutative = false;

    // Value Monoid
    static constexpr value_type id() {
        return BaseMonoid::id();
    }
    static constexpr value_type op(const value_type& a, const value_type& b) {
        return BaseMonoid::op(a, b);
    }

    // Operator Monoid (Update/Overwrite)
    static constexpr operator_type op_id() {
        return std::nullopt;
    }
    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        return f.has_value() ? f : g;
    }

    // Mapping
    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        if (!f.has_value()) return x;
        bool v = f.value();

        // If updating to 'true', the entire length satisfies the condition.
        // If updating to 'false', zero elements satisfy the condition.
        return {x.len, v ? x.len : 0, v ? x.len : 0, v ? x.len : 0};
    }

    // Helper for initializing a leaf node
    static constexpr value_type make(bool val) {
        return BaseMonoid::make(val);
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_update_range_max.hpp"



#line 7 "acted_monoid/range_update_range_max.hpp"

namespace m1une {
namespace acted_monoid {

template <typename T, T Id = std::numeric_limits<T>::lowest()>
struct RangeUpdateRangeMax {
    using value_type = T;
    using operator_type = std::optional<T>;
    static constexpr bool commutative = true;
    static constexpr bool operator_commutative = false;

    // Value Monoid (Max)
    static constexpr value_type id() {
        return Id;
    }
    static constexpr value_type op(const value_type& a, const value_type& b) {
        return std::max(a, b);
    }

    // Operator Monoid (Update)
    static constexpr operator_type op_id() {
        return std::nullopt;
    }
    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        // Prioritize the newer operation (f) over the older one (g)
        return f.has_value() ? f : g;
    }

    // Mapping
    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        if (!f.has_value() || x == id()) return x;
        return f.value();
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_update_range_max_subarray.hpp"



#line 6 "acted_monoid/range_update_range_max_subarray.hpp"

namespace m1une {
namespace acted_monoid {

template <typename T>
struct RangeUpdateRangeMaxSubarrayNode {
    T sum, pref, suff, max_sub;
    long long size;
};

// Acted Monoid for Range Assignment (Update) and Max Contiguous Subarray Sum.
// Note: This implementation assumes empty subarrays are allowed (max sum is at least 0).
template <typename T>
struct RangeUpdateRangeMaxSubarray {
    using value_type = RangeUpdateRangeMaxSubarrayNode<T>;
    using operator_type = std::optional<T>;
    static constexpr bool commutative = false;
    static constexpr bool operator_commutative = false;

    static constexpr value_type id() {
        return {T(0), T(0), T(0), T(0), 0};
    }

    static constexpr value_type op(const value_type& a, const value_type& b) {
        if (a.size == 0) return b;
        if (b.size == 0) return a;
        value_type res;
        res.sum = a.sum + b.sum;
        res.pref = std::max(a.pref, a.sum + b.pref);
        res.suff = std::max(b.suff, b.sum + a.suff);
        res.max_sub = std::max({a.max_sub, b.max_sub, a.suff + b.pref});
        res.size = a.size + b.size;
        return res;
    }

    static constexpr operator_type op_id() {
        return std::nullopt;
    }

    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        return f ? f : g;  // left-biased because new updates override old ones
    }

    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        if (!f || x.size == 0) return x;
        value_type res;
        res.sum = (*f) * x.size;
        T max_val = std::max(T(0), res.sum);
        // If empty subarrays are NOT allowed, change to: T max_val = (*f) > 0 ? res.sum : (*f);
        res.pref = res.suff = res.max_sub = max_val;
        res.size = x.size;
        return res;
    }

    static constexpr value_type make(const T& val) {
        T max_val = std::max(T(0), val);
        return {val, max_val, max_val, max_val, 1};
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_update_range_min.hpp"



#line 7 "acted_monoid/range_update_range_min.hpp"

namespace m1une {
namespace acted_monoid {

template <typename T, T Id = std::numeric_limits<T>::max()>
struct RangeUpdateRangeMin {
    using value_type = T;
    using operator_type = std::optional<T>;
    static constexpr bool commutative = true;
    static constexpr bool operator_commutative = false;

    // Value Monoid (Min)
    static constexpr value_type id() {
        return Id;
    }
    static constexpr value_type op(const value_type& a, const value_type& b) {
        return std::min(a, b);
    }

    // Operator Monoid (Update)
    static constexpr operator_type op_id() {
        return std::nullopt;
    }
    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        // Prioritize the newer operation (f) over the older one (g)
        return f.has_value() ? f : g;
    }

    // Mapping
    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        if (!f.has_value() || x == id()) return x;
        return f.value();
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_update_range_product.hpp"



#line 5 "acted_monoid/range_update_range_product.hpp"

#line 1 "monoid/concept.hpp"



#line 5 "monoid/concept.hpp"

namespace m1une {
namespace monoid {

// Concept to check if a type satisfies the requirements of a Monoid.
// A Monoid must have a `value_type`, an identity element `id()`, and an associative binary operation `op()`.
template <typename M>
concept IsMonoid = requires(typename M::value_type a, typename M::value_type b) {
    // 1. Must define `value_type`
    typename M::value_type;

    // 2. Must have a static method `id()` returning `value_type`
    { M::id() } -> std::same_as<typename M::value_type>;

    // 3. Must have a static method `op(a, b)` returning `value_type`
    { M::op(a, b) } -> std::same_as<typename M::value_type>;
};

// Concept for groups. A type satisfying this concept must also obey the group
// laws; concepts can check the interface but not the algebraic properties.
template <typename M>
concept IsGroup = IsMonoid<M> && requires(typename M::value_type a) {
    { M::inv(a) } -> std::same_as<typename M::value_type>;
};

// Concept for commutative groups. Commutativity is a semantic requirement and
// cannot be checked by a C++ concept.
template <typename M>
concept IsCommutativeGroup = IsGroup<M>;

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/power.hpp"



#line 5 "monoid/power.hpp"

namespace m1une {
namespace monoid {

// Computes a^n (a * a * ... * a, n times) for an element 'a' in Monoid 'M'.
// Uses binary exponentiation to achieve O(log n) time complexity.
// The template parameter 'M' is constrained by the 'IsMonoid' concept.
template <IsMonoid M>
constexpr typename M::value_type power(typename M::value_type a, long long n) {
    typename M::value_type res = M::id();
    while (n > 0) {
        if (n & 1) {
            res = M::op(res, a);
        }
        a = M::op(a, a);
        n >>= 1;
    }
    return res;
}

}  // namespace monoid
}  // namespace m1une


#line 8 "acted_monoid/range_update_range_product.hpp"

namespace m1une {
namespace acted_monoid {

template <m1une::monoid::IsMonoid Monoid>
struct RangeUpdateRangeProductNode {
    using base_type = typename Monoid::value_type;

    base_type product;
    long long size;
};

// Range assignment and range product for an arbitrary, possibly
// noncommutative, monoid.
template <m1une::monoid::IsMonoid Monoid>
struct RangeUpdateRangeProduct {
    using base_type = typename Monoid::value_type;
    using value_type = RangeUpdateRangeProductNode<Monoid>;
    using operator_type = std::optional<base_type>;
    static constexpr bool commutative = [] {
        if constexpr (requires { Monoid::commutative; }) {
            return bool(Monoid::commutative);
        } else {
            return false;
        }
    }();
    static constexpr bool operator_commutative = false;

    static constexpr value_type id() {
        return {Monoid::id(), 0};
    }

    static constexpr value_type op(const value_type& a, const value_type& b) {
        return {Monoid::op(a.product, b.product), a.size + b.size};
    }

    static constexpr operator_type op_id() {
        return std::nullopt;
    }

    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        return f.has_value() ? f : g;
    }

    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        if (!f.has_value() || x.size == 0) return x;
        return {m1une::monoid::power<Monoid>(f.value(), x.size), x.size};
    }

    static constexpr value_type make(const base_type& value) {
        return {value, 1};
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_update_range_sum.hpp"



#line 5 "acted_monoid/range_update_range_sum.hpp"

namespace m1une {
namespace acted_monoid {

template <typename T>
struct RangeUpdateRangeSumNode {
    T sum;
    long long size;
};

template <typename T>
struct RangeUpdateRangeSum {
    using value_type = RangeUpdateRangeSumNode<T>;
    using operator_type = std::optional<T>;
    static constexpr bool commutative = true;
    static constexpr bool operator_commutative = false;

    static constexpr value_type id() {
        return {T(0), 0};
    }
    static constexpr value_type op(const value_type& a, const value_type& b) {
        return {a.sum + b.sum, a.size + b.size};
    }

    static constexpr operator_type op_id() {
        return std::nullopt;
    }
    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        return f.has_value() ? f : g;
    }

    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        if (!f.has_value() || x.size == 0) return x;
        return {f.value() * static_cast<T>(x.size), x.size};
    }

    static constexpr value_type make(const T& val) {
        return {val, 1};
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_xor_range_sum.hpp"



#line 5 "acted_monoid/range_xor_range_sum.hpp"

namespace m1une {
namespace acted_monoid {

template <typename T, int BITS = 30>
struct RangeXorRangeSumNode {
    T sum;
    std::array<int, BITS> bit_count;
    long long size;
};

// Acted Monoid for Range XOR updates and Range Sum queries.
// BITS defines the maximum bit length (default 30 for standard integers, use 60 for long long).
template <typename T, int BITS = 30>
struct RangeXorRangeSum {
    using value_type = RangeXorRangeSumNode<T, BITS>;
    using operator_type = T;
    static constexpr bool commutative = true;
    static constexpr bool operator_commutative = true;

    static constexpr value_type id() {
        value_type res;
        res.sum = T(0);
        res.bit_count.fill(0);
        res.size = 0;
        return res;
    }

    static constexpr value_type op(const value_type& a, const value_type& b) {
        value_type res;
        res.sum = a.sum + b.sum;
        res.size = a.size + b.size;
        for (int i = 0; i < BITS; ++i) {
            res.bit_count[i] = a.bit_count[i] + b.bit_count[i];
        }
        return res;
    }

    static constexpr operator_type op_id() {
        return T(0);
    }

    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        return f ^ g;
    }

    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        if (f == T(0) || x.size == 0) return x;
        value_type res = x;
        res.sum = T(0);
        for (int i = 0; i < BITS; ++i) {
            if ((f >> i) & 1) {
                res.bit_count[i] = x.size - x.bit_count[i];
            }
            res.sum += static_cast<T>(res.bit_count[i]) * (T(1) << i);
        }
        return res;
    }

    static constexpr value_type make(const T& val) {
        value_type res;
        res.sum = val;
        res.size = 1;
        for (int i = 0; i < BITS; ++i) {
            res.bit_count[i] = ((val >> i) & 1) ? 1 : 0;
        }
        return res;
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/range_xor_range_xor.hpp"



namespace m1une {
namespace acted_monoid {

template <typename T>
struct RangeXorRangeXorNode {
    T val;
    long long size;
};

template <typename T>
struct RangeXorRangeXor {
    using value_type = RangeXorRangeXorNode<T>;
    using operator_type = T;
    static constexpr bool commutative = true;
    static constexpr bool operator_commutative = true;

    static constexpr value_type id() {
        return {T(0), 0};
    }
    static constexpr value_type op(const value_type& a, const value_type& b) {
        return {a.val ^ b.val, a.size + b.size};
    }
    static constexpr value_type inv(const value_type& x) {
        return {x.val, -x.size};
    }

    static constexpr operator_type op_id() {
        return T(0);
    }
    static constexpr operator_type op_comp(const operator_type& f, const operator_type& g) {
        return f ^ g;
    }

    static constexpr value_type mapping(const operator_type& f, const value_type& x) {
        if (x.size % 2 != 0) {
            return {x.val ^ f, x.size};
        }
        return x;
    }

    static constexpr value_type make(const T& val) {
        return {val, 1};
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "acted_monoid/wrapper.hpp"



namespace m1une {
namespace acted_monoid {

// Wrapper struct to generate an Acted Monoid using Non-Type Template Parameters (NTTP).
// Useful for quickly defining acted monoids using callables supplied as NTTPs during contests.
template <typename T, typename E, auto Op, auto Id, auto OpComp, auto OpId, auto Mapping,
          bool Commutative = false, bool OperatorCommutative = false>
struct Wrapper {
    using value_type = T;
    using operator_type = E;
    static constexpr bool commutative = Commutative;
    static constexpr bool operator_commutative = OperatorCommutative;

    // Returns the identity element of the value monoid.
    static constexpr T id() {
        return Id();
    }

    // Returns the result of the value monoid binary operation.
    static constexpr T op(const T& a, const T& b) {
        return Op(a, b);
    }

    // Returns the identity element of the operator monoid.
    static constexpr E op_id() {
        return OpId();
    }

    // Composes two operations f and g (corresponds to f(g(x))).
    static constexpr E op_comp(const E& f, const E& g) {
        return OpComp(f, g);
    }

    // Applies the operator f onto the value x.
    static constexpr T mapping(const E& f, const T& x) {
        return Mapping(f, x);
    }
};

}  // namespace acted_monoid
}  // namespace m1une


#line 1 "beats_acted_monoid/concept.hpp"



#line 5 "beats_acted_monoid/concept.hpp"

#line 7 "beats_acted_monoid/concept.hpp"

namespace m1une {
namespace beats_acted_monoid {

// An acted monoid whose action may require descent before it can be applied.
template <typename AM>
concept IsBeatsActedMonoid = m1une::acted_monoid::IsActedMonoid<AM> &&
    requires(typename AM::value_type x, typename AM::operator_type f) {
        { AM::can_apply(f, x) } -> std::same_as<bool>;
    };

}  // namespace beats_acted_monoid
}  // namespace m1une


#line 1 "beats_acted_monoid/wrapper.hpp"



#line 5 "beats_acted_monoid/wrapper.hpp"

namespace m1une {
namespace beats_acted_monoid {

// Wrapper for defining a Beats acted monoid with callables supplied as NTTPs.
template <
    typename T,
    typename E,
    auto Op,
    auto Id,
    auto OpComp,
    auto OpId,
    auto Mapping,
    auto CanApply,
    auto Make = nullptr,
    auto MakeAt = nullptr,
    auto MappingAt = nullptr,
    auto CanApplyAt = nullptr,
    auto OpShift = nullptr,
    bool Commutative = false,
    bool OperatorCommutative = false
>
struct Wrapper {
    using value_type = T;
    using operator_type = E;
    static constexpr bool commutative = Commutative;
    static constexpr bool operator_commutative = OperatorCommutative;

    static constexpr T id() {
        return Id();
    }

    static constexpr T op(const T& lhs, const T& rhs) {
        return Op(lhs, rhs);
    }

    static constexpr E op_id() {
        return OpId();
    }

    static constexpr E op_comp(const E& f, const E& g) {
        return OpComp(f, g);
    }

    static constexpr T mapping(const E& f, const T& x) {
        return Mapping(f, x);
    }

    static constexpr bool can_apply(const E& f, const T& x) {
        return CanApply(f, x);
    }

    template <typename U>
    requires requires(const U& value) {
        { Make(value) } -> std::convertible_to<T>;
    }
    static constexpr T make(const U& value) {
        return Make(value);
    }

    template <typename U>
    requires requires(const U& value, int index) {
        { MakeAt(value, index) } -> std::convertible_to<T>;
    }
    static constexpr T make(const U& value, int index) {
        return MakeAt(value, index);
    }

    static constexpr T mapping(const E& f, const T& x, long long ordinal)
    requires requires {
        { MappingAt(f, x, ordinal) } -> std::convertible_to<T>;
    }
    {
        return MappingAt(f, x, ordinal);
    }

    static constexpr bool can_apply(
        const E& f,
        const T& x,
        long long ordinal
    )
    requires requires {
        { CanApplyAt(f, x, ordinal) } -> std::convertible_to<bool>;
    }
    {
        return CanApplyAt(f, x, ordinal);
    }

    static constexpr E op_shift(const E& f, long long ordinal)
    requires requires {
        { OpShift(f, ordinal) } -> std::convertible_to<E>;
    }
    {
        return OpShift(f, ordinal);
    }
};

}  // namespace beats_acted_monoid
}  // namespace m1une


#line 1 "monoid/add.hpp"



namespace m1une {
namespace monoid {

// Monoid for addition (Range Sum).
template <typename T>
struct Add {
    using value_type = T;
    static constexpr bool commutative = true;

    // Returns the identity element for addition, which is 0.
    static constexpr T id() {
        return T(0);
    }

    // Returns the sum of a and b.
    static constexpr T op(const T& a, const T& b) {
        return a + b;
    }

    static constexpr T inv(const T& x) {
        return -x;
    }
};

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/affine.hpp"



#line 5 "monoid/affine.hpp"

namespace m1une {
namespace monoid {

// Monoid for affine transformations f(x) = ax + b.
// Represented as a pair {a, b}.
template <typename T>
struct Affine {
    using value_type = std::pair<T, T>;
    static constexpr bool commutative = false;

    // The identity transformation is f(x) = 1*x + 0.
    static constexpr value_type id() {
        return {T(1), T(0)};
    }

    // Composes two affine transformations.
    // f(g(x)) where f = a, g = b.
    // a.first * (b.first * x + b.second) + a.second
    // = (a.first * b.first) * x + (a.first * b.second + a.second)
    static constexpr value_type op(const value_type& a, const value_type& b) {
        return {a.first * b.first, a.first * b.second + a.second};
    }

    // Helpers to create common affine transformations
    static constexpr value_type make_add(const T& b) {
        return {T(1), b};
    }
    static constexpr value_type make_mul(const T& a) {
        return {a, T(0)};
    }
    static constexpr value_type make_assign(const T& b) {
        return {T(0), b};
    }
};

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/and.hpp"



namespace m1une {
namespace monoid {

// Monoid for bitwise AND (Range AND).
// ~T(0) sets all bits to 1, acting as the identity for bitwise AND.
template <typename T>
struct And {
    using value_type = T;
    static constexpr bool commutative = true;

    // The identity element for bitwise AND is all bits set to 1.
    static constexpr T id() { return ~T(0); }

    // Returns the bitwise AND of a and b.
    static constexpr T op(const T& a, const T& b) { return a & b; }
};

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/arg_max.hpp"



#line 6 "monoid/arg_max.hpp"

#line 8 "monoid/arg_max.hpp"

namespace m1une {
namespace monoid {

// Monoid for finding the maximum value and its corresponding index.
// Defined as a type alias of ArgMin using std::greater.
template <typename T, T Id = std::numeric_limits<T>::lowest()>
using ArgMax = ArgMin<T, Id, std::greater<T>>;

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/bottom_k.hpp"



#line 5 "monoid/bottom_k.hpp"

#line 1 "monoid/top_k.hpp"



#line 6 "monoid/top_k.hpp"
#include <vector>

namespace m1une {
namespace monoid {

// Monoid for finding the top/bottom K elements in a range.
// The elements must be stored in the order defined by the Compare functor.
// Default Compare is std::greater<T> (i.e., descending order for Top K).
template <typename T, int K, typename Compare = std::greater<T>>
struct TopK {
    using value_type = std::vector<T>;
    static constexpr bool commutative = true;

    // The identity element is an empty vector.
    static constexpr value_type id() {
        return std::vector<T>();
    }

    // Merges two sorted vectors and keeps only the first K elements.
    static constexpr value_type op(const value_type& a, const value_type& b) {
        value_type res;
        res.reserve(std::min(K, (int)(a.size() + b.size())));

        int i = 0, j = 0;
        while (res.size() < (std::size_t)K && (i < (int)a.size() || j < (int)b.size())) {
            if (i == (int)a.size()) {
                res.push_back(b[j++]);
            } else if (j == (int)b.size()) {
                res.push_back(a[i++]);
            } else if (Compare()(a[i], b[j])) {
                res.push_back(a[i++]);
            } else {
                res.push_back(b[j++]);
            }
        }
        return res;
    }

    // Helper to securely create a leaf node from a single value.
    static constexpr value_type make(const T& val) {
        return {val};
    }
};

}  // namespace monoid
}  // namespace m1une


#line 7 "monoid/bottom_k.hpp"

namespace m1une {
namespace monoid {

// Monoid for finding the bottom K (smallest) elements in a range.
// Defined as a type alias of TopK using std::less.
template <typename T, int K>
using BottomK = TopK<T, K, std::less<T>>;

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/bracket.hpp"



#line 5 "monoid/bracket.hpp"

namespace m1une {
namespace monoid {

struct BracketNode {
    int matched;
    int unmatched_right;  // Count of unmatched ')'
    int unmatched_left;   // Count of unmatched '('
};

// Monoid for matching parentheses (Bracket Sequences).
struct Bracket {
    using value_type = BracketNode;
    static constexpr bool commutative = false;

    // The identity element is an empty sequence.
    static constexpr value_type id() {
        return {0, 0, 0};
    }

    // Merges two bracket sequences.
    // The unmatched '(' from the left perfectly matches the unmatched ')' from the right.
    static constexpr value_type op(const value_type& a, const value_type& b) {
        int match = std::min(a.unmatched_left, b.unmatched_right);
        return {a.matched + b.matched + match, a.unmatched_right + b.unmatched_right - match,
                a.unmatched_left + b.unmatched_left - match};
    }

    // Helper to securely create a leaf node from a single character.
    static constexpr value_type make(char c) {
        if (c == '(') return {0, 0, 1};
        if (c == ')') return {0, 1, 0};
        return {0, 0, 0};
    }
};

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/gcd.hpp"



#include <numeric>

namespace m1une {
namespace monoid {

// Monoid for Greatest Common Divisor (Range GCD).
template <typename T>
struct Gcd {
    using value_type = T;
    static constexpr bool commutative = true;

    // The identity element for GCD is 0.
    static constexpr T id() {
        return T(0);
    }

    // Returns the greatest common divisor of a and b.
    static constexpr T op(const T& a, const T& b) {
        return std::gcd(a, b);
    }
};

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/longest_same.hpp"



#line 5 "monoid/longest_same.hpp"

namespace m1une {
namespace monoid {

template <typename T>
struct LongestSameNode {
    int len;
    int max_len;
    T l_val;
    int l_len;
    T r_val;
    int r_len;
};

// Monoid for finding the maximum length of a contiguous subarray
// where all elements have the same value.
template <typename T>
struct LongestSame {
    using value_type = LongestSameNode<T>;
    static constexpr bool commutative = false;

    // The identity element represents an empty array.
    static constexpr value_type id() {
        return {0, 0, T(), 0, T(), 0};
    }

    // Merges two segments.
    static constexpr value_type op(const value_type& a, const value_type& b) {
        if (a.len == 0) return b;
        if (b.len == 0) return a;

        value_type res;
        res.len = a.len + b.len;
        res.max_len = std::max(a.max_len, b.max_len);

        if (a.r_val == b.l_val) {
            res.max_len = std::max(res.max_len, a.r_len + b.l_len);
        }

        res.l_val = a.l_val;
        res.l_len = a.l_len;
        if (a.len == a.l_len && a.l_val == b.l_val) {
            res.l_len += b.l_len;
        }

        res.r_val = b.r_val;
        res.r_len = b.r_len;
        if (b.len == b.r_len && b.r_val == a.r_val) {
            res.r_len += a.r_len;
        }

        return res;
    }

    // Helper to securely create a leaf node from a single value.
    static constexpr value_type make(const T& val) {
        return {1, 1, val, 1, val, 1};
    }
};

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/matrix.hpp"



#line 5 "monoid/matrix.hpp"

namespace m1une {
namespace monoid {

// Monoid for fixed-size square matrix multiplication.
template <typename T, int N>
struct Matrix {
    using value_type = std::array<std::array<T, N>, N>;
    static constexpr bool commutative = false;

    // The identity element is the identity matrix.
    static constexpr value_type id() {
        value_type res{};
        for (int i = 0; i < N; ++i) {
            res[i][i] = T(1);
        }
        return res;
    }

    // Multiplies two matrices: a * b
    static constexpr value_type op(const value_type& a, const value_type& b) {
        value_type res{};
        for (int i = 0; i < N; ++i) {
            for (int k = 0; k < N; ++k) {
                for (int j = 0; j < N; ++j) {
                    res[i][j] += a[i][k] * b[k][j];
                }
            }
        }
        return res;
    }
};

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/max.hpp"



#line 6 "monoid/max.hpp"

namespace m1une {
namespace monoid {

// Monoid for maximum (Range Maximum).
// The identity element defaults to the lowest possible value of type T, but can be overridden.
template <typename T, T Id = std::numeric_limits<T>::lowest()>
struct Max {
    using value_type = T;
    static constexpr bool commutative = true;

    // Returns the identity element for maximum.
    static constexpr T id() {
        return Id;
    }

    // Returns the maximum of a and b.
    static constexpr T op(const T& a, const T& b) {
        return std::max(a, b);
    }
};

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/max_count.hpp"



#line 6 "monoid/max_count.hpp"

#line 8 "monoid/max_count.hpp"

namespace m1une {
namespace monoid {

// Monoid for finding the maximum value and its frequency in a range.
// Defined as a type alias of MinCount using std::greater.
template <typename T, T Id = std::numeric_limits<T>::lowest()>
using MaxCount = MinCount<T, Id, std::greater<T>>;

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/max_plus_matrix.hpp"



#line 7 "monoid/max_plus_matrix.hpp"

namespace m1une {
namespace monoid {

// Monoid for fixed-size square matrix multiplication over the Max-Plus semiring.
// Useful for Dynamic DP (Maximization) and Longest Path problems.
template <typename T, int N, T MinInf = std::numeric_limits<T>::lowest() / 2>
struct MaxPlusMatrix {
    using value_type = std::array<std::array<T, N>, N>;
    static constexpr bool commutative = false;

    // The identity matrix for max-plus algebra.
    // Diagonal elements are 0 (identity for addition).
    // Off-diagonal elements are MinInf (identity for max).
    static constexpr value_type id() {
        value_type res{};
        for (int i = 0; i < N; ++i) {
            for (int j = 0; j < N; ++j) {
                res[i][j] = (i == j) ? T(0) : MinInf;
            }
        }
        return res;
    }

    // Multiplies two max-plus matrices: c_{i, j} = max_k (a_{i, k} + b_{k, j})
    static constexpr value_type op(const value_type& a, const value_type& b) {
        value_type res{};
        for (int i = 0; i < N; ++i) {
            for (int j = 0; j < N; ++j) {
                res[i][j] = MinInf;
            }
        }
        for (int i = 0; i < N; ++i) {
            for (int k = 0; k < N; ++k) {
                if (a[i][k] == MinInf) continue;
                for (int j = 0; j < N; ++j) {
                    if (b[k][j] == MinInf) continue;
                    res[i][j] = std::max(res[i][j], a[i][k] + b[k][j]);
                }
            }
        }
        return res;
    }

    // Helper to securely create a matrix initialized with MinInf.
    static constexpr value_type make_inf() {
        value_type res{};
        for (int i = 0; i < N; ++i) {
            for (int j = 0; j < N; ++j) {
                res[i][j] = MinInf;
            }
        }
        return res;
    }
};

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/max_subarray.hpp"



#line 6 "monoid/max_subarray.hpp"

#line 1 "monoid/min_subarray.hpp"



#line 6 "monoid/min_subarray.hpp"

namespace m1une {
namespace monoid {

// Node for managing the optimal subarray sum.
template <typename T>
struct SubarrayNode {
    T sum;
    T pre;
    T suf;
    T opt;  // Holds the optimal value (e.g., min or max)
};

// Monoid for finding the minimum subarray sum in a range.
// Uses a comparison functor (Compare) to determine the optimal value.
// Can be reused for maximum subarray sum by changing the Compare functor.
template <typename T, T Id = std::numeric_limits<T>::max() / 2, typename Compare = std::less<T>>
struct MinSubarray {
    using value_type = SubarrayNode<T>;
    static constexpr bool commutative = false;

    // The identity element contains values that do not affect the result.
    static constexpr value_type id() {
        return {T(0), Id, Id, Id};
    }

    // Merges two subarray nodes.
    static constexpr value_type op(const value_type& a, const value_type& b) {
        if (a.opt == Id) return b;
        if (b.opt == Id) return a;

        // Lambda to select the optimal value according to the comparison functor.
        auto get_opt = [](const T& x, const T& y) { return Compare()(x, y) ? x : y; };

        return {a.sum + b.sum, get_opt(a.pre, a.sum + b.pre), get_opt(b.suf, a.suf + b.sum),
                get_opt(get_opt(a.opt, b.opt), a.suf + b.pre)};
    }

    // Helper to securely create a leaf node from a single value.
    // Set `allow_empty = true` if empty subarrays (sum = 0) are valid answers.
    static constexpr value_type make(const T& val, bool allow_empty = false) {
        if (allow_empty) {
            T opt_val = Compare()(val, T(0)) ? val : T(0);
            return {val, opt_val, opt_val, opt_val};
        }
        return {val, val, val, val};
    }
};

}  // namespace monoid
}  // namespace m1une


#line 8 "monoid/max_subarray.hpp"

namespace m1une {
namespace monoid {

// Monoid for finding the maximum subarray sum in a range.
// Defined as a type alias of MinSubarray using std::greater.
template <typename T, T Id = std::numeric_limits<T>::lowest() / 2>
using MaxSubarray = MinSubarray<T, Id, std::greater<T>>;

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/min.hpp"



#line 6 "monoid/min.hpp"

namespace m1une {
namespace monoid {

// Monoid for minimum (Range Minimum).
// The identity element defaults to the maximum possible value of type T, but can be overridden.
template <typename T, T Id = std::numeric_limits<T>::max()>
struct Min {
    using value_type = T;
    static constexpr bool commutative = true;

    // Returns the identity element for minimum.
    static constexpr T id() {
        return Id;
    }

    // Returns the minimum of a and b.
    static constexpr T op(const T& a, const T& b) {
        return std::min(a, b);
    }
};

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/min_max.hpp"



#line 7 "monoid/min_max.hpp"

namespace m1une {
namespace monoid {

// Monoid for finding both the minimum and maximum values in a range simultaneously.
template <typename T, T MinId = std::numeric_limits<T>::max(), T MaxId = std::numeric_limits<T>::lowest()>
struct MinMax {
    using value_type = std::pair<T, T>;
    static constexpr bool commutative = true;

    // The identity element contains the bounds for min and max.
    static constexpr value_type id() {
        return {MinId, MaxId};
    }

    // Merges two elements, extracting the overall min and max.
    static constexpr value_type op(const value_type& a, const value_type& b) {
        return {std::min(a.first, b.first), std::max(a.second, b.second)};
    }

    // Helper to securely create a leaf node from a single value.
    static constexpr value_type make(const T& val) {
        return {val, val};
    }
};

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/min_plus_matrix.hpp"



#line 7 "monoid/min_plus_matrix.hpp"

namespace m1une {
namespace monoid {

// Monoid for fixed-size square matrix multiplication over the Min-Plus (Tropical) semiring.
// Useful for Dynamic DP (Minimization) and Shortest Path problems.
template <typename T, int N, T Inf = std::numeric_limits<T>::max() / 2>
struct MinPlusMatrix {
    using value_type = std::array<std::array<T, N>, N>;
    static constexpr bool commutative = false;

    // The identity matrix for min-plus algebra.
    // Diagonal elements are 0 (identity for addition).
    // Off-diagonal elements are Inf (identity for min).
    static constexpr value_type id() {
        value_type res{};
        for (int i = 0; i < N; ++i) {
            for (int j = 0; j < N; ++j) {
                res[i][j] = (i == j) ? T(0) : Inf;
            }
        }
        return res;
    }

    // Multiplies two min-plus matrices: c_{i, j} = min_k (a_{i, k} + b_{k, j})
    static constexpr value_type op(const value_type& a, const value_type& b) {
        value_type res{};
        for (int i = 0; i < N; ++i) {
            for (int j = 0; j < N; ++j) {
                res[i][j] = Inf;
            }
        }
        for (int i = 0; i < N; ++i) {
            for (int k = 0; k < N; ++k) {
                if (a[i][k] == Inf) continue;
                for (int j = 0; j < N; ++j) {
                    if (b[k][j] == Inf) continue;
                    res[i][j] = std::min(res[i][j], a[i][k] + b[k][j]);
                }
            }
        }
        return res;
    }

    // Helper to securely create a matrix initialized with Inf.
    static constexpr value_type make_inf() {
        value_type res{};
        for (int i = 0; i < N; ++i) {
            for (int j = 0; j < N; ++j) {
                res[i][j] = Inf;
            }
        }
        return res;
    }
};

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/mul.hpp"



namespace m1une {
namespace monoid {

// Monoid for multiplication (Range Product).
template <typename T>
struct Mul {
    using value_type = T;
    static constexpr bool commutative = true;

    // Returns the identity element for multiplication, which is 1.
    static constexpr T id() {
        return T(1);
    }

    // Returns the product of a and b.
    static constexpr T op(const T& a, const T& b) {
        return a * b;
    }
};

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/or.hpp"



namespace m1une {
namespace monoid {

// Monoid for bitwise OR (Range OR).
template <typename T>
struct Or {
    using value_type = T;
    static constexpr bool commutative = true;

    // The identity element for bitwise OR is 0 (all bits 0).
    static constexpr T id() {
        return T(0);
    }

    // Returns the bitwise OR of a and b.
    static constexpr T op(const T& a, const T& b) {
        return a | b;
    }
};

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/permutation.hpp"



#line 6 "monoid/permutation.hpp"

namespace m1une {
namespace monoid {

// Monoid for Permutation Composition.
// Represents a permutation of fixed size N.
template <int N>
struct Permutation {
    using value_type = std::array<int, N>;
    static constexpr bool commutative = false;

    // The identity element is the identity permutation (0, 1, 2, ..., N-1).
    static constexpr value_type id() {
        value_type res{};
        std::iota(res.begin(), res.end(), 0);
        return res;
    }

    // Composes two permutations (applies 'a' then 'b').
    static constexpr value_type op(const value_type& a, const value_type& b) {
        value_type res{};
        for (int i = 0; i < N; ++i) {
            res[i] = b[a[i]];
        }
        return res;
    }
};

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/rolling_hash.hpp"



#line 5 "monoid/rolling_hash.hpp"

#line 1 "string/rolling_hash.hpp"



#line 5 "string/rolling_hash.hpp"
#include <string>
#line 8 "string/rolling_hash.hpp"

namespace m1une {
namespace string {

// Standard Rolling Hash for static strings.
// Precomputes hashes to answer substring queries in O(1).
// Provides advanced operations like LCP, lexicographical comparison, and string repetition in O(log N).
template <long long Base = 10007, long long Mod = (1LL << 61) - 1>
struct RollingHash {
    std::string s;
    std::vector<long long> hash;
    std::vector<long long> power;

    RollingHash() = default;

    // Constructs the rolling hash table for the given string.
    explicit RollingHash(const std::string& str) : s(str) {
        int n = s.size();
        hash.assign(n + 1, 0);
        power.assign(n + 1, 1);
        for (int i = 0; i < n; ++i) {
            // Use __int128_t to prevent overflow during multiplication
            hash[i + 1] = (static_cast<__int128_t>(hash[i]) * Base + s[i]) % Mod;
            power[i + 1] = (static_cast<__int128_t>(power[i]) * Base) % Mod;
        }
    }

    // Returns the hash of the substring S[l..r) in O(1).
    long long get(int l, int r) const {
        long long res = hash[r] - (static_cast<__int128_t>(hash[l]) * power[r - l]) % Mod;
        if (res < 0) res += Mod;
        return res;
    }

    // Returns the hash of the concatenated substrings S[l1..r1) and S[l2..r2).
    long long concat(int l1, int r1, int l2, int r2) const {
        long long h1 = get(l1, r1);
        long long h2 = get(l2, r2);
        return combine(h1, h2, power[r2 - l2]);
    }

    // Calculates the Longest Common Prefix (LCP) length of S[l1..r1) and S[l2..r2) in O(log N).
    int lcp(int l1, int r1, int l2, int r2) const {
        int len = std::min(r1 - l1, r2 - l2);
        int low = 0, high = len + 1;
        while (high - low > 1) {
            int mid = low + (high - low) / 2;
            if (get(l1, l1 + mid) == get(l2, l2 + mid)) {
                low = mid;
            } else {
                high = mid;
            }
        }
        return low;
    }

    // Lexicographically compares S[l1..r1) and S[l2..r2) in O(log N).
    // Returns -1 if S[l1..r1) < S[l2..r2), 0 if equal, and 1 if S[l1..r1) > S[l2..r2).
    int compare(int l1, int r1, int l2, int r2) const {
        int l = lcp(l1, r1, l2, r2);
        bool end1 = (l1 + l == r1);
        bool end2 = (l2 + l == r2);
        if (end1 && end2) return 0;
        if (end1) return -1;
        if (end2) return 1;
        return s[l1 + l] < s[l2 + l] ? -1 : 1;
    }

    // Returns the hash of the substring S[l..r) repeated 'k' times.
    long long repeat(int l, int r, long long k) const {
        long long h = get(l, r);
        long long p = power[r - l];
        return repeat_hash(h, p, k);
    }

    // --- Static Helpers for dynamic processing and Monoid integration ---

    // Computes the hash of a single string in O(N) time and O(1) space.
    static long long compute_hash(const std::string& str) {
        long long h = 0;
        for (char c : str) {
            h = (static_cast<__int128_t>(h) * Base + c) % Mod;
        }
        return h;
    }

    // Combines two hashes. Equivalent to concatenating string 'b' to the right of string 'a'.
    static constexpr long long combine(long long h1, long long h2, long long base_power2) {
        return (static_cast<__int128_t>(h1) * base_power2 + h2) % Mod;
    }

    // Returns the hash of a string (with hash 'h' and base_power 'p') repeated 'k' times.
    static constexpr long long repeat_hash(long long h, long long p, long long k) {
        long long res_h = 0;
        long long res_p = 1;
        long long cur_h = h;
        long long cur_p = p;
        while (k > 0) {
            if (k & 1) {
                res_h = combine(res_h, cur_h, cur_p);
                res_p = (static_cast<__int128_t>(res_p) * cur_p) % Mod;
            }
            cur_h = combine(cur_h, cur_h, cur_p);
            cur_p = (static_cast<__int128_t>(cur_p) * cur_p) % Mod;
            k >>= 1;
        }
        return res_h;
    }

    // Creates the state pair {hash_value, base_power} for a single character.
    static constexpr std::pair<long long, long long> make_single(long long c) {
        return {c % Mod, Base % Mod};
    }
};

}  // namespace string
}  // namespace m1une


#line 7 "monoid/rolling_hash.hpp"

namespace m1une {
namespace monoid {

// Monoid for Dynamic Rolling Hash (String Concatenation).
// Acts as a clean wrapper around the mathematical logic defined in string::RollingHash.
//
// [Important Usage Note for Contests]
// To initialize a leaf node for a single character S[i], use the `make` method:
//
// Example:
//   std::vector<RH::value_type> init_data(N);
//   for (int i = 0; i < N; ++i) {
//       init_data[i] = RH::make(S[i]);
//   }
//   Segtree<RH> seg(init_data);
template <long long Base = 10007, long long Mod = (1LL << 61) - 1>
struct RollingHash {
    using StringRH = m1une::string::RollingHash<Base, Mod>;
    using value_type = std::pair<long long, long long>;
    static constexpr bool commutative = false;

    // The identity element represents an empty string.
    static constexpr value_type id() {
        return {0LL, 1LL};
    }

    // Combines two hashes by delegating to string::RollingHash.
    static constexpr value_type op(const value_type& a, const value_type& b) {
        return {StringRH::combine(a.first, b.first, b.second), (static_cast<__int128_t>(a.second) * b.second) % Mod};
    }

    // Helper to securely create a monoid element from a single character (or integer).
    // Delegates to string::RollingHash to hide the base/mod mechanics.
    static constexpr value_type make(long long c) {
        return StringRH::make_single(c);
    }
};

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/strict_max2.hpp"



#line 6 "monoid/strict_max2.hpp"

#line 1 "monoid/strict_min2.hpp"



#line 6 "monoid/strict_min2.hpp"

namespace m1une {
namespace monoid {

template <typename T>
struct StrictOpt2Node {
    T opt1;  // The strictly best value
    T opt2;  // The strictly second-best value
};

// Monoid for finding the strictly 1st and 2nd optimal (minimum by default) values in a range.
template <typename T, T Id = std::numeric_limits<T>::max(), typename Compare = std::less<T>>
struct StrictMin2 {
    using value_type = StrictOpt2Node<T>;
    static constexpr bool commutative = true;

    // The identity element has both values set to Id.
    static constexpr value_type id() {
        return {Id, Id};
    }

    // Merges two elements, preserving the top 2 strictly unique values.
    static constexpr value_type op(const value_type& a, const value_type& b) {
        auto update = [](T& m1, T& m2, T val) {
            if (val == Id || val == m1 || val == m2) return;
            if (m1 == Id || Compare()(val, m1)) {
                m2 = m1;
                m1 = val;
            } else if (m2 == Id || Compare()(val, m2)) {
                m2 = val;
            }
        };

        T m1 = Id, m2 = Id;
        update(m1, m2, a.opt1);
        update(m1, m2, a.opt2);
        update(m1, m2, b.opt1);
        update(m1, m2, b.opt2);

        return {m1, m2};
    }

    // Helper to securely create a leaf node.
    static constexpr value_type make(const T& val) {
        return {val, Id};
    }
};

}  // namespace monoid
}  // namespace m1une


#line 8 "monoid/strict_max2.hpp"

namespace m1une {
namespace monoid {

// Monoid for finding the strictly 1st and 2nd maximum values in a range.
// Defined as a type alias of StrictMin2 using std::greater.
template <typename T, T Id = std::numeric_limits<T>::lowest()>
using StrictMax2 = StrictMin2<T, Id, std::greater<T>>;

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/top_k_count.hpp"



#line 8 "monoid/top_k_count.hpp"

namespace m1une {
namespace monoid {

// Monoid for finding the top K distinct elements and their frequencies in a range.
// The default Compare is std::greater<T> (descending order for Top K).
template <typename T, int K, typename Compare = std::greater<T>>
struct TopKCount {
    using value_type = std::vector<std::pair<T, int>>;
    static constexpr bool commutative = true;

    static constexpr value_type id() {
        return value_type();
    }

    static constexpr value_type op(const value_type& a, const value_type& b) {
        value_type res;
        res.reserve(std::min(K, (int)(a.size() + b.size())));

        int i = 0, j = 0;
        while (res.size() < (std::size_t)K && (i < (int)a.size() || j < (int)b.size())) {
            if (i == (int)a.size()) {
                res.push_back(b[j++]);
            } else if (j == (int)b.size()) {
                res.push_back(a[i++]);
            } else if (a[i].first == b[j].first) {
                // If the values are identical, merge their counts
                res.push_back({a[i].first, a[i].second + b[j].second});
                i++;
                j++;
            } else if (Compare()(a[i].first, b[j].first)) {
                res.push_back(a[i++]);
            } else {
                res.push_back(b[j++]);
            }
        }
        return res;
    }

    // Helper to securely create a leaf node from a single value.
    static constexpr value_type make(const T& val, int count = 1) {
        return value_type{std::pair<T, int>{val, count}};
    }
};

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/update.hpp"



#line 5 "monoid/update.hpp"

namespace m1une {
namespace monoid {

// Monoid for range updates/assignments.
// Uses std::optional to represent the presence of an assignment.
template <typename T>
struct Update {
    using value_type = std::optional<T>;
    static constexpr bool commutative = false;

    // The identity element represents "no operation".
    static constexpr value_type id() {
        return std::nullopt;
    }

    // Composes two updates. The newer operation 'a' overwrites the older 'b'.
    // If 'a' does not exist, it falls back to 'b'.
    static constexpr value_type op(const value_type& a, const value_type& b) {
        return a.has_value() ? a : b;
    }
};

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/wrapper.hpp"



namespace m1une {
namespace monoid {

// Wrapper struct to generate a Monoid using Non-Type Template Parameters (NTTP).
// Useful for quickly defining monoids using custom functions or constexpr lambdas during contests.
template <typename T, auto Op, auto Id, bool Commutative = false>
struct Wrapper {
    using value_type = T;
    static constexpr bool commutative = Commutative;

    // Returns the identity element by invoking the provided `Id` function.
    static constexpr T id() {
        return Id();
    }

    // Returns the result of the binary operation by invoking the provided `Op` function.
    static constexpr T op(const T& a, const T& b) {
        return Op(a, b);
    }
};

}  // namespace monoid
}  // namespace m1une


#line 1 "monoid/xor.hpp"



namespace m1une {
namespace monoid {

// Monoid for bitwise XOR (Range XOR).
template <typename T>
struct Xor {
    using value_type = T;
    static constexpr bool commutative = true;

    // Returns the identity element for bitwise XOR, which is 0.
    static constexpr T id() {
        return T(0);
    }

    // Returns the bitwise XOR of a and b.
    static constexpr T op(const T& a, const T& b) {
        return a ^ b;
    }

    static constexpr T inv(const T& x) {
        return x;
    }
};

}  // namespace monoid
}  // namespace m1une


#line 67 "verify/monoid/commutative_flags.test.cpp"

namespace {

struct ContestMonoid {
    using value_type = int;

    static constexpr int id() {
        return 0;
    }
    static constexpr int op(const int& a, const int& b) {
        return a + b;
    }
};

struct ContestActedMonoid {
    using value_type = int;
    using operator_type = int;

    static constexpr int id() {
        return 0;
    }
    static constexpr int op(const int& a, const int& b) {
        return a + b;
    }
    static constexpr int op_id() {
        return 0;
    }
    static constexpr int op_comp(const int& f, const int& g) {
        return f + g;
    }
    static constexpr int mapping(const int& f, const int& x) {
        return f + x;
    }
};

constexpr auto int_add = [](const int& a, const int& b) { return a + b; };
constexpr auto int_zero = [] { return 0; };
constexpr auto int_mapping = [](const int& f, const int& x) { return f + x; };
constexpr auto always_applicable = [](const int&, const int&) { return true; };

using DefaultMonoidWrapper = m1une::monoid::Wrapper<int, int_add, int_zero>;
using CommutativeMonoidWrapper = m1une::monoid::Wrapper<int, int_add, int_zero, true>;
using DefaultActedWrapper =
    m1une::acted_monoid::Wrapper<int, int, int_add, int_zero, int_add, int_zero, int_mapping>;
using CommutativeActedWrapper =
    m1une::acted_monoid::Wrapper<int, int, int_add, int_zero, int_add, int_zero, int_mapping, true>;
using CommutativeOperatorActedWrapper =
    m1une::acted_monoid::Wrapper<int, int, int_add, int_zero, int_add, int_zero, int_mapping, false, true>;
using DefaultBeatsWrapper = m1une::beats_acted_monoid::Wrapper<
    int, int, int_add, int_zero, int_add, int_zero, int_mapping, always_applicable>;
using CommutativeBeatsWrapper = m1une::beats_acted_monoid::Wrapper<
    int, int, int_add, int_zero, int_add, int_zero, int_mapping, always_applicable,
    nullptr, nullptr, nullptr, nullptr, nullptr, true>;
using CommutativeOperatorBeatsWrapper = m1une::beats_acted_monoid::Wrapper<
    int, int, int_add, int_zero, int_add, int_zero, int_mapping, always_applicable,
    nullptr, nullptr, nullptr, nullptr, nullptr, false, true>;

static_assert(m1une::monoid::IsMonoid<ContestMonoid>);
static_assert(m1une::acted_monoid::IsActedMonoid<ContestActedMonoid>);
static_assert(
    m1une::beats_acted_monoid::IsBeatsActedMonoid<DefaultBeatsWrapper>
);

static_assert(m1une::monoid::Add<int>::commutative);
static_assert(m1une::monoid::And<int>::commutative);
static_assert(m1une::monoid::BottomK<int, 2>::commutative);
static_assert(m1une::monoid::Gcd<int>::commutative);
static_assert(m1une::monoid::Max<int>::commutative);
static_assert(m1une::monoid::MaxCount<int>::commutative);
static_assert(m1une::monoid::Min<int>::commutative);
static_assert(m1une::monoid::MinCount<int>::commutative);
static_assert(m1une::monoid::MinMax<int>::commutative);
static_assert(m1une::monoid::Mul<int>::commutative);
static_assert(m1une::monoid::Or<int>::commutative);
static_assert(m1une::monoid::StrictMax2<int>::commutative);
static_assert(m1une::monoid::StrictMin2<int>::commutative);
static_assert(m1une::monoid::TopK<int, 2>::commutative);
static_assert(m1une::monoid::TopKCount<int, 2>::commutative);
static_assert(m1une::monoid::Xor<int>::commutative);
static_assert(CommutativeMonoidWrapper::commutative);

static_assert(!m1une::monoid::Affine<int>::commutative);
static_assert(!m1une::monoid::ArgMax<int>::commutative);
static_assert(!m1une::monoid::ArgMin<int>::commutative);
static_assert(!m1une::monoid::BinaryInversion<int>::commutative);
static_assert(!m1une::monoid::Bracket::commutative);
static_assert(!m1une::monoid::LongestSame<int>::commutative);
static_assert(!m1une::monoid::LongestTrue::commutative);
static_assert(!m1une::monoid::Matrix<int, 2>::commutative);
static_assert(!m1une::monoid::MaxPlusMatrix<int, 2>::commutative);
static_assert(!m1une::monoid::MaxSubarray<int>::commutative);
static_assert(!m1une::monoid::MinPlusMatrix<int, 2>::commutative);
static_assert(!m1une::monoid::MinSubarray<int>::commutative);
static_assert(!m1une::monoid::Permutation<3>::commutative);
static_assert(!m1une::monoid::RollingHash<>::commutative);
static_assert(!m1une::monoid::Update<int>::commutative);
static_assert(!DefaultMonoidWrapper::commutative);

static_assert(m1une::acted_monoid::RangeAddRangeMax<int>::commutative);
static_assert(m1une::acted_monoid::RangeAddRangeMin<int>::commutative);
static_assert(m1une::acted_monoid::RangeAddRangeMinCount<int>::commutative);
static_assert(m1une::acted_monoid::RangeAddRangeSum<int>::commutative);
static_assert(m1une::acted_monoid::RangeAffineRangeMinMax<int>::commutative);
static_assert(m1une::acted_monoid::RangeAffineRangeSum<int>::commutative);
static_assert(m1une::acted_monoid::RangeAffineRangeSumOfSquares<int>::commutative);
static_assert(m1une::acted_monoid::RangeApUpdateRangeMinMax<int>::commutative);
static_assert(m1une::acted_monoid::RangeBitwiseAndOrXorRangeSum<int>::commutative);
static_assert(m1une::acted_monoid::RangeFlipRangeSum<int>::commutative);
static_assert(m1une::acted_monoid::RangeMulRangeSum<int>::commutative);
static_assert(m1une::acted_monoid::RangeOrRangeSum<int>::commutative);
static_assert(m1une::acted_monoid::RangeUpdateRangeMax<int>::commutative);
static_assert(m1une::acted_monoid::RangeUpdateRangeMin<int>::commutative);
static_assert(m1une::acted_monoid::RangeUpdateRangeProduct<m1une::monoid::Add<int>>::commutative);
static_assert(m1une::acted_monoid::RangeUpdateRangeSum<int>::commutative);
static_assert(m1une::acted_monoid::RangeXorRangeSum<int>::commutative);
static_assert(m1une::acted_monoid::RangeXorRangeXor<int>::commutative);
static_assert(CommutativeActedWrapper::commutative);
static_assert(CommutativeBeatsWrapper::commutative);

static_assert(!m1une::acted_monoid::RangeAddRangeArgMax<int>::commutative);
static_assert(!m1une::acted_monoid::RangeAddRangeArgMin<int>::commutative);
static_assert(!m1une::acted_monoid::RangeApAddRangeSum<int>::commutative);
static_assert(!m1une::acted_monoid::RangeApUpdateRangeSum<int>::commutative);
static_assert(!m1une::acted_monoid::RangeFlipRangeBinaryInversion<int>::commutative);
static_assert(!m1une::acted_monoid::RangeUpdateRangeLongestTrue::commutative);
static_assert(!m1une::acted_monoid::RangeUpdateRangeMaxSubarray<int>::commutative);
static_assert(!m1une::acted_monoid::RangeUpdateRangeProduct<m1une::monoid::Affine<int>>::commutative);
static_assert(!m1une::acted_monoid::RangeUpdateRangeProduct<ContestMonoid>::commutative);
static_assert(!DefaultActedWrapper::commutative);
static_assert(!DefaultBeatsWrapper::commutative);

static_assert(m1une::acted_monoid::RangeAddRangeArgMax<int>::operator_commutative);
static_assert(m1une::acted_monoid::RangeAddRangeArgMin<int>::operator_commutative);
static_assert(m1une::acted_monoid::RangeAddRangeMax<int>::operator_commutative);
static_assert(m1une::acted_monoid::RangeAddRangeMin<int>::operator_commutative);
static_assert(m1une::acted_monoid::RangeAddRangeMinCount<int>::operator_commutative);
static_assert(m1une::acted_monoid::RangeAddRangeSum<int>::operator_commutative);
static_assert(m1une::acted_monoid::RangeApAddRangeSum<int>::operator_commutative);
static_assert(m1une::acted_monoid::RangeFlipRangeBinaryInversion<int>::operator_commutative);
static_assert(m1une::acted_monoid::RangeFlipRangeSum<int>::operator_commutative);
static_assert(m1une::acted_monoid::RangeMulRangeSum<int>::operator_commutative);
static_assert(m1une::acted_monoid::RangeOrRangeSum<int>::operator_commutative);
static_assert(m1une::acted_monoid::RangeXorRangeSum<int>::operator_commutative);
static_assert(m1une::acted_monoid::RangeXorRangeXor<int>::operator_commutative);
static_assert(CommutativeOperatorActedWrapper::operator_commutative);
static_assert(CommutativeOperatorBeatsWrapper::operator_commutative);

static_assert(!m1une::acted_monoid::RangeAffineRangeMinMax<int>::operator_commutative);
static_assert(!m1une::acted_monoid::RangeAffineRangeSum<int>::operator_commutative);
static_assert(!m1une::acted_monoid::RangeAffineRangeSumOfSquares<int>::operator_commutative);
static_assert(!m1une::acted_monoid::RangeApUpdateRangeMinMax<int>::operator_commutative);
static_assert(!m1une::acted_monoid::RangeApUpdateRangeSum<int>::operator_commutative);
static_assert(!m1une::acted_monoid::RangeBitwiseAndOrXorRangeSum<int>::operator_commutative);
static_assert(!m1une::acted_monoid::RangeUpdateRangeLongestTrue::operator_commutative);
static_assert(!m1une::acted_monoid::RangeUpdateRangeMax<int>::operator_commutative);
static_assert(!m1une::acted_monoid::RangeUpdateRangeMaxSubarray<int>::operator_commutative);
static_assert(!m1une::acted_monoid::RangeUpdateRangeMin<int>::operator_commutative);
static_assert(
    !m1une::acted_monoid::RangeUpdateRangeProduct<m1une::monoid::Add<int>>::operator_commutative);
static_assert(!m1une::acted_monoid::RangeUpdateRangeSum<int>::operator_commutative);
static_assert(!DefaultActedWrapper::operator_commutative);
static_assert(!DefaultBeatsWrapper::operator_commutative);
static_assert(!CommutativeActedWrapper::operator_commutative);
static_assert(!CommutativeBeatsWrapper::operator_commutative);
static_assert(!CommutativeOperatorActedWrapper::commutative);
static_assert(!CommutativeOperatorBeatsWrapper::commutative);

}  // namespace

int main() {
    int a, b;
    std::cin >> a >> b;
    std::cout << a + b << '\n';
}
Back to top page