// Slower C++ solution:
// InterestingLSY

// codeforces&github: interestingLSY, qq: 2659723130

// 《幽灵公主》是真的好看！

#ifdef intLSY

#include <intlsy/stdc++.h>

#else

#include <bits/stdc++.h>

#endif

#include <bits/c++0x_warning.h>

using namespace std;

#define il inline

#define elif else if



// Type

#define ld double

#define ll long long

#define ull unsigned ll



// Vector

#define vc vector

#define Pb push_back

#define Pf push_front

#define Eb emplace_back

#define All(x) x.begin(),x.end()

#define AllRev(x) x.rbegin(),x.rend()



// Memory

#define Ms(_data) memset(_data,0,sizeof(_data))

#define Msn(_data,_num) memset(_data,_num,sizeof(_data))



// Pair

#define F first

#define S second

#define pii pair<int,int>

#define pli pair<ll,int>

#define pil pair<int,ll>

#define pll pair<ll,ll>



// Loop

#define For(i,j) for( int (i) = 1 ; (i) <= (j) ; ++(i) )

#define For0(i,j) for( int (i) = 0 ; (i) < (j) ; ++(i) )

#define Forx(i,j,k) for( int (i) = (j) ; (i) <= (k) ; ++(i) )

#define Forstep(i,j,k,st) for( int (i) = (j) ; (i) <= (k) ; (i) += (st) )

#define fOR(i,j) for( int (i) = (j) ; (i) >= 1 ; --(i) )

#define fOR0(i,j) for( int (i) = (j)-1 ; (i) >= 0 ; --(i) )

#define fORx(i,j,k) for( int (i) = (k) ; (i) >= (j) ; --(i) )



// Read

struct InputReader{

	static constexpr int MAXSZ = 1048576;

	char buf[MAXSZ]; int p, ed;

	bool detectedEOF = false;

	il InputReader(){ p = MAXSZ; }

	il void Flush(){ p = 0; ed = fread(buf,1,MAXSZ,stdin); }

	il void GetChar( char &c ){

		if(p >= MAXSZ) Flush();

		if( p == ed ){ detectedEOF = true; }

		c = buf[p++];

	}

	il void ReadNum( char &c ){ GetChar(c); while( !isdigit(c) && c != '-' && !detectedEOF ) GetChar(c); }

	il void ReadAlpha( char &c ){ GetChar(c); while( !isalpha(c) && !detectedEOF ) GetChar(c); }

	il void ReadInt( int &ans ){

		ans = 0; int nega = 1;

		char c; ReadNum(c); if(detectedEOF) return;

		if( c == '-' ){

			nega = -1;

			GetChar(c);

		}

		while( isdigit(c) && !detectedEOF ){

			ans = ans*10 + c-'0';

			GetChar(c);

		}

		ans *= nega;

	}

	il void Readll( ll &ans ){

		ans = 0; int nega = 1;

		char c; ReadNum(c); if(detectedEOF) return;

		if( c == '-' ){

			nega = -1;

			GetChar(c);

		}

		while( isdigit(c) && !detectedEOF ){

			ans = ans*10 + c-'0';

			GetChar(c);

		}

		ans *= nega;

	}

	il void ReadString( string &x ){

		x.clear(); char ch; GetChar(ch);

		while( !isdigit(ch) && !isalpha(ch) && ch != '#' && ch != '.' && !detectedEOF ) GetChar(ch); if(detectedEOF) return;

		while( (isdigit(ch) || isalpha(ch) || ch == '#' || ch == '.') && !detectedEOF ){

			x += ch;

			GetChar(ch);

		}

	}

	il void ReadCString( char s[] ){

		int len = 0; char ch; GetChar(ch);

		while( !isdigit(ch) && !isalpha(ch) && ch != '#' && ch != '.' && !detectedEOF ) GetChar(ch); if(detectedEOF) return;

		while( (isdigit(ch) || isalpha(ch) || ch == '#' || ch == '.') && !detectedEOF ){

			s[len++] = ch;

			GetChar(ch);

		}

		s[len] = '\0';

	}

