#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;

template <class T> void mini(T &l, T r) {l = min(l, r);}
template <class T> void maxi(T &l, T r) {l = max(l, r);}

template <class T> using Tree = tree <T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

string to_string(string s) {
    return '"' + s + '"';
}

string to_string(bool a) {
    return a ? "T" : "F";
}

string to_string(const char* s) {
    return to_string((string) s);
}

template <typename A, typename B>
string to_string(pair<A, B> p) {
    return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A>
string to_string(A v) {
    bool first = true;
    string res = "{";
    for (const auto &x : v) {
        if (!first) {
            res += ", ";
        }
        first = false;
        res += to_string(x);
    }
    res += "}";
    return res;
}

void debug_out() { cerr << endl; }

template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
    cerr << " " << to_string(H);
    debug_out(T...);
}

#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

#define X first
#define Y second
#define mid ((l + r) >> 1)
#define lson (p << 1)
#define rson (p << 1 | 1)

using ll = long long;
using ld = long double;

const int N = 1e5 + 10;

int n;
vector <int> e[N];
vector <int> e2[N];
int c[N];
int contain_white[N];
int white[N], black[N];
int vis[N];
int tot;
int bg[N], ed[N];
int timestamp;
int ww[N];
int ans;
int idx[N];

void add(int x, int y) {
    e2[x].push_back(y);
    e2[y].push_back(x);
}

void dfs(int u, int p) {
    contain_white[u] = c[u];
    for (auto &v : e[u]) {
        if (v != p) {
            dfs(v, u);
            if (contain_white[v]) {
                add(u, v);
            }
            contain_white[u] |= contain_white[v];
        }
    }
}

void dfs2(int u, int p, int cnt_w, int cnt_b) {
    vis[u] = 1;
    white[u] = cnt_w;
    black[u] = cnt_b;
    if ((c[u] ^ int(e2[u].size() & 1)) == 1) {
        cnt_w += 1;
        ww[u] = 1;
        tot += 1;
    } else {
        cnt_b += 1;
    }
    for (auto &v : e2[u]) {
        if (v != p) {
            dfs2(v, u, cnt_w, cnt_b);
        }
    }
}

void dfs3(int u, int p) {
    bg[u] = ++timestamp;
    idx[timestamp] = u;
    for (int v : e2[u]) if (v != p) {
        dfs3(v, u);
    }
    ed[u] = timestamp;
}

struct Seg {
    struct Node {
        int mx;
        int lz;
    } tr[N << 2];

    void build(int p, int l, int r) {
        if (l == r) {
            tr[p].mx = white[idx[l]] * 2;
            tr[p].lz = 0;
            return;
        }
        build(lson, l, mid);
        build(rson, mid + 1, r);
        tr[p].mx = max(tr[lson].mx, tr[rson].mx);
        tr[p].lz = 0;
    }

    void push_down(int p, int l, int r) {
        if (tr[p].lz) {
            tr[lson].lz += tr[p].lz;
            tr[lson].mx += tr[p].lz;
            tr[rson].lz += tr[p].lz;
            tr[rson].mx += tr[p].lz;
            tr[p].lz = 0;
        }
    }

    void update(int p, int l, int r, int ll, int rr, int v) {
        if (ll > r || rr < l) return;
        debug(p, l, r, ll, rr, v);
        if (ll <= l && rr >= r) {
            tr[p].mx += v;
            tr[p].lz += v;
            return;
        }
        push_down(p, l, r);
        update(lson, l, mid, ll, rr, v);
        update(rson, mid + 1, r, ll, rr, v);
        tr[p].mx = max(tr[lson].mx, tr[rson].mx);
    }

    int query(int p, int l, int r, int ll, int rr) {
        if (ll > r || rr < l) return 0;
        if (ll <= l && rr >= r) {
            return tr[p].mx;
        }
        push_down(p, l, r);
        return max(query(lson, l, mid, ll, rr), query(rson, mid + 1, r, ll, rr));
    }

} seg;

void dfs4(int u, int p) {
    debug(u, p);
    debug(seg.query(1, 1, timestamp, 1, timestamp));
    debug(seg.query(1, 1, timestamp, bg[2], bg[2]));
    mini(ans, tot - seg.query(1, 1, timestamp, 1, timestamp));
    for (auto &v : e2[u]) {
        if (v != p) {
            seg.update(1, 1, timestamp, bg[v], ed[v], 2 * (-ww[u] - ww[v]));
            seg.update(1, 1, timestamp, 1, timestamp, 2 * ww[v]);
            //seg.update(1, 1, timestamp, bg[v], ed[v], -ww[v]);
            dfs4(v, u);
            seg.update(1, 1, timestamp, bg[v], ed[v], 2 * (ww[u] + ww[v]));
            seg.update(1, 1, timestamp, 1, timestamp, 2 * (-ww[v]));
        }
    }
}

void run() {
    cin >> n;
    for (int i = 1; i < n; ++i) {
        int x, y;
        cin >> x >> y;
        e[x].push_back(y);
        e[y].push_back(x);
    }

    string s;
    cin >> s;
    for (int i = 1; i <= n; ++i) {
        c[i] = (s[i - 1] == 'W');
    }

    int who = find(c + 1, c + n + 1, 1) - c;
    dfs(who, 0);
    debug(who);
    dfs2(who, 0, 0, 0);

    dfs3(who, 0);
    
    for (int i = 1; i <= n; ++i) if (vis[i]) {
        debug(i);
        debug(ww[i]);
        debug(white[i], black[i]);
        tot += e2[i].size();
    }
    debug(tot);
    
    ans = tot;

    seg.build(1, 1, timestamp);

    dfs4(who, 0);
    cout << ans << endl;

}

int main() {
    run();
    return 0;
}


Measured memory_bytes: 30464