#include "registers.h"
#include<bits/stdc++.h>
using namespace std;
namespace sub1{
const int m = 100;
const int b = 2000;
void solve(int s, int n, int k){
if(k == 1){
append_right(1, 0, 1);
append_left(0, 0, b - 1);
append_right(0, 0, b - 1);
append_and(0, 0, 1);
return;
}
auto get_bit = [&] (int t, int x, int i){
append_left(t, x, b - i - 1);
append_right(t, t, b - 1);
};
get_bit(3, 0, 0);
get_bit(1, 0, 1);
get_bit(4, 0, 2);
append_right(2, 0, 3);
append_xor(5, 1, 2);
append_not(5, 5);
append_not(6, 2);
append_and(6, 1, 6);
append_not(7, 4);
append_and(7, 3, 7);
append_and(7, 5, 7);
append_or(6, 7, 6);
append_and(2, 2, 6);
append_and(4, 4, 6);
append_not(6, 6);
append_and(1, 1, 6);
append_and(3, 3, 6);
append_left(0, 1, 1);
append_left(2, 2, 1);
append_add(0, 0, 2);
append_add(0, 0, 3);
append_add(0, 0, 4);
}
}
namespace sub2{
const int m = 100;
const int b = 2000;
void solve(int s, int n, int k){
if(k == 1){
append_right(1, 0, 1);
append_left(0, 0, b - 1);
append_right(0, 0, b - 1);
append_and(0, 0, 1);
return;
}
auto get_bit = [&] (int t, int x, int i){
append_left(t, x, b - i - 1);
append_right(t, t, b - 1);
};
get_bit(1, 0, 0);
get_bit(2, 0, 1);
get_bit(3, 0, 2);
append_right(4, 0, 3);
append_and(5, 2, 4);
append_xor(2, 5, 2);
append_or(1, 1, 2);
append_xor(4, 5, 4);
append_or(3, 3, 4);
append_and(0, 1, 3);
append_left(5, 5, 1);
append_add(0, 0, 5);
}
}
namespace sub3{
const int m = 100;
const int b = 2000;
void solve(int s, int n, int k){
auto copy_number = [&] (int t, int i){
append_left(t, 0, b - (i + 1) * k);
append_right(t, t, b - k);
};
copy_number(1, 0);
for(int i = 1; i < n; i++){
copy_number(2, i);
append_not(3, 2);
append_add(3, 3, 1);
append_right(3, 3, b - 1);
append_left(4, 3, 1);
append_or(3, 3, 4);
append_left(4, 3, 2);
append_or(3, 3, 4);
append_left(4, 3, 4);
append_or(3, 3, 4);
append_left(4, 3, 8);
append_or(3, 3, 4);
append_and(1, 1, 3);
append_not(3, 3);
append_and(2, 2, 3);
append_or(1, 1, 2);
}
append_move(0, 1);
}
}
namespace sub4{
const int m = 100;
const int b = 2000;
void solve(int s, int n, int k){
vector<bool>t(b, false);
for(int i = 0; i < n; i++){
t[(i + 1) * k] = true;
}
append_store(3, t);
while(n > 1){
int cnt = (n + 1) >> 1;
fill(t.begin(), t.end(), false);
fill(t.begin(), t.begin() + cnt * k, true);
append_store(1, t);
append_and(1, 1, 0);
append_right(0, 0, (n - cnt) * k);
append_xor(5, 0, 1);
append_not(4, 1);
append_add(2, 0, 4);
append_xor(2, 2, 5);
append_and(2, 2, 3);
append_right(2, 2, 1);
for(int len = 1; len < k; len <<= 1){
append_right(4, 2, min(len, k - len));
append_or(2, 2, 4);
}
append_and(0, 0, 2);
append_not(2, 2);
append_and(1, 1, 2);
append_or(0, 0, 1);
n = cnt;
}
}
}
namespace sub5{
const int m = 100;
const int b = 2000;
void solve(int s, int n, int k){
auto copy_number = [&] (int t, int i){
append_left(t, 0, b - (i + 1) * k);
append_right(t, t, b - k);
};
for(int _ = 1; _ < n; _++){
for(int i = 1; i < n; i++){
copy_number(1, i - 1);
copy_number(2, i);
append_not(3, 2);
append_add(4, 3, 1);
append_right(4, 4, b - 1);
append_left(5, 4, 1);
append_or(4, 4, 5);
append_left(5, 4, 2);
append_or(4, 4, 5);
append_left(5, 4, 4);
append_or(4, 4, 5);
append_left(5, 4, 8);
append_or(4, 4, 5);
append_and(6, 2, 4);
append_not(4, 4);
append_and(7, 1, 4);
append_or(6, 6, 7);
append_xor(2, 2, 1);
append_xor(2, 2, 6);
append_move(1, 6);
vector<bool>t(b, true);
fill(t.begin() + (i - 1) * k, t.begin() + (i + 1) * k, false);
append_store(6, t);
append_and(0, 0, 6);
append_left(1, 1, i * k);
append_left(2, 2, (i - 1) * k);
append_or(0, 0, 1);
append_or(0, 0, 2);
}
}
}
}
namespace sub6{
const int m = 100;
const int b = 2000;
void solve(int s, int n, int k){
vector<bool>t(b, false);
for(int i = 0; i < n; i++){
t[(i + 1) * k] = true;
}
append_store(3, t);
fill(t.begin(), t.end(), false);
for(int i = 0; i + 1 < n; i += 2){
for(int j = 0; j < k; j++){
t[i * k + j] = true;
}
}
append_store(10, t);
fill(t.begin(), t.end(), false);
for(int i = 1; i + 1 < n; i += 2){
for(int j = 0; j < k; j++){
t[i * k + j] = true;
}
}
append_store(11, t);
for(int _ = (n >> 1) + 1; _ > 0; _--){
for(int p = 0; p < 2; p++){
append_right(1, 0, k);
append_xor(5, 0, 1);
append_not(4, 1);
append_add(2, 0, 4);
append_xor(2, 2, 5);
append_and(2, 2, 3);
append_right(2, 2, 1);
for(int len = 1; len < k; len <<= 1){
append_right(4, 2, min(len, k - len));
append_or(2, 2, 4);
}
append_and(5, 0, 2);
append_not(2, 2);
append_and(6, 1, 2);
append_or(5, 5, 6);
append_and(5, 5, 10 + p);
append_move(6, 5);
append_xor(6, 6, 0);
append_xor(6, 6, 1);
append_and(6, 6, 10 + p);
append_left(6, 6, k);
append_or(5, 5, 6);
if(p == 0){
if(n & 1){
append_right(6, 0, (n - 1) * k);
append_left(6, 6, (n - 1) * k);
append_or(5, 5, 6);
}
}
else{
append_left(6, 0, b - k);
append_right(6, 6, b - k);
append_or(5, 5, 6);
if(~n & 1){
append_right(6, 0, (n - 1) * k);
append_left(6, 6, (n - 1) * k);
append_or(5, 5, 6);
}
}
append_move(0, 5);
}
}
}
}
void construct_instructions(int s, int n, int k, int q){
if(s == 0){
if(n == 2 && k <= 2){
if(q == 1000){
return sub1::solve(s, n, k);
}
return sub2::solve(s, n, k);
}
if(q == 4000){
return sub3::solve(s, n, k);
}
return sub4::solve(s, n, k);
}
if(n <= 10 && q == 4000){
return sub5::solve(s, n, k);
}
return sub6::solve(s, n, k);
}