QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#702405#9539. Disrupting Communicationsucup-team5234#AC ✓340ms62820kbC++2377.9kb2024-11-02 15:55:322024-11-02 15:55:33

Judging History

This is the latest submission verdict.

  • [2024-11-02 15:55:33]
  • Judged
  • Verdict: AC
  • Time: 340ms
  • Memory: 62820kb
  • [2024-11-02 15:55:32]
  • Submitted

answer


#include <algorithm>
#include <array>
#include <cassert>
#include <type_traits>
#include <vector>


#ifdef _MSC_VER
#include <intrin.h>
#endif

#if __cplusplus >= 202002L
#include <bit>
#endif

namespace atcoder {

namespace internal {

#if __cplusplus >= 202002L

using std::bit_ceil;

#else

// @return same with std::bit::bit_ceil
unsigned int bit_ceil(unsigned int n) {
    unsigned int x = 1;
    while (x < (unsigned int)(n)) x *= 2;
    return x;
}

#endif

// @param n `1 <= n`
// @return same with std::bit::countr_zero
int countr_zero(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}

// @param n `1 <= n`
// @return same with std::bit::countr_zero
constexpr int countr_zero_constexpr(unsigned int n) {
    int x = 0;
    while (!(n & (1 << x))) x++;
    return x;
}

}  // namespace internal

}  // namespace atcoder


#include <cassert>
#include <numeric>
#include <type_traits>

#ifdef _MSC_VER
#include <intrin.h>
#endif


#include <utility>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

// @param m `1 <= m`
// @return x mod m
constexpr long long safe_mod(long long x, long long m) {
    x %= m;
    if (x < 0) x += m;
    return x;
}

// Fast modular multiplication by barrett reduction
// Reference: https://en.wikipedia.org/wiki/Barrett_reduction
// NOTE: reconsider after Ice Lake
struct barrett {
    unsigned int _m;
    unsigned long long im;

    // @param m `1 <= m`
    explicit barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {}

    // @return m
    unsigned int umod() const { return _m; }

    // @param a `0 <= a < m`
    // @param b `0 <= b < m`
    // @return `a * b % m`
    unsigned int mul(unsigned int a, unsigned int b) const {
        // [1] m = 1
        // a = b = im = 0, so okay

        // [2] m >= 2
        // im = ceil(2^64 / m)
        // -> im * m = 2^64 + r (0 <= r < m)
        // let z = a*b = c*m + d (0 <= c, d < m)
        // a*b * im = (c*m + d) * im = c*(im*m) + d*im = c*2^64 + c*r + d*im
        // c*r + d*im < m * m + m * im < m * m + 2^64 + m <= 2^64 + m * (m + 1) < 2^64 * 2
        // ((ab * im) >> 64) == c or c + 1
        unsigned long long z = a;
        z *= b;
#ifdef _MSC_VER
        unsigned long long x;
        _umul128(z, im, &x);
#else
        unsigned long long x =
            (unsigned long long)(((unsigned __int128)(z)*im) >> 64);
#endif
        unsigned long long y = x * _m;
        return (unsigned int)(z - y + (z < y ? _m : 0));
    }
};

// @param n `0 <= n`
// @param m `1 <= m`
// @return `(x ** n) % m`
constexpr long long pow_mod_constexpr(long long x, long long n, int m) {
    if (m == 1) return 0;
    unsigned int _m = (unsigned int)(m);
    unsigned long long r = 1;
    unsigned long long y = safe_mod(x, m);
    while (n) {
        if (n & 1) r = (r * y) % _m;
        y = (y * y) % _m;
        n >>= 1;
    }
    return r;
}

// Reference:
// M. Forisek and J. Jancina,
// Fast Primality Testing for Integers That Fit into a Machine Word
// @param n `0 <= n`
constexpr bool is_prime_constexpr(int n) {
    if (n <= 1) return false;
    if (n == 2 || n == 7 || n == 61) return true;
    if (n % 2 == 0) return false;
    long long d = n - 1;
    while (d % 2 == 0) d /= 2;
    constexpr long long bases[3] = {2, 7, 61};
    for (long long a : bases) {
        long long t = d;
        long long y = pow_mod_constexpr(a, t, n);
        while (t != n - 1 && y != 1 && y != n - 1) {
            y = y * y % n;
            t <<= 1;
        }
        if (y != n - 1 && t % 2 == 0) {
            return false;
        }
    }
    return true;
}
template <int n> constexpr bool is_prime = is_prime_constexpr(n);

// @param b `1 <= b`
// @return pair(g, x) s.t. g = gcd(a, b), xa = g (mod b), 0 <= x < b/g
constexpr std::pair<long long, long long> inv_gcd(long long a, long long b) {
    a = safe_mod(a, b);
    if (a == 0) return {b, 0};

    // Contracts:
    // [1] s - m0 * a = 0 (mod b)
    // [2] t - m1 * a = 0 (mod b)
    // [3] s * |m1| + t * |m0| <= b
    long long s = b, t = a;
    long long m0 = 0, m1 = 1;

    while (t) {
        long long u = s / t;
        s -= t * u;
        m0 -= m1 * u;  // |m1 * u| <= |m1| * s <= b

        // [3]:
        // (s - t * u) * |m1| + t * |m0 - m1 * u|
        // <= s * |m1| - t * u * |m1| + t * (|m0| + |m1| * u)
        // = s * |m1| + t * |m0| <= b

        auto tmp = s;
        s = t;
        t = tmp;
        tmp = m0;
        m0 = m1;
        m1 = tmp;
    }
    // by [3]: |m0| <= b/g
    // by g != b: |m0| < b/g
    if (m0 < 0) m0 += b / s;
    return {s, m0};
}

// Compile time primitive root
// @param m must be prime
// @return primitive root (and minimum in now)
constexpr int primitive_root_constexpr(int m) {
    if (m == 2) return 1;
    if (m == 167772161) return 3;
    if (m == 469762049) return 3;
    if (m == 754974721) return 11;
    if (m == 998244353) return 3;
    int divs[20] = {};
    divs[0] = 2;
    int cnt = 1;
    int x = (m - 1) / 2;
    while (x % 2 == 0) x /= 2;
    for (int i = 3; (long long)(i)*i <= x; i += 2) {
        if (x % i == 0) {
            divs[cnt++] = i;
            while (x % i == 0) {
                x /= i;
            }
        }
    }
    if (x > 1) {
        divs[cnt++] = x;
    }
    for (int g = 2;; g++) {
        bool ok = true;
        for (int i = 0; i < cnt; i++) {
            if (pow_mod_constexpr(g, (m - 1) / divs[i], m) == 1) {
                ok = false;
                break;
            }
        }
        if (ok) return g;
    }
}
template <int m> constexpr int primitive_root = primitive_root_constexpr(m);

// @param n `n < 2^32`
// @param m `1 <= m < 2^32`
// @return sum_{i=0}^{n-1} floor((ai + b) / m) (mod 2^64)
unsigned long long floor_sum_unsigned(unsigned long long n,
                                      unsigned long long m,
                                      unsigned long long a,
                                      unsigned long long b) {
    unsigned long long ans = 0;
    while (true) {
        if (a >= m) {
            ans += n * (n - 1) / 2 * (a / m);
            a %= m;
        }
        if (b >= m) {
            ans += n * (b / m);
            b %= m;
        }

        unsigned long long y_max = a * n + b;
        if (y_max < m) break;
        // y_max < m * (n + 1)
        // floor(y_max / m) <= n
        n = (unsigned long long)(y_max / m);
        b = (unsigned long long)(y_max % m);
        std::swap(m, a);
    }
    return ans;
}

}  // namespace internal

}  // namespace atcoder


#include <cassert>
#include <numeric>
#include <type_traits>

namespace atcoder {

namespace internal {

#ifndef _MSC_VER
template <class T>
using is_signed_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value ||
                                  std::is_same<T, __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int128 =
    typename std::conditional<std::is_same<T, __uint128_t>::value ||
                                  std::is_same<T, unsigned __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using make_unsigned_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value,
                              __uint128_t,
                              unsigned __int128>;

template <class T>
using is_integral = typename std::conditional<std::is_integral<T>::value ||
                                                  is_signed_int128<T>::value ||
                                                  is_unsigned_int128<T>::value,
                                              std::true_type,
                                              std::false_type>::type;

template <class T>
using is_signed_int = typename std::conditional<(is_integral<T>::value &&
                                                 std::is_signed<T>::value) ||
                                                    is_signed_int128<T>::value,
                                                std::true_type,
                                                std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<(is_integral<T>::value &&
                               std::is_unsigned<T>::value) ||
                                  is_unsigned_int128<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<
    is_signed_int128<T>::value,
    make_unsigned_int128<T>,
    typename std::conditional<std::is_signed<T>::value,
                              std::make_unsigned<T>,
                              std::common_type<T>>::type>::type;

#else

template <class T> using is_integral = typename std::is_integral<T>;

template <class T>
using is_signed_int =
    typename std::conditional<is_integral<T>::value && std::is_signed<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<is_integral<T>::value &&
                                  std::is_unsigned<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<is_signed_int<T>::value,
                                              std::make_unsigned<T>,
                                              std::common_type<T>>::type;

#endif

template <class T>
using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;

template <class T>
using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;

template <class T> using to_unsigned_t = typename to_unsigned<T>::type;

}  // namespace internal

}  // namespace atcoder


namespace atcoder {

namespace internal {

struct modint_base {};
struct static_modint_base : modint_base {};

template <class T> using is_modint = std::is_base_of<modint_base, T>;
template <class T> using is_modint_t = std::enable_if_t<is_modint<T>::value>;

}  // namespace internal

template <int m, std::enable_if_t<(1 <= m)>* = nullptr>
struct static_modint : internal::static_modint_base {
    using mint = static_modint;

  public:
    static constexpr int mod() { return m; }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    static_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    static_modint(T v) {
        long long x = (long long)(v % (long long)(umod()));
        if (x < 0) x += umod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    static_modint(T v) {
        _v = (unsigned int)(v % umod());
    }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v -= rhs._v;
        if (_v >= umod()) _v += umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        unsigned long long z = _v;
        z *= rhs._v;
        _v = (unsigned int)(z % umod());
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        if (prime) {
            assert(_v);
            return pow(umod() - 2);
        } else {
            auto eg = internal::inv_gcd(_v, m);
            assert(eg.first == 1);
            return eg.second;
        }
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static constexpr unsigned int umod() { return m; }
    static constexpr bool prime = internal::is_prime<m>;
};

template <int id> struct dynamic_modint : internal::modint_base {
    using mint = dynamic_modint;

  public:
    static int mod() { return (int)(bt.umod()); }
    static void set_mod(int m) {
        assert(1 <= m);
        bt = internal::barrett(m);
    }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    dynamic_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        long long x = (long long)(v % (long long)(mod()));
        if (x < 0) x += mod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        _v = (unsigned int)(v % mod());
    }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v += mod() - rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        _v = bt.mul(_v, rhs._v);
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        auto eg = internal::inv_gcd(_v, mod());
        assert(eg.first == 1);
        return eg.second;
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static internal::barrett bt;
    static unsigned int umod() { return bt.umod(); }
};
template <int id> internal::barrett dynamic_modint<id>::bt(998244353);

using modint998244353 = static_modint<998244353>;
using modint1000000007 = static_modint<1000000007>;
using modint = dynamic_modint<-1>;

namespace internal {

template <class T>
using is_static_modint = std::is_base_of<internal::static_modint_base, T>;

template <class T>
using is_static_modint_t = std::enable_if_t<is_static_modint<T>::value>;

template <class> struct is_dynamic_modint : public std::false_type {};
template <int id>
struct is_dynamic_modint<dynamic_modint<id>> : public std::true_type {};

template <class T>
using is_dynamic_modint_t = std::enable_if_t<is_dynamic_modint<T>::value>;

}  // namespace internal

}  // namespace atcoder


namespace atcoder {

namespace internal {

template <class mint,
          int g = internal::primitive_root<mint::mod()>,
          internal::is_static_modint_t<mint>* = nullptr>
struct fft_info {
    static constexpr int rank2 = countr_zero_constexpr(mint::mod() - 1);
    std::array<mint, rank2 + 1> root;   // root[i]^(2^i) == 1
    std::array<mint, rank2 + 1> iroot;  // root[i] * iroot[i] == 1

    std::array<mint, std::max(0, rank2 - 2 + 1)> rate2;
    std::array<mint, std::max(0, rank2 - 2 + 1)> irate2;

    std::array<mint, std::max(0, rank2 - 3 + 1)> rate3;
    std::array<mint, std::max(0, rank2 - 3 + 1)> irate3;

