#include <iostream> // cout, endl, cin
#include <string> // string, to_string, stoi
#include <vector> // vector
#include <algorithm> // min, max, swap, sort, reverse, lower_bound, upper_bound
#include <utility> // pair, make_pair
#include <tuple> // tuple, make_tuple
#include <cstdint> // int64_t, int*_t
#include <cstdio> // printf
#include <map> // map
#include <queue> // queue, priority_queue
#include <set> // set
#include <stack> // stack
#include <deque> // deque
#include <unordered_map> // unordered_map
#include <unordered_set> // unordered_set
#include <bitset> // bitset
#include <cctype> // isupper, islower, isdigit, toupper, tolower
#include <stdexcept>
#include<math.h>
#include<iomanip>
using namespace std;


using ll=long long ;

#define rep(i,n)  for(int i=0;i<(n);i++)
#define f first
#define sc second
const int mod=1'000'000'007;

// UnionFind
// coding: https://youtu.be/TdR816rqc3s?t=726
// comment: https://youtu.be/TdR816rqc3s?t=6822
struct UnionFind {
  vector<int> d;
  UnionFind(int n=0): d(n,-1) {}
  int find(int x) {
    if (d[x] < 0) return x;
    return d[x] = find(d[x]);
  }
  bool unite(int x, int y) {
    x = find(x); y = find(y);
    if (x == y) return false;
    if (d[x] > d[y]) swap(x,y);
    d[x] += d[y];
    d[y] = x;
    return true;
  }
  bool same(int x, int y) { return find(x) == find(y);}
  int size(int x) { return -d[find(x)];}
};


int fact(int n){
if(n==0){
     return 1;
 }else{
     return n*fact(n-1);
 }
}

bool is_prime(int x){
if(x<=1) return false;
for(int i=2;i*i<x;i++){
    if(x%i==0) return false;}
return true;}

template<class T>void chmin(T& a,T b){
    if(a>b){
        a=b;
    }
}

template<class T>void chmax(T& a,T b){
    if(a<b){
        a=b;
    }
}
int gcd(int x, int y) {
     if(x % y == 0) {
        return y;
     } else {
        return gcd(y, x % y); 
     }
}

ll f(ll x,ll c,ll d){
    return x-x/c-x/d+x/(c/(gcd(c,d))*d);
}



string to_oct(int n){
    string s;
    while(n){
     s = std::to_string(n%8) + s;
     n /= 8;
    }
return s;
}

using Graph=vector<vector<int > >;


using namespace std;
vector<int> c;
vector<bool> seen;
vector<int>  num;
vector<int> ans;

void dfs(const Graph &G, int v,int p=-1) {
    //seen[v] = true; // v を訪問済にする
    num[c[v]]++;
    if(num[c[v]]==1)ans.push_back(v);
    // v から行ける各頂点 next_v について
    for (auto next_v : G[v]) { 
        if(p==next_v)continue;
        if (seen[next_v]) continue; // next_v が探索済だったらスルー
        dfs(G, next_v,v); // 再帰的に探索
    }
    num[c[v]]--;
}

int main(){
   int n;
   cin>>n;

   c=vector<int>(n+1);

   rep(i,n){
       cin>>c[i+1];
   }
   Graph g(n+1);
   rep(i,n-1){
       int a,b;
       cin>>a>>b;
       g[b].push_back(a);
       g[a].push_back(b);
   }
   seen.assign(n+1,false);
   num.assign(1000001,0);
   dfs(g,1);

   sort(ans.begin(),ans.end());

   for(auto a:ans)cout << a << endl;

}
#include <bits/stdc++.h>
using namespace std;
const int kN = 1e5 + 10;

int n;
vector<int> g[kN];
int a[kN], cnt[kN];
vector<int> ans;

void Dfs(int u, int fa = 0) {
  if(!cnt[a[u]]) ans.push_back(u);
  cnt[a[u]]++;
  for(int v : g[u]) if(v != fa) Dfs(v, u);
  cnt[a[u]]--;
}
int main() {
  scanf("%d", &n);
  for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
  for(int i = 1; i < n; i++) {
    int x, y; scanf("%d%d", &x, &y);
    g[x].push_back(y), g[y].push_back(x);
  }
  Dfs(1);
  sort(ans.begin(), ans.end());
  for(int x : ans) printf("%d\n", x);
  return 0;
}
