stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#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);

    }

}

// Faster C++ solution for the same problem (measured speedup: 4.978079486521699x):
#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;

}
// Slower C++ solution:
#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';

}


// Faster C++ solution for the same problem (measured speedup: 8.99041484619559x):
#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';

}
// Slower C++ solution:
#include <cmath>

#include <cstdio>

#include <cstring>

#include <iostream>

#include <algorithm>

#define For(i, a, b) for (i = a; i <= b; i++)

#define Tree(u) for (int e = adj[u], v; e; e = nxt[e]) if ((v = go[e]) != fu)



inline int read()

{

	int res = 0; bool bo = 0; char c;

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

	if (c == '-') bo = 1; else res = c - 48;

	while ((c = getchar()) >= '0' && c <= '9')

		res = (res << 3) + (res << 1) + (c - 48);

	return bo ? ~res + 1 : res;

}



const int N = 3005, M = N << 1;



int n, a[N], ecnt, nxt[M], adj[N], go[M];

bool f[N];



void add_edge(int u, int v)

{

	nxt[++ecnt] = adj[u]; adj[u] = ecnt; go[ecnt] = v;

	nxt[++ecnt] = adj[v]; adj[v] = ecnt; go[ecnt] = u;

}



void dfs(int u, int fu)

{

	f[u] = 0;

	Tree(u)

	{

		dfs(v, u);

		if (a[v] < a[u]) f[u] |= !f[v];

	}

}



int main()

{

	int i, x, y;

	n = read();

	For (i, 1, n) a[i] = read();

	For (i, 1, n - 1)

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

	For (i, 1, n) if (dfs(i, 0), f[i]) printf("%d ", i);

	std::cout << std::endl;

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 5.13206288699x):
#if 0

#endif

#include <cstdio>

#include <algorithm>



inline int input() { int x; scanf("%d", &x); return x; }



const int maxn = 3030;

int head[maxn], nxt[maxn << 1], to[maxn << 1], hp;

bool vis[maxn], win[maxn];

int a[maxn];



inline void add(int u, int v) {

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

	head[u] = hp;

	to[hp] = v;

}



void dfs(int u) {

	vis[u] = true;

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

		if(not vis[to[i]])

			dfs(to[i]);

		if(not win[to[i]])

			win[u] = true;

	}

}



int main() {

	int n = input();

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

		a[i] = input();

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

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

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

			add(u, v);

		else if(a[u] < a[v])

			add(v, u);

	}

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

		if(not vis[u])

			dfs(u);

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

		if(win[u])

			printf("%d ", u);

	puts("");

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

int a[3005],x,y,n;

vector<int>e[3005];

int dfs(int x,int fa)

{

    for(int i=0;i<e[x].size();i++) if(e[x][i]!=fa&&a[x]>a[e[x][i]]&&!dfs(e[x][i],x)) return 1;

    return 0;

}

int main()

{

    scanf("%d",&n);

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

    for(int i=1;i<n;i++) scanf("%d%d",&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);

}

// Faster C++ solution for the same problem (measured speedup: 5.55765607953406x):
#if 0

#endif

#include <cstdio>

#include <algorithm>



inline int input() { int x; scanf("%d", &x); return x; }



const int maxn = 3030;

int head[maxn], nxt[maxn << 1], to[maxn << 1], hp;

bool vis[maxn], win[maxn];

int a[maxn];



inline void add(int u, int v) {

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

	head[u] = hp;

	to[hp] = v;

}



void dfs(int u) {

	vis[u] = true;

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

		if(not vis[to[i]])

			dfs(to[i]);

		if(not win[to[i]])

			win[u] = true;

	}

}



int main() {

	int n = input();

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

		a[i] = input();

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

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

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

			add(u, v);

		else if(a[u] < a[v])

			add(v, u);

	}

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

		if(not vis[u])

			dfs(u);

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

		if(win[u])

			printf("%d ", u);

	puts("");

}
// Slower C++ solution:
#include <iostream>

#include <cstdlib>

#include <cstdio>

#define N 3011

using namespace std;

struct apple{

	int v,nxt;

}edge[N*4];

int indexx[N],tot,n,val[N];

void addedge(int x,int y){

	edge[++tot].v=y;

	edge[tot].nxt=indexx[x];

	indexx[x]=tot;

}

int dfs(int u,int fa){

	int t=indexx[u],vv,sum=val[u];

	while(t){

		vv=edge[t].v;

		if(vv!=fa){

			int k=dfs(vv,u);

			if(!k && val[vv]<val[u]) return 1;

		}

		t=edge[t].nxt;

	}

	return 0;

}

int main(){

	int x,y;

	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);

		addedge(x,y);

		addedge(y,x);

	}

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

		int k=dfs(i,0);

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

	}

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 5.1707536698998116x):
#if 0

#endif

#include <cstdio>

#include <algorithm>



inline int input() { int x; scanf("%d", &x); return x; }



const int maxn = 3030;

int head[maxn], nxt[maxn << 1], to[maxn << 1], hp;

bool vis[maxn], win[maxn];

int a[maxn];



inline void add(int u, int v) {

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

	head[u] = hp;

	to[hp] = v;

}



void dfs(int u) {

	vis[u] = true;

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

		if(not vis[to[i]])

			dfs(to[i]);

		if(not win[to[i]])

			win[u] = true;

	}

}



int main() {

	int n = input();

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

		a[i] = input();

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

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

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

			add(u, v);

		else if(a[u] < a[v])

			add(v, u);

	}

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

		if(not vis[u])

			dfs(u);

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

		if(win[u])

			printf("%d ", u);

	puts("");

}
// Slower C++ solution:
#include <bits/stdc++.h>



using namespace std;



typedef long long ll;

typedef pair<bool , bool> pii;

typedef pair<ll, ll> pll;



#define $ system("pause")

#define MOD ll(1e9 + 7)

#define MAXN 300010

#define inf (ll)1e18



template<typename T> inline T smin(T &a, const T &b) { return a > b ? a = b : a; }

template<typename T> inline T smax(T &a, const T &b) { return a < b ? a = b : a; }

inline void add(ll &l, const ll &r) { l = (l + r) % MOD; }

ll gcd(ll v, ll u) { return u ? gcd(u, v % u) : v; }

ll po(ll v, ll u) { return u ? (po(v * v % MOD, u >> 1) * (u & 1 ? v : 1) % MOD) : 1; }



/*

int n, arr[MAXN];

int have[MAXN][20];

int pl[MAXN][20], pr[MAXN][20];

vector<int> p[MAXN];



int main() {

	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

	for (int i = 2; i < MAXN; i++)

		if (p[i].empty()) {

			for (int j = i; j < MAXN; j += i)

				p[j].push_back(i);

		}



	cin >> n;

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

		cin >> arr[i];

		int local = arr[i];

		for (auto e : p[arr[i]]) {

			int cnt = 0;

			while ((local % e) == 0) {

				cnt++;

				local /= e;

			}

			have[e][cnt]++;

		}

	}

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

		pr[i][19] = have[i][19];

		for (int j = 18; j; j--) 

			pr[i][j] = pr[i][j + 1] + have[i][j];

		have[i][0] = n - pr[i][1];

		pr[i][0] = n;

		pl[i][0] = have[i][0];

		for (int j = 1; j < 20; j++)

			pl[i][j] = pl[i][j - 1] + have[i][j];



	}

	return 0;

}



*/



int n, arr[MAXN];

vector<int> adj[MAXN];



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

	bool res = false;

	for (auto e : adj[v]) {

		if (e ^ p && arr[e] < arr[v]) {

			res |= !dfs(e, v);

		}

	}

	return res;

}



