#include <bits/stdc++.h>
using namespace std;
long long int power(long long int x, long long int y) {
  long long int res = 1;
  while (y > 0) {
    if (y & 1) res = (res * x) % 1000000007;
    y = y >> 1;
    x = (x * x) % 1000000007;
  }
  if (res < 0) res += 1000000007;
  return res;
}
long long int modInverse(long long int a, long long int m) {
  long long int m0 = m;
  long long int y = 0, x = 1;
  if (m == 1) return 0;
  while (a > 1) {
    long long int q = a / m;
    long long int t = m;
    m = a % m, a = t;
    t = y;
    y = x - q * y;
    x = t;
  }
  if (x < 0) x += m0;
  return x;
}
int intersectiontype1(int l, int r, int ll, int rr) {
  if (r < ll || rr < l) return 0;
  return 1;
}
struct node {
  int l, r, lazy = 0, lazyval = 0;
  int max = -1000000000, sum = 0;
};
void cst(int l, int r, int k, std::vector<node> &st, std::vector<int> &h) {
  st[k].l = l, st[k].r = r;
  if (l == r) {
    st[k].sum = h[l];
    st[k].max = h[l];
    return;
  }
  cst(l, (l + r) / 2, 2 * k + 1, st, h);
  cst((l + r) / 2 + 1, r, 2 * k + 2, st, h);
  st[k].max = max(st[2 * k + 1].max, st[2 * k + 2].max);
  st[k].sum = st[2 * k + 1].sum + st[2 * k + 2].sum;
}
void shift(int k, std::vector<node> &st) {
  st[k].max = st[k].lazyval;
  st[k].sum += (st[k].r - st[k].l + 1) * st[k].lazyval;
  st[2 * k + 1].lazyval += st[k].lazyval;
  st[2 * k + 2].lazyval += st[k].lazyval;
  st[2 * k + 1].lazy = st[2 * k + 1].lazy = 1;
  st[2 * k + 2].lazy = st[2 * k + 2].lazy = 1;
  st[k].lazyval = 0;
  st[k].lazy = 0;
}
long long int query(int l, int r, int k, std::vector<node> &st) {
  if (st[k].lazy != 0) shift(k, st);
  int ll = st[k].l, rr = st[k].r, mid = (ll + rr) / 2;
  if (ll >= l && rr <= r) return st[k].sum;
  long long int ans = 0;
  if (intersectiontype1(ll, mid, l, r) == 1) ans = query(l, r, 2 * k + 1, st);
  if (intersectiontype1(1 + mid, rr, l, r) == 1)
    ans += query(l, r, 2 * k + 2, st);
  return ans;
}
void update(int l, int r, int x, int k, std::vector<node> &st) {
  if (l > r) return;
  int ll = st[k].l, rr = st[k].r, mid = (ll + rr) / 2;
  if (ll >= l && rr <= r) {
    st[k].lazyval += x;
    st[k].lazy = 1;
    return;
  }
  if (st[k].lazy != 0) shift(k, st);
  if (intersectiontype1(ll, mid, l, r) == 1) update(l, r, x, 2 * k + 1, st);
  if (intersectiontype1(mid + 1, rr, l, r) == 1) update(l, r, x, 2 * k + 2, st);
  if (st[2 * k + 1].lazy != 0) shift(2 * k + 1, st);
  if (st[2 * k + 2].lazy != 0) shift(2 * k + 2, st);
  st[k].max = max(st[2 * k + 1].max, st[2 * k + 2].max);
  st[k].sum = st[2 * k + 1].sum + st[2 * k + 2].sum;
}
struct tree_node {
  vector<int> adj;
  int goal, init, dist;
};
vector<int> init(100001, 0), ansv;
vector<node> stodd(800008), steven(800008);
void set_dist(int u, int p, vector<tree_node> &tree) {
  for (auto x : tree[u].adj) {
    if (x == p) continue;
    tree[x].dist = 1 + tree[u].dist;
    set_dist(x, u, tree);
  }
}
int solve(int u, int p, vector<tree_node> &tree) {
  int ans = 0, flag = 1;
  int halfdist = tree[u].dist / 2;
  if (tree[u].dist % 2 == 0) {
    tree[u].init = (tree[u].init + query(halfdist, halfdist, 0, steven)) % 2;
    tree[u].init = (tree[u].init + 2) % 2;
  } else {
    tree[u].init = (tree[u].init + query(halfdist, halfdist, 0, stodd)) % 2;
    tree[u].init = (tree[u].init + 2) % 2;
  }
  if (tree[u].init != tree[u].goal) {
    ans++;
    if (tree[u].dist % 2 == 0)
      update(halfdist, 100000, 1, 0, steven);
    else
      update(halfdist, 100000, 1, 0, stodd);
    ansv.push_back(u);
    flag = 0;
  }
  for (auto x : tree[u].adj) {
    if (x == p) continue;
    ans += solve(x, u, tree);
  }
  if (flag == 0) {
    if (tree[u].dist % 2 == 0)
      update(halfdist, 100000, -1, 0, steven);
    else
      update(halfdist, 100000, -1, 0, stodd);
  }
  return ans;
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cst(0, 100000, 0, stodd, init), cst(0, 100000, 0, steven, init);
  int n;
  cin >> n;
  vector<tree_node> tree(n + 1);
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    cin >> u >> v;
    tree[u].adj.push_back(v);
    tree[v].adj.push_back(u);
  }
  for (int i = 1; i < n + 1; i++) cin >> tree[i].init;
  for (int i = 1; i < n + 1; i++) cin >> tree[i].goal;
  set_dist(1, 0, tree);
  cout << solve(1, 0, tree) << "\n";
  for (int i = 0; i < ansv.size(); i++) cout << ansv[i] << "\n";
  return 0;
}
