#pragma GCC optimize ("O3")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
using namespace std;

//#include <ext/pb_ds/tree_policy.hpp>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/rope>
//using namespace __gnu_pbds;
//using namespace __gnu_cxx;
//
//template<class T> using Tree = tree<T, null_type, less<T>, rb_t_tag,t_order_statistics_node_update>;
/***********************************************/
/* Dear online judge:
 * I've read the problem, and tried to solve it.
 * Even if you don't accept my solution, you should respect my effort.
 * I hope my code compiles and gets accepted.
 *  ___  __     _______    _______      
 * |\  \|\  \  |\  ___ \  |\  ___ \     
 * \ \  \/  /|_\ \   __/| \ \   __/|    
 *  \ \   ___  \\ \  \_|/__\ \  \_|/__  
 *   \ \  \\ \  \\ \  \_|\ \\ \  \_|\ \ 
 *    \ \__\\ \__\\ \_______\\ \_______\
 *     \|__| \|__| \|_______| \|_______|
 */
const long long mod = 1000000007;
//const long long mod = 998244353;

// watch this
//using ll = long long;
//typedef long long LL;
#define ll long long
#undef ll

const int mxN = 100010;

int dp[mxN][3];

bool is_ex[mxN];
int deg[mxN];
vector<int> g[mxN];
string s;
int N;

void clear() {
	set<pair<int, int> > dg;
	for (int i = 1; i <= N; i++)
		if (s[i] == 'B')
			dg.insert( { deg[i], i });
	while (!dg.empty() && dg.begin()->first <= 1) {
		auto u = dg.begin()->second;
		dg.erase(dg.begin());
		is_ex[u] = true;
		for (auto v : g[u])
			if (s[v] == 'B' && !is_ex[v]) {
				dg.erase( { deg[v], v });
				deg[v]--;
				dg.insert( { deg[v], v });
			}
	}
	for (int i = 1; i <= N; i++)
		if (is_ex[i])
			g[i].clear();
		else {
			vector<int> nw;
			for (auto x : g[i])
				if (!is_ex[x])
					nw.push_back(x);
			g[i] = nw;
		}
}

void dfs(int u, int p = -1) {
	if (p != -1 && g[u].size() == 1) {
		dp[u][0] = 2;
		dp[u][1] = 1;
		dp[u][2] = 2;
		assert(s[u] == 'W');
//		cerr << u << '\n';
		return;
	}
	int dpo = 0;
	vector<int> df;
	int mx2 = INT_MAX;
	char cur = s[u];
	for (auto v : g[u])
		if (v != p) {
			dfs(v, u);
			dpo += dp[v][0];
			df.push_back(dp[v][1] - dp[v][0]);
			mx2 = min(mx2, dp[v][2] - dp[v][0]);
			cur = (cur == 'W' ? 'B' : 'W');
		}
	dp[u][0] = dpo + 2 + (cur == 'B');
	sort(begin(df), end(df));
	dp[u][1] = dpo + df[0] + 1 + (cur == 'W');
	dp[u][2] = dpo + mx2 + ((cur == 'B') ^ (p == -1)) + (p != -1 ? 2 : 1);
	if (df.size() > 1)
		dp[u][2] = min(dp[u][2],
				dpo + df[0] + df[1] + ((cur == 'W') ^ (p == -1))
						+ (p != -1 ? 2 : 1));
	cerr << u << ' ' << dp[u][0] << ' ' << dp[u][1] << ' ' << dp[u][2] << ' '
			<< s[u] << ' ' << cur << '\n';
}

void perf(vector<int> x) {
	cerr << x.size() << '\n';
	int lst = -1;
	for (auto u : x) {
		assert(
				lst == -1 || lst == u
						|| find(g[lst].begin(), g[lst].end(), u)
								!= g[lst].end());
		s[u] = (s[u] == 'W' ? 'B' : 'W');
	}
}

int main(int argc, char** argv) {
//#ifdef ONLINE_JUDGE
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
//#endif

	int u, v;
	cin >> N;
	for (int i = 1; i < N; i++) {
		cin >> u >> v;
		g[u].push_back(v);
		g[v].push_back(u);
		deg[u]++, deg[v]++;
	}
	cin >> s;
	s = 'W' + s;
//	perf( { 5, 13, 19, 19, 2, 2, 8, 7, 14, 7, 8, 3, 11, 9, 11, 3, 20, 10, 1 });
//	cout << s << '\n';
//	return 0;
	if (count(begin(s), end(s), 'W') <= 2) {
		cout << count(begin(s), end(s), 'W') - 1 << '\n';
		return 0;
	}
	clear();
	int root = 0;
	for (int i = 1; i <= N; i++)
		if (!is_ex[i]) {
			root = i;
			dfs(i);
			break;
		}
	cout << min(dp[root][1], dp[root][2]) << '\n';
	return 0;
}


Measured memory_bytes: 25324