Problem:
Modern Announce Network
Today, modern teenagers use SNS to communicate with each other.
In a high school, $N$ students are using an SNS called ICPC (International Community for Programming Contest). Some pairs of these $N$ students are 'friends' on this SNS, and can send messages to each other. Among these $N$ students, $A$ first grade students, $B$ second grade students, and $C$ third grade students are members of the Programming Society. Note that there may be some students who are not the members of the Programming Society, so $A+B +C$ can be less than $N$.
There are good relationships between members of the same grade in the Society. Thus, there is a chat group in the SNS for each grade, and the Society members of the same grade can communicate with each other instantly via their group chat. On the other hand, the relationships between any different grades are not so good, and there are no chat group for the entire Society and the entire high school.
In order to broadcast a message to all the Society members on the SNS, the administrator of the Society came up with a method: the administrator tells the message to one of the $N$ students and have them spread the message on the SNS via the chat groups and their friends. (The administrator itself does not have an account for the SNS.) As the members of the same grade can broadcast the message by the chat group for the grade, we can assume that if one of a grade gets the message, all other members of that grade also get the message instantly. Therefore, if the message is told to at least one member of each grade, we can assume that the message is broadcasted to the all members of the Society on the SNS.
Because it is bothering to communicate between friends, we want to minimize the number of communications between friends. What is the minimum number of communications between friends to broadcast a message to all the Society members? Who is the first person to whom the administrator should tell the message to achieve the minimum communications?
Input
The input consists of a single test case. The test case is formatted as follows:
$N$ $A$ $B$ $C$
$a_1$ ... $a_A$
$b_1$ ... $b_B$
$c_1$ ... $c_C$
$M$
$x_1$ $y_1$
...
$x_M$ $y_M$
The first line contains four integers $N$, $A$, $B$, and $C$. $N$ ($3 \leq N \leq 10,000$) denotes the number of students in the SNS, and $A$, $B$ and $C$ ($1 \leq A,B,C \leq N$ and $A + B + C \leq N$) denote the number of members of the first, second, and third grade respectively. Each student on the SNS is represented by a unique numeric ID between 1 and $N$. The second line contains $A$ integers $a_1, ...,  a_A$ ($1 \leq a_1, ..., a_A \leq N$), which are the IDs of members of the first grade. The third line contains $B$ integers $b_1, ..., b_B$ ($1 \leq b_1, ..., b_B \leq N$), which are the IDs of members of the second grade. The fourth line contains $C$ integers $c_1, ..., c_C$ ($1 \leq c_1, ... , c_C \leq N$), which are the IDs of members of the third grade. You can assume
...(truncated)

Submitted solutions:

code_snippet: #include <queue>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
typedef long long ll;
#define rep(i, a, b) for (int i = a; i <= b; ++ i)
const int maxn = 10005, maxm = 2000005, inf = 1000000007; 
using namespace std;
bool vis[maxn];
int n, N[5], bel[maxn], m, e, ter[maxm], nxt[maxm], lnk[maxn], w[maxm], dis[maxn][8], opt[maxn];
void add(int x, int y, int z) { ter[++ e] = y, nxt[e] = lnk[x], lnk[x] = e, w[e] = z; }
void spfa(int st) {
	int he = 0, ta = 0;
	rep(i, 1, n) vis[i] = true;
	rep(i, 1, n) if (dis[i][st] != inf) opt[++ ta] = i, vis[i] = false;
	for ( ; he != ta; ) {
		he = (he + 1) % maxn; int u = opt[he];
		for (int i = lnk[u]; i; i = nxt[i]) {
			if (dis[u][st] + w[i] < dis[ter[i]][st]) {
			dis[ter[i]][st] = dis[u][st] + w[i];
			if (vis[ter[i]]) vis[ter[i]] = false, ta = (ta + 1) % maxn, opt[ta] = ter[i];
		}
	}
		vis[u] = true;
	}
}
int main() {
	scanf("%d%d%d%d", &n, &N[1], &N[2], &N[3]); int x, las, y;
	rep(col, 1, 3) {
		las = 0;
		rep(i, 1, N[col]) {
			scanf("%d", &x), bel[x] = col;
			if (las) add(las, x, 0), add(x, las, 0);
			las = x;
		}
	}
	scanf("%d", &m);
	rep(i, 1, m) scanf("%d%d", &x, &y), add(x, y, 1), add(y, x, 1);
	rep(i, 1, n) rep(j, 0, 7) dis[i][j] = inf;
	rep(col, 1, 3) {
		int st = (1 << (col - 1));
		rep(i, 1, n) if (bel[i] == col) dis[i][st] = 0;
		spfa(st);
	}
	int st = 3;
	rep(i, 1, n) dis[i][st] = min(dis[i][1] + dis[i][2], inf);
	spfa(st);
	st = 5;
	rep(i, 1, n) dis[i][st] = min(dis[i][1] + dis[i][4], inf);
	spfa(st);
	st = 6;
	rep(i, 1, n) dis[i][st] = min(dis[i][2] + dis[i][4], inf);
	spfa(st);
	st = 7;
	rep(i, 1, n) 
		dis[i][st] = min(dis[i][st], min(dis[i][1] + dis[i][2], inf) + dis[i][4]),
		dis[i][st] = min(dis[i][st], dis[i][1] + dis[i][6]),
		dis[i][st] = min(dis[i][st], dis[i][2] + dis[i][5]),
		dis[i][st] = min(dis[i][st], dis[i][4] + dis[i][3]);
	spfa(st);
	int ans = inf, id = 0;
	rep(i, 1, n) 
		if (dis[i][7] < ans) {
			ans = dis[i][7], id = i;
		}
	printf("%d %d\n", ans, id); 
	return 0;
}
accuracy: 1
time_ms: 800
memory_kb: 21692
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;

const int N=10010,M=1000010;
struct Edge{int v,nxt;} e[M];
int h[N],sum=0,n,m,a,b,c,sa,sb,sc,fa[N];
int disa[N],disb[N],disc[N],disx[N];
int ans1=N,ans2=N;

void add_edge(int u,int v)
{
	e[++sum]=(Edge){v,h[u]};h[u]=sum;
	e[++sum]=(Edge){u,h[v]};h[v]=sum;
}

int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}

void input()
{
	scanf("%d%d%d%d",&n,&a,&b,&c);
	for(int i=1;i<=n;i++) fa[i]=i;
	scanf("%d",&sa);
	for(int i=1,x;i<a;i++)
		scanf("%d",&x),fa[x]=find(sa);
	scanf("%d",&sb);
	for(int i=1,x;i<b;i++)
		scanf("%d",&x),fa[x]=find(sb);
	scanf("%d",&sc);
	for(int i=1,x;i<c;i++)
		scanf("%d",&x),fa[x]=find(sc);
	scanf("%d",&m);
	for(int i=1,u,v;i<=m;i++)
	{
		scanf("%d%d",&u,&v);
		u=find(u);v=find(v);
		add_edge(u,v);
	}
}

void bfs(int s,int *dis)
{
	static bool vis[N];
	memset(vis,0,sizeof(vis));
	memset(dis,0x3f,sizeof(int)*(n+3));
	queue<int> q;q.push(s);vis[s]=1;dis[s]=0;
	while(!q.empty())
	{
		int u=q.front();q.pop();
		for(int i=h[u];i;i=e[i].nxt)
			if(!vis[e[i].v]) vis[e[i].v]=1,dis[e[i].v]=dis[u]+1,q.push(e[i].v);
	}
}

int main()
{
	input();
	bfs(sa,disa);bfs(sb,disb);bfs(sc,disc);
	for(int i=1;i<=n;i++)
		ans1=min(ans1,disa[find(i)]+disb[find(i)]+disc[find(i)]);
	for(int i=1;i<=n;i++)
	{
		if(fa[i]!=i) continue;
		if(disa[i]+disb[i]+disc[i]!=ans1) continue;
		bfs(i,disx);
		for(int j=1;j<=min(ans2,n);j++)
			if(disx[j]+disa[j]==disx[sa]||disx[j]+disb[j]==disx[sb]||disx[j]+disc[j]==disx[sc])
				ans2=min(ans2,j);
		if(ans2==1) break;
	}
	printf("%d %d\n",ans1,ans2);
	return 0;
}
accuracy: 0.1076923076923077
time_ms: 40
memory_kb: 9780
final_rank: 18

code_snippet: #include<bits/stdc++.h>
#define maxn 100005
#define maxm 2000005
#define inf 1e8
//#define eps 1e-9
#define LL long long
using namespace std;

char cb[1<<15],*cs=cb,*ct=cb;
#define getc() (cs==ct && (ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
template<class T>inline void read(T &res){
	char ch;bool f=0;
	for(;!isdigit(ch=getc());) if(ch=='-') f=1;
	for(res=ch-'0';isdigit(ch=getc());res=res*10+ch-'0');
	(f) && (res = -res);
}

int n,a,b,c,m,bl[maxn],A[4];
pair<int,int>ans;

int info[maxn],Prev[maxm],to[maxm],cnt_e;
void Node(int u,int v){ Prev[++cnt_e]=info[u],info[u]=cnt_e,to[cnt_e]=v; }

int dis[4][maxn],mpt[4][maxn];
bool vis[maxn];

void Solve(int dis[maxn],int mpt[maxn],int S){
	for(int i=1;i<=n;i++) mpt[i] = i , dis[i] = inf;
	dis[S] = 0;
	queue<int>q;q.push(S);
	for(int now;!q.empty();){
		now = q.front() , q.pop();
		for(int i=info[now];i;i=Prev[i]){
			if(dis[to[i]] > dis[now] + 1 || (dis[to[i]] == dis[now] + 1 && mpt[to[i]] > mpt[now])){
				dis[to[i]] = dis[now] + 1;
				mpt[to[i]] = min(mpt[to[i]] , mpt[now]);
				q.push(to[i]);
			}
		}
	}
}

int main(){	
	scanf("%d%d%d%d",&n,&a,&b,&c);
	for(int i=1,x;i<=a;i++)
		scanf("%d",&x),bl[x]=1,(!A[1]) && (A[1] = x);
	for(int i=1,x;i<=b;i++)
		scanf("%d",&x),bl[x]=2,(!A[2]) && (A[2] = x);
	for(int i=1,x;i<=c;i++)
		scanf("%d",&x),bl[x]=3,(!A[3]) && (A[3] = x);
	scanf("%d",&m);
	for(int i=1,x,y;i<=m;i++){
		scanf("%d%d",&x,&y);
		if(bl[x]) x = A[bl[x]];
		if(bl[y]) y = A[bl[y]];
		Node(x,y),Node(y,x);
	}
	Solve(dis[1],mpt[1],A[1]);
	Solve(dis[2],mpt[2],A[2]);
	Solve(dis[3],mpt[3],A[3]);
	ans = make_pair(inf,inf);
	for(int i=1;i<=n;i++){
//		printf("@%d %d %d\n",dis[1][i],dis[2][i] , dis[3][i]);
//		printf("#%d %d %d\n",mpt[1][i],mpt[2][i] , mpt[3][i]);
		ans = min(ans , make_pair(dis[1][i] + dis[2][i] + dis[3][i] , min(mpt[1][i] , min(mpt[2][i],mpt[3][i]))));
	}
	printf("%d %d\n",ans.first,ans.second);
}
accuracy: 0.1076923076923077
time_ms: 40
memory_kb: 13868
final_rank: 19

