#include<bits/stdc++.h>
#define re register
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read() {
	char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
	while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
const int maxn=2e6+1;
struct E{int v,nxt;}e[maxn*10];
int dfn[maxn],low[maxn],st[maxn],f[maxn],col[maxn],head[maxn],id[2][maxn>>1],l[maxn>>2],r[maxn>>2];
int n,m,A,B,num,__,cnt,top,col_num,ans,Ans[500005];
inline void add(int x,int y) {e[++num].v=y;e[num].nxt=head[x];head[x]=num;}
void tarjan(int x) {
	dfn[x]=low[x]=++__,st[++top]=x,f[x]=1;
	for(re int i=head[x];i;i=e[i].nxt)
	if(!dfn[e[i].v]) tarjan(e[i].v),low[x]=min(low[x],low[e[i].v]);
	else if(f[e[i].v]) low[x]=min(low[x],dfn[e[i].v]);
	if(dfn[x]==low[x]) {
		col_num++;int now;
		do{now=st[top--];f[now]=0;col[now]=col_num;}while(x!=now);
	}
}
int main() {
	A=read(),n=read(),m=read(),B=read();
	for(re int i=1;i<=n;i++) id[0][i]=++cnt,id[1][i]=++cnt;
	for(re int i=0;i<=m;i++) id[0][i+1+n]=++cnt,id[1][i+1+n]=++cnt;
	for(re int x,y,i=1;i<=A;i++) {
		x=read(),y=read();
		add(id[0][x],id[1][y]);
		add(id[0][y],id[1][x]);
	}
	for(re int i=1;i<=n;i++) l[i]=read(),r[i]=read();
	for(re int x,y,i=1;i<=B;i++) {
		x=read(),y=read();
		add(id[1][x],id[0][y]);
		add(id[1][y],id[0][x]);
	}
	add(id[1][n+1],id[0][n+1]);
	for(re int i=1;i<=m;i++) {
		int x=i+1+n;
		add(id[0][x],id[0][x-1]);
		add(id[1][x-1],id[1][x]);
	}
	add(id[0][n+m+1],id[1][n+m+1]);
	for(re int i=1;i<=n;i++) {
		int li=l[i]+n,ri=r[i]+n+1;
		add(id[1][li],id[0][i]);
		add(id[1][i],id[0][li]);
		add(id[0][ri],id[0][i]);
		add(id[1][i],id[1][ri]);
	}
	for(re int i=1;i<=cnt;++i) if(!dfn[i]) tarjan(i);
	for(re int i=1;i<=n+1+m;i++) if(col[id[0][i]]==col[id[1][i]]) {puts("-1");return 0;}
	for(re int i=1;i<=n;i++)
		if(col[id[1][i]]<col[id[0][i]]) Ans[++ans]=i;
	for(re int i=1;i<=m;i++) if(col[id[1][i+n+1]]<col[id[0][i+n+1]]) {
		printf("%d %d\n",ans,i);
		for(re int j=1;j<=ans;j++) printf("%d ",Ans[j]);
		return 0;
	}
}


#include<bits/stdc++.h>
#define FRER() freopen("/Users/seven7777777/Desktop/Code/TESTXCODE/TESTXCODE/i.txt","r",stdin)
using namespace std;
int const N=400000+10;
int const M=1600000+10;
int h[M],cnt,bl[M],dfn[M],low[M],sum,n,p,t,s[M],top,vis[M],m;
struct edge{
    int to,nt;
}e[M<<2];
void add(int a,int b){
    e[++cnt].to=b;
    e[cnt].nt=h[a];
    h[a]=cnt;
}
void dfs(int x){
    dfn[x]=low[x]=++cnt;
    s[++top]=x;
    for(int i=h[x];i;i=e[i].nt){
        int v=e[i].to;
        if(!dfn[v]){
            dfs(v);
            low[x]=min(low[x],low[v]);
        }else if(!bl[v])  low[x]=min(low[x],dfn[v]);
    }
    if(dfn[x]==low[x]){
        sum++;
        while (s[top]!=x){
            bl[s[top]]=sum;
            top--;
        }
        bl[x]=sum; top--;
    }
}
int main(){
    //FRER();
    scanf("%d%d%d%d",&n,&p,&m,&t);
    for(int i=1;i<=n;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        add(x<<1,y<<1|1);
        add(y<<1,x<<1|1);
    }
    for(int i=1;i<=m;i++){
        add((p+i)<<1|1,(p+i+1)<<1|1);
        add((p+i+1)<<1,(p+i)<<1);
    }
    for(int i=1;i<=p;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        add((p+x)<<1|1,i<<1);
        add(i<<1|1,(p+x)<<1);
        add((p+y+1)<<1,i<<1);
        add(i<<1|1,(p+y+1)<<1|1);
    }
    for(int i=1;i<=t;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        add(x<<1|1,y<<1);
        add(y<<1|1,x<<1);
    }
    cnt=0; int ans=0;
    for(int i=2;i<=(p+m)*2+3;i++)
        if(!bl[i]) dfs(i);

    int f=m;
    for(int i=1;i<=p+m+1;i++)
        if(bl[i<<1]==bl[i<<1|1]) {
            printf("-1\n");
            return 0;
        }else{
            vis[i]=bl[i<<1|1]<bl[i<<1];
            if(i<=p) ans+=vis[i];
        }
    while (f>0 && vis[p+f+1])  f--;
    printf("%d %d\n",ans,f+1);
    for(int i=1;i<=p;i++)
        if(vis[i]) printf("%d ",i);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=4e5+5;
int n,p,M,m;
int node,id[N],yes[N*2],no[N*2],head[N*4],ce;
bool vis[N*4];
struct edge{int to,nxt;} e[N*10];
void adde(int a,int b) {e[++ce]=(edge){b,head[a]},head[a]=ce;}
vector<int> cs;
int f;
int rd() {
    char ch=getchar(); int x=0;
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-48,ch=getchar();return x;
}
void build()
{
	for(int i=1;i<=p;++i) yes[i]=++node,no[i]=++node;
	for(int i=0;i<=M;++i) id[i]=p+i+1;
	for(int i=0;i<=M;++i) yes[id[i]]=++node,no[id[i]]=++node;
	for(int i=1;i<=n;++i)
	{
		int x,y;
		x=rd(),y=rd();
		adde(no[x],yes[y]); adde(no[y],yes[x]);
	}
	for(int i=1;i<=p;++i)
	{
		int l,r;
		l=rd(),r=rd();
		adde(yes[i],yes[id[r]]); adde(yes[i],no[id[l-1]]);
		adde(no[id[r]],no[i]); adde(yes[id[l-1]],no[i]);
	}
	for(int i=1;i<=m;++i)
	{
		int u,v;
		u=rd(),v=rd();
		adde(yes[u],no[v]); adde(yes[v],no[u]);
	}
	for(int i=0;i<=M;++i)
	{
		if(i>0) adde(no[id[i]],no[id[i-1]]);
		if(i<M) adde(yes[id[i]],yes[id[i+1]]);
	}
	adde(yes[id[0]],no[id[0]]);
}
int dfn[N*4],low[N*4],Time,st[N*4],top,ins[N*4],c[N*4],cnt;
void tarjan(int u)
{
	dfn[u]=low[u]=++Time,st[++top]=u,ins[u]=1;
	for(int i=head[u],v;i;i=e[i].nxt)
	{
		v=e[i].to;
		if(!dfn[v]) tarjan(v),low[u]=min(low[v],low[u]);
		else if(ins[v]) low[u]=min(dfn[v],low[u]);
	}
	if(low[u]==dfn[u])
	{
		int v=-1; ++cnt;
		while(v!=u) v=st[top--],ins[v]=0,c[v]=cnt;
	}
}
int main()
{
	//freopen("1.in","r",stdin); freopen("1.out","w",stdout);
	scanf("%d%d%d%d",&n,&p,&M,&m);
	build();
	for(int i=1;i<=node;++i)
		if(!dfn[i]) tarjan(i);
	for(int i=1;i<=p;++i) if(c[yes[i]] == c[no[i]]) {puts("-1"); return 0;}
	for(int i=0;i<=M;++i) if(c[yes[id[i]]] == c[no[id[i]]]) {puts("-1"); return 0;}
	for(int i=1;i<=p;++i) if(c[yes[i]]<c[no[i]]) cs.push_back(i);
	for(int i=0;i<=M;++i)
		if(c[yes[id[i]]] < c[no[id[i]]]) {f=i; break;}
	printf("%d %d\n",(int)cs.size(),f);
	for(int i=0;i<cs.size();++i) printf("%d ",cs[i]);
	return 0;
}


#include <iostream>
#include <vector>

using namespace std;

struct boolean
{
    int iTrue, iFalse;
    bool value;
};

vector<vector<int>> i_graph;
vector<vector<int>> t_graph;
boolean vertex[500000];
boolean f_ge[500000];
vector<char> used;
int component[1000000];
vector<int> out_order;
int n, m, M, p;

void dfs1(int v)
{
    used[v] = true;
    for(int u: i_graph[v])
        if(!used[u])
            dfs1(u);
    out_order.push_back(v);
}

void dfs2(int v, int &color)
{
    used[v] = true;
    component[v] = color;
    for(int u: t_graph[v])
        if(!used[u])
            dfs2(u, color);
}

void add_join(int v, int u)
{
    i_graph[v].push_back(u);
}

void add_boolean(int &index)
{
    index = i_graph.size();
    i_graph.push_back(vector<int>());
}

int main()
{
    ios_base::sync_with_stdio(false);
    //freopen("input.txt", "r", stdin);

    cin >> n >> p >> M >> m;
    for(int i = 1; i <= p; i++)
    {
        add_boolean(vertex[i].iFalse);
        add_boolean(vertex[i].iTrue);
    }
    for(int power = 1; power <= M + 1; power++)
    {
        add_boolean(f_ge[power].iFalse);
        add_boolean(f_ge[power].iTrue);
    }

    for(int i = 0; i < n; i++)
    {
        int x, y;
        cin >> x >> y;
        add_join(vertex[x].iFalse, vertex[y].iTrue);
        add_join(vertex[y].iFalse, vertex[x].iTrue);
    }
    for(int i = 1; i <= p; i++)
    {
        int l, r;
        cin >> l >> r;
        add_join(vertex[i].iTrue, f_ge[l].iTrue);
        add_join(f_ge[l].iFalse, vertex[i].iFalse);

        add_join(vertex[i].iTrue, f_ge[r + 1].iFalse);
        add_join(f_ge[r + 1].iTrue, vertex[i].iFalse);
    }
    for(int i = 0; i < m; i++)
    {
        int v, u;
        cin >> v >> u;
        add_join(vertex[v].iTrue, vertex[u].iFalse);
        add_join(vertex[u].iTrue, vertex[v].iFalse);
    }

    for(int i = 1; i <= M; i++)
    {
        add_join(f_ge[i].iFalse, f_ge[i + 1].iFalse);
        add_join(f_ge[i + 1].iTrue, f_ge[i].iTrue);
    }
    /*cout << "\n";
    cout << "vertex\n";
    for(int i = 1; i <= p; i++)
        cout << i << ": " << vertex[i].iFalse << ' ' << vertex[i].iTrue << "\n";
    cout << "\n";
    cout << "f_ge\n";
    for(int i = 1; i <= M + 1; i++)
        cout << i << ": " << f_ge[i].iFalse << ' ' << f_ge[i].iTrue << "\n";
    cout << "\n";
    for(int i = 0; i < i_graph.size(); i++)
    {
        cout << i << ": ";
        for(int j : i_graph[i])
            cout << j << ' ';
        cout << "\n";
    }*/
    t_graph.assign(i_graph.size(), vector<int> ());
    for(int v = 0; v < i_graph.size(); v++)
        for(int u: i_graph[v])
            t_graph[u].push_back(v);

    used.assign(i_graph.size() + 1, 0);
    for(int v = 0; v < i_graph.size(); v++)
        if(!used[v])
            dfs1(v);

    used.assign(i_graph.size() + 1, 0);
    int components_count = 0;
    for(int i = out_order.size() - 1; i >= 0; i--)
    {
        if(!used[out_order[i]])
        {
            components_count++;
            dfs2(out_order[i], components_count);
        }
    }

    vector<int> result_vertices;
    for(int v = 1; v <= n; v++)
    {
        if(component[vertex[v].iTrue] == component[vertex[v].iFalse])
        {
            cout << -1;
            return 0;
        }
    }
    for(int power = 1; power <= M + 1; power++)
    {
        if(component[f_ge[power].iTrue] == component[f_ge[power].iFalse])
        {
            cout << -1;
            return 0;
        }
    }
    for(int v = 1; v <= p; v++)
    {

        if(component[vertex[v].iTrue] < component[vertex[v].iFalse])
            vertex[v].value = false;
        else
            vertex[v].value = true;
        if(vertex[v].value)
            result_vertices.push_back(v);
    }

    int f = 0;
    while(component[f_ge[f + 1].iFalse] < component[f_ge[f + 1].iTrue])
        f++;

    cout << result_vertices.size() << ' ' << f << "\n";
    for(int it : result_vertices)
        cout << it << ' ';
    return 0;
}


#include <iostream>
#include <vector>

using namespace std;

struct boolean
{
    int iTrue, iFalse;
    bool value;
};

vector<vector<int>> i_graph;
vector<vector<int>> t_graph;
boolean vertex[500000];
boolean f_ge[500000];
vector<char> used;
int component[2000000];
vector<int> out_order;
int n, m, M, p;

void dfs1(int v)
{
    used[v] = true;
    for(int u: i_graph[v])
        if(!used[u])
            dfs1(u);
    out_order.push_back(v);
}

void dfs2(int v, int &color)
{
    used[v] = true;
    component[v] = color;
    for(int u: t_graph[v])
        if(!used[u])
            dfs2(u, color);
}

void add_join(int v, int u)
{
    i_graph[v].push_back(u);
}

void add_boolean(int &index)
{
    index = i_graph.size();
    i_graph.push_back(vector<int>());
}

int main()
{
    ios_base::sync_with_stdio(false);
    //freopen("input.txt", "r", stdin);

    cin >> n >> p >> M >> m;
    for(int i = 1; i <= p; i++)
    {
        add_boolean(vertex[i].iFalse);
        add_boolean(vertex[i].iTrue);
    }
    for(int power = 1; power <= M + 1; power++)
    {
        add_boolean(f_ge[power].iFalse);
        add_boolean(f_ge[power].iTrue);
    }

    for(int i = 0; i < n; i++)
    {
        int x, y;
        cin >> x >> y;
        add_join(vertex[x].iFalse, vertex[y].iTrue);
        add_join(vertex[y].iFalse, vertex[x].iTrue);
    }
    for(int i = 1; i <= p; i++)
    {
        int l, r;
        cin >> l >> r;
        add_join(vertex[i].iTrue, f_ge[l].iTrue);
        add_join(f_ge[l].iFalse, vertex[i].iFalse);

        add_join(vertex[i].iTrue, f_ge[r + 1].iFalse);
        add_join(f_ge[r + 1].iTrue, vertex[i].iFalse);
    }
    for(int i = 0; i < m; i++)
    {
        int v, u;
        cin >> v >> u;
        add_join(vertex[v].iTrue, vertex[u].iFalse);
        add_join(vertex[u].iTrue, vertex[v].iFalse);
    }

    for(int i = 1; i <= M; i++)
    {
        add_join(f_ge[i].iFalse, f_ge[i + 1].iFalse);
        add_join(f_ge[i + 1].iTrue, f_ge[i].iTrue);
    }
    /*cout << "\n";
    cout << "vertex\n";
    for(int i = 1; i <= p; i++)
        cout << i << ": " << vertex[i].iFalse << ' ' << vertex[i].iTrue << "\n";
    cout << "\n";
    cout << "f_ge\n";
    for(int i = 1; i <= M + 1; i++)
        cout << i << ": " << f_ge[i].iFalse << ' ' << f_ge[i].iTrue << "\n";
    cout << "\n";
    for(int i = 0; i < i_graph.size(); i++)
    {
        cout << i << ": ";
        for(int j : i_graph[i])
            cout << j << ' ';
        cout << "\n";
    }*/
    t_graph.assign(i_graph.size(), vector<int> ());
    for(int v = 0; v < i_graph.size(); v++)
        for(int u: i_graph[v])
            t_graph[u].push_back(v);

    used.assign(i_graph.size() + 1, 0);
    for(int v = 0; v < i_graph.size(); v++)
        if(!used[v])
            dfs1(v);

    used.assign(i_graph.size() + 1, 0);
    int components_count = 0;
    for(int i = out_order.size() - 1; i >= 0; i--)
    {
        if(!used[out_order[i]])
        {
            components_count++;
            dfs2(out_order[i], components_count);
        }
    }

    vector<int> result_vertices;
    for(int v = 1; v <= n; v++)
    {
        if(component[vertex[v].iTrue] == component[vertex[v].iFalse])
        {
            cout << -1;
            return 0;
        }
    }
    for(int power = 1; power <= M + 1; power++)
    {
        if(component[f_ge[power].iTrue] == component[f_ge[power].iFalse])
        {
            cout << -1;
            return 0;
        }
    }
    for(int v = 1; v <= p; v++)
    {

        if(component[vertex[v].iTrue] < component[vertex[v].iFalse])
            vertex[v].value = false;
        else
            vertex[v].value = true;
        if(vertex[v].value)
            result_vertices.push_back(v);
    }

    int f = 0;
    while(component[f_ge[f + 1].iFalse] < component[f_ge[f + 1].iTrue])
        f++;

    cout << result_vertices.size() << ' ' << f << "\n";
    for(int it : result_vertices)
        cout << it << ' ';
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=16e5+3,M=4e6+3;
int o,t,he[N],to[M],ne[M],l[N],id,st[N],tp,bl[N],ct,ans[N];
void add(int x,int y){ne[++t]=he[x],to[t]=y,he[x]=t;}
void ins(int x,int y){add(x,y),add(y>o?y-o:y+o,x>o?x-o:x+o);}
void tar(int x){
	int i=he[x],p=++id,j;
	for(l[st[++tp]=x]=p;i;i=ne[i])if(!l[j=to[i]])tar(j),l[x]=min(l[x],l[j]);else if(!bl[j])l[x]=min(l[x],l[j]);
	if(l[x]==p)for(++ct;bl[st[tp]]=ct,st[tp--]!=x;);
}
int main(){
	int a,n,m,b,i,j,k;
	scanf("%d%d%d%d",&a,&n,&m,&b),o=n+m;
	while(a--)scanf("%d%d",&i,&j),ins(i+o,j);
	for(i=1;i<=n;++i)if(scanf("%d%d",&j,&k),ins(i,k+n),--j)ins(i,j+n+o);
	for(add(o*2,o);i<o;++i)ins(i,i+1);
	while(b--)scanf("%d%d",&i,&j),ins(i,j+o);
	for(i=1;i<=2*o;++i)if(!l[i])tar(i);
	for(i=1;i<=o;++i)if(bl[i]==bl[i+o])return puts("-1"),0;
	for(i=1,k=0;i<=n;++i)if(bl[i]<bl[i+o])ans[++k]=i;
	for(;bl[i]>bl[i+o];++i);
	printf("%d %d\n",k,i-n);
	for(i=1;i<=k;++i)printf("%d ",ans[i]);
	return 0;
}


#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const int N=400050;
struct node{
	int l,r,id;
}a[N];
int G[N<<3],to[N*50],nxt[N*50],sz=0,dfn[N<<3],col[N<<3],dfsc=0,st[N<<3],sl=-1,cnt=0,tot,id[N<<2],n,x,y,p;
vector<int> ans;
inline bool cmp1(node a,node b){return a.r<b.r;}
inline bool cmp2(node a,node b){return a.l<b.l;}
inline bool cmp3(node a,node b){return a.id<b.id;}
inline void adde(int u,int v){
	to[++sz]=v;nxt[sz]=G[u];G[u]=sz;
}
int dfs(int u){
	int i,v,lowu=dfn[u]=++dfsc,lowv;
	st[++sl]=u;
	for(i=G[u];i;i=nxt[i])if(!dfn[v=to[i]]){
		lowv=dfs(v);
		if(lowv<lowu)lowu=lowv;
	}else if(!col[v=to[i]]&&dfn[v]<lowu)lowu=dfn[v];
	if(lowu==dfn[u]){
		++cnt;
		do{
			v=st[sl--];
			col[v]=cnt;
		}while(v!=u);
	}
	return lowu;
}
void build(int o,int L,int R){
	if(L==R)id[o]=a[L].id+n;
	else{
		int lc=o<<1,rc=lc|1,M=L+R>>1;
		id[o]=++tot;
		build(lc,L,M);build(rc,M+1,R);
		adde(id[o],id[lc]);adde(id[o],id[rc]);
	}
}
void cov(int o,int L,int R){
	if(x<=L&&y>=R)adde(p,id[o]);
	else{
		int lc=o<<1,rc=lc|1,M=L+R>>1;
		if(x<=M)cov(lc,L,M);
		if(y>M)cov(rc,M+1,R);
	}
}
inline int bs1(int x){
	int l=0,r=n,mid;
	while(l<r){
		mid=l+r+1>>1;
		if(a[mid].r<x)l=mid;
		else r=mid-1;
	}
	return l;
}
inline int bs2(int x){
	int l=1,r=n+1,mid;
	while(l<r){
		mid=l+r>>1;
		if(a[mid].l>x)r=mid;
		else l=mid+1;
	}
	return l;
}
int main(){
	int q,M,m,i,u,v,L=0,R;
	scanf("%d%d%d%d",&q,&n,&M,&m);R=M;
	while(q--){
		scanf("%d%d",&u,&v);
		adde(u+n,v);adde(v+n,u);
	}
	for(i=1;i<=n;++i){scanf("%d%d",&a[i].l,&a[i].r);a[i].id=i;}
	while(m--){
		scanf("%d%d",&u,&v);
		adde(u,v+n);adde(v,u+n);
	}
	tot=n<<1;
	sort(a+1,a+n+1,cmp1);build(1,1,n);
	for(i=1;i<=n;++i){
		x=1;y=bs1(a[i].l);p=a[i].id;
		if(x<=y)cov(1,1,n);
	}
	sort(a+1,a+n+1,cmp2);build(1,1,n);
	for(i=1;i<=n;++i){
		y=n;x=bs2(a[i].r);p=a[i].id;
		if(x<=y)cov(1,1,n);
	}
	for(i=1;i<=tot;++i)if(!dfn[i])dfs(i);
	sort(a+1,a+n+1,cmp3);
	for(i=1;i<=n;++i){
		if(col[i]==col[i+n]){
			puts("-1");
			return 0;
		}
		if(col[i]<col[i+n]){
			ans.push_back(i);
			L=max(L,a[i].l);R=min(R,a[i].r);
		}
	}
//	printf("%.6lf\n",(double)(sizeof(G)+sizeof(nxt)+sizeof(to)+sizeof(dfn)+sizeof(col)+sizeof(st)+sizeof(id))/(1<<20));
	printf("%d %d\n",ans.size(),L);
	for(i=0;i<ans.size();++i)printf("%d ",ans[i]);
	return 0;
}


#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const int N=400050;
struct node{
	int l,r,id;
}a[N];
int G[N<<2],to[N*10],nxt[N*10],sz=0,dfn[N<<2],col[N<<2],dfsc=0,st[N<<2],sl=-1,cnt=0,tot,id[N],n;
vector<int> ans;
inline bool cmp1(node a,node b){return a.r<b.r;}
inline bool cmp2(node a,node b){return a.l<b.l;}
inline bool cmp3(node a,node b){return a.id<b.id;}
inline void adde(int u,int v){
	to[++sz]=v;nxt[sz]=G[u];G[u]=sz;
}
int dfs(int u){
	int i,v,lowu=dfn[u]=++dfsc,lowv;
	st[++sl]=u;
	for(i=G[u];i;i=nxt[i])if(!dfn[v=to[i]]){
		lowv=dfs(v);
		if(lowv<lowu)lowu=lowv;
	}else if(!col[v=to[i]]&&dfn[v]<lowu)lowu=dfn[v];
	if(lowu==dfn[u]){
		++cnt;
		do{
			v=st[sl--];
			col[v]=cnt;
		}while(v!=u);
	}
	return lowu;
}
inline int bs1(int x){
	int l=0,r=n,mid;
	while(l<r){
		mid=l+r+1>>1;
		if(a[mid].r<x)l=mid;
		else r=mid-1;
	}
	return l;
}
inline int bs2(int x){
	int l=1,r=n+1,mid;
	while(l<r){
		mid=l+r>>1;
		if(a[mid].l>x)r=mid;
		else l=mid+1;
	}
	return l;
}
int main(){
	int q,M,m,i,u,v,x,f=0;
	scanf("%d%d%d%d",&q,&n,&M,&m);
	while(q--){
		scanf("%d%d",&u,&v);
		adde(u+n,v);adde(v+n,u);
	}
	for(i=1;i<=n;++i){scanf("%d%d",&a[i].l,&a[i].r);a[i].id=i;}
	while(m--){
		scanf("%d%d",&u,&v);
		adde(u,v+n);adde(v,u+n);
	}
	tot=n<<1;
	sort(a+1,a+n+1,cmp1);
	for(adde(id[1]=++tot,a[1].id+n),i=2;i<=n;++i){adde(id[i]=++tot,id[i-1]);adde(id[i],a[i].id+n);}
	for(i=1;i<=n;++i)if(x=bs1(a[i].l))adde(a[i].id,id[x]);
	sort(a+1,a+n+1,cmp2);
	for(adde(id[n]=++tot,a[n].id+n),i=n-1;i;--i){adde(id[i]=++tot,id[i+1]);adde(id[i],a[i].id+n);}
	for(i=1;i<=n;++i)if((x=bs2(a[i].r))<=n)adde(a[i].id,id[x]);
	for(i=1;i<=tot;++i)if(!dfn[i])dfs(i);
	sort(a+1,a+n+1,cmp3);
	for(i=1;i<=n;++i){
		if(col[i]==col[i+n]){
			puts("-1");
			return 0;
		}
		if(col[i]<col[i+n]){
			ans.push_back(i);
			f=max(f,a[i].l);
		}
	}
	printf("%d %d\n",ans.size(),f);
	for(i=0;i<ans.size();++i)printf("%d ",ans[i]);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<vector>
using namespace std;
const int maxn=800003;
int n,p,M,m,N,cnt,idx,scc,siz;
int head[maxn],dfn[maxn],low[maxn],c[maxn];
vector<int> e[maxn];
int ans[maxn];
stack<int> s;
bool v[maxn];
bool flag;
void add(int u,int v)
{
	e[u].push_back(v);
}
void tarjan(int x)
{
	dfn[x]=low[x]=++idx;
	s.push(x);
	v[x]=true;
	for(int i=0;i<e[x].size();i++)
	{
		int to=e[x][i];
		if(!dfn[to])
		{
			tarjan(to);
			low[x]=min(low[x],low[to]);
		}
		else if(v[to]) low[x]=min(low[x],dfn[to]);
	}
	if(dfn[x]==low[x])
	{
		scc++;
		while(1)
		{
			int k=s.top();
			s.pop();
			v[k]=false;
			c[k]=scc;
			if(k==x) return;
		}
	}
}
void solve()
{
	for(int i=1;i<=N+N;i++)
		if(!dfn[i]) tarjan(i);
	for(int i=1;i<=N;i++)
		if(c[i]==c[i+N])
		{
			flag=true;
			return;
		}
}
int main()
{
	scanf("%d%d%d%d",&n,&p,&M,&m);
	N=p+M+1;
	for(int i=1;i<=n;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		add(x+N,y);
		add(y+N,x);
	}
	for(int i=1;i<=p;i++)
	{
		int l,r;
		scanf("%d%d",&l,&r);
		add(i,l+p+N);
		add(i,r+p+1);
		add(l+p,i+N);
		add(r+p+1+N,i+N);
	}
	for(int i=1;i<=M;i++)
	{
		add(i+p,i+p+1);
		add(i+p+1+N,i+p+N);
	}
	for(int i=1;i<=m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		add(u,v+N);
		add(v,u+N);
	}
	add(p+1,p+1+N);
	solve();
	if(flag)
	{
		puts("-1");
		return 0;
	}
	for(int i=1;i<=p;i++)
		if(c[i]<c[i+N]) ans[++siz]=i;
	for(int i=1;i<=M;i++)
		if(c[i+p+1]<c[i+p+1+N])
		{
			printf("%d %d\n",siz,i);
			break;
		}
	for(int i=1;i<=siz;i++)
		printf("%d ",ans[i]);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
using namespace std;
const int maxn=800003;
struct Edge
{
	int nxt,to;
}e[maxn*8];
int n,p,M,m,N,cnt,idx,scc,siz;
int head[maxn],dfn[maxn],low[maxn],c[maxn];
int ans[maxn];
stack<int> s;
bool v[maxn];
bool flag;
void add(int u,int v)
{
	e[++cnt].nxt=head[u];
	e[cnt].to=v;
	head[u]=cnt;
}
void tarjan(int x)
{
	dfn[x]=low[x]=++idx;
	s.push(x);
	v[x]=true;
	for(int i=head[x];i;i=e[i].nxt)
	{
		int to=e[i].to;
		if(!dfn[to])
		{
			tarjan(to);
			low[x]=min(low[x],low[to]);
		}
		else if(v[to]) low[x]=min(low[x],dfn[to]);
	}
	if(dfn[x]==low[x])
	{
		scc++;
		while(1)
		{
			int k=s.top();
			s.pop();
			v[k]=false;
			c[k]=scc;
			if(k==x) return;
		}
	}
}
void solve()
{
	for(int i=1;i<=N+N;i++)
		if(!dfn[i]) tarjan(i);
	for(int i=1;i<=N;i++)
		if(c[i]==c[i+N])
		{
			flag=true;
			return;
		}
}
int main()
{
	scanf("%d%d%d%d",&n,&p,&M,&m);
	N=p+M+1;
	for(int i=1;i<=n;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		add(x+N,y);
		add(y+N,x);
	}
	for(int i=1;i<=p;i++)
	{
		int l,r;
		scanf("%d%d",&l,&r);
		add(i,l+p+N);
		add(i,r+p+1);
		add(l+p,i+N);
		add(r+p+1+N,i+N);
	}
	for(int i=1;i<=M;i++)
	{
		add(i+p,i+p+1);
		add(i+p+1+N,i+p+N);
	}
	for(int i=1;i<=m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		add(u,v+N);
		add(v,u+N);
	}
	add(p+1,p+1+N);
	solve();
	if(flag)
	{
		puts("-1");
		return 0;
	}
	for(int i=1;i<=p;i++)
		if(c[i]<c[i+N]) ans[++siz]=i;
	for(int i=1;i<=M;i++)
		if(c[i+p+1]<c[i+p+1+N])
		{
			printf("%d %d\n",siz,i);
			break;
		}
	for(int i=1;i<=siz;i++)
		printf("%d ",ans[i]);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<vector>
using namespace std;
const int maxn=1200003;
int n,p,M,m,N,cnt,idx,scc,siz;
int head[maxn],dfn[maxn],low[maxn],c[maxn];
vector<int> e[maxn];
int ans[maxn];
stack<int> s;
bool v[maxn];
bool flag;
void add(int u,int v)
{
	e[u].push_back(v);
}
void tarjan(int x)
{
	dfn[x]=low[x]=++idx;
	s.push(x);
	v[x]=true;
	for(int i=0;i<e[x].size();i++)
	{
		int to=e[x][i];
		if(!dfn[to])
		{
			tarjan(to);
			low[x]=min(low[x],low[to]);
		}
		else if(v[to]) low[x]=min(low[x],dfn[to]);
	}
	if(dfn[x]==low[x])
	{
		scc++;
		while(1)
		{
			int k=s.top();
			s.pop();
			v[k]=false;
			c[k]=scc;
			if(k==x) return;
		}
	}
}
void solve()
{
	for(int i=1;i<=N+N;i++)
		if(!dfn[i]) tarjan(i);
	for(int i=1;i<=N;i++)
		if(c[i]==c[i+N])
		{
			flag=true;
			return;
		}
}
int main()
{
	scanf("%d%d%d%d",&n,&p,&M,&m);
	N=p+M+1;
	for(int i=1;i<=n;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		add(x+N,y);
		add(y+N,x);
	}
	for(int i=1;i<=p;i++)
	{
		int l,r;
		scanf("%d%d",&l,&r);
		add(i,l+p+N);
		add(i,r+p+1);
		add(l+p,i+N);
		add(r+p+1+N,i+N);
	}
	for(int i=1;i<=M;i++)
	{
		add(i+p,i+p+1);
		add(i+p+1+N,i+p+N);
	}
	for(int i=1;i<=m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		add(u,v+N);
		add(v,u+N);
	}
	add(p+1,p+1+N);
	solve();
	if(flag)
	{
		puts("-1");
		return 0;
	}
	for(int i=1;i<=p;i++)
		if(c[i]<c[i+N]) ans[++siz]=i;
	for(int i=1;i<=M;i++)
		if(c[i+p+1]<c[i+p+1+N])
		{
			printf("%d %d\n",siz,i);
			break;
		}
	for(int i=1;i<=siz;i++)
		printf("%d ",ans[i]);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<vector>
using namespace std;
const int maxn=1600003;
int n,p,M,m,N,cnt,idx,scc,siz;
int head[maxn],dfn[maxn],low[maxn],c[maxn];
vector<int> e[maxn];
int ans[maxn];
stack<int> s;
bool v[maxn];
bool flag;
void add(int u,int v)
{
	e[u].push_back(v);
}
void tarjan(int x)
{
	dfn[x]=low[x]=++idx;
	s.push(x);
	v[x]=true;
	for(int i=0;i<e[x].size();i++)
	{
		int to=e[x][i];
		if(!dfn[to])
		{
			tarjan(to);
			low[x]=min(low[x],low[to]);
		}
		else if(v[to]) low[x]=min(low[x],dfn[to]);
	}
	if(dfn[x]==low[x])
	{
		scc++;
		while(1)
		{
			int k=s.top();
			s.pop();
			v[k]=false;
			c[k]=scc;
			if(k==x) return;
		}
	}
}
void solve()
{
	for(int i=1;i<=N+N;i++)
		if(!dfn[i]) tarjan(i);
	for(int i=1;i<=N;i++)
		if(c[i]==c[i+N])
		{
			flag=true;
			return;
		}
}
int main()
{
	scanf("%d%d%d%d",&n,&p,&M,&m);
	N=p+M+1;
	for(int i=1;i<=n;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		add(x+N,y);
		add(y+N,x);
	}
	for(int i=1;i<=p;i++)
	{
		int l,r;
		scanf("%d%d",&l,&r);
		add(i,l+p+N);
		add(i,r+p+1);
		add(l+p,i+N);
		add(r+p+1+N,i+N);
	}
	for(int i=1;i<=M;i++)
	{
		add(i+p,i+p+1);
		add(i+p+1+N,i+p+N);
	}
	for(int i=1;i<=m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		add(u,v+N);
		add(v,u+N);
	}
	add(p+1,p+1+N);
	solve();
	if(flag)
	{
		puts("-1");
		return 0;
	}
	for(int i=1;i<=p;i++)
		if(c[i]<c[i+N]) ans[++siz]=i;
	for(int i=1;i<=M;i++)
		if(c[i+p+1]<c[i+p+1+N])
		{
			printf("%d %d\n",siz,i);
			break;
		}
	for(int i=1;i<=siz;i++)
		printf("%d ",ans[i]);
	return 0;
}


#include<iostream>
using namespace std;
int main()
{
    cout<<"-1";
    return 0;
}


#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#define NM 400040
using namespace std;
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
	return x*f;
}
int n,m,p,M,x,y,l,r,u,v,N,num,ans[NM];
int bh,head[NM<<2];
int dfn[NM<<2],low[NM<<2],tim,stac[NM<<2],top,color[NM<<2],cnt;
bool vis[NM<<2];
struct node{
	int to,nxt;
}e[NM*10];
inline int id(int x,int k){return x+N*k;}
inline void add(int u,int v){
	e[++bh].to=v;e[bh].nxt=head[u];head[u]=bh;
}
inline void tarjan(int u)
{
	dfn[u]=low[u]=++tim;
	vis[u]=1;stac[++top]=u;
	for(int i=head[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(!dfn[v])
		{
			tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else if(vis[v]) low[u]=min(low[u],dfn[v]);
	}
	if(dfn[u]==low[u])
	{
		cnt++;int now;
		do{
			now=stac[top--];
			vis[now]=0;color[now]=cnt;
		}while(u!=now);
	}
}
inline void two_sat()
{
	for(int i=1;i<=(N<<1);i++)
		if(!dfn[i]) tarjan(i);
	for(int i=1;i<=N;i++)
	{
		if(color[i]==color[i+N])
		{
			printf("-1");
			exit(0);
		}
	}
}
int main()
{
	n=read();p=read();M=read();m=read();
	N=p+M+1;
	for(int i=1;i<=n;i++)
	{
		x=read();y=read();
		add(id(x,1),id(y,0));add(id(y,1),id(x,0));
	}
	for(int i=1;i<=M;i++)
	{
		add(id(p+i,0),id(p+i+1,0));//0表示<,1表示>=
		add(id(p+i+1,1),id(p+i,1));
	}
	add(id(p+1,0),id(p+1,1));//p+1这个点选连到不选上
	for(int i=1;i<=p;i++)
	{
		l=read();r=read();
		add(id(i,0),id(p+l,1));
		add(id(i,0),id(p+r+1,0));
		add(id(p+l,0),id(i,1));
		add(id(p+r+1,1),id(i,1));
	}
	for(int i=1;i<=m;i++)
	{
		u=read();v=read();
		add(id(u,0),id(v,1));
		add(id(v,0),id(u,1));
	}
	two_sat();
	for(int i=1;i<=p;i++)
		if(color[id(i,0)]<color[id(i,1)])
			ans[++num]=i;
	for(int i=1;i<=M;i++)
	{
		if(color[id(i+p+1,0)]<color[id(i+p+1,1)])
		{
			printf("%d %d\n",num,i);
			break;
		}
	}
	for(int i=1;i<=num;i++) printf("%d ",ans[i]);
	return 0;
}


#include <stack>
#include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define DB double
#define LL int
#define MAXN 2000005
#define Int register int

using namespace std;

inline void read(LL &x)
{
	x = 0;
	LL f = 1;
	char s = getchar();
	while (s < '0' || s > '9')
	{
		if (s == '-')
			f = -1;
		s = getchar();
	}
	while (s >= '0' && s <= '9')
	{
		x = (x << 3) + (x << 1) + (s ^ 48);
		s = getchar();
	}
	x *= f;
}

inline LL Max(LL x,LL y)
{
	return x > y ? x : y;
}

inline LL Min(LL x,LL y)
{
	return x < y ? x : y;
}

bool InStack[MAXN];

stack<LL> S;
vector<LL> G[MAXN];
vector<LL> FG[MAXN];

LL Color, Opp[MAXN], Col[MAXN], Du[MAXN], Dfn[MAXN], Low[MAXN], Bel[MAXN], Cnt, tot;

void Tarjan(LL x)
{
	S.push( x );
	InStack[x] = 1;
	Dfn[x] = Low[x] = ++ Cnt;
	int l = G[x].size();
	for (Int i = 0; i < l; ++ i)
	{
		LL to = G[x][i];
		if (! Dfn[to])
		{
			Tarjan( to );
			Low[x] = Min(Low[to], Low[x]);
		}
		else if (InStack[to])
			Low[x] = Min(Low[x], Dfn[to]);
	}

	if (Dfn[x] == Low[x])
	{
		++ tot;
		LL v;
		do
		{
			v = S.top();
			S.pop();
			Col[v] = Color;
			InStack[v] = 0;
			Bel[v] = tot;
		} while(v != x);
		Color ++;
	}
}

LL n, p, M, m, x[MAXN], y[MAXN], l[MAXN], r[MAXN], u[MAXN], v[MAXN];

inline LL Yes(LL x)
{
	return x << 1;
}

inline LL No(LL x)
{
	return x << 1 | 1;
}

int main()
{
	read( n ); read( p ); read( M ); read( m );
	for (Int i = 0; i < n; ++ i)
	{
		read( x[i] ); read( y[i] );
		x[i] --, y[i] --;
		G[No( x[i] )].push_back( Yes( y[i] ) );
		G[No( y[i] )].push_back( Yes( x[i] ) );
		// 0 - p - 1
	}
	for (Int i = 0; i < M; ++ i)
	{
		G[Yes(p + i)].push_back(Yes(p + i + 1));
		G[No(p + i + 1)].push_back(No(p + i));
	}
	G[Yes( p )].push_back(No( p ));
	for (Int i = 0; i < p; ++ i)
	{
		read( l[i] ); read( r[i] );
		G[Yes( i )].push_back(No(p + l[i] - 1));
		G[Yes(p + l[i] - 1)].push_back(No( i ));
		G[Yes( i )].push_back(Yes(p + r[i]));
		G[No(p + r[i])].push_back(No( i ));
	}
	for (Int i = 0; i < m; ++ i)
	{
		read( u[i] ); read( v[i] );
		u[i] --, v[i] --;
		G[Yes( u[i] )].push_back(No( v[i] ));
		G[Yes( v[i] )].push_back(No( u[i] ));
	}
	for (Int i = 0; i <= No(p + M); ++ i)
	{
		if (! Dfn[i])
			Tarjan( i );
	}
	for (Int i = 0; i <= p + M; ++ i)
	{
		if (Bel[Yes( i )] == Bel[No( i )])
			return ! printf("-1");
		Opp[Bel[Yes( i )]] = Bel[No( i )];
		Opp[Bel[No( i )]] = Bel[Yes( i )];
	}
	queue<LL> Q;
	for (Int i = 0; i <= No(p + M); ++ i)
	{
		int l = G[i].size();
		LL x = Bel[i];
		for (Int j = 0; j < l; ++ j)
		{
			LL to = Bel[G[i][j]];
			if (x == to)
				continue;
			FG[to].push_back( x );
			Du[x] ++;
		}
	}
	/*for (Int i = 1; i <= tot; ++ i)
		if (! Du[i])
			Q.push( i );
	while (! Q.empty())
	{
		LL x = Q.front();
		Q.pop();
		if (! Col[x])
		{
			Col[x] = 1;
			Col[Opp[x]] = 2;
		}
		int l = FG[x].size();
		for (Int i = 0; i < l; ++ i)
		{
			LL to = FG[x][i];
			if (-- Du[to] == 0)
				Q.push( to );
		}
	}*/
	LL Chosen = 0;
	for (Int i = 0; i < p; ++ i)
		if (Col[Yes( i )] < Col[No( i )])
			Chosen ++;
	for (Int i = 1; i <= M; ++ i)
		if (Col[Yes(p + i)] < Col[No(p + i)])
		{
			printf("%d %d\n", Chosen, i);
			break;
		}
	for (Int i = 0; i < p; ++ i)
		if (Col[Yes( i )] < Col[No( i )])
			printf("%d ", i + 1);
	return 0;
}
/*
if i then li && ri
if li then ! i
if ! ri then ! i
*/


#define FRER() freopen("/Users/seven7777777/Desktop/Code/TESTXCODE/TESTXCODE/i.txt","r",stdin)
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5;
int nEdge,n,p,M,m,dfn;
int head[N],to[N],nxt[N],pre[N],sccno[N],scc_cnt;
void addEdge(int u,int v){
    to[nEdge]=v;nxt[nEdge]=head[u];head[u]=nEdge++;
}
stack<int>s;
int dfs(int u){
    int lowu = pre[u] = ++dfn;
    s.push(u);
    for(int e=head[u];~e;e=nxt[e]){
        int v = to[e];
        if(pre[v]==-1){
            int lowv = dfs(v);
            lowu = min(lowu,lowv);
        }else if(!sccno[v]) lowu = min(pre[v],lowu);
    }
    if(lowu == pre[u]){
        ++scc_cnt;
        int v;
        do{
            v = s.top();
            s.pop();
            sccno[v] = scc_cnt;
        }while(u!=v);
    }
    return lowu;
}

int main()
{
    //FRER();
    nEdge = dfn = 0;
    memset(head, -1, sizeof(head));
    memset(pre, -1, sizeof(pre));
    scc_cnt = dfn = 0;
    scanf("%d%d%d%d",&n,&p,&M,&m);
    for(int i=1;i<=n;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        addEdge(u<<1, v<<1|1);
        addEdge(v<<1, u<<1|1);
    }
    for(int i=1;i<=M;i++){
        addEdge((p+i+1)<<1, (p+i)<<1);
        addEdge((p+i)<<1|1, (p+i+1)<<1|1);
    }
    for(int i=1;i<=p;i++){
        int l,r;
        scanf("%d%d",&l,&r);
        addEdge((p+l)<<1|1, i<<1);
        addEdge(i<<1|1, (p+l)<<1);
        addEdge((p+r+1)<<1, i<<1);
        addEdge(i<<1|1, (p+r+1)<<1|1);
    }
    for(int i=1;i<=m;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        addEdge(u<<1|1, v<<1);
        addEdge(v<<1|1, u<<1);
    }    for(int i=1;i<=(p+M)*2+3;i++){
        if(pre[i]==-1) dfs(i);
    }
    for(int i=1;i<=p+M;i++){
        if(sccno[i<<1]==sccno[i<<1|1]) return 0*printf("-1\n");
    }
    int ans = 0;
    for(int i=1;i<=p;i++) if(sccno[i<<1|1]<sccno[i<<1]) ans++;
    for(int i=M;i>=1;i--){
        if(sccno[i<<1|1]<sccno[i<<1]){
            printf("%d %d\n",ans,i);
            for(int j=1;j<=p;j++){
                if(sccno[j<<1|1]<sccno[j<<1]) printf("%d ",j);
            }
            return 0*puts("");
        }
    }
}


#include <bits/stdc++.h>

const int N = 1e6 + 5;

inline void cmin(int &a, int b) { a = a < b ? a : b; }
inline void cmax(int &a, int b) { a = a > b ? a : b; }

struct Edge {
	int to, next;
} edge[N << 2];

int head[N], dfn[N], low[N], stk[N], bl[N], pre[N], suf[N], l[N], r[N];
int n, p, m, M, idx, top, cntb, tot = 1;
std::vector<int> ansc;

void addedge(int u, int v) {
	edge[tot] = {v, head[u]};
	head[u] = tot++;
}

void tarjan(int u) {
	dfn[u] = low[u] = ++idx;
	stk[++top] = u;
	for (int i = head[u]; i; i = edge[i].next) {
		int v = edge[i].to;
		if (!dfn[v]) {
			tarjan(v), cmin(low[u], low[v]);
		} else {
			if (!bl[v]) cmin(low[u], dfn[v]);
		}
	}
	if (dfn[u] == low[u]) {
		cntb++;
		while (stk[top] != u) bl[stk[top--]] = cntb;
		bl[stk[top--]] = cntb;
	}
}

int main() {
	scanf("%d%d%d%d", &n, &p, &M, &m);
	int cnt = p * 2;
	pre[1] = ++cnt, suf[1] = cnt + M;
	for (int i = 2; i <= M; i++) {
		pre[i] = ++cnt;
		suf[i] = cnt + M;
		addedge(pre[i], pre[i - 1]);
		addedge(suf[i - 1], suf[i]);
	}
	for (int i = 1; i <= n; i++) {
		int x, y;
		scanf("%d%d", &x, &y);
		addedge(x + p, y);
		addedge(y + p, x);
	}
	for (int i = 1; i <= p; i++) {
		scanf("%d%d", &l[i], &r[i]);
		if (l[i] > 1) addedge(i, pre[l[i] - 1]);
		if (r[i] < M) addedge(i, suf[r[i] + 1]);
		addedge(suf[l[i]], i + p);
		addedge(pre[r[i]], i + p);
	}
	for (int i = 1; i <= m; i++) {
		int x, y;
		scanf("%d%d", &x, &y);
		addedge(x, y + p);
		addedge(y, x + p);
	}
	for (int i = 1; i <= 2 * p; i++)
		if (!dfn[i]) tarjan(i);
	for (int i = 1; i <= p; i++)
		if (bl[i] == bl[i + p]) {
			printf("-1\n");
			return 0;
		}
	int ans = 0;
	for (int i = 1; i <= p; i++)
		if (bl[i] < bl[i + p]) {
			ans = std::max(ans, l[i]);
			ansc.push_back(i);
		}
	printf("%d %d\n", ansc.size(), ans);
	for (auto t : ansc) printf("%d ", t);
	printf("\n");
	return 0;
}


#define FRER() freopen("/Users/seven7777777/Desktop/Code/TESTXCODE/TESTXCODE/i.txt","r",stdin)
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5;
int nEdge,n,p,M,m,dfn;
int head[N],to[N],nxt[N],pre[N],sccno[N],scc_cnt;
void addEdge(int u,int v){
    to[nEdge]=v;nxt[nEdge]=head[u];head[u]=nEdge++;
}
stack<int>s;
int dfs(int u){
    int lowu = pre[u] = ++dfn;
    s.push(u);
    for(int e=head[u];~e;e=nxt[e]){
        int v = to[e];
        if(pre[v]==-1){
            int lowv = dfs(v);
            lowu = min(lowu,lowv);
        }else if(!sccno[v]) lowu = min(pre[v],lowu);
    }
    if(lowu == pre[u]){
        ++scc_cnt;
        int v;
        do{
            v = s.top();
            s.pop();
            sccno[v] = scc_cnt;
        }while(u!=v);
    }
    return lowu;
}

int main()
{
    //FRER();
    nEdge = dfn = 0;
    memset(head, -1, sizeof(head));
    memset(pre, -1, sizeof(pre));
    scc_cnt = dfn = 0;
    scanf("%d%d%d%d",&n,&p,&M,&m);
    for(int i=1;i<=n;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        addEdge(u<<1, v<<1|1);
        addEdge(v<<1, u<<1|1);
    }
    for(int i=1;i<=M;i++){
        addEdge((p+i+1)<<1, (p+i)<<1);
        addEdge((p+i)<<1|1, (p+i+1)<<1|1);
    }
    for(int i=1;i<=p;i++){
        int l,r;
        scanf("%d%d",&l,&r);
        addEdge((p+l)<<1|1, i<<1);
        addEdge(i<<1|1, (p+l)<<1);
        addEdge((p+r+1)<<1, i<<1);
        addEdge(i<<1|1, (p+r+1)<<1|1);
    }
    for(int i=1;i<=m;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        addEdge(u<<1|1, v<<1);
        addEdge(v<<1|1, u<<1);
    }    for(int i=1;i<=(p+M)*2+3;i++){
        if(pre[i]==-1) dfs(i);
    }
    for(int i=1;i<=p+M;i++){
        if(sccno[i<<1]==sccno[i<<1|1]) return 0*printf("-1\n");
    }
    int ans = 0;
    for(int i=1;i<=p;i++) if(sccno[i<<1|1]<sccno[i<<1]) ans++;
    for(int i=M;i>=1;i--){
        if(sccno[(i+p)<<1|1]<sccno[(i+p)<<1]){
            printf("%d %d\n",ans,i);
            for(int j=1;j<=p;j++){
                if(sccno[j<<1|1]<sccno[j<<1]) printf("%d ",j);
            }
            return 0*puts("");
        }
    }
}


#include <bits/stdc++.h>

const int N = 2e6 + 5;

inline void cmin(int &a, int b) { a = a < b ? a : b; }
inline void cmax(int &a, int b) { a = a > b ? a : b; }

struct Edge {
	int to, next;
} edge[N << 2];

int head[N], dfn[N], low[N], stk[N], bl[N], pre[N], suf[N], l[N], r[N];
int n, p, m, M, idx, top, cntb, tot = 1;
std::vector<int> ansc;

void addedge(int u, int v) {
	edge[tot] = {v, head[u]};
	head[u] = tot++;
}

void tarjan(int u) {
	dfn[u] = low[u] = ++idx;
	stk[++top] = u;
	for (int i = head[u]; i; i = edge[i].next) {
		int v = edge[i].to;
		if (!dfn[v]) {
			tarjan(v), cmin(low[u], low[v]);
		} else {
			if (!bl[v]) cmin(low[u], dfn[v]);
		}
	}
	if (dfn[u] == low[u]) {
		cntb++;
		while (stk[top] != u) bl[stk[top--]] = cntb;
		bl[stk[top--]] = cntb;
	}
}

int main() {
	scanf("%d%d%d%d", &n, &p, &M, &m);
	int cnt = p * 2;
	pre[1] = ++cnt, suf[1] = cnt + M;
	for (int i = 2; i <= M; i++) {
		pre[i] = ++cnt;
		suf[i] = cnt + M;
		addedge(pre[i], pre[i - 1]);
		addedge(suf[i - 1], suf[i]);
	}
	for (int i = 1; i <= n; i++) {
		int x, y;
		scanf("%d%d", &x, &y);
		addedge(x + p, y);
		addedge(y + p, x);
	}
	for (int i = 1; i <= p; i++) {
		scanf("%d%d", &l[i], &r[i]);
		if (l[i] > 1) addedge(i, pre[l[i] - 1]);
		if (r[i] < M) addedge(i, suf[r[i] + 1]);
		addedge(suf[l[i]], i + p);
		addedge(pre[r[i]], i + p);
	}
	for (int i = 1; i <= m; i++) {
		int x, y;
		scanf("%d%d", &x, &y);
		addedge(x, y + p);
		addedge(y, x + p);
	}
	for (int i = 1; i <= 2 * p; i++)
		if (!dfn[i]) tarjan(i);
	for (int i = 1; i <= p; i++)
		if (bl[i] == bl[i + p]) {
			printf("-1\n");
			return 0;
		}
	int ans = 0;
	for (int i = 1; i <= p; i++)
		if (bl[i] < bl[i + p]) {
			ans = std::max(ans, l[i]);
			ansc.push_back(i);
		}
	printf("%d %d\n", ansc.size(), ans);
	for (auto t : ansc) printf("%d ", t);
	printf("\n");
	return 0;
}


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

const int N=2000010;
int n,p,M,m,sum,deep,colour,v[N],dfn[N],low[N],color[N];
int ver[N<<1],Next[N<<1],head[N],tot;
stack<int> st;

inline int read(){
    int x=0,tmp=1;
    char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') tmp=-1;ch=getchar();}
    while(isdigit(ch)) {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return tmp*x;
}

inline void write(int x)
{
    if(x<0) putchar('-'),x=-x;
    int y=10,len=1;
    while(y<=x) y=(y<<3)+(y<<1),len++;
    while(len--) y/=10,putchar(x/y+48),x%=y;
}

inline void addEdge(int x,int y)
{
    ver[++tot]=y;
    Next[tot]=head[x];
    head[x]=tot;
}

void tarjan(int x)
{
    low[x]=dfn[x]=++deep;
    v[x]=1; st.push(x);
    for(int i=head[x]; i; i=Next[i])
	{
        int y=ver[i];
        if(dfn[y]==-1)
		{
            tarjan(y);
            low[x]=min(low[x],low[y]);
        }
        else if(v[y]) low[x]=min(low[x],dfn[y]);
    }
    if(dfn[x]==low[x])
	{
        color[x]=++colour;
        v[x]=0;
        while(st.top()!=x){
            color[st.top()]=colour;
            v[st.top()]=0;
            st.pop();
        }
        st.pop();
    }
}

inline int yes(int p){return p<<1;}
inline int no(int p){return p<<1|1;}

int main(){
    n=read(); p=read(); M=read(); m=read();
    for(int i=1; i<=n; i++)
	{
        int x=read()-1,y=read()-1;
        addEdge(no(x),yes(y));
        addEdge(yes(y)^1,no(x)^1);
    }
    for(int i=0; i<M; i++)
	{
        addEdge(yes(p+i),yes(p+i+1));
        addEdge(yes(p+i+1)^1,yes(p+i)^1);
    }
    addEdge(yes(p),no(p));
    addEdge(no(p)^1,yes(p)^1);
    for(int i=0; i<p; i++)
	{
        int l=read(),r=read();
        addEdge(yes(i),no(p+l-1));
        addEdge(no(p+l-1)^1,yes(i)^1);
        addEdge(yes(i),yes(p+r));
        addEdge(yes(p+r)^1,yes(i)^1);
    }
    for(int i=0; i<m; i++)
	{
        int x=read()-1,y=read()-1;
        addEdge(yes(x),no(y));
        addEdge(no(y)^1,yes(x)^1);
    }
    memset(dfn,-1,sizeof(dfn));
    for(int i=0; i<=no(p+M); i++) if(dfn[i]==-1) tarjan(i);
	for(int i=0; i<=p+M; i++) if(color[yes(i)]==color[no(i)]) return printf("-1")&0;
    for(int i=0; i<p; i++) if(color[yes(i)]<color[no(i)]) sum++;
    for(int i=1; i<=M; i++)
	{
        if(color[yes(p+i)]<color[no(p+i)])
		{
            write(sum); putchar(' ');
            write(i); putchar('\n');
            break;
        }
    }
    for(int i=0; i<p; i++)
	{
        if(color[yes(i)]<color[no(i)])
		{
            write(i+1);
            putchar(' ');
        }
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define N 2000005
#define E 4000005
#define yes(u) u<<1
#define no(u) u<<1|1

struct Edge
{
    int tot,fst[N],nxt[E],to[E];
    List()
	{
		memset(fst,-1,sizeof(fst));
	}

    inline void insert(int u, int v)
	{
        nxt[tot]=fst[u];
		to[tot]=v;
		fst[u]=tot++;
    }

    inline void link(int u, int v)
	{
        insert(u,v);
		insert(v^1,u^1);
    }
}e;

int n,m,m0,m1;
int k,c,tms,vol;
int dfn[N],low[N],stc[N],col[N];
bool ins[N];

void tarjan(int u)
{
    dfn[u]=low[u]=tms++;
    int pos=vol;
	stc[vol++]=u;
	ins[u]=true;
    for(int i=e.fst[u];~i;i=e.nxt[i])
	{
        int v=e.to[i];
        if(dfn[v]==-1)
		{
            tarjan(v);
            low[u]=min(low[u], low[v]);
        }
		else if(ins[v]) low[u]=min(low[u],dfn[v]);
    }
    if (dfn[u]==low[u])
	{
        while (vol>pos)
		{
            int v=stc[--vol];
            col[v]=c;
			ins[v]=false;
        }
		c++;
    }
}

bool solve()
{
    for(int i=0;i<=no(n+m);i++) dfn[i]=-1;
    for(int i=0;i<=no(n+m);i++) if(dfn[i]==-1) tarjan(i);
    for(int i=0;i<=n+m;i++) {if(col[yes(i)]==col[no(i)]) return false;}
    return true;
}

int main()
{
    scanf("%d%d%d%d",&m0,&n,&m,&m1);
    for(int i=0;i<m0;i++)
	{
        int u,v;
        scanf("%d%d",&u,&v);
		u--,v--;
        e.link(no(u), yes(v));
    }
    for(int i=0;i<m;i++) e.link(yes(n+i),yes(n+i+1));
	e.link(yes(n),no(n));
    for(int i=0;i<n;i++)
	{
		int l,r;
        scanf("%d%d",&l,&r);
        e.link(yes(i),no(n+l-1));
        e.link(yes(i),yes(n+r));
    }
    for(int i=0;i<m1;i++)
	{
		int u,v;
        scanf("%d%d",&u,&v);
		u--,v--;
        e.link(yes(u), no(v));
    }
    if(solve());
	{
        for(int i=0;i<n;i++) if(col[yes(i)]<col[no(i)]) k++;
        for(int i=1;i<=m;i++)
		{
            if(col[yes(n+i)]<col[no(n+i)])
			{
                printf("%d %d\n", k,i);
				break;
            }
        }
        for (int i=0;i<n;i++) if(col[yes(i)]<col[no(i)]) printf("%d ",i+1);
    }
	//else puts("-1");
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define N 2000005
#define E 4000005
#define yes(u) u<<1
#define no(u) u<<1|1

struct Edge
{
    int tot,fst[N],nxt[E],to[E];
    List()
	{
		memset(fst,-1,sizeof(fst));
	}

    inline void insert(int u, int v)
	{
        nxt[tot]=fst[u];
		to[tot]=v;
		fst[u]=tot++;
    }

    inline void link(int u, int v)
	{
        insert(u,v);
		insert(v^1,u^1);
    }
}e;

int n,m,m0,m1;
int k,c,tms,vol;
int dfn[N],low[N],stc[N],col[N];
bool ins[N];

void tarjan(int u)
{
    dfn[u]=low[u]=tms++;
    int pos=vol;
	stc[vol++]=u;
	ins[u]=true;
    for(int i=e.fst[u];~i;i=e.nxt[i])
	{
        int v=e.to[i];
        if(dfn[v]==-1)
		{
            tarjan(v);
            low[u]=min(low[u], low[v]);
        }
		else if(ins[v]) low[u]=min(low[u],dfn[v]);
    }
    if (dfn[u]==low[u])
	{
        while (vol>pos)
		{
            int v=stc[--vol];
            col[v]=c;
			ins[v]=false;
        }
		c++;
    }
}

bool solve()
{
    for(int i=0;i<=no(n+m);i++) dfn[i]=-1;
    for(int i=0;i<=no(n+m);i++) if(dfn[i]==-1) tarjan(i);
    for(int i=0;i<=n+m;i++) {if(col[yes(i)]==col[no(i)]) return false;}
    return true;
}

int main()
{
    scanf("%d%d%d%d",&m0,&n,&m,&m1);
    for(int i=0;i<m0;i++)
	{
        int u,v;
        scanf("%d%d",&u,&v);
		u--,v--;
        e.link(no(u), yes(v));
    }
    for(int i=0;i<m;i++) e.link(yes(n+i),yes(n+i+1));
	e.link(yes(n),no(n));
    for(int i=0;i<n;i++)
	{
		int l,r;
        scanf("%d%d",&l,&r);
        e.link(yes(i),no(n+l-1));
        e.link(yes(i),yes(n+r));
    }
    for(int i=0;i<m1;i++)
	{
		int u,v;
        scanf("%d%d",&u,&v);
		u--,v--;
        e.link(yes(u), no(v));
    }
    if(solve())
	{
        for(int i=0;i<n;i++) if(col[yes(i)]<col[no(i)]) k++;
        for(int i=1;i<=m;i++)
		{
            if(col[yes(n+i)]<col[no(n+i)])
			{
                printf("%d %d\n", k,i);
				break;
            }
        }
        for (int i=0;i<n;i++) if(col[yes(i)]<col[no(i)]) printf("%d ",i+1);
    }
	else puts("-1");
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=4e5+5;
int n,p,M,m;
int node,id[N],yes[N*2],no[N*2],head[N*4],ce;
bool vis[N*4];
struct edge{int to,nxt;} e[N*6];
void adde(int a,int b) {e[++ce]=(edge){b,head[a]},head[a]=ce;}
vector<int> cs;
int f;
int rd() {
    char ch=getchar(); int x=0;
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-48,ch=getchar();return x;
}
void build()
{
	for(int i=1;i<=p;++i) yes[i]=++node,no[i]=++node;
	for(int i=0;i<=M;++i) id[i]=p+i+1;
	for(int i=0;i<=M;++i) yes[id[i]]=++node,no[id[i]]=++node;
	for(int i=1;i<=n;++i)
	{
		int x,y;
		x=rd(),y=rd();
		adde(no[x],yes[y]); adde(no[y],yes[x]);
	}
	for(int i=1;i<=p;++i)
	{
		int l,r;
		l=rd(),r=rd();
		adde(yes[i],yes[id[r]]); adde(yes[i],no[id[l-1]]);
		adde(no[id[r]],no[i]); adde(yes[id[l-1]],no[i]);
	}
	for(int i=1;i<=m;++i)
	{
		int u,v;
		u=rd(),v=rd();
		adde(yes[u],no[v]); adde(yes[v],no[u]);
	}
	for(int i=0;i<=M;++i)
	{
		if(i>0) adde(no[id[i]],no[id[i-1]]);
		if(i<M) adde(yes[id[i]],yes[id[i+1]]);
	}
	adde(yes[id[0]],no[id[0]]);
}
int dfn[N],low[N],Time,st[N],top,ins[N],c[N],cnt;
void tarjan(int u)
{
	dfn[u]=low[u]=++Time,st[++top]=u,ins[u]=1;
	for(int i=head[u],v;i;i=e[i].nxt)
	{
		v=e[i].to;
		if(!dfn[v]) tarjan(v),low[u]=min(low[v],low[u]);
		else if(ins[v]) low[u]=min(dfn[v],low[u]);
	}
	if(low[u]==dfn[u])
	{
		int v=-1; ++cnt;
	//	cout<<cnt<<":"<<endl;
		while(v!=u)
		{
			v=st[top--],ins[v]=0,c[v]=cnt;
	//		cout<<v<<" ";
		}
	//	puts("");
	}
}
int main()
{
	scanf("%d%d%d%d",&n,&p,&M,&m);
	build();
	for(int i=1;i<=node;++i)
		if(!dfn[i]) tarjan(i);
	for(int i=1;i<=p;++i) if(c[yes[i]] == c[no[i]]) {puts("-1"); return 0;}
	for(int i=0;i<=M;++i) if(c[yes[id[i]]] == c[no[id[i]]]) {puts("-1"); return 0;}
	for(int i=1;i<=p;++i) if(c[yes[i]]<c[no[i]]) cs.push_back(i);
	for(int i=0;i<=M;++i)
		if(c[yes[id[i]]] < c[no[id[i]]]) {f=i; break;}
	printf("%d %d\n",(int)cs.size(),f);
	for(int i=0;i<cs.size();++i) printf("%d ",cs[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=4e5+5;
int n,p,M,m;
int node,id[N],yes[N*2],no[N*2],head[N*4],ce;
bool vis[N*4];
struct edge{int to,nxt;} e[N*6];
void adde(int a,int b) {e[++ce]=(edge){b,head[a]},head[a]=ce;}
vector<int> cs;
int f;
void build()
{
	for(int i=1;i<=p;++i) yes[i]=++node;
	for(int i=1;i<=p;++i) no[i]=++node;
	for(int i=0;i<=M;++i) id[i]=p+i+1;
	for(int i=0;i<=M;++i) yes[id[i]]=++node;
	for(int i=0;i<=M;++i) no[id[i]]=++node;
	for(int i=1;i<=n;++i)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		adde(no[x],yes[y]); adde(no[y],yes[x]);
	}
	for(int i=1;i<=p;++i)
	{
		int l,r;
		scanf("%d%d",&l,&r);
		adde(yes[i],yes[id[r]]); adde(yes[i],no[id[l-1]]);
		adde(no[id[r]],no[i]); adde(yes[id[l-1]],yes[i]);
	}
	for(int i=1;i<=m;++i)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		adde(yes[u],no[v]); adde(yes[v],no[u]);
	}
	for(int i=0;i<=M;++i)
	{
		if(i>0) adde(no[id[i]],no[id[i-1]]);
		if(i<M) adde(yes[id[i]],yes[id[i+1]]);
	}
	adde(yes[id[0]],no[id[0]]);
}
int dfn[N],low[N],Time,st[N],top,ins[N],c[N],cnt;
void tarjan(int u)
{
	dfn[u]=low[u]=++Time,st[++top]=u,ins[u]=1;
	for(int i=head[u],v;i;i=e[i].nxt)
	{
		v=e[i].to;
		if(!dfn[v]) tarjan(v),low[u]=min(low[v],low[u]);
		else if(ins[v]) low[u]=min(dfn[v],low[u]);
	}
	if(low[u]==dfn[u])
	{
		int v=-1; ++cnt;
	//	cout<<cnt<<":"<<endl;
		while(v!=u)
		{
			v=st[top--],ins[v]=0,c[v]=cnt;
		//	cout<<v<<" ";
		}
	//	puts("");
	}
}
int main()
{
	scanf("%d%d%d%d",&n,&p,&M,&m);
	build();
	for(int i=1;i<=node;++i)
		if(!dfn[i]) tarjan(i);
	for(int i=1;i<=p;++i) if(c[yes[i]] == c[no[i]]) {puts("-1"); return 0;}
	for(int i=0;i<=M;++i) if(c[yes[id[i]]] == c[no[id[i]]]) {puts("-1"); return 0;}
	for(int i=1;i<=p;++i) if(c[yes[i]]<c[no[i]]) cs.push_back(i);
	for(int i=0;i<=M;++i)
		if(c[yes[id[i]]] < c[no[id[i]]]) {f=i; break;}
	printf("%d %d\n",(int)cs.size(),f);
	for(int i=0;i<cs.size();++i) printf("%d ",cs[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=4e5+5;
int n,p,M,m;
int node,id[N],yes[N*2],no[N*2],head[N*4],ce;
bool vis[N*4];
struct edge{int to,nxt;} e[N*10];
void adde(int a,int b) {e[++ce]=(edge){b,head[a]},head[a]=ce;}
vector<int> cs;
int f;
int rd() {
    char ch=getchar(); int x=0;
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-48,ch=getchar();return x;
}
void build()
{
	for(int i=1;i<=p;++i) yes[i]=++node,no[i]=++node;
	for(int i=0;i<=M;++i) id[i]=p+i+1;
	for(int i=0;i<=M;++i) yes[id[i]]=++node,no[id[i]]=++node;
	for(int i=1;i<=n;++i)
	{
		int x,y;
		x=rd(),y=rd();
		adde(no[x],yes[y]); adde(no[y],yes[x]);
	}
	for(int i=1;i<=p;++i)
	{
		int l,r;
		l=rd(),r=rd();
		adde(yes[i],yes[id[r]]); adde(yes[i],no[id[l-1]]);
		adde(no[id[r]],no[i]); adde(yes[id[l-1]],no[i]);
	}
	for(int i=1;i<=m;++i)
	{
		int u,v;
		u=rd(),v=rd();
		adde(yes[u],no[v]); adde(yes[v],no[u]);
	}
	for(int i=0;i<=M;++i)
	{
		if(i>0) adde(no[id[i]],no[id[i-1]]);
		if(i<M) adde(yes[id[i]],yes[id[i+1]]);
	}
	adde(yes[id[0]],no[id[0]]);
}
int dfn[N*4],low[N*4],Time,st[N*4],top,ins[N*4],c[N*4],cnt;
void tarjan(int u)
{
	dfn[u]=low[u]=++Time,st[++top]=u,ins[u]=1;
	for(int i=head[u],v;i;i=e[i].nxt)
	{
		v=e[i].to;
		if(!dfn[v]) tarjan(v),low[u]=min(low[v],low[u]);
		else if(ins[v]) low[u]=min(dfn[v],low[u]);
	}
	if(low[u]==dfn[u])
	{
		int v=-1; ++cnt;
		while(v!=u) v=st[top--],ins[v]=0,c[v]=cnt;
	}
}
int main()
{
	//freopen("1.in","r",stdin); freopen("1.out","w",stdout);
	scanf("%d%d%d%d",&n,&p,&M,&m);
	build();
	for(int i=1;i<=node;++i)
		if(!dfn[i]) tarjan(i);
	for(int i=1;i<=p;++i) if(c[yes[i]] == c[no[i]]) {puts("-1"); return 0;}
	for(int i=0;i<=M;++i) if(c[yes[id[i]]] == c[no[id[i]]]) {puts("-1"); return 0;}
	for(int i=1;i<=p;++i) if(c[yes[i]]<c[no[i]]) cs.push_back(i);
	for(int i=0;i<=M;++i)
		if(c[yes[id[i]]] < c[no[id[i]]]) {f=i; break;}
	printf("%d %d\n",(int)cs.size(),f);
	for(int i=0;i<cs.size();++i) printf("%d ",cs[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=4e5+5;
int n,p,M,m;
int node,id[N],yes[N*2],no[N*2],head[N*4],ce;
bool vis[N*4];
struct edge{int to,nxt;} e[N*6];
void adde(int a,int b) {e[++ce]=(edge){b,head[a]},head[a]=ce;}
vector<int> cs;
int f;
void build()
{
	for(int i=1;i<=p;++i) yes[i]=++node,no[i]=++node;
	for(int i=0;i<=M;++i) id[i]=p+i+1;
	for(int i=0;i<=M;++i) yes[id[i]]=++node,no[id[i]]=++node;
	for(int i=1;i<=n;++i)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		adde(no[x],yes[y]); adde(no[y],yes[x]);
	}
	for(int i=1;i<=p;++i)
	{
		int l,r;
		scanf("%d%d",&l,&r);
		adde(yes[i],yes[id[r]]); adde(yes[i],no[id[l-1]]);
		adde(no[id[r]],no[i]); adde(yes[id[l-1]],no[i]);
	}
	for(int i=1;i<=m;++i)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		adde(yes[u],no[v]); adde(yes[v],no[u]);
	}
	for(int i=0;i<=M;++i)
	{
		if(i>0) adde(no[id[i]],no[id[i-1]]);
		if(i<M) adde(yes[id[i]],yes[id[i+1]]);
	}
	adde(yes[id[0]],no[id[0]]);
}
int dfn[N],low[N],Time,st[N],top,ins[N],c[N],cnt;
void tarjan(int u)
{
	dfn[u]=low[u]=++Time,st[++top]=u,ins[u]=1;
	for(int i=head[u],v;i;i=e[i].nxt)
	{
		v=e[i].to;
		if(!dfn[v]) tarjan(v),low[u]=min(low[v],low[u]);
		else if(ins[v]) low[u]=min(dfn[v],low[u]);
	}
	if(low[u]==dfn[u])
	{
		int v=-1; ++cnt;
	//	cout<<cnt<<":"<<endl;
		while(v!=u)
		{
			v=st[top--],ins[v]=0,c[v]=cnt;
	//		cout<<v<<" ";
		}
	//	puts("");
	}
}
int main()
{
	scanf("%d%d%d%d",&n,&p,&M,&m);
	build();
	for(int i=1;i<=node;++i)
		if(!dfn[i]) tarjan(i);
	for(int i=1;i<=p;++i) if(c[yes[i]] == c[no[i]]) {puts("-1"); return 0;}
	for(int i=0;i<=M;++i) if(c[yes[id[i]]] == c[no[id[i]]]) {puts("-1"); return 0;}
	for(int i=1;i<=p;++i) if(c[yes[i]]<c[no[i]]) cs.push_back(i);
	for(int i=0;i<=M;++i)
		if(c[yes[id[i]]] < c[no[id[i]]]) {f=i; break;}
	printf("%d %d\n",(int)cs.size(),f);
	for(int i=0;i<cs.size();++i) printf("%d ",cs[i]);
	return 0;
}


#include <bits/stdc++.h>

#define pb push_back
#define mp make_pair
#define x first
#define y second

using namespace std;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;

const int N = 1600200;

vector<int> g[N];
vector<int> gt[N];

vector<bool> used;
vector<int> order;

vector<int> comp;
vector<int> result;

void addEdge(int v1, int v2)
{
    g[v1].pb(v2);
    gt[v2].pb(v1);
}

void addDisjunction(int v1, int v2)
{
    addEdge(v1 ^ 1, v2);
    addEdge(v2 ^ 1, v1);
}

void dfs1(int v)
{
    if(used[v]) return;
    used[v] = true;
    for(int c : g[v])
        dfs1(c);
    order.pb(v);
}

void dfs2(int v, int cc)
{
    if(comp[v]) return;
    comp[v] = cc;
    for(int c : gt[v])
        dfs2(c, cc);
}

bool solve_2SAT()
{
    used.assign(N, false);
    for(int i=0;i<N;i++)
        dfs1(i);
    reverse(order.begin(), order.end());
    comp.assign(N, 0);
    int cc = 0;
    for(int v : order){
        if(!comp[v]){
            cc++;
            dfs2(v, cc);
        }
    }
    for(int i=0;2*i+1<N;i++){
        if(comp[2*i] == comp[2*i+1])
            return false;
        if(comp[2*i] > comp[2*i+1])
            result.pb(i);
    }

    return true;
}

int main()
{
    // freopen("entree.txt", "r", stdin);

    int n, p, M, m;
    scanf("%d %d %d %d", &n, &p, &M, &m);

    for(int i=0;i<m;i++){
        int x, y; scanf("%d %d", &x, &y);
        x--; y--;
        addDisjunction(2*x, 2*y);
    }

    for(int i=0;i<M;i++)
        addDisjunction(2*(i+p), 2*(i+p+1)+1);

    for(int i=0;i<p;i++){
        int l, r; scanf("%d %d", &l, &r);
        addDisjunction(2*(p+l-1), 2*i + 1);
        addDisjunction(2*(p+r)+1, 2*i + 1);
    }

    for(int i=0;i<m;i++){
        int u, v; scanf("%d %d", &u, &v);
        u--; v--;
        addDisjunction(2*u + 1, 2*v + 1);
    }

    if(!solve_2SAT()){
        printf("-1");
        return 0;
    }

    int f = 1;
    vector<int> stations;
    for(int x : result){
        if(x < p)
            stations.pb(x);
        else if(x < M + p + 1)
            f = max(f, x - p);
    }

    printf("%d %d\n", stations.size(), f);
    for(int v : stations)
        printf("%d ", v + 1);
    printf("\n");

    return 0;
}


#include <bits/stdc++.h>

#define pb push_back
#define mp make_pair
#define x first
#define y second

using namespace std;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;

const int N = 1600200;

vector<int> g[N];
vector<int> gt[N];

vector<bool> used;
vector<int> order;

vector<int> comp;
vector<int> result;

void addEdge(int v1, int v2)
{
    g[v1].pb(v2);
    gt[v2].pb(v1);
}

void addDisjunction(int v1, int v2)
{
    addEdge(v1 ^ 1, v2);
    addEdge(v2 ^ 1, v1);
}

void dfs1(int v)
{
    if(used[v]) return;
    used[v] = true;
    for(int c : g[v])
        dfs1(c);
    order.pb(v);
}

void dfs2(int v, int cc)
{
    if(comp[v]) return;
    comp[v] = cc;
    for(int c : gt[v])
        dfs2(c, cc);
}

bool solve_2SAT()
{
    used.assign(N, false);
    for(int i=0;i<N;i++)
        dfs1(i);
    reverse(order.begin(), order.end());
    comp.assign(N, 0);
    int cc = 0;
    for(int v : order){
        if(!comp[v]){
            cc++;
            dfs2(v, cc);
        }
    }
    for(int i=0;2*i+1<N;i++){
        if(comp[2*i] == comp[2*i+1])
            return false;
        if(comp[2*i] > comp[2*i+1])
            result.pb(i);
    }

    return true;
}

int main()
{
    // freopen("entree.txt", "r", stdin);

    int n, p, M, m;
    scanf("%d %d %d %d", &n, &p, &M, &m);

    for(int i=0;i<m;i++){
        int x, y; scanf("%d %d", &x, &y);
        x--; y--;
        addDisjunction(2*x, 2*y);
    }

    for(int i=0;i<M;i++)
        addDisjunction(2*(i+p), 2*(i+p+1)+1);

    for(int i=0;i<p;i++){
        int l, r; scanf("%d %d", &l, &r);
        addDisjunction(2*(p+l), 2*i + 1);
        addDisjunction(2*(p+r)+1, 2*i + 1);
    }

    for(int i=0;i<m;i++){
        int u, v; scanf("%d %d", &u, &v);
        u--; v--;
        addDisjunction(2*u + 1, 2*v + 1);
    }

    if(!solve_2SAT()){
        printf("-1");
        return 0;
    }

    int f = 1;
    vector<int> stations;
    for(int x : result){
        if(x < p)
            stations.pb(x);
        else if(x < M + p + 1)
            f = max(f, x - p);
    }

    printf("%d %d\n", stations.size(), f);
    for(int v : stations)
        printf("%d ", v + 1);
    printf("\n");

    return 0;
}


#include <bits/stdc++.h>

#define pb push_back
#define mp make_pair
#define x first
#define y second

using namespace std;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;

const int N = 1600200;

vector<int> g[N];
vector<int> gt[N];

vector<bool> used;
vector<int> order;

vector<int> comp;
vector<int> result;

void addEdge(int v1, int v2)
{
    g[v1].pb(v2);
    gt[v2].pb(v1);
}

void addDisjunction(int v1, int v2)
{
    addEdge(v1 ^ 1, v2);
    addEdge(v2 ^ 1, v1);
}

void dfs1(int v)
{
    if(used[v]) return;
    used[v] = true;
    for(int c : g[v])
        dfs1(c);
    order.pb(v);
}

void dfs2(int v, int cc)
{
    if(comp[v]) return;
    comp[v] = cc;
    for(int c : gt[v])
        dfs2(c, cc);
}

bool solve_2SAT()
{
    used.assign(N, false);
    for(int i=0;i<N;i++)
        dfs1(i);
    reverse(order.begin(), order.end());
    comp.assign(N, 0);
    int cc = 0;
    for(int v : order){
        if(!comp[v]){
            cc++;
            dfs2(v, cc);
        }
    }
    for(int i=0;2*i+1<N;i++){
        if(comp[2*i] == comp[2*i+1])
            return false;
        if(comp[2*i] > comp[2*i+1])
            result.pb(i);
    }

    return true;
}

int main()
{
    // freopen("entree.txt", "r", stdin);

    int n, p, M, m;
    scanf("%d %d %d %d", &n, &p, &M, &m);

    for(int i=0;i<m;i++){
        int x, y; scanf("%d %d", &x, &y);
        x--; y--;
        addDisjunction(2*x, 2*y);
    }

    for(int i=0;i<M;i++)
        addDisjunction(2*(i+p), 2*(i+p+1)+1);

    for(int i=0;i<p;i++){
        int l, r; scanf("%d %d", &l, &r);
        addDisjunction(2*(p+l), 2*i + 1);
        addDisjunction(2*(p+r+1)+1, 2*i + 1);
    }

    for(int i=0;i<m;i++){
        int u, v; scanf("%d %d", &u, &v);
        u--; v--;
        addDisjunction(2*u + 1, 2*v + 1);
    }

    if(!solve_2SAT()){
        printf("-1");
        return 0;
    }

    int f = 1;
    vector<int> stations;
    for(int x : result){
        if(x < p)
            stations.pb(x);
        else if(x < M + p + 1)
            f = max(f, x - p);
    }

    printf("%d %d\n", stations.size(), f);
    for(int v : stations)
        printf("%d ", v + 1);
    printf("\n");

    return 0;
}


#include <bits/stdc++.h>

#define pb push_back
#define mp make_pair
#define x first
#define y second

using namespace std;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;

const int N = 1600041;

vector<int> g[N];
vector<int> gt[N];

vector<bool> used;
vector<int> order;

vector<int> comp;
vector<int> result;

void addEdge(int v1, int v2)
{
    g[v1].pb(v2);
    gt[v2].pb(v1);
}

void addDisjunction(int v1, int v2)
{
    addEdge(v1 ^ 1, v2);
    addEdge(v2 ^ 1, v1);
}

void dfs1(int v)
{
    if(used[v]) return;
    used[v] = true;
    for(int c : g[v])
        dfs1(c);
    order.pb(v);
}

void dfs2(int v, int cc)
{
    if(comp[v]) return;
    comp[v] = cc;
    for(int c : gt[v])
        dfs2(c, cc);
}

bool solve_2SAT()
{
    used.assign(N, false);
    for(int i=0;i<N;i++)
        dfs1(i);
    reverse(order.begin(), order.end());
    comp.assign(N, 0);
    int cc = 0;
    for(int v : order){
        if(!comp[v]){
            cc++;
            dfs2(v, cc);
        }
    }
    for(int i=0;i<N/2;i++){
        if(comp[2*i] == comp[2*i+1])
            return false;
        if(comp[2*i] > comp[2*i+1])
            result.pb(i);
    }

    return true;
}

int main()
{
    // freopen("entree.txt", "r", stdin);

    int n, p, M, m;
    scanf("%d %d %d %d", &n, &p, &M, &m);
    for(int i=0;i<m;i++){
        int x, y; scanf("%d %d", &x, &y);
        x--; y--;
        addDisjunction(2*x, 2*y);
    }
    for(int i=0;i<=M;i++){
        addDisjunction(2*(i+p), 2*(i+p+1)+1);
    }
    for(int i=0;i<p;i++){
        int l, r; scanf("%d %d", &l, &r);
        addDisjunction(2*(p+l), 2*i + 1);
        addDisjunction(2*(p+r)+1, 2*i + 1);
    }
    for(int i=0;i<m;i++){
        int u, v; scanf("%d %d", &u, &v);
        u--; v--;
        addDisjunction(2*u + 1, 2*v + 1);
    }

    if(!solve_2SAT()){
        printf("-1");
        return 0;
    }

    int f = 1;
    vector<int> stations;
    for(int x : result){
        if(x < p)
            stations.pb(x);
        else if(x < M + p + 1)
            f = max(f, x - p);
    }

    printf("%d %d\n", stations.size(), f);
    for(int v : stations)
        printf("%d ", v + 1);
    printf("\n");

    return 0;
}


#include <bits/stdc++.h>

#define pb push_back
#define mp make_pair
#define x first
#define y second

using namespace std;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;

const int N = 1600200;

vector<int> g[N];
vector<int> gt[N];

vector<bool> used;
vector<int> order;

vector<int> comp;
vector<int> result;

void addEdge(int v1, int v2)
{
    g[v1].pb(v2);
    gt[v2].pb(v1);
}

void addDisjunction(int v1, int v2)
{
    addEdge(v1 ^ 1, v2);
    addEdge(v2 ^ 1, v1);
}

void dfs1(int v)
{
    if(used[v]) return;
    used[v] = true;
    for(int c : g[v])
        dfs1(c);
    order.pb(v);
}

void dfs2(int v, int cc)
{
    if(comp[v]) return;
    comp[v] = cc;
    for(int c : gt[v])
        dfs2(c, cc);
}

bool solve_2SAT()
{
    used.assign(N, false);
    for(int i=0;i<N;i++)
        dfs1(i);
    reverse(order.begin(), order.end());
    comp.assign(N, 0);
    int cc = 0;
    for(int v : order){
        if(!comp[v]){
            cc++;
            dfs2(v, cc);
        }
    }
    for(int i=0;i<N/2;i++){
        if(comp[2*i] == comp[2*i+1])
            return false;
        if(comp[2*i] > comp[2*i+1])
            result.pb(i);
    }

    return true;
}

int main()
{
    // freopen("entree.txt", "r", stdin);

    int n, p, M, m;
    scanf("%d %d %d %d", &n, &p, &M, &m);
    for(int i=0;i<m;i++){
        int x, y; scanf("%d %d", &x, &y);
        x--; y--;
        addDisjunction(2*x, 2*y);
    }
    for(int i=0;i<=M;i++){
        addDisjunction(2*(i+p), 2*(i+p+1)+1);
    }
    for(int i=0;i<p;i++){
        int l, r; scanf("%d %d", &l, &r);
        addDisjunction(2*(p+l), 2*i + 1);
        addDisjunction(2*(p+r)+1, 2*i + 1);
    }
    for(int i=0;i<m;i++){
        int u, v; scanf("%d %d", &u, &v);
        u--; v--;
        addDisjunction(2*u + 1, 2*v + 1);
    }

    if(!solve_2SAT()){
        printf("-1");
        return 0;
    }

    int f = 1;
    vector<int> stations;
    for(int x : result){
        if(x < p)
            stations.pb(x);
        else if(x < M + p + 1)
            f = max(f, x - p);
    }

    printf("%d %d\n", stations.size(), f);
    for(int v : stations)
        printf("%d ", v + 1);
    printf("\n");

    return 0;
}


#include <bits/stdc++.h>
#define mset(a, b) memset(a, b, sizeof(a))
#define mcpy(a, b) memcpy(a, b, sizeof(a))
#define rg register
using namespace std;
typedef long long LL;
const int MAXN = 1600005;

template <typename T> inline void read(T &AKNOI) {
	T x = 0, flag = 1;
	char ch = getchar();
	while (!isdigit(ch)) {
		if (ch == '-') flag = -1;
		ch = getchar();
	}
	while (isdigit(ch)) {
		x = x * 10 + ch - '0';
		ch = getchar();
	}
	AKNOI = flag * x;
}

int n, p, M, m, tot, ansf;
int dfn[MAXN], low[MAXN], clk;
int stk[MAXN], top, instk[MAXN];
int scc, bel[MAXN];
vector<int> g[MAXN], ans;

inline void Add(int u, int v) {
	g[u].push_back(v);
}

void Tarjan(int u) {
	dfn[u] = low[u] = ++clk;
	stk[++top] = u; instk[u] = 1;
	for (auto v : g[u]) {
		if (!dfn[v]) {
			Tarjan(v);
			low[u] = min(low[u], low[v]);
		} else if (instk[v]) {
			low[u] = min(low[u], dfn[v]);
		}
	}
	if (low[u] == dfn[u]) {
		++scc; int x;
		do {
			x = stk[top--];
			instk[x] = 0;
			bel[x] = scc;
		} while (x != u);
	}
}

void init() {
	read(n); read(p); read(M); read(m);
	tot = p + M;
	for (int i = 1, x, y; i <= n; ++i) { //if x not chosen, we must choose y; same for y
		read(x); read(y);
		Add(x + tot, y);
		Add(y + tot, x);
	}
	for (int i = 1, l, r; i <= p; ++i) { //if i chosen, we must choose [f >= l] and ![f >= r+1]
		read(l); read(r);
		Add(i, l + p);
		Add(l + p + tot, i + tot);
		if (++r <= M) {
			Add(i, r + p + tot);
			Add(r + p, i + tot);
		}
	}
	for (int i = 1, x, y; i <= m; ++i) { //if x chosen, we mustn't choose y; same for y
		read(x); read(y);
		Add(x, y + tot);
		Add(y, x + tot);
	}
	for (int i = 1; i < M; ++i) { //if [f >= i + 1] chosen, we must choose [f >= i]
		Add(i + 1 + p, i + p);
		Add(i + p + tot, i + 1 + p + tot);
	}
}

void solve() {
	for (int i = 1; i <= (tot << 1); ++i) {
		if (!dfn[i]) {
			Tarjan(i);
		}
	}
	for (int i = 1; i <= tot; ++i) {
		if (bel[i] == bel[i + tot]) {
			printf("-1\n");
			return;
		}
		if (bel[i] < bel[i + tot]) {
			if (i <= p) ans.push_back(i);
			else ansf = i - p;
		}
	}
	printf("%d %d\n", ans.size(), ansf);
	for (auto i : ans) {
		printf("%d ", i);
	}
}

int main() {
	init();
	solve();
	return 0;
}


#include <bits/stdc++.h>
#define mset(a, b) memset(a, b, sizeof(a))
#define mcpy(a, b) memcpy(a, b, sizeof(a))
#define rg register
using namespace std;
typedef long long LL;
const int MAXN = 1600005;

template <typename T> inline void read(T &AKNOI) {
	T x = 0, flag = 1;
	char ch = getchar();
	while (!isdigit(ch)) {
		if (ch == '-') flag = -1;
		ch = getchar();
	}
	while (isdigit(ch)) {
		x = x * 10 + ch - '0';
		ch = getchar();
	}
	AKNOI = flag * x;
}

int n, p, M, m, tot, ansf;
int dfn[MAXN], low[MAXN], clk;
int stk[MAXN], top, instk[MAXN];
int scc, bel[MAXN];
vector<int> g[MAXN], ans;

inline void Add(int u, int v) {
	g[u].push_back(v);
}

void Tarjan(int u) {
	dfn[u] = low[u] = ++clk;
	stk[++top] = u; instk[u] = 1;
	for (auto v : g[u]) {
		if (!dfn[v]) {
			Tarjan(v);
			low[u] = min(low[u], low[v]);
		} else if (instk[v]) {
			low[u] = min(low[u], dfn[v]);
		}
	}
	if (low[u] == dfn[u]) {
		++scc; int x;
		do {
			x = stk[top--];
			instk[x] = 0;
			bel[x] = scc;
		} while (x != u);
	}
}

void init() {
	read(n); read(p); read(M); read(m);
	tot = p + M;
	for (int i = 1, x, y; i <= n; ++i) { //if x not chosen, we must choose y; same for y
		read(x); read(y);
		Add(x + tot, y);
		Add(y + tot, x);
	}
	for (int i = 1, l, r; i <= p; ++i) { //if i chosen, we must choose [f >= l] and ![f >= r+1]
		read(l); read(r);
		Add(i, l + p);
		Add(l + p + tot, i + tot);
		if (++r <= p) {
			Add(i, r + p + tot);
			Add(r + p, i + tot);
		}
	}
	for (int i = 1, x, y; i <= m; ++i) { //if x chosen, we mustn't choose y; same for y
		read(x); read(y);
		Add(x, y + tot);
		Add(y, x + tot);
	}
	for (int i = 1; i < M; ++i) { //if [f >= i + 1] chosen, we must choose [f >= i]
		Add(i + 1 + p, i + p);
		Add(i + p + tot, i + 1 + p + tot);
	}
}

void solve() {
	for (int i = 1; i <= (tot << 1); ++i) {
		if (!dfn[i]) {
			Tarjan(i);
		}
	}
	for (int i = 1; i <= tot; ++i) {
		if (bel[i] == bel[i + tot]) {
			printf("-1\n");
			return;
		}
		if (bel[i] < bel[i + tot]) {
			if (i <= p) ans.push_back(i);
			else ansf = i - p;
		}
	}
	printf("%d %d\n", ans.size(), ansf);
	for (auto i : ans) {
		printf("%d ", i);
	}
}

int main() {
	init();
	solve();
	return 0;
}


#include<algorithm>
#include<cstdio>
#define N 2000010
#define M 4000010
#define ci const int
#define yes(x) (x)<<1
#define no(x) (x)<<1|1
using namespace std;
int head[N],ver[M],nxt[M],tot;
int dfn[N],low[N],belong[N],num;
int sta[N],top,cnt;bool vis[N];
int n,m;
void add(ci&x,ci&y){ver[++tot]=y;nxt[tot]=head[x];head[x]=tot;}
void link(ci&x,ci&y){add(x,y),add(y^1,x^1);}
void tarjan(ci&x)
{
	dfn[x]=low[x]=++num,sta[++top]=x,vis[x]=true;
	for(int k=head[x],y;y=ver[k],k;k=nxt[k])
	if(!dfn[y])tarjan(y),low[x]=min(low[x],low[y]);
	else if(vis[y])low[x]=min(low[x],dfn[y]);
	if(low[x]==dfn[x])
	{
		int y;++cnt;
		do belong[y=sta[top--]]=cnt,vis[y]=false;
		while(y!=x);
	}
}
void readin()
{
	int m0,m1;
	scanf("%d%d%d%d",&m0,&n,&m,&m1);
	for(int i=0,x,y;i<m0;++i)
		scanf("%d%d",&x,&y),
		link(no(x-1),yes(y-1));
	for(int i=0;i<m;++i)
		link(yes(n+i),yes(n+i+1));
	link(yes(n),no(n));
	for(int i=0,l,r;i<n;++i)
		scanf("%d%d",&l,&r),
		link(yes(i),no(n+l-1)),//
		link(yes(i),yes(n+r));//
	for(int i=0,u,v;i<m1;++i)
		scanf("%d%d",&u,&v),
		link(yes(u-1),no(v-1));
}
void print()
{
	for(int i=0;i<=n+m;++i)
	if(belong[yes(i)]==belong[no(i)])
	{
		printf("-1");return;
	}
	int k=0;
	for(int i=0;i<n;++i)
		if(belong[yes(i)]<belong[no(i)])++k;
	for(int i=1;i<=m;++i)
	if(belong[yes(n+i)]<belong[no(n+i)])//
	{
		printf("%d %d\n",k,i);break;
	}
	for(int i=0;i<n;++i)
		if(belong[yes(i)]<belong[no(i)])printf("%d ",i+1);
}
signed main(int argc,char **argv)
{
	readin();
	for(int i=0;i<=(no(n+m));++i)
	if(!dfn[i])tarjan(i);
	print();
	return 0;
}


#include<algorithm>
#include<cstdio>
#define N 400010
#define ci const int
#define yes(x) (x)<<1
#define no(x) (x)<<1|1
using namespace std;
int head[N],ver[N<<1],nxt[N<<1],tot=1;
int dfn[N],low[N],belong[N],num;
int sta[N],top,cnt;bool vis[N];
int n,m;
void add(ci&x,ci&y){ver[++tot]=y;nxt[tot]=head[x];head[x]=tot;}
void link(ci&x,ci&y){add(x,y),add(y^1,x^1);}
void tarjan(ci&x)
{
	dfn[x]=low[x]=++num,sta[++top]=x,vis[x]=true;
	for(int k=head[x],y;y=ver[k],k;k=nxt[k])
	if(!dfn[y])tarjan(y),low[x]=min(low[x],low[y]);
	else if(vis[y])low[x]=min(low[x],dfn[y]);
	if(low[x]==dfn[x])
	{
		int y;++cnt;
		do belong[y=sta[top--]]=cnt,vis[y]=false;
		while(y!=x);
	}
}
void readin()
{
	int m0,m1;
	scanf("%d%d%d%d",&m0,&n,&m,&m1);
	for(int i=0,x,y;i<m0;++i)
		scanf("%d%d",&x,&y),
		link(no(x-1),yes(y-1));
	for(int i=0;i<m;++i)
		link(yes(n+i),yes(n+i+1));
	link(yes(n),no(n));
	for(int i=0,l,r;i<n;++i)
		scanf("%d%d",&l,&r),
		link(yes(i),no(n+l-1)),//
		link(yes(i),yes(n+r));//
	for(int i=0,u,v;i<m1;++i)
		scanf("%d%d",&u,&v),
		link(yes(u-1),no(v-1));
}
void print()
{
	for(int i=0;i<=n+m;++i)
	if(belong[yes(i)]==belong[no(i)])
	{
		printf("-1");return;
	}
	int k=0;
	for(int i=0;i<n;++i)
		if(belong[yes(i)]<belong[no(i)])++k;
	for(int i=0;i<m;++i)
	if(belong[yes(n+i)]<belong[no(n+i)])//
	{
		printf("%d %d\n",k,i);break;
	}
	for(int i=0;i<n;++i)
		if(belong[yes(i)]<belong[no(i)])printf("%d ",i+1);
}
signed main(int argc,char **argv)
{
	readin();
	for(int i=0;i<=(no(n+m));++i)
	if(!dfn[i])tarjan(i);
	print();
	return 0;
}


#include<algorithm>
#include<cstdio>
#define N 2000010
#define M 4000010
#define ci const int
#define yes(x) (x)<<1
#define no(x) (x)<<1|1
using namespace std;
int head[N],ver[M],nxt[M],tot;
int dfn[N],low[N],belong[N],num;
int sta[N],top,cnt;bool vis[N];
int n,m;
void add(ci&x,ci&y){ver[++tot]=y;nxt[tot]=head[x];head[x]=tot;}
void link(ci&x,ci&y){add(x,y),add(y^1,x^1);}
void tarjan(ci&x)
{
	dfn[x]=low[x]=++num,sta[++top]=x,vis[x]=true;
	for(int k=head[x],y;y=ver[k],k;k=nxt[k])
	if(!dfn[y])tarjan(y),low[x]=min(low[x],low[y]);
	else if(vis[y])low[x]=min(low[x],dfn[y]);
	if(low[x]==dfn[x])
	{
		int y;++cnt;
		do belong[y=sta[top--]]=cnt,vis[y]=false;
		while(y!=x);
	}
}
void readin()
{
	int m0,m1;
	scanf("%d%d%d%d",&m0,&n,&m,&m1);
	for(int i=0,x,y;i<m0;++i)
		scanf("%d%d",&x,&y),
		link(no(x-1),yes(y-1));
	for(int i=0;i<m;++i)
		link(yes(n+i),yes(n+i+1));
	link(yes(n),no(n));
	for(int i=0,l,r;i<n;++i)
		scanf("%d%d",&l,&r),
		link(yes(i),no(n+l-1)),//
		link(yes(i),yes(n+r));//
	for(int i=0,u,v;i<m1;++i)
		scanf("%d%d",&u,&v),
		link(yes(u-1),no(v-1));
}
void print()
{
	for(int i=0;i<=n+m;++i)
	if(belong[yes(i)]==belong[no(i)])
	{
		printf("-1");return;
	}
	int k=0;
	for(int i=0;i<n;++i)
		if(belong[yes(i)]<belong[no(i)])++k;
	for(int i=0;i<m;++i)
	if(belong[yes(n+i)]<belong[no(n+i)])//
	{
		printf("%d %d\n",k,i);break;
	}
	for(int i=0;i<n;++i)
		if(belong[yes(i)]<belong[no(i)])printf("%d ",i+1);
}
signed main(int argc,char **argv)
{
	readin();
	for(int i=0;i<=(no(n+m));++i)
	if(!dfn[i])tarjan(i);
	print();
	return 0;
}


#include<algorithm>
#include<cstdio>
#define N 800010
#define ci const int
#define yes(x) (x)<<1
#define no(x) (x)<<1|1
using namespace std;
int head[N],ver[N*3],nxt[N*3],tot=1;
int dfn[N],low[N],belong[N],num;
int sta[N],top,cnt;bool vis[N];
int n,m;
void add(ci&x,ci&y){ver[++tot]=y;nxt[tot]=head[x];head[x]=tot;}
void link(ci&x,ci&y){add(x,y),add(y^1,x^1);}
void tarjan(ci&x)
{
	dfn[x]=low[x]=++num,sta[++top]=x,vis[x]=true;
	for(int k=head[x],y;y=ver[k],k;k=nxt[k])
	if(!dfn[y])tarjan(y),low[x]=min(low[x],low[y]);
	else if(vis[y])low[x]=min(low[x],dfn[y]);
	if(low[x]==dfn[x])
	{
		int y;++cnt;
		do belong[y=sta[top--]]=cnt,vis[y]=false;
		while(y!=x);
	}
}
void readin()
{
	int m0,m1;
	scanf("%d%d%d%d",&m0,&n,&m,&m1);
	for(int i=0,x,y;i<m0;++i)
		scanf("%d%d",&x,&y),
		link(no(x-1),yes(y-1));
	for(int i=0;i<m;++i)
		link(yes(n+i),yes(n+i+1));
	link(yes(n),no(n));
	for(int i=0,l,r;i<n;++i)
		scanf("%d%d",&l,&r),
		link(yes(i),no(n+l-1)),//
		link(yes(i),yes(n+r));//
	for(int i=0,u,v;i<m1;++i)
		scanf("%d%d",&u,&v),
		link(yes(u-1),no(v-1));
}
void print()
{
	for(int i=0;i<=n+m;++i)
	if(belong[yes(i)]==belong[no(i)])
	{
		printf("-1");return;
	}
	int k=0;
	for(int i=0;i<n;++i)
		if(belong[yes(i)]<belong[no(i)])++k;
	for(int i=0;i<m;++i)
	if(belong[yes(n+i)]<belong[no(n+i)])//
	{
		printf("%d %d\n",k,i);break;
	}
	for(int i=0;i<n;++i)
		if(belong[yes(i)]<belong[no(i)])printf("%d ",i+1);
}
signed main(int argc,char **argv)
{
	readin();
	for(int i=0;i<=(no(n+m));++i)
	if(!dfn[i])tarjan(i);
	print();
	return 0;
}


#include<algorithm>
#include<cstdio>
#define N 400010
#define ci const int
#define yes(x) (x)<<1
#define no(x) (x)<<1|1
using namespace std;
int head[N],ver[N<<1],next[N<<1],tot=1;
int dfn[N],low[N],belong[N],num;
int sta[N],top,cnt;bool vis[N];
int n,m;
void add(ci&x,ci&y){ver[++tot]=y;next[tot]=head[x];head[x]=tot;}
void link(ci&x,ci&y){add(x,y),add(y^1,x^1);}
void tarjan(ci&x)
{
	dfn[x]=low[x]=++num,sta[++top]=x,vis[x]=true;
	for(int k=head[x],y;y=ver[k],k;k=next[k])
	if(!dfn[y])tarjan(y),low[x]=min(low[x],low[y]);
	else if(vis[y])low[x]=min(low[x],dfn[y]);
	if(low[x]==dfn[x])
	{
		int y;++cnt;
		do belong[y=sta[top--]]=cnt,vis[y]=false;
		while(y!=x);
	}
}
void readin()
{
	int m0,m1;
	scanf("%d%d%d%d",&m0,&n,&m,&m1);
	for(int i=0,x,y;i<m0;++i)
		scanf("%d%d",&x,&y),
		link(no(x-1),yes(y-1));
	for(int i=0;i<m;++i)
		link(yes(n+i),yes(n+i+1));
	link(yes(n),no(n));
	for(int i=0,l,r;i<n;++i)
		scanf("%d%d",&l,&r),
		link(yes(i),no(n+l-1)),//
		link(yes(i),yes(n+r));//
	for(int i=0,u,v;i<m1;++i)
		scanf("%d%d",&u,&v),
		link(yes(u-1),no(v-1));
}
void print()
{
	for(int i=0;i<=n+m;++i)
	if(belong[yes(i)]==belong[no(i)])
	{
		printf("-1");return;
	}
	int k=0;
	for(int i=0;i<n;++i)
		if(belong[yes(i)]<belong[no(i)])++k;
	for(int i=0;i<m;++i)
	if(belong[yes(n+i)]<belong[no(n+i)])//
	{
		printf("%d %d\n",k,i);break;
	}
	for(int i=0;i<n;++i)
		if(belong[yes(i)]<belong[no(i)])printf("%d ",i+1);
}
signed main(int argc,char **argv)
{
	readin();
	for(int i=0;i<=(no(n+m));++i)
	if(!dfn[i])tarjan(i);
	print();
	return 0;
}


#include<algorithm>
#include<cstdio>
#define N 800010
#define ci const int
#define yes(x) (x)<<1
#define no(x) (x)<<1|1
using namespace std;
int head[N],ver[N*10],nxt[N*10],tot=1;
int dfn[N],low[N],belong[N],num;
int sta[N],top,cnt;bool vis[N];
int n,m;
void add(ci&x,ci&y){ver[++tot]=y;nxt[tot]=head[x];head[x]=tot;}
void link(ci&x,ci&y){add(x,y),add(y^1,x^1);}
void tarjan(ci&x)
{
	dfn[x]=low[x]=++num,sta[++top]=x,vis[x]=true;
	for(int k=head[x],y;y=ver[k],k;k=nxt[k])
	if(!dfn[y])tarjan(y),low[x]=min(low[x],low[y]);
	else if(vis[y])low[x]=min(low[x],dfn[y]);
	if(low[x]==dfn[x])
	{
		int y;++cnt;
		do belong[y=sta[top--]]=cnt,vis[y]=false;
		while(y!=x);
	}
}
void readin()
{
	int m0,m1;
	scanf("%d%d%d%d",&m0,&n,&m,&m1);
	for(int i=0,x,y;i<m0;++i)
		scanf("%d%d",&x,&y),
		link(no(x-1),yes(y-1));
	for(int i=0;i<m;++i)
		link(yes(n+i),yes(n+i+1));
	link(yes(n),no(n));
	for(int i=0,l,r;i<n;++i)
		scanf("%d%d",&l,&r),
		link(yes(i),no(n+l-1)),//
		link(yes(i),yes(n+r));//
	for(int i=0,u,v;i<m1;++i)
		scanf("%d%d",&u,&v),
		link(yes(u-1),no(v-1));
}
void print()
{
	for(int i=0;i<=n+m;++i)
	if(belong[yes(i)]==belong[no(i)])
	{
		printf("-1");return;
	}
	int k=0;
	for(int i=0;i<n;++i)
		if(belong[yes(i)]<belong[no(i)])++k;
	for(int i=0;i<m;++i)
	if(belong[yes(n+i)]<belong[no(n+i)])//
	{
		printf("%d %d\n",k,i);break;
	}
	for(int i=0;i<n;++i)
		if(belong[yes(i)]<belong[no(i)])printf("%d ",i+1);
}
signed main(int argc,char **argv)
{
	readin();
	for(int i=0;i<=(no(n+m));++i)
	if(!dfn[i])tarjan(i);
	print();
	return 0;
}


#include<cstdio>
#include<algorithm>
int m1,m2,n,m,cnt,head[1600010],to[3200010],nxt[3200010];
void add(int const &x,int const &y){
	to[++cnt]=y,nxt[cnt]=head[x],head[x]=cnt;
}
int col[1600010];
void tarjan(int const &x){
	static int ccnt,cnt,dfn[1600010],low[1600010],s[1600010],st,ins[1600010];
	dfn[x]=low[x]=++cnt,s[st++]=x,ins[x]=1;
	for(int i=head[x];i;i=nxt[i])
		if(!dfn[to[i]]){
			tarjan(to[i]);
			low[x]=std::min(low[to[i]],low[x]);
		}else if(ins[to[i]])low[x]=std::min(low[x],dfn[to[i]]);
	if(dfn[x]==low[x]){
		++ccnt;
		do{
			--st;
			col[s[st]]=ccnt;
			ins[s[st]]=0;
		}while(s[st]!=x);
	}
}
int main(){
	scanf("%d%d%d%d",&m1,&n,&m,&m2);
	for(int i=1,x,y;i<=m1;i++){
		scanf("%d%d",&x,&y);
		add(x+n,y),add(y+n,x);
	}
	++m;
	for(int i=1,l,r;i<=n;i++){
		scanf("%d%d",&l,&r);
		add(i,n+n+m+l),add(i,n+n+r+1),add(n+n+l,i+n),add(n+n+m+r+1,i+n);
	}
	for(int i=1;i<m;i++){
		add(n+n+m+i+1,n+n+m+i),add(n+n+i,n+n+i+1);
	}
	for(int i=1,x,y;i<=m2;i++){
		scanf("%d%d",&x,&y);
		add(x,y+n),add(y,x+n);
	}
	add(n+n+1,n+n+m+1);
	for(int i=1;i<=n+n+m+m;i++)if(!col[i])tarjan(i);
	for(int i=1;i<=n;i++)
		if(col[i]==col[i+n])return puts("-1"),0;
	for(int i=1;i<=m;i++)
		if(col[n+n+i]==col[i+n+n+m])return puts("-1"),0;
	int k=0;
	for(int i=1;i<=n;i++)
		if(col[i]<col[i+n]) ++k;
	for(int i=2;i<=m;i++)
		if(col[n+n+i]<col[n+n+m+i]){
			printf("%d %d\n",k,i);
			break;
		}
	for(int i=1;i<=n;i++)
		if(col[i]<col[i+n]){
			printf("%d ",i);
		}
	return 0;
}


#include<cstdio>
#include<algorithm>
int m1,m2,n,m,cnt,head[1600010],to[3200010],nxt[3200010];
void add(int const &x,int const &y){
	to[++cnt]=y,nxt[cnt]=head[x],head[x]=cnt;
}
int col[1600010];
void tarjan(int const &x){
	static int ccnt,cnt,dfn[1600010],low[1600010],s[1600010],st,ins[1600010];
	dfn[x]=low[x]=++cnt,s[st++]=x,ins[x]=1;
	for(int i=head[x];i;i=nxt[i])
		if(!dfn[to[i]]){
			tarjan(to[i]);
			low[x]=std::min(low[to[i]],low[x]);
		}else if(ins[to[i]])low[x]=std::min(low[x],dfn[to[i]]);
	if(dfn[x]==low[x]){
		++ccnt;
		do{
			--st;
			col[s[st]]=ccnt;
			ins[s[st]]=0;
		}while(s[st]!=x);
	}
}
int main(){
	scanf("%d%d%d%d",&m1,&n,&m,&m2);
	for(int i=1,x,y;i<=m1;i++){
		scanf("%d%d",&x,&y);
		add(x+n,y),add(y+n,x);
	}
	++m;
	for(int i=1,l,r;i<=n;i++){
		scanf("%d%d",&l,&r);
		add(i,n+n+m+l),add(i,n+n+r+1),add(n+n+l,i+n),add(n+n+m+r+1,i+n);
	}
	for(int i=1;i<m;i++){
		add(n+n+m+i+1,n+n+m+i),add(n+n+i,n+n+i+1);
	}
	for(int i=1,x,y;i<=m2;i++){
		scanf("%d%d",&x,&y);
		add(x,y+n),add(y,x+n);
	}
	add(n+n+1,n+n+m+1);
	for(int i=1;i<=n+n+m+m;i++)if(!col[i])tarjan(i);
	for(int i=1;i<=n;i++)
		if(col[i]==col[i+n])return puts("-1"),0;
	for(int i=1;i<=m;i++)
		if(col[n+n+i]==col[i+n+n+m])return puts("-1"),0;
	int k=0;
	for(int i=1;i<=n;i++)
		if(col[i]<col[i+n]) ++k;
	for(int i=2;i<=m;i++)
		if(col[n+n+i]<col[n+n+m+i]){
			printf("%d %d\n",k,i-1);
			break;
		}
	for(int i=1;i<=n;i++)
		if(col[i]<col[i+n]){
			printf("%d ",i);
		}
	return 0;
}


#include<cstdio>
#include<algorithm>
int m1,m2,n,m,cnt,head[1600010],to[4800010],nxt[4800010];
void add(int const &x,int const &y){
	to[++cnt]=y,nxt[cnt]=head[x],head[x]=cnt;
}
int col[1600010];
void tarjan(int const &x){
	static int ccnt,cnt,dfn[1600010],low[1600010],s[1600010],st,ins[1600010];
	dfn[x]=low[x]=++cnt,s[st++]=x,ins[x]=1;
	for(int i=head[x];i;i=nxt[i])
		if(!dfn[to[i]]){
			tarjan(to[i]);
			low[x]=std::min(low[to[i]],low[x]);
		}else if(ins[to[i]])low[x]=std::min(low[x],dfn[to[i]]);
	if(dfn[x]==low[x]){
		++ccnt;
		do{
			--st;
			col[s[st]]=ccnt;
			ins[s[st]]=0;
		}while(s[st]!=x);
	}
}
int main(){
	scanf("%d%d%d%d",&m1,&n,&m,&m2);
	for(int i=1,x,y;i<=m1;i++){
		scanf("%d%d",&x,&y);
		add(x+n,y),add(y+n,x);
	}
	++m;
	for(int i=1,l,r;i<=n;i++){
		scanf("%d%d",&l,&r);
		add(i,n+n+m+l),add(i,n+n+r+1),add(n+n+l,i+n),add(n+n+m+r+1,i+n);
	}
	for(int i=1;i<m;i++){
		add(n+n+m+i+1,n+n+m+i),add(n+n+i,n+n+i+1);
	}
	for(int i=1,x,y;i<=m2;i++){
		scanf("%d%d",&x,&y);
		add(x,y+n),add(y,x+n);
	}
	add(n+n+1,n+n+m+1);
	for(int i=1;i<=n+n+m+m;i++)if(!col[i])tarjan(i);
	for(int i=1;i<=n;i++)
		if(col[i]==col[i+n])return puts("-1"),0;
	for(int i=1;i<=m;i++)
		if(col[n+n+i]==col[i+n+n+m])return puts("-1"),0;
	int k=0;
	for(int i=1;i<=n;i++)
		if(col[i]<col[i+n]) ++k;
	for(int i=2;i<=m;i++)
		if(col[n+n+i]<col[n+n+m+i]){
			printf("%d %d\n",k,i-1);
			break;
		}
	for(int i=1;i<=n;i++)
		if(col[i]<col[i+n]){
			printf("%d ",i);
		}
	return 0;
}


#include<cstdio>
#include<algorithm>
int m1,m2,n,m,cnt,head[1600010],to[3200010],nxt[3200010];
void add(int const &x,int const &y){
	to[++cnt]=y,nxt[cnt]=head[x],head[x]=cnt;
}
int col[1600010];
void tarjan(int const &x){
	static int ccnt,cnt,dfn[1600010],low[1600010],s[1600010],st,ins[1600010];
	dfn[x]=low[x]=++cnt,s[st++]=x,ins[x]=1;
	for(int i=head[x];i;i=nxt[i])
		if(!dfn[to[i]]){
			tarjan(to[i]);
			low[x]=std::min(low[to[i]],low[x]);
		}else if(ins[to[i]])low[x]=std::min(low[x],dfn[to[i]]);
	if(dfn[x]==low[x]){
		++ccnt;
		do{
			--st;
			col[s[st]]=ccnt;
			ins[s[st]]=0;
		}while(s[st]!=x);
	}
}
int yes(int const &x){
	return (x<<1)-1;
}
int no(int const &x){
	return x<<1;
}
int main(){
	scanf("%d%d%d%d",&m1,&n,&m,&m2);
	for(int i=1,x,y;i<=m1;i++){
		scanf("%d%d",&x,&y);
		add(no(x),yes(y)),add(no(y),yes(x));
	}
	for(int i=1;i<=m;i++){
		add(yes(n+i),yes(n+i+1)),add(no(n+i+1),no(n+i));
	}
	add(yes(n+1),no(n+1));
	for(int i=1,l,r;i<=n;i++){
		scanf("%d%d",&l,&r);
		add(yes(i),no(n+l)),add(yes(n+l),no(i)),add(yes(i),yes(n+r+1)),add(no(n+r+1),no(i));
	}
	for(int i=1,x,y;i<=m2;i++){
		scanf("%d%d",&x,&y);
		add(yes(x),no(y)),add(yes(y),no(x));
	}
	for(int i=1;i<=no(n+m+1);i++)if(!col[i])tarjan(i);
	for(int i=1;i<=n+m+1;i++)
		if(col[yes(i)]==col[no(i)])return puts("-1"),0;
	int k=0;
	for(int i=1;i<=n;i++)
		if(col[yes(i)]<col[no(i)]) ++k;
	for(int i=1;i<=m;i++)
		if(col[yes(n+i+1)]<col[no(n+i+1)]){
			printf("%d %d\n",k,i);
			break;
		}
	for(int i=1;i<=n;i++)
		if(col[yes(i)]<col[no(i)]){
			printf("%d ",i);
		}
	return 0;
}


#include<cstdio>
#include<algorithm>
int m1,m2,n,m,cnt,head[1600010],to[3200010],nxt[3200010];
void add(int const &x,int const &y){
	to[++cnt]=y,nxt[cnt]=head[x],head[x]=cnt;
}
int col[1600010];
void tarjan(int const &x){
	static int ccnt,cnt,dfn[1600010],low[1600010],s[1600010],st,ins[1600010];
	dfn[x]=low[x]=++cnt,s[st++]=x,ins[x]=1;
	for(int i=head[x];i;i=nxt[i])
		if(!dfn[to[i]]){
			tarjan(to[i]);
			low[x]=std::min(low[to[i]],low[x]);
		}else if(ins[to[i]])low[x]=std::min(low[x],dfn[to[i]]);
	if(dfn[x]==low[x]){
		++ccnt;
		do{
			--st;
			col[s[st]]=ccnt;
			ins[s[st]]=0;
		}while(s[st]!=x);
	}
}
int yes(int const &x){
	return (x<<1)-1;
}
int no(int const &x){
	return x<<1;
}
int main(){
	scanf("%d%d%d%d",&m1,&n,&m,&m2);
	for(int i=1,x,y;i<=m1;i++){
		scanf("%d%d",&x,&y);
		add(no(x),yes(y)),add(no(y),yes(x));
	}
	++m;
	for(int i=1,l,r;i<=n;i++){
		scanf("%d%d",&l,&r);
		add(yes(i),no(n+l)),add(yes(i),yes(n+r+1)),add(yes(n+l),no(i)),add(no(n+r+1),no(i));
	}
	for(int i=1;i<m;i++){
		add(no(n+i+1),no(n+i)),add(yes(n+i),yes(n+i+1));
	}
	for(int i=1,x,y;i<=m2;i++){
		scanf("%d%d",&x,&y);
		add(yes(x),no(y)),add(yes(y),no(x));
	}
	add(yes(n+1),no(n+1));
	for(int i=1;i<=no(n+m);i++)if(!col[i])tarjan(i);
	for(int i=1;i<=n+m;i++)
		if(col[yes(i)]==col[no(i)])return puts("-1"),0;
	int k=0;
	for(int i=1;i<=n;i++)
		if(col[yes(i)]<col[no(i)]) ++k;
	for(int i=2;i<=m;i++)
		if(col[yes(n+i)]<col[no(n+i)]){
			printf("%d %d\n",k,i);
			break;
		}
	for(int i=1;i<=n;i++)
		if(col[yes(i)]<col[no(i)]){
			printf("%d ",i);
		}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int const N=400000+10;
int const M=1600000+10;
int h[M],cnt,bl[M],dfn[M],low[M],sum,n,p,t,s[M],top,vis[M],m;
struct edge{
	int to,nt;
}e[M<<2];
void read(int &x){
	x=0; char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) x=x*10+(c^48),c=getchar();
}
void add(int a,int b){
	e[++cnt].to=b;
	e[cnt].nt=h[a];
	h[a]=cnt;
}
void dfs(int x){
	dfn[x]=low[x]=++cnt;
	s[++top]=x;
	for(int i=h[x];i;i=e[i].nt){
		int v=e[i].to;
		if(!dfn[v]){
			dfs(v);
			low[x]=min(low[x],low[v]);
		}else if(!bl[v])  low[x]=min(low[x],dfn[v]);
	}
	if(dfn[x]==low[x]){
		sum++;
		while (s[top]!=x){
			bl[s[top]]=sum;
			top--;
		}
		bl[x]=sum; top--;
	}
}
int main(){
	read(n); read(p); read(m);read(t);
	for(int i=1;i<=n;i++){
		int x,y;
		read(x); read(y);
		add(x<<1,y<<1|1);
		add(y<<1,x<<1|1);
	}
	for(int i=1;i<=m;i++){
		add((p+i)<<1|1,(p+i+1)<<1|1);
		add((p+i+1)<<1,(p+i)<<1);
	}
	for(int i=1;i<=p;i++){
		int x,y;
		read(x); read(y);
		add((p+x)<<1|1,i<<1);
		add(i<<1|1,(p+x)<<1);
		add((p+y+1)<<1,i<<1);
		add(i<<1|1,(p+y+1)<<1|1);
	}
	for(int i=1;i<=t;i++){
		int x,y;
		read(x);read(y);
		add(x<<1|1,y<<1);
		add(y<<1|1,x<<1);
	}
	cnt=0; int ans=0;
	for(int i=2;i<=(p+m)*2+3;i++)
		if(!bl[i]) dfs(i);
	int f=m;
	for(int i=1;i<=p+m+1;i++)
		if(bl[i<<1]==bl[i<<1|1]) {
			printf("-1\n");
			return 0;
		}else{
			vis[i]=bl[i<<1|1]<bl[i<<1];
			if(i<=p) ans+=vis[i];
		}
	while (f>1 && vis[p+f+1])  f--;
	printf("%d %d\n",ans,f);
	for(int i=1;i<=p;i++)
		if(vis[i]) printf("%d ",i);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 2000005;
int n,p,M,m;
vector<int> e[N];//1~2n:STAT 2n+1~2n+2M:VALUE
inline int s1(int pos) {return pos << 1;}
inline int s0(int pos) {return pos << 1 | 1;}
inline void add_edge(int uu,int vv)
{e[uu].push_back(vv);e[vv ^ 1].push_back(uu ^ 1);}
int dfn[N],low[N],scc_idx[N],idx,tim;
stack<int> stk;bool vis[N];
void tarjan(int pos)
{
    dfn[pos] = low[pos] = ++tim;vis[pos] = 1;stk.push(pos);
    // printf("DFSed %d\n",pos);
    for (auto &i : e[pos])
        if (!dfn[i]) tarjan(i),low[pos] = min(low[pos],low[i]);
        else if (vis[i]) low[pos] = min(low[pos],dfn[i]);
    if (dfn[pos] == low[pos])
    {
        // puts("Hop");
        ++idx;
        while (!stk.empty())
        {
            int nd = stk.top();stk.pop();
            scc_idx[nd] = idx;vis[nd] = 0;
            // cout << "OutStack" << nd << ' ' << scc_idx[nd] << endl;
            if (nd == pos) break;
        }
    }
}
int main ()
{
    // ios::sync_with_stdio(false);
    cin >> p >> n >> M >> m;
    int t1,t2;
    for (int i = 1;i <= p;i++)
    {
        cin >> t1 >> t2;
        add_edge(s0(t1),s1(t2));
    }
    for (int i = 1;i <= M;i++)
        add_edge(s1(n + i),s1(n + i + 1));
    add_edge(s1(n + 1),s0(n + 1));
    for (int i = 1;i <= n;i++)
    {
        cin >> t1 >> t2;
        add_edge(s1(i),s1(n + t2 + 1));
        add_edge(s1(i),s0(n + t1));
    }
    for (int i = 1;i <= m;i++)
    {
        cin >> t1 >> t2;
        add_edge(s1(t1),s0(t2));
    }
    for (int i = 2;i <= s0(n + M + 1);i++)
        if (!dfn[i]) tarjan(i);
    // for (int i = 1;i <= n + M + 1;i++)
    // {
    //     printf("S0:%d S1:%d\n",scc_idx[s0(i)],scc_idx[s1(i)]);
    // }
    for (int i = 1;i <= n + M + 1;i++)
        if (scc_idx[s0(i)] == scc_idx[s1(i)])
        {
            // cout << "ERROR" << i << endl;
            cout << -1 << endl;return 0;
        }
    int cnt = 0;
    for (int i = 1;i <= n;i++)
        if (scc_idx[s1(i)] < scc_idx[s0(i)]) ++cnt;
    for (int i = n + 1;i <= n + M + 1;i++)
        if (scc_idx[s1(i + 1)] < scc_idx[s0(i + 1)])
        {
            cout /*<< "Output"*/ << cnt << ' ' << i - n << endl;
            break;
        }
    for (int i = 1;i <= n;i++)
        if (scc_idx[s1(i)] < scc_idx[s0(i)]) cout << i << ' ';
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
int n,p,M,m;
vector<int> e[N];//1~2n:STAT 2n+1~2n+2M:VALUE
inline int s1(int pos) {return pos << 1;}
inline int s0(int pos) {return pos << 1 | 1;}
inline void add_edge(int uu,int vv)
{e[uu].push_back(vv);e[vv ^ 1].push_back(uu ^ 1);}
int dfn[N],low[N],scc_idx[N],idx,tim;
stack<int> stk;bool vis[N];
void tarjan(int pos)
{
    dfn[pos] = low[pos] = ++tim;vis[pos] = 1;stk.push(pos);
    // printf("DFSed %d\n",pos);
    for (auto &i : e[pos])
        if (!dfn[i]) tarjan(i),low[pos] = min(low[pos],low[i]);
        else if (vis[i]) low[pos] = min(low[pos],dfn[i]);
    if (dfn[pos] == low[pos])
    {
        // puts("Hop");
        ++idx;
        while (!stk.empty())
        {
            int nd = stk.top();stk.pop();
            scc_idx[nd] = idx;vis[nd] = 0;
            // cout << "OutStack" << nd << ' ' << scc_idx[nd] << endl;
            if (nd == pos) break;
        }
    }
}
int main ()
{
    // ios::sync_with_stdio(false);
    cin >> p >> n >> M >> m;
    int t1,t2;
    for (int i = 1;i <= p;i++)
    {
        cin >> t1 >> t2;
        add_edge(s0(t1),s1(t2));
    }
    for (int i = 1;i <= M;i++)
        add_edge(s1(n + i),s1(n + i + 1));
    add_edge(s1(n + 1),s0(n + 1));
    for (int i = 1;i <= n;i++)
    {
        cin >> t1 >> t2;
        add_edge(s1(i),s1(n + t2 + 1));
        add_edge(s1(i),s0(n + t1));
    }
    for (int i = 1;i <= m;i++)
    {
        cin >> t1 >> t2;
        add_edge(s1(t1),s0(t2));
    }
    for (int i = 2;i <= s0(n + M + 1);i++)
        if (!dfn[i]) tarjan(i);
    // for (int i = 1;i <= n + M + 1;i++)
    // {
    //     printf("S0:%d S1:%d\n",scc_idx[s0(i)],scc_idx[s1(i)]);
    // }
    for (int i = 1;i <= n + M + 1;i++)
        if (scc_idx[s0(i)] == scc_idx[s1(i)])
        {
            // cout << "ERROR" << i << endl;
            cout << -1 << endl;return 0;
        }
    int cnt = 0;
    for (int i = 1;i <= n;i++)
        if (scc_idx[s1(i)] < scc_idx[s0(i)]) ++cnt;
    for (int i = n + 1;i <= n + M + 1;i++)
        if (scc_idx[s1(i + 1)] < scc_idx[s0(i + 1)])
        {
            cout /*<< "Output"*/ << cnt << ' ' << i - n << endl;
            break;
        }
    for (int i = 1;i <= n;i++)
        if (scc_idx[s1(i)] < scc_idx[s0(i)]) cout << i << ' ';
    return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn 800008
struct node
{
	int nxt,to;
}e[maxn<<1];
int n,m,p,M,cnt,h[maxn],ans[maxn],o;
void add(int x,int y)
{
	e[++cnt].nxt=h[x];
	e[cnt].to=y;
	h[x]=cnt;
}
int dfn[maxn<<1],low[maxn<<1],id,stac[maxn<<1],in[maxn<<1],head,k[maxn<<1],cmt;
void tarjan(int x)
{
	dfn[x]=low[x]=++id;
	stac[++head]=x;
	in[x]=1;
	for(int i=h[x];i;i=e[i].nxt)
	{
		int to=e[i].to;
		if(!dfn[to])
		{
			tarjan(to);
			low[x]=min(low[to],low[x]);
		}
		else
			if(in[to])
				low[x]=min(low[x],dfn[to]);
	}
	if(low[x]==dfn[x])
	{
		int y=stac[head--];
		in[x]=0;
		k[x]=++cmt;
		while(y!=x)
		{
			in[y]=0;
			k[y]=cmt;
			y=stac[head--];
		}
	}
}
int main()
{
	scanf("%d%d%d%d",&n,&p,&M,&m);
	int N=p+M+1;
	for(int i=1;i<=n;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		add(x+N,y);
		add(y+N,x);
	}
	for(int i=1;i<=p;i++)
	{
		int l,r;
		scanf("%d%d",&l,&r);
		add(i,l+p+N);
		add(i,r+1+p);
		add(l+p,i+N);
		add(r+1+p+N,i+N);
	}
	for(int i=1;i<=M;i++)
	{
		add(i+p,i+1+p);
		add(i+1+p+N,i+p+N);
	}
	for(int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		add(x,y+N);
		add(y,x+N);
	}
	add(p+1,p+1+N);
	for(int i=1;i<=(N<<1);i++)
		if(!dfn[i])
			tarjan(i);
	for(int i=1;i<=N;i++)
		if(k[i]==k[i+N])
		{
			cout<<-1;
			return 0;
		}
	for(int i=1;i<=p;i++)
		if(k[i+N]>k[i])
			ans[++o]=i;
	for(int i=1;i<=M;i++)
		if(k[i+1+p]<k[i+1+p+N])
		{
			cout<<o<<" "<<i<<endl;
			break;
		}
	//cout<<endl;
	for(int i=1;i<=o;i++)
		cout<<ans[i]<<" ";
}


#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn 2000008
struct node
{
	int nxt,to;
}e[maxn*3];
int n,m,p,M,cnt,h[maxn],ans[maxn],o;
void add(int x,int y)
{
	e[++cnt].nxt=h[x];
	e[cnt].to=y;
	h[x]=cnt;
}
int dfn[maxn],low[maxn],id,stac[maxn],in[maxn],head,k[maxn],cmt;
void tarjan(int x)
{
	dfn[x]=low[x]=++id;
	stac[++head]=x;
	in[x]=1;
	for(int i=h[x];i;i=e[i].nxt)
	{
		int to=e[i].to;
		if(!dfn[to])
		{
			tarjan(to);
			low[x]=min(low[to],low[x]);
		}
		else
			if(in[to])
				low[x]=min(low[x],dfn[to]);
	}
	if(low[x]==dfn[x])
	{
		int y=stac[head--];
		in[x]=0;
		k[x]=++cmt;
		while(y!=x)
		{
			in[y]=0;
			k[y]=cmt;
			y=stac[head--];
		}
	}
}
int main()
{
	scanf("%d%d%d%d",&n,&p,&M,&m);
	int N=p+M+1;
	for(int i=1;i<=n;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		add(x+N,y);
		add(y+N,x);
	}
	for(int i=1;i<=p;i++)
	{
		int l,r;
		scanf("%d%d",&l,&r);
		add(i,l+p+N);
		add(i,r+1+p);
		add(l+p,i+N);
		add(r+1+p+N,i+N);
	}
	for(int i=1;i<=M;i++)
	{
		add(i+p,i+1+p);
		add(i+1+p+N,i+p+N);
	}
	for(int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		add(x,y+N);
		add(y,x+N);
	}
	add(p+1,p+1+N);
	for(int i=1;i<=(N<<1);i++)
		if(!dfn[i])
			tarjan(i);
	for(int i=1;i<=N;i++)
		if(k[i]==k[i+N])
		{
			cout<<-1;
			return 0;
		}
	for(int i=1;i<=p;i++)
		if(k[i+N]>k[i])
			ans[++o]=i;
	for(int i=1;i<=M;i++)
		if(k[i+1+p]<k[i+1+p+N])
		{
			cout<<o<<" "<<i<<endl;
			break;
		}
	//cout<<endl;
	for(int i=1;i<=o;i++)
		cout<<ans[i]<<" ";
}


#include<bits/stdc++.h>

#define ll long long
#define INF 2147483647
#define tr(a) ((a) << 1)
#define fs(a) ((a) << 1 | 1)

int inp(){
    char c = getchar();
    while(c < '0' || c > '9')
        c = getchar();
    int sum = 0;
    while(c >= '0' && c <= '9'){
        sum = sum * 10 + c - '0';
        c = getchar();
    }
    return sum;
}

int head[3200010], nxt[4000010], end[4000010];
int dfn[3200010], low[3200010], col[3200010], st[3200010], top = 0;
bool ins[3200010];

int cnt = 0;
int idx = 0;
void tarjan(int cur){
    // printf("cur = %d\n", cur);
    dfn[cur] = low[cur] = ++idx;
    st[++top] = cur;
    ins[cur] = true;
    for(int x = head[cur]; x != -1; x = nxt[x]){
        if(!dfn[end[x]]){
            tarjan(end[x]);
            low[cur] = std::min(low[cur], low[end[x]]);
        } else if(ins[end[x]])
            low[cur] = std::min(low[cur], dfn[end[x]]);
    }
    // printf("dfn[%d] = %d, low[%d] = %d\n", cur, dfn[cur], cur, low[cur]);
    if(dfn[cur] == low[cur]){
        cnt++;
        while(st[top] != cur){
            // printf("cur = %d\n", st[top]);
            col[st[top]] = cnt;
            ins[st[top]] = false;
            top--;
        }
        col[cur] = cnt;
        top--;
        ins[cur] = false;
    }
}
int cou = 0;
void link(int a, int b){
    nxt[++cou] = head[a];
    head[a] = cou;
    end[cou] = b;
}

int main(){
    memset(head, -1, sizeof(head));
    int p = inp();
    int n = inp();
    int M = inp();
    int m = inp();
    for(int i = 1; i <= p; i++){
        int u = inp();
        int v = inp();
        link(fs(u), tr(v));
        link(fs(v), tr(u));
    }
    link(tr(n + 1), fs(n + 1));
    for(int i = 1; i <= n; i++){
        int l = inp();
        int r = inp();
        link(tr(i), tr(n + r + 1));
        link(fs(n + r + 1), fs(i));
        link(tr(i), fs(n + l));
        link(tr(n + l), fs(i));
    }
    for(int i = 1; i <= m; i++){
        int u = inp();
        int v = inp();
        link(tr(u), fs(v));
        link(tr(v), fs(u));
    }
    for(int i = n + 1; i <= n + M; i++){
        link(tr(i), tr(i + 1));
        link(fs(i + 1), fs(i));
    }
    for(int i = 1; i <= fs(n + M + 1); i++)
        if(!dfn[i])
            tarjan(i);
    std::vector<int> vec;
    for(int i = 1; i <= n + M + 1; i++){
        // printf("{%d, %d}\n", col[tr(i)], col[fs(i)]);
        if(col[tr(i)] == col[fs(i)]){
            printf("-1\n");
            return 0;
        }
        if(i <= n && col[tr(i)] < col[fs(i)])
            vec.push_back(i);
    }
    printf("%d ", vec.size());
    for(int i = n + 2; i <= n + M + 1; i++){
        if(col[tr(i)] < col[fs(i)]){
            printf("%d\n", i - n - 1);
            break;
        }
    }
    for(int i = 0; i < vec.size(); i++)
        printf("%d ", vec[i]);
    putchar('\n');
}
// ...


#include<bits/stdc++.h>

#define ll long long
#define INF 2147483647
#define tr(a) ((a) << 1)
#define fs(a) ((a) << 1 | 1)

int inp(){
    char c = getchar();
    while(c < '0' || c > '9')
        c = getchar();
    int sum = 0;
    while(c >= '0' && c <= '9'){
        sum = sum * 10 + c - '0';
        c = getchar();
    }
    return sum;
}

int head[1600010], nxt[2000010], end[2000010];
int dfn[1600010], low[1600010], col[1600010], st[1600010], top = 0;
bool ins[1600010];

int cnt = 0;
int idx = 0;
void tarjan(int cur){
    // printf("cur = %d\n", cur);
    dfn[cur] = low[cur] = ++idx;
    st[++top] = cur;
    ins[cur] = true;
    for(int x = head[cur]; x != -1; x = nxt[x]){
        if(!dfn[end[x]]){
            tarjan(end[x]);
            low[cur] = std::min(low[cur], low[end[x]]);
        } else if(ins[end[x]])
            low[cur] = std::min(low[cur], dfn[end[x]]);
    }
    // printf("dfn[%d] = %d, low[%d] = %d\n", cur, dfn[cur], cur, low[cur]);
    if(dfn[cur] == low[cur]){
        cnt++;
        while(st[top] != cur){
            // printf("cur = %d\n", st[top]);
            col[st[top]] = cnt;
            ins[st[top]] = false;
            top--;
        }
        col[cur] = cnt;
        top--;
        ins[cur] = false;
    }
}
int cou = 0;
void link(int a, int b){
    nxt[++cou] = head[a];
    head[a] = cou;
    end[cou] = b;
}

int main(){
    memset(head, -1, sizeof(head));
    int p = inp();
    int n = inp();
    int M = inp();
    int m = inp();
    for(int i = 1; i <= p; i++){
        int u = inp();
        int v = inp();
        link(fs(u), tr(v));
        link(fs(v), tr(u));
    }
    link(tr(n + 1), fs(n + 1));
    for(int i = 1; i <= n; i++){
        int l = inp();
        int r = inp();
        link(tr(i), tr(n + r + 1));
        link(fs(n + r + 1), fs(i));
        link(tr(i), fs(n + l));
        link(tr(n + l), fs(i));
    }
    for(int i = 1; i <= m; i++){
        int u = inp();
        int v = inp();
        link(tr(u), fs(v));
        link(tr(v), fs(u));
    }
    for(int i = n + 1; i <= n + M; i++){
        link(tr(i), tr(i + 1));
        link(fs(i + 1), fs(i));
    }
    for(int i = 1; i <= fs(n + M + 1); i++)
        if(!dfn[i])
            tarjan(i);
    std::vector<int> vec;
    for(int i = 1; i <= n + M + 1; i++){
        // printf("{%d, %d}\n", col[tr(i)], col[fs(i)]);
        if(col[tr(i)] == col[fs(i)]){
            printf("-1\n");
            return 0;
        }
        if(i <= n && col[tr(i)] < col[fs(i)])
            vec.push_back(i);
    }
    printf("%d ", vec.size());
    for(int i = n + 2; i <= n + M + 1; i++){
        if(col[tr(i)] < col[fs(i)]){
            printf("%d\n", i - n - 1);
            break;
        }
    }
    for(int i = 0; i < vec.size(); i++)
        printf("%d ", vec[i]);
    putchar('\n');
}