int main() {

	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

	cin >> n;

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

		cin >> arr[i];

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

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

		adj[u].push_back(v);

		adj[v].push_back(u);

	}

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

		if (dfs(i))

			cout << i << ' ';

	}

	//$;

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 8.65216426153701x):
#include <bits/stdc++.h>

using namespace std;



const int N = 3e3 + 7;



vector <int> ad[N];

int a[N], n, ord[N];

bool w[N];



int main() {

	cin >> n;

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

		cin >> a[i], ord[i] = i;

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

		int v, u;

		cin >> v >> u;

		ad[v].push_back(u);

		ad[u].push_back(v);

	}

	sort (ord + 1, ord + n + 1, [](int v, int u) {

		return a[v] < a[u];		

	});

	vector <int> res;

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

		int v = ord[i];

		for (auto u: ad[v])

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

				continue;

			else

				w[v] |= 1 ^ w[u];

		if (w[v])

			res.push_back(v);

	}

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

	for (auto u: res)

		cout << u << " ";

	return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>



using namespace std;



typedef long long ll;

typedef pair<bool , bool> pii;

typedef pair<ll, ll> pll;



#define $ system("pause")

#define MOD ll(1e9 + 7)

#define MAXN 300010

#define inf (ll)1e18



template<typename T> inline T smin(T &a, const T &b) { return a > b ? a = b : a; }

template<typename T> inline T smax(T &a, const T &b) { return a < b ? a = b : a; }

inline void add(ll &l, const ll &r) { l = (l + r) % MOD; }

ll gcd(ll v, ll u) { return u ? gcd(u, v % u) : v; }

ll po(ll v, ll u) { return u ? (po(v * v % MOD, u >> 1) * (u & 1 ? v : 1) % MOD) : 1; }



/*

int n, arr[MAXN];

int have[MAXN][20];

int pl[MAXN][20], pr[MAXN][20];

vector<int> p[MAXN];



int main() {

	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

	for (int i = 2; i < MAXN; i++)

		if (p[i].empty()) {

			for (int j = i; j < MAXN; j += i)

				p[j].push_back(i);

		}



	cin >> n;

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

		cin >> arr[i];

		int local = arr[i];

		for (auto e : p[arr[i]]) {

			int cnt = 0;

			while ((local % e) == 0) {

				cnt++;

				local /= e;

			}

			have[e][cnt]++;

		}

	}

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

		pr[i][19] = have[i][19];

		for (int j = 18; j; j--) 

			pr[i][j] = pr[i][j + 1] + have[i][j];

		have[i][0] = n - pr[i][1];

		pr[i][0] = n;

		pl[i][0] = have[i][0];

		for (int j = 1; j < 20; j++)

			pl[i][j] = pl[i][j - 1] + have[i][j];



	}

	return 0;

}



*/



int n, arr[MAXN];

vector<int> adj[MAXN];



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

	bool res = false;

	for (auto e : adj[v]) {

		if (e ^ p && arr[e] < arr[v]) {

			res |= !dfs(e, v);

		}

	}

	return res;

}



int main() {

	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

	cin >> n;

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

		cin >> arr[i];

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

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

		adj[u].push_back(v);

		adj[v].push_back(u);

	}

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

		if (dfs(i))

			cout << i << ' ';

	}

	//$;

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 8.72277924769044x):
#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 << ' ';

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

typedef int ll;

typedef long long int li;

const ll MAXN=2e5+51;

struct Edge{

	ll to,prev;

};

Edge ed[MAXN];

ll n,tot,from,to;

ll last[MAXN],x[MAXN],dp[MAXN];

inline ll read()

{

    register ll num=0,neg=1;

    register char ch=getchar();

    while(!isdigit(ch)&&ch!='-')

    {

        ch=getchar();

    }

    if(ch=='-')

    {

        neg=-1;

        ch=getchar();

    }

    while(isdigit(ch))

    {

        num=(num<<3)+(num<<1)+(ch-'0');

        ch=getchar();

    }

    return num*neg;

}