	il void SpecialRead( char &c ){

		GetChar(c); if(detectedEOF) return;

		while( !isdigit(c) && !isalpha(c) && c != '#' && c != '.' && c != '=' && c != 'B' && !detectedEOF ) GetChar(c);

	}

}In;

il void Read( int &x ){ In.ReadInt(x); }

il void Read( int &x, int &y ){ In.ReadInt(x); In.ReadInt(y); }

il void Read( int &x1 , int &x2 , int &x3 ){ In.ReadInt(x1); In.ReadInt(x2); In.ReadInt(x3); }

il void Read( int &x1 , int &x2 , int &x3 , int &x4 ){ In.ReadInt(x1); In.ReadInt(x2); In.ReadInt(x3); In.ReadInt(x4); }

il void Read( ll &x ){ In.Readll(x); }

il void Read( ll &x, ll &y ){ In.Readll(x); In.Readll(y); }

il void Read( ll &x1 , ll &x2 , ll &x3 ){ In.Readll(x1); In.Readll(x2); In.Readll(x3); }

il void Read( ll &x1 , ll &x2 , ll &x3 , ll &x4 ){ In.Readll(x1); In.Readll(x2); In.Readll(x3); In.Readll(x4); }

template<typename T> void Read( T a[] , int st , int ed ){ Forx(i,st,ed) Read(a[i]); }

#define iRead(k) int k; Read(k);

#define iRead2(a,b) iRead(a); iRead(b);

#define iRead3(a,b,c) iRead2(a,b); iRead(c);

#define iRead4(a,b,c,d) iRead2(a,b); iRead2(c,d);

#define lRead(k) ll k; Read(k);

#define lRead2(a,b) lRead(a); lRead(b);

#define lRead3(a,b,c) lRead2(a,b); lRead(c);

#define lRead4(a,b,c,d) lRead2(a,b); lRead2(c,d);



// File

#define Fin(a) freopen(a,"r",stdin)

#define Fout(a) freopen(a,"w",stdout)

il void FILEIO(){

	#ifdef intLSY

		Fin("in.in");

	#endif

}

il void FILEIO( string pname ){

	#ifndef intLSY

		Fin((pname+".in").c_str());

		Fout((pname+".out").c_str());

	#else

		Fin("in.in");

	#endif

}

il void FILEIO_OICONTEST( string pname ){

	Fin((pname+".in").c_str());

	#ifndef intLSY

		Fout((pname+".out").c_str());

	#endif

}

void Printtime(){

	#ifdef intLSY

		double _timeuse = clock()* 1000.0 / CLOCKS_PER_SEC;

		fprintf(stderr,"\n\nTime usage:\n%.0lf ms\n",_timeuse);

	#endif

}

void END(){ Printtime(); exit(0); }

template<typename T>void END( T mes ){ cout << mes << endl; END(); }



// Debug

#define B cerr << "BreakPoint" << endl;

#define O(x) cerr << #x << " " << (x) << endl;

#define o(x) cerr << #x << " " << (x) << "  ";

template<typename T0>

void P( T0 t0 ){

	cerr << t0 << endl;

}

template<typename T0, typename... Ts>

void P( T0 t0 , Ts... ts ){

	cerr << t0 << " ";

	P(ts...);

}

#define Msz(x) cerr << "Sizeof " << #x << " " << sizeof(x)/1024/1024 << " MB" << endl;

template<typename T>void Print( T a[] , int s , int t , char sp = ' ' , char ed = '\n' ){

	if( s > t ) return;

	for( int i = s ; i < t ; i++ )

		cout << a[i] << sp;

	cout << a[t] << ed;

	cout.flush();

}

template<typename T>void Print( T a , int s = 0 , int t = -1 , char sp = ' ' , char ed = '\n' ){

	if( t == -1 ) t = a.size()-1;

	for( int i = s ; i <= t ; i++ )

		cout << a[i] << sp;

	cout << ed;

	cout.flush();

}



