stablegradients/pie-gem5-bysrc huggingface dataset:
// Original C++ solution (slower):
#include <bits/stdc++.h>





using namespace std;





const int MAXN = 3000 + 3;







int n, a[MAXN];

vector<int> v, g[MAXN];









bool dfs(int v, int p = -1) {

    bool ret = false;

    for (auto u : g[v])

        if (u != p && a[u] < a[v])

            ret |= !dfs(u);

    return ret;

}















int main() {

    cin >> n;

    for (int i = 0; i < n; i++) cin >> a[i];

    for (int i = 1; i < n; i++) {

        int u, v;

        cin >> u >> v;

        g[--u].push_back(--v), g[v].push_back(u);

    }

    for (int i = 0; i < n; i++)

        if (dfs(i))

            cout << i + 1 << ' ';

    return 0;

}

// Optimized solution to the same problem (faster):
#include <cstdio>



const int N(3010);

struct edge { int next, to; } e[N << 1];

int n, A[N], head[N], e_num, ans[N];

inline void add_edge(int from, int to)

{

	e[++e_num] = (edge) {head[from], to};

	head[from] = e_num;

}



void dfs(int x, int f)

{

	ans[x] = 0;

	for (int i = head[x]; i; i = e[i].next) if (e[i].to != f && A[e[i].to] < A[x])

		{ dfs(e[i].to, x); if (!ans[e[i].to]) { ans[x] = 1; break; } }

}



int main()

