#define MULTI_CASES 0 #define INTERACTIVE 0 #define USE_INT 1 #ifndef LOCAL #define LOCAL 0 #endif #if !LOCAL #define NDEBUG #endif #ifndef __GLIBCXX_TYPE_INT_N_0 #define __GLIBCXX_TYPE_INT_N_0 __int128 #endif #include #include #include namespace r7h { using namespace std; auto main(int) -> void; } // namespace r7h #if LOCAL #include #else #define DUMP(...) void(0) #endif namespace r7h { using i8 = signed char; using u8 = unsigned char; using i16 = short int; using u16 = unsigned short int; using i32 = int; using u32 = unsigned int; using i64 = long long int; using u64 = unsigned long long int; using i128 = __int128; using u128 = unsigned __int128; template struct signed_int; template struct unsigned_int; #define INT_TYPE(N) \ template <> \ struct signed_int { \ using type = i##N; \ }; \ template <> \ struct unsigned_int { \ using type = u##N; \ }; INT_TYPE(8) INT_TYPE(16) INT_TYPE(32) INT_TYPE(64) INT_TYPE(128) #undef INT_TYPE template using signed_int_t = typename signed_int::type; template using unsigned_int_t = typename unsigned_int::type; } // namespace r7h #define LIFT(...) \ [](Ts_&&... xs_) -> decltype(__VA_ARGS__(::std::forward(xs_)...)) { \ return __VA_ARGS__(::std::forward(xs_)...); \ } #define LAMBDA(...) \ [&]([[maybe_unused]] T1_&& _1 = nullptr, [[maybe_unused]] T2_&& _2 = nullptr) \ -> decltype(__VA_ARGS__) { \ return __VA_ARGS__; \ } namespace r7h { template class fix { [[no_unique_address]] F f; public: explicit fix(F f) : f(move(f)) {} template auto operator()(Ts&&... xs) const -> decltype(invoke(f, ref(*this), forward(xs)...)) { return invoke(f, ref(*this), forward(xs)...); } }; struct left_shift { template auto operator()(T1&& x, T2&& y) const -> decltype(forward(x) << forward(y)) { return forward(x) << forward(y); } }; struct right_shift { template auto operator()(T1&& x, T2&& y) const -> decltype(forward(x) >> forward(y)) { return forward(x) >> forward(y); } }; template auto decay_copy(T&& x) -> decay_t { return forward(x); } template auto ref_or_move(remove_reference_t& x) -> auto { if constexpr (is_reference_v && !is_placeholder_v>) { return ref(x); } else { return move(x); } } template > auto const is_lambda_expr = is_placeholder_v || is_bind_expression_v; #define UNARY_LAMBDA(OP, FN) \ template >* = nullptr> \ auto operator OP(T&& x) -> auto { \ return bind(FN(), ref_or_move(x)); \ } #define BINARY_LAMBDA(OP, FN) \ template || is_lambda_expr>* = nullptr> \ auto operator OP(T1&& x, T2&& y) -> auto { \ return bind(FN(), ref_or_move(x), ref_or_move(y)); \ } UNARY_LAMBDA(-, negate) BINARY_LAMBDA(+, plus) BINARY_LAMBDA(-, minus) BINARY_LAMBDA(*, multiplies) BINARY_LAMBDA(/, divides) BINARY_LAMBDA(%, modulus) UNARY_LAMBDA(~, bit_not) BINARY_LAMBDA(&, bit_and) BINARY_LAMBDA(|, bit_or) BINARY_LAMBDA(^, bit_xor) BINARY_LAMBDA(<<, left_shift) BINARY_LAMBDA(>>, right_shift) BINARY_LAMBDA(==, equal_to) BINARY_LAMBDA(!=, not_equal_to) BINARY_LAMBDA(<, less) BINARY_LAMBDA(>, greater) BINARY_LAMBDA(<=, less_equal) BINARY_LAMBDA(>=, greater_equal) UNARY_LAMBDA(!, logical_not) BINARY_LAMBDA(&&, logical_and) BINARY_LAMBDA(||, logical_or) #undef UNARY_LAMBDA #undef BINARY_LAMBDA template >* = nullptr> auto operator+(T&& x) -> auto { return bind([](T_&& x_) -> decltype(+forward(x_)) { return +forward(x_); }, ref_or_move(x)); } template >* = nullptr> auto operator++(T&& x) -> auto { return bind([](T_&& x_) -> decltype(++forward(x_)) { return ++forward(x_); }, ref_or_move(x)); } template >* = nullptr> auto operator--(T&& x) -> auto { return bind([](T_&& x_) -> decltype(--forward(x_)) { return --forward(x_); }, ref_or_move(x)); } #define ASSIGN_LAMBDA(OP) \ template || is_lambda_expr>* = nullptr> \ auto operator OP##=(T1&& x, T2&& y) -> auto { \ auto f = [](T1_&& x_, T2_&& y_) -> decltype(forward(x_) OP##= forward(y_)) { \ return forward(x_) OP##= forward(y_); \ }; \ return bind(move(f), ref_or_move(x), ref_or_move(y)); \ } ASSIGN_LAMBDA(+) ASSIGN_LAMBDA(-) ASSIGN_LAMBDA(*) ASSIGN_LAMBDA(/) ASSIGN_LAMBDA(%) ASSIGN_LAMBDA(&) ASSIGN_LAMBDA(|) ASSIGN_LAMBDA(^) ASSIGN_LAMBDA(<<) ASSIGN_LAMBDA(>>) #undef ASSIGN_LAMBDA using namespace placeholders; } // namespace r7h namespace r7h { namespace scan_impl { #if INTERACTIVE || LOCAL auto scan(char& c) -> bool { return scanf(" %c", &c) != EOF; } auto scan(string& s) -> bool { char c; if (!scan(c)) { return false; } s = c; while (true) { c = char(getchar()); if (' ' < c) { s += c; } else { ungetc(c, stdin); break; } } return true; } template >* = nullptr> auto scan(T& x) -> bool { char c; if (!scan(c)) { return false; } auto u = make_unsigned_t>((c == '-' ? getchar() : c) & 15); while (true) { if (auto t = getchar(); '0' <= t && t <= '9') { u *= 10; u += t & 15; } else { ungetc(t, stdin); break; } } x = T(c == '-' ? -u : u); return true; } template >* = nullptr> auto scan(T& x) -> bool { if constexpr (is_same_v) { return scanf("%f", &x) != EOF; } else if constexpr (is_same_v) { return scanf("%lf", &x) != EOF; } else if constexpr (is_same_v) { return scanf("%Lf", &x) != EOF; } else { static_assert(LAMBDA(false)()); } } #else char buf[1 << 15]; auto ptr = buf; auto last = buf; auto scan(char& c) -> bool { while (true) { if (last - ptr < 64) { last = move(ptr, last, buf); ptr = buf; last += read(STDIN_FILENO, last, end(buf) - last - 1); *last = '\0'; } if (ptr == last) { return false; } if (' ' < *ptr) { c = *ptr++; return true; } ++ptr; } } auto scan(string& s) -> bool { char c; if (!scan(c)) { return false; } s = c; while (' ' < *ptr) { scan(c); s += c; } return true; } template >* = nullptr> auto scan(T& x) -> bool { char c; if (!scan(c)) { return false; } auto u = make_unsigned_t>((c == '-' ? *ptr++ : c) & 15); while ('0' <= *ptr && *ptr <= '9') { u *= 10; u += *ptr++ & 15; } x = T(c == '-' ? -u : u); return true; } template >* = nullptr> auto scan(T& x) -> bool { char c; if (!scan(c)) { return false; } --ptr; if constexpr (is_same_v) { x = strtof(ptr, &ptr); } else if constexpr (is_same_v) { x = strtod(ptr, &ptr); } else if constexpr (is_same_v) { x = strtold(ptr, &ptr); } else { static_assert(LAMBDA(false)()); } return true; } #endif template auto scan(pair&) -> bool; template auto scan(tuple&) -> bool; template auto scan(R&& r) -> decltype(begin(r), end(r), true) { return all_of(begin(r), end(r), LIFT(scan)); } template * = nullptr> auto scan(Ts&&... xs) -> bool { return (... && scan(forward(xs))); } template auto scan(pair& p) -> bool { return scan(p.first, p.second); } template auto scan(tuple& t) -> bool { return apply(LIFT(scan), t); } } // namespace scan_impl using scan_impl::scan; template auto input(Args&&... args) -> T { auto ret = T(forward(args)...); [[maybe_unused]] auto res = scan(ret); assert(res); return ret; } namespace print_impl { #if INTERACTIVE || LOCAL template auto print(char c) -> void { if (c) { putchar(c); } if (c == '\n') { fflush(stdout); } } template >* = nullptr> auto print(T x) -> void { char buf[64]; auto ptr = to_chars(buf, end(buf), x).ptr; for_each(buf, ptr, LIFT(print)); } template >* = nullptr> auto print(T x) -> void { if constexpr (is_same_v) { printf("%.6f", x); } else if constexpr (is_same_v) { printf("%.15f", x); } else if constexpr (is_same_v) { printf("%.18Lf", x); } else { static_assert(LAMBDA(false)()); } } #else char buf[1 << 15]; auto ptr = buf; __attribute__((destructor)) auto flush() -> void { if (write(STDOUT_FILENO, buf, ptr - buf) == -1) { abort(); } ptr = buf; } template auto print(char c) -> void { if (end(buf) - ptr < 64) { flush(); } if (c) { *ptr++ = c; } } template >* = nullptr> auto print(T x) -> void { print('\0'); ptr = to_chars(ptr, end(buf), x).ptr; } template >* = nullptr> auto print(T x) -> void { print('\0'); if constexpr (is_same_v) { ptr += snprintf(ptr, end(buf) - ptr, "%.6f", x); } else if constexpr (is_same_v) { ptr += snprintf(ptr, end(buf) - ptr, "%.15f", x); } else if constexpr (is_same_v) { ptr += snprintf(ptr, end(buf) - ptr, "%.18Lf", x); } else { static_assert(LAMBDA(false)()); } } #endif template auto print(pair const&) -> void; template auto print(tuple const&) -> void; template auto print(R&& r) -> void_t { [[maybe_unused]] auto c = '\0'; for (auto&& e : r) { if constexpr (!is_same_v, char>) { print(exchange(c, Sep)); } print(e); } } template auto print(char const* s) -> void { print(string_view(s)); } template * = nullptr> auto print(Ts&&... xs) -> void { [[maybe_unused]] auto c = '\0'; (..., (print(exchange(c, Sep)), print(forward(xs)))); } template auto print(pair const& p) -> void { print(p.first, p.second); } template auto print(tuple const& t) -> void { apply(LIFT(print), t); } } // namespace print_impl using print_impl::print; template auto println(Ts&&... xs) -> void { print(forward(xs)...); print(End); } } // namespace r7h namespace r7h { template auto operator++(T& x, int) -> decltype(++x, T(x)) { auto ret = x; ++x; return ret; } template auto operator--(T& x, int) -> decltype(--x, T(x)) { auto ret = x; --x; return ret; } #define BINARY_ARITH_OP(OP) \ template > \ auto operator OP(T1 const& x, T2 const& y) -> decltype(declval() OP##= y, T(x)) { \ auto ret = T(x); \ ret OP##= y; \ return ret; \ } BINARY_ARITH_OP(+) BINARY_ARITH_OP(-) BINARY_ARITH_OP(*) BINARY_ARITH_OP(/) BINARY_ARITH_OP(%) BINARY_ARITH_OP(&) BINARY_ARITH_OP(|) BINARY_ARITH_OP(^) BINARY_ARITH_OP(<<) BINARY_ARITH_OP(>>) #undef BINARY_ARITH_OP #define COMPARISON_OP(OP, E) \ template \ auto operator OP(T1 const& x, T2 const& y) -> decltype(E) { \ return E; \ } COMPARISON_OP(!=, !(x == y)) COMPARISON_OP(>, y < x) COMPARISON_OP(<=, !(y < x)) COMPARISON_OP(>=, !(x < y)) #undef COMPARISON_OP } // namespace r7h namespace r7h { #if USE_INT using ptrdiff_t = int; #endif template class iter_base { auto derived() & -> D& { return static_cast(*this); } auto derived() const& -> D const& { return static_cast(*this); } auto equal(D const& x) const -> bool { return derived().equal(x); } auto dist_to(D const& x) const -> ptrdiff_t { return derived().dist_to(x); } public: using iterator_category = C; using value_type = decay_t; using difference_type = ptrdiff_t; using pointer = void; using reference = R; #define REQUIRE(CATEGORY) template >* = nullptr> auto operator*() const -> R { return derived().deref(); } REQUIRE(random_access) auto operator[](ptrdiff_t n) const -> R { return *(derived() + n); } auto operator++() & -> D& { derived().inc(); return derived(); } REQUIRE(bidirectional) auto operator--() & -> D& { derived().dec(); return derived(); } REQUIRE(random_access) auto operator+=(ptrdiff_t n) & -> D& { derived().advance(n); return derived(); } REQUIRE(random_access) auto operator-=(ptrdiff_t n) & -> D& { derived().advance(-n); return derived(); } REQUIRE(random_access) friend auto operator+(D const& x, ptrdiff_t n) -> D { auto ret = x; ret += n; return ret; } REQUIRE(random_access) friend auto operator+(ptrdiff_t n, D const& x) -> D { return x + n; } REQUIRE(random_access) friend auto operator-(D const& x, ptrdiff_t n) -> D { auto ret = x; ret -= n; return ret; } REQUIRE(random_access) friend auto operator-(D const& x, D const& y) -> ptrdiff_t { return static_cast(y).dist_to(x); } friend auto operator==(D const& x, D const& y) -> bool { return static_cast(x).equal(y); } REQUIRE(random_access) friend auto operator<(D const& x, D const& y) -> bool { return x - y < 0; } #undef REQUIRE }; template >* = nullptr> class int_iter : public iter_base, random_access_iterator_tag, T> { friend class int_iter::iter_base; T v; auto deref() const -> T { return v; } auto equal(int_iter const& x) const -> bool { return v == x.v; } auto inc() & -> void { ++v; } auto dec() & -> void { --v; } auto advance(ptrdiff_t n) & -> void { v += T(n); } auto dist_to(int_iter const& x) const -> ptrdiff_t { return make_signed_t(x.v - v); } public: int_iter() = default; explicit int_iter(T v) : v(v) {} }; template auto sz(R&& r) -> decltype(ptrdiff_t(size(forward(r)))) { return ptrdiff_t(size(forward(r))); } } // namespace r7h namespace r7h { template >* = nullptr> auto div_floor(T x, T y) -> T { return T(x / y - ((x ^ y) < 0 && x % y)); } template >* = nullptr> auto div_ceil(T x, T y) -> T { return T(x / y + (0 <= (x ^ y) && x % y)); } template auto chmin(T& x, U&& y) -> decltype(x = forward(y), bool(y < x)) { if (y < x) { x = forward(y); return true; } else { return false; } } template auto chmax(T& x, U&& y) -> decltype(x = forward(y), bool(x < y)) { if (x < y) { x = forward(y); return true; } else { return false; } } template >* = nullptr> auto const inf_v = T(numeric_limits::max() / 2); auto const inf = inf_v; } // namespace r7h namespace r7h { auto mt = mt19937_64(LOCAL ? 5489 : _rdtsc()); template >* = nullptr> auto rand(T a, T b) -> T { if constexpr (is_integral_v) { return uniform_int_distribution(a, b)(mt); } else { return uniform_real_distribution(a, b)(mt); } } } // namespace r7h namespace r7h { template class view_base; template using iter_t = decltype(begin(declval())); template using range_cat = typename iterator_traits>::iterator_category; template using range_ref = typename iterator_traits>::reference; #define REQUIRE(I, CATEGORY) \ enable_if_t::iterator_category, CATEGORY##_iterator_tag>>* = nullptr template , input)> class filtered : public view_base> { friend class filtered::view_base; class iter : public iter_base, bidirectional_iterator_tag>, range_ref> { friend class iter::iter_base; filtered const* p; iter_t i; auto deref() const -> range_ref { return *i; } auto equal(iter const& x) const -> bool { return i == x.i; } auto inc() & -> void { do { ++i; } while (i != end(p->r) && !invoke(p->f, *i)); } auto dec() & -> void { do { --i; } while (!invoke(p->f, *i)); } public: iter() = default; explicit iter(filtered const* p, iter_t i) : p(p), i(move(i)) {} }; R r; [[no_unique_address]] F f; auto b() const -> iter { return iter(this, find_if(begin(r), end(r), ref(f))); } auto e() const -> iter { return iter(this, end(r)); } public: explicit filtered(R&& r, F f) : r(forward(r)), f(move(f)) {} }; template filtered(R&&, F) -> filtered; template , input)> class mapped : public view_base> { friend class mapped::view_base; using ref = invoke_result_t>; class iter : public iter_base, random_access_iterator_tag>, ref> { friend class iter::iter_base; mapped const* p; iter_t i; auto deref() const -> ref { return invoke(p->f, *i); } auto equal(iter const& x) const -> bool { return i == x.i; } auto inc() & -> void { ++i; } auto dec() & -> void { --i; } auto advance(ptrdiff_t n) & -> void { i += n; } auto dist_to(iter const& x) const -> ptrdiff_t { return x.i - i; } public: iter() = default; explicit iter(mapped const* p, iter_t i) : p(p), i(move(i)) {} }; R r; [[no_unique_address]] F f; auto b() const -> iter { return iter(this, begin(r)); } auto e() const -> iter { return iter(this, end(r)); } public: explicit mapped(R&& r, F f) : r(forward(r)), f(move(f)) {} }; template mapped(R&&, F) -> mapped; template , input)> class taken : public view_base> { friend class taken::view_base; class iter : public iter_base, range_ref> { friend class iter::iter_base; taken const* p; iter_t i; ptrdiff_t pos; auto deref() const -> range_ref { return *i; } auto equal(iter const& x) const -> bool { return i == x.i; } auto inc() & -> void { ++i; ++pos; if (pos == p->n) { i = end(p->r); } } auto dec() & -> void { --i; --pos; } public: iter() = default; explicit iter(taken const* p, iter_t i, ptrdiff_t pos) : p(p), i(pos == p->n ? end(p->r) : move(i)), pos(pos) {} }; static auto const is_rand = is_convertible_v, random_access_iterator_tag>; R r; ptrdiff_t n; auto b() const -> conditional_t, iter> { if constexpr (is_rand) { return begin(r); } else { return iter(this, begin(r), 0); } } auto e() const -> conditional_t, iter> { if constexpr (is_rand) { return begin(r) + min(n, sz(r)); } else { return iter(this, end(r), -1); } } public: explicit taken(R&& r, ptrdiff_t n) : r(forward(r)), n(max(n, ptrdiff_t(0))) { assert(0 <= n); } }; template taken(R&&, ptrdiff_t) -> taken; template , input)> class dropped : public view_base> { friend class dropped::view_base; R r; ptrdiff_t n; auto b() const -> iter_t { if constexpr (is_convertible_v, random_access_iterator_tag>) { return begin(r) + min(n, sz(r)); } else { auto ret = begin(r); for (auto _ = n; _-- && ret != end(r);) { ++ret; } return ret; } } auto e() const -> iter_t { return end(r); } public: explicit dropped(R&& r, ptrdiff_t n) : r(forward(r)), n(max(n, ptrdiff_t(0))) { assert(0 <= n); } }; template dropped(R&&, ptrdiff_t) -> dropped; template , bidirectional)> class reversed : public view_base> { friend class reversed::view_base; R r; auto b() const -> reverse_iterator> { return make_reverse_iterator(end(r)); } auto e() const -> reverse_iterator> { return make_reverse_iterator(begin(r)); } public: explicit reversed(R&& r) : r(forward(r)) {} }; template reversed(R&&) -> reversed; template reversed(reversed&) -> reversed&>; template reversed(reversed const&) -> reversed const&>; template reversed(reversed&&) -> reversed>; template , input)> class strided : public view_base> { friend class strided::view_base; class iter : public iter_base, range_ref> { friend class iter::iter_base; strided const* p; iter_t i; auto deref() const -> range_ref { return *i; } auto equal(iter const& x) const -> bool { return i == x.i; } auto inc() & -> void { if constexpr (is_convertible_v, random_access_iterator_tag>) { i += min(p->s, ptrdiff_t(end(p->r) - i)); } else { for (auto _ = p->s; _-- && i != end(p->r);) { ++i; } } } auto dec() & -> void { if (i == end(p->r)) { auto n = sz(p->r); std::advance(i, (n - 1) / p->s * p->s - n); } else { std::advance(i, -p->s); } } auto advance(ptrdiff_t n) & -> void { if (n < 0) { dec(); ++n; } i += min(p->s * n, ptrdiff_t(end(p->r) - i)); } auto dist_to(iter const& x) const -> ptrdiff_t { auto d = ptrdiff_t(x.i - i); return d < 0 ? div_floor(d, p->s) : div_ceil(d, p->s); } public: iter() = default; explicit iter(strided const* p, iter_t i) : p(p), i(move(i)) {} }; R r; ptrdiff_t s; auto b() const -> iter { return iter(this, begin(r)); } auto e() const -> iter { return iter(this, end(r)); } public: explicit strided(R&& r, ptrdiff_t s) : r(forward(r)), s(max(s, ptrdiff_t(1))) { assert(1 <= s); } }; template strided(R&&, ptrdiff_t) -> strided; template , input)> class scanned : public view_base> { friend class scanned::view_base; class iter : public iter_base, forward_iterator_tag>, T> { friend class iter::iter_base; scanned const* p; T v; iter_t i; bool past; auto deref() const -> T { return v; } auto equal(iter const& x) const -> bool { return i == x.i && past == x.past; } auto inc() & -> void { if (i == end(p->r)) { past = true; } else { v = invoke(p->op, move(v), *i); ++i; } } public: iter() = default; explicit iter(scanned const* p, T v, iter_t i, bool past) : p(p), v(move(v)), i(move(i)), past(past) {} }; R r; T init; [[no_unique_address]] Op op; auto b() const -> iter { return iter(this, init, begin(r), false); } auto e() const -> iter { return iter(this, T(), end(r), true); } public: explicit scanned(R&& r, T init, Op op) : r(forward(r)), init(move(init)), op(move(op)) {} }; template scanned(R&&, T, Op) -> scanned; template class view_base { auto derived() const -> D const& { return static_cast(*this); } public: auto begin() const -> auto { return derived().b(); } auto end() const -> auto { return derived().e(); } auto empty() const -> bool { return begin() == end(); } explicit operator bool() const { return begin() != end(); } auto size() const -> ptrdiff_t { return ptrdiff_t(distance(begin(), end())); } auto front() const -> decltype(auto) { return *begin(); } auto back() const -> decltype(auto) { return *prev(end()); } auto operator[](ptrdiff_t n) const -> decltype(auto) { return begin()[n]; } template auto filter(F f) const& -> auto { return filtered(derived(), move(f)); } template auto filter(F f) && -> auto { return filtered(static_cast(*this), move(f)); } template auto map(F f) const& -> auto { return mapped(derived(), move(f)); } template auto map(F f) && -> auto { return mapped(static_cast(*this), move(f)); } template auto elements() const& -> auto { return mapped(derived(), LIFT(get)); } template auto elements() && -> auto { return mapped(static_cast(*this), LIFT(get)); } auto keys() const& -> auto { return mapped(derived(), LIFT(get<0>)); } auto keys() && -> auto { return mapped(static_cast(*this), LIFT(get<0>)); } auto values() const& -> auto { return mapped(derived(), LIFT(get<1>)); } auto values() && -> auto { return mapped(static_cast(*this), LIFT(get<1>)); } auto take(ptrdiff_t n) const& -> auto { return taken(derived(), n); } auto take(ptrdiff_t n) && -> auto { return taken(static_cast(*this), n); } auto drop(ptrdiff_t n) const& -> auto { return dropped(derived(), n); } auto drop(ptrdiff_t n) && -> auto { return dropped(static_cast(*this), n); } auto rev() const& -> auto { return reversed(derived()); } auto rev() && -> auto { return reversed(static_cast(*this)); } auto stride(ptrdiff_t s) const& -> auto { return strided(derived(), s); } auto stride(ptrdiff_t s) && -> auto { return strided(static_cast(*this), s); } template > auto scan(T init, Op op = {}) const& -> auto { return scanned(derived(), move(init), move(op)); } template > auto scan(T init, Op op = {}) && -> auto { return scanned(static_cast(*this), move(init), move(op)); } template auto all_of(F f) const -> bool { return std::all_of(begin(), end(), ref(f)); } template auto any_of(F f) const -> bool { return std::any_of(begin(), end(), ref(f)); } template auto each(F f) const -> D const& { for (auto&& e : derived()) { invoke(f, e); } return derived(); } template auto find(F f) const -> ptrdiff_t { return ptrdiff_t(distance(begin(), find_if(begin(), end(), ref(f)))); } template auto adjacent_find(F f) const -> ptrdiff_t { return ptrdiff_t(distance(begin(), std::adjacent_find(begin(), end(), ref(f)))); } template auto transform(F f) const -> D const& { for (auto&& e : derived()) { e = invoke(f, e); } return derived(); } template auto remove(F f) const -> ptrdiff_t { return ptrdiff_t(distance(begin(), remove_if(begin(), end(), ref(f)))); } auto reverse() const -> D const& { std::reverse(begin(), end()); return derived(); } auto rotate(ptrdiff_t n) const -> D const& { std::rotate(begin(), next(begin(), n), end()); return derived(); } auto shuffle() const -> D const& { std::shuffle(begin(), end(), mt); return derived(); } template > auto unique(C comp = {}) const -> ptrdiff_t { return ptrdiff_t(distance(begin(), std::unique(begin(), end(), ref(comp)))); } template auto partition(F f) const -> ptrdiff_t { return ptrdiff_t(distance(begin(), std::partition(begin(), end(), ref(f)))); } template auto stable_partition(F f) const -> ptrdiff_t { return ptrdiff_t(distance(begin(), std::stable_partition(begin(), end(), ref(f)))); } template auto partition_point(F f) const -> ptrdiff_t { return ptrdiff_t(distance(begin(), std::partition_point(begin(), end(), ref(f)))); } template auto max_right(F f) const -> auto { return *prev(std::partition_point(next(begin()), end(), ref(f))); } template auto min_left(F f) const -> auto { return *std::partition_point(begin(), prev(end()), not_fn(ref(f))); } template > auto sort(C comp = {}) const -> D const& { std::sort(begin(), end(), ref(comp)); return derived(); } template > auto stable_sort(C comp = {}) const -> D const& { std::stable_sort(begin(), end(), ref(comp)); return derived(); } template > auto partial_sort(ptrdiff_t n, C comp = {}) const -> D const& { std::partial_sort(begin(), begin() + n, end(), ref(comp)); return derived(); } template > auto nth_element(ptrdiff_t n, C comp = {}) const -> D const& { std::nth_element(begin(), begin() + n, end(), ref(comp)); return derived(); } template > auto lower_bound(T const& val, C comp = {}) const -> ptrdiff_t { return ptrdiff_t(distance(begin(), std::lower_bound(begin(), end(), val, ref(comp)))); } template > auto upper_bound(T const& val, C comp = {}) const -> ptrdiff_t { return ptrdiff_t(distance(begin(), std::upper_bound(begin(), end(), val, ref(comp)))); } template auto binary_search(T const& val) const -> bool { return std::binary_search(begin(), end(), val); } template > auto merge(ptrdiff_t n, C comp = {}) const -> D const& { inplace_merge(begin(), next(begin(), n), end(), ref(comp)); return derived(); } auto min() const -> auto { return *std::min_element(begin(), end()); } auto max() const -> auto { return *std::max_element(begin(), end()); } auto minmax() const -> auto { auto [mn, mx] = std::minmax_element(begin(), end()); return pair(*mn, *mx); } auto min_element() const -> ptrdiff_t { return ptrdiff_t(distance(begin(), std::min_element(begin(), end()))); } auto max_element() const -> ptrdiff_t { return ptrdiff_t(distance(begin(), std::max_element(begin(), end()))); } auto minmax_element() const -> pair { auto [mn, mx] = std::minmax_element(begin(), end()); return pair(ptrdiff_t(distance(begin(), mn)), ptrdiff_t(distance(begin(), mx))); } auto next_permutation() const -> bool { return std::next_permutation(begin(), end()); } auto prev_permutation() const -> bool { return std::prev_permutation(begin(), end()); } template > auto fold(T init, Op op = {}) const -> T { return accumulate(begin(), end(), move(init), ref(op)); } template > auto fold1(Op op = {}) const -> auto { return accumulate(next(begin()), end(), front(), ref(op)); } auto to_vector() const -> auto { return vector(begin(), end()); } auto to_valarray() const -> auto { auto ret = valarray>>(size()); copy(begin(), end(), std::begin(ret)); return ret; } }; template auto operator==(view_base const& x, view_base const& y) -> decltype(bool(*begin(x) == *begin(y))) { return equal(begin(x), end(x), begin(y), end(y)); } template auto operator<(view_base const& x, view_base const& y) -> decltype(bool(*begin(x) < *begin(y)), bool(*begin(y) < *begin(x))) { return lexicographical_compare(begin(x), end(x), begin(y), end(y)); } template , input)> class all : public view_base> { friend class all::view_base; R r; auto b() const -> iter_t { return begin(r); } auto e() const -> iter_t { return end(r); } public: explicit all(R&& r) : r(forward(r)) {} }; template all(R&&) -> all; template class range : public view_base> { friend class range::view_base; I first; I last; auto b() const -> I { return first; } auto e() const -> I { return last; } public: explicit range(I first, I last) : first(move(first)), last(move(last)) {} }; #undef REQUIRE template auto rep(T l, T r) -> range> { return range(int_iter(min(l, r)), int_iter(r)); } template auto rep(T n) -> range> { return rep(0, n); } } // namespace r7h auto main(int argc, char* argv[]) -> int { if (1 < argc) { r7h::mt.seed(std::stoull(argv[1])); } r7h::rep(MULTI_CASES ? r7h::input() : 1).each(r7h::main); } auto r7h::main(int) -> void { auto n = input(); auto m = input(); auto k = input(); auto num = m * i64(n - 1); auto den = n * i64(n - k - 1); auto g = gcd(num, den); num /= g; den /= g; println(num, den); }