Problem:
Problem C:
Disarmament of the Units
This is a story in a country far away. In this country, two armed groups, ACM and ICPC, have
fought in the civil war for many years. However, today October 21, reconciliation was approved
between them; they have marked a turning point in their histories.
In this country, there are a number of roads either horizontal or vertical, and a town is built on
every endpoint and every intersection of those roads (although only one town is built at each
place). Some towns have units of either ACM or ICPC. These units have become unneeded
by the reconciliation. So, we should make them disarm in a verifiable way simultaneously. All
disarmament must be carried out at the towns designated for each group, and only one unit can
be disarmed at each town. Therefore, we need to move the units.
The command of this mission is entrusted to you. You can have only one unit moved by a
single order, where the unit must move to another town directly connected by a single road.
You cannot make the next order to any unit until movement of the unit is completed. The unit
cannot pass nor stay at any town another unit stays at. In addition, even though reconciliation
was approved, members of those units are still irritable enough to start battles. For these
reasons, two units belonging to different groups may not stay at towns on the same road. You
further have to order to the two groups alternatively, because ordering only to one group may
cause their dissatisfaction. In spite of this restriction, you can order to either group first.
Your job is to write a program to find the minimum number of orders required to complete the
mission of disarmament.
Input
The input consists of multiple datasets. Each dataset has the following format:
n m
A
m
I
rx
1,1
ry
1,1
rx
1,2
ry
1,2
...
rx
n
,1
ry
n
,1
rx
n
,2
ry
n
,2
sx
A
,1
sy
A
,1
...
sx
A
,
m
A
sy
A
,
m
A
sx
I
,1
sy
I
,1
...
sx
I
,
m
I
sy
I
,
m
I
tx
A
,1
ty
A
,1
...
tx
A
,
m
A
ty
A
,
m
A
tx
I
,1
ty
I
,1
...
tx
I
,
m
I
ty
I
,
m
I
n
is the number of roads.
m
A
and
m
I
are the number of units in ACM and ICPC respectively
(
m
A
> 0,
m
I
> 0,
m
A
+
m
B
< 8). (
rx
i
,1
,
ry
i
,1
) and (
rx
i
,2
,
ry
i
,2
) indicate the two endpoints of the
i
-th road, which is always parallel to either
x
-axis or
y
-axis. A series of (
sx
A
,
i
,
sy
A
,
i
) indicates
the coordinates of the towns where the ACM units initially stay, and a series of (
sx
I
,
i
,
sy
I
,
i
)
indicates where the ICPC units initially stay. A series of (
tx
A
,
i
,
ty
A
,
i
) indicates the coordinates
of the towns where the ACM units can be disarmed, and a series of (
tx
I
,
i
,
ty
I
,
i
) indicates where
the ICPC units can be disarmed.
You may assume the following:
the number of towns, that is, the total number of coordinates where endpoints and/or
  intersections of the roads exist does not exceed 18;
no two horizontal roads are connected nor ovarlapped; no two vertical roads, either;
all the towns are connected by roads; and
no pair of ACM and 
...(truncated)

Submitted solutions:

code_snippet: #include<iostream>
#include<complex>
#include<map>
#include<algorithm>
#include<set>
#include<queue>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
#define pb push_back
#define mp make_pair
#define ALL(c)   (c).begin(),(c).end()

typedef complex<int> P;
typedef pair<P,P>    Line;
typedef unsigned long long ull;

const int N = 20;

namespace std{
  bool operator<(const P &a,const P &b){
    if (a.real() != b.real())return a.real() < b.real();
    return a.imag() < b.imag();
  }
}

bool isp(P a,P b,P c){
  complex<double> A(a.real(),a.imag()),B(b.real(),b.imag()),C(c.real(),c.imag());
  return abs(A-C)+abs(B-C) < abs(A-B) + 1e-10;
}

bool isptable[N][N][N];
bool edge[N][N];

enum {icpcgoal=0,acmgoal=1,els=2};
enum {icpc=0,acm=1};
int isgoal[N];

bool isicpc[8];
class state{
public:
  int n;
  int goal;
  short cnt;
  bool lastmove;
  short node[8];
  ull st;
  bool isclear();
  void makest();
  bool isvalid(int,int,vector<P>&);
  bool operator<(const state& a)const;
};

bool state::operator<(const state& a)const{
  return st < a.st;
}