    fft_info() {
        root[rank2] = mint(g).pow((mint::mod() - 1) >> rank2);
        iroot[rank2] = root[rank2].inv();
        for (int i = rank2 - 1; i >= 0; i--) {
            root[i] = root[i + 1] * root[i + 1];
            iroot[i] = iroot[i + 1] * iroot[i + 1];
        }

        {
            mint prod = 1, iprod = 1;
            for (int i = 0; i <= rank2 - 2; i++) {
                rate2[i] = root[i + 2] * prod;
                irate2[i] = iroot[i + 2] * iprod;
                prod *= iroot[i + 2];
                iprod *= root[i + 2];
            }
        }
        {
            mint prod = 1, iprod = 1;
            for (int i = 0; i <= rank2 - 3; i++) {
                rate3[i] = root[i + 3] * prod;
                irate3[i] = iroot[i + 3] * iprod;
                prod *= iroot[i + 3];
                iprod *= root[i + 3];
            }
        }
    }
};

template <class mint, internal::is_static_modint_t<mint>* = nullptr>
void butterfly(std::vector<mint>& a) {
    int n = int(a.size());
    int h = internal::countr_zero((unsigned int)n);

    static const fft_info<mint> info;

    int len = 0;  // a[i, i+(n>>len), i+2*(n>>len), ..] is transformed
    while (len < h) {
        if (h - len == 1) {
            int p = 1 << (h - len - 1);
            mint rot = 1;
            for (int s = 0; s < (1 << len); s++) {
                int offset = s << (h - len);
                for (int i = 0; i < p; i++) {
                    auto l = a[i + offset];
                    auto r = a[i + offset + p] * rot;
                    a[i + offset] = l + r;
                    a[i + offset + p] = l - r;
                }
                if (s + 1 != (1 << len))
                    rot *= info.rate2[countr_zero(~(unsigned int)(s))];
            }
            len++;
        } else {
            // 4-base
            int p = 1 << (h - len - 2);
            mint rot = 1, imag = info.root[2];
            for (int s = 0; s < (1 << len); s++) {
                mint rot2 = rot * rot;
                mint rot3 = rot2 * rot;
                int offset = s << (h - len);
                for (int i = 0; i < p; i++) {
                    auto mod2 = 1ULL * mint::mod() * mint::mod();
                    auto a0 = 1ULL * a[i + offset].val();
                    auto a1 = 1ULL * a[i + offset + p].val() * rot.val();
                    auto a2 = 1ULL * a[i + offset + 2 * p].val() * rot2.val();
                    auto a3 = 1ULL * a[i + offset + 3 * p].val() * rot3.val();
                    auto a1na3imag =
                        1ULL * mint(a1 + mod2 - a3).val() * imag.val();
                    auto na2 = mod2 - a2;
                    a[i + offset] = a0 + a2 + a1 + a3;
                    a[i + offset + 1 * p] = a0 + a2 + (2 * mod2 - (a1 + a3));
                    a[i + offset + 2 * p] = a0 + na2 + a1na3imag;
                    a[i + offset + 3 * p] = a0 + na2 + (mod2 - a1na3imag);
                }
                if (s + 1 != (1 << len))
                    rot *= info.rate3[countr_zero(~(unsigned int)(s))];
            }
            len += 2;
        }
    }
}

template <class mint, internal::is_static_modint_t<mint>* = nullptr>
void butterfly_inv(std::vector<mint>& a) {
    int n = int(a.size());
    int h = internal::countr_zero((unsigned int)n);

    static const fft_info<mint> info;

    int len = h;  // a[i, i+(n>>len), i+2*(n>>len), ..] is transformed
    while (len) {
        if (len == 1) {
            int p = 1 << (h - len);
            mint irot = 1;
            for (int s = 0; s < (1 << (len - 1)); s++) {
                int offset = s << (h - len + 1);
                for (int i = 0; i < p; i++) {
                    auto l = a[i + offset];
                    auto r = a[i + offset + p];
                    a[i + offset] = l + r;
                    a[i + offset + p] =
                        (unsigned long long)(mint::mod() + l.val() - r.val()) *
                        irot.val();
                    ;
                }
                if (s + 1 != (1 << (len - 1)))
                    irot *= info.irate2[countr_zero(~(unsigned int)(s))];
            }
            len--;
        } else {
            // 4-base
            int p = 1 << (h - len);
            mint irot = 1, iimag = info.iroot[2];
            for (int s = 0; s < (1 << (len - 2)); s++) {
                mint irot2 = irot * irot;
                mint irot3 = irot2 * irot;
                int offset = s << (h - len + 2);
                for (int i = 0; i < p; i++) {
                    auto a0 = 1ULL * a[i + offset + 0 * p].val();
                    auto a1 = 1ULL * a[i + offset + 1 * p].val();
                    auto a2 = 1ULL * a[i + offset + 2 * p].val();
                    auto a3 = 1ULL * a[i + offset + 3 * p].val();

                    auto a2na3iimag =
                        1ULL *
                        mint((mint::mod() + a2 - a3) * iimag.val()).val();

                    a[i + offset] = a0 + a1 + a2 + a3;
                    a[i + offset + 1 * p] =
                        (a0 + (mint::mod() - a1) + a2na3iimag) * irot.val();
                    a[i + offset + 2 * p] =
                        (a0 + a1 + (mint::mod() - a2) + (mint::mod() - a3)) *
                        irot2.val();
                    a[i + offset + 3 * p] =
                        (a0 + (mint::mod() - a1) + (mint::mod() - a2na3iimag)) *
                        irot3.val();
                }
                if (s + 1 != (1 << (len - 2)))
                    irot *= info.irate3[countr_zero(~(unsigned int)(s))];
            }
            len -= 2;
        }
    }
}

template <class mint, internal::is_static_modint_t<mint>* = nullptr>
std::vector<mint> convolution_naive(const std::vector<mint>& a,
                                    const std::vector<mint>& b) {
    int n = int(a.size()), m = int(b.size());
    std::vector<mint> ans(n + m - 1);
    if (n < m) {
        for (int j = 0; j < m; j++) {
            for (int i = 0; i < n; i++) {
                ans[i + j] += a[i] * b[j];
            }
        }
    } else {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                ans[i + j] += a[i] * b[j];
            }
        }
    }
    return ans;
}

template <class mint, internal::is_static_modint_t<mint>* = nullptr>
std::vector<mint> convolution_fft(std::vector<mint> a, std::vector<mint> b) {
    int n = int(a.size()), m = int(b.size());
    int z = (int)internal::bit_ceil((unsigned int)(n + m - 1));
    a.resize(z);
    internal::butterfly(a);
    b.resize(z);
    internal::butterfly(b);
    for (int i = 0; i < z; i++) {
        a[i] *= b[i];
    }
    internal::butterfly_inv(a);
    a.resize(n + m - 1);
    mint iz = mint(z).inv();
    for (int i = 0; i < n + m - 1; i++) a[i] *= iz;
    return a;
}

}  // namespace internal

template <class mint, internal::is_static_modint_t<mint>* = nullptr>
std::vector<mint> convolution(std::vector<mint>&& a, std::vector<mint>&& b) {
    int n = int(a.size()), m = int(b.size());
    if (!n || !m) return {};

    int z = (int)internal::bit_ceil((unsigned int)(n + m - 1));
    assert((mint::mod() - 1) % z == 0);

    if (std::min(n, m) <= 60) return convolution_naive(a, b);
    return internal::convolution_fft(a, b);
}
template <class mint, internal::is_static_modint_t<mint>* = nullptr>
std::vector<mint> convolution(const std::vector<mint>& a,
                              const std::vector<mint>& b) {
    int n = int(a.size()), m = int(b.size());
    if (!n || !m) return {};

    int z = (int)internal::bit_ceil((unsigned int)(n + m - 1));
    assert((mint::mod() - 1) % z == 0);

    if (std::min(n, m) <= 60) return convolution_naive(a, b);
    return internal::convolution_fft(a, b);
}

template <unsigned int mod = 998244353,
          class T,
          std::enable_if_t<internal::is_integral<T>::value>* = nullptr>
std::vector<T> convolution(const std::vector<T>& a, const std::vector<T>& b) {
    int n = int(a.size()), m = int(b.size());
    if (!n || !m) return {};

    using mint = static_modint<mod>;

    int z = (int)internal::bit_ceil((unsigned int)(n + m - 1));
    assert((mint::mod() - 1) % z == 0);

    std::vector<mint> a2(n), b2(m);
    for (int i = 0; i < n; i++) {
        a2[i] = mint(a[i]);
    }
    for (int i = 0; i < m; i++) {
        b2[i] = mint(b[i]);
    }
    auto c2 = convolution(std::move(a2), std::move(b2));
    std::vector<T> c(n + m - 1);
    for (int i = 0; i < n + m - 1; i++) {
        c[i] = c2[i].val();
    }
    return c;
}

std::vector<long long> convolution_ll(const std::vector<long long>& a,
                                      const std::vector<long long>& b) {
    int n = int(a.size()), m = int(b.size());
    if (!n || !m) return {};

    static constexpr unsigned long long MOD1 = 754974721;  // 2^24
    static constexpr unsigned long long MOD2 = 167772161;  // 2^25
    static constexpr unsigned long long MOD3 = 469762049;  // 2^26
    static constexpr unsigned long long M2M3 = MOD2 * MOD3;
    static constexpr unsigned long long M1M3 = MOD1 * MOD3;
    static constexpr unsigned long long M1M2 = MOD1 * MOD2;
    static constexpr unsigned long long M1M2M3 = MOD1 * MOD2 * MOD3;

    static constexpr unsigned long long i1 =
        internal::inv_gcd(MOD2 * MOD3, MOD1).second;
    static constexpr unsigned long long i2 =
        internal::inv_gcd(MOD1 * MOD3, MOD2).second;
    static constexpr unsigned long long i3 =
        internal::inv_gcd(MOD1 * MOD2, MOD3).second;
        
    static constexpr int MAX_AB_BIT = 24;
    static_assert(MOD1 % (1ull << MAX_AB_BIT) == 1, "MOD1 isn't enough to support an array length of 2^24.");
    static_assert(MOD2 % (1ull << MAX_AB_BIT) == 1, "MOD2 isn't enough to support an array length of 2^24.");
    static_assert(MOD3 % (1ull << MAX_AB_BIT) == 1, "MOD3 isn't enough to support an array length of 2^24.");
    assert(n + m - 1 <= (1 << MAX_AB_BIT));

    auto c1 = convolution<MOD1>(a, b);
    auto c2 = convolution<MOD2>(a, b);
    auto c3 = convolution<MOD3>(a, b);

    std::vector<long long> c(n + m - 1);
    for (int i = 0; i < n + m - 1; i++) {
        unsigned long long x = 0;
        x += (c1[i] * i1) % MOD1 * M2M3;
        x += (c2[i] * i2) % MOD2 * M1M3;
        x += (c3[i] * i3) % MOD3 * M1M2;
        // B = 2^63, -B <= x, r(real value) < B
        // (x, x - M, x - 2M, or x - 3M) = r (mod 2B)
        // r = c1[i] (mod MOD1)
        // focus on MOD1
        // r = x, x - M', x - 2M', x - 3M' (M' = M % 2^64) (mod 2B)
        // r = x,
        //     x - M' + (0 or 2B),
        //     x - 2M' + (0, 2B or 4B),
        //     x - 3M' + (0, 2B, 4B or 6B) (without mod!)
        // (r - x) = 0, (0)
        //           - M' + (0 or 2B), (1)
        //           -2M' + (0 or 2B or 4B), (2)
        //           -3M' + (0 or 2B or 4B or 6B) (3) (mod MOD1)
        // we checked that
        //   ((1) mod MOD1) mod 5 = 2
        //   ((2) mod MOD1) mod 5 = 3
        //   ((3) mod MOD1) mod 5 = 4
        long long diff =
            c1[i] - internal::safe_mod((long long)(x), (long long)(MOD1));
        if (diff < 0) diff += MOD1;
        static constexpr unsigned long long offset[5] = {
            0, 0, M1M2M3, 2 * M1M2M3, 3 * M1M2M3};
        x -= offset[diff % 5];
        c[i] = x;
    }

    return c;
}

}  // namespace atcoder


#include <algorithm>
#include <cassert>
#include <vector>

namespace atcoder {

// Implement (union by size) + (path compression)
// Reference:
// Zvi Galil and Giuseppe F. Italiano,
// Data structures and algorithms for disjoint set union problems
struct dsu {
  public:
    dsu() : _n(0) {}
    explicit dsu(int n) : _n(n), parent_or_size(n, -1) {}

    int merge(int a, int b) {
        assert(0 <= a && a < _n);
        assert(0 <= b && b < _n);
        int x = leader(a), y = leader(b);
        if (x == y) return x;
        if (-parent_or_size[x] < -parent_or_size[y]) std::swap(x, y);
        parent_or_size[x] += parent_or_size[y];
        parent_or_size[y] = x;
        return x;
    }

    bool same(int a, int b) {
        assert(0 <= a && a < _n);
        assert(0 <= b && b < _n);
        return leader(a) == leader(b);
    }

    int leader(int a) {
        assert(0 <= a && a < _n);
        if (parent_or_size[a] < 0) return a;
        return parent_or_size[a] = leader(parent_or_size[a]);
    }

    int size(int a) {
        assert(0 <= a && a < _n);
        return -parent_or_size[leader(a)];
    }

