//#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <vector>
#include <cassert>
#include <fstream>
#include <algorithm>
#include <list>
#include <random>
#include <ctime>
#include <cmath>
#include <random>
#include <bitset>
#include <complex>

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
//#define int ll
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector< vi > vvi;
typedef vector< vvi > vvvi;
typedef vector<short> vs;
typedef vector<vs> vvs;
typedef vector<vvs> vvvs;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<vvl> vvvl;
typedef pair<ld, ld> pld;
typedef complex<double> base;

#define mmin(a, b) a = min(a, (b))
#define mmax(a, b) a = max(a, (b))
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define ALL(a) a.begin(),a.end()
#define sqr(x) (x) * (x)
#define fori(i, n) for(int i = 0; i < int(n); ++i)
#define cint const int & 
#define SZ(a) ((int)(a.size()))
#define watch(x) cout << (#x) << " = " << x << endl;

const double PI = 2 * acos(0.0);

template<class T>
void show(const vector<T> &a) {
	for (T x : a)
		cout << x << " ";
	cout << endl;
}

const int N = 1e5 + 9;
const int oo = 1e9;
bool black[N];
/// input begin
vi g[N];
string s;
int n;
/// input end
int solve();
int naive();
void gen();

int dp[2][N]; // 0 stay in subtree, 1 go away from subtree
int dp_up[2][N];
int total[N];
int total_up[N];

void dfs1(int v, int par) {// come from up
	bool kek = !black[v];
	// stop in vertice
	dp[0][v] = 1;
	for (int to : g[v]) if (to != par && !total[to]) {
		dfs1(to, v);
		dp[0][v] += dp[1][to];
		kek ^= 1;
	}
	dp[0][v] += !kek;

	// go in father
	dp[1][v] = dp[0][v] + 1;

	// go in child
	int sum = dp[0][v] - !kek;

	for (int to : g[v]) if (to != par && !total[to]) {
		kek ^= 1;
		sum += dp[0][to] - dp[1][to];
		mmin(dp[0][v], sum + !kek);
		sum -= dp[0][to] - dp[1][to];
		kek ^= 1;
	}
}
int ans;
void dfs2(int v, int par, pii up) {
	vector<pii> kek;
	/*watch(up.first);
	watch(up.second);*/
	if (!total_up[v]) kek.pb(up);
	for (int to : g[v]) if (to != par && !total[to]) kek.pb(mp(dp[0][to], dp[1][to]));
	int sum = 0;
	bool odd = black[v];
	for (auto x : kek) {
		sum += x.second;
		odd ^= 1;
	}
	mmin(ans, sum + !odd);
	for (auto x : kek) {
		odd ^= 1;
		sum += x.first - x.second;
		mmin(ans, sum + !odd);
		sum -= x.first - x.second;
		odd ^= 1;
	}
	/*watch(v);
	watch(ans);*/
	sum = 1;
	odd = !black[v];
	set<pii> kek_set;
	if (!total_up[v]) {
		odd ^= 1;
		sum += up.second;
		kek_set.insert(mp(up.first - up.second, -1));
	}
	for (int to : g[v]) if (to != par && !total[to]) {
		odd ^= 1;
		sum += dp[1][to];
		kek_set.insert(mp(dp[0][to] - dp[1][to], to));
	}
	for (int to : g[v]) if (to != par) {
		int old = sum;
		bool old_odd = odd;
		pii p = { oo, oo };
		if (total[to]) {
			p = { sum + !odd, sum + !odd + 1};
			if (!kek_set.empty()) {
				odd ^= 1;
				sum += !odd + (*kek_set.begin()).first;
				mmin(p.first, sum);
			}
		}
		else {
			kek_set.erase(mp(dp[0][to] - dp[1][to], to));
			p = { odd + sum - dp[1][to], sum - dp[1][to] + odd + 1 };
			if (!kek_set.empty()) {
				sum += !odd + (*kek_set.begin()).first;
				mmin(p.first, sum - dp[1][to]);
			}
			kek_set.insert(mp(dp[0][to] - dp[1][to], to));
		}
		odd = old_odd;
		sum = old;
		dfs2(to, v, p);
	}
}
void pre_dfs1(int v, int par) {
	total[v] = black[v];
	for (int to : g[v]) if (to != par) {
		pre_dfs1(to, v);
		total[v] &= total[to];
	}
}

void pre_dfs2(int v, int par) {
	total_up[v] = 1;
	if (!black[v]) return;
	int cnt = 0;
	for (int to : g[v]) if (to != par)
		cnt += !total[to];
	if (!cnt) for (int to : g[v]) if (to != par)
		pre_dfs2(to, v);
	if (cnt == 1) for (int to : g[v]) if (to != par && !total[to])
		pre_dfs2(to, v);
}

int naive() {
	if (total[1]) return 0;
	int ret = oo;
	for (int v = 1; v <= n; ++v) {
		black[v] ^= 1;
		pre_dfs1(v, -1);
		dfs1(v, -1);
		//cout << "ans[" << v << "] = " << dp[0][v] - 1 << endl;
		mmin(ret, dp[0][v] - 1);
		black[v] ^= 1;
	}
	return ret;
}

void stress() {
	int cnt = 0;
	while (1) {
		if (++cnt % 20 == 0) watch(cnt);
		gen();
		fill(total_up, total_up + n + 1, 0);
		int sl = solve();
		//watch(sl);
		int nv = naive();
		//watch(nv);
		if (sl != nv) {
			watch(sl);
			watch(nv);
			cout << "TEST: " << endl;
			cout << n << endl;
			for (int i = 1; i <= n; ++i) {
				cout << i << " : ";
				for (int to : g[i]) cout << to << " ";
				cout << endl;	
			}
			cout << s << endl;
			assert(0);
		}
	}
}

int solve() {
	bool total = 1;
fori(i, n) {
		black[i + 1] = s[i] == 'B';
		total &= s[i] == 'B';
	}
	if (total) 
		return 0;
	ans = oo;
	pre_dfs1(1, -1);
	pre_dfs2(1, -1);
	total_up[1] = 1;
	dfs1(1, -1);
	dfs2(1, -1, mp(-oo, +oo));
	return ans;
}

void gen() {
	const int L = 40;
	n = 1 + rand() % L;
	for (int i = 1; i <= n; ++i) g[i].clear();
	for (int i = 2; i <= n; ++i) {
		int par = rand() % (i - 1) + 1;
		g[par].pb(i);
		g[i].pb(par);
	}
	s.clear();
	fori(i, n)
		s += (rand() & 1) ? 'W' : 'B';
}

void input() {
	cin >> n;
	fori(iter, n - 1) {
		int u, v;
		cin >> u >> v;
		g[u].pb(v);
		g[v].pb(u);
	}
	cin >> s;
}
/*
7
1 2
1 3 
1 4
2 5
2 7
3 6
WWWWWWB

*/
signed main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	input();
	cout << solve() << endl;
	//cout << naive() << endl;
	return 0;
	srand(time(0));
	stress();
}

Measured memory_bytes: 39120