bool state::isclear(){
  int cnt =0;
  rep(i,n){
    if      (isicpc[i] &&isgoal[node[i]]==icpcgoal)cnt++;
    else if (!isicpc[i]&&isgoal[node[i]]==acmgoal )cnt++;
  }
  return cnt == n;
}

bool state::isvalid(int ii,int prev,vector<P>&p){
  rep(i,n){
    if (i == ii)continue;
    if (isptable[prev][node[ii]][node[i]])
      return false;
  }
  rep(i,n){
    REP(j,i+1,n){
      if (node[i] == node[j])return false;
      if (isicpc[i] != isicpc[j] &&
	  edge[node[i]][node[j]])return false;
    }
  }
  return true;
}

void state::makest(){
  st=lastmove;
  rep(i,n){
    st=st*18 + node[i];
  }
}

int bfs(int n,state ini,vector<P> &node,int ma){
  queue<state> Q;  
  set<ull> S;
  ini.lastmove=icpc;
  ini.makest();
  Q.push(ini);
  S.insert(ini.st);
  ini.lastmove=acm;
  ini.makest();
  Q.push(ini);
  S.insert(ini.st);
  if (ini.isclear())return 0;

  while(!Q.empty()){
    state now = Q.front();Q.pop();
    int curmove=now.lastmove==icpc?acm:icpc;
    rep(i,now.n){
      if (curmove==icpc && !isicpc[i])continue;
      if (curmove==acm  && isicpc[i])continue;
      rep(j,n){
	if (!edge[now.node[i]][j])continue;
	state next = now;
	next.cnt++;
	next.lastmove=curmove;
	next.node[i]=j;
	if  (!next.isvalid(i,now.node[i],node))continue;
	sort(next.node,next.node+ma);
	sort(next.node+ma,next.node+next.n);
	next.makest();
	if (S.find(next.st) == S.end()){
	  if (next.isclear()){
	    return next.cnt;
	  }
	  S.insert(next.st);
	  Q.push(next);
	}
      }
    }    
  }
  return -1;
}

int getindex(P &a,map<P,int> &M){
  int index = M.size();
  if (M.find(a) == M.end())M[a]=index;
  return M[a];
}

void make_intersection(vector<Line> ver,vector<Line>hor, map<P,int> &M){
  rep(i,ver.size()){
    rep(j,hor.size()){
      if (ver[i].first.imag()  <= hor[j].first.imag() &&
	  ver[i].second.imag() >= hor[j].first.imag() &&
	  hor[j].first.real()  <= ver[i].first.real() &&
	  hor[j].second.real() >= ver[i].first.real()){
	P ins(ver[i].first.real(),hor[j].first.imag());
	getindex(ins,M);
      }
    }
  }
}

void make_graph(vector<P> node,vector<Line> ver,
		map<P,int> M){
  rep(i,ver.size()){
    vector<int> connect;
    rep(j,node.size()){
      if (isptable[M[ver[i].first]][M[ver[i].second]][j]){
	connect.pb(M[node[j]]);
      }
    }
    rep(j,connect.size()){
      REP(k,j+1,connect.size()){
	edge[connect[j]][connect[k]]=edge[connect[k]][connect[j]]=true;
      }
    }
  }
}