inline void addEdge(ll from,ll to)

{

	ed[++tot].prev=last[from];

	ed[tot].to=to;

	last[from]=tot;

}

inline void dfs(ll node,ll fa)

{

	dp[node]=0;

	for(register int i=last[node];i;i=ed[i].prev)

	{

		if(ed[i].to!=fa)

		{

			dfs(ed[i].to,node);

			if(!dp[ed[i].to]&&x[node]>x[ed[i].to])

			{

				dp[node]=1;

			}

		}

	}

}

int main()

{

	n=read();

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

	{

		x[i]=read();

	}

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

	{

		from=read(),to=read();

		addEdge(from,to),addEdge(to,from);

	}

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

	{

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

		if(dp[i])

		{

			printf("%d ",i);

		}

	}

}

// Faster C++ solution for the same problem (measured speedup: 10.766376896507394x):
#include <cstdio>

typedef long long ll;

inline int rd(){

    int x=0,p=1;

    char a=getchar();

    while((a<48||a>57)&&a!='-')a=getchar();

    if(a=='-')p=-p,a=getchar();

    while(a>47&&a<58)x=(x<<1)+(x<<3)+(a&15),a=getchar();

    return x*p;

}

const int N=3002;

struct Edge{

	int to,next;

}edge[N<<1];

int head[N],cnt;

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

inline void add(int f,int t){

	edge[++cnt].next=head[f];

	edge[cnt].to=t;

	head[f]=cnt;

}

inline void dp(int u,int ft){

	f[u]=0;

	for(int i=head[u];i;i=edge[i].next){

		int v=edge[i].to;

		if(v==ft)continue;

		dp(v,u);

		if(f[v]==0&&a[u]>a[v])f[u]=1;

	}

}

int main(){

	n=rd();

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

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

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

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

	}

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

		dp(i,0);

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

	}

	puts("");

    return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

typedef int ll;

typedef long long int li;

const ll MAXN=2e5+51;

struct Edge{

	ll to,prev;

};

Edge ed[MAXN];

ll n,tot,from,to;

ll last[MAXN],x[MAXN],dp[MAXN];

inline ll read()

{

    register ll num=0,neg=1;

    register char ch=getchar();

    while(!isdigit(ch)&&ch!='-')

    {

        ch=getchar();

    }

    if(ch=='-')

    {

        neg=-1;

        ch=getchar();

    }

    while(isdigit(ch))

    {

        num=(num<<3)+(num<<1)+(ch-'0');

        ch=getchar();

    }

    return num*neg;

}

inline void addEdge(ll from,ll to)

{

	ed[++tot].prev=last[from];

	ed[tot].to=to;

	last[from]=tot;

}

inline void dfs(ll node,ll fa)

{

	dp[node]=0;

	for(register int i=last[node];i;i=ed[i].prev)

	{

		if(ed[i].to!=fa)

		{

			dfs(ed[i].to,node);

			if(!dp[ed[i].to]&&x[node]>x[ed[i].to])

			{

				dp[node]=1;

			}

		}

	}

}

int main()

{

	n=read();

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

	{

		x[i]=read();

	}

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

	{

		from=read(),to=read();

		addEdge(from,to),addEdge(to,from);

	}

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

	{

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

		if(dp[i])

		{

			printf("%d ",i);

		}

	}

}

// Faster C++ solution for the same problem (measured speedup: 2.0323071186211914x):
#include <iostream>

#include <stdio.h>



using namespace std;

const int N = 3005;

int n, tot, a[N], lnk[N], son[N << 1], nxt[N << 1]; bool win[N];

void add(int x, int y) {

    nxt[++tot] = lnk[x];

    lnk[x] = tot;

    son[tot] = y;

    

}