code_snippet: #include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
struct dir
{
	int y,n;
}a[1000010];
int h[10010],map[10010],q[10010],l,r,k,dat[10010],f[10010],fa[10010],fl[10010],s,sab,sbc,sac,ans;
int find(int x)
{
	if (x==map[x])
		return x;
	else
		return map[x]=find(map[x]);
}
void make(int x, int y)
{
	a[++k].y=y;
	a[k].n=h[x];
	h[x]=k;
	return;
}
void spfa(int x)
{
	memset(dat,0x7f,sizeof(dat));
	memset(f,0,sizeof(f));
	l=r=f[x]=1;
	q[r++]=x;
	dat[x]=0;
	int k,y;
	for (;l!=r;l%=10010)
	{
		for (k=h[q[l]];k;k=a[k].n)
		{
			y=a[k].y;
			if (dat[y]>dat[q[l]]+1)
			{
				dat[y]=dat[q[l]]+1;
				if (!f[y])
				{
					q[r]=y;
					r++;
					r%=10010;
					f[y]=1;
				}
			}
		}
		f[q[l++]]=0;
	}
	return;
}
void flag(int x)
{
	f[x]=1;
	int k,y;
	for (k=h[x];k;k=a[k].n)
	{
		y=a[k].y;
		if ((dat[y]==dat[x]+1)&&(!f[y])) flag(y);
	}
	return;
}
void aflag(int x)
{
	fl[++k]=x;
	fa[x]=1;
	int k,y;
	for (k=h[x];k;k=a[k].n)
	{
		y=a[k].y;
		if ((dat[y]==dat[x]-1)&&(f[y])&&(!fa[y])) aflag(y);
	}
	return;
}
int main()
{
	int n,m,na,nb,nc,i,t,x;
	scanf("%d%d%d%d",&n,&na,&nb,&nc);
	for (i=1;i<=n;i++) map[i]=i;
	t=0;
	for (i=1;i<=na;i++)
	{
		scanf("%d",&x);
		if (t)
		{
			map[t]=map[x]=min(map[t],map[x]);
			t=map[t];
		}
		else
			t=x;
	}
	na=t;
	t=0;
	for (i=1;i<=nb;i++)
	{
		scanf("%d",&x);
		if (t)
		{
			map[t]=map[x]=min(map[t],map[x]);
			t=map[t];
		}
		else
			t=x;
	}
	nb=t;
	t=0;
	for (i=1;i<=nc;i++)
	{
		scanf("%d",&x);
		if (t)
		{
			map[t]=map[x]=min(map[t],map[x]);
			t=map[t];
		}
		else
			t=x;
	}
	nc=t;
	scanf("%d",&m);
	for (i=1;i<=m;i++)
	{
		scanf("%d%d",&t,&x);
		t=find(t);
		x=find(x);
		if (t==x) continue;
		make(t,x);
		make(x,t);
	}
/*	spfa(na);
	sab=dat[nb];
	sac=dat[nc];
	spfa(nb);
	flag(nb);
	aflag(na);
	aflag(nb);
	sbc=dat[nc];
	if (sab+sbc==sac)
		printf("%d",sac);
	else if (sac+sbc==sab)
		printf("%d",sab);
	else if (sab+sac==sbc)
		printf("%d",sbc);
	else
	{
		printf("%d",(sab+sac+sbc)>>1);
	}
	printf(" %d\n",ans);*/
	spfa(na);
	if (dat[nb]>dat[nc]) swap(nb,nc);
	memset(f,0,sizeof(f));
	k=0;
	flag(na);
	aflag(nb);
	s=dat[nb];
	spfa(nc);
	ans=t=0x7fffffff;
	for (i=1;i<=k;i++)
		if (ans>dat[fl[i]])
		{
			ans=dat[fl[i]];
			t=fl[i];
		}
		else if (ans==dat[fl[i]])
			t=min(t,fl[i]);
 	printf("%d ",s+ans);
 	ans=0x7fffffff;
	k=0;
	memset(f,0,sizeof(f));
	flag(nc);
	memset(fa,0,sizeof(fa));
	aflag(t);
	sort(fl+1,fl+k+1);
	ans=min(ans,fl[1]);

	spfa(nb);
	k=0;
	memset(f,0,sizeof(f));
	flag(nb);
	memset(fa,0,sizeof(fa));
	aflag(t);
	sort(fl+1,fl+k+1);
	ans=min(ans,fl[1]);
	
	spfa(na);
	k=0;
	memset(f,0,sizeof(f));
	flag(na);
	memset(fa,0,sizeof(fa));
	aflag(t);
	sort(fl+1,fl+k+1);
	printf("%d\n",min(ans,fl[1]));
	return 0;
}
accuracy: 0.2
time_ms: 80
memory_kb: 9108
final_rank: 16

code_snippet: #include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
struct dir
{
	int y,n;
}a[1000010];
int h[10010],map[10010],q[10010],l,r,k,dat[10010],f[10010],fa[10010],fl[10010],s,sab,sbc,sac,ans;
int find(int x)
{
	if (x==map[x])
		return x;
	else
		return map[x]=find(map[x]);
}
void make(int x, int y)
{
	a[++k].y=y;
	a[k].n=h[x];
	h[x]=k;
	return;
}
void spfa(int x)
{
	memset(dat,0x7f,sizeof(dat));
	memset(f,0,sizeof(f));
	l=r=f[x]=1;
	q[r++]=x;
	dat[x]=0;
	int k,y;
	for (;l!=r;l%=10010)
	{
		for (k=h[q[l]];k;k=a[k].n)
		{
			y=a[k].y;
			if (dat[y]>dat[q[l]]+1)
			{
				dat[y]=dat[q[l]]+1;
				if (!f[y])
				{
					q[r]=y;
					r++;
					r%=10010;
					f[y]=1;
				}
			}
		}
		f[q[l++]]=0;
	}
	return;
}
void flag(int x)
{
	f[x]=1;
	int k,y;
	for (k=h[x];k;k=a[k].n)
	{
		y=a[k].y;
		if ((dat[y]==dat[x]+1)&&(!f[y])) flag(y);
	}
	return;
}
void aflag(int x)
{
	fl[++k]=x;
	fa[x]=1;
	int k,y;
	for (k=h[x];k;k=a[k].n)
	{
		y=a[k].y;
		if ((dat[y]==dat[x]-1)&&(f[y])&&(!fa[y])) aflag(y);
	}
	return;
}
int main()
{
	int n,m,na,nb,nc,i,t,x;
	scanf("%d%d%d%d",&n,&na,&nb,&nc);
	for (i=1;i<=n;i++) map[i]=i;
	t=0;
	for (i=1;i<=na;i++)
	{
		scanf("%d",&x);
		if (t)
		{
			map[t]=map[x]=min(map[t],map[x]);
			t=map[t];
		}
		else
			t=x;
	}
	na=t;
	t=0;
	for (i=1;i<=nb;i++)
	{
		scanf("%d",&x);
		if (t)
		{
			map[t]=map[x]=min(map[t],map[x]);
			t=map[t];
		}
		else
			t=x;
	}
	nb=t;
	t=0;
	for (i=1;i<=nc;i++)
	{
		scanf("%d",&x);
		if (t)
		{
			map[t]=map[x]=min(map[t],map[x]);
			t=map[t];
		}
		else
			t=x;
	}
	nc=t;
	scanf("%d",&m);
	for (i=1;i<=m;i++)
	{
		scanf("%d%d",&t,&x);
		t=find(t);
		x=find(x);
		if (t==x) continue;
		make(t,x);
		make(x,t);
	}
/*	spfa(na);
	sab=dat[nb];
	sac=dat[nc];
	spfa(nb);
	flag(nb);
	aflag(na);
	aflag(nb);
	sbc=dat[nc];
	if (sab+sbc==sac)
		printf("%d",sac);
	else if (sac+sbc==sab)
		printf("%d",sab);
	else if (sab+sac==sbc)
		printf("%d",sbc);
	else
	{
		printf("%d",(sab+sac+sbc)>>1);
	}
	printf(" %d\n",ans);*/
	spfa(na);
	if (dat[nb]>dat[nc]) swap(nb,nc);
	memset(f,0,sizeof(f));
	k=0;
	flag(na);
	aflag(nb);
	s=dat[nb];
	spfa(nc);
	ans=t=0x7fffffff;
	for (i=1;i<=k;i++)
		if (ans>=dat[fl[i]])
		{
			ans=dat[fl[i]];
			t=min(fl[i],t);
		}
 	printf("%d ",s+ans);
	sort(fl+1,fl+k+1);
	ans=fl[1];
	k=0;
	memset(f,0,sizeof(f));
	flag(nc);
	memset(fa,0,sizeof(fa));
	aflag(t);
	sort(fl+1,fl+k+1);
	printf("%d\n",min(ans,fl[1]));
	return 0;
}
accuracy: 0.2
time_ms: 60
memory_kb: 9084
final_rank: 14

code_snippet: #include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
struct dir
{
	int y,n;
}a[1000010];
int h[10010],map[10010],q[10010],l,r,k,dat[10010],f[10010],fa[10010],fl[10010],s,sab,sbc,sac,ans;
int find(int x)
{
	if (x==map[x])
		return x;
	else
		return map[x]=find(map[x]);
}
void make(int x, int y)
{
	a[++k].y=y;
	a[k].n=h[x];
	h[x]=k;
	return;
}
void spfa(int x)
{
	memset(dat,0x7f,sizeof(dat));
	memset(f,0,sizeof(f));
	l=r=f[x]=1;
	q[r++]=x;
	dat[x]=0;
	int k,y;
	for (;l!=r;l%=10010)
	{
		for (k=h[q[l]];k;k=a[k].n)
		{
			y=a[k].y;
			if (dat[y]>dat[q[l]]+1)
			{
				dat[y]=dat[q[l]]+1;
				if (!f[y])
				{
					q[r]=y;
					r++;
					r%=10010;
					f[y]=1;
				}
			}
		}
		f[q[l++]]=0;
	}
	return;
}
void flag(int x)
{
	f[x]=1;
	int k,y;
	for (k=h[x];k;k=a[k].n)
	{
		y=a[k].y;
		if ((dat[y]==dat[x]+1)&&(!f[y])) flag(y);
	}
	return;
}
void aflag(int x)
{
	if (f[x]) fl[++k]=x;
	fa[x]=1;
	int k,y;
	for (k=h[x];k;k=a[k].n)
	{
		y=a[k].y;
		if ((dat[y]==dat[x]-1)&&(f[y])&&(!fa[y])) aflag(y);
	}
	return;
}
int main()
{
	int n,m,na,nb,nc,i,t,x;
	scanf("%d%d%d%d",&n,&na,&nb,&nc);
	for (i=1;i<=n;i++) map[i]=i;
	t=0;
	for (i=1;i<=na;i++)
	{
		scanf("%d",&x);
		if (t)
		{
			map[t]=map[x]=min(map[t],map[x]);
			t=map[t];
		}
		else
			t=x;
	}
	na=t;
	t=0;
	for (i=1;i<=nb;i++)
	{
		scanf("%d",&x);
		if (t)
		{
			map[t]=map[x]=min(map[t],map[x]);
			t=map[t];
		}
		else
			t=x;
	}
	nb=t;
	t=0;
	for (i=1;i<=nc;i++)
	{
		scanf("%d",&x);
		if (t)
		{
			map[t]=map[x]=min(map[t],map[x]);
			t=map[t];
		}
		else
			t=x;
	}
	nc=t;
	scanf("%d",&m);
	for (i=1;i<=m;i++)
	{
		scanf("%d%d",&t,&x);
		t=find(t);
		x=find(x);
		if (t==x) continue;
		make(t,x);
		make(x,t);
	}
/*	spfa(na);
	sab=dat[nb];
	sac=dat[nc];
	spfa(nb);
	flag(nb);
	aflag(na);
	aflag(nb);
	sbc=dat[nc];
	if (sab+sbc==sac)
		printf("%d",sac);
	else if (sac+sbc==sab)
		printf("%d",sab);
	else if (sab+sac==sbc)
		printf("%d",sbc);
	else
	{
		printf("%d",(sab+sac+sbc)>>1);
	}
	printf(" %d\n",ans);*/
	spfa(na);
	memset(f,0,sizeof(f));
	k=0;
	flag(na);
	aflag(nb);
	s=dat[nb];
	spfa(nc);
	memset(f,0,sizeof(f));
	ans=0x7fffffff;
	for (i=1;i<=k;i++)
		if (ans>dat[fl[i]])
		{
			ans=dat[fl[i]];
			t=fl[i];
		}
 	printf("%d ",s+ans);
	sort(fl+1,fl+k+1);
	ans=fl[1];
	k=0;
	flag(nc);
	aflag(t);
	sort(fl+1,fl+k+1);
	printf("%d\n",min(ans,fl[1]));
	return 0;
}
accuracy: 0.07692307692307693
time_ms: 20
memory_kb: 6804
final_rank: 20