main(){
  int n,ma,mi;
  while(cin>>n>>ma>>mi && n){
    rep(i,N){
      rep(j,N)edge[i][j]=false;
      isgoal[i]=els;
    }
    rep(i,N)rep(j,N)rep(k,N)isptable[i][j][k]=false;
    vector<Line> hor,ver;
    map<P,int> M;
    rep(i,n){
      Line ins;
      cin>>ins.first.real()>>ins.first.imag()
	 >>ins.second.real()>>ins.second.imag();
      getindex(ins.first,M);
      getindex(ins.second,M);
      if (ins.second < ins.first)swap(ins.first,ins.second);
      if (ins.first.real() == ins.second.real())ver.pb(ins);
      else hor.pb(ins);
    }
    
    state ini;
    ini.cnt=0;
    ini.n=ma+mi;
    ini.goal=0;
    rep(i,ma){
      P a;
      cin>>a.real()>>a.imag();
      isicpc[i]=false;
      ini.node[i]  =getindex(a,M);
    }
    rep(i,mi){
      P b;
      cin>>b.real()>>b.imag();
      isicpc[ma+i]=true;
      ini.node[ma+i]  =getindex(b,M);
    }

    rep(i,ma){
      P a;
      cin>>a.real()>>a.imag();
      isgoal[getindex(a,M)]=acmgoal;
    }
    rep(j,mi){
      P a;
      cin>>a.real()>>a.imag();
      isgoal[getindex(a,M)]=icpcgoal;
    }

    make_intersection(ver,hor,M);
    map<P,int>::iterator itr = M.begin();
    vector<P> node(M.size());
    while(itr != M.end()){
      node[(*itr).second]=(*itr).first;
      itr++;
    }

    rep(i,node.size()){
      rep(j,node.size()){
	rep(k,node.size()){
	  if (isp(node[i],node[j],node[k]))isptable[i][j][k]=true;
	}
      }            
    }

    make_graph(node,hor,M);
    make_graph(node,ver,M);
    rep(i,ini.n){
      if (      isicpc[i]&&isgoal[ini.node[i]]==icpcgoal)ini.goal++;
      else if (!isicpc[i]&&isgoal[ini.node[i]]==acmgoal )ini.goal++;
    }

    sort(ini.node,ini.node+ma);
    sort(ini.node+ma,ini.node+ini.n);
    cout << bfs(M.size(),ini,node,ma)<<endl;
  }
  return false;
}
accuracy: 1
time_ms: 6420
memory_kb: 5028
final_rank: 1

code_snippet: #include<iostream>
#include<complex>
#include<map>
#include<algorithm>
#include<set>
#include<queue>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
#define pb push_back
#define mp make_pair
#define ALL(c)   (c).begin(),(c).end()

typedef complex<int> P;
typedef pair<P,P>    Line;
typedef unsigned long long ull;

const int N = 20;

namespace std{
  bool operator<(const P &a,const P &b){
    if (a.real() != b.real())return a.real() < b.real();
    return a.imag() < b.imag();
  }
}

bool isp(P a,P b,P c){
  complex<double> A(a.real(),a.imag()),B(b.real(),b.imag()),C(c.real(),c.imag());
  return abs(A-C)+abs(B-C) < abs(A-B) + 1e-10;
}

bool isptable[N][N][N];

bool edge[N][N];

enum GOAL{icpcgoal=0,acmgoal=1,els=2};
enum ICPC{icpc=0,acm=1};
int isgoal[N];

bool isicpc[8];
class state{
public:
  int n;
  int goal;
  short cnt;
  bool lastmove;
  short node[8];
  ull st;
  bool isclear();
  void makest();
  bool isvalid(int,int,vector<P>&);
  bool operator<(const state& a)const;
};

bool state::operator<(const state& a)const{
  return st < a.st;
}

bool state::isclear(){
  int cnt =0;
  rep(i,n){
    if      (isicpc[i] &&isgoal[node[i]]==icpcgoal)cnt++;
    else if (!isicpc[i]&&isgoal[node[i]]==acmgoal )cnt++;
  }
  return cnt == n;
}

bool state::isvalid(int ii,int prev,vector<P>&p){
  rep(i,n){
    if (i == ii)continue;
    if (isptable[prev][node[ii]][node[i]])
      return false;
  }
  rep(i,n){
    REP(j,i+1,n){
      if (node[i] == node[j])return false;
      if (isicpc[i] != isicpc[j] &&
	  edge[node[i]][node[j]])return false;
    }
  }
  return true;
}

void state::makest(){
  st=lastmove;
  rep(i,n){
    st=st*18 + node[i];
  }
}

int bfs(int n,state ini,vector<P> &node,int ma){
  queue<state> Q;  
  set<ull> S;
  ini.lastmove=icpc;
  ini.makest();
  Q.push(ini);
  S.insert(ini.st);
  ini.lastmove=acm;
  ini.makest();
  Q.push(ini);
  S.insert(ini.st);
  if (ini.isclear())return 0;

  while(!Q.empty()){
    state now = Q.front();Q.pop();
    int curmove=now.lastmove==icpc?acm:icpc;
    rep(i,now.n){
      if (curmove==icpc && !isicpc[i])continue;
      if (curmove==acm  && isicpc[i])continue;
      rep(j,n){
	if (!edge[now.node[i]][j])continue;
	state next = now;
	next.cnt++;
	next.lastmove=curmove;
	next.node[i]=j;
	if  (!next.isvalid(i,now.node[i],node))continue;
	sort(next.node,next.node+ma);
	sort(next.node+ma,next.node+next.n);
	next.makest();
	if (S.find(next.st) == S.end()){
	  if (next.isclear()){
	    return next.cnt;
	  }
	  S.insert(next.st);
	  Q.push(next);
	}
      }
    }    
  }
  return -1;
}