void dfs(int x, int p) {

       win[x] = 0;

       for (int j = lnk[x]; j; j = nxt[j]) {

                 if (son[j] == p) continue;

                if (a[x] > a[son[j]]) {

                         dfs(son[j], x);

                         if (!win[son[j]]) win[x] = 1;

            

        }

        

    }

    

}

 int main() {

     while (cin >> n) {

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

             std::cin >> a[i];

         }

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

             cin >> x >> y;

             add(x, y);

             add(y, x);

         }

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

             dfs(i, 0);

             if (win[i]) cout << i << " ";

         }

     }

     return 0;

}
// Slower C++ solution:
#include<iostream>

#include<cstdio>

#include<algorithm>

#include<cmath>

//#define int long long

using namespace std;

const int maxn=5e5+1000;

typedef long long ll;

int n,m;

const int mod=998244353;

int fr[maxn],ans;

inline int ksm(int num,int t){

	int res=1;

	for(;t;t>>=1,num=1ll*num*num%mod){

		if(t&1)res=1ll*res*num%mod;

	}

	return res;

}

inline int c(int m,int n){

	return 1ll*fr[n]*ksm((1ll*fr[m]*fr[n-m])%mod,mod-2)%mod;	

}

int main(){

	ios::sync_with_stdio(0);

	cin>>n>>m;

	fr[0]=fr[1]=1;

	for(int i=2;i<maxn;i++)fr[i]=1ll*fr[i-1]*i%mod;	

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

		ans=(ans+1ll*ksm(-1,i)*(1ll*c(i,n)*c(i,m)%mod*fr[i]%mod*ksm(m+1,n-i)%mod*ksm(n+1,m-i)%mod)%mod)%mod;	

	}

	ans=(ans%mod+mod)%mod;

	cout<<ans;

	return 0;

}//

// Faster C++ solution for the same problem (measured speedup: 3.8009702338828655x):
#include <iostream>

#include <cstdio>

using namespace std;

#define N 500005

#define mod 998244353

#define ll long long

ll Pow(ll a, ll b)

{

	ll ans = 1;

	while (b)

	{

		if (b & 1)

			ans = ans * a % mod;

		a = a * a % mod;

		b >>= 1;

	}

	return ans;

}

int n, m, ans;

int fac[N], inv[N];

void Init(int n)

{

	fac[0] = 1;

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

		fac[i] = 1ll * fac[i - 1] * i % mod;

	inv[n] = Pow(fac[n], mod - 2);

	for (int i = n - 1; i >= 0; i--)

		inv[i] = 1ll * inv[i + 1] * (i + 1) % mod;

}

int C(int n, int m)

{

	if (n < 0 || m < 0 || m > n)

		return 0;

	return 1ll * fac[n] * inv[m] % mod * inv[n - m] % mod;

}

int main()

{

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

	if (n < m) swap(n, m);

	Init(n);

	for (int k = 0; k <= m; ++k)

	{

		ans += 1ll * Pow(-1, k) * C(n, k) % mod * C(m, k) % mod * fac[k] % mod * Pow(m + 1, n - k) % mod * Pow(n + 1, m - k) % mod;

		ans = (ans % mod + mod) % mod;

	}

	printf("%d\n", ans);

}
// Slower C++ solution:
#include<iostream>

#include<cstdio>

#include<algorithm>

#include<cmath>

//#define int long long

using namespace std;

const int maxn=5e5+1000;

typedef long long ll;

int n,m;

const int mod=998244353;

int fr[maxn],ans;

inline int ksm(int num,int t){

	int res=1;

	for(;t;t>>=1,num=1ll*num*num%mod){

		if(t&1)res=1ll*res*num%mod;

	}

	return res;

}

inline int c(int m,int n){

	return 1ll*fr[n]*ksm((1ll*fr[m]*fr[n-m])%mod,mod-2)%mod;	

}

