#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#define mp make_pair
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define xx first
#define yy second
#define srt(a) sort(a.begin(),a.end());
#define srtg(a,ll) sort(a.begin(),a.end(),greater<ll>())
#define lb(a,x) lower_bound(a.begin(),a.end(),x)
#define up(a,x) upper_bound(a.begin(),a.end(),x)
#define fnd(a,x) find(a.begin(),a.end(),x)
#define vstart auto startt=chrono::system_clock::now()
#define vend auto endd=chrono::system_clock::now()
#define vvreme chrono::duration<double> vremee=endd-startt
#define ios ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define mt make_tuple

using namespace std;

typedef long long ll;
typedef pair<ll,ll> pii;
typedef pair<ll,ll> pll;
typedef string str;
typedef tuple<ll,ll,ll> tiii;

const ll maxn=3e5+2;
const ll logg=21;

deque<ll> tren;
vector<pair<ll,char> > g[maxn];
tiii razlike[maxn];
bool bio[maxn];
pii vremena[maxn];
ll vreme=0;
ll lift[maxn][logg];

void dfs(ll cvor,ll S,ll I,ll O){
    if(bio[cvor]) return;
    bio[cvor]=true;
    vreme++;
    vremena[cvor].xx=vreme;
    get<0>(razlike[cvor])=S-I;
    get<1>(razlike[cvor])=S-O;
    get<2>(razlike[cvor])=I-O;
    for(ll i=0;i<logg;i++){
        if((ll)tren.size()<((ll)1<<i)) lift[cvor][i]=-1;
        else lift[cvor][i]=tren[(ll)tren.size()-((ll)1<<i)];
    }
    tren.pb(cvor);
    for(pair<ll,char> i:g[cvor]){
        dfs(i.xx,S+(i.yy=='S' ? 1:0),I+(i.yy=='I' ? 1:0),O+(i.yy=='O' ? 1:0));
    }
    tren.pop_back();
    vreme++;
    vremena[cvor].yy=vreme;
}

bool iznad(ll a,ll b){
    if(vremena[a].xx<=vremena[b].xx && vremena[b].yy<=vremena[a].yy) return true;
    return false;
}

ll lca(ll a,ll b){
    for(ll i=logg-1;i>=0;i--){
        if(lift[b][i]==-1) continue;
        //cout<<"lca: "<<b<<" "<<i<<" "<<lift[b][i]<<"\n";
        if(!iznad(lift[b][i],a)) b=lift[b][i];
    }
    return lift[b][0];
}

bool ok(tiii a,tiii b,tiii c){
    if(get<0>(a)+get<0>(b)-2*get<0>(c)==0 && get<1>(a)+get<1>(b)-2*get<1>(c)==0
       && get<2>(a)+get<2>(b)-2*get<2>(c)==0) return true;
    return false;
}

void dfs3(ll cvor,ll prosli,ll jos,ll S,ll I,ll O,ll &res){
    //cout<<"  novi cvor: "<<cvor<<"\n";
    if(S==1 && I==1 && O==1) {res++;}
    if(jos==0) return;
    for(pair<ll,char> i:g[cvor]){
        if(i.xx!=prosli)
        dfs3(i.xx,cvor,jos-1,S+(i.yy=='S' ? 1:0),I+(i.yy=='I' ? 1:0),O+(i.yy=='O' ? 1:0),res);
    }
}

void dfs2(ll cvor,ll prosli,ll jos,ll &res){
    //cout<<"cvor: "<<cvor<<"\n";
    if(bio[cvor]) return;
    bio[cvor]=true;
    dfs3(cvor,-1,3,0,0,0,res);
    if(jos==0) return;
    for(pair<char,ll> i:g[cvor]){
        if(i.xx!=prosli && !bio[i.xx]) dfs2(i.xx,cvor,jos-1,res);
    }
}

ll kolikoo(tiii a,vector<tiii> &b){
    return upper_bound(b.begin(),b.end(),a)-lower_bound(b.begin(),b.end(),a);
}

