#include "vision.h"
#include<bits/stdc++.h>
using namespace std;
typedef int ll;
typedef pair<ll, ll> pll;
ll h, w;
ll idx_at_memory(ll i, ll j){
return i * w + j;
}
ll test_dist(ll k, ll n, ll &c, vector<ll> v){
vector<ll> indexes;
for(ll i = 0; i + k < n; i++) {
add_and({v[i], v[i+k]});
indexes.push_back(c++);
}
if(indexes.empty()) return 0;
add_or(indexes); c++;
return c-1;
}
void construct_network(int H, int W, int k) {
h = H, w = W;
vector<ll> row_idx(h), col_idx(w);
ll c = h*w;
for(ll i = 0; i < h; i++) {
vector<ll> v;
for(ll j = 0; j < w; j++) v.push_back(idx_at_memory(i, j));
add_or(v);
row_idx[i] = c++;
}
for(ll j = 0; j < w; j++){
vector<ll> v;
for(ll i = 0; i < h; i++) v.push_back(idx_at_memory(i, j));
add_or(v);
col_idx[j] = c++;
}
vector<pll> p;
for(ll l = 1; l < k; l++){
ll x = test_dist(l, h, c, row_idx), y = (test_dist(k - l, w, c, col_idx));
if(!x || !y) continue;
p.push_back({x, y});
}
add_xor(row_idx);
ll x = c++;
ll y = test_dist(k, w, c, col_idx);
if(y) p.push_back({x, y});
add_xor(col_idx);
x = c++;
y = test_dist(k, h, c, row_idx);
if(y) p.push_back({x, y});
vector<ll> final_indexes;
for(auto[a, b]: p){
add_and({a, b}); final_indexes.push_back(c++);
}
add_or(final_indexes);
//c++
}