code_snippet: #include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
struct dir
{
	int y,n;
}a[1000010];
int h[10010],map[10010],q[10010],l,r,k,dat[10010],f[10010],fa[10010],fl[10010],s,sab,sbc,sac,ans;
int find(int x)
{
	if (x==map[x])
		return x;
	else
		return map[x]=find(map[x]);
}
void make(int x, int y)
{
	a[++k].y=y;
	a[k].n=h[x];
	h[x]=k;
	return;
}
void spfa(int x)
{
	memset(dat,0x7f,sizeof(dat));
	memset(f,0,sizeof(f));
	l=r=f[x]=1;
	q[r++]=x;
	dat[x]=0;
	int k,y;
	for (;l!=r;l%=10010)
	{
		for (k=h[q[l]];k;k=a[k].n)
		{
			y=a[k].y;
			if (dat[y]>dat[q[l]]+1)
			{
				dat[y]=dat[q[l]]+1;
				if (!f[y])
				{
					q[r]=y;
					r++;
					r%=10010;
					f[y]=1;
				}
			}
		}
		f[q[l++]]=0;
	}
	return;
}
void flag(int x)
{
	f[x]=1;
	int k,y;
	for (k=h[x];k;k=a[k].n)
	{
		y=a[k].y;
		if ((dat[y]==dat[x]+1)&&(!f[y])) flag(y);
	}
	return;
}
void aflag(int x)
{
	fl[++k]=x;
	fa[x]=1;
	int k,y;
	for (k=h[x];k;k=a[k].n)
	{
		y=a[k].y;
		if ((dat[y]==dat[x]-1)&&(f[y])&&(!fa[y])) aflag(y);
	}
	return;
}
int main()
{
	int n,m,na,nb,nc,i,t,x;
	scanf("%d%d%d%d",&n,&na,&nb,&nc);
	for (i=1;i<=n;i++) map[i]=i;
	t=0;
	for (i=1;i<=na;i++)
	{
		scanf("%d",&x);
		if (t)
		{
			map[t]=map[x]=min(map[t],map[x]);
			t=map[t];
		}
		else
			t=x;
	}
	na=t;
	t=0;
	for (i=1;i<=nb;i++)
	{
		scanf("%d",&x);
		if (t)
		{
			map[t]=map[x]=min(map[t],map[x]);
			t=map[t];
		}
		else
			t=x;
	}
	nb=t;
	t=0;
	for (i=1;i<=nc;i++)
	{
		scanf("%d",&x);
		if (t)
		{
			map[t]=map[x]=min(map[t],map[x]);
			t=map[t];
		}
		else
			t=x;
	}
	nc=t;
	scanf("%d",&m);
	for (i=1;i<=m;i++)
	{
		scanf("%d%d",&t,&x);
		t=find(t);
		x=find(x);
		if (t==x) continue;
		make(t,x);
		make(x,t);
	}
/*	spfa(na);
	sab=dat[nb];
	sac=dat[nc];
	spfa(nb);
	flag(nb);
	aflag(na);
	aflag(nb);
	sbc=dat[nc];
	if (sab+sbc==sac)
		printf("%d",sac);
	else if (sac+sbc==sab)
		printf("%d",sab);
	else if (sab+sac==sbc)
		printf("%d",sbc);
	else
	{
		printf("%d",(sab+sac+sbc)>>1);
	}
	printf(" %d\n",ans);*/
	spfa(na);
	if (dat[nb]>dat[nc]) swap(nb,nc);
	memset(f,0,sizeof(f));
	k=0;
	flag(na);
	aflag(nb);
	s=dat[nb];
	spfa(nc);
	ans=t=0x7fffffff;
	for (i=1;i<=k;i++)
		if (ans>=dat[fl[i]])
		{
			ans=dat[fl[i]];
			t=min(fl[i],t);
		}
 	printf("%d ",s+ans);
	sort(fl+1,fl+k+1);
	ans=fl[1];
	k=0;
	memset(f,0,sizeof(f));
	flag(nc);
	memset(fa,0,sizeof(fa));
	aflag(t);
	sort(fl+1,fl+k+1);
	printf("%d\n",min(ans,fl[1]));
	spfa(nb);
	spfa(na);
	spfa(nc);
	return 0;
}
accuracy: 0.2
time_ms: 70
memory_kb: 9084
final_rank: 15

code_snippet: #include <iostream>
#include <iomanip>
#include <cassert>
#include <vector>
#include <algorithm>
#include <utility>
#include <numeric>
#include <tuple>
#include <ranges>
namespace ranges = std::ranges;
namespace views = std::views;
// #include "Src/Number/IntegerDivision.hpp"
// #include "Src/Utility/BinarySearch.hpp"
// #include "Src/Sequence/CompressedSequence.hpp"
// #include "Src/Sequence/RunLengthEncoding.hpp"
// #include "Src/Algebra/Group/AdditiveGroup.hpp"
// #include "Src/DataStructure/FenwickTree/FenwickTree.hpp"
// #include "Src/DataStructure/SegmentTree/SegmentTree.hpp"
// using namespace zawa;
// #include "atcoder/modint"
// using mint = atcoder::modint998244353;
#include <queue>
int N, M;
std::vector<std::pair<int, int>> g[100010 + 3];
int main() {
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    std::ios::sync_with_stdio(false);
    int n[3];
    std::cin >> N >> n[0] >> n[1] >> n[2];
    for (int j = 0 ; j < 3 ; j++) {
        for (int i = 0 ; i < n[j] ; i++) {
            int a;
            std::cin >> a;
            a--;
            g[a].push_back({N + j, 0});
            g[N + j].push_back({a, 0});
        }
    }
    std::cin >> M;
    for (int i = 0 ; i < M ; i++) {
        int u, v;
        std::cin >> u >> v;
        u--; v--;
        g[u].push_back({v, 1});
        g[v].push_back({u, 1});
    }
    const int INF = (int)1e9;
    std::vector dp(8, std::vector<int>(N + 3, INF));
    for (int i = 0 ; i < 3 ; i++) dp[1 << i][N + i] = 0;
    for (int b = 1 ; b < 8 ; b++) {
        for (int i = 0 ; i < N + 3 ; i++) {
            for (int msk = (b - 1) & b ; msk ; msk = (msk - 1) & b) {
                dp[b][i] = std::min(dp[b][i], dp[msk][i] + dp[b ^ msk][i]);
            }
        }
        using qt = std::pair<int, int>;
        std::priority_queue<qt, std::vector<qt>, std::greater<qt>> que;
        for (int i = 0 ; i < N + 3 ; i++) if (dp[b][i] < INF) que.push({dp[b][i], i});
        while (que.size()) {
            auto [d, v] = que.top();
            que.pop();
            if (d > dp[b][v]) continue;
            for (auto [x, w] : g[v]) if (dp[b][x] > d + w) {
                dp[b][x] = d + w;
                que.push({d + w, x});
            }
        }
    }
    assert(dp[7][N] == dp[7][N + 1] and dp[7][N + 1] == dp[7][N + 2]);
    int ans = N + 2;
    for (int i = N - 1 ; i >= 0 ; i--) if (dp[7][ans] >= dp[7][i]) ans = i;
    std::cout << dp[7][ans] << ' ' << ans + 1 << '\n';
}
accuracy: 1
time_ms: 50
memory_kb: 18048
final_rank: 9

code_snippet: // AOJ #2732 Modern Announce Network
// 2025.3.23

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

typedef pair<int, int> pii;

const int INF = 100000000;
const int MAX = 10101;

int N, A, B, C, M;
int g1[MAX], g2[MAX], g3[MAX];
vector<pii> adj[MAX];