{

	scanf("%d", &n);

	for (int i = 1; i <= n; i++) scanf("%d", A + i);

	for (int i = 1, a, b; i <= n; i++)

		scanf("%d%d", &a, &b), add_edge(a, b), add_edge(b, a);

	for (int i = 1; i <= n; i++) { dfs(i, 0); if (ans[i]) printf("%d ", i); }

	return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;

const int mx =10000;

vector<int> g[mx];

int a[mx];

bool dfs(int u,int par){

    bool re=(par!=0&&a[u]>=a[par]);

    for(auto v: g[u]){

        if(v==par)continue;

        re|=!dfs(v,u);

    }

    return re;

}

int main (){

    int n,u,v;

    scanf("%d",&n);

    for(int i=1;i<=n;i++){

        scanf("%d",a+i);

    }

    for(int i=0;i<n-1;i++){

        scanf("%d %d",&u,&v);

        g[u].push_back(v);

        g[v].push_back(u);

    }

    for(int i=1;i<=n;i++){

        if(dfs(i,0)){

            printf("%d ",i);

        }

    }

    return 0;

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;



const int MAXN = 3000 + 10;

int a[MAXN];

vector <int> adj[MAXN];



bool dfs(int v, int p = -1) {

	for (int i: adj[v])

		if (i != p) {

			if (a[i] >= a[v])

				continue;

			else if(!dfs(i, v))

				return true;

		}

	return false;

}



int main() {

	int n;

	cin >> n;

	for (int i = 0; i < n; i++)

		cin >> a[i];

	for (int i = 0; i < n - 1; i++) {

		int a, b;

		cin >> a >> b;

		a--, b--;

		adj[a].push_back(b);

		adj[b].push_back(a);

	}

	for (int i = 0; i < n; i++)

		if (dfs(i))

			cout << i + 1 << ' ';

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<iostream>

#include<cstdio>

#include<cstring>

using namespace std;

 

int tot=0,h[3005];

int n,x,y,f[3005],val[3005];

struct Edge{

    int x,next;

}e[6005];

 

inline void add_edge(int x,int y){

    e[++tot].x=y;

    e[tot].next=h[x],h[x]=tot;

}

 

void dfs(int x){

    f[x]=0;

    for(int i=h[x];i;i=e[i].next){

        if(~f[e[i].x])continue;

        dfs(e[i].x);

        if(val[e[i].x]<val[x]&&f[e[i].x]==0)f[x]=1;

    }

}

 

int main(){

    scanf("%d",&n);

    for(int i=1;i<=n;i++)scanf("%d",val+i);

    for(int i=1;i<n;i++){

        scanf("%d%d",&x,&y);

        add_edge(x,y);

        add_edge(y,x);

    }

    for(int i=1;i<=n;i++){

        memset(f,-1,sizeof(f));

        dfs(i);

        if(f[i])printf("%d ",i);

    }

}

// Optimized solution to the same problem (faster):
#include<cstdio>

#include<cstring>

#include<algorithm>

using namespace std;

int n,tot,a[3010],head[3010],to[6010],nxt[6010];

void add_edge(int u,int v){

	nxt[++tot]=head[u];

	to[tot]=v;

	head[u]=tot;

	return;

}

bool dfs(int u,int father){

	for(int i=head[u];~i;i=nxt[i]){

		int v=to[i];

		if(v!=father)

			if(a[v]<a[u]&&!dfs(v,u))

				return 1;

	}

	return 0;

}

int main(){

	memset(head,-1,sizeof(head));

	scanf("%d",&n);

	for(int i=1;i<=n;i++)

		scanf("%d",a+i);

	for(int i=1;i<n;i++){

		int u,v;

		scanf("%d%d",&u,&v);

		add_edge(u,v);

		add_edge(v,u);

	}

	for(int i=1;i<=n;i++)

		if(dfs(i,0))

			printf("%d ",i);

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

#define ll long long

#define pb push_back

#define mp make_pair

#define ld long double

#define F first

#define S second

#define pii pair<ll,ll>

 

using namespace :: std;

 

const ll maxn=3100;

const ll mod=1e9+7;

const ll inf=1e9+500;

 

ll a[maxn];

vector<ll> out[maxn];

vector<ll> in[maxn];

bool ans[maxn];

bool vis[maxn];

vector<ll> topol;

 

void dfs(ll a){

    vis[a]=1;

    for(auto v:in[a]){

        if(vis[v]==0){

            dfs(v);

        }

    }

    topol.pb(a);

}

char ansyal[maxn][maxn];

 

int main(){

    ll n;

    cin>>n;

    for(ll i=1;i<=n;i++){

        cin>>a[i];

    }

    for(ll i=1;i<n;i++){

        ll v,u;

        cin>>v>>u;

        if(a[v]!=a[u]){

            if(a[v]>a[u]){

                swap(v,u);

            }

            out[u].pb(v);

            in[v].pb(u);

        }

    }

    for(ll i=1;i<=n;i++){

        if(vis[i]==0){

            dfs(i);

        }

    }

    vector<ll> anss;

    for(ll i=n-1;i>=0;i--){

        ll v=topol[i];

        bool win=0;

        for(auto u:out[v]){

            // javab v-->u

            ansyal[v][u]='w';

            for(auto z:out[u]){

                if(ansyal[u][z]=='w'){

                    ansyal[v][u]='l';

                }

            }

            if(ansyal[v][u]=='w'){

                win=1;

            }

        }

        if(win){

            anss.pb(v);

        }

    }

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

    for(auto v:anss){

        cout<<v<<' ';

    }

}

// Optimized solution to the same problem (faster):
#include<cstdio>

#include<cstring>

#define maxn 3005

int n,a[maxn],ans[maxn],cnt;

bool f[maxn];

struct node { int v; node *nxt; } edge[maxn*2],*head[maxn],*ncnt;

void addedge(int u,int v)

{

	ncnt++;

	ncnt->v=v,ncnt->nxt=head[u];

	head[u]=ncnt;

}

bool dfs(int u,int fa)

{

	for(node *p=head[u];p;p=p->nxt)

	{

		int v=p->v;

		if(a[v]<a[u]&&!dfs(v,u)) return f[u]=true;

	}

	return f[u]=false;

}

int main()

{

	ncnt=&edge[0];

	scanf("%d",&n);

	for(int i=1;i<=n;i++) scanf("%d",&a[i]);

	for(int i=1;i<n;i++)

	{

		int u,v;

		scanf("%d%d",&u,&v);

		addedge(u,v); addedge(v,u);

	}

	for(int i=1;i<=n;i++)

	{

		memset(f,0,sizeof(f));

		if(dfs(i,0)) ans[++cnt]=i;

	}

	for(int i=1;i<=cnt;i++) printf("%d ",ans[i]);

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>



#define pb push_back



using namespace std;



const int MAXN = 3e4 + 10;



int a[MAXN];



vector<int> adj[MAXN];



bool dfs(int u, int fa = -1) {

	for (int v : adj[u]) {

		if (v != fa && a[v] < a[u] && !dfs(v))

			return true;

	}

	return false;

}



int main() {

	int n;

	cin >> n;

	for (int i = 0; i < n; ++i)

		cin >> a[i];

	for (int i = 1; i < n; ++i) {

		int u, v;

		cin >> u >> v;

		adj[--u].pb(--v);

		adj[v].pb(u);

	}

	for (int i = 0; i < n; i++) {

		if (dfs(i))

			cout << i + 1 << " ";

	}



	return 0;

}

// Optimized solution to the same problem (faster):
#include<cstdio>

#include<cstring>

#define maxn 3005

int n,a[maxn],ans[maxn],cnt;

bool f[maxn];

struct node { int v; node *nxt; } edge[maxn*2],*head[maxn],*ncnt;

void addedge(int u,int v)

{

	ncnt++;

	ncnt->v=v,ncnt->nxt=head[u];

	head[u]=ncnt;

}

bool dfs(int u,int fa)

{

	for(node *p=head[u];p;p=p->nxt)

	{

		int v=p->v;

		if(a[v]<a[u]&&!dfs(v,u)) return f[u]=true;

	}

	return f[u]=false;

}

int main()

{

	ncnt=&edge[0];

	scanf("%d",&n);

	for(int i=1;i<=n;i++) scanf("%d",&a[i]);

	for(int i=1;i<n;i++)

	{

		int u,v;

		scanf("%d%d",&u,&v);

		addedge(u,v); addedge(v,u);

	}

	for(int i=1;i<=n;i++)

	{

		memset(f,0,sizeof(f));

		if(dfs(i,0)) ans[++cnt]=i;

	}

	for(int i=1;i<=cnt;i++) printf("%d ",ans[i]);

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>



#define pb push_back



using namespace std;



const int MAXN = 3e4 + 10;



int a[MAXN];



vector<int> adj[MAXN];



bool dfs(int u) {

	for (int v : adj[u]) {

		if (a[v] < a[u] && !dfs(v))

			return true;

	}

	return false;

}



int main() {

	int n;

	cin >> n;

	for (int i = 0; i < n; ++i)

		cin >> a[i];

	for (int i = 1; i < n; ++i) {

		int u, v;

		cin >> u >> v;

		u--;

		v--;

		adj[u].pb(v);

		adj[v].pb(u);

	}

	for (int i = 0; i < n; i++) {

		if (dfs(i))

			cout << i + 1 << " ";

	}



	return 0;

}

// Optimized solution to the same problem (faster):
#include<cstdio>

#include<cstring>

#define maxn 3005

int n,a[maxn],ans[maxn],cnt;

bool f[maxn];

struct node { int v; node *nxt; } edge[maxn*2],*head[maxn],*ncnt;

void addedge(int u,int v)

{

	ncnt++;

	ncnt->v=v,ncnt->nxt=head[u];

	head[u]=ncnt;

}

bool dfs(int u,int fa)

{

	for(node *p=head[u];p;p=p->nxt)

	{

		int v=p->v;

		if(a[v]<a[u]&&!dfs(v,u)) return f[u]=true;

	}

	return f[u]=false;

}

int main()

{

	ncnt=&edge[0];

	scanf("%d",&n);

	for(int i=1;i<=n;i++) scanf("%d",&a[i]);

	for(int i=1;i<n;i++)

	{

		int u,v;

		scanf("%d%d",&u,&v);

		addedge(u,v); addedge(v,u);

	}

	for(int i=1;i<=n;i++)

	{

		memset(f,0,sizeof(f));

		if(dfs(i,0)) ans[++cnt]=i;

	}

	for(int i=1;i<=cnt;i++) printf("%d ",ans[i]);

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<iostream>

#include<cstring>

#include<cstdio>

#include<algorithm>

#define N 3010

using namespace std;

struct edges{

	int to,pre;

}e[N<<1];int h[N],etop,a[N];

inline int add_edge(int u,int v)

{	return e[++etop].to=v,e[etop].pre=h[u],h[u]=etop;	}

int can(int x,int fa=0)

{

	for(int i=h[x];i;i=e[i].pre)

	{

		int y=e[i].to;if(y==fa) continue;

		if(a[x]>a[y]&&!can(y)) return true;

	}

	return false;

}

int main()

{

	int n;scanf("%d",&n);

	for(int i=1;i<=n;i++) scanf("%d",&a[i]);

	for(int i=1;i<n;i++)

	{

		int u,v;scanf("%d%d",&u,&v);

		add_edge(u,v),add_edge(v,u);

	}

	for(int i=1;i<=n;i++)

		if(can(i)) printf("%d ",i);

	return !printf("\n");

}

// Optimized solution to the same problem (faster):
#include<cstdio>

#include<cstring>

#define maxn 3005

int n,a[maxn],ans[maxn],cnt;

bool f[maxn];

struct node { int v; node *nxt; } edge[maxn*2],*head[maxn],*ncnt;

void addedge(int u,int v)

{

	ncnt++;

	ncnt->v=v,ncnt->nxt=head[u];

	head[u]=ncnt;

}

bool dfs(int u,int fa)

{

	for(node *p=head[u];p;p=p->nxt)

	{

		int v=p->v;

		if(a[v]<a[u]&&!dfs(v,u)) return f[u]=true;

	}

	return f[u]=false;

}

int main()

{

	ncnt=&edge[0];

	scanf("%d",&n);

	for(int i=1;i<=n;i++) scanf("%d",&a[i]);

	for(int i=1;i<n;i++)

	{

		int u,v;

		scanf("%d%d",&u,&v);

		addedge(u,v); addedge(v,u);

	}

	for(int i=1;i<=n;i++)

	{

		memset(f,0,sizeof(f));

		if(dfs(i,0)) ans[++cnt]=i;

	}

	for(int i=1;i<=cnt;i++) printf("%d ",ans[i]);

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;



#define pb push_back

#define ff first

#define ss second



const long long MAXN = 3e3 + 21, LG = 20, inf = 1e18;



int n;

int a[MAXN];

bool dp[MAXN];

vector<int> adj[MAXN];



void dfs(int v, int par = -1){

    dp[v] = 0;

    for(auto &y: adj[v])

        if(y ^ par && a[v] > a[y]) {

            dfs(y, v);

            dp[v] |= (!dp[y]);

        }

}



int main(){

    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);

    cin >> n;

    for(int i = 1; i <= n; i++)

        cin >> a[i];

    for(int i = 1; i < n; i++) {

        int u, v;

        cin >> u >> v;

        adj[u].pb(v);

        adj[v].pb(u);

    }



    for(int i = 1; i <= n; i++){

        dfs(i);

        if(dp[i]) 

            cout << i << ' ';

    }

    cout <<'\n';

    return 0;

}

// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>



#define LL long long

#define RG register



using namespace std;

template<class T> T gi() {

	T x = 0; bool f = 0; char c = getchar();

	while (c != '-' && (c < '0' || c > '9')) c = getchar();

	if (c == '-') f = 1, c = getchar();

	while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();

	return f ? -x : x;

}

const int N = 5010;

struct node { int to, nxt; } g[N << 1];

int lst[N], gl, n, f[N], a[N];

void add(int x, int y) {

	g[++gl] = (node) {y, lst[x]}; lst[x] = gl;

	g[++gl] = (node) {x, lst[y]}; lst[y] = gl;

}

void dfs(int u, int ff) {

	f[u] = 0;

	for (int i = lst[u]; i; i = g[i].nxt) {

		int v = g[i].to; if (v == ff || a[v] >= a[u]) continue;

		dfs(v, u); if (!f[v]) { f[u] = 1; break; }

	}

	return ;

}

int main() {

	//freopen(".in", "r", stdin);

	//freopen(".out", "w", stdout);

	n = gi<int>();

	for (int i = 1; i <= n; i++) a[i] = gi<int>();

	for (int i = 1; i < n; i++) add(gi<int>(), gi<int>());

	for (int i = 1; i <= n; i++) {

		dfs(i, 0);

		if (f[i]) printf("%d ", i);

	}

	return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<cmath>

#include<cstdio>

#include<iostream>

#include<cstdlib>

#include<algorithm>

#include<cstring>

#include<map>

#include<queue>

#include<set>

#include<vector>

#include<bitset>

#define int long long

#define lowbit(x) ((x)&(-x))

using namespace std;

const int maxn=10005;

int n,a[maxn],head[maxn],cnt,bisheng[maxn];

struct edge

{

	int to,next;

}e[maxn<<1];

inline int read()

{

    int x=0,f=1;

    char ch=getchar();

    while(ch<'0'||ch>'9')

    {

		if(ch=='-')

			f=-1;

		ch=getchar();

    }

    while(ch>='0'&&ch<='9')

    {

		x=(x<<1)+(x<<3)+(ch^48);

		ch=getchar();

    }

    return x*f;

}

inline void write(int a)

{

    if(a<0)

    {

		putchar('-');

		putchar('1');

    }

    else

    {

		if(a>=10)

			write(a/10);

		putchar(a%10+'0');

    }

}

void add(int from,int to)

{

	e[++cnt]=(edge){to,head[from]};

	head[from]=cnt;

}

void dfs(int now,int father)

{

	for(int i=head[now];i;i=e[i].next)

	{

		int to=e[i].to;

		if(to==father)

			continue;

		dfs(to,now);

		if(!bisheng[to]&&a[now]>a[to])

			bisheng[now]=1;

	}

}

signed main()

{

	n=read();

	for(int i=1;i<=n;++i)

		a[i]=read();

	for(int i=1;i<n;++i)

	{

		int u=read(),v=read();

		add(u,v),add(v,u);

	}

	for(int i=1;i<=n;++i)

	{

		memset(bisheng,0,sizeof(bisheng));

		dfs(i,0);

		if(bisheng[i])

			write(i),putchar(' ');

	}

    return 0;

}


// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>



#define LL long long

#define RG register



using namespace std;

template<class T> T gi() {

	T x = 0; bool f = 0; char c = getchar();

	while (c != '-' && (c < '0' || c > '9')) c = getchar();

	if (c == '-') f = 1, c = getchar();

	while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();

	return f ? -x : x;

}

const int N = 5010;

struct node { int to, nxt; } g[N << 1];

int lst[N], gl, n, f[N], a[N];

void add(int x, int y) {

	g[++gl] = (node) {y, lst[x]}; lst[x] = gl;

	g[++gl] = (node) {x, lst[y]}; lst[y] = gl;

}

void dfs(int u, int ff) {

	f[u] = 0;

	for (int i = lst[u]; i; i = g[i].nxt) {

		int v = g[i].to; if (v == ff || a[v] >= a[u]) continue;

		dfs(v, u); if (!f[v]) { f[u] = 1; break; }

	}

	return ;

}

int main() {

	//freopen(".in", "r", stdin);

	//freopen(".out", "w", stdout);

	n = gi<int>();

	for (int i = 1; i <= n; i++) a[i] = gi<int>();

	for (int i = 1; i < n; i++) add(gi<int>(), gi<int>());

	for (int i = 1; i <= n; i++) {

		dfs(i, 0);

		if (f[i]) printf("%d ", i);

	}

	return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

int read(){

	int x=0,f=1;char c=getchar();

	while(c<'0'||c>'9') c=='-'?f=-1,c=getchar():c=getchar();

	while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();

	return x*f;

}

int head[30001],cnt,w[30001],pd[30001];

struct node {

	int to,next;

}a[30001];

void add(int x,int y){

	a[++cnt].to=y;

	a[cnt].next=head[x];

	head[x]=cnt;

}

void dfs(int x,int fa){

    for(int i=head[x];i;i=a[i].next){

		int v=a[i].to;

		if(v==fa||w[v]>=w[x])

			continue;

		dfs(v,x);

		if(!pd[v]){

			pd[x]=1;

			break;

		}

	}

}

int main(){

	int n=read(),x,y;

	for(int i=1;i<=n;i++)

		w[i]=read();

	for(int i=1;i<n;i++)

		x=read(),y=read(),add(x,y),add(y,x);

	for(int i=1;i<=n;i++){

		memset(pd,0,sizeof(pd));

		dfs(i,0);

		if(pd[i])

			printf("%d ",i);

	}

	return 0;

}

// Optimized solution to the same problem (faster):
#include<cstdio>

#include<cstring>

const int N=3069;

template<typename TP>

inline void read(TP &kk)

{

	TP ret=0,f=1;char ch=getchar();

	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}

	while(ch>='0'&&ch<='9'){ret=ret*10+ch-'0';ch=getchar();}

	kk=ret*f;

}

int n,a[N];

struct sumireko{int to,ne;}e[N<<1];

int he[N],ecnt;

void addline(int f,int t)

{

	e[++ecnt].to=t;

	e[ecnt].ne=he[f];

	he[f]=ecnt;

}

int dp[N];

void dfs(int x,int f)

{

	for(int i=he[x],t;i;i=e[i].ne)

	{

		t=e[i].to;

		if(t==f) continue;

		dfs(t,x);

		if(a[t]<a[x]&&(!dp[t])) dp[x]=1;

	}

}



int xi,yi;

signed main()

{

	read(n);

	for(int i=1;i<=n;i++) read(a[i]);

	for(int i=1;i<n;i++)

	{

		read(xi),read(yi);

		addline(xi,yi),addline(yi,xi);

	}

	for(int i=1;i<=n;i++)

	{

		memset(dp,0,sizeof(dp));

		dfs(i,0);

		if(dp[i]) printf("%d ",i);

	}

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<iostream>

#include<vector>

using namespace std;

const int N=3400;

vector<int> E[N];

int n,A[N];

int dfs(int x,int fr)

{

	for(auto R:E[x])

		if(R!=fr&&A[x]>A[R]&&!dfs(R,x)) return 1;

	return 0;

}

int main()

{

	cin>>n;

	for(int i=1;i<=n;i++) cin>>A[i];

	for(int i=1,x,y;i<n;i++) cin>>x>>y,E[x].push_back(y),E[y].push_back(x);

	for(int i=1;i<=n;i++) if(dfs(i,0)) printf("%d ",i);

}


// Optimized solution to the same problem (faster):
#include<cstdio>

#include<cstring>

const int N=3069;

template<typename TP>

inline void read(TP &kk)

{

	TP ret=0,f=1;char ch=getchar();

	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}

	while(ch>='0'&&ch<='9'){ret=ret*10+ch-'0';ch=getchar();}

	kk=ret*f;

}

int n,a[N];

struct sumireko{int to,ne;}e[N<<1];

int he[N],ecnt;

void addline(int f,int t)

{

	e[++ecnt].to=t;

	e[ecnt].ne=he[f];

	he[f]=ecnt;

}

int dp[N];

void dfs(int x,int f)

{

	for(int i=he[x],t;i;i=e[i].ne)

	{

		t=e[i].to;

		if(t==f) continue;

		dfs(t,x);

		if(a[t]<a[x]&&(!dp[t])) dp[x]=1;

	}

}



int xi,yi;

signed main()

{

	read(n);

	for(int i=1;i<=n;i++) read(a[i]);

	for(int i=1;i<n;i++)

	{

		read(xi),read(yi);

		addline(xi,yi),addline(yi,xi);

	}

	for(int i=1;i<=n;i++)

	{

		memset(dp,0,sizeof(dp));

		dfs(i,0);

		if(dp[i]) printf("%d ",i);

	}

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <algorithm>

#include <iostream>

#include <cstring>

#include <climits>

#include <cstdlib>

#include <utility>

#include <cstdio>

#include <vector>

#include <queue>

#include <stack>

#include <cmath>

#include <map>

#include <set>

#define ri register int

#define pi acos(-1.0)



using namespace std;



inline char gch()

{

    static char buf[100010], *h = buf, *t = buf;

    return h == t && (t = (h = buf) + fread(buf, 1, 100000, stdin), h == t) ? EOF : *h ++;

}



typedef long long lo;



typedef unsigned int uint;



template<typename inp_typ>



inline void re(inp_typ &x)

{

    x = 0;

    char a; bool b = 0;

    while(!isdigit(a = getchar()))

        b = a == '-';

    while(isdigit(a))

        x = x * 10 + a - '0', a = getchar();

    if(b == 1)

        x = - x;

}



bool sta[5050];



int tot = -1, lx, ly, head[5050], n, a[5050];



struct in

{

    int to, ne;

}ter[10010];



inline void build(int f, int l)

{

    ter[++ tot] = (in){l, head[f]}, head[f] = tot;

    ter[++ tot] = (in){f, head[l]}, head[l] = tot;

}



void dfs(int no, int f)

{

    sta[no] = 0;

    for(ri i = head[no]; i >= 0; i = ter[i].ne)

    {

        int to = ter[i].to;

        if(to == f)

            continue;

        dfs(to, no);

        if(a[no] > a[to] && (!sta[to]))

        {

            sta[no] = 1; break;

        }

    }

}



int main()

{

    re(n), memset(head, -1, sizeof(head));

    for(ri i = 1; i <= n; re(a[i ++]));

    for(ri i = 1; i < n; i ++)

        re(lx), re(ly), build(lx, ly);

    for(ri i = 1; i <= n; i ++)

    {

        dfs(i, 0);

        if(sta[i])

            printf("%d ", i);

    }

}

// Optimized solution to the same problem (faster):
#include<cstdio>

#include<cstring>

const int N=3069;

template<typename TP>

inline void read(TP &kk)

{

	TP ret=0,f=1;char ch=getchar();

	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}

	while(ch>='0'&&ch<='9'){ret=ret*10+ch-'0';ch=getchar();}

	kk=ret*f;

}

int n,a[N];

struct sumireko{int to,ne;}e[N<<1];

int he[N],ecnt;

void addline(int f,int t)

{

	e[++ecnt].to=t;

	e[ecnt].ne=he[f];

	he[f]=ecnt;

}

int dp[N];

void dfs(int x,int f)

{

	for(int i=he[x],t;i;i=e[i].ne)

	{

		t=e[i].to;

		if(t==f) continue;

		dfs(t,x);

		if(a[t]<a[x]&&(!dp[t])) dp[x]=1;

	}

}



int xi,yi;

signed main()

{

	read(n);

	for(int i=1;i<=n;i++) read(a[i]);

	for(int i=1;i<n;i++)

	{

		read(xi),read(yi);

		addline(xi,yi),addline(yi,xi);

	}

	for(int i=1;i<=n;i++)

	{

		memset(dp,0,sizeof(dp));

		dfs(i,0);

		if(dp[i]) printf("%d ",i);

	}

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

#define F first

#define S second

#define pii pair<int,int>

#define pb push_back

typedef long long ll;

const int N = 3 * 1e5 + 10;

using namespace std;

vector<int> adj[N];

bool dp[N]; int e[N];



void dfs(int v , int p = 0){

    for(auto u : adj[v]){

        if(u == p)continue;

        dfs(u , v);

        if(e[u] < e[v] && !dp[u])dp[v] = true;

    }

}



int main(){

    ios_base::sync_with_stdio(0); cin.tie(0);

    int n; cin >> n;

    for(int i=1;i<=n;i++)cin >> e[i];

    for(int i=0;i<n-1;i++){

        int u , v; cin >> u >> v;

        adj[u].pb(v);

        adj[v].pb(u);

    }

    for(int i=1;i<=n;i++){

        memset(dp , 0 , sizeof dp);

        dfs(i);

        if(dp[i])cout << i << ' ';

    }cout << '\n';

}


// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

#define F first

#define S second

#define pii pair<int,int>

#define pb push_back

typedef long long ll;

const int N = 3107;

using namespace std;

vector<int> adj[N];

bool dp[N]; int e[N];



void dfs(int v , int p = 0){

    for(auto u : adj[v]){

        if(u == p)continue;

        dfs(u , v);

        if(e[u] < e[v] && !dp[u])dp[v] = true;

    }

}



int main(){

    ios_base::sync_with_stdio(0); cin.tie(0);

    int n; cin >> n;

    for(int i=1;i<=n;i++)cin >> e[i];

    for(int i=0;i<n-1;i++){

        int u , v; cin >> u >> v;

        adj[u].pb(v);

        adj[v].pb(u);

    }

    for(int i=1;i<=n;i++){

        memset(dp , 0 , sizeof dp);

        dfs(i);

        if(dp[i])cout << i << ' ';

    }cout << '\n';

}


// Fastest known solution for this problem: