#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

#define ff(i,a,b) for(int (i) = (a); (i) <= (b); ++(i))
#define fb(i,a,b) for(int (i) = (a); (i) >= (b); --(i))
#define mod 998244353
#define xx first
#define yy second
#define all(a) (a).begin(), (a).end()
#define pb push_back
#define ll long long
#define pii pair<int,int>
#define maxn 300005

using namespace std;
using namespace __gnu_pbds;
typedef tree<int, null_type, less<int>,rb_tree_tag, tree_order_statistics_node_update> ordered_set;/// find_by_order(x)(x+1th) , order_of_key() (strictly less)
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());


int n;
vector<pii> graf[maxn];
struct edge{
    int x,y;
    int b;
};


pii cale[maxn];
int d[maxn];
struct cvor{
    int x;
    int y;
    ll br;
};
struct cvor_compare{
    bool operator() (const cvor &l, const cvor &r){
        pii prvi = {l.x, l.y};
        pii drugi = {r.x, r.y};
        if(prvi == drugi){
            return l.br < r.br;
        }
        return prvi < drugi;
    }
};

set<cvor, cvor_compare> s[maxn];


ll ans = 0;

void dfs(int x, int y){
    int mx = -1;
    int idx = -1;
    int gr = 0;
    //cout << x << " " << y << "\n";
    for(auto c:graf[x]){
        if(c.xx == y)continue;
        dfs(c.xx,x);
        int sta = s[c.xx].size();
        if(sta > mx){mx = sta; idx = c.xx; gr = c.yy;};
    }
    if(mx == -1)return;
    for(auto t:s[idx]){
        pii tr = {t.x, t.y};
        if(gr == 1)tr = {t.x + 1, t.y + 1};
        if(gr == 2)tr = {t.x - 1, t.y};
        if(gr == 3)tr = {t.x, t.y - 1};
        s[x].insert({tr.xx, tr.yy, t.br});
    }
    if(s[x].empty()){
        //cout << x << "\n";
        if(gr == 1)s[x].insert({1,1,1});
        else if(gr == 2)s[x].insert({-1,0,1});
        else if(gr == 3)s[x].insert({0,-1,1});
    }
    else{
        pii kurac = {1,1};
        if(gr == 2)kurac = {-1 ,0};
        if(gr == 3)kurac = {0, -1};
        cvor sta = *s[x].lower_bound({kurac.xx, kurac.yy, 0});
        pii pom = {sta.x, sta.y};
        if(pom == kurac){
            s[x].erase(sta);
            s[x].insert({sta.x, sta.y, sta.br + 1});
        }
        else s[x].insert({kurac.xx, kurac.yy, 1});
    }

    for(auto c:graf[x]){
        if(c.xx == y)continue;
        if(c.xx == idx)continue;
        pii kurac = {1,1};
        if(c.yy == 2)kurac = {-1 ,0};
        else if(c.yy == 3)kurac = {0, - 1};
        cvor stap = *s[x].lower_bound({-kurac.xx, -kurac.yy, 0});
        if(stap.x == -kurac.xx && stap.y == -kurac.yy)ans += stap.br;

        for(auto t:s[c.xx]){
            pii koji = {-t.x, -t.y};
            koji.xx -= kurac.xx;
            koji.yy -= kurac.yy;
            cvor sta = *s[x].lower_bound({koji.xx, koji.yy, 0});
            pii pom = {sta.x, sta.y};
            if(pom == koji){
                ans += (sta.br) * t.br;
            }
        }
        for(auto t:s[c.xx]){
            pii koji = {t.x, t.y};
            koji.xx += kurac.xx;
            koji.yy += kurac.yy;
            cvor sta = *s[x].lower_bound({koji.xx, koji.yy, 0});
            pii pom = {sta.x, sta.y};
            if(pom == koji){
                s[x].erase(sta);
                s[x].insert({sta.x, sta.y, sta.br + t.br});
            }
            else{
                s[x].insert({koji.xx, koji.yy, t.br});
            }
        }
        if(s[x].empty()){
            s[x].insert({kurac.xx, kurac.yy, 1});
        }
        else{
            cvor sta = *s[x].lower_bound({kurac.xx, kurac.yy, 0});
            if(sta.x == kurac.xx && sta.y == kurac.yy){
                s[x].erase(sta);
                s[x].insert({sta.x, sta.y, sta.br + 1});
            }
            else s[x].insert({kurac.xx, kurac.yy, 1});
        }
    }
    cvor sta = *s[x].lower_bound({0,0,0});
    if(sta.x == 0 && sta.y == 0)ans+=(sta.br);
}


ll moj(){
    ans = 0;
    ff(i,1,n)s[i].clear();
    ff(i,1,n){
        int sta = graf[i].size();
        d[i] = sta;
    }
    dfs(1,0);
    return ans;
}

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





int main()
{

    ios_base::sync_with_stdio(false);
    cin.tie(0);
    //testiraj();
    cin >> n;
    ff(i,1,n - 1){
        int a,b;
        cin >> a >> b;
        int x;
        char pp;
        cin >> pp;
        if(pp == 'S')x = 1;
        if(pp == 'I')x = 3;
        if(pp == 'O')x = 2;
        //cin >> x;
        graf[a].pb({b, x});
        graf[b].pb({a, x});

    }
    //cout << brut() << "\n";
    cout << moj() << "\n";
    return 0;
}