#include "vision.h"
/*
* Author: Nonoze
* Created: Thursday 05/03/2026
*/
#include <bits/stdc++.h>
using namespace std;
#ifndef DEBUG
#define dbg(...)
#endif
// #define cout cerr << "OUT: "
// #define endl '\n'
#define endlfl '\n' << flush
#define quit(x) return (void)(cout << x << endl)
template<typename T> void read(T& x) { cin >> x; }
template<typename T1, typename T2> void read(pair<T1, T2>& p) { read(p.first), read(p.second); }
template<typename T> void read(vector<T>& v) { for (auto& x : v) read(x); }
template<typename T1, typename T2> void read(T1& x, T2& y) { read(x), read(y); }
template<typename T1, typename T2, typename T3> void read(T1& x, T2& y, T3& z) { read(x), read(y), read(z); }
template<typename T1, typename T2, typename T3, typename T4> void read(T1& x, T2& y, T3& z, T4& zz) { read(x), read(y), read(z), read(zz); }
template<typename T> void print(vector<T>& v) { for (auto& x : v) cout << x << ' '; cout << endl; }
#define sz(x) (int)(x.size())
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define make_unique(v) sort(all(v)), v.erase(unique(all(v)), (v).end())
#define pb push_back
#define mp(a, b) make_pair(a, b)
#define fi first
#define se second
#define cmin(a, b) a = min(a, b)
#define cmax(a, b) a = max(a, b)
#define YES cout << "YES" << endl
#define NO cout << "NO" << endl
#define QYES quit("YES")
#define QNO quit("NO")
int zero, one;
pair<vector<int>, vector<int>> calc(vector<int> v) {
int n=sz(v);
vector<int> ans1, ans2;
for (int bit=1; bit<n; bit*=2) {
vector<int> cur;
for (int i=0; i<n; i++) {
vector<int> vec;
for (int j=i+1; j<n; j++) {
if (((j-i)&bit)==bit) {
vec.pb(v[j]);
}
}
if (!vec.empty()) {
int x=add_or(vec);
cur.pb(add_and({v[i], x}));
}
}
if (cur.empty()) {
ans1.pb(zero);
ans2.pb(one);
continue;
}
ans1.pb(add_or(cur));
ans2.pb(add_not(ans1.back()));
}
return {ans1, ans2};
}
void construct_network(int n, int m, int k) {
if (n+m==2) {
add_or({0, 1});
return;
}
zero=add_and({0, 1, 2});
one=add_not(zero);
vector<int> lines, columns;
for (int i=0; i<n; i++) {
vector<int> cur;
for (int j=0; j<m; j++) {
cur.pb(i*m+j);
}
lines.pb(add_or(cur));
}
for (int j=0; j<m; j++) {
vector<int> cur;
for (int i=0; i<n; i++) {
cur.pb(i*m+j);
}
columns.pb(add_or(cur));
}
auto l=calc(lines), c=calc(columns);
vector<int> ans;
for (int i=0; i<min(n, k+1); i++) {
vector<int> must_have;
for (int bit=1, cnt=0; bit<n; bit*=2, cnt++) {
if ((i&bit)) {
must_have.pb(l.fi[cnt]);
} else {
must_have.pb(l.se[cnt]);
}
}
int left=k-i;
for (int bit=1, cnt=0; bit<m; bit*=2, cnt++) {
if ((left&bit)) {
must_have.pb(c.fi[cnt]);
} else {
must_have.pb(c.se[cnt]);
}
}
if ((m==1 && left!=0) || (n==1 && i!=0)) {
ans.pb(zero);
continue;
}
assert(!must_have.empty());
ans.pb(add_and(must_have));
}
add_or(ans);
return;
}