#include <bits/stdc++.h>
using namespace std;

#define endl "\n"
#define ll long long
#define PB push_back
#define F first
#define S second
#define all(a) a.begin(), a.end()
#define MAX 300005
#define Fast ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define w(a) cout<<#a<<" : "<<a<<endl;

vector<pair<int,int>> A[MAX];
bool visited[MAX];
int SIO[3];
bool oce[3];
int n;
ll ans=0;
//int lastoce;
//bool prekidaj;

void travelDrugi(int cvor)
{
    visited[cvor]=1;
    if(SIO[0]==SIO[1] && SIO[2]==SIO[1] && SIO[0])
    {
        ans++;
    }
    for(auto x:A[cvor])
    {
        if(visited[x.F]) continue;
        SIO[x.S]++;
        travelDrugi(x.F);
        SIO[x.S]--;
    }
}

void travelPrvi(int cvor)
{
    //if(prekidaj) return;
    //visited[cvor]=1;
    if(!oce[1] && !oce[2])
    {
        //visited[cvor]=1;
        ans++;
        //prekidaj=1;
        return;
    }
    for(auto x:A[cvor])
    {
        if(!oce[x.S]) continue;
        //if(visited[x.F]) continue;
        oce[x.S]=0;
        travelPrvi(x.F);
        oce[x.S]=1;
    }
}
void Prvi()
{
    int cvor1=-1,cvor2;
    for(int i=0; i<n && cvor1==-1; ++i)
    {
        for(auto x:A[i])
        {
            if(x.S==0)
            {
                cvor1=i;
                cvor2=x.F;
                break;
            }
        }
    }
    vector<pair<int,int>> brojac(2,{0,0});
    for(int i=0; i<A[cvor1].size(); ++i)
    {
        if(A[cvor1][i].S==1) brojac[0].F++;
        if(A[cvor1][i].S==2) brojac[0].S++;
    }
    for(int i=0; i<A[cvor2].size(); ++i)
    {
        if(A[cvor2][i].S==1) brojac[1].F++;
        if(A[cvor2][i].S==2) brojac[1].S++;
    }
    ans=brojac[0].F*brojac[1].S+brojac[1].F*brojac[0].S;

    //w(I1); w(I2); w(O1); w(O2);

    oce[1]=oce[2]=1;
    oce[0]=0;
    travelPrvi(cvor1);

    oce[1]=oce[2]=1;
    oce[0]=0;
    travelPrvi(cvor2);

    cout<<ans;
    exit(0);
}
void Drugi()
{
    SIO[0]=SIO[1]=SIO[2]=0;
    for(int i=0; i<n; ++i)
    {
        for(int j=0; j<n; ++j) visited[j]=0;
        travelDrugi(i);
    }
    cout<<ans/2;
    exit(0);
}

struct s_i_o
{

    int S,I,O;
    bool operator == (const s_i_o &m)
    {
        return S==m.S && O==m.O && I==m.I;
    }
};
struct compare
{
    bool operator() (const s_i_o& a, const s_i_o& b) const
    {
        if(a.S < b.S) return 1;
        else if(a.S != b.S) return 0;
        if(a.I < b.I) return 1;
        else if(a.I != b.I) return 0;
        if(a.O < b.O) return 1;
        else if(a.O != b.O) return 0;
        return 0;
    }
};
void Treci(vector<int> a)
{
    map<s_i_o,ll,compare> br;
    br[{0,0,0}]=0;
    int ES=0,I=0,O=0;
    for(int i=0; i<n-1; ++i)
    {
        if(a[i]==0) ES++;
        if(a[i]==1) I++;
        if(a[i]==2) O++;
        int mini=min(min(ES,I),O);
        s_i_o diff={ES-mini,I-mini,O-mini};
        if(br.count(diff))
        {
            br[diff]++;
            ans+=br[diff];
        }
        else br[diff]=0;
    }
    cout<<ans;
    exit(0);
}

int sio(int x)
{
    if(x=='S') return 0;
    if(x=='I') return 1;
    return 2;
}

int main()
{
    Fast;
    cin>>n;
    int a,b,scnt=0,x;
    char c;
    bool tr=true;
    vector<int> niz(n-1);
    for(int i=0; i<n-1; ++i)
    {
        cin>>a>>b>>c;
        x=sio(c);
        a--; b--;
        if(abs(a-b)!=1) tr=false;
        niz[min(a,b)]=x;
        A[a].PB({b,x});
        A[b].PB({a,x});
        if(x==0)
        {
            scnt++;
        }
    }

    //if(scnt==1) Prvi();
    //for(int i=0; i<n-1; ++i) cout<<niz[i]<<" ";

    //Prvi();
    //Drugi();
    //Treci(niz);

    if(n<=1000) Drugi();
    else if(scnt==1) Prvi();
    else if(tr) Treci(niz);
    else Drugi();
    //if(cnt2==n) Treci(s_i_o,n-1);
    return 0;
}