vector<tiii> merguj(vector<vector<tiii> > &nesto,ll cvor,ll &res){
    vector<ll> ind(nesto.size(),0);
    vector<tiii> ret;
    ll koliko=nesto.size();
    ll sum=0;
    for(auto i:nesto){
        for(auto j:i){
            sum-=kolikoo(mt(2*get<0>(razlike[cvor])-get<0>(j),2*get<1>(razlike[cvor])-get<1>(j),2*get<2>(razlike[cvor])-get<2>(j)),i);
        }
    }
    //cout<<"proso "<<cvor<<endl;
    priority_queue<pair<tiii,ll>,vector<pair<tiii,ll> >, greater<pair<tiii,ll> > > sta;
    for(ll i=0;i<nesto.size();i++){
        sta.push(mp(nesto[i][0],i));
    }
    //cout<<"proso "<<cvor<<endl;
    while(!sta.empty()){
        ret.pb(sta.top().xx);
        ll molim=sta.top().yy;
        ind[molim]++;
        if(ind[molim]==nesto[molim].size()){
            sta.pop();
            continue;
        }
        //cout<<"kurac "<<sta.size()<<endl;
        sta.pop();
        sta.push(mp(nesto[molim][ind[molim]],molim));
    }
    //cout<<"proso "<<cvor<<endl;
    for(auto j:ret){
        sum+=kolikoo(mt(2*get<0>(razlike[cvor])-get<0>(j),2*get<1>(razlike[cvor])-get<1>(j),2*get<2>(razlike[cvor])-get<2>(j)),ret);
    }
    res+=sum/2;
    //cout<<"proso "<<cvor<<endl;
    return ret;
}

vector<tiii> uradi(ll cvor,ll prosli,ll &res){
    vector<vector<tiii> > nesto;
    //cout<<cvor<<endl;
    for(pair<ll,char> i:g[cvor]){
        if(i.xx!=prosli)
        nesto.pb(uradi(i.xx,cvor,res));
    }
    nesto.pb({razlike[cvor]});
    if(nesto.size()>1) return merguj(nesto,cvor,res);
    else return nesto[0];
}

void solve(){
    ll n;
    cin>>n;
    bool linija=true;
    bool binarno=true;
    ll koliko=0;
    ll koji=0;
    for(ll i=0;i<n-1;i++){
        ll a,b;
        char c;
        cin>>a>>b>>c;
        if(max(a,b)!=min(a,b)+1) linija=false;
        if(max(a,b)/2!=min(a,b)) binarno=false;
        if(c=='S'){
            koliko++;
            koji=a;
        }
        g[b].pb({a,c});
        g[a].pb({b,c});
    }
    if(linija){
        map<tiii,ll> nesto;
        ll S=0;
        ll I=0;
        ll O=0;
        ll res=0;
        for(ll i=1;i<=n;i++){
            //cout<<i<<"\n";
            if(i>2){
                S+=(max(g[i-1][0],g[i-1][1]).yy=='S');
                I+=(max(g[i-1][0],g[i-1][1]).yy=='I');
                O+=(max(g[i-1][0],g[i-1][1]).yy=='O');
            }else if(i>1){
                S+=g[i-1][0].yy=='S';
                I+=g[i-1][0].yy=='I';
                O+=g[i-1][0].yy=='O';
            }
            //cout<<S-I<<" "<<O-S<<" "<<O-I<<"\n";
            res+=nesto[mt(S-I,S-O,I-O)];
            nesto[mt(S-I,S-O,I-O)]++;
        }
        cout<<res;
    }else if(n<=1000){
        dfs(1,0,0,0);
        /*for(ll i=1;i<=n;i++){
            cout<<get<0>(razlike[i])<<" "<<get<1>(razlike[i])<<" "<<get<2>(razlike[i])<<"\n";
        }*/
        ll res=0;
        for(ll i=1;i<=n;i++){
            for(ll j=i+1;j<=n;j++){
                //cout<<i<<" "<<j<<" "<</*lca(i,j)<<*/"\n";
                if(ok(razlike[i],razlike[j],razlike[lca(i,j)])){
                    res++;
                    //cout<<i<<" "<<j<<"\n";
                }
            }
        }
        cout<<res;
    }else if(koliko==1){
        ll res=0;
        //cout<<"ovde\n";
        dfs2(koji,-1,5,res);
        cout<<res/2;
    }else/* if(binarno)*/{
        ll res=0;
        dfs(1,0,0,0);
        uradi(1,-1,res);
        cout<<res;
    }
}

int main(){
    ios;
    ll t=1;
    //cin>>t;
    while(t--) solve();
    return 0;
}
/*
7
1 2 S
2 3 S
3 4 I
4 5 O
5 6 O
6 7 I

12
12 11 I
11 10 O
10 3 O
3 4 S
4 5 O
5 6 I
3 2 I
2 1 O
3 7 I
7 8 I
8 9 I

12
1 2 I
1 3 S
2 4 S
2 5 I
3 6 S
3 7 I
4 8 O
4 9 I
5 10 O
5 11 O
6 12 O
*/