#include "bits/stdc++.h"
using namespace std;

typedef long long ll;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<long long> VL;
typedef vector<vector<long long>> VVL;
typedef pair<int,int> Pair;
typedef tuple<int,int,int> tpl;

#define ALL(a)  (a).begin(),(a).end()
#define SORT(c) sort((c).begin(),(c).end())
#define REVERSE(c) reverse((c).begin(),(c).end())
#define EXIST(m,v) (m).find((v)) != (m).end()
#define LB(a,x) lower_bound((a).begin(), (a).end(), x) - (a).begin()
#define UB(a,x) upper_bound((a).begin(), (a).end(), x) - (a).begin()

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)
#define RFOR(i,a,b) for(int i=(a)-1;i>=(b);--i)
#define RREP(i,n) RFOR(i,n,0)

#define en "\n"

constexpr double EPS = 1e-9;
constexpr double PI  = 3.1415926535897932;
constexpr int INF = 2147483647;
constexpr long long LINF = 1LL<<60;
constexpr long long MOD = 1000000007; // 998244353;

template<class T> inline bool chmax(T& a, T b){if(a<b){a=b;return true;}return false;}
template<class T> inline bool chmin(T& a, T b){if(a>b){a=b;return true;}return false;}

VI exist(100100,0),vis,C,ans;
VVI edge;

void dfs(int v){
    vis[v] = 1;
    bool flag = false;
    if(exist[C[v]] == 0){
        flag = true;
        exist[C[v]] = 1;
        ans.push_back(v+1);
    }

    for(int to : edge[v]){
        if(vis[to]) continue;
        dfs(to);
    }
    if(flag) exist[C[v]] = 0;
    return;
}

void Main(){
    int N; cin >> N;
    C.resize(N); vis.resize(N,0); edge.resize(N);
    REP(i,N) cin >> C[i], C[i]--;
    REP(_,N-1){
        int a,b; cin >> a >> b; a--; b--;
        edge[a].push_back(b); edge[b].push_back(a);
    }

    dfs(0);

    SORT(ans);
    for(int x : ans) cout << x << en;
    return;
}

int main(void){
    cin.tie(0);cout.tie(0);ios_base::sync_with_stdio(0);cout<<fixed<<setprecision(15);
    int t=1; //cin>>t;
    while(t--) Main();
    return 0;
}
// MOHIT KUMAR
#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef complex<ld> cd;

typedef pair<int, int> pin;
typedef pair<ll, ll> pl;
typedef pair<ld, ld> pd;

#define ff(i, a, b) for ( ll i=a; i<(b); i++)
#define ffd(i, a, b) for ( ll i=a; i<= b; i++)
#define fr(i, a, b) for ( ll i = (b)-1; i >= a; i--)
#define ffr(i, a, b) for ( ll i = b ; i >= a; i--)
#define vl vector < ll >
#define vp vector < pl >
#define endl "\n"
#define sz(x) (ll)(x).size()
#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()

const ld pi = acos(-1) ;
const ll maxn = 3e5 + 5 ;
const int mod = 998244353 ;
const ll INF = 1e18 ;
const int MX = 2000000001 ; // check the limits, dummy

vl lps(maxn, 0) ; // longest prefix array which is also a suffix

void KMP( string s) {
  ll l = 0, r = 1 ;
  while (r < s.size()) {
    if (s[l] == s[r]) {
      lps[r++] = ++l ;
    }
    else {
      l = 0 ;
      lps[r++] = 0;
    }
  }
  ff(i, 0, sz(s)) cout << lps[i] << " " ;
}

void find_sub(string s, string t) {
  ll i = 0, j = 0, ans = 0  ;
  bool ch = false ;
  while (i < s.size()) {
    if (s[i] == t[j]) {
      j++ ;
      i++ ;
      if (j == t.size()) {
        ans++ ;
        cout << "Substring found at " << i - j << " index" << endl ;
        // return true ;
        j = lps[j - 1] ;
        ch = true ;
      }
    }
    else {
      if (j) j = lps[j - 1] ;
      else i++ ;
    }
  }
  if (!ch) cout << "Substring not found\n" ;
  cout << "NUMBER OD OCC" << ans << endl ;
  // return false ;
}

ll max_gold_mine() {
  ll v[3][1] = {{1}, {2}, {3}};
  ll m = 3, n = 1 ;
  ll ans = 0 ;
  for ( int j = n - 2; j >= 0; j--) {
    for ( int i = 0; i <  m; i++) {
      if (!i) v[i][j] += max(v[i][j + 1], v[i + 1][j + 1]) ;
      else if (i == m - 1)v[i][j] += max(v[i][j + 1], v[i - 1][j + 1]) ;
      else v[i][j] += max({v[i + 1][j + 1], v[i - 1][j + 1], v[i][j + 1]}) ;
    }
  }
  for ( int i = 0; i < m; i++) ans = max(ans, v[i][0]) ;
  return ans ;
}

int optimal_merge( vector < int > v) {
  int ans = 0 ;
  priority_queue < int , vector < int > , greater < int >> pq;
  for (auto x : v) pq.push(x) ;
  while (pq.size() != 1) {
    int a = pq.top() ;
    pq.pop() ;
    int b = pq.top() ;
    pq.pop() ;
    ans += a + b ;
    pq.push(a + b) ;
  }
  return ans ;
}

// void dfs( ll u) {
//   vis[u] = 1 ;
//   for (auto x : adj[u]) {
//     if (!vis[x]) dfs(x) ;
//   }
//   top.pb(u) ;
// }
// void topo_sort(vl adj[], ll n) {
//   ffr(i, 1, n) {
//     if (!vis[i]) dfs(i) ;
//   }
//   reverse(all(top)) ;
//   cout << "TOPOLOGICAL SORTING OF GRAPH IS\n " ;
//   for (auto x : top) cout << x  << " ";
// }

// vl v[maxn] ;
// vector <double > prob(maxn, 0) ;

// void dfs (ll n, ll par) {
//   ll res = sz(v[n]) ;
//   if (par != -1) --res ;
//   for (auto x : v[n]) {
//     if ( x != par ) {
//       prob[x] = prob[n] / res ;
//       dfs(x, n) ;
//     }
//   }
// }

vl v[maxn], val(maxn, 0) ;
bool vis[maxn] = {0} ;
ll csum = 0 ;

void dfs(ll n ) {
  vis[n] = 1 ;
  csum += val[n] ;
  for (auto x : v[n]) {
    if (!vis[x]) dfs(x) ;
  }
}

int main() {
  ios_base::sync_with_stdio(0) , cin.tie(0);
  ll t, q, n, a, b, c, d, k, l, m, r,  x = 0, y = 0, z = 0 , sum = 0, ans = 0, temp = 0, res = 0 ;
  cin >> n >> m ;
  ff(i, 0, n) {
    cin >> val[i] ;
  }
  ff(i, 0, n) {
    cin >> x ;
    val[i] -= x ;
  }
  ff(i, 0, m) {
    cin >> a >> b ;
    a--, b-- ;
    v[a].pb(b) ;
    v[b].pb(a) ;
  }
  ff(i, 0, n) {
    if (!vis[i])
      dfs(i) ;
    if (csum) {
      cout << "No\n" ;
      return 0 ;
    }
  }
  cout << "Yes\n" ;
}