int getindex(P &a,map<P,int> &M){
  int index = M.size();
  if (M.find(a) == M.end())M[a]=index;
  return M[a];
}

void make_intersection(vector<Line> ver,vector<Line>hor, map<P,int> &M){
  rep(i,ver.size()){
    rep(j,hor.size()){
      if (ver[i].first.imag()  <= hor[j].first.imag() &&
	  ver[i].second.imag() >= hor[j].first.imag() &&
	  hor[j].first.real()  <= ver[i].first.real() &&
	  hor[j].second.real() >= ver[i].first.real()){
	P ins(ver[i].first.real(),hor[j].first.imag());
	getindex(ins,M);
      }
    }
  }
}

void make_graph(vector<P> node,vector<Line> ver,
		map<P,int> M){
  rep(i,ver.size()){
    vector<int> connect;
    rep(j,node.size()){
      if (isptable[M[ver[i].first]][M[ver[i].second]][j]){
	connect.pb(M[node[j]]);
      }
    }
    rep(j,connect.size()){
      REP(k,j+1,connect.size()){
	edge[connect[j]][connect[k]]=edge[connect[k]][connect[j]]=true;
      }
    }
  }
}

main(){
  int n,ma,mi;
  while(cin>>n>>ma>>mi && n){
    rep(i,N){
      rep(j,N)edge[i][j]=false;
      isgoal[i]=els;
    }
    rep(i,N)rep(j,N)rep(k,N)isptable[i][j][k]=false;
    vector<Line> hor,ver;
    map<P,int> M;
    rep(i,n){
      Line ins;
      cin>>ins.first.real()>>ins.first.imag()
	 >>ins.second.real()>>ins.second.imag();
      getindex(ins.first,M);
      getindex(ins.second,M);
      if (ins.second < ins.first)swap(ins.first,ins.second);
      if (ins.first.real() == ins.second.real())ver.pb(ins);
      else hor.pb(ins);
    }
    
    state ini;
    ini.cnt=0;
    ini.n=ma+mi;
    ini.goal=0;
    rep(i,ma){
      P a;
      cin>>a.real()>>a.imag();
      isicpc[i]=false;
      ini.node[i]  =getindex(a,M);
    }
    rep(i,mi){
      P b;
      cin>>b.real()>>b.imag();
      isicpc[ma+i]=true;
      ini.node[ma+i]  =getindex(b,M);
    }

    rep(i,ma){
      P a;
      cin>>a.real()>>a.imag();
      isgoal[getindex(a,M)]=acmgoal;
    }
    rep(j,mi){
      P a;
      cin>>a.real()>>a.imag();
      isgoal[getindex(a,M)]=icpcgoal;
    }

    make_intersection(ver,hor,M);
    map<P,int>::iterator itr = M.begin();
    vector<P> node(M.size());
    while(itr != M.end()){
      node[(*itr).second]=(*itr).first;
      itr++;
    }

    rep(i,node.size()){
      rep(j,node.size()){
	rep(k,node.size()){
	  if (isp(node[i],node[j],node[k]))isptable[i][j][k]=true;
	}
      }            
    }

    make_graph(node,hor,M);
    make_graph(node,ver,M);
    rep(i,ini.n){
      if (      isicpc[i]&&isgoal[ini.node[i]]==icpcgoal)ini.goal++;
      else if (!isicpc[i]&&isgoal[ini.node[i]]==acmgoal )ini.goal++;
    }

    sort(ini.node,ini.node+ma);
    sort(ini.node+ma,ini.node+ini.n);
    cout << bfs(M.size(),ini,node,ma)<<endl;
  }
  return false;
}
accuracy: 1
time_ms: 6460
memory_kb: 5028
final_rank: 2

code_snippet: #include<iostream>
#include<complex>
#include<map>
#include<algorithm>
#include<set>
#include<queue>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
#define pb push_back
#define mp make_pair
#define ALL(c)   (c).begin(),(c).end()

typedef complex<int> P;
typedef pair<P,P>    Line;
typedef unsigned long long ull;

