#include #include #include #include //#include #include #include #include #include #include //#include #include #include #include //#include #include #include //#include #include #include #include #include #include const int dx[] = {1, 0, -1, 0}; const int dy[] = {0, 1, 0, -1}; using namespace std; typedef long long ll; typedef unsigned long long ull; typedef vector vi; typedef vector vll; typedef pair pii; typedef pair pll; const int MAXN = 100010; int N; string s; vector G; pll P[MAXN]; // v 以下の部分木にある (ww, w) を求める pll dfs(int v, int p) { pll& ret = P[v]; if (s[v] == 'w') ret.second++; for (int ch : G[v]) if (ch != p) { pll tmp = dfs(ch, v); ret.first += tmp.first; ret.second += tmp.second; if (s[v] == 'w') ret.first += tmp.second; } return ret; } ll ans; void dfs2(int v, int par, pll p) { if (s[v] == 'c') { // c -> par 側 if (s[v] ) ans += p.first; // c -> 子 for (int ch : G[v]) if (ch != par) { ans += P[ch].first; } } // 子に移動 for (int ch : G[v]) if (ch != par) { pll tmp = p; tmp.first += P[v].first, tmp.second += P[v].second; tmp.first -= P[ch].first, tmp.second -= P[ch].second; if (s[v] == 'w') { tmp.first -= P[ch].second; tmp.first += p.second; } dfs2(ch, v, tmp); } } int main() { cin.tie(0); ios::sync_with_stdio(false); cin >> N; cin >> s; for (int i = 0; i < N; i++) assert(s[i] == 'c' || s[i] == 'w'); G.resize(N); for (int i = 0; i < N-1; i++) { int a, b; cin >> a >> b; a--; b--; G[a].emplace_back(b); G[b].emplace_back(a); } dfs(0, -1); // for (int i = 0; i < N; i++) { // cout << i << " " << P[i].first << " " << P[i].second << endl; // } dfs2(0, -1, pll()); cout << ans << endl; return 0; }