#pragma GCC optimize("O3,unroll-loops")
// #pragma GCC target("avx2,bmi,bmi2,popcnt,lzcnt")
#if __has_include("bits/extc++.h")
#include <bits/extc++.h>
#define HAS_BITS_EXTC
#else
#include <bits/stdc++.h>
#endif
#define force_inline inline __attribute__((always_inline))
using namespace std;
// Rand
mt19937_64 rng((uint64_t)chrono::high_resolution_clock::now().time_since_epoch().count());
template<typename A, typename = enable_if_t<__is_integer<A>::__value>> [[maybe_unused]] A rand(A max) { uniform_int_distribution<A> dist(0, max - 1); return dist(rng); } // returns a random number in [0;max)
// PBDS
#ifndef HAS_BITS_EXTC
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#endif
using namespace __gnu_pbds;
#if (__cplusplus >= 202002L) // if c++20 or newer version
template<class L, class R=L> concept less_than_operator = requires(const L& lhs, const R& rhs) { { lhs < rhs } -> same_as<bool>; };
template<class L, class R=L> concept less_equal_to_operator = requires(const L& lhs, const R& rhs) { { lhs <= rhs } -> same_as<bool>; };
template<typename A, typename B = null_type> requires less_than_operator<A> using pbds = tree<A, B, less<A>, rb_tree_tag, tree_order_statistics_node_update>;
template<typename A, typename B = null_type> requires less_equal_to_operator<A> using multi_pbds = tree<A, B, less_equal<A>, rb_tree_tag, tree_order_statistics_node_update>;
#else
template<typename A, typename B = null_type> using pbds = tree<A,B,less<A>,rb_tree_tag, tree_order_statistics_node_update>;
template<typename A, typename B = null_type> using multi_pbds = tree<A,B,less_equal<A>,rb_tree_tag, tree_order_statistics_node_update>;
#endif
// Hash_table
template<typename Key, typename Hash_Fn>
struct chash {
public:
inline static Hash_Fn hash;
inline static uint64_t RANDOM = (uint64_t)(std::make_unique<char>().get()) ^ rng();
static uint64_t splitmix64(uint64_t x) {
x += 0x9e3779b97f4a7c15;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}
size_t operator()(Key x) const {
return (size_t)splitmix64((uint64_t)hash(x) ^ RANDOM);
}
};
template<typename Key, typename Value = null_type, typename Hash_Fn = tr1::hash<Key>> using hash_table [[maybe_unused]] = gp_hash_table<Key, Value, chash<Key, Hash_Fn>, equal_to<Key>, direct_mask_range_hashing<>, linear_probe_fn<>, hash_standard_resize_policy<hash_exponential_size_policy<>, hash_load_check_resize_trigger<>, true>>;
// typedef
[[maybe_unused]] typedef int8_t i8;
[[maybe_unused]] typedef int16_t i16;
[[maybe_unused]] typedef int64_t i64;
[[maybe_unused]] typedef int32_t i32;
[[maybe_unused]] typedef uint8_t u8;
[[maybe_unused]] typedef uint16_t u16;
[[maybe_unused]] typedef uint32_t u32;
[[maybe_unused]] typedef uint64_t u64;
[[maybe_unused]] typedef float f32;
[[maybe_unused]] typedef double f64;
#if (__SIZEOF_LONG_DOUBLE__ > __SIZEOF_DOUBLE__)
[[maybe_unused]] typedef long double f80;
#endif
#ifdef __SIZEOF_INT128__
[[maybe_unused]] typedef __int128_t i128;
[[maybe_unused]] typedef __uint128_t u128;
#endif
#ifdef __SIZEOF_FLOAT128__
[[maybe_unused]] typedef __float128 f128;
#endif
// utils
constexpr pair<i32, i32> GridMoves4[] = {{-1,0},{1,0},{0,-1},{0,1}};
constexpr pair<i32, i32> GridMoves8[] = {{1,0},{0,1},{-1,0},{0,-1},{1,-1},{1,1},{-1,-1},{-1,1}};
template<typename T> [[maybe_unused]] bool InB(T x, pair<T, T> bounds) { return x >= bounds.first && x < bounds.second; } // In bounds [bounds.first, bounds.second)
template <typename T> [[maybe_unused]] void clear(T& x) { memset(x, 0, sizeof(x)); }
template<typename A> force_inline A* startVectorOrArray(A* X, [[maybe_unused]] i32 _) { return X; }
template<typename A> force_inline auto startVectorOrArray(A&& X) -> decltype(begin(X)) { return begin(X); }
template<typename A> force_inline A* endVectorOrArray(A* X, i32 size) { return X + size; }
template<typename A> force_inline auto endVectorOrArray(A&& X) -> decltype(end(X)) { return end(X); }
// I/O
template<typename A> struct ElementWithSeparator {A data; string separator;};
template<typename T_container, typename = enable_if_t<!is_same<T_container, string>::value, typename T_container::value_type>> ElementWithSeparator<T_container> operator , (T_container first, string sep) { return ElementWithSeparator<T_container>{first, sep}; }
template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) { return os << p.first << " " << p.second; }
template<typename T_container, typename = enable_if_t<!is_same<T_container, string>::value, typename T_container::value_type>> ostream& operator<<(ostream &os, const T_container &v) { string sep; for (const auto &x : v) {os << sep << x; sep = " ";} return os; }
template<typename T_container, typename = enable_if_t<!is_same<T_container, string>::value, typename T_container::value_type>> ostream& operator<<(ostream &os, const ElementWithSeparator<T_container> &v) {string sep; for (const auto &x : v.data) {os << sep; os << x; sep = v.separator;} return os; }
template<typename T_container, typename = enable_if_t<!is_same<T_container, string>::value, typename T_container::value_type>> istream& operator>>(istream &is, T_container &v) { for (auto &x : v) cin >> x; return is; }
template<typename A, typename B> istream& operator>>(istream &is, pair<A, B> &p) { return is >> p.first >> p.second; }
template<typename ...A> istream& operator>>(istream &is, tuple<A...> &t) { apply([&is](auto&&... args) {((is >> args), ...);}, t); return is; }
template<typename ...A> ostream& operator<<(ostream &os, tuple<A...> &t) { string sep; apply([&os, &sep](auto&&... args){(((os << sep << args), (sep = " ")), ...);}, t); return os; }
// Fast power
template<typename A, typename B, typename = enable_if_t<(__is_floating<A>::__value || __is_integer<A>::__value) && __is_integer<B>::__value>> A customPow(A base, B power) { if (power == 0) return 1; if (power&1) return base * customPow(base*base, power>>1); return customPow(base*base, power>>1); };
template<typename A, typename B, typename C, typename = enable_if<__is_integer<A>::__value && __is_integer<B>::__value && __is_integer<C>::__value>> A customPow(A base, B power, C mod) { if (power == 0) return 1; if (power&1) return (base*customPow((base*base)%mod, power>>1, mod))%mod; return customPow((base*base)%mod, power>>1, mod); };
template<typename A, typename B, typename = enable_if_t<!((__is_floating<A>::__value || __is_integer<A>::__value) && __is_integer<B>::__value)>> auto customPow(A base, B power) { return pow(base, power); }
// Min/Max
template<typename T, typename... Args> constexpr T min(T first, Args... args) { if constexpr (sizeof...(args) == 0) { return first; } else { T rest_min = ::min(args...); return first < rest_min ? first : rest_min; }}
template<typename T, typename... Args> constexpr T max(T first, Args... args) { if constexpr (sizeof...(args) == 0) { return first; } else { T rest_max = ::max(args...); return first > rest_max ? first : rest_max; }}
// INF
template <class T>
constexpr T inf = 0;
template <> constexpr i32 inf<i32> = 1'010'000'000;
template <> constexpr u32 inf<u32> = 1'010'000'000;
template <> constexpr i64 inf<i64> = 2'020'000'000'000'000'000;
template <> constexpr u64 inf<u64> = 2'020'000'000'000'000'000;
#ifdef __SIZEOF_INT128__
template <> constexpr i128 inf<i128> = static_cast<i128>(inf<i64>) * 2'000'000'000'000'000'000;
template <> constexpr u128 inf<u128> = static_cast<u128>(inf<i64>) * 2'000'000'000'000'000'000;
#endif
template <> constexpr f64 inf<f64> = f64(inf<i64>);
#if (__SIZEOF_LONG_DOUBLE__ > __SIZEOF_DOUBLE__)
template <> constexpr f80 inf<f80> = inf<i64>;
#endif
// Debug
#ifdef LOCAL
#define debug(x) cerr << "\033[91mLine " << __LINE__ << ": " << "\033[97m" << #x << " = " << (x) << "\033[0m" << endl
struct auto_timer {
chrono::system_clock::time_point start;
auto_timer() : start(chrono::system_clock::now()) {}
~auto_timer() {
chrono::duration<long double, milli> total = chrono::system_clock::now() - start;
clog << total.count() << "ms\n";
}
};
#else
#define debug(x)
typedef int auto_timer;
#endif
// Defines
#define endl '\n'
#define elif else if
#define all(...) startVectorOrArray(__VA_ARGS__), endVectorOrArray(__VA_ARGS__)
#define rall(...) make_reverse_iterator(endVectorOrArray(__VA_ARGS__)), make_reverse_iterator(startVectorOrArray(__VA_ARGS__))
#define pow(...) customPow(__VA_ARGS__)
#define forind(v, ...) if (size_t v = -1) for (__VA_ARGS__) if ((++v, true))
#define flush() cout.flush()
#define precision(x) cout << fixed << showpoint << setprecision(x)
#define mp(...) make_pair(__VA_ARGS__)
#define mt(...) make_tuple(__VA_ARGS__)
#define min min
#define max max
#define GridMoves4 auto [dx, dy] : GridMoves4
#define GridMoves8 auto [dx, dy] : GridMoves8
i32 queryRes(i32 s, i32 a, i32 b) {
i32 cnt = 0;
i32 c0 = 0;
for (i32 i = a; i < b; i++) {
if (s & (1L << i)) {
cnt += c0;
} else {
c0++;
}
}
return cnt;
}
const int N = 20; //21 fails
auto Query = new i32[1 << N][N][N+1];
void TestCase() {
bool failed = false;
vector<i32> A[N+1];
for (i32 i = 0; i < (1 << N); i++) {
for (i32 j = 0; j < N; j++) {
for (i32 k = 0; k <= N; k++) {
Query[i][j][k] = queryRes(i, j, k);
}
}
}
A[0].push_back(0);
for (i32 i = 1; i < (1 << N); i++) {
A[__popcount(i)].push_back(i);
}
for (i32 ones = 1; ones <= N; ones++) {
map<i32, vector<i32>> m;
for (auto x : A[ones]) {
i32 cnt = 0;
for (i32 i = 0; i < N; i++) {
if (x & (1 << i)) {
cnt += i;
} else {
}
}
m[cnt].push_back(x);
}
for (auto T : m) {
auto tmp = T.second;
bool flag = false;
for (i32 i = 0; i < N; i++) {
for (i32 j = i+1; j <= N; j++) {
cout << ones << ' ' << T.first << ' ' << i << ' ' << j << endl;
flush();
map<i32, vector<i32>> m2;
bool flag2 = true;
for (auto x : tmp) {
m2[Query[x][i][j]].push_back(x);
}
for (auto T2 : m2) {
auto tmp2 = T2.second;
bool flag3 = false;
for (i32 i2 = 0; i2 < N; i2++) {
for (i32 j2 = i2+1; j2 <= N; j2++) {
map<i32, vector<i32>> m3;
for (auto x : tmp2) {
m3[Query[x][i2][j2]].push_back(x);
}
bool flag4 = true;
for (auto T3 : m3) {
auto tmp3 = T3.second;
bool flag5 = false;
for (i32 i3 = 0; i3 < N; i3++) {
for (i32 j3 = i3+1; j3 <= N; j3++) {
map<i32, vector<i32>> m4;
for (auto x : tmp3) {
m4[Query[x][i3][j3]].push_back(x);
}
bool flag6 = true;
for (auto T4 : m4) {
auto tmp4 = T4.second;
bool flag7 = false;
bitset<500> S;
for (i32 i4 = 0; i4 < N; i4++) {
for (i32 j4 = i4+1; j4 <= N; j4++) {
bool tmpflag = true;
for (auto x : tmp4) {
i32 t = Query[x][i4][j4];
if (S[t]) {
tmpflag = false;
break;
}
S[t] = true;
}
S.reset();
if (tmpflag) {
flag7 = true;
goto FLAG7TRUE;
}
}
}
FLAG7TRUE:
if (!flag7) {
flag6 = false;
break;
}
}
if (flag6) {
flag5 = true;
goto FLAG5TRUE;
}
}
}
FLAG5TRUE:
if (!flag5) {
flag4 = false;
break;
}
}
if (flag4) {
flag3 = true;
goto FLAG3TRUE;
}
}
}
FLAG3TRUE:
if (!flag3) {
flag2 = false;
break;
}
}
if (flag2) {
flag = true;
goto FLAG1TRUE;
}
}
}
FLAG1TRUE:
if (!flag) {
cout << "Fail\n" << tmp << endl;
failed = true;
}
}
}
if (failed) {
cout << "Failed\n";
} else {
cout << "Correct\n";
}
}
int32_t main() {
[[maybe_unused]] auto_timer time;
// freopen("../output.txt", "w", stdout);
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cin.exceptions(ios_base::iostate(((u32)ios_base::failbit) | ((u32)ios_base::badbit))); // ios_base::failbit | ios_base::badbit
uint32_t t = 1;
// cin >> t;
for (uint32_t i = 1; i <= t; ++i) {
// cout << "Case #" << i << ": ";
TestCase();
}
return 0;
}