void dij(int s, vector<int> &d, vector<int> &mn) {
    priority_queue<pii, vector<pii>, greater<pii>> pq;
    for (int i = 1; i <= N; i++) mn[i] = i;
    d[s] = 0;
    pq.push({0, s});
    while (!pq.empty()) {
        auto [dist, cur] = pq.top();
        pq.pop();
        if (dist != d[cur]) continue;
        for (auto &e : adj[cur]) {
            int nxt = e.first, cost = e.second;
            if (d[nxt] > d[cur] + cost) {
                d[nxt] = d[cur] + cost;
                mn[nxt] = min(nxt, mn[cur]);
                pq.push({d[nxt], nxt});
            } else if (d[nxt] == d[cur] + cost) mn[nxt] = min(mn[nxt], mn[cur]);
        }
    }
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    cin >> N >> A >> B >> C;

    int sa, sb, sc;
    for (int i = 1; i <= A; i++) {
        cin >> g1[i];
        if (i == 1) sa = g1[i];
        else {
            int u = g1[i - 1], v = g1[i];
            adj[u].push_back({v, 0});
            adj[v].push_back({u, 0});
        }
    }
    for (int i = 1; i <= B; i++) {
        cin >> g2[i];
        if (i == 1) sb = g2[i];
        else {
            int u = g2[i - 1], v = g2[i];
            adj[u].push_back({v, 0});
            adj[v].push_back({u, 0});
        }
    }
    for (int i = 1; i <= C; i++) {
        cin >> g3[i];
        if (i == 1) sc = g3[i];
        else {
            int u = g3[i - 1], v = g3[i];
            adj[u].push_back({v, 0});
            adj[v].push_back({u, 0});
        }
    }

    cin >> M;
    for (int i = 0; i < M; i++) {
        int u, v;
        cin >> u >> v;
        adj[u].push_back({v, 1});
        adj[v].push_back({u, 1});
    }

    vector<int> d1(N+1, INF), d2(N+1, INF), d3(N+1, INF);
    vector<int> m1(N+1), m2(N+1), m3(N+1);
    dij(sa, d1, m1);
    dij(sb, d2, m2);
    dij(sc, d3, m3);

    pii ans = {INF, INF};
    for (int i = 1; i <= N; i++) ans = min(ans, {d1[i] + d2[i] + d3[i], i});

    int mn = ans.second;
    for (int i = 1; i <= N; i++) {
        if (d1[i] + d2[i] + d3[i] != ans.first) continue;
        mn = min({mn, m1[i], m2[i], m3[i]});
    }
    for (int i = 1; i <= A; i++) mn = min(mn, g1[i]);
    for (int i = 1; i <= B; i++) mn = min(mn, g2[i]);
    for (int i = 1; i <= C; i++) mn = min(mn, g3[i]);

    cout << ans.first << ' ' << mn << endl;
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 15400
final_rank: 5

code_snippet: // AOJ #2732 Modern Announce Network
// 2025.3.14

#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
 
struct Node { int d, m; };
 
vector<Node> bfs(int n, const vector<vector<int>> &adj, const vector<int> &src, int init) {
    vector<Node> dist(n+1, {INF, INF});
    deque<int> dq;
    for (int s : src) {
        dist[s] = {0, init};
        dq.push_back(s);
    }
    while(!dq.empty()){
        int u = dq.front(); dq.pop_front();
        for (int w : adj[u]) {
            int nd = dist[u].d + 1;
            int nm = min(dist[u].m, w);
            if(dist[w].d > nd || (dist[w].d == nd && dist[w].m > nm)){
                dist[w] = {nd, nm};
                dq.push_back(w);
            }
        }
    }
    return dist;
}
 
pair<int,int> comb(const pair<int,int> &a, const pair<int,int> &b) {
    return {a.first + b.first, min(a.second, b.second)};
}
 
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
 
    int N, A, B, C;
    cin >> N >> A >> B >> C;
    vector<int> g1(A), g2(B), g3(C);
    for (int i = 0; i < A; i++) cin >> g1[i];
    for (int i = 0; i < B; i++) cin >> g2[i];
    for (int i = 0; i < C; i++) cin >> g3[i];
 
    int M;
    cin >> M;
    vector<vector<int>> adj(N+1);
    for (int i = 0; i < M; i++){
        int u, v;
        cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    for (int i = 1; i <= N; i++) sort(adj[i].begin(), adj[i].end());
 
    int min1 = *min_element(g1.begin(), g1.end());
    int min2 = *min_element(g2.begin(), g2.end());
    int min3 = *min_element(g3.begin(), g3.end());
 
    auto d1 = bfs(N, adj, g1, min1);
    auto d2 = bfs(N, adj, g2, min2);
    auto d3 = bfs(N, adj, g3, g3.empty()? INF: min3);
 
    vector<bool> soc(N+1, false);
    for (int x : g1) soc[x] = true;
    for (int x : g2) soc[x] = true;
    for (int x : g3) soc[x] = true;
 
    pair<int,int> cand12 = {INF, INF};
    for (int v : g2) {
        pair<int,int> cur = {d1[v].d, min(d1[v].m, v)};
        if(cur.first < cand12.first || (cur.first == cand12.first && cur.second < cand12.second))
            cand12 = cur;
    }
    pair<int,int> cand13 = {INF, INF};
    for (int v : g3) {
        pair<int,int> cur = {d1[v].d, min(d1[v].m, v)};
        if(cur.first < cand13.first || (cur.first == cand13.first && cur.second < cand13.second))
            cand13 = cur;
    }
    pair<int,int> cand23 = {INF, INF};
    for (int v : g3) {
        pair<int,int> cur = {d2[v].d, min(d2[v].m, v)};
        if(cur.first < cand23.first || (cur.first == cand23.first && cur.second < cand23.second))
            cand23 = cur;
    }
 
    pair<int,int> socCand = {INF, INF};
    socCand = min(socCand, comb(cand12, cand13));
    socCand = min(socCand, comb(cand12, cand23));
    socCand = min(socCand, comb(cand13, cand23));
 
    pair<int,int> nonCand = {INF, INF};
    for (int v = 1; v <= N; v++){
        if(!soc[v]){
            int cost = d1[v].d + d2[v].d + d3[v].d;
            int mn = min({d1[v].m, d2[v].m, d3[v].m, v});
            pair<int,int> cur = {cost, mn};
            if(cur.first < nonCand.first || (cur.first == nonCand.first && cur.second < nonCand.second))
                nonCand = cur;
        }
    }
 
    pair<int,int> ans;
    if(nonCand.first < socCand.first) ans = nonCand;
    else if(nonCand.first > socCand.first) ans = socCand;
    else ans = min(nonCand, socCand);
     cout << ans.first << " " << ans.second << endl;
    return 0;
}
accuracy: 0.4153846153846154
time_ms: 70
memory_kb: 9396
final_rank: 13

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int main() {
    int N, A, B, C;
    cin >> N >> A >> B >> C;
    vector<int> ID(N,-1);
    rep(i,0,A) {
        int X;
        cin >> X;
        X--;
        ID[X] = 0;
    }
    rep(i,0,B) {
        int X;
        cin >> X;
        X--;
        ID[X] = 1;
    }
    rep(i,0,C) {
        int X;
        cin >> X;
        X--;
        ID[X] = 2;
    }
    int Cur = 3;
    rep(i,0,N) {
        if (ID[i] == -1) {
            ID[i] = Cur;
            Cur++;
        }
    }
    N = Cur;
    vector<int> MinV(N,inf);
    rep(i,0,ID.size()) chmin(MinV[ID[i]],i);
    vector<vector<int>> G(N);
    int M;
    cin >> M;
    rep(i,0,M) {
        int X, Y;
        cin >> X >> Y;
        X--, Y--;
        X=ID[X],Y=ID[Y];
        if (X == Y) continue;
        G[X].push_back(Y);
        G[Y].push_back(X);
    }
    auto Dijkstra = [&](int S) -> vector<pair<int,int>> {
        vector<pair<int,int>> DP(N,{inf,inf});
        DP[S] = {0,MinV[S]};
        priority_queue<pair<pair<int,int>,int>,vector<pair<pair<int,int>,int>>,greater<pair<pair<int,int>,int>>> PQ;
        PQ.push({{0,MinV[S]},S});
        while(!PQ.empty()) {
            auto [P,V] = PQ.top();
            PQ.pop();
            if (DP[V] < P) continue;
            for (auto NV : G[V]) {
                if (chmin(DP[NV],{P.first+1,min(P.second,MinV[NV])})) {
                    PQ.push({DP[NV],NV});
                }
            }
        }
        return DP;
    };
    vector<vector<pair<int,int>>> DPS(3);
    rep(i,0,3) DPS[i] = Dijkstra(i);
    pair<int,int> ANS = {inf,inf};
    rep(i,0,N) {
        int SUM = 0, MIN = inf;
        rep(j,0,3) {
            SUM += DPS[j][i].first;
            chmin(MIN,DPS[j][i].second);
        }
        chmin(ANS,{SUM,MIN});
    }
    cout << ANS.first << ' ' << ANS.second+1 << endl;
}
accuracy: 1
time_ms: 130
memory_kb: 8228
final_rank: 1

code_snippet: #line 1 "c.cpp"
/*	author:  Kite_kuma
	created: 2022.07.05 15:38:12 */

#line 2 "SPJ-Library/graph/graph.hpp"
#include <algorithm>
#include <cassert>
#include <deque>
#include <iostream>
#include <queue>
#include <tuple>
#include <vector>

#pragma region graph

template <class cost_type = long long>
class graph {
   public:
	struct edge {
	   public:
		int from, to;
		cost_type cost;
		int id;
		edge() = default;
		edge(int from_, int to_, cost_type cost_ = 1, int id_ = -1) : from(from_), to(to_), cost(cost_), id(id_) {}
		bool operator<(const edge &a) const { return cost < a.cost; }
		bool operator>(const edge &a) const { return cost > a.cost; }
		friend std::ostream &operator<<(std::ostream &s, const edge &a) {
			s << '(' << a.from << " -> " << a.to << "), cost: " << a.cost << ", id: " << a.id;
			return s;
		}
	};

   private:
	std::vector<std::vector<edge>> edges;
	int next_edge_id = 0;

   public:
	inline const std::vector<edge> &operator[](int k) const { return edges[k]; }
	inline std::vector<edge> &operator[](int k) { return edges[k]; }

	int size() const { return int(edges.size()); }
	void resize(const int n) { edges.resize(n); }
	int edge_count() const { return next_edge_id; }

	friend std::ostream &operator<<(std::ostream &s, const graph<cost_type> &g) {
		for(const auto &adj : g.edges)
			for(const auto &ed : adj) s << ed << '\n';
		return s;
	}

	graph() = default;
	graph(int n) : edges(n) {}
	graph(int n, int e, bool weight = 0, bool directed = 0, int idx = 1) : edges(n) { input(e, weight, directed, idx); }
	const cost_type INF = std::numeric_limits<cost_type>::max() / 3;

	void input(int e = -1, bool weight = false, bool directed = false, int idx = 1) {
		if(e == -1) e = size() - 1;
		while(e--) {
			int u, v;
			std::cin >> u >> v;
			cost_type cost = 1;
			if(weight) std::cin >> cost;
			add_edge(u, v, cost, directed, idx);
		}
	}

	inline int add_edge(int u, int v, cost_type cost = 1, bool directed = false, int idx = 0) {
		u -= idx, v -= idx;
		edges[u].emplace_back(u, v, cost, next_edge_id);
		if(!directed && u != v) edges[v].emplace_back(v, u, cost, next_edge_id);
		return next_edge_id++;
	}

	// Ο(V+E)
	std::vector<cost_type> bfs(int s) const {
		std::vector<cost_type> dist(size(), INF);
		std::queue<int> que;
		dist[s] = 0;
		que.push(s);
		while(!que.empty()) {
			int v = que.front();
			que.pop();
			for(auto &e : edges[v]) {
				if(dist[e.to] != INF) continue;
				dist[e.to] = dist[v] + e.cost;
				que.push(e.to);
			}
		}
		return dist;
	}

	// Ο(V+E)
	// constraint: cost of each edge is zero or x (>= 0)
	std::vector<cost_type> zero_one_bfs(int s) const {
		std::vector<cost_type> dist(size(), INF);
		std::deque<int> deq;
		dist[s] = 0;
		deq.push_back(s);
		while(!deq.empty()) {
			int v = deq.front();
			deq.pop_front();
			for(auto &e : edges[v]) {
				if(dist[e.to] > dist[v] + e.cost) {
					dist[e.to] = dist[v] + e.cost;
					e.cost ? deq.push_back(e.to) : deq.push_front(e.to);
				}
			}
		}
		return dist;
	}

	// Ο((E+V) lg E)
	// unreachable: INF
	std::vector<cost_type> dijkstra(int s) const {
		std::vector<cost_type> dist(size(), INF);
		const auto compare = [](const std::pair<cost_type, int> &a, const std::pair<cost_type, int> &b) {
			return a.first > b.first;
		};
		std::priority_queue<std::pair<cost_type, int>, std::vector<std::pair<cost_type, int>>, decltype(compare)> que{compare};
		dist[s] = 0;
		que.emplace(0, s);
		while(!que.empty()) {
			std::pair<cost_type, int> p = que.top();
			que.pop();
			int v = p.second;
			if(dist[v] < p.first) continue;
			for(auto &e : edges[v]) {
				if(dist[e.to] > dist[v] + e.cost) {
					dist[e.to] = dist[v] + e.cost;
					que.emplace(dist[e.to], e.to);
				}
			}
		}
		return dist;
	}

	// Ο(VE)
	// unreachable: INF
	// reachable via negative cycle: -INF
	std::vector<cost_type> bellman_ford(int s) const {
		int n = size();
		std::vector<cost_type> res(n, INF);
		res[s] = 0;
		for(int loop = 0; loop < n - 1; loop++) {
			for(int v = 0; v < n; v++) {
				if(res[v] == INF) continue;
				for(auto &e : edges[v]) {
					res[e.to] = std::min(res[e.to], res[v] + e.cost);
				}
			}
		}
		std::queue<int> que;
		std::vector<int> chk(n);
		for(int v = 0; v < n; v++) {
			if(res[v] == INF) continue;
			for(auto &e : edges[v]) {
				if(res[e.to] > res[v] + e.cost and !chk[e.to]) {
					que.push(e.to);
					chk[e.to] = 1;
				}
			}
		}
		while(!que.empty()) {
			int now = que.front();
			que.pop();
			for(auto &e : edges[now]) {
				if(!chk[e.to]) {
					chk[e.to] = 1;
					que.push(e.to);
				}
			}
		}
		for(int i = 0; i < n; i++)
			if(chk[i]) res[i] = -INF;
		return res;
	}

	// Ο(V^3)
	std::vector<std::vector<cost_type>> warshall_floyd() const {
		const int n = size();
		std::vector<std::vector<cost_type>> dist(n, std::vector<cost_type>(n, INF));
		for(int i = 0; i < n; i++) dist[i][i] = 0;
		for(int i = 0; i < n; i++)
			for(auto &e : edges[i]) dist[i][e.to] = std::min(dist[i][e.to], e.cost);
		for(int k = 0; k < n; k++)
			for(int i = 0; i < n; i++) {
				if(dist[i][k] == INF) continue;
				for(int j = 0; j < n; j++) {
					if(dist[k][j] == INF) continue;
					dist[i][j] = std::min(dist[i][j], dist[i][k] + dist[k][j]);
				}
			}
		return dist;
	}

	// Ο(V) (using DFS)
	// if a cycle exists, return {}
	std::vector<int> topological_sort() const {
		std::vector<int> res;
		std::vector<int> used(size(), 0);
		bool not_DAG = false;
		auto dfs = [&](auto self, int k) -> void {
			if(not_DAG) return;
			if(used[k]) {
				if(used[k] == 1) not_DAG = true;
				return;
			}
			used[k] = 1;
			for(auto &e : edges[k]) self(self, e.to);
			used[k] = 2;
			res.push_back(k);
		};
		for(int i = 0; i < size(); i++) dfs(dfs, i);
		if(not_DAG) return std::vector<int>{};
		std::reverse(res.begin(), res.end());
		return res;
	}

	bool is_dag() const { return !topological_sort().empty(); }

	// Ο(V)
	// array of the distance to the most distant vertex
	// constraint: the graph is a tree
	std::vector<cost_type> height() const {
		auto vec1 = bfs(0);
		int v1 = -1, v2 = -1;
		cost_type dia = -1;
		for(int i = 0; i < int(size()); i++)
			if(dia < vec1[i]) dia = vec1[i], v1 = i;
		vec1 = bfs(v1);
		dia = -1;
		for(int i = 0; i < int(size()); i++)
			if(dia < vec1[i]) dia = vec1[i], v2 = i;
		auto vec2 = bfs(v2);
		for(int i = 0; i < int(size()); i++) {
			if(vec1[i] < vec2[i]) vec1[i] = vec2[i];
		}
		return vec1;
	}

	// O(V+E)
	// vector<(int)(0 or 1)>
	// if it is not bipartite, return {}
	std::vector<int> bipartite_grouping() const {
		std::vector<int> colors(size(), -1);
		auto dfs = [&](auto self, int now, int col) -> bool {
			colors[now] = col;
			for(auto &e : edges[now]) {
				if(col == colors[e.to]) return false;
				if(colors[e.to] == -1 and !self(self, e.to, !col)) return false;
			}
			return true;
		};
		for(int i = 0; i < int(size()); i++)
			if(colors[i] == -1 and !dfs(dfs, i, 0)) return std::vector<int>{};
		return colors;
	}

	bool is_bipartite() const { return !bipartite_grouping().empty(); }

	// Ο(V+E)
	// (v1, v2, diameter)
	std::tuple<int, int, cost_type> diameter() {
		std::vector<cost_type> dist = bfs(0);
		auto it = std::max_element(dist.begin(), dist.end());
		const int v = it - dist.begin();
		dist = bfs(v);
		it = std::max_element(dist.begin(), dist.end());
		return std::make_tuple(v, int(it - dist.begin()), *it);
	}

	// Ο(V+E)
	std::vector<int> subtree_size(const int root) {
		const int n = size();
		std::vector<int> ret(n, 1);
		auto dfs = [&](auto self, int now, int p = -1) -> void {
			for(const auto &e : (*this)[now]) {
				if(e.to == p) continue;
				self(self, e.to, now);
				ret[now] += ret[e.to];
			}
		};
		dfs(dfs, root);
		return ret;
	}

	// Ο(ElgE)
	cost_type prim() const {
		cost_type res = 0;
		std::priority_queue<edge, std::vector<edge>, std::greater<edge>> que;
		for(auto &e : edges[0]) que.push(e);
		std::vector<int> chk(size());
		chk[0] = 1;
		int cnt = 1;
		while(cnt < size()) {
			auto e = que.top();
			que.pop();
			if(chk[e.to]) continue;
			cnt++;
			res += e.cost;
			chk[e.to] = 1;
			for(auto &e2 : edges[e.to]) que.push(e2);
		}
		return res;
	}

	// Ο(ElgE)
	cost_type kruskal() const {
		std::vector<std::tuple<int, int, cost_type>> eds;
		for(const auto &adj : edges)
			for(const auto &ed : adj) eds.emplace_back(ed.from, ed.to, ed.cost);
		std::sort(eds.begin(), eds.end(), [](const std::tuple<int, int, cost_type> &a, const std::tuple<int, int, cost_type> &b) {
			return std::get<2>(a) < std::get<2>(b);
		});
		std::vector<int> uf_data(size(), -1);
		auto root = [&uf_data](auto self, int x) -> int {
			if(uf_data[x] < 0) return x;
			return uf_data[x] = self(self, uf_data[x]);
		};
		auto unite = [&uf_data, &root](int u, int v) -> bool {
			u = root(root, u), v = root(root, v);
			if(u == v) return false;
			if(uf_data[u] > uf_data[v]) std::swap(u, v);
			uf_data[u] += uf_data[v];
			uf_data[v] = u;
			return true;
		};
		cost_type ret = 0;
		for(auto &e : eds)
			if(unite(std::get<0>(e), std::get<1>(e))) ret += std::get<2>(e);
		return ret;
	}

	// O(V)
	std::vector<int> centroid() const {
		std::vector<int> centroid, sz(size());
		auto dfs = [&](auto self, int now, int per) -> void {
			sz[now] = 1;
			bool is_centroid = true;
			for(auto &e : edges[now]) {
				if(e.to != per) {
					self(self, e.to, now);
					sz[now] += sz[e.to];
					if(sz[e.to] > size() / 2) is_centroid = false;
				}
			}
			if(size() - sz[now] > size() / 2) is_centroid = false;
			if(is_centroid) centroid.push_back(now);
		};
		dfs(dfs, 0, -1);
		return centroid;
	}

	// O(V+E)
	// bridge: (s, t)  (s < t);
	std::pair<std::vector<std::pair<int, int>>, std::vector<int>> bridges_and_articulations() const {
		std::vector<int> order(size(), -1), low(size()), articulation;
		int order_next = 0;
		std::vector<std::pair<int, int>> bridge;
		auto dfs = [&](auto self, int now, int par = -1) -> void {
			low[now] = order[now] = order_next++;
			bool is_articulation = false;
			int cnt = 0;
			for(auto &ed : edges[now]) {
				int &nxt = ed.to;
				if(nxt == par) continue;
				if(order[nxt] == -1) {
					cnt++;
					self(self, nxt, now);
					if(order[now] < low[nxt]) bridge.push_back(std::minmax(now, nxt));
					if(order[now] <= low[nxt]) is_articulation = true;
					low[now] = std::min(low[now], low[nxt]);
				} else if(order[now] > order[nxt]) {
					low[now] = std::min(low[now], order[nxt]);
				}
			}
			if(par == -1 and cnt < 2) is_articulation = false;
			if(is_articulation) articulation.push_back(now);
			return;
		};
		for(int i = 0; i < (int)size(); i++)
			if(order[i] == -1) dfs(dfs, i);
		return std::make_pair(bridge, articulation);
	}

	// Ο(V+E)
	// directed graph from root to leaf
	graph root_to_leaf(int root = 0) const {
		graph res(size());
		std::vector<int> chk(size(), 0);
		chk[root] = 1;
		auto dfs = [&](auto self, int now) -> void {
			for(auto &e : edges[now]) {
				if(chk[e.to] == 1) continue;
				chk[e.to] = 1;
				res.add_edge(now, e.to, e.cost, 1, 0);
				self(self, e.to);
			}
		};
		dfs(dfs, root);
		return res;
	}

	// Ο(V+E)
	// directed graph from leaf to root
	graph leaf_to_root(int root = 0) const {
		graph res(size());
		std::vector<int> chk(size(), 0);
		chk[root] = 1;
		auto dfs = [&](auto self, int now) -> void {
			for(auto &e : edges[now]) {
				if(chk[e.to] == 1) continue;
				chk[e.to] = 1;
				res.add_edge(e.to, now, e.cost, 1, 0);
				self(self, e.to);
			}
		};
		dfs(dfs, root);
		return res;
	}

	// cost_type Chu_Liu_Edmonds(int root = 0) {}
};
#pragma endregion
#line 2 "SPJ-Library/template/kuma.hpp"

#line 2 "SPJ-Library/template/basic_func.hpp"

#line 7 "SPJ-Library/template/basic_func.hpp"

template <class T0, class T1, class T2>
inline bool in_range(T0 x, T1 lef, T2 rig) {
	return ((lef <= x) && (x < rig));
}

template <class T>
inline bool chmin(T &a, T b) {
	if(a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T>
inline bool chmax(T &a, T b) {
	if(a < b) {
		a = b;
		return true;
	}
	return false;
}

void Yes(bool flag = true) { std::cout << (flag ? "Yes" : "No") << '\n'; }
void YES(bool flag = true) { std::cout << (flag ? "YES" : "NO") << '\n'; }

template <class T>
void drop(T answer) {
	std::cout << answer << '\n';
	exit(0);
}

template <class T>
void vout(std::vector<T> const &v, bool vertically = 0) {
	if(vertically) {
		for(auto const &a : v) {
			std::cout << a << '\n';
		}
		return;
	}
	for(auto it = v.begin(); it != v.end(); it++) {
		std::cout << (*it);
		if(it != v.end() - 1) {
			std::cout << ' ';
		}
	}
	std::cout << '\n';
	return;
}

inline void print() { std::cout << '\n'; }
template <class T>
inline void print(const T &x) {
	std::cout << x << '\n';
	return;
}
template <typename Head, typename... Tail>
void print(const Head &H, const Tail &... T) {
	std::cout << H << " ";
	print(T...);
}

template <class T>
void add(std::vector<T> &v, T value) {
	for(auto &a : v) a += value;
	return;
}

template <class T>
T greatest_lower_multiple(T x, T d) {
	if(d == 0) return 0;
	if(d < 0) d *= -1;
	T y = x % d;
	if(y < 0) y += d;
	return x - y;
}

template <class T>
T least_upper_multiple(T x, T d) {
	return -greatest_lower_multiple(-x, d);
}

// ceil(a / b);
template <class T>
T dup(T a, T b) {
	assert(b);
	if(b < 0) {
		a *= -1;
		b *= -1;
	}
	return least_upper_multiple(a, b) / b;
}

long long pow_ll(long long a, long long n) {
	assert(n >= 0LL);
	if(n == 0) return 1LL;
	if(a == 0) return 0LL;
	if(a == 1) return 1LL;
	if(a == -1) return (n & 1LL) ? -1LL : 1LL;
	long long res = 1;
	while(n > 1LL) {
		if(n & 1LL) res *= a;
		a *= a;
		n >>= 1;
	}
	return res * a;
}

long long modpow(long long a, long long n, long long mod) {	 // a^n mod
	assert(n >= 0 && mod);
	if(mod == 1) return 0LL;
	long long res = 1;
	a %= mod;
	while(n > 0) {
		if(n & 1) res = res * a % mod;
		a = a * a % mod;
		n >>= 1;
	}
	return res < 0 ? res + mod : res;
}

// return x which satisfies a * x % mod == gcd(a, mod)
// not (mod | a)
long long modinv(long long a, const long long mod) {
	long long b = mod, u = 1, v = 0;
	while(b) {
		long long t = a / b;
		a -= t * b;
		std::swap(a, b);
		u -= t * v;
		std::swap(u, v);
	}
	u %= mod;
	if(u < 0) u += mod;
	return u;
}

template <class T>
int lb(const std::vector<T> &a, const T x) {
	return (int)std::distance(a.begin(), std::lower_bound(a.begin(), a.end(), x));
}
template <class T>
int ub(const std::vector<T> &a, const T x) {
	return (int)std::distance(a.begin(), std::upper_bound(a.begin(), a.end(), x));
}
template <class T>
void unq_sort(std::vector<T> &a) {
	std::sort(a.begin(), a.end());
	a.erase(std::unique(a.begin(), a.end()), a.end());
}
template <class T>
std::vector<int> press(const std::vector<T> &a) {
	std::vector<T> vec = a;
	unq_sort(vec);
	std::vector<int> ret;
	for(const auto &v : a) ret.push_back(lb(vec, v));
	return ret;
}
#line 1 "SPJ-Library/template/header.hpp"
#include <bits/stdc++.h>
#line 2 "SPJ-Library/template/io.hpp"

#line 4 "SPJ-Library/template/io.hpp"

#line 8 "SPJ-Library/template/debug.hpp"

#line 3 "SPJ-Library/template/constants.hpp"

constexpr int inf = 1000'000'000;
constexpr long long INF = 1'000'000'000'000'000'000LL;
constexpr int mod_1000000007 = 1000000007;
constexpr int mod_998244353 = 998244353;
const long double pi = acosl(-1.);
constexpr int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
constexpr int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
#line 10 "SPJ-Library/template/debug.hpp"

namespace viewer {

template <typename T, typename U>
void view(const std::pair<T, U> &p);

template <class T0, class T1, class T2>
void view(const std::tuple<T0, T1, T2> &p);

template <class T0, class T1, class T2, class T3>
void view(const std::tuple<T0, T1, T2, T3> &p);

void view(const long long &e);

void view(const int &e);

template <typename T>
void view(const T &e);

template <typename T>
void view(const std::set<T> &s);

template <typename T>
void view(const std::unordered_set<T> &s);

template <typename T>
void view(const std::multiset<T> &s);

template <typename T>
void view(const std::unordered_multiset<T> &s);

template <typename T>
void view(const std::vector<T> &v);

template <typename T, std::size_t ary_size>
void view(const std::array<T, ary_size> &v);

template <typename T>
void view(const std::vector<std::vector<T>> &vv);

template <typename T, typename U>
void view(const std::vector<std::pair<T, U>> &v);

template <class T0, class T1, class T2>
void view(const std::vector<std::tuple<T0, T1, T2>> &v);

template <class T0, class T1, class T2, class T3>
void view(const std::vector<std::tuple<T0, T1, T2, T3>> &v);

template <typename map_type>
void view_map_container(const map_type &m);

template <typename T, typename U>
void view(const std::map<T, U> &m);

template <typename T, typename U>
void view(const std::unordered_map<T, U> &m);

template <typename container_type>
void view_container(const container_type &c, bool vertically = false) {
	typename container_type::const_iterator begin = c.begin();
	const typename container_type::const_iterator end = c.end();
	if(vertically) {
		std::cerr << "{\n";
		while(begin != end) {
			std::cerr << '\t';
			view(*(begin++));
			if(begin != end) std::cerr << ',';
			std::cerr << '\n';
		}
		std::cerr << '}';
		return;
	}
	std::cerr << "{ ";
	while(begin != end) {
		view(*(begin++));
		if(begin != end) std::cerr << ',';
		std::cerr << ' ';
	}
	std::cerr << '}';
}

template <typename T, typename U>
void view(const std::pair<T, U> &p) {
	std::cerr << '(';
	view(p.first);
	std::cerr << ", ";
	view(p.second);
	std::cerr << ')';
}

template <class T0, class T1, class T2>
void view(const std::tuple<T0, T1, T2> &p) {
	std::cerr << '(';
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ')';
}

template <class T0, class T1, class T2, class T3>
void view(const std::tuple<T0, T1, T2, T3> &p) {
	std::cerr << '(';
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ", ";
	view(std::get<3>(p));
	std::cerr << ')';
}

void view(const long long &e) {
	if(e == INF)
		std::cerr << "INF";
	else if(e == -INF)
		std::cerr << "-INF";
	else
		std::cerr << e;
}

void view(const int &e) {
	if(e == inf)
		std::cerr << "inf";
	else if(e == -inf)
		std::cerr << "-inf";
	else
		std::cerr << e;
}

template <typename T>
void view(const T &e) {
	std::cerr << e;
}

template <typename T>
void view(const std::set<T> &s) {
	view_container(s);
}

template <typename T>
void view(const std::unordered_set<T> &s) {
	view_container(s);
}

template <typename T>
void view(const std::multiset<T> &s) {
	view_container(s);
}

template <typename T>
void view(const std::unordered_multiset<T> &s) {
	view_container(s);
}

template <typename T>
void view(const std::vector<T> &v) {
	view_container(v);
}

template <typename T, std::size_t ary_size>
void view(const std::array<T, ary_size> &v) {
	view_container(v);
}

template <typename T>
void view(const std::vector<std::vector<T>> &vv) {
	view_container(vv, true);
}

template <typename T, typename U>
void view(const std::vector<std::pair<T, U>> &v) {
	view_container(v, true);
}

template <class T0, class T1, class T2>
void view(const std::vector<std::tuple<T0, T1, T2>> &v) {
	view_container(v, true);
}

template <class T0, class T1, class T2, class T3>
void view(const std::vector<std::tuple<T0, T1, T2, T3>> &v) {
	view_container(v, true);
}

template <typename map_type>
void view_map_container(const map_type &m) {
	std::cerr << "{\n";
	for(typename map_type::const_iterator it = m.begin(); it != m.end(); it++) {
		std::cerr << "\t[";
		view(it->first);
		std::cerr << "] : ";
		view(it->second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::map<T, U> &m) {
	view_map_container(m);
}

template <typename T, typename U>
void view(const std::unordered_map<T, U> &m) {
	view_map_container(m);
}

}  // namespace viewer

// when compiling : g++ foo.cpp -DLOCAL
#ifdef LOCAL
void debug_out() {}
template <typename T>
void debug_out(const T &x) {
	viewer::view(x);
}
template <typename Head, typename... Tail>
void debug_out(const Head &H, const Tail &... T) {
	viewer::view(H);
	std::cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                                \
	do {                                                          \
		std::cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                                   \
		std::cerr << "]\n";                                       \
	} while(0)
#else
#define debug(...) (void(0))
#endif
#line 2 "SPJ-Library/template/scanner.hpp"

#line 6 "SPJ-Library/template/scanner.hpp"

namespace scanner {
template <class T>
void scan(T &a) {
	std::cin >> a;
}

template <class T, class L>
void scan(std::pair<T, L> &p) {
	scan(p.first);
	scan(p.second);
}

template <class T0, class T1, class T2>
void scan(std::tuple<T0, T1, T2> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	scan(t0);
	scan(t1);
	scan(t2);
	p = std::make_tuple(t0, t1, t2);
}

template <class T0, class T1, class T2, class T3>
void scan(std::tuple<T0, T1, T2, T3> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	T3 t3;
	scan(t0);
	scan(t1);
	scan(t2);
	scan(t3);
	p = std::make_tuple(t0, t1, t2, t3);
}

template <class T>
void scan(std::vector<T> &a) {
	for(auto &i : a) scan(i);
}

void INPUT() {}
template <class Head, class... Tail>
void INPUT(Head &head, Tail &... tail) {
	scan(head);
	INPUT(tail...);
}
}  // namespace scanner
#line 7 "SPJ-Library/template/io.hpp"

#define VEC(type, name, size) \
	vector<type> name(size);  \
	scanner::INPUT(name)
#define VVEC(type, name, h, w)                     \
	vector<vector<type>> name(h, vector<type>(w)); \
	scanner::INPUT(name)
#define INT(...)     \
	int __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LL(...)            \
	long long __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define STR(...)        \
	string __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define CHR(...)      \
	char __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define DBL(...)        \
	double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LD(...)              \
	long double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define TPL3(type0, type1, type2, name)   \
	std::tuple<type0, type1, type2> name; \
	scanner::INPUT(name);
#define TPL4(type0, type1, type2, type3, name)   \
	std::tuple<type0, type1, type2, type3> name; \
	scanner::INPUT(name);

template <typename T1, typename T2>
std::istream &operator>>(std::istream &is, std::pair<T1, T2> &p) {
	is >> p.first >> p.second;
	return is;
}

template <typename T1, typename T2>
std::ostream &std::operator<<(std::ostream &os, const std::pair<T1, T2> &p) {
	os << p.first << ' ' << p.second;
	return os;
}
template <class T>
std::ostream &std::operator<<(std::ostream &os, const std::vector<T> &v) {
	for(typename std::vector<T>::const_iterator it = v.begin(); it != v.end(); it++) {
		if(it != v.begin()) std::cerr << ' ';
		os << *it;
	}
	return os;
}

struct fast_io {
	fast_io() {
		std::ios::sync_with_stdio(false);
		std::cin.tie(nullptr);
		std::cout << std::fixed << std::setprecision(15);
		srand((unsigned)time(NULL));
	}
} fast_io_;
#line 2 "SPJ-Library/template/macros.hpp"

#define foa(s, v) for(auto &s : v)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define pcnt(n) __builtin_popcountll((long long)n)

#define REPname(a, b, c, d, e, ...) e
#define rep(...) REPname(__VA_ARGS__, REP3, REP2, REP1, REP0)(__VA_ARGS__)
#define REP0(x) for(int Counter_in_rep_macro = 0; Counter_in_rep_macro < (x); ++Counter_in_rep_macro)
#define REP1(i, x) for(int i = 0; i < (x); ++i)
#define REP2(i, l, r) for(int i = (l); i < (r); ++i)
#define REP3(i, l, r, c) for(int i = (l); i < (r); i += (c))
#define DREPname(a, b, c, d, e, ...) e
#define drep(...) DREPname(__VA_ARGS__, DREP3, DREP2, DREP1)(__VA_ARGS__)
#define DREP1(i, x) for(int i = (x)-1; i >= 0; --i)
#define DREP2(i, l, r) for(int i = (r)-1; i >= (l); --i)
#define DREP3(i, l, r, c) for(int i = (r)-1; i >= (l); i -= (c))

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = std::vector<int>;
using vvi = std::vector<std::vector<int>>;
using vvvi = std::vector<std::vector<std::vector<int>>>;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vvvll = std::vector<vvll>;
template <class T = ll>
using V = std::vector<T>;
template <class T = ll>
using VV = V<V<T>>;
template <class T = ll>
using VVV = V<V<V<T>>>;
template <class T = ll>
using pqup = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <class T = ll>
using pqdn = std::priority_queue<T>;
#line 7 "SPJ-Library/template/kuma.hpp"

using namespace std;
#line 6 "c.cpp"

void solve(int n) {
	VEC(int, szs, 3);
	vvi grps(3);
	vi groupnumber(n, -1);
	rep(i, 3) {
		rep(szs[i]) {
			int id;
			cin >> id;
			grps[i].push_back(id - 1);
			groupnumber[id - 1] = i;
		}
	}
	vi mins;
	rep(i, 3) { mins.push_back(*min_element(all(grps[i]))); }

	vi newid(n);
	rep(i, n) {
		if(groupnumber[i] == -1)
			newid[i] = i;
		else {
			newid[i] = mins[groupnumber[i]];
		}
	}

	int m;
	cin >> m;
	graph<int> g(n);
	rep(m) {
		int x, y;
		cin >> x >> y;
		x--;
		y--;
		x = newid[x];
		y = newid[y];
		if(x == y) continue;
		g.add_edge(x, y, 1, false, 0);
	};

	vvi dists(3);
	vvi minimal_idx(3);

	auto dist_grp_id = [&](int grp_id) {
		vector<int> idx_min(n, inf);
		vector<int> dist(n, n + 10);
		int grpmin = *min_element(all(grps[grp_id]));
		pqup<tuple<int, int, int>> q;  // dist, id, vertex;
									   // foa(start, grps[grp_id]) {
		const int start = mins[grp_id];
		dist[start] = 0;
		idx_min[start] = grpmin;
		q.emplace(0, idx_min[start], start);
		// }
		auto update = [&](int nxt, int minidx, int d) {
			if(dist[nxt] > d) {
				return true;
			}
			return idx_min[nxt] > minidx && dist[nxt] == d;
		};
		while(q.size()) {
			int d;
			int minidx;
			int now;
			tie(d, minidx, now) = q.top();
			q.pop();
			if(d > dist[now]) continue;
			if(minidx > idx_min[now]) continue;
			foa(e, g[now]) {
				const int to = e.to;
				if(update(to, min(minidx, to), d + 1)) {
					dist[to] = d + 1;
					idx_min[to] = min(minidx, to);
					q.emplace(dist[to], idx_min[to], to);
				}
			}
		}

		dists[grp_id] = dist;
		minimal_idx[grp_id] = idx_min;
		return;
	};

	rep(i, 3) { dist_grp_id(i); }

	int ans = n + 10;
	int dist_min = inf;

	debug(dists);
	debug(minimal_idx);

	rep(mid, n) {
		int dsum = 0;
		rep(i, 3) dsum += dists[i][mid];
		if(dist_min > dsum) {
			dist_min = dsum;
			ans = inf;
			rep(i, 3) chmin(ans, minimal_idx[i][mid]);
		} else if(dist_min == dsum) {
			rep(i, 3) chmin(ans, minimal_idx[i][mid]);
		}
	}

	print(dist_min, ans + 1);
}

int main() {
	int n;
	while(cin >> n && n) {
		solve(n);
	}
}
accuracy: 1
time_ms: 60
memory_kb: 24312
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T> bool chmax(T& a, const T& b) { return a < b ? (a = b, 1) : 0; }
template <typename T> bool chmin(T& a, const T& b) { return a > b ? (a = b, 1) : 0; }

vector<pair<int, int>> bfs01(vector<vector<pair<int, int>>>& G, int s) {
    const int n = G.size();
    vector<pair<int, int>> dist(n, {1e9, -1});
    dist[s] = {0, s};
    deque<pair<pair<int, int>, int>> dq;
    dq.push_back({{0, s}, s});
    while (!dq.empty()) {
        auto [d, v] = dq.front();
        dq.pop_front();
        for (auto [u, w] : G[v]) {
            pair<int, int> nd(d.first + w, min(d.second, u));
            if (dist[u] > nd) {
                dist[u] = nd;
                if (w == 0) dq.push_front({nd, u});
                else dq.push_back({nd, u});
            }
        }
    }
    return dist;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int N;
    cin >> N;
    vector<int> S(3);
    for (auto& x : S) cin >> x;
    int m = N;
    vector<vector<pair<int, int>>> G(N+3);
    rep(k,0,3) {
        rep(_,0,S[k]) {
            int i;
            cin >> i;
            --i;
            chmin(m, i);
            G[i].push_back({N+k, 0});
            G[N+k].push_back({i, 0});
        }
    }
    int M;
    cin >> M;
    rep(_,0,M) {
        int x, y;
        cin >> x >> y;
        --x, --y;
        G[x].push_back({y, 1});
        G[y].push_back({x, 1});
    }
    vector<vector<pair<int, int>>> dist(3);
    rep(k,0,3) dist[k] = bfs01(G, N+k);
    pair<int, int> ans(1e9, 0);
    rep(i,0,N) {
        // cout << dist[0][i]+dist[1][i]+dist[2][i] << endl;
        int d = dist[0][i].first + dist[1][i].first + dist[2][i].first;
        int v = min({m, dist[0][i].second, dist[1][i].second, dist[2][i].second}) + 1;
        chmin(ans, {d, v});
    }
    cout << ans.first << " " << ans.second << endl;
}
accuracy: 1
time_ms: 110
memory_kb: 15376
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using ll = long long;
#define var auto
const char newl = '\n';

using namespace std;

template<typename T1, typename T2> inline void chmin(T1& a, T2 b) { if (a > b) a = b; }
template<typename T1, typename T2> inline void chmax(T1& a, T2 b) { if (a < b) a = b; }

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int n, ac, bc, cc;
  cin >> n >> ac >> bc >> cc;
  vector<vector<pair<int, int>>> g(n + 3);
  vector<int> a(ac), b(bc), c(cc);
  for (var&& item : a) {
    cin >> item; item--;
    g[n + 0].emplace_back(item, 0);
    g[item].emplace_back(n + 0, 0);
  }
  for (var&& item : b) {
    cin >> item; item--;
    g[n + 1].emplace_back(item, 0);
    g[item].emplace_back(n + 1, 0);
  }
  for (var&& item : c) {
    cin >> item; item--;
    g[n + 2].emplace_back(item, 0);
    g[item].emplace_back(n + 2, 0);
  }
  
  int m;
  cin >> m;
  for (int i = 0; i < m; i++) {
    int s, t;
    cin >> s >> t;
    s--; t--;
    g[s].emplace_back(t, 1);
    g[t].emplace_back(s, 1);
  }

  var calc = [&](int start) {
    vector<int> dist(n + 3, INT_MAX / 4);
    deque<pair<int, int>> q;
    q.emplace_front(start, 0);
    while (q.size()) {
      var [v, c] = q.front(); q.pop_front();
      if (dist[v] <= c) continue;
      dist[v] = c;
      for (var&& [adj, d] : g[v]) {
        if (dist[adj] <= c + d) continue;
        if (d == 0) q.emplace_front(adj, c + d);
        if (d == 1) q.emplace_back(adj, c + d);
      }
    }

    return dist;
  };

  vector<int> dist_a = calc(n + 0), dist_b = calc(n + 1), dist_c = calc(n + 2);

  vector v{ make_pair(n, dist_a), make_pair(n + 1, dist_b), make_pair(n + 2, dist_c) };
  
  int min_ind = -1;
  int cur_min = INT_MAX;
  for (int i = 0; i < n; i++) {
    vector<int> perm{ 0, 1, 2 };
    var val = INT_MAX;
    do
    {
      var& [a, av] = v[perm[0]];
      var& [b, bv] = v[perm[1]];
      var& [c, cv] = v[perm[2]];
      // 
      // x-a-b-c
      // 
      chmin(val, av[i] + bv[a] + cv[b]);
      //
      // x-a-b
      //   |-c
      //
      chmin(val, av[i] + bv[a] + cv[a]);
      //
      // x--a-b
      //  |-c
      //
      chmin(val, av[i] + bv[a] + cv[i]);
      //
      //  |-a
      // x--b
      //  |-c
      //
      chmin(val, av[i] + bv[i] + cv[i]);

    } while (next_permutation(perm.begin(), perm.end()));

    if (cur_min <= val) continue;
    cur_min = val;
    min_ind = i;
  }

  cout << cur_min << " " << (min_ind + 1) << endl;
}
accuracy: 0.2
time_ms: 50
memory_kb: 17752
final_rank: 17

code_snippet: #pragma GCC optimize("Ofast")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <cstdio>
#include <ctime>
#include <assert.h>
#include <chrono>
#include <random>
#include <numeric>
#include <set>
#include <deque>
#include <stack>
#include <sstream>
#include <utility>
#include <cstring>
#include <unordered_map>
#include <unordered_set>
#include <tuple>
#include <array>
#include <bitset>
using namespace std;
typedef long long int ll;
typedef unsigned long long ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline double time() {
    return static_cast<double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n; cin >> n;
    vector<int> idx(n);
    for(int i=0;i<n;i++){
        idx[i] = i;
    }
    vector<int> v(3);
    vector<int> sz(3);
    for(int i=0;i<3;i++){
        cin >> sz[i];
    }
    for(int _=0;_<3;_++){
        int m = sz[_];
        vector<int> c(m);
        for(int j=0;j<m;j++){
            cin >> c[j]; c[j]--;
        }
        sort(c.begin(), c.end());
        v[_] = c[0];
        for(int j:c){
            idx[j] = c[0];
        }
    }
    int m; cin >> m;
    vector<vector<int>> g(n);
    for(int i=0;i<m;i++){
        int x,y; cin >> x >> y;
        x--; y--;
        x = idx[x];
        y = idx[y];
        g[x].push_back(y);
        g[y].push_back(x);
    }
    vector<vector<int>> d(3,vector<int>(n,1e9));
    vector<vector<int>> mi(3,vector<int>(n));
    for(int i=0;i<n;i++){
        for(int j=0;j<3;j++){
            mi[j][i] = i;
        }
    }
    for(int i=0;i<3;i++){
        queue<int> q;
        d[i][v[i]] = 0;
        q.push(v[i]);
        while(q.size()){
            int s = q.front(); q.pop();
            for(int t:g[s]){
                if(d[i][t] > d[i][s]+1){
                    d[i][t] = d[i][s]+1;
                    mi[i][t] = min(mi[i][t],mi[i][s]);
                    q.push(t);
                }
                else if(d[i][t] == d[i][s] + 1){
                    mi[i][t] = min(mi[i][t],mi[i][s]);
                }
            }
        }
    }
    int res = 1e9, id = -1;
    for(int i=0;i<n;i++){
        if(idx[i] != i)continue;
        int sum = 0;
        for(int j=0;j<3;j++){
            sum += d[j][i];
        }
        if(sum < res){
            res = sum;
            id = min({mi[0][i],mi[1][i],mi[2][i]});
        }
        else if(sum == res){
            id = min(id, min({mi[0][i],mi[1][i],mi[2][i]}));
        }
    }
    cout << res << " " << id+1 << endl;
}
accuracy: 1
time_ms: 50
memory_kb: 11132
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;
using PII = pair<ll, ll>;

#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()
#define POPCOUNT(x) __builtin_popcount(x)
template <typename T> void chmin(T &a, const T &b) { a = min(a, b); }
template <typename T> void chmax(T &a, const T &b) { a = max(a, b); }

const ll INF = 1LL << 60;

struct FastIO {
    FastIO() {
        cin.tie(0);
        ios::sync_with_stdio(0);
    }
} fastiofastio;

const ll MOD = 1e9 + 7;

// BEGIN CUT
ll modpow(ll x, ll y, ll m) {
    ll a = 1, p = x;
    while (y > 0) {
        if (y % 2 == 0) {
            p = (p * p) % m;
            y /= 2;
        } else {
            a = (a * p) % m;
            y--;
        }
    }
    return a;
}
// END CUT

ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

vector<int> G[100010];
int group[100000];
int idx[100010];
int distA[100010], distB[100010], distC[100010];
int min_idxA[100010], min_idxB[100010], min_idxC[100010];

void bfs(int s, int *dist, int *min_idx) {
    fill(dist, dist + 100010, -1);
    dist[s] = 0;
    min_idx[s] = idx[s];
    queue<int> que;
    que.push(s);
    while (!que.empty()) {
        int now = que.front();
        que.pop();
        for (int to : G[now]) {
            if (dist[to] == -1) {
                dist[to] = dist[now] + 1;
                min_idx[to] = min(idx[to], min_idx[now]);
                que.push(to);
            } else if (dist[to] == dist[now] + 1) {
                min_idx[to] = min(min_idx[to], min_idx[now]);
            }
        }
    }
}

int main() {
    int N, A, B, C;
    cin >> N >> A >> B >> C;
    for (int i = 0; i <= N + 2; i++)
        idx[i] = i;
    memset(group, -1, sizeof(group));
    for (int i = 0; i < A; i++) {
        int a;
        cin >> a;
        a--;
        group[a] = N;
        chmin(idx[N], a);
    }
    for (int i = 0; i < B; i++) {
        int b;
        cin >> b;
        b--;
        group[b] = N + 1;
        chmin(idx[N + 1], b);
    }
    for (int i = 0; i < C; i++) {
        int c;
        cin >> c;
        c--;
        group[c] = N + 2;
        chmin(idx[N + 2], c);
    }
    int M;
    cin >> M;
    for (int i = 0; i < M; i++) {
        int x, y;
        cin >> x >> y;
        x--;
        y--;
        if (group[x] != -1)
            x = group[x];
        if (group[y] != -1)
            y = group[y];
        G[x].push_back(y);
        G[y].push_back(x);
    }
    bfs(N, distA, min_idxA);
    bfs(N + 1, distB, min_idxB);
    bfs(N + 2, distC, min_idxC);
    int ans = 1 << 30;
    int v = 1 << 30;
    for (int i = 0; i <= N + 2; i++) {
        if (distA[i] == -1 || distB[i] == -1 || distC[i] == -1)
            continue;
        int sum = distA[i] + distB[i] + distC[i];
        int x = min(min_idxA[i], min(min_idxB[i], min_idxC[i]));
        if (ans > sum) {
            ans = sum;
            v = x;
        } else if (ans == sum) {
            v = min(v, x);
        }
    }
    cout << ans << " " << v + 1 << endl;
}
accuracy: 1
time_ms: 40
memory_kb: 13556
final_rank: 3

code_snippet: #pragma GCC tag("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
//#include <atcoder/maxflow>
//using namespace atcoder;
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 5050000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
const double pi = acos(-1);
const double eps = 1e-9;
const int mod = 1e9 + 7;
//const int mod = 998244353;

int main(){
    int n; cin >> n;
    vl num(3); rep(i,3) cin >> num[i];
    vl node(n,-1);
    rep(i,3) rep(j,num[i]){
        int x; cin >> x; x--;
        node[x] = i;
    }
    vvl G(n+3);
    int m; cin >> m;
    rep(i,m){
        int u,v; cin >> u >> v; u--; v--;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    rep(i,n){
        if(node[i] != -1){
            G[i].push_back(n+node[i]);
            G[n+node[i]].push_back(i);
        }
    }
    vector<vpl> d(3,vpl(n+3,{inf,inf}));
    rep(i,3){
        priority_queue<pair<P,int>,vector<pair<P,int>>,greater<pair<P,int>>> pq;
        rep(j,n) if(node[j] == i){
            pq.emplace(P(0,j),j);
            d[i][j] = {0,j};
        }
        while(!pq.empty()){
            auto p = pq.top(); pq.pop();
            int u = p.second;
            if(d[i][u] < p.first) continue;
            for(auto v : G[u]){
                int c = u>=n || v>=n;
                if(chmin(d[i][v], P(d[i][u].first+1-c,min(d[i][u].second,v)))){
                    pq.emplace(d[i][v],v);
                }
            }
        }
    }
    P ans = {inf,inf};
    rep(i,n+3){
        int s = 0, mn = inf;
        rep(j,3){
            s += d[j][i].first;
            chmin(mn,d[j][i].second);
        }
        chmin(ans,P(s,mn));
    }
    cout << ans.first << " " << ans.second+1 << "\n";
}
accuracy: 1
time_ms: 140
memory_kb: 16068
final_rank: 10

code_snippet: #include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

//constexpr long long MOD = 1000000007;
constexpr long long MOD = 998244353;
constexpr double EPS = 1e-8;

//int N, M, K, T, H, W, L, R;
long long int N, M, K, T, H, W, L, R;

struct Node {
	int cost, mn, idx;
	Node(int cost, int mn, int idx) :cost(cost), mn(mn), idx(idx) {

	}
	bool operator<(const Node &n)const {
		return make_pair(cost, mn) > make_pair(n.cost, n.mn);
	}
};

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin >> N;
	vector<int>num(3);
	for (auto& i : num)cin >> i;
	vector<vector<int>>v(3);
	for (int i = 0; i < 3; i++) {
		v[i].resize(num[i]);
		for (auto& j : v[i]) {
			cin >> j;
			j += 2;
		}
	}
	cin >> M;
	vector<vector<pair<int, int>>>edge(N + 3);
	for (int i = 0; i < M; i++) {
		cin >> L >> R;
		L += 2;
		R += 2;
		edge[L].push_back({ R,1 });
		edge[R].push_back({ L,1 });
	}
	for (int i = 0; i < 3; i++) {
		for (auto j : v[i]) {
			edge[i].push_back({ j,0 });
			edge[j].push_back({ i,0 });
		}
	}
	vector<vector<pair<int, int>>>dis(3, vector<pair<int, int>>(N + 3, { MOD,0 }));
	for (int i = 0; i < 3; i++) {
		priority_queue<Node>PQ;
		for (auto j : v[i]) {
			dis[i][j] = { 0,j };
			PQ.push(Node(0, j, j));
		}
		while (!PQ.empty()) {
			auto box = PQ.top();
			PQ.pop();
			int cn = box.idx;
			for (auto j : edge[cn]) {
				if (j.second == 1) {
					if (dis[i][j.first] > make_pair(dis[i][cn].first + 1, dis[i][cn].second)) {
						dis[i][j.first] = { dis[i][cn].first + 1,dis[i][cn].second };
						if (j.first >= 3) {
							dis[i][j.first].second = min(dis[i][j.first].second, j.first);
						}
						PQ.push(Node(dis[i][j.first].first, dis[i][j.first].second, j.first));;
					}
				}
				else {
					if (dis[i][j.first] > make_pair(dis[i][cn].first + 0, dis[i][cn].second)) {
						dis[i][j.first] = { dis[i][cn].first + 0,dis[i][cn].second };
						if (j.first >= 3) {
							dis[i][j.first].second = min(dis[i][j.first].second, j.first);
						}
						PQ.push(Node(dis[i][j.first].first, dis[i][j.first].second, j.first));
					}
				}
			}
		}
	}
	//for (int i = 0; i < 3; i++) {
	//	for (auto j : dis[i]) {
	//		cout << j.first << "<->" << j.second << " ";
	//	}
	//	cout << endl;
	//}
	pair<int, int>ans = { MOD,-1 };
	for (int i = 3; i < N+3; i++) {
		pair<int, int>c = { 0,MOD };
		for (int j = 0; j < 3; j++) {
			c.first += dis[j][i].first;
			c.second = min(c.second, dis[j][i].second);
		}
		//cout << c.first << " " << c.second << endl;
		c.second = min(c.second, i);
		ans = min(ans, c);
	}
	cout << ans.first << " " << ans.second - 2 << endl;
}
accuracy: 1
time_ms: 60
memory_kb: 15584
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
const int INF = 100000;
int main(){
  int N, A, B, C;
  cin >> N >> A >> B >> C;
  vector<int> a(A);
  for (int i = 0; i < A; i++){
    cin >> a[i];
    a[i]--;
  }
  vector<int> b(B);
  for (int i = 0; i < B; i++){
    cin >> b[i];
    b[i]--;
  }
  vector<int> c(C);
  for (int i = 0; i < C; i++){
    cin >> c[i];
    c[i]--;
  }
  int M;
  cin >> M;
  vector<int> x(M), y(M);
  for (int i = 0; i < M; i++){
    cin >> x[i] >> y[i];
    x[i]--;
    y[i]--;
  }
  vector<int> id(N, -1);
  for (int i = 0; i < A; i++){
    id[a[i]] = 0;
  }
  for (int i = 0; i < B; i++){
    id[b[i]] = 1;
  }
  for (int i = 0; i < C; i++){
    id[c[i]] = 2;
  }
  int cnt = 3;
  for (int i = 0; i < N; i++){
    if (id[i] == -1){
      id[i] = cnt;
      cnt++;
    }
  }
  vector<vector<int>> E(cnt);
  for (int i = 0; i < M; i++){
    x[i] = id[x[i]];
    y[i] = id[y[i]];
    E[x[i]].push_back(y[i]);
    E[y[i]].push_back(x[i]);
  }
  vector<vector<int>> bfs(3);
  vector<vector<int>> d(3, vector<int>(cnt, -1));
  for (int i = 0; i < 3; i++){
    d[i][i] = 0;
    queue<int> Q;
    Q.push(i);
    while (!Q.empty()){
      int v = Q.front();
      Q.pop();
      bfs[i].push_back(v);
      for (int w : E[v]){
        if (d[i][w] == -1){
          d[i][w] = d[i][v] + 1;
          Q.push(w);
        }
      }
    }
  }
  int mn = INF;
  for (int i = 0; i < cnt; i++){
    mn = min(mn, d[0][i] + d[1][i] + d[2][i]);
  }
  vector<bool> ok(cnt, false);
  for (int i = 0; i < cnt; i++){
    if (d[0][i] + d[1][i] + d[2][i] == mn){
      ok[i] = true;
    }
  }
  vector<bool> ok2(cnt, false);
  for (int i = 0; i < 3; i++){
    vector<bool> ok3 = ok;
    for (int j = cnt - 1; j >= 0; j--){
      int v = bfs[i][j];
      if (ok3[v]){
        for (int w : E[v]){
          if (d[i][w] == d[i][v] - 1){
            ok3[w] = true;
          }
        }
      }
    }
    for (int j = 0; j < cnt; j++){
      if (ok3[j]){
        ok2[j] = true;
      }
    }
  }
  int ans;
  for (int i = 0; i < N; i++){
    if (ok2[id[i]]){
      ans = i;
      break;
    }
  }
  cout << mn << ' ' << ans + 1 << endl;
}
accuracy: 1
time_ms: 180
memory_kb: 12712
final_rank: 6

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <deque>


template <typename T>
std::vector<T> unweighted_shortest_path(std::vector<std::vector<T>> &g_spmat, T st){
    std::vector<T> res(g_spmat.size(), 0x7f7f7f7f);
    std::deque<std::pair<T, T>> deq;
    deq.push_back(std::make_pair(0, st));

    while(!deq.empty()){
        auto x = deq.front();
        deq.pop_front();
        if(res[x.second] == 0x7f7f7f7f){
            for(auto pt: g_spmat[x.second]){
                if(res[pt] == 0x7f7f7f7f) deq.push_back(std::make_pair(1 + x.first, pt));
            }
            res[x.second] = x.first;
        }
    }
    return res;
}

template <typename T>
std::vector<T> unweighted_shortest_path_exe(std::vector<std::vector<T>> &g_spmat, std::vector<T> &dist, T st){
    std::vector<T> res;
    std::vector<bool> nvisited(g_spmat.size(), true);
    std::deque<T> deq;
    deq.push_back(st);
    while(!deq.empty()){
        T ind = deq.front();
        deq.pop_front();
        if(nvisited[ind]){
            nvisited[ind] = false;
            res.push_back(ind);
            for(auto nx: g_spmat[ind]) if(dist[nx] < dist[ind]) deq.push_back(nx);
        }
    }
    return res;
}

int main(){
    int n, a, b, c, p;
    std::cin >> n >> a >> b >> c;
    std::vector<int> smi(3, 0x7f7f7f7f), s(n, -1);
    while(a--){
        std::cin >> p, p--;
        smi[0] = std::min(smi[0], p);
        s[p] = 0;
    }
    while(b--){
        std::cin >> p, p--;
        smi[1] = std::min(smi[1], p);
        s[p] = 1;
    }
    while(c--){
        std::cin >> p, p--;
        smi[2] = std::min(smi[2], p);
        s[p] = 2;
    }
    std::vector<std::vector<int>> gmat(n);
    std::cin >> p;
    while(p--){
        int x, y;
        std::cin >> x >> y;
        x--, y--;
        if(s[x] != -1) x = smi[s[x]];
        if(s[y] != -1) y = smi[s[y]];
        if(x == y) continue;

        gmat[x].push_back(y);
        gmat[y].push_back(x);
    }
    

    auto dista = unweighted_shortest_path(gmat, smi[0]);
    auto distb = unweighted_shortest_path(gmat, smi[1]);
    auto distc = unweighted_shortest_path(gmat, smi[2]);
    std::vector<int> dist(n, 0);
    for(int i = 0; i < n; i++){
        dist[i] = dista[i] + distb[i] + distc[i];
        if(dista[i] == 0x7f7f7f7f || distb[i] == 0x7f7f7f7f || distc[i] == 0x7f7f7f7f) dist[i] = 0x7f7f7f7f;
    }

    int ind = std::min_element(dist.begin(), dist.end()) - dist.begin();
    int resid = 0x7f7f7f7f;
    for(int i = 0; i < n; i++) if(dist[i] == dist[ind]){
        auto patha = unweighted_shortest_path_exe(gmat, dista, i);
        auto pathb = unweighted_shortest_path_exe(gmat, distb, i);
        auto pathc = unweighted_shortest_path_exe(gmat, distc, i);

        int tempa = *std::min_element(patha.begin(), patha.end());
        int tempb = *std::min_element(pathb.begin(), pathb.end());
        int tempc = *std::min_element(pathc.begin(), pathc.end());

        resid = std::min({resid, tempa, tempb, tempc});
    }
    std::cout << dist[ind] << " " << resid + 1 << "\n";
}
accuracy: 1
time_ms: 140
memory_kb: 11588
final_rank: 4