const int N = 20;

namespace std{
  bool operator<(const P &a,const P &b){
    if (a.real() != b.real())return a.real() < b.real();
    return a.imag() < b.imag();
  }
}

bool isp(P a,P b,P c){
  complex<double> A(a.real(),a.imag()),B(b.real(),b.imag()),C(c.real(),c.imag());
  return abs(A-C)+abs(B-C) < abs(A-B) + 1e-10;
}

bool isptable[N][N][N];

bool edge[N][N];

enum GOAL{icpcgoal=0,acmgoal=1,els=2};
enum ICPC{icpc=0,acm=1};
int isgoal[N];

bool isicpc[8];
class state{
public:
  int n;
  int goal;
  short cnt;
  bool lastmove;
  short node[8];
  ull st;
  bool isclear();
  void makest();
  bool isvalid(int,int,vector<P>&);
  bool operator<(const state& a)const;
};

bool state::operator<(const state& a)const{
  /*
  if (lastmove != a.lastmove)return lastmove<a.lastmove;
  rep(i,n){
    if (node[i] != a.node[i])return node[i] < a.node[i];
  }
  */
  return st < a.st;
  //  return false;
}

bool state::isclear(){
  //return goal == n;
  
  int cnt =0;
  rep(i,n){
    if      (isicpc[i] &&isgoal[node[i]]==icpcgoal)cnt++;
    else if (!isicpc[i]&&isgoal[node[i]]==acmgoal )cnt++;
  }
  return cnt == n;
  
}

bool state::isvalid(int ii,int prev,vector<P>&p){
  rep(i,n){
    if (i == ii)continue;
    if (isptable[prev][node[ii]][node[i]])
      return false;
  }
  rep(i,n){
    REP(j,i+1,n){
      if (node[i] == node[j])return false;
      if (isicpc[i] != isicpc[j] &&
	  edge[node[i]][node[j]])return false;
    }
  }
  return true;
}

void state::makest(){
  st=lastmove;
  rep(i,n){
    st=st*18 + node[i];
  }
}

int bfs(int n,state ini,vector<P> &node,int ma){
  queue<state> Q;  
  set<ull> S;
  ini.lastmove=icpc;
  ini.makest();
  Q.push(ini);
  S.insert(ini.st);
  ini.lastmove=acm;
  ini.makest();
  Q.push(ini);
  S.insert(ini.st);
  if (ini.isclear())return 0;

  while(!Q.empty()){
    state now = Q.front();Q.pop();
    //    if (now.isclear()){
    //      return now.cnt;
    //    }
    int curmove=now.lastmove==icpc?acm:icpc;
    rep(i,now.n){
      if (curmove==icpc && !isicpc[i])continue;
      if (curmove==acm  && isicpc[i])continue;
      //      if      (isicpc[i] &&isgoal[now.node[i]]==icpcgoal)continue;
      //else if (!isicpc[i]&&isgoal[now.node[i]]==acmgoal)continue;
      rep(j,n){
	if (!edge[now.node[i]][j])continue;
	state next = now;
	next.cnt++;
	next.lastmove=curmove;
	next.node[i]=j;
	if  (!next.isvalid(i,now.node[i],node))continue;
	sort(next.node,next.node+ma);
	sort(next.node+ma,next.node+next.n);
	next.makest();
	if (S.find(next.st) == S.end()){
	  /*
	  cout << next.cnt << endl;
	  rep(k,now.n){
	    cout << node[now.node[k]]<<" " << node[next.node[k]]<<
	      " "<< now.isicpc[k] << endl;
	  }
	  cout << "end "<< endl;
	  */
	  //if (      isicpc[i]&&isgoal[next.node[i]]==icpcgoal)next.goal++;
	  //	  else if (!isicpc[i]&&isgoal[next.node[i]]==acmgoal )next.goal++;

	  if (next.isclear()){
	    //cout << S.size()<<" " << Q.size() << endl;
	    return next.cnt;
	  }
	  S.insert(next.st);
	  Q.push(next);
	}
      }
    }    
  }
  return -1;
}

int getindex(P &a,map<P,int> &M){
  int index = M.size();
  if (M.find(a) == M.end())M[a]=index;
  return M[a];
}

