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

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
typedef pair<P, int> PI;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcount

#define INF INT_MAX/3

struct UnionFind{
  vector<int> v;
  UnionFind(int n) : v(n, -1) {}
  void init(){ for(int i = 0;i < v.size();i++)v[i]=-1; }
  int find(int x) { return v[x] < 0 ? x : v[x] = find(v[x]); }
  bool unite(int x, int y) {
    x = find(x); y = find(y);
    if (x == y) return false;
    if (-v[x] < -v[y]) swap(x, y);
    v[x] += v[y]; v[y] = x;
    return true;
  }
  bool root(int x) { return v[x] < 0; }
  bool same(int x, int y) { return find(x) == find(y); }
  int size(int x) { return -v[find(x)]; }
};

int N,A,B,C,M;
int fa,fb,fc;
vector<int> g[100010];
P dist[3][100010];

void shortpath(int s,int t){
  rep(i,N)dist[t][i]=P(INF,INF);
  priority_queue<PI,vector<PI>,greater<PI> > que;
  que.push(PI(P(0,s),s));
  while(que.size()){
    int d=que.top().fi.fi;
    int mnv=que.top().fi.se;
    int v=que.top().se;
    que.pop();
    if(dist[t][v]!=P(INF,INF))continue;
    dist[t][v]=P(d,mnv);
    for(int nv : g[v]){
      que.push(PI(P(d+1,min(mnv,nv)),nv));
    }
  }
}

int main(){
  cin>>N>>A>>B>>C;
  UnionFind uf(N);
  int pre=-1;
  int mnv=INF;
  rep(i,A){
    int a;
    cin>>a;
    a--;
    minch(mnv,a);
    if(pre==-1)pre=a;
    else{
      uf.unite(pre,a);
    }
  }
  fa=uf.find(pre);
  pre=-1;
  rep(i,B){
    int a;
    cin>>a;
    a--;
    minch(mnv,a);
    if(pre==-1)pre=a;
    else{
      uf.unite(pre,a);
    }
  }
  fb=uf.find(pre);
  pre=-1;
  rep(i,C){
    int a;
    cin>>a;
    a--;
    minch(mnv,a);
    if(pre==-1)pre=a;
    else{
      uf.unite(pre,a);
    }
  }
  fc=uf.find(pre);

  cin>>M;
  rep(i,M){
    int a,b;
    cin>>a>>b;
    a--;b--;
    a=uf.find(a); b=uf.find(b);
    g[a].push_back(b);
    g[b].push_back(a);
  }

  shortpath(fa,0); shortpath(fb,1); shortpath(fc,2);

  int mn=INF,res=-1;
  rep(i,N){
    int j=uf.find(i);
    if(mn>dist[0][j].fi+dist[1][j].fi+dist[2][j].fi||(mn==dist[0][j].fi+dist[1][j].fi+dist[2][j].fi&&res>min({dist[0][j].se,dist[1][j].se,dist[2][j].se}))){
      mn=dist[0][j].fi+dist[1][j].fi+dist[2][j].fi;
      res=min({dist[0][j].se,dist[1][j].se,dist[2][j].se});
    }
  }
  cout<<mn<<" "<<min(mnv,res)+1<<endl;

  return 0;
}


### Prompt

Please provide a CPP coded solution to the problem described below:

Example

Input

4 2 1 1
1 2
3
4
3
1 2
2 4
3 4


Output

2 1

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
typedef pair<P, int> PI;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcount

#define INF INT_MAX/3

struct UnionFind{
  vector<int> v;
  UnionFind(int n) : v(n, -1) {}
  void init(){ for(int i = 0;i < v.size();i++)v[i]=-1; }
  int find(int x) { return v[x] < 0 ? x : v[x] = find(v[x]); }
  bool unite(int x, int y) {
    x = find(x); y = find(y);
    if (x == y) return false;
    if (-v[x] < -v[y]) swap(x, y);
    v[x] += v[y]; v[y] = x;
    return true;
  }
  bool root(int x) { return v[x] < 0; }
  bool same(int x, int y) { return find(x) == find(y); }
  int size(int x) { return -v[find(x)]; }
};

int N,A,B,C,M;
int fa,fb,fc;
vector<int> g[100010];
P dist[3][100010];

void shortpath(int s,int t){
  rep(i,N)dist[t][i]=P(INF,INF);
  priority_queue<PI,vector<PI>,greater<PI> > que;
  que.push(PI(P(0,s),s));
  while(que.size()){
    int d=que.top().fi.fi;
    int mnv=que.top().fi.se;
    int v=que.top().se;
    que.pop();
    if(dist[t][v]!=P(INF,INF))continue;
    dist[t][v]=P(d,mnv);
    for(int nv : g[v]){
      que.push(PI(P(d+1,min(mnv,nv)),nv));
    }
  }
}

int main(){
  cin>>N>>A>>B>>C;
  UnionFind uf(N);
  int pre=-1;
  int mnv=INF;
  rep(i,A){
    int a;
    cin>>a;
    a--;
    minch(mnv,a);
    if(pre==-1)pre=a;
    else{
      uf.unite(pre,a);
    }
  }
  fa=uf.find(pre);
  pre=-1;
  rep(i,B){
    int a;
    cin>>a;
    a--;
    minch(mnv,a);
    if(pre==-1)pre=a;
    else{
      uf.unite(pre,a);
    }
  }
  fb=uf.find(pre);
  pre=-1;
  rep(i,C){
    int a;
    cin>>a;
    a--;
    minch(mnv,a);
    if(pre==-1)pre=a;
    else{
      uf.unite(pre,a);
    }
  }
  fc=uf.find(pre);

  cin>>M;
  rep(i,M){
    int a,b;
    cin>>a>>b;
    a--;b--;
    a=uf.find(a); b=uf.find(b);
    g[a].push_back(b);
    g[b].push_back(a);
  }

  shortpath(fa,0); shortpath(fb,1); shortpath(fc,2);

  int mn=INF,res=-1;
  rep(i,N){
    int j=uf.find(i);
    if(mn>dist[0][j].fi+dist[1][j].fi+dist[2][j].fi||(mn==dist[0][j].fi+dist[1][j].fi+dist[2][j].fi&&res>min({dist[0][j].se,dist[1][j].se,dist[2][j].se}))){
      mn=dist[0][j].fi+dist[1][j].fi+dist[2][j].fi;
      res=min({dist[0][j].se,dist[1][j].se,dist[2][j].se});
    }
  }
  cout<<mn<<" "<<min(mnv,res)+1<<endl;

  return 0;
}


```