    std::vector<std::vector<int>> groups() {
        std::vector<int> leader_buf(_n), group_size(_n);
        for (int i = 0; i < _n; i++) {
            leader_buf[i] = leader(i);
            group_size[leader_buf[i]]++;
        }
        std::vector<std::vector<int>> result(_n);
        for (int i = 0; i < _n; i++) {
            result[i].reserve(group_size[i]);
        }
        for (int i = 0; i < _n; i++) {
            result[leader_buf[i]].push_back(i);
        }
        result.erase(
            std::remove_if(result.begin(), result.end(),
                           [&](const std::vector<int>& v) { return v.empty(); }),
            result.end());
        return result;
    }

  private:
    int _n;
    // root node: -1 * component size
    // otherwise: parent
    std::vector<int> parent_or_size;
};

}  // namespace atcoder


#include <cassert>
#include <vector>


namespace atcoder {

// Reference: https://en.wikipedia.org/wiki/Fenwick_tree
template <class T> struct fenwick_tree {
    using U = internal::to_unsigned_t<T>;

  public:
    fenwick_tree() : _n(0) {}
    explicit fenwick_tree(int n) : _n(n), data(n) {}

    void add(int p, T x) {
        assert(0 <= p && p < _n);
        p++;
        while (p <= _n) {
            data[p - 1] += U(x);
            p += p & -p;
        }
    }

    T sum(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        return sum(r) - sum(l);
    }

  private:
    int _n;
    std::vector<U> data;

    U sum(int r) {
        U s = 0;
        while (r > 0) {
            s += data[r - 1];
            r -= r & -r;
        }
        return s;
    }
};

}  // namespace atcoder


#include <algorithm>
#include <cassert>
#include <functional>
#include <vector>


namespace atcoder {

#if __cplusplus >= 201703L

template <class S,
          auto op,
          auto e,
          class F,
          auto mapping,
          auto composition,
          auto id>
struct lazy_segtree {
    static_assert(std::is_convertible_v<decltype(op), std::function<S(S, S)>>,
                  "op must work as S(S, S)");
    static_assert(std::is_convertible_v<decltype(e), std::function<S()>>,
                  "e must work as S()");
    static_assert(
        std::is_convertible_v<decltype(mapping), std::function<S(F, S)>>,
        "mapping must work as F(F, S)");
    static_assert(
        std::is_convertible_v<decltype(composition), std::function<F(F, F)>>,
        "compostiion must work as F(F, F)");
    static_assert(std::is_convertible_v<decltype(id), std::function<F()>>,
                  "id must work as F()");

#else

template <class S,
          S (*op)(S, S),
          S (*e)(),
          class F,
          S (*mapping)(F, S),
          F (*composition)(F, F),
          F (*id)()>
struct lazy_segtree {

#endif

  public:
    lazy_segtree() : lazy_segtree(0) {}
    explicit lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
    explicit lazy_segtree(const std::vector<S>& v) : _n(int(v.size())) {
        size = (int)internal::bit_ceil((unsigned int)(_n));
        log = internal::countr_zero((unsigned int)size);
        d = std::vector<S>(2 * size, e());
        lz = std::vector<F>(size, id());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }

    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return e();

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        S sml = e(), smr = e();
        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }

        return op(sml, smr);
    }

    S all_prod() { return d[1]; }