void make_intersection(vector<Line> ver,vector<Line>hor, map<P,int> &M){
  rep(i,ver.size()){
    
    rep(j,hor.size()){
      if (ver[i].first.imag()  <= hor[j].first.imag() &&
	  ver[i].second.imag() >= hor[j].first.imag() &&
	  hor[j].first.real()  <= ver[i].first.real() &&
	  hor[j].second.real() >= ver[i].first.real()){
	P ins(ver[i].first.real(),hor[j].first.imag());
	getindex(ins,M);
      }
    }
  }
}

void make_graph(vector<P> node,vector<Line> ver,
		map<P,int> M){
  rep(i,ver.size()){
    vector<int> connect;
    rep(j,node.size()){
      //      if (isp(ver[i].first,ver[i].second,node[j])){
      if (isptable[M[ver[i].first]][M[ver[i].second]][j]){
	//cout << isptable[M[ver[i].first]][M[ver[i].second]][j] << endl;
	connect.pb(M[node[j]]);
      }
    }
    
    rep(j,connect.size()){
      REP(k,j+1,connect.size()){
	edge[connect[j]][connect[k]]=true;
	edge[connect[k]][connect[j]]=true;
      }
    }
  }
}

main(){
  int n,ma,mi;
  while(cin>>n>>ma>>mi && n){
    rep(i,N){
      rep(j,N)edge[i][j]=false;
      isgoal[i]=els;
    }
    rep(i,N)rep(j,N)rep(k,N)isptable[i][j][k]=false;
    vector<Line> hor,ver;
    map<P,int> M;
    rep(i,n){
      Line ins;
      cin>>ins.first.real()>>ins.first.imag()
	 >>ins.second.real()>>ins.second.imag();
      getindex(ins.first,M);
      getindex(ins.second,M);
      if (ins.second < ins.first)swap(ins.first,ins.second);
      if (ins.first.real() == ins.second.real())ver.pb(ins);
      else hor.pb(ins);
    }
    
    state ini;
    ini.cnt=0;
    ini.n=ma+mi;
    ini.goal=0;
    rep(i,ma){
      P a;
      cin>>a.real()>>a.imag();
      isicpc[i]=false;
      ini.node[i]  =getindex(a,M);
    }
    rep(i,mi){
      P b;
      cin>>b.real()>>b.imag();
      isicpc[ma+i]=true;
      ini.node[ma+i]  =getindex(b,M);
    }

    rep(i,ma){
      P a;
      cin>>a.real()>>a.imag();
      isgoal[getindex(a,M)]=acmgoal;
    }
    rep(j,mi){
      P a;
      cin>>a.real()>>a.imag();
      isgoal[getindex(a,M)]=icpcgoal;
    }


    make_intersection(ver,hor,M);
    map<P,int>::iterator itr = M.begin();
    vector<P> node(M.size());
    while(itr != M.end()){
      node[(*itr).second]=(*itr).first;
      itr++;
    }

    rep(i,node.size()){
      rep(j,node.size()){
	rep(k,node.size()){
	  if (isp(node[i],node[j],node[k]))isptable[i][j][k]=true;
	}
      }            
    }

    make_graph(node,hor,M);
    make_graph(node,ver,M);
    rep(i,ini.n){
      if (      isicpc[i]&&isgoal[ini.node[i]]==icpcgoal)ini.goal++;
      else if (!isicpc[i]&&isgoal[ini.node[i]]==acmgoal )ini.goal++;
    }

    sort(ini.node,ini.node+ma);
    sort(ini.node+ma,ini.node+ini.n);
    //    rep(i,ini.n){
    //      cout << i <<" " << node[ini.node[i]]<<" " << isicpc[i] << endl;
    //    }
    /*    
    rep(i,M.size()){
      cout << node[i] <<"-";
      rep(j,M.size()){
	if (edge[i][j])cout << node[j];
      }
      cout << endl;
    }
    cout <<"end "<< endl;
    */            
    
    /*    rep(i,node.size()){
      cout <<i <<" " << node[i] << endl;
    }
    rep(i,M.size()){
      rep(j,M.size()){
	if (edge[i][j] != edge[j][i]){
	  cout <<"error" << endl;
	  exit(1);
	}
	cout << edge[i][j];
      }
      cout << endl;
    }
    */    

    cout << bfs(M.size(),ini,node,ma)<<endl;
  }
  return false;
}
accuracy: 1
time_ms: 6420
memory_kb: 5032
final_rank: 2