#include "Azer.h"
#include <vector>
#include <bits/stdc++.h>
using namespace std;
const int NODE=11, DIST=20, DISTINF=1e6+5, NODEINF=1004;
namespace {
int n, cnt, msg, num, tot;
vector<bool> in;
vector<int> pot;
vector<vector<pair<int,int>>> al;
}
void InitA(int N, int A, std::vector<int> U, std::vector<int> V,
std::vector<int> C) {
n=N;
cnt = 0, num=0, tot=0;
in.resize(n, 0);
in[0]=1;
pot.resize(n, DISTINF);
pot[0]=0;
al.resize(n);
for(int i=0;i<A;i++){
al[U[i]].push_back({V[i], C[i]});
al[V[i]].push_back({U[i], C[i]});
}
for(auto [to, cost] : al[0]){
pot[to]=min(pot[to], cost);
}
}
void sendbestA(int dist, int nw){
// find best in A's side
// compare with B's side.
pair<int,int> mn={DISTINF, NODEINF};
for(int i=0;i<n;i++){
if(in[i])continue;
mn=min(mn, {pot[i], i});
}
//printf("best on A side : dist %d, node %d \n B side: %d, %d\n", mn.first, mn.second, dist, nw);
mn=min(mn, {dist, nw});
// relax on A's side.
in[mn.second]=1;
pot[mn.second] = mn.first;
for(auto [to, cost] : al[mn.second]){
if(in[to])continue;
pot[to]=min(pot[to], pot[mn.second] + cost);
}
num++;
if(num == n-1) return;
// send the better dude
for(int i=0;i<NODE;i++){
SendA(!!(mn.second&(1<<i)));
}
for(int i=0;i<DIST;i++){
SendA(!!(mn.first&(1<<i)));
}
}
void ReceiveA(bool x) {
if(x) msg |= (1<<cnt);
cnt++, tot++;
if(tot > 58000) return;
if(cnt == NODE+DIST){
int nw=msg & ((1<<NODE)-1);
int dist= msg >> NODE;
msg=0, cnt=0;
sendbestA(dist, nw);
}
}
vector<int> Answer() {
return pot;
}
#include "Baijan.h"
#include <vector>
#include <bits/stdc++.h>
using namespace std;
const int NODE=11, DIST=20, DISTINF=1e6+5, NODEINF=1004;
namespace {
int n, cnt, msg;
vector<bool> in;
vector<int> pot;
vector<vector<pair<int,int>>> al;
}
void sendbestB(int dist, int nw){
//printf("b side, fixed dist %d, node %d\n", dist, nw);
in[nw]=1;
pot[nw]=dist;
for(auto [to, cost] : al[nw]){
if(in[to])continue;
pot[to]=min(pot[to], pot[nw] + cost);
}
pair<int,int> mn={DISTINF, NODEINF};
for(int i=0;i<n;i++){
if(in[i])continue;
mn=min(mn, {pot[i], i});
}
for(int i=0;i<NODE;i++){
SendB(!!(mn.second&(1<<i)));
}
for(int i=0;i<DIST;i++){
SendB(!!(mn.first&(1<<i)));
}
}
void InitB(int N, int B, std::vector<int> S, std::vector<int> T,
std::vector<int> D) {
n=N;
cnt = 0;
in.resize(n, 0);
in[0]=1;
pot.resize(n, DISTINF);
al.resize(n);
for(int i=0;i<B;i++){
al[S[i]].push_back({T[i], D[i]});
al[T[i]].push_back({S[i], D[i]});
}
if(n==1) return;
sendbestB(0, 0);
}
void ReceiveB(bool y) {
if(y) msg |= (1<<cnt);
cnt++;
if(cnt == NODE+DIST){
int nw = msg & ((1<<NODE)-1);
int dist= msg >> NODE;
cnt=0, msg=0;
sendbestB(dist, nw);
}
}