    void apply(int p, F f) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = mapping(f, d[p]);
        for (int i = 1; i <= log; i++) update(p >> i);
    }
    void apply(int l, int r, F f) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return;

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        {
            int l2 = l, r2 = r;
            while (l < r) {
                if (l & 1) all_apply(l++, f);
                if (r & 1) all_apply(--r, f);
                l >>= 1;
                r >>= 1;
            }
            l = l2;
            r = r2;
        }

        for (int i = 1; i <= log; i++) {
            if (((l >> i) << i) != l) update(l >> i);
            if (((r >> i) << i) != r) update((r - 1) >> i);
        }
    }

    template <bool (*g)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return g(x); });
    }
    template <class G> int max_right(int l, G g) {
        assert(0 <= l && l <= _n);
        assert(g(e()));
        if (l == _n) return _n;
        l += size;
        for (int i = log; i >= 1; i--) push(l >> i);
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!g(op(sm, d[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*g)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return g(x); });
    }
    template <class G> int min_left(int r, G g) {
        assert(0 <= r && r <= _n);
        assert(g(e()));
        if (r == 0) return 0;
        r += size;
        for (int i = log; i >= 1; i--) push((r - 1) >> i);
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!g(op(d[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    std::vector<S> d;
    std::vector<F> lz;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    void all_apply(int k, F f) {
        d[k] = mapping(f, d[k]);
        if (k < size) lz[k] = composition(f, lz[k]);
    }
    void push(int k) {
        all_apply(2 * k, lz[k]);
        all_apply(2 * k + 1, lz[k]);
        lz[k] = id();
    }
};

}  // namespace atcoder


#include <algorithm>
#include <cassert>
#include <tuple>
#include <vector>


namespace atcoder {

long long pow_mod(long long x, long long n, int m) {
    assert(0 <= n && 1 <= m);
    if (m == 1) return 0;
    internal::barrett bt((unsigned int)(m));
    unsigned int r = 1, y = (unsigned int)(internal::safe_mod(x, m));
    while (n) {
        if (n & 1) r = bt.mul(r, y);
        y = bt.mul(y, y);
        n >>= 1;
    }
    return r;
}

long long inv_mod(long long x, long long m) {
    assert(1 <= m);
    auto z = internal::inv_gcd(x, m);
    assert(z.first == 1);
    return z.second;
}

// (rem, mod)
std::pair<long long, long long> crt(const std::vector<long long>& r,
                                    const std::vector<long long>& m) {
    assert(r.size() == m.size());
    int n = int(r.size());
    // Contracts: 0 <= r0 < m0
    long long r0 = 0, m0 = 1;
    for (int i = 0; i < n; i++) {
        assert(1 <= m[i]);
        long long r1 = internal::safe_mod(r[i], m[i]), m1 = m[i];
        if (m0 < m1) {
            std::swap(r0, r1);
            std::swap(m0, m1);
        }
        if (m0 % m1 == 0) {
            if (r0 % m1 != r1) return {0, 0};
            continue;
        }
        // assume: m0 > m1, lcm(m0, m1) >= 2 * max(m0, m1)

        // (r0, m0), (r1, m1) -> (r2, m2 = lcm(m0, m1));
        // r2 % m0 = r0
        // r2 % m1 = r1
        // -> (r0 + x*m0) % m1 = r1
        // -> x*u0*g = r1-r0 (mod u1*g) (u0*g = m0, u1*g = m1)
        // -> x = (r1 - r0) / g * inv(u0) (mod u1)

        // im = inv(u0) (mod u1) (0 <= im < u1)
        long long g, im;
        std::tie(g, im) = internal::inv_gcd(m0, m1);

        long long u1 = (m1 / g);
        // |r1 - r0| < (m0 + m1) <= lcm(m0, m1)
        if ((r1 - r0) % g) return {0, 0};

        // u1 * u1 <= m1 * m1 / g / g <= m0 * m1 / g = lcm(m0, m1)
        long long x = (r1 - r0) / g % u1 * im % u1;

        // |r0| + |m0 * x|
        // < m0 + m0 * (u1 - 1)
        // = m0 + m0 * m1 / g - m0
        // = lcm(m0, m1)
        r0 += x * m0;
        m0 *= u1;  // -> lcm(m0, m1)
        if (r0 < 0) r0 += m0;
    }
    return {r0, m0};
}

long long floor_sum(long long n, long long m, long long a, long long b) {
    assert(0 <= n && n < (1LL << 32));
    assert(1 <= m && m < (1LL << 32));
    unsigned long long ans = 0;
    if (a < 0) {
        unsigned long long a2 = internal::safe_mod(a, m);
        ans -= 1ULL * n * (n - 1) / 2 * ((a2 - a) / m);
        a = a2;
    }
    if (b < 0) {
        unsigned long long b2 = internal::safe_mod(b, m);
        ans -= 1ULL * n * ((b2 - b) / m);
        b = b2;
    }
    return ans + internal::floor_sum_unsigned(n, m, a, b);
}

}  // namespace atcoder


#include <algorithm>
#include <cassert>
#include <limits>
#include <queue>
#include <vector>


#include <vector>

namespace atcoder {

namespace internal {

template <class T> struct simple_queue {
    std::vector<T> payload;
    int pos = 0;
    void reserve(int n) { payload.reserve(n); }
    int size() const { return int(payload.size()) - pos; }
    bool empty() const { return pos == int(payload.size()); }
    void push(const T& t) { payload.push_back(t); }
    T& front() { return payload[pos]; }
    void clear() {
        payload.clear();
        pos = 0;
    }
    void pop() { pos++; }
};

}  // namespace internal

}  // namespace atcoder


namespace atcoder {

template <class Cap> struct mf_graph {
  public:
    mf_graph() : _n(0) {}
    explicit mf_graph(int n) : _n(n), g(n) {}

    int add_edge(int from, int to, Cap cap) {
        assert(0 <= from && from < _n);
        assert(0 <= to && to < _n);
        assert(0 <= cap);
        int m = int(pos.size());
        pos.push_back({from, int(g[from].size())});
        int from_id = int(g[from].size());
        int to_id = int(g[to].size());
        if (from == to) to_id++;
        g[from].push_back(_edge{to, to_id, cap});
        g[to].push_back(_edge{from, from_id, 0});
        return m;
    }

    struct edge {
        int from, to;
        Cap cap, flow;
    };

    edge get_edge(int i) {
        int m = int(pos.size());
        assert(0 <= i && i < m);
        auto _e = g[pos[i].first][pos[i].second];
        auto _re = g[_e.to][_e.rev];
        return edge{pos[i].first, _e.to, _e.cap + _re.cap, _re.cap};
    }
    std::vector<edge> edges() {
        int m = int(pos.size());
        std::vector<edge> result;
        for (int i = 0; i < m; i++) {
            result.push_back(get_edge(i));
        }
        return result;
    }
    void change_edge(int i, Cap new_cap, Cap new_flow) {
        int m = int(pos.size());
        assert(0 <= i && i < m);
        assert(0 <= new_flow && new_flow <= new_cap);
        auto& _e = g[pos[i].first][pos[i].second];
        auto& _re = g[_e.to][_e.rev];
        _e.cap = new_cap - new_flow;
        _re.cap = new_flow;
    }

    Cap flow(int s, int t) {
        return flow(s, t, std::numeric_limits<Cap>::max());
    }
    Cap flow(int s, int t, Cap flow_limit) {
        assert(0 <= s && s < _n);
        assert(0 <= t && t < _n);
        assert(s != t);

        std::vector<int> level(_n), iter(_n);
        internal::simple_queue<int> que;

        auto bfs = [&]() {
            std::fill(level.begin(), level.end(), -1);
            level[s] = 0;
            que.clear();
            que.push(s);
            while (!que.empty()) {
                int v = que.front();
                que.pop();
                for (auto e : g[v]) {
                    if (e.cap == 0 || level[e.to] >= 0) continue;
                    level[e.to] = level[v] + 1;
                    if (e.to == t) return;
                    que.push(e.to);
                }
            }
        };
        auto dfs = [&](auto self, int v, Cap up) {
            if (v == s) return up;
            Cap res = 0;
            int level_v = level[v];
            for (int& i = iter[v]; i < int(g[v].size()); i++) {
                _edge& e = g[v][i];
                if (level_v <= level[e.to] || g[e.to][e.rev].cap == 0) continue;
                Cap d =
                    self(self, e.to, std::min(up - res, g[e.to][e.rev].cap));
                if (d <= 0) continue;
                g[v][i].cap += d;
                g[e.to][e.rev].cap -= d;
                res += d;
                if (res == up) return res;
            }
            level[v] = _n;
            return res;
        };

        Cap flow = 0;
        while (flow < flow_limit) {
            bfs();
            if (level[t] == -1) break;
            std::fill(iter.begin(), iter.end(), 0);
            Cap f = dfs(dfs, t, flow_limit - flow);
            if (!f) break;
            flow += f;
        }
        return flow;
    }

    std::vector<bool> min_cut(int s) {
        std::vector<bool> visited(_n);
        internal::simple_queue<int> que;
        que.push(s);
        while (!que.empty()) {
            int p = que.front();
            que.pop();
            visited[p] = true;
            for (auto e : g[p]) {
                if (e.cap && !visited[e.to]) {
                    visited[e.to] = true;
                    que.push(e.to);
                }
            }
        }
        return visited;
    }

  private:
    int _n;
    struct _edge {
        int to, rev;
        Cap cap;
    };
    std::vector<std::pair<int, int>> pos;
    std::vector<std::vector<_edge>> g;
};

}  // namespace atcoder


#include <algorithm>
#include <cassert>
#include <limits>
#include <queue>
#include <vector>


#include <algorithm>
#include <utility>
#include <vector>

namespace atcoder {
namespace internal {

template <class E> struct csr {
    std::vector<int> start;
    std::vector<E> elist;
    explicit csr(int n, const std::vector<std::pair<int, E>>& edges)
        : start(n + 1), elist(edges.size()) {
        for (auto e : edges) {
            start[e.first + 1]++;
        }
        for (int i = 1; i <= n; i++) {
            start[i] += start[i - 1];
        }
        auto counter = start;
        for (auto e : edges) {
            elist[counter[e.first]++] = e.second;
        }
    }
};

}  // namespace internal

}  // namespace atcoder


namespace atcoder {

template <class Cap, class Cost> struct mcf_graph {
  public:
    mcf_graph() {}
    explicit mcf_graph(int n) : _n(n) {}

    int add_edge(int from, int to, Cap cap, Cost cost) {
        assert(0 <= from && from < _n);
        assert(0 <= to && to < _n);
        assert(0 <= cap);
        assert(0 <= cost);
        int m = int(_edges.size());
        _edges.push_back({from, to, cap, 0, cost});
        return m;
    }

    struct edge {
        int from, to;
        Cap cap, flow;
        Cost cost;
    };

    edge get_edge(int i) {
        int m = int(_edges.size());
        assert(0 <= i && i < m);
        return _edges[i];
    }
    std::vector<edge> edges() { return _edges; }

    std::pair<Cap, Cost> flow(int s, int t) {
        return flow(s, t, std::numeric_limits<Cap>::max());
    }
    std::pair<Cap, Cost> flow(int s, int t, Cap flow_limit) {
        return slope(s, t, flow_limit).back();
    }
    std::vector<std::pair<Cap, Cost>> slope(int s, int t) {
        return slope(s, t, std::numeric_limits<Cap>::max());
    }
    std::vector<std::pair<Cap, Cost>> slope(int s, int t, Cap flow_limit) {
        assert(0 <= s && s < _n);
        assert(0 <= t && t < _n);
        assert(s != t);

        int m = int(_edges.size());
        std::vector<int> edge_idx(m);

        auto g = [&]() {
            std::vector<int> degree(_n), redge_idx(m);
            std::vector<std::pair<int, _edge>> elist;
            elist.reserve(2 * m);
            for (int i = 0; i < m; i++) {
                auto e = _edges[i];
                edge_idx[i] = degree[e.from]++;
                redge_idx[i] = degree[e.to]++;
                elist.push_back({e.from, {e.to, -1, e.cap - e.flow, e.cost}});
                elist.push_back({e.to, {e.from, -1, e.flow, -e.cost}});
            }
            auto _g = internal::csr<_edge>(_n, elist);
            for (int i = 0; i < m; i++) {
                auto e = _edges[i];
                edge_idx[i] += _g.start[e.from];
                redge_idx[i] += _g.start[e.to];
                _g.elist[edge_idx[i]].rev = redge_idx[i];
                _g.elist[redge_idx[i]].rev = edge_idx[i];
            }
            return _g;
        }();

        auto result = slope(g, s, t, flow_limit);

        for (int i = 0; i < m; i++) {
            auto e = g.elist[edge_idx[i]];
            _edges[i].flow = _edges[i].cap - e.cap;
        }

        return result;
    }

  private:
    int _n;
    std::vector<edge> _edges;

    // inside edge
    struct _edge {
        int to, rev;
        Cap cap;
        Cost cost;
    };

    std::vector<std::pair<Cap, Cost>> slope(internal::csr<_edge>& g,
                                            int s,
                                            int t,
                                            Cap flow_limit) {
        // variants (C = maxcost):
        // -(n-1)C <= dual[s] <= dual[i] <= dual[t] = 0
        // reduced cost (= e.cost + dual[e.from] - dual[e.to]) >= 0 for all edge

        // dual_dist[i] = (dual[i], dist[i])
        std::vector<std::pair<Cost, Cost>> dual_dist(_n);
        std::vector<int> prev_e(_n);
        std::vector<bool> vis(_n);
        struct Q {
            Cost key;
            int to;
            bool operator<(Q r) const { return key > r.key; }
        };
        std::vector<int> que_min;
        std::vector<Q> que;
        auto dual_ref = [&]() {
            for (int i = 0; i < _n; i++) {
                dual_dist[i].second = std::numeric_limits<Cost>::max();
            }
            std::fill(vis.begin(), vis.end(), false);
            que_min.clear();
            que.clear();

            // que[0..heap_r) was heapified
            size_t heap_r = 0;

            dual_dist[s].second = 0;
            que_min.push_back(s);
            while (!que_min.empty() || !que.empty()) {
                int v;
                if (!que_min.empty()) {
                    v = que_min.back();
                    que_min.pop_back();
                } else {
                    while (heap_r < que.size()) {
                        heap_r++;
                        std::push_heap(que.begin(), que.begin() + heap_r);
                    }
                    v = que.front().to;
                    std::pop_heap(que.begin(), que.end());
                    que.pop_back();
                    heap_r--;
                }
                if (vis[v]) continue;
                vis[v] = true;
                if (v == t) break;
                // dist[v] = shortest(s, v) + dual[s] - dual[v]
                // dist[v] >= 0 (all reduced cost are positive)
                // dist[v] <= (n-1)C
                Cost dual_v = dual_dist[v].first, dist_v = dual_dist[v].second;
                for (int i = g.start[v]; i < g.start[v + 1]; i++) {
                    auto e = g.elist[i];
                    if (!e.cap) continue;
                    // |-dual[e.to] + dual[v]| <= (n-1)C
                    // cost <= C - -(n-1)C + 0 = nC
                    Cost cost = e.cost - dual_dist[e.to].first + dual_v;
                    if (dual_dist[e.to].second - dist_v > cost) {
                        Cost dist_to = dist_v + cost;
                        dual_dist[e.to].second = dist_to;
                        prev_e[e.to] = e.rev;
                        if (dist_to == dist_v) {
                            que_min.push_back(e.to);
                        } else {
                            que.push_back(Q{dist_to, e.to});
                        }
                    }
                }
            }
            if (!vis[t]) {
                return false;
            }

            for (int v = 0; v < _n; v++) {
                if (!vis[v]) continue;
                // dual[v] = dual[v] - dist[t] + dist[v]
                //         = dual[v] - (shortest(s, t) + dual[s] - dual[t]) +
                //         (shortest(s, v) + dual[s] - dual[v]) = - shortest(s,
                //         t) + dual[t] + shortest(s, v) = shortest(s, v) -
                //         shortest(s, t) >= 0 - (n-1)C
                dual_dist[v].first -= dual_dist[t].second - dual_dist[v].second;
            }
            return true;
        };
        Cap flow = 0;
        Cost cost = 0, prev_cost_per_flow = -1;
        std::vector<std::pair<Cap, Cost>> result = {{Cap(0), Cost(0)}};
        while (flow < flow_limit) {
            if (!dual_ref()) break;
            Cap c = flow_limit - flow;
            for (int v = t; v != s; v = g.elist[prev_e[v]].to) {
                c = std::min(c, g.elist[g.elist[prev_e[v]].rev].cap);
            }
            for (int v = t; v != s; v = g.elist[prev_e[v]].to) {
                auto& e = g.elist[prev_e[v]];
                e.cap += c;
                g.elist[e.rev].cap -= c;
            }
            Cost d = -dual_dist[s].first;
            flow += c;
            cost += c * d;
            if (prev_cost_per_flow == d) {
                result.pop_back();
            }
            result.push_back({flow, cost});
            prev_cost_per_flow = d;
        }
        return result;
    }
};

}  // namespace atcoder


#include <algorithm>
#include <cassert>
#include <vector>


#include <algorithm>
#include <utility>
#include <vector>


namespace atcoder {
namespace internal {

// Reference:
// R. Tarjan,
// Depth-First Search and Linear Graph Algorithms
struct scc_graph {
  public:
    explicit scc_graph(int n) : _n(n) {}

    int num_vertices() { return _n; }

    void add_edge(int from, int to) { edges.push_back({from, {to}}); }

    // @return pair of (# of scc, scc id)
    std::pair<int, std::vector<int>> scc_ids() {
        auto g = csr<edge>(_n, edges);
        int now_ord = 0, group_num = 0;
        std::vector<int> visited, low(_n), ord(_n, -1), ids(_n);
        visited.reserve(_n);
        auto dfs = [&](auto self, int v) -> void {
            low[v] = ord[v] = now_ord++;
            visited.push_back(v);
            for (int i = g.start[v]; i < g.start[v + 1]; i++) {
                auto to = g.elist[i].to;
                if (ord[to] == -1) {
                    self(self, to);
                    low[v] = std::min(low[v], low[to]);
                } else {
                    low[v] = std::min(low[v], ord[to]);
                }
            }
            if (low[v] == ord[v]) {
                while (true) {
                    int u = visited.back();
                    visited.pop_back();
                    ord[u] = _n;
                    ids[u] = group_num;
                    if (u == v) break;
                }
                group_num++;
            }
        };
        for (int i = 0; i < _n; i++) {
            if (ord[i] == -1) dfs(dfs, i);
        }
        for (auto& x : ids) {
            x = group_num - 1 - x;
        }
        return {group_num, ids};
    }

    std::vector<std::vector<int>> scc() {
        auto ids = scc_ids();
        int group_num = ids.first;
        std::vector<int> counts(group_num);
        for (auto x : ids.second) counts[x]++;
        std::vector<std::vector<int>> groups(ids.first);
        for (int i = 0; i < group_num; i++) {
            groups[i].reserve(counts[i]);
        }
        for (int i = 0; i < _n; i++) {
            groups[ids.second[i]].push_back(i);
        }
        return groups;
    }

  private:
    int _n;
    struct edge {
        int to;
    };
    std::vector<std::pair<int, edge>> edges;
};

}  // namespace internal

}  // namespace atcoder


namespace atcoder {

struct scc_graph {
  public:
    scc_graph() : internal(0) {}
    explicit scc_graph(int n) : internal(n) {}

    void add_edge(int from, int to) {
        int n = internal.num_vertices();
        assert(0 <= from && from < n);
        assert(0 <= to && to < n);
        internal.add_edge(from, to);
    }

    std::vector<std::vector<int>> scc() { return internal.scc(); }

  private:
    internal::scc_graph internal;
};

}  // namespace atcoder


#include <algorithm>
#include <cassert>
#include <functional>
#include <vector>


namespace atcoder {

#if __cplusplus >= 201703L

template <class S, auto op, auto e> struct segtree {
    static_assert(std::is_convertible_v<decltype(op), std::function<S(S, S)>>,
                  "op must work as S(S, S)");
    static_assert(std::is_convertible_v<decltype(e), std::function<S()>>,
                  "e must work as S()");

#else

template <class S, S (*op)(S, S), S (*e)()> struct segtree {

#endif

  public:
    segtree() : segtree(0) {}
    explicit segtree(int n) : segtree(std::vector<S>(n, e())) {}
    explicit segtree(const std::vector<S>& v) : _n(int(v.size())) {
        size = (int)internal::bit_ceil((unsigned int)(_n));
        log = internal::countr_zero((unsigned int)size);
        d = std::vector<S>(2 * size, e());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) const {
        assert(0 <= p && p < _n);
        return d[p + size];
    }

    S prod(int l, int r) const {
        assert(0 <= l && l <= r && r <= _n);
        S sml = e(), smr = e();
        l += size;
        r += size;

        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }
        return op(sml, smr);
    }

    S all_prod() const { return d[1]; }

    template <bool (*f)(S)> int max_right(int l) const {
        return max_right(l, [](S x) { return f(x); });
    }
    template <class F> int max_right(int l, F f) const {
        assert(0 <= l && l <= _n);
        assert(f(e()));
        if (l == _n) return _n;
        l += size;
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!f(op(sm, d[l]))) {
                while (l < size) {
                    l = (2 * l);
                    if (f(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*f)(S)> int min_left(int r) const {
        return min_left(r, [](S x) { return f(x); });
    }
    template <class F> int min_left(int r, F f) const {
        assert(0 <= r && r <= _n);
        assert(f(e()));
        if (r == 0) return 0;
        r += size;
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!f(op(d[r], sm))) {
                while (r < size) {
                    r = (2 * r + 1);
                    if (f(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    std::vector<S> d;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};

}  // namespace atcoder


#include <algorithm>
#include <cassert>
#include <numeric>
#include <string>
#include <vector>

namespace atcoder {

namespace internal {

std::vector<int> sa_naive(const std::vector<int>& s) {
    int n = int(s.size());
    std::vector<int> sa(n);
    std::iota(sa.begin(), sa.end(), 0);
    std::sort(sa.begin(), sa.end(), [&](int l, int r) {
        if (l == r) return false;
        while (l < n && r < n) {
            if (s[l] != s[r]) return s[l] < s[r];
            l++;
            r++;
        }
        return l == n;
    });
    return sa;
}

std::vector<int> sa_doubling(const std::vector<int>& s) {
    int n = int(s.size());
    std::vector<int> sa(n), rnk = s, tmp(n);
    std::iota(sa.begin(), sa.end(), 0);
    for (int k = 1; k < n; k *= 2) {
        auto cmp = [&](int x, int y) {
            if (rnk[x] != rnk[y]) return rnk[x] < rnk[y];
            int rx = x + k < n ? rnk[x + k] : -1;
            int ry = y + k < n ? rnk[y + k] : -1;
            return rx < ry;
        };
        std::sort(sa.begin(), sa.end(), cmp);
        tmp[sa[0]] = 0;
        for (int i = 1; i < n; i++) {
            tmp[sa[i]] = tmp[sa[i - 1]] + (cmp(sa[i - 1], sa[i]) ? 1 : 0);
        }
        std::swap(tmp, rnk);
    }
    return sa;
}

// SA-IS, linear-time suffix array construction
// Reference:
// G. Nong, S. Zhang, and W. H. Chan,
// Two Efficient Algorithms for Linear Time Suffix Array Construction
template <int THRESHOLD_NAIVE = 10, int THRESHOLD_DOUBLING = 40>
std::vector<int> sa_is(const std::vector<int>& s, int upper) {
    int n = int(s.size());
    if (n == 0) return {};
    if (n == 1) return {0};
    if (n == 2) {
        if (s[0] < s[1]) {
            return {0, 1};
        } else {
            return {1, 0};
        }
    }
    if (n < THRESHOLD_NAIVE) {
        return sa_naive(s);
    }
    if (n < THRESHOLD_DOUBLING) {
        return sa_doubling(s);
    }

    std::vector<int> sa(n);
    std::vector<bool> ls(n);
    for (int i = n - 2; i >= 0; i--) {
        ls[i] = (s[i] == s[i + 1]) ? ls[i + 1] : (s[i] < s[i + 1]);
    }
    std::vector<int> sum_l(upper + 1), sum_s(upper + 1);
    for (int i = 0; i < n; i++) {
        if (!ls[i]) {
            sum_s[s[i]]++;
        } else {
            sum_l[s[i] + 1]++;
        }
    }
    for (int i = 0; i <= upper; i++) {
        sum_s[i] += sum_l[i];
        if (i < upper) sum_l[i + 1] += sum_s[i];
    }

    auto induce = [&](const std::vector<int>& lms) {
        std::fill(sa.begin(), sa.end(), -1);
        std::vector<int> buf(upper + 1);
        std::copy(sum_s.begin(), sum_s.end(), buf.begin());
        for (auto d : lms) {
            if (d == n) continue;
            sa[buf[s[d]]++] = d;
        }
        std::copy(sum_l.begin(), sum_l.end(), buf.begin());
        sa[buf[s[n - 1]]++] = n - 1;
        for (int i = 0; i < n; i++) {
            int v = sa[i];
            if (v >= 1 && !ls[v - 1]) {
                sa[buf[s[v - 1]]++] = v - 1;
            }
        }
        std::copy(sum_l.begin(), sum_l.end(), buf.begin());
        for (int i = n - 1; i >= 0; i--) {
            int v = sa[i];
            if (v >= 1 && ls[v - 1]) {
                sa[--buf[s[v - 1] + 1]] = v - 1;
            }
        }
    };

    std::vector<int> lms_map(n + 1, -1);
    int m = 0;
    for (int i = 1; i < n; i++) {
        if (!ls[i - 1] && ls[i]) {
            lms_map[i] = m++;
        }
    }
    std::vector<int> lms;
    lms.reserve(m);
    for (int i = 1; i < n; i++) {
        if (!ls[i - 1] && ls[i]) {
            lms.push_back(i);
        }
    }

    induce(lms);

    if (m) {
        std::vector<int> sorted_lms;
        sorted_lms.reserve(m);
        for (int v : sa) {
            if (lms_map[v] != -1) sorted_lms.push_back(v);
        }
        std::vector<int> rec_s(m);
        int rec_upper = 0;
        rec_s[lms_map[sorted_lms[0]]] = 0;
        for (int i = 1; i < m; i++) {
            int l = sorted_lms[i - 1], r = sorted_lms[i];
            int end_l = (lms_map[l] + 1 < m) ? lms[lms_map[l] + 1] : n;
            int end_r = (lms_map[r] + 1 < m) ? lms[lms_map[r] + 1] : n;
            bool same = true;
            if (end_l - l != end_r - r) {
                same = false;
            } else {
                while (l < end_l) {
                    if (s[l] != s[r]) {
                        break;
                    }
                    l++;
                    r++;
                }
                if (l == n || s[l] != s[r]) same = false;
            }
            if (!same) rec_upper++;
            rec_s[lms_map[sorted_lms[i]]] = rec_upper;
        }

        auto rec_sa =
            sa_is<THRESHOLD_NAIVE, THRESHOLD_DOUBLING>(rec_s, rec_upper);

        for (int i = 0; i < m; i++) {
            sorted_lms[i] = lms[rec_sa[i]];
        }
        induce(sorted_lms);
    }
    return sa;
}

}  // namespace internal

std::vector<int> suffix_array(const std::vector<int>& s, int upper) {
    assert(0 <= upper);
    for (int d : s) {
        assert(0 <= d && d <= upper);
    }
    auto sa = internal::sa_is(s, upper);
    return sa;
}

template <class T> std::vector<int> suffix_array(const std::vector<T>& s) {
    int n = int(s.size());
    std::vector<int> idx(n);
    iota(idx.begin(), idx.end(), 0);
    sort(idx.begin(), idx.end(), [&](int l, int r) { return s[l] < s[r]; });
    std::vector<int> s2(n);
    int now = 0;
    for (int i = 0; i < n; i++) {
        if (i && s[idx[i - 1]] != s[idx[i]]) now++;
        s2[idx[i]] = now;
    }
    return internal::sa_is(s2, now);
}

std::vector<int> suffix_array(const std::string& s) {
    int n = int(s.size());
    std::vector<int> s2(n);
    for (int i = 0; i < n; i++) {
        s2[i] = s[i];
    }
    return internal::sa_is(s2, 255);
}

// Reference:
// T. Kasai, G. Lee, H. Arimura, S. Arikawa, and K. Park,
// Linear-Time Longest-Common-Prefix Computation in Suffix Arrays and Its
// Applications
template <class T>
std::vector<int> lcp_array(const std::vector<T>& s,
                           const std::vector<int>& sa) {
    int n = int(s.size());
    assert(n >= 1);
    std::vector<int> rnk(n);
    for (int i = 0; i < n; i++) {
        rnk[sa[i]] = i;
    }
    std::vector<int> lcp(n - 1);
    int h = 0;
    for (int i = 0; i < n; i++) {
        if (h > 0) h--;
        if (rnk[i] == 0) continue;
        int j = sa[rnk[i] - 1];
        for (; j + h < n && i + h < n; h++) {
            if (s[j + h] != s[i + h]) break;
        }
        lcp[rnk[i] - 1] = h;
    }
    return lcp;
}

std::vector<int> lcp_array(const std::string& s, const std::vector<int>& sa) {
    int n = int(s.size());
    std::vector<int> s2(n);
    for (int i = 0; i < n; i++) {
        s2[i] = s[i];
    }
    return lcp_array(s2, sa);
}

// Reference:
// D. Gusfield,
// Algorithms on Strings, Trees, and Sequences: Computer Science and
// Computational Biology
template <class T> std::vector<int> z_algorithm(const std::vector<T>& s) {
    int n = int(s.size());
    if (n == 0) return {};
    std::vector<int> z(n);
    z[0] = 0;
    for (int i = 1, j = 0; i < n; i++) {
        int& k = z[i];
        k = (j + z[j] <= i) ? 0 : std::min(j + z[j] - i, z[i - j]);
        while (i + k < n && s[k] == s[i + k]) k++;
        if (j + z[j] < i + z[i]) j = i;
    }
    z[0] = n;
    return z;
}

std::vector<int> z_algorithm(const std::string& s) {
    int n = int(s.size());
    std::vector<int> s2(n);
    for (int i = 0; i < n; i++) {
        s2[i] = s[i];
    }
    return z_algorithm(s2);
}

}  // namespace atcoder


#include <cassert>
#include <vector>


namespace atcoder {

// Reference:
// B. Aspvall, M. Plass, and R. Tarjan,
// A Linear-Time Algorithm for Testing the Truth of Certain Quantified Boolean
// Formulas
struct two_sat {
  public:
    two_sat() : _n(0), scc(0) {}
    explicit two_sat(int n) : _n(n), _answer(n), scc(2 * n) {}

    void add_clause(int i, bool f, int j, bool g) {
        assert(0 <= i && i < _n);
        assert(0 <= j && j < _n);
        scc.add_edge(2 * i + (f ? 0 : 1), 2 * j + (g ? 1 : 0));
        scc.add_edge(2 * j + (g ? 0 : 1), 2 * i + (f ? 1 : 0));
    }
    bool satisfiable() {
        auto id = scc.scc_ids().second;
        for (int i = 0; i < _n; i++) {
            if (id[2 * i] == id[2 * i + 1]) return false;
            _answer[i] = id[2 * i] < id[2 * i + 1];
        }
        return true;
    }
    std::vector<bool> answer() { return _answer; }

  private:
    int _n;
    std::vector<bool> _answer;
    internal::scc_graph scc;
};

}  // namespace atcoder

#include <bits/stdc++.h>

using namespace std;
#define SZ(x) (int) (x).size()
#define REP(i, n) for(int i = 0; i < (n); i++)
#define FOR(i, a, b) for(auto i = (a); i < (b); i++)
#define For(i, a, b, c) \
	for(auto i = (a); i != (b); i += (c))
#define REPR(i, n) for(auto i = (n) - 1; i >= 0; i--)
#define ALL(s) (s).begin(), (s).end()
#define so(V) sort(ALL(V))
#define rev(V) reverse(ALL(V))
#define uni(v) v.erase(unique(ALL(v)), (v).end())
#define eb emplace_back

typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<bool> vb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int, int> PI;
typedef pair<ll, ll> PL;
const double EPS = 1e-6;
const int MOD = 1e9 + 7;
const int INF = (1 << 30);
const ll LINF = 1e18;
const double math_PI = acos(-1);

template<typename T>
vector<T> make_v(size_t a) {
	return vector<T>(a);
}

template<typename T, typename... Ts>
auto make_v(size_t a, Ts... ts) {
	return vector<decltype(make_v<T>(ts...))>(
		a, make_v<T>(ts...));
}

template<typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type fill_v(
	T &t, const V &v) {
	t = v;
}

template<typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type fill_v(
	T &t, const V &v) {
	for(auto &e: t) fill_v(e, v);
}

template<class T>
bool chmax(T &a, const T &b) {
	if(a < b) {
		a = b;
		return true;
	}
	return false;
}

template<class T>
bool chmin(T &a, const T &b) {
	if(a > b) {
		a = b;
		return true;
	}
	return false;
}

template<typename S, typename T>
istream &operator>>(istream &is, pair<S, T> &p) {
	cin >> p.first >> p.second;
	return is;
}

template<typename T>
istream &operator>>(istream &is, vector<T> &vec) {
	for(T &x: vec) is >> x;
	return is;
}

template<typename T>
string join(vector<T> &vec, string splitter) {
	stringstream ss;
	REP(i, SZ(vec)) {
		if(i != 0) ss << splitter;
		ss << vec[i];
	}
	return ss.str();
}

template<typename T>
ostream &operator<<(ostream &os, vector<T> &vec) {
	os << join(vec, " ");
	return os;
}

#ifdef LOCAL
#include "./cpp-dump/dump.hpp"
#include "./cpp-dump/mytypes.hpp"
#define dump(...) cpp_dump(__VA_ARGS__)
namespace cp = cpp_dump;
#else
#define dump(...)
#define preprocess(...)
#define CPP_DUMP_SET_OPTION(...)
#define CPP_DUMP_DEFINE_EXPORT_OBJECT(...)
#define CPP_DUMP_DEFINE_EXPORT_ENUM(...)
#define CPP_DUMP_DEFINE_DANGEROUS_EXPORT_OBJECT(...)
#endif
template<class T = ll>
struct Edge {
public:
	int from, to;
	T cost;
	Edge() {
	}
	Edge(int _from, int _to, T _cost) {
		from = _from;
		to = _to;
		cost = _cost;
	}
};
template<class T = ll>
using Edges = vector<Edge<T>>;
template<class T = ll>
using Graph = vector<Edges<T>>;
class HLdecomposition {
private:
	int V;
	vector<vector<int>> G;
	vector<int> stsize, parent, pathtop, in, out;
	int root;
	bool built_flag;
	void BuildStsize(int u, int p) {
		stsize[u] = 1, parent[u] = p;
		for(int& v: G[u]) {
			if(v == p) {
				if(v == G[u].back())
					break;
				else
					swap(v, G[u].back());
			}
			BuildStsize(v, u);
			stsize[u] += stsize[v];
			if(stsize[v] > stsize[G[u][0]]) {
				swap(v, G[u][0]);
			}
		}
	}
	void BuildPath(int u, int p, int& tm) {
		in[u] = tm++;
		for(int v: G[u]) {
			if(v == p) continue;
			pathtop[v] = (v == G[u][0] ? pathtop[u] : v);
			BuildPath(v, u, tm);
		}
		out[u] = tm;
	}

public:
	void add_edge(int u, int v) {
		G[u].push_back(v), G[v].push_back(u);
	}
	void build(int _root = 0) {
		root = _root;
		built_flag = true;
		int tm = 0;
		BuildStsize(root, -1);
		pathtop[root] = root;
		BuildPath(root, -1, tm);
	}
	inline int index(int a) {
		return in[a];
	}
	int lca(int a, int b) {
		int pa = pathtop[a], pb = pathtop[b];
		while(pathtop[a] != pathtop[b]) {
			if(in[pa] > in[pb]) {
				a = parent[pa], pa = pathtop[a];
			} else {
				b = parent[pb], pb = pathtop[b];
			}
		}
		if(in[a] > in[b]) swap(a, b);
		return a;
	}
	PI subtree_query(int a) {
		assert(
			built_flag
			&& "You must call hld.build() before call query function");
		return { in[a], out[a] };
	}
	vector<tuple<int, int, bool>> path_query(int from,
											 int to) {
		assert(
			built_flag
			&& "You must call hld.build() before call query function");
		int pf = pathtop[from], pt = pathtop[to];
		using T = tuple<int, int, bool>;
		deque<T> front, back;
		while(pathtop[from] != pathtop[to]) {
			if(in[pf] > in[pt]) {
				front.emplace_back(in[pf], in[from] + 1,
								   true);
				from = parent[pf], pf = pathtop[from];
			} else {
				back.emplace_front(in[pt], in[to] + 1,
								   false);
				to = parent[pt], pt = pathtop[to];
			}
		}
		if(in[from] > in[to]) {
			front.emplace_back(in[to], in[from] + 1, true);
		} else {
			front.emplace_back(in[from], in[to] + 1, false);
		}
		vector<T> ret;
		while(!front.empty()) {
			ret.push_back(front.front());
			front.pop_front();
		}
		while(!back.empty()) {
			ret.push_back(back.front());
			back.pop_front();
		}
		return ret;
	}
	HLdecomposition(int node_size)
		: V(node_size),
		  G(V),
		  stsize(V, 0),
		  parent(V, -1),
		  pathtop(V, -1),
		  in(V, -1),
		  out(V, -1),
		  built_flag(false) {
	}
};

template<typename T>
struct RangeSum {
private:
	vector<T> V;
	int N = -1;

public:
	RangeSum(vector<T> &v) {
		N = SZ(v);
		V = vector<T>(N + 1);
		V[0] = T(0);
		REP(i, N) {
			V[i + 1] = v[i] + V[i];
		}
	}

	T sum(int l, int r) {
		chmax(l, 0);
		chmin(r, N);
		chmax(r, l);
		return V[r] - V[l];
	}
};

template<typename T>
struct RangeSum2D {
private:
	vector<vector<T>> V;
	int H = -1;
	int W = -1;

public:
	RangeSum2D(vector<vector<T>> &v) {
		H = SZ(v);
		W = SZ(v[0]);
		V = vector<vector<T>>(H, vector<T>(W));
		REP(i, H) {
			REP(j, W) {
				V[i][j] += v[i][j];
				if(i != 0) V[i][j] += V[i - 1][j];
				if(j != 0) V[i][j] += V[i][j - 1];
				if(i != 0 && j != 0)
					V[i][j] -= V[i - 1][j - 1];
			}
		}
	}

	T sum(int y1, int x1, int y2, int x2) {
		T ret = V[y2][x2];
		if(y1 != 0) ret -= V[y1 - 1][x2];
		if(x1 != 0) ret -= V[y2][x1 - 1];
		if(y1 != 0 && x1 != 0) ret += V[y1 - 1][x1 - 1];
		return ret;
	}
};
template <typename Data, typename Cost = ll> struct Rerooting {
  vector<Data> dp, memo;
  Graph<> G;
  int N = -1;
  using F1 = function<Data(Data, Data)>;
  using F2 = function<Data(Data, Edge<Cost>)>;
  F1 merge;
  F2 apply;
  Data e, leaf;
  map<ll, Data> hash;
  bool calc_contribution;
  Rerooting(int n, F1 merge, F2 apply, Data e, Data leaf,
            bool calc_contribution = false)
      : N(n), merge(merge), apply(apply), e(e), leaf(leaf),
        calc_contribution(calc_contribution) {
    G = Graph<Cost>(n);
  }
  void add_edge(int u, int v, Cost cost) {
    G[u].eb(u, v, cost);
    G[v].eb(v, u, cost);
  }

  void add_edge(Edge<Cost> edge) {
    assert(0 <= edge.from && edge.from < N && 0 <= edge.to && edge.to < N);
    G[edge.from].push_back(edge);
  }

  vector<Data> build() {
    memo = vector<Data>(SZ(G), e);
    dp = vector<Data>(SZ(G));
    dfs1(0);
    dfs2(0, e);
    return dp;
  }

  Data getContribution(int p, int c) {
    assert(calc_contribution &&
           "Enable this function by setting calc_contribution = true");
    if (hash.count(p * N + c) == 0) {
      return e;
    } else {
      return hash[p * N + c];
    }
  }

private:
  void dfs1(int cur, int pre = -1) {
    bool isLeaf = true;
    for (Edge<Cost> edge : G[cur]) {
      if (edge.to == pre)
        continue;
      dfs1(edge.to, cur);
      isLeaf = false;
      memo[cur] =
          merge(memo[cur], apply(memo[edge.to], Edge(edge.to, cur, edge.cost)));
    }
    if (isLeaf)
      memo[cur] = leaf;
  }

  void dfs2(int cur, const Data val, int pre = -1) {
    vector<Data> ds{val};
    if (calc_contribution && pre != -1) {
      hash[cur * N + pre] = val;
    }
    for (auto edge : G[cur]) {
      if (edge.to == pre)
        continue;
      ds.push_back(apply(memo[edge.to], Edge<Cost>(edge.to, cur, edge.cost)));
      if (calc_contribution) {
        hash[cur * N + edge.to] =
            apply(memo[edge.to], Edge<Cost>(edge.to, cur, edge.cost));
      }
    }
    int N = SZ(ds);
    vector<Data> dp_left(N + 1, e), dp_right(N + 1, e);
    REP(i, N) dp_left[i + 1] = merge(dp_left[i], ds[i]);
    REPR(i, N)
    dp_right[i] = merge(dp_right[i + 1], ds[i]);
    dp[cur] = dp_left[N];
    int ind = 1; // 親以外の頂点にインデックスをつける
    for (auto edge : G[cur]) {
      if (edge.to == pre)
        continue;
      Data sub = merge(dp_left[ind], dp_right[ind + 1]);
      dfs2(edge.to, apply(sub, Edge<Cost>(cur, edge.to, edge.cost)), cur);
      ind++;
    }
  }
};
using namespace atcoder;

using mint = modint998244353;

void solve() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	int N, Q;
	cin >> N >> Q;
	vector<mint> ans(N);
	vi P(N);
	vvi G(N);
	auto merge = [](mint a, mint b) -> mint {
		return a * b;
	};
	auto apply = [](mint a, Edge<> e) -> mint {
		return a + 1;
	};
	Rerooting<mint> rr(N, merge, apply, 1, 1);
	HLdecomposition hld(N);
	FOR(i, 1, N) {
		cin >> P[i];
		P[i]--;
		G[P[i]].push_back(i);
		rr.add_edge(P[i], i, 1);
		hld.add_edge(i, P[i]);
	}
	auto dfs = [&](auto f, int cur) -> mint {
		mint c = 1;
		for(auto to: G[cur]) {
			c *= f(f, to);
		}
		ans[cur] = c;
		return c + 1;
	};
	dfs(dfs, 0);
	vector<mint> ans2 = rr.build();
	REP(i, N) {
		dump(i, ans[i].val(), ans2[i].val());
	}
	hld.build();
	vector<mint> V(N);
	REP(i, N) {
		V[hld.index(i)] = ans[i];
	}
	RangeSum<mint> RS(V);
	while(Q--) {
		int u, v;
		cin >> u >> v;
		u--;
		v--;
		int p = hld.lca(u, v);
		mint A = 0;
		for(auto [l, r, b]: hld.path_query(u, v)) {
			A += RS.sum(l, r);
		}
		A -= ans[p];
		A += ans2[p];
		cout << A.val() << endl;
	}

	return;
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	int T;
	cin >> T;
	while(T--) {
		solve();
	}
	return 0;
}


这程序好像有点Bug,我给组数据试试?

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3936kb

input:

2
3 2
1 1
2 3
1 2
5 3
1 1 2 2
4 5
2 4
2 3

output:

6
5
14
13
15

result:

ok 5 lines

Test #2:

score: 0
Accepted
time: 260ms
memory: 3752kb

input:

3000
98 100
1 2 1 3 5 3 2 5 5 4 3 7 12 10 12 8 10 4 4 3 10 14 11 11 22 23 14 20 29 1 18 7 12 29 20 29 12 21 6 20 3 25 7 21 16 44 38 44 7 11 5 24 34 24 41 48 56 58 56 3 26 55 62 33 9 38 63 39 3 67 14 24 60 35 1 22 74 36 57 61 55 46 44 12 16 60 44 50 22 58 78 15 57 57 75 88 15
43 28
67 66
3 39
6 19
84...

output:

964062690
949799024
949777463
964050185
119859605
949794873
949799267
964064991
836980963
964045750
964065023
959849545
536098301
964045791
964064966
964046253
964052677
949782329
964050627
949794848
188617843
964065041
2617316
949782330
964046253
536098346
949777935
964052584
949777939
964046254
94...

result:

ok 300000 lines

Test #3:

score: 0
Accepted
time: 293ms
memory: 3948kb

input:

300
998 1000
1 2 1 3 3 2 2 8 5 2 8 8 12 3 13 3 7 8 16 14 10 22 10 1 24 17 16 1 16 21 2 23 2 1 20 11 1 1 22 19 5 15 10 37 15 39 13 16 33 37 37 36 37 16 3 45 10 28 14 4 16 17 55 6 6 5 31 67 51 35 47 48 10 16 75 21 45 71 28 64 39 9 37 5 65 79 28 84 29 79 21 50 21 16 93 72 58 35 30 14 86 90 60 65 33 47 ...

output:

327306708
121504060
970333956
71256467
492200713
164920447
56359491
54857868
62271655
175858304
373532115
138628785
54854112
616763633
41337286
837501264
861536431
572242958
417784906
22152900
460075855
89587278
985881197
291627546
96610921
437457168
101307362
180803897
373532108
80109336
837492247
...

result:

ok 300000 lines

Test #4:

score: 0
Accepted
time: 316ms
memory: 59084kb

input:

3
100000 100000
1 1 2 4 2 4 6 5 1 8 9 7 12 10 7 12 10 4 9 7 6 22 10 5 18 3 8 18 5 20 12 26 10 11 14 5 28 29 33 12 5 10 30 21 36 24 1 26 39 29 2 42 40 33 41 39 23 2 50 11 47 61 61 52 3 27 65 4 24 1 15 41 68 5 62 1 44 60 44 79 68 6 53 72 21 58 66 24 54 78 29 39 75 74 13 52 71 35 40 85 47 19 60 44 101 ...

output:

174648911
988966670
586060443
352691812
610467698
718056854
353397034
944134980
945506609
743772159
17398768
898225958
509929535
581516662
124983919
679181027
890516256
792976265
81256963
846568565
990778256
394490295
307247131
281874314
78565559
438162317
218440246
677940950
608561943
237178689
748...

result:

ok 300000 lines

Test #5:

score: 0
Accepted
time: 340ms
memory: 59020kb

input:

3
100000 100000
1 2 3 2 2 3 4 3 7 6 10 8 6 4 3 6 5 8 3 17 2 7 1 1 17 3 4 11 25 26 5 7 2 20 2 32 35 11 9 39 16 42 26 43 29 22 35 18 3 34 45 19 27 3 41 27 10 14 4 4 45 53 35 49 57 37 24 43 68 6 44 5 15 12 62 22 11 26 37 41 8 73 56 76 78 9 46 14 81 67 49 12 74 15 16 69 86 48 47 77 58 77 87 54 79 80 99 ...

output:

761112418
717651384
861477152
134730845
623546487
488508714
852403783
522543884
880846196
809656417
876270841
575462796
111884802
845956357
990889899
222833220
7564761
917539269
355409810
261089607
166264493
612109684
526575279
410009284
848925228
885468503
90907188
969960703
663719627
309794696
503...

result:

ok 300000 lines

Test #6:

score: 0
Accepted
time: 176ms
memory: 24968kb

input:

3
100000 100000
1 2 1 2 3 5 1 4 2 6 10 3 10 6 13 14 4 18 13 4 21 19 9 16 14 5 13 15 10 29 11 4 33 31 25 15 19 32 12 17 22 24 35 38 3 1 46 28 16 8 13 5 46 44 25 49 37 30 47 37 10 56 32 29 36 7 13 47 11 2 24 6 51 65 36 52 15 74 62 65 25 34 35 61 12 4 20 81 64 39 21 79 90 29 68 30 7 34 60 1 1 1 1 1 1 1...

output:

47613014
867989885
314355471
515168737
161160818
552527
328577529
705173752
262933227
431743363
481168259
545043565
319743713
655278418
20733052
900938971
104104163
575553196
635937653
545910595
298966873
864807486
817091004
10697715
66840685
327639210
80580410
489368876
303238352
545043565
26533356...

result:

ok 300000 lines

Test #7:

score: 0
Accepted
time: 324ms
memory: 25352kb

input:

10000
10 10
1 2 2 4 4 3 4 7 9
5 4
6 7
1 9
9 5
2 2
2 1
4 5
5 5
4 6
7 6
10 10
1 1 2 4 3 4 7 5 6
10 7
7 5
10 2
10 1
4 6
1 4
1 9
8 9
4 2
10 5
9 9
1 2 1 4 2 5 2 5
5 6
9 4
4 4
3 4
6 9
8 2
7 9
9 4
1 3
10 10
1 1 2 4 4 2 7 6 1
2 10
3 10
2 6
8 3
4 8
5 6
8 5
3 6
6 10
4 7
9 9
1 2 1 3 5 2 5 2
7 8
9 6
7 2
2 3
2 6...

output:

89
106
100
108
90
91
89
45
89
106
71
58
60
50
68
63
66
60
59
71
72
55
50
68
73
57
46
55
63
110
90
113
113
114
99
115
118
118
113
83
83
73
77
82
57
82
57
83
90
91
92
92
91
59
91
93
88
66
79
69
80
72
66
66
63
33
171
169
169
170
106
160
159
157
168
169
56
91
23
95
86
80
87
91
92
89
40
34
41
37
31
37
33...

result:

ok 290206 lines

Test #8:

score: 0
Accepted
time: 224ms
memory: 62524kb

input:

10000
9 9
1 2 2 4 2 5 1 7
1 2
4 7
5 6
5 7
7 4
8 5
5 8
7 4
8 5
10 10
1 2 1 1 5 2 1 7 3
5 3
5 9
5 6
10 9
3 5
2 6
6 6
8 10
7 7
6 6
10 10
1 1 2 4 5 1 2 3 7
3 5
4 7
5 9
7 8
1 3
5 8
1 9
6 9
8 6
7 10
10 10
1 2 3 1 1 1 3 3 2
1 1
3 10
10 6
4 10
4 10
3 2
8 9
6 8
6 3
8 9
10 10
1 2 1 3 4 6 3 7 5
10 6
10 7
3 6
5...

output:

62
57
68
44
57
70
70
57
70
133
134
83
123
133
132
42
133
80
42
96
94
97
92
83
86
84
98
87
57
152
171
172
172
172
170
154
180
179
154
63
65
60
30
46
49
42
63
62
54
97
110
98
114
114
115
98
110
112
112
170
171
170
158
160
170
171
79
169
160
74
74
77
73
75
76
26
76
112
110
112
100
112
91
99
99
58
99
36...

result:

ok 290080 lines

Test #9:

score: 0
Accepted
time: 220ms
memory: 24948kb

input:

10000
9 9
1 2 3 1 3 6 3 6
2 1
9 1
7 9
7 7
6 6
2 7
6 8
3 6
4 6
10 10
1 1 3 3 5 2 7 3 6
8 7
4 9
3 10
10 8
9 4
5 1
9 9
4 6
8 5
4 2
9 9
1 1 2 4 4 5 4 4
5 2
9 8
2 2
8 1
3 5
6 1
9 3
2 8
4 6
8 8
1 2 3 1 2 5 2
1 6
8 4
7 1
8 4
8 3
7 3
8 1
1 5
9 9
1 2 1 3 5 3 7 1
7 2
6 3
4 3
7 7
9 7
4 4
4 4
8 6
4 4
10 10
1 1 ...

output:

65
90
70
35
68
88
85
84
85
39
82
86
96
82
87
41
86
93
88
101
98
75
102
104
102
103
100
97
52
52
42
52
51
56
52
41
61
57
64
38
66
23
23
60
23
87
116
86
115
118
136
87
135
129
115
123
130
82
120
82
119
120
133
132
129
85
89
87
90
41
85
86
45
63
53
48
23
46
35
45
47
41
36
58
64
62
62
61
67
20
69
56
56
...

result:

ok 289972 lines

Test #10:

score: 0
Accepted
time: 303ms
memory: 43488kb

input:

10000
9 9
1 2 2 1 2 3 1 1
3 3
3 3
2 7
8 2
3 5
1 1
9 2
3 1
7 5
8 8
1 1 2 4 5 1 7
6 6
6 2
4 8
4 7
2 4
8 7
2 1
6 5
9 9
1 2 2 2 1 4 2 1
5 2
3 1
8 5
8 2
1 5
7 2
2 5
4 3
8 1
9 9
1 2 1 4 4 4 2 8
5 7
1 2
7 7
7 4
9 2
7 7
8 2
3 6
8 5
9 9
1 1 2 4 3 6 7 5
2 2
7 8
3 5
7 2
6 4
7 3
5 9
6 6
2 7
10 10
1 2 1 2 4 6 6 ...

output:

74
74
111
117
119
104
117
118
120
10
34
40
39
31
23
34
19
121
125
122
121
125
123
121
123
125
66
69
33
65
63
33
62
79
80
24
17
38
38
39
29
17
21
38
66
74
70
50
68
69
45
70
45
81
95
103
96
100
75
75
75
61
100
91
87
92
92
86
43
55
86
82
80
95
100
102
49
25
108
71
94
104
89
92
98
91
94
93
96
63
63
98
6...

result:

ok 289954 lines

Test #11:

score: 0
Accepted
time: 308ms
memory: 62520kb

input:

10000
9 9
1 1 3 1 4 3 5 7
7 7
7 6
2 3
2 6
2 7
4 1
6 5
6 7
6 7
8 8
1 1 2 1 5 6 2
8 2
8 3
1 1
6 8
1 4
2 8
3 5
8 4
8 8
1 2 1 4 3 1 5
3 2
5 5
7 8
4 4
6 7
2 8
2 1
1 3
9 9
1 2 3 2 3 3 3 7
9 9
4 4
4 3
9 9
8 6
3 8
6 1
1 1
7 6
8 8
1 1 3 3 2 2 1
4 1
7 1
4 7
2 8
2 2
8 5
4 8
1 5
10 10
1 2 2 3 4 2 3 6 7
3 5
10 3...

output:

44
68
70
73
72
71
74
68
68
37
46
40
50
45
37
44
38
29
20
39
27
39
41
35
37
42
61
121
42
122
121
126
51
123
55
55
60
55
44
56
56
55
101
127
51
83
127
125
127
131
123
127
44
132
135
118
79
136
128
137
137
128
112
92
99
92
111
108
106
106
114
112
55
56
51
60
55
54
55
56
52
22
42
53
31
44
45
45
50
45
40...

result:

ok 289847 lines

Test #12:

score: 0
Accepted
time: 276ms
memory: 24844kb

input:

10000
8 8
1 1 3 3 1 4 2
2 5
1 3
7 1
2 7
7 8
1 6
5 6
4 4
8 8
1 2 1 3 4 6 5
4 3
5 3
6 4
6 4
5 5
2 8
4 8
7 2
9 9
1 2 3 3 1 2 3 4
5 6
1 3
2 8
5 2
7 5
6 1
8 3
8 5
2 8
9 9
1 1 1 2 4 6 3 3
3 9
6 2
6 5
6 3
6 6
4 5
4 5
9 4
3 4
8 8
1 1 3 4 2 5 1
1 2
7 2
4 2
8 3
1 7
5 1
2 4
3 6
9 9
1 2 1 4 5 1 3 5
9 6
1 9
7 4
...

output:

51
48
51
53
54
43
50
30
30
20
20
20
14
26
33
30
94
92
91
91
92
55
85
86
91
53
67
68
69
34
66
66
68
67
32
42
39
35
40
39
39
37
42
58
54
50
49
42
61
51
53
18
88
68
78
85
36
81
63
24
84
28
40
31
39
38
24
38
30
84
73
75
57
82
78
57
65
84
68
70
53
70
53
67
68
50
71
74
72
23
31
45
66
73
65
22
108
101
102
...

result:

ok 290127 lines

Test #13:

score: 0
Accepted
time: 287ms
memory: 43492kb

input:

10000
9 9
1 1 3 2 3 1 1 3
9 8
3 9
5 8
1 9
6 4
7 3
2 2
8 8
2 5
9 9
1 2 1 3 5 4 7 6
9 5
2 3
6 1
4 1
2 9
1 1
8 5
5 8
5 1
9 9
1 1 2 1 4 1 1 2
8 3
9 1
4 6
6 1
9 4
1 9
7 6
3 3
9 2
8 8
1 2 3 2 1 3 1
5 6
8 5
6 7
3 6
2 8
2 7
4 2
5 3
9 9
1 1 3 1 2 6 1 2
2 1
1 4
5 9
1 4
3 6
6 9
7 4
7 7
5 4
8 8
1 2 1 3 5 2 4
3 ...

output:

118
105
112
117
106
117
74
55
75
24
29
38
27
35
24
42
42
36
114
119
71
121
105
119
122
57
103
56
56
60
59
55
55
55
55
90
87
92
87
94
81
96
28
88
38
38
21
37
21
44
35
21
37
42
48
33
46
42
48
14
39
32
95
97
39
78
94
63
96
106
86
34
100
104
97
85
99
113
106
71
47
65
70
67
39
60
63
64
60
74
53
60
52
60
...

result:

ok 289926 lines

Test #14:

score: 0
Accepted
time: 242ms
memory: 62296kb

input:

10000
8 8
1 2 1 2 4 2 7
4 5
2 6
5 8
1 1
7 7
6 5
2 1
4 4
10 10
1 1 2 2 5 6 5 3 6
3 8
10 8
8 3
9 3
5 5
1 1
7 2
2 9
7 2
2 10
8 8
1 1 1 1 3 3 6
5 7
8 8
4 5
4 4
5 2
4 2
4 2
3 3
9 9
1 1 1 4 5 6 6 5
1 3
1 3
6 3
9 3
3 6
1 2
5 9
8 5
8 1
8 8
1 2 1 3 5 3 6
1 5
7 3
5 2
5 7
1 5
1 3
5 5
5 7
9 9
1 2 3 1 2 1 7 2
7 ...

output:

54
54
52
39
34
55
51
28
104
96
104
49
90
69
103
94
103
103
64
20
58
29
58
58
58
54
49
49
74
71
74
49
61
65
74
40
33
38
36
40
37
27
36
93
87
94
79
90
28
93
88
93
52
43
49
45
45
43
31
54
48
52
31
22
53
52
50
46
104
107
100
94
102
96
108
105
104
96
112
92
115
94
93
62
111
92
107
62
32
44
44
33
42
23
44...

result:

ok 289769 lines

Test #15:

score: 0
Accepted
time: 260ms
memory: 62328kb

input:

10000
8 8
1 2 1 3 4 6 4
1 8
8 5
7 7
5 4
1 6
3 1
8 7
1 8
9 9
1 2 3 2 5 1 7 4
4 8
9 6
3 9
4 8
4 7
3 9
5 2
6 1
2 6
8 8
1 2 2 4 2 4 6
6 5
1 1
8 4
2 6
7 4
7 8
1 2
1 6
9 9
1 1 1 4 4 2 1 5
2 7
1 4
4 4
8 3
5 2
6 7
2 6
7 6
6 9
10 10
1 1 2 1 1 4 3 2 6
3 7
2 5
10 9
3 5
5 7
1 7
1 10
1 9
8 3
3 6
9 9
1 1 3 2 5 3 ...

output:

35
41
12
40
36
33
34
35
59
57
42
59
58
42
50
54
51
67
31
67
62
53
68
61
63
59
90
78
86
94
94
93
94
82
137
133
136
129
136
135
129
133
87
130
78
78
71
64
80
65
64
71
65
164
168
165
164
164
167
167
167
166
163
36
40
36
37
37
37
39
38
95
92
92
86
94
57
92
87
90
80
29
57
55
60
59
57
51
57
54
64
39
59
64...

result:

ok 290030 lines

Test #16:

score: 0
Accepted
time: 228ms
memory: 43528kb

input:

10000
8 8
1 2 1 4 5 6 7
8 8
7 5
3 5
5 5
8 4
4 6
1 7
1 2
8 8
1 1 3 3 2 5 4
4 3
7 1
8 5
6 3
2 8
5 7
4 4
2 8
8 8
1 1 1 3 1 4 2
2 5
7 1
7 8
5 6
5 8
4 8
7 8
7 1
9 9
1 1 2 3 2 2 1 7
6 6
7 6
4 7
3 5
7 9
8 6
2 5
6 4
4 2
9 9
1 2 3 3 2 5 2 5
8 5
8 5
6 6
9 6
3 1
4 2
4 7
7 5
9 7
8 8
1 2 3 4 4 2 1
3 8
3 5
5 2
3 ...

output:

8
25
30
20
30
27
32
20
38
42
41
42
44
27
26
44
59
57
60
58
60
59
60
57
43
87
87
55
59
92
93
86
85
103
103
45
104
99
99
96
77
78
44
40
46
42
43
48
33
49
62
66
45
45
31
70
62
64
67
34
80
86
78
75
48
86
80
84
82
71
64
70
69
68
63
58
68
62
138
145
154
156
151
114
157
151
113
158
51
31
51
22
49
51
50
44
...

result:

ok 289869 lines

Test #17:

score: 0
Accepted
time: 332ms
memory: 25392kb

input:

10000
8 8
1 1 2 3 3 4 6
7 8
1 6
2 3
5 8
2 1
2 5
8 4
2 5
8 8
1 2 3 2 4 2 4
4 2
7 8
5 8
7 4
6 4
6 4
7 4
1 7
8 8
1 1 2 2 2 4 3
6 3
3 2
5 1
7 5
6 1
2 5
3 2
7 8
8 8
1 1 2 3 3 5 7
6 8
8 8
4 1
1 6
7 3
8 2
8 1
7 2
8 8
1 2 3 3 2 1 7
8 3
1 4
6 5
8 2
3 3
3 6
1 3
5 7
9 9
1 2 1 3 2 5 5 8
3 7
9 6
5 9
1 1
4 2
3 1
...

output:

43
36
37
34
31
38
42
38
57
59
59
58
41
41
58
50
54
53
52
52
52
49
53
57
39
11
30
36
37
43
41
42
50
48
46
46
36
45
47
50
56
65
51
34
51
57
56
55
48
23
65
66
74
74
69
74
23
63
116
113
119
66
112
116
99
105
116
113
59
53
25
59
41
41
49
59
116
110
125
110
83
110
123
109
111
122
79
74
79
79
75
51
51
51
5...

result:

ok 289830 lines

Test #18:

score: 0
Accepted
time: 300ms
memory: 62476kb

input:

10000
8 8
1 2 2 4 3 3 4
4 7
7 7
5 1
4 7
6 4
3 6
3 1
2 6
10 10
1 1 1 4 1 5 3 1 9
10 10
4 9
9 2
3 3
8 1
7 1
4 8
1 10
8 7
3 9
8 8
1 2 2 2 5 6 5
6 5
1 8
8 6
3 5
4 8
8 7
2 1
3 7
8 8
1 2 2 4 4 3 3
8 6
1 7
2 6
1 6
8 3
3 2
3 2
8 4
8 8
1 2 2 1 2 3 2
8 1
7 6
5 7
8 5
1 5
1 2
2 2
3 3
8 8
1 1 1 2 3 6 4
6 6
1 4
1...

output:

59
23
56
59
59
45
55
55
50
149
147
98
147
150
150
147
153
148
56
64
57
63
64
58
57
66
60
56
55
56
45
54
54
59
75
76
78
76
51
74
72
50
22
38
39
44
43
39
22
27
41
21
41
40
41
49
51
47
126
109
135
122
135
129
126
133
51
135
135
135
101
140
135
135
140
134
137
134
45
59
45
56
60
60
56
45
220
219
74
218
...

result:

ok 290002 lines

Test #19:

score: 0
Accepted
time: 240ms
memory: 24708kb

input:

10000
10 10
1 2 1 1 3 5 6 6 1
5 9
1 3
6 6
1 5
8 10
9 5
9 9
5 10
3 4
9 8
10 10
1 1 3 4 1 1 1 2 9
5 2
1 1
4 1
7 1
7 2
9 4
9 2
3 4
7 10
7 3
10 10
1 2 3 3 4 3 7 3 7
2 2
2 3
2 10
8 6
9 1
10 4
1 6
7 5
4 2
9 6
8 8
1 2 3 1 5 4 5
2 7
1 8
8 7
1 3
2 3
7 5
1 4
5 6
8 8
1 1 3 2 1 4 4
2 2
8 5
8 1
2 6
3 7
5 2
2 3
5...

output:

102
95
60
86
101
102
31
87
96
62
137
128
133
129
132
138
101
101
135
132
122
182
187
188
184
187
186
185
184
184
30
30
40
32
27
39
34
25
26
49
46
39
40
27
43
14
57
66
64
54
62
38
59
67
59
110
113
75
75
111
112
75
111
113
83
97
23
93
95
94
83
86
86
84
156
144
159
69
156
159
143
156
145
73
168
165
168...

result:

ok 289994 lines

Test #20:

score: 0
Accepted
time: 317ms
memory: 43408kb

input:

10000
9 9
1 2 3 4 5 2 2 1
2 4
1 9
9 2
2 4
7 4
8 5
9 5
7 3
1 5
8 8
1 2 1 1 5 2 2
8 1
5 3
5 3
5 2
1 1
3 1
3 4
7 3
9 9
1 1 3 1 1 2 2 7
6 5
2 9
2 8
3 5
1 4
5 7
8 2
1 1
7 6
9 9
1 2 1 2 5 1 1 5
3 1
9 6
1 7
1 5
4 9
4 9
8 1
1 3
3 4
8 8
1 1 2 3 3 6 5
5 5
6 3
7 2
1 4
3 4
2 4
3 1
8 4
10 10
1 1 3 3 2 5 4 8 4
3 ...

output:

67
43
63
67
68
70
72
65
71
63
65
65
64
54
63
64
58
86
81
79
87
87
93
79
84
93
99
78
89
102
104
104
89
99
100
26
38
44
33
42
23
39
45
90
94
97
97
87
47
96
96
69
90
114
118
110
110
119
121
120
114
119
82
43
51
31
44
46
16
52
52
68
33
66
70
71
70
37
71
57
51
51
52
34
18
18
49
73
64
74
66
61
70
49
65
75...

result:

ok 289988 lines

Test #21:

score: 0
Accepted
time: 268ms
memory: 62820kb

input:

10000
8 8
1 2 2 2 2 4 4
6 6
3 7
8 7
5 3
1 6
8 4
6 2
4 4
10 10
1 2 3 4 3 5 5 6 7
4 4
1 10
4 9
9 4
7 5
6 9
6 1
3 2
6 2
9 10
10 10
1 1 1 3 4 5 3 5 3
1 8
9 3
6 6
6 2
6 5
7 1
10 5
4 2
7 3
3 9
8 8
1 2 3 1 3 3 3
6 8
5 8
4 8
1 6
3 8
5 5
7 3
2 4
8 8
1 1 2 1 5 4 2
2 6
2 1
1 5
7 4
5 8
1 2
8 4
4 1
8 8
1 2 3 4 4...

output:

41
86
70
82
82
69
81
68
70
91
82
82
68
51
77
74
76
91
147
145
44
130
153
151
145
129
145
145
66
71
66
70
65
19
65
68
51
48
44
31
51
48
45
50
60
59
59
51
54
59
55
45
74
73
77
77
75
75
75
75
160
171
160
160
157
170
168
158
159
171
90
90
117
114
118
117
107
114
37
113
47
37
45
37
19
45
50
48
121
116
11...

result:

ok 290036 lines

Test #22:

score: 0
Accepted
time: 267ms
memory: 25108kb

input:

10000
9 9
1 2 2 1 2 2 7 3
8 1
6 1
2 4
4 4
2 7
6 5
2 9
9 9
1 9
9 9
1 1 3 1 5 6 5 7
9 5
3 5
7 5
1 3
4 6
7 4
6 6
8 1
8 7
8 8
1 1 3 2 1 5 1
2 1
5 5
4 7
5 2
1 1
7 5
2 5
1 6
10 10
1 1 2 1 5 3 2 7 4
10 3
5 6
4 10
9 3
3 3
4 6
7 7
4 7
9 3
7 7
9 9
1 2 2 4 3 2 1 7
7 8
4 6
9 7
4 3
8 3
2 1
8 6
8 3
2 5
9 9
1 1 2 ...

output:

113
111
109
55
110
112
111
38
113
62
64
61
56
68
70
45
63
62
51
28
57
41
48
29
41
49
96
59
55
69
66
95
46
97
69
46
86
86
57
85
86
83
87
86
84
48
68
63
54
20
68
17
61
65
69
49
49
25
70
69
66
60
66
105
112
68
117
117
116
69
113
113
115
49
45
47
48
45
48
39
40
160
169
172
159
169
170
171
171
169
160
79...

result:

ok 289982 lines

Test #23:

score: 0
Accepted
time: 292ms
memory: 43456kb

input:

10000
8 8
1 1 2 3 2 4 6
7 8
3 4
5 2
2 4
5 3
5 3
2 2
1 7
9 9
1 2 3 1 4 1 3 2
9 6
5 8
9 7
7 4
5 8
3 1
3 1
2 7
1 8
9 9
1 1 3 3 5 1 1 5
8 2
6 4
1 7
8 5
7 3
3 2
5 7
2 4
6 8
9 9
1 2 3 1 3 2 5 1
6 4
4 6
2 1
8 1
8 5
9 2
7 2
3 1
1 2
8 8
1 2 2 2 4 1 1
7 7
7 4
5 8
4 5
8 2
3 4
8 6
4 4
10 10
1 1 1 4 1 5 4 8 4
6 ...

output:

42
43
42
38
23
23
36
42
80
82
76
83
82
80
80
75
81
90
96
89
103
99
99
103
100
104
62
62
76
69
47
77
71
80
76
27
67
66
63
65
63
68
42
154
154
172
171
111
171
154
153
154
173
112
113
112
112
114
113
114
108
109
105
122
123
125
131
132
55
122
123
123
65
62
53
63
61
53
64
67
166
81
165
166
166
133
161
1...

result:

ok 289985 lines

Test #24:

score: 0
Accepted
time: 1ms
memory: 3904kb

input:

2
2 1
1
2 1
2 4
1
1 1
1 2
2 1
2 2

output:

3
2
3
3
2

result:

ok 5 lines

Test #25:

score: 0
Accepted
time: 271ms
memory: 62268kb

input:

10000
9 9
1 1 3 1 4 2 6 4
6 1
9 1
2 2
7 3
8 5
8 3
3 8
7 4
8 3
9 9
1 2 1 1 3 1 1 5
9 5
1 5
1 5
4 7
1 4
6 7
7 9
2 8
6 5
10 10
1 2 3 2 5 6 5 1 6
10 2
4 2
1 1
10 7
3 4
5 5
4 8
3 2
6 1
4 6
8 8
1 2 3 3 2 4 2
2 8
1 4
7 8
5 7
1 4
4 6
5 5
7 5
8 8
1 2 1 4 5 4 6
8 7
3 7
6 8
6 2
2 8
1 7
2 8
5 3
8 8
1 1 1 1 3 6 ...

output:

63
62
34
58
65
58
58
64
58
67
98
98
98
97
103
100
100
104
114
102
68
86
69
100
113
101
115
116
57
65
66
58
65
65
28
58
39
39
21
42
43
36
43
41
50
59
59
59
50
49
58
49
45
49
54
52
52
54
45
16
14
15
25
23
27
26
26
23
85
94
94
92
93
88
94
91
54
154
177
176
85
177
177
177
103
171
175
92
94
94
92
92
59
9...

result:

ok 290047 lines

Test #26:

score: 0
Accepted
time: 247ms
memory: 62276kb

input:

10000
10 10
1 1 2 4 3 4 3 1 1
8 9
5 8
2 8
2 10
1 1
1 8
5 7
9 8
6 5
7 7
10 10
1 2 3 2 5 1 3 4 2
3 1
2 10
2 6
2 6
10 2
9 5
6 3
4 3
8 8
6 1
9 9
1 1 3 3 5 2 3 1
8 1
2 3
6 4
5 8
4 3
1 5
1 4
2 5
8 6
10 10
1 1 1 4 4 3 5 6 6
7 2
5 2
8 10
4 4
8 1
10 2
4 7
9 3
3 7
1 9
10 10
1 1 3 3 3 2 5 7 9
8 8
1 2
10 8
7 7
...

output:

126
135
130
126
120
125
90
126
135
45
134
127
129
129
127
137
135
116
58
131
91
92
88
87
85
92
91
94
88
100
114
113
105
114
117
114
118
67
116
26
69
90
45
75
87
65
78
62
78
83
29
73
84
29
37
73
83
70
74
75
77
74
73
26
76
74
33
38
35
40
40
26
49
48
86
78
102
101
96
30
87
75
84
100
62
64
23
57
46
73
6...

result:

ok 290027 lines

Test #27:

score: 0
Accepted
time: 265ms
memory: 43468kb

input:

10000
10 10
1 2 2 2 3 2 7 4 5
8 7
4 9
10 4
10 5
5 10
6 10
4 2
7 8
6 10
8 9
8 8
1 2 2 2 3 3 1
5 8
5 4
4 4
8 8
6 4
8 1
8 1
4 8
8 8
1 2 3 4 3 5 6
3 5
2 7
8 1
5 7
1 6
3 3
6 4
4 8
10 10
1 1 3 1 1 1 3 2 8
1 6
5 2
3 3
3 8
2 3
7 7
4 8
4 9
5 10
2 6
9 9
1 1 3 4 3 6 3 4
7 3
2 2
2 5
2 6
1 8
3 9
5 3
1 7
9 9
9 9
...

output:

111
111
167
111
111
168
164
111
168
168
64
62
31
22
66
43
43
64
41
44
42
23
41
36
41
42
169
171
150
152
176
85
153
178
178
171
93
32
98
95
93
95
95
95
39
146
145
148
147
148
146
147
146
147
49
51
50
53
42
51
51
43
35
99
100
100
102
97
100
99
101
99
33
71
65
51
70
71
67
66
136
131
129
135
118
115
129...

result:

ok 290108 lines

Extra Test:

score: 0
Extra Test Passed