//misaka will carry me to master #include #include #include #include #include #include #include #include #include #include #include #include #define ll long long #define lb long double #define sz(vec) ((int)(vec.size())) #define all(x) x.begin(), x.end() #define pb push_back #define mp make_pair const lb eps = 1e-9; const ll mod = 1e9 + 7, ll_max = 1e18; //const ll mod = (1 << (23)) * 119 +1; const int MX = 2e5 +10, int_max = 0x3f3f3f3f; using namespace std; //negative trust //so i need a trie that does //xor all and max //easiest is a push/pull implicit segtree const int NN = MX*20; char flag[NN]; int lc[NN], rc[NN], tag[NN]; int root[MX]; int xum[MX], grundy[MX]; int color[MX]; vector adj[MX]; int n; const int LG = 20, s = (1 << LG); #define lsb(x) (x&(-x)) void push(int k, int a){ if(tag[k]){ if(a&tag[k]) swap(lc[k], rc[k]); if(lc[k]) tag[lc[k]] ^= tag[k]; if(rc[k]) tag[rc[k]] ^= tag[k]; } tag[k] = 0; } void pull(int k){ if(flag[lc[k]] && flag[rc[k]]){ flag[k] = 1; } } void dup(int& k){ static int ind = 0; if(!k) k = ++ind; } void U(int p, int &k, int L, int R){ dup(k); if(L + 1 == R){ assert(L == p); //cout << "wave\n"; flag[k] = 1; return ; } int mid = (L + R)/2; push(k, lsb(mid)); if(p < mid) U(p, lc[k], L, mid); else U(p, rc[k], mid, R); pull(k); } void merge(int& k1, int k2, int d){ if(min(k1, k2) == 0){ k1 ^= k2; return ; } if(d == 0){ return ; } push(k1, (1 << (d-1))); push(k2, (1 << (d-1))); merge(lc[k1], lc[k2], d-1); merge(rc[k1], rc[k2], d-1); pull(k1); } int mex(int k, int L, int R){ if(L + 1 == R) return L; int mid = (L + R)/2; push(k, lsb(mid)); if(flag[lc[k]]) return mex(rc[k], mid, R); else return mex(lc[k], L, mid); } void dfs(int u, int p){ for(int v : adj[u]){ if(v == p) continue; dfs(v, u); xum[u] ^= grundy[v]; } if(color[u] == 0){ U(xum[u], root[u], 0, s); }else{ dup(root[u]); } for(int v : adj[u]){ if(v == p) continue; if(root[v]){ tag[root[v]] ^= xum[u] ^ grundy[v]; merge(root[u], root[v], LG); //i hope //cout << "new root " << root[u] << "\n"; } } grundy[u] = mex(root[u], 0, s); } vector ans; void dfs2(int u, int p, int tot){ tot ^= xum[u]; if(tot == 0 && color[u] == 0){ ans.pb(u); } for(int v : adj[u]){ if(v != p){ dfs2(v, u, tot^grundy[v]); } } } void solve(){ cin >> n; for(int i = 1; i<=n; i++){ cin >> color[i]; } for(int i = 1; i> a >> b; adj[a].pb(b); b[adj].pb(a); } dfs(1, 0); //for(int i = 1; i<=n; i++){ //cout << grundy[i] << " " ; //} cout << "\n"; //for(int i = 1; i<=n; i++){ //cout << xum[i] << " " ; //} cout << "\n"; if(grundy[1] == 0){ cout << "-1\n"; }else{ dfs2(1, 0, 0); sort(all(ans)); for(int x : ans){ cout << x << "\n"; } } } int main(){ cin.tie(0) -> sync_with_stdio(0); int T = 1; //cin >> T; while(T--){ solve(); } return 0; }