#include <bits/stdc++.h>
#define int long long
#define fi first
#define se second
#define sz(a) (int)((a).size())
#define all(a) (a).begin(), (a).end()
#define lsb(x) (x & (-x))
#define vi vector<int>
#define YES { cout << "YES" << endl; return; }
#define NO { cout << "NO" << endl; return; }
using ll = long long;
using pii = std::pair<int, int>;
const int NMAX = 1e5;
using namespace std;
vector<int> T[NMAX + 5];
int dp[NMAX + 5][2][2], a[NMAX + 5], mn[NMAX + 5], n;
void dfs(int nod ,int p = -1) {
vector<int> sons;
for (auto &son : T[nod]) {
if (son == p) continue;
dfs(son, nod);
sons.push_back(son);
}
dp[nod][0][0] = dp[nod][0][1] = dp[nod][1][0] = dp[nod][1][1] = INT_MAX;
if (sons.empty()) {
dp[nod][a[nod]][0] = 0;
dp[nod][(a[nod] ^ 1)][1] = 1;
return;
}
for (int use = 0; use < 2; ++use) {
///a[nod] ^ use_son = v
///val_son = use
vector<int> dif;
int offset = use;
for (auto &son : sons) {
offset += dp[son][use][0];
dif.push_back(dp[son][use][1] - dp[son][use][0]);
}
dp[nod][(a[nod] ^ use)][use] = offset;
sort(all(dif));
for (int i = 0, v = (a[nod] ^ use); i < sz(dif); ++i) {
v ^= 1;
offset += dif[i];
dp[nod][v][use] = min(dp[nod][v][use], offset);
}
}
}
signed main() {
cin.tie(nullptr)->sync_with_stdio(false);
cin >> n;
for (int i = 0, u, v; i < n - 1; ++i) {
cin >> u >> v;
T[u].push_back(v);
T[v].push_back(u);
}
for (int i = 1; i <= n; ++i)
cin >> a[i];
dfs(1);
int ans = min(dp[1][0][1], dp[1][0][0]);
if (ans == INT_MAX) {
cout << "impossible\n";
exit(0);
}
cout << ans << '\n';
return 0;
}
/*
dp[u][val][used] - numarul minim astfel incat
tot subarborele lui u este rezolvat pe nodul u se afla valoarea val
si used reprezinta daca am folosit operatia pe nodul u
*/