#include
using namespace std;
struct edge { int t; edge *ne; };
struct node { int sz, rv; node *ch[2]; };
const int maxn = 100003; const int maxnd = maxn * 46; const int maxl = 19;
int n, vo[maxn], f[maxn], sp[maxn], tsp; node nbuf_arr[maxnd], *nbuf(nbuf_arr), *rt[maxn]; edge ebuf_arr[maxn « 1], *ebuf(ebuf_arr), *head[maxn];
#define szof(p) (p?p->sz:0)
inline void pushDown(node* q, int l) { if ((q-> rv » l) & 1) swap(q-> ch[0], q-> ch[1]); if (q-> ch[0]) q-> ch[0]-> rv ^= q-> rv; if (q-> ch[1]) q-> ch[1]-> rv ^= q-> rv; q-> rv = 0; }
node* trieIns(int v) { node s(nbuf ++), p(s); for (int i = maxl; i >= 0; – i) { int d((v » i)& 1); p-> sz = 1, p-> rv = 0; p-> ch[d ^ 1] = 0; p-> ch[d] = nbuf ++; p = p-> ch[d]; } p-> sz = 1; return s; } node trieMerge(node p, node* q, int l, int x) { if (!p) { if (q) q-> rv ^= x; return q; } else if (!q) { return p; } node r(nbuf ++); if (l == -1) { r-> ch[0] = r-> ch[1] = 0; r-> sz = 1, r-> rv = 0; } else { int d((x » l) & 1); pushDown(p, l); pushDown(q, l); r-> ch[0] = trieMerge(p-> ch[0], q-> ch[d], l - 1, x); r-> ch[1] = trieMerge(p-> ch[1], q-> ch[d ^ 1], l - 1, x); r-> sz = szof(r-> ch[0]) + szof(r-> ch[1]); } return r; } int trieMex(node p) { int ans(0); for (int i = maxl; i >= 0 && p; – i) { pushDown(p, i); if (szof(p-> ch[0]) == (1 « i)) { p = p-> ch[1]; ans |= 1 « i; } else p = p-> ch[0]; } return ans; }
void triePrint(node* p, int l, int v) { if (l == -1) { fprintf(stderr, “%d “, v); } else { pushDown(p, l); if (p-> ch[0]) triePrint(p-> ch[0], l - 1, v); if (p-> ch[1]) triePrint(p-> ch[1], l - 1, v | (1 « l)); } }
void sgDFS(int p, int fr) { rt[p] = 0; int xs(0); for (edge* e = head[p]; e; e = e-> ne) if (e-> t != fr) { sgDFS(e-> t, p); xs ^= f[e-> t]; } if (!vo[p]) rt[p] = trieIns(xs); for (edge* e = head[p]; e; e = e-> ne) if (e-> t != fr) rt[p] = trieMerge(rt[p], rt[e-> t], maxl, xs ^ f[e-> t]); f[p] = trieMex(rt[p]); }
void ansDFS(int p, int fr, int xf) { int xs(0); for (edge* e = head[p]; e; e = e-> ne) if (e-> t != fr) xs ^= f[e-> t]; if (vo[p] == 0 && (xs ^ xf) == 0) sp[tsp ++] = p; for (edge* e = head[p]; e; e = e-> ne) if (e-> t != fr) ansDFS(e-> t, p, xf ^ xs ^ f[e-> t]); }
inline void addEdge(int u, int v) { ebuf-> t = v; ebuf-> ne = head[u]; head[u] = ebuf ++; }
int main() { #ifdef LAEKOV_LOCAL freopen(".in”, “r”, stdin); #endif
scanf("%d", &n);
for (int i = 1; i <= n; ++ i)
scanf("%d", vo + i);
memset(head, 0, sizeof(head));
for (int i = 1; i < n; ++ i) {
int u, v;
scanf("%d%d", &u, &v);
addEdge(u, v);
addEdge(v, u);
}
sgDFS(1, 0);
if (f[1]) {
tsp = 0;
ansDFS(1, 0, 0);
sort(sp, sp + tsp);
for (int i = 0; i < tsp; ++ i)
printf("%d%c", sp[i], 10);
}
else
puts("-1");
}