#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <string>
#include <set>
#include <map>

using namespace std;

#define fastInp cin.tie(0); cout.tie(0); ios_base::sync_with_stdio(0);

typedef long long ll;
typedef long double ld;

const ll SZ = 1e5 + 100, INF = 1e9 * 1e9;
ll n, ans = 0;
vector<vector<ll>> gr, tree;
vector<pair<ll, ll>> edges;
bool used[SZ], good[SZ];
ll dp[SZ][2], svdp[SZ][2];
string s;

void reft(int v) {
	used[v] = 1;
	ll c1 = 0, c2 = 0;
	for (auto to : gr[v]) {
		if (!used[to]) {
			c1++;
			reft(to);
			if (!good[to]) c2++;
		}
	}

	if (gr[v].size() == 1 && s[v] == 'B') {
		good[v] = 0;
	}
	if (c1 == c2 && s[v] == 'B') {
		good[v] = 0;
	}
}

char nt(char a) {
	if (a == 'B') return 'W';
	return 'B';
}

void dfs(int v, int par = -1) {
	used[v] = 1;

	bool fl = false;
	for (auto to : tree[v]) {
		if (!used[to]) {
			fl = true;
			dfs(to, v);
		}
	}

	if (!fl) {
		dp[v][0] = 0;
		dp[v][1] = 0;
	}
	else {
		ll sm = 0, sz = 0;
		for (auto to : tree[v]) {
			if (to != par) {
				sm += dp[to][0];
				sz += 2;
			}
		}
		ll x = (1 * (par != -1)) + sz / 2;
		x %= 2;
		char cur = s[v];
		if (x == 1) {
			cur = nt(cur);
		}
		dp[v][0] = sm + sz + (cur == 'W');

		dp[v][1] = INF;
		for (auto to : tree[v]) {
			if (to != par) dp[v][1] = min(dp[v][1], (sm - dp[to][0] + dp[to][1]) + sz - 1 + (cur == 'B'));
		}
	}
}

ll vl = INF;

void reroot(int v) {
	ll sm = 0, sz = 0;
	for (auto to : tree[v]) {
		sm += dp[to][0];
		sz += 2;
	}
	ll x = sz / 2;
	x %= 2;
	char cur = s[v];
	if (x == 1) {
		cur = nt(cur);
	}
	dp[v][0] = sm + sz + (cur == 'W');

	dp[v][1] = INF;
	for (auto to : tree[v]) {
		dp[v][1] = min(dp[v][1], (sm - dp[to][0] + dp[to][1]) + sz - 1 + (cur == 'B'));
	}

	used[v] = 1;

	vl = min(vl, min(dp[v][0], dp[v][1]));

	sm = 0, sz = 0;
	for (auto to : tree[v]) {
		sm += dp[to][0];
		sz += 2;
	}

	sz -= 2;
	x = (sz) / 2;
	x %= 2;
	cur = s[v];
	if (x == 0) {
		cur = nt(cur);
	}
	dp[v][0] = sm + sz + (cur == 'W');

	vector<pair<ll, ll>> vals;
	for (auto to : tree[v]) {
		vals.push_back({ (sm - dp[to][0] + dp[to][1]) + sz - 1 + (cur == 'B'), to });
	}

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

	for (auto to : tree[v]) {
		if (!used[to]) {
			pair<ll, ll> pr = { dp[v][0], dp[v][1] };
			pair<ll, ll> pr2 = { dp[to][0], dp[to][1] };

			sm -= dp[to][0];
			dp[v][0] = sm + sz + (cur == 'W');
			sm += dp[to][0];
			if (vals.size() == 1) {
				dp[v][1] = 0;
			}
			else {
				if (vals[0].second == to) {
					dp[v][1] = vals[1].first - dp[to][0];
				}
				else {
					dp[v][1] = vals[0].first - dp[to][0];
				}
			}
			reroot(to);

			dp[v][0] = pr.first;
			dp[v][1] = pr.second;

			dp[to][0] = pr2.first;
			dp[to][1] = pr2.second;
		}
	}
}

ll sol() {
	vl = INF;

	for (int i = n - 1; i >= 0; i--) {
		if (!good[i]) continue;
		for (int j = 0; j < n; j++) used[j] = 0;
		dfs(i);
		for (int j = 0; j < n; j++) used[j] = 0;
		reroot(i);
		break;
	}

	return vl;
}

ll stresses() {
	ll ans = INF;

	for (int i = n - 1; i >= 0; i--) {
		for (int j = 0; j < n; j++) used[j] = 0;
		if (!good[i]) continue;
		dfs(i);
		ans = min(ans, dp[i][0]);
		ans = min(ans, dp[i][1]);
		svdp[i][0] = dp[i][0];
		svdp[i][1] = dp[i][1];
	}

	return ans;
}

int main() {
	fastInp;

	cin >> n;
	gr.resize(n);

	good[0] = 1;
	for (int i = 0; i < n; i++) good[i] = 1;
	for (int i = 0; i < n - 1; i++) {
		good[i] = 1;
		good[i + 1] = 1;
		ll u, v;
		cin >> u >> v;
		u--; v--;
		edges.push_back({ u, v });
		gr[u].push_back(v);
		gr[v].push_back(u);
	}

	cin >> s;
	bool fl = true;
	for (int i = 0; i < s.size(); i++) {
		if (s[i] != 'B') fl = false;
	}

	if (fl) {
		cout << 0;
		return 0;
	}

	

	for (int i = 0; i < n; i++) {
		if (s[i] == 'W') {
			reft(i);
			break;
		}
	}

	tree.resize(n);
	for (int i = 0; i < edges.size(); i++) {
		ll u = edges[i].first, v = edges[i].second;
		if (good[u] && good[v]) {
			tree[u].push_back(v);
			tree[v].push_back(u);
		}
	}


	cout << sol();

	return 0;
}

Measured memory_bytes: 36480