#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

const long long INF = 1LL<<60;
using pll = pair<long long, long long>;
using Graph = vector<vector<int>>;
vector<int> color;
string str_color;
int N;
Graph origG, G;

// no-need subtree
vector<int> deg;
vector<bool> nonneed;

// dp, left, right (in 全方位木dp)
vector<vector<pll>> dp;
vector<vector<pll>> Left, Right;
vector<int> parent_ord; // G[v][parent_ord[v]] is v's parent
const pll CUMUL_UNITY = {0, 0};

pll merge(pll a, pll b) {
    return pll(a.first + b.first,
               a.first + b.first - max(a.first - a.second, b.first - b.second));
}

pll calc(int v, int jogai, int ini) {
    int s = G[v].size();
    int adjnum = s - 1;
    if (jogai == -1) ++adjnum;

    // leaf
    if (adjnum == 0) {
        if (ini % 2 == 1) return {1, 1};
        else return {0, 0};
    }

    // cumulative sum (not necessary to change)
    auto tmp = CUMUL_UNITY;
    if (adjnum == 1) {
        if (s == 1 || jogai == 1) tmp = dp[v][0];
        else tmp = dp[v][1];
    }
    else {
        if (jogai == -1) tmp = Left[v][s];
        else tmp = merge(Left[v][jogai], Right[v][s-jogai-1]);
    }
    
    // merge
    auto res = tmp;
    res.first += adjnum * 2;
    res.second += adjnum * 2 - 1;
    if ( (ini + adjnum) % 2 == 1 ) ++res.first;
    if ( (ini + adjnum + 1) % 2 == 1 ) ++res.second;
    
    return res;
}

void build(int v) {
    int s = G[v].size();
    Left[v].assign(s+1, CUMUL_UNITY);
    Right[v].assign(s+1, CUMUL_UNITY);
    for (int i = 0; i < s; ++i) {
        Left[v][i+1] = merge(Left[v][i], dp[v][i]);
        Right[v][i+1] = merge(Right[v][i], dp[v][s-i-1]);
    }
}
    
pll rec(int v, int p = -1) {
    int s = G[v].size();
    dp[v].assign(s, CUMUL_UNITY);
    for (int i = 0; i < s; ++i) {
        int to = G[v][i];
        if (to == p) {
            parent_ord[v] = i;
            continue;
        }
        dp[v][i] = rec(to, v);
    }
    build(v);
    return calc(v, parent_ord[v], 1 - color[v]);
}

void rerec(int v, pll pval, int p = -1) {
    int s = G[v].size();
    if (parent_ord[v] != -1) dp[v][parent_ord[v]] = pval;
    build(v);
    for (int i = 0; i < s; ++i) {
        int to = G[v][i];
        if (to == p) continue;
        auto nval = calc(v, i, 1 - color[v]);        
        rerec(to, nval, v);
    }
}

void pre() {
    nonneed.assign(N, false);
    queue<int> que;
    for (int v = 0; v < N; ++v) if (color[v] == 0 && deg[v] == 1) que.push(v);
    while (!que.empty()) {
        int v = que.front(); que.pop();
        nonneed[v] = true;
        for (auto to : origG[v]) {
            if (nonneed[to]) continue;
            --deg[to];
            if (color[to] == 0 && deg[to] == 1) que.push(to);
        }
    }
    for (int v = 0; v < N; ++v) {
        if (nonneed[v]) continue;
        for (auto to : origG[v]) {
            if (nonneed[to]) continue;
            G[v].push_back(to);
        }
    }
}

long long solve() {
    // cut down black leaves
    pre();

    // DP
    dp.assign(N, vector<pll>());
    Left.assign(N, vector<pll>());
    Right.assign(N, vector<pll>());
    parent_ord.assign(N, -1);

    // 後退解析で削られなかった頂点を探す
    int r = 0;
    for (; r < N; ++r) if (!nonneed[r]) break;
    if (r == N) return 0;
    
    rec(r);
    rerec(r, {0, 0});

    // search
    long long res = INF;
    for (int v = 0; v < N; ++v) {
        if (nonneed[v]) continue;
        auto tmp = calc(v, -1, color[v]);
        chmin(res, tmp.second);
    }
    return res;
}

int main() {
    cin >> N;
    origG.assign(N, vector<int>());
    G.assign(N, vector<int>());
    deg.assign(N, 0);
    for (int i = 0; i < N-1; ++i) {
        int u, v; cin >> u >> v; --u, --v;
        origG[u].push_back(v), origG[v].push_back(u);
        ++deg[u], ++deg[v];
    }
    cin >> str_color;
    color.assign(N, 0);
    for (int i = 0; i < N; ++i) if (str_color[i] == 'W') color[i] = 1;
    cout << solve() << endl;
}


Measured memory_bytes: 43648