int main(){

	ios::sync_with_stdio(0);

	cin>>n>>m;

	fr[0]=fr[1]=1;

	for(int i=2;i<maxn;i++)fr[i]=1ll*fr[i-1]*i%mod;	

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

		ans=(ans+1ll*ksm(-1,i)*(1ll*c(i,n)*c(i,m)%mod*fr[i]%mod*ksm(m+1,n-i)%mod*ksm(n+1,m-i)%mod)%mod)%mod;	

	}

	ans=(ans%mod+mod)%mod;

	cout<<ans;

	return 0;

}//

// Faster C++ solution for the same problem (measured speedup: 3.8094086446681357x):
#include <cstdio>

#include <iostream>

using namespace std;

const int N = 1e7 + 10, mod = 998244353;

int fac[N], inv[N], n, ans, m;

int qpow(int a, int b) {

    int c = 1;

    while(b) {

        if(b & 1) c = 1ll * c * a % mod;

        a = 1ll * a * a % mod;

        b >>= 1;

    } return c;

}

int C(int x, int y) {

    if(x < y) return 0;

    return 1ll * fac[x] * inv[y] % mod * inv[x - y] % mod;

}

int main() {

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

    if(n > m) swap(n, m);

    fac[0] = 1;

    for(int i = 1; i <= m; ++i) fac[i] = 1ll * fac[i - 1] * i % mod;

    inv[m] = qpow(fac[m], mod - 2);

    for(int i = m; i >= 1; --i) inv[i - 1] = 1ll * inv[i] * i % mod;

    for(int i = 0, o = 1; i <= n; ++i, o = mod - o)

        ans += 1ll * C(n, i) * C(m, i) % mod * fac[i] % mod * qpow(m + 1, n - i) % mod * qpow(n + 1, m - i) % mod * o % mod,

        ans %= mod;

    printf("%d\n", ans);

    return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

#define ll long long

using namespace std;

ll n,m,jc[1000010],ny[1000100],ans,p=998244353;

ll C(ll x,ll y){

	return jc[x]*ny[y]%p*ny[x-y]%p;

}

ll ksm(ll x,ll y){

	ll xlh=1;

	while(y){

		if(y&1)xlh=xlh*x%p;

		x=x*x%p;

		y/=2;

	}

	return xlh;

}

int main(){

	ll i,xlh;

	scanf("%lld%lld",&n,&m);

	if(n>m)swap(n,m);

	jc[0]=ny[0]=1;

	for(i=1;i<=m;i++)jc[i]=jc[i-1]*i%p,ny[i]=ksm(jc[i],p-2);

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

		xlh=C(n,i)*C(m,i)%p*jc[i]%p*ksm(n+1,m-i)%p*ksm(m+1,n-i)%p;

		if(i%2)ans=(ans-xlh+p)%p;

		 else ans=(ans+xlh)%p;

	}

	printf("%lld",ans);

}

/*

仔细想想不难，但感觉这种容斥确实非常奇怪。 

*/

// Faster C++ solution for the same problem (measured speedup: 1.232692850650927x):
#include<bits/stdc++.h>

#define ll long long

using namespace std;

const ll p=998244353;

ll n,m,ans,jc[1000010],ny[1000010];

ll ksm(ll x,ll y){

	ll xlh=1;

	while(y){

		if(y&1)xlh=xlh*x%p;

		x=x*x%p;

		y/=2;

	}

	return xlh;

}

ll C(ll x,ll y){

	return jc[x]*ny[y]%p*ny[x-y]%p;

}

int main(){

	ll i,op;

	scanf("%lld%lld",&n,&m);

	jc[0]=ny[0]=1;

	for(i=1;i<=max(n,m);i++)jc[i]=jc[i-1]*i%p,ny[i]=ksm(jc[i],p-2)%p;

	for(i=0;i<=min(n,m);i++){

		if(i%2)op=-1;

		 else op=1;

		ans=(ans+op*C(n,i)%p*C(m,i)%p*jc[i]%p*ksm(n+1,m-i)%p*ksm(m+1,n-i)%p+p)%p;

	}

	printf("%lld",ans);

}