// Optimize

#define Max(a,b) ((a)>(b)?(a):(b))

#define Min(a,b) ((a)<(b)?(a):(b))

#define Mymax(a,b) (a) = max((a),(b))

#define Mymin(a,b) (a) = min((a),(b))

#define MyMax(a,b) (a) = Max((a),(b))

#define MyMin(a,b) (a) = Min((a),(b))

#define INF (0x3f3f3f3f)

#define LINF ((long long)(0x3f3f3f3f3f3f3f3f))

#define Sqr(x) ((x)*(x))

#define Lowbit(a) ((a)&(-(a)))

///////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////

constexpr int MAXN = 131072;

constexpr int LOG = 18;



int n;

vc<int> e[MAXN];

bool col[MAXN]; // col = 0: ok



int in[MAXN];

void GetDfsOrder(){

	function<void(int,int)> Dfs = [&]( int pos , int fa ){

		static int nowTime = 0;

		in[pos] = ++nowTime;

		for( auto v : e[pos] )

			if( v != fa )

				Dfs(v,pos);

	};

	Dfs(1,0);

}



int up[MAXN][LOG];

int dep[MAXN];

void LCAInit(){

	function<void(int,int)> Dfs = [&]( int pos , int fa ){

		dep[pos] = dep[fa] + 1;

		up[pos][0] = fa;

		For(i,LOG-1) up[pos][i] = up[up[pos][i-1]][i-1];

		for( auto v : e[pos] ){

			if( v == fa ) continue;

			Dfs(v,pos);

		}

	};

	Dfs(1,0);

}

int LCA( int a , int b ){

	if( dep[a] < dep[b] ) swap(a,b);

	fOR0(i,LOG){

		int v = up[a][i];

		if( dep[v] >= dep[b] )

			a = v;

	}

	if( a == b ) return a;

	fOR0(i,LOG){

		int u = up[a][i], v = up[b][i];

		if( u != v ){

			a = u;

			b = v;

		}

	}

	return up[a][0];

}

il int GetDis( int a , int b ){

	int lca = LCA(a,b);

	return dep[a] + dep[b] - 2*dep[lca];

}



vc<int> whites;

ll GetInitAnswer(){

	For(i,n) if(col[i]) whites.Eb(i);

	if( whites.empty() ) END(0);

	if( whites.size() == 1 ) END(1);

	sort(All(whites),[]( int a , int b ){

		return in[a] < in[b];

	});

	// Print(whites);



	ll initAns = 0;

	int last;



	static bool flags[MAXN];

	auto UpdatePath = [&]( int a , int b ){

		int lca = LCA(a,b);

		if( lca == b ) swap(a,b);

		if( lca == a ){

			flags[up[a][0]] ^= 1;

			flags[b] ^= 1;

		}else{

			flags[a] ^= 1;

			flags[b] ^= 1;

			col[lca] ^= 1;

		}

	};



	last = whites.back();

	for( auto u : whites ){

		col[u] ^= 1;

		UpdatePath(last,u);

		initAns += GetDis(last,u);

		last = u;

	}



	function<void(int,int)> Dfs = [&]( int pos , int fa ){

		for( auto v : e[pos] ){

			if( v == fa ) continue;

			Dfs(v,pos);

			flags[pos] ^= flags[v];

		}

		col[pos] ^= flags[pos];

	};



	Dfs(1,0);



	// Print(flags,1,n);

	// Print(col,1,n);

	For(i,n) initAns += col[i];

	return initAns;

}



bool ban[MAXN];

int newRoot;

void InitBan(){

	static queue<int> q;

	static int deg[MAXN];

	For(i,n) deg[i] = e[i].size();

	For(i,n) if( deg[i] == 1 and !col[i] ){

		q.push(i);

		ban[i] = true;

	}

	while(!q.empty()){

		int u = q.front();

		q.pop();

		for( auto v : e[u] ){

			if( ban[v] or col[v] ) continue;

			--deg[v];

			if( deg[v] == 1 ){

				ban[v] = true;

				q.push(v);

			}

		}

	}

	// Print(ban,1,n);

	newRoot = [&](){ For(i,n) if(!ban[i]) return i; }();

}



ll FuckTheWorld(){

	ll tot = GetInitAnswer();

	// O(tot);

	static int cost[MAXN];

	For(i,n) cost[i] = col[i] ? -2 : 0;



	ll ans = LINF;

	function<int(int,int)> Dfs = [&]( int pos , int fa ){

		ll mi = 0, secMi = 0;

		for( int v : e[pos] ){

			if( ban[v] or v == fa ) continue;

			ll res = Dfs(v,pos);

			if( res <= mi ){

				secMi = mi;

				mi = res;

			}else

				Mymin(secMi,res);

		}

		Mymin(ans,mi+secMi+cost[pos]);

		return mi+cost[pos];

	};

	Dfs(newRoot,0);

	// O(ans);



	ans += tot;

	// Mymin(ans,tot);



	return ans;

}



int main(){

	FILEIO();



	Read(n);

	For(i,n-1){

		iRead2(a,b);

		e[a].Eb(b);

		e[b].Eb(a);

	}

	For(i,n){

		char c; In.ReadAlpha(c);

		col[i] = c == 'W';

	}

	// if( n <= 10 ) assert(0);



	InitBan();

	// For(i,n){

	// 	cout << i << " | ";

	// 	for( auto v : e[i] ) cout << v << " ";

	// 	cout << endl;

	// }



	GetDfsOrder();

	LCAInit();



	ll ans = FuckTheWorld();

	cout << ans << endl;



	END();

}


// Faster C++ solution for the same problem (measured speedup: 4.34934052553615x):
#include <bits/stdc++.h>

using namespace std;



const int N = 1e5 + 100;



int n, ind[N], dp[N];

int sum, mn;

bool vis[N];

char s[N];



struct edg {

  int v;

  edg *nxt;

} pol[N << 1], *h[N], *cur = pol;



void add(int u, int v) {

  edg *p = ++cur, *q = ++cur;

  ind[u]++, ind[v]++;

  p->v = v, p->nxt = h[u], h[u] = p;

  q->v = u, q->nxt = h[v], h[v] = q;

}



void topo() {

  queue <int> Q;

  for (int i = 1; i <= n; i++) {

    if (s[i] == 'B' && ind[i] == 1) {

      Q.push(i);

    }

  }

  while (!Q.empty()) {

    int u = Q.front();

    Q.pop();

    vis[u] = 1;

    for (edg *p = h[u]; p; p = p->nxt) {

      int v = p->v;

      if (ind[v]) ind[v]--;

      if (s[v] == 'B' && ind[v] == 1 && vis[v] == 0) {

        Q.push(v);

      }

    }

  }

}



int tp(int u) {

  return (ind[u] & 1) ^ (s[u] == 'W');

}



int val(int u) {

  return tp(u) == 1 ? -2 : 0;

}



void dfs(int u, int fa) {

  sum += (tp(u) == 1) + 2;

  dp[u] = val(u);

  for (edg *p = h[u]; p; p = p->nxt) {

    int v = p->v;

    if (v == fa || vis[v]) continue ;

    dfs(v, u);

    mn = min(mn, dp[u] + dp[v]);

    dp[u] = min(dp[u], dp[v] + val(u));

  }

}



int main() {

  scanf("%d", &n);

  for (int i = 1; i < n; i++) {

    int u, v;

    scanf("%d %d", &u, &v);

    add(u, v);

  }

  scanf("%s", s + 1);

  topo();

  int x = 1;

  while (x <= n) {

    if (vis[x] == 0) break ;

    x++;

  }

  dfs(x, 0);

  sum -= 2;

  printf("%d\n", sum + mn);

  return 0;

}