#include<bits/stdc++.h>
using namespace std;
void SendA(bool y);
int baseDistA=0;
vector<int> DistanceA;
vector<priority_queue<pair<int,int>>> EdgesA;
pair<int,int> OPTIM;
int DistTempA=0;
int stateA=0;
int valueA=0;
int transA=0;
pair<int,int> GetClosest(vector<int>& Distance,vector<priority_queue<pair<int,int>>>& Edges){
pair<int,int> OPT={1000000000,1000000000};
for(int i=0;i<Distance.size();i++){
if(Distance[i]!=-1){
while(!Edges[i].empty() && Distance[Edges[i].top().second]!=-1){
Edges[i].pop();
}
if(!Edges[i].empty()){
pair<int,int> SOL={-Edges[i].top().first+Distance[i],Edges[i].top().second};
OPT=min(OPT,SOL);
}
}
}
return OPT;
}
void InitA(int N, int A, std::vector<int> U, std::vector<int> V, std::vector<int> C){
DistanceA=vector<int>(N,-1);
DistanceA[0]=0;
for(int i=0;i<A;i++){
EdgesA[U[i]].push({-C[i],V[i]});
EdgesA[V[i]].push({-C[i],U[i]});
}
OPTIM=GetClosest(DistanceA,EdgesA);
}
void ReceiveA(bool x){
if(OPTIM==(pair<int,int>){1000000000,1000000000}){
return;
}
if(stateA==0){
if(x){
valueA=valueA | (1<<transA);
}
transA++;
if(transA==9){
if(OPTIM.first-baseDistA<valueA){
SendA(false);
for(int i=0;i<9;i++){
if(((OPTIM.first-baseDistA) & (1<<i))==0){
SendA(false);
}
else{
SendA(true);
}
}
baseDistA=OPTIM.first;
DistanceA[OPTIM.second]=OPTIM.first;
for(int i=0;i<12;i++){
if((OPTIM.second & (1<<i))==0){
SendA(false);
}
else{
SendA(true);
}
}
OPTIM=GetClosest(DistanceA,EdgesA);
}
else{
stateA=1;
DistTempA=valueA;
SendA(true);
}
transA=0;
valueA=0;
}
}
else{
if(x){
valueA=valueA | (1<<transA);
}
transA++;
if(transA==12){
DistanceA[valueA]=DistTempA+baseDistA;
baseDistA+=DistTempA;
transA=0;
valueA=0;
stateA=0;
}
}
}
std::vector<int> Answer(){
return DistanceA;
}
#include<bits/stdc++.h>
using namespace std;
void SendB(bool y);
vector<int> DistanceB;
vector<priority_queue<pair<int,int>>> EdgesB;
int baseDistB=0;
int stateB=0;
int valueB=0;
int transB=0;
int tempB=0;
pair<int,int> GetClosestB(vector<int>& Distance,vector<priority_queue<pair<int,int>>>& Edges){
pair<int,int> OPT={1000000000,1000000000};
for(int i=0;i<Distance.size();i++){
if(Distance[i]!=-1){
while(!Edges[i].empty() && Distance[Edges[i].top().second]!=-1){
Edges[i].pop();
}
if(!Edges[i].empty()){
pair<int,int> SOL={-Edges[i].top().first+Distance[i],Edges[i].top().second};
OPT=min(OPT,SOL);
}
}
}
return OPT;
}
void InitB(int N, int B, std::vector<int> U, std::vector<int> V, std::vector<int> C){
DistanceB=vector<int>(N,-1);
DistanceB[0]=0;
for(int i=0;i<B;i++){
EdgesB[U[i]].push({-C[i],V[i]});
EdgesB[V[i]].push({-C[i],U[i]});
}
pair<int,int> A=GetClosestB(DistanceB,EdgesB);
for(int i=0;i<9;i++){
if((A.first & (1<<i))==0){
SendB(false);
}
else{
SendB(true);
}
}
}
void ReceiveB(bool x){
if(stateB==0){
if(x){
pair<int,int> A=GetClosest(DistanceB,EdgesB);
for(int i=0;i<12;i++){
if((A.second & (1<<i))==0){
SendB(false);
}
else{
SendB(true);
}
}
baseDistB=A.first;
DistanceB[A.second]=A.first;
A=GetClosestB(DistanceB,EdgesB);
for(int i=0;i<9;i++){
if(((A.first-baseDistB) & (1<<i))==0){
SendB(false);
}
else{
SendB(true);
}
}
}else{
stateB=1;
}
}
else if(stateB==1){
if(x){
valueB=valueB | (1<<transB);
}
transB++;
if(transB==9){
tempB=valueB;
valueB=0;
transB=0;
stateB=2;
}
}
else{
if(x){
valueB=valueB | (1<<transB);
}
transB++;
if(transB==12){
baseDistB+=tempB;
DistanceB[valueB]=baseDistB;
valueB=0;
transB=0;
stateB=0;
}
}
}