1 #include<bits/stdc++.h>
2 using namespace std;
3 inline void read(int &tmp)
4 {
5 int x=1;char c=getchar();
6 for(tmp=0;!isdigit(c);c=getchar()) if(c=='-') x=-1;
7 for(;isdigit(c);tmp=tmp*10+c-48,c=getchar());
8 tmp*=x;
9 }
10 const int maxn=2000005;
11 const int maxm=4000005;
12 const int INF=0x3f3f3f3f;
13 struct node{//并查集
14 int val,fa;//val- 权值(时间)
15 }f[maxn];
16 struct data{//链表
17 int l,r;
18 }my_list[maxn];
19 struct edge{//存边
20 int f,s;//f-编号 s-左右手
21 }e[maxn];
22 bool del[maxn][5];//标记已删除的边
23 int find(int x)
24 {
25 if(f[x].fa==x) return x;
26 int root=find(f[x].fa);
27 f[x].val=min(f[x].val,f[f[x].fa].val);//不断更新最小值
28 return f[x].fa=root;
29 }
30 void Union(int x,int y,int z)//用并查集在x和y之间连一条权值为z的边
31 {
32 x=find(x),y=find(y);
33 if(x==y) return;
34 if(x==1) f[y].fa=x,f[y].val=z;//默认1号为根节点
35 else f[x].fa=y,f[x].val=z;
36 }
37 int n,m;
38 int main()
39 {
40 read(n),read(m);
41 for(int i=1;i<=n;i++) f[i].fa=i,f[i].val=INF;//初始化
42 for(int i=1;i<=n;i++) read(my_list[i].l),read(my_list[i].r);
43 for(int i=1;i<=m;i++)
44 {
45 read(e[i].f);read(e[i].s);//读入边
46 del[e[i].f][e[i].s]=true;//标记已删除
47 }
48 for(int i=1;i<=n;i++)//将最后连在一起的猴子并在一起
49 {
50 if(!del[i][1]&&my_list[i].l!=-1) Union(i,my_list[i].l,INF);
51 if(!del[i][2]&&my_list[i].r!=-1) Union(i,my_list[i].r,INF);
52 }
53 for(int i=m;i>=1;i--)//倒序处理
54 {
55 if(e[i].s==1&&my_list[e[i].f].l!=-1) Union(e[i].f,my_list[e[i].f].l,i-1);
56 if(e[i].s==2&&my_list[e[i].f].r!=-1) Union(e[i].f,my_list[e[i].f].r,i-1);
57 }
58 for(int i=1;i<=n;i++)
59 {
60 find(i);//路径压缩 更新权值
61 printf("%d\n",f[i].val==INF?-1:f[i].val);
62 }
63 return 0;
64 }