#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;
}

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


vector<edge>e;

int dist[maxn];

void dfs2(int x, int y, int duz){
    dist[x] = duz;
    for(auto c:graf[x]){
        if(c.xx == y)continue;
        dfs2(c.xx, x, duz+1);
    }
}

int soluj(int x, int y){
    dfs2(y,0,0);

    int p1 = 0;
    int p2 = 0;
    int p3 = 0;
    while(x != y){
        //cout << x << " " << y << "\n";
        int najm = 1e9;
        int koji = 0;
        int val = 0;
        for(auto c:graf[x]){
            if(dist[c.xx] < najm){
                najm = dist[c.xx];
                koji = c.xx;
                val = c.yy;
            }
        }
        if(val == 1)p1++;
        if(val == 2)p2++;
        if(val == 3)p3++;
        x = koji;
    }
    if(p1 == p2 && p2 == p3 && p1 > 0)return 1;
    return 0;
}

ll brut(){
    ll resres = 0;
    ff(i,1,n){
        ff(j,1,n){
            if(i >= j)continue;
            resres += soluj(i,j);
        }
    }
    return resres;
}


void kliruj(){
    e.clear();
    ff(i,1,n)graf[i].clear();
}

int puf[maxn];

int boja(){
    return (rnd()%3) + 1;
}

int deg[maxn];

void gen(){
    ff(i,1,n)deg[i] = 1;
    ff(i,1,n - 2){
        deg[puf[i]]++;
    }
    ff(i,1,n - 2){
        ff(j,1,n){
            if(deg[j] == 1){
                int sta = boja();
                e.pb({puf[i], j, sta});
                deg[puf[i]]--;
                deg[j]--;
                break;
            }
        }
    }
    int u = 0,v = 0;
    ff(i,1,n){
        if(deg[i] == 1){
            if(u == 0)u = i;
            else v = i;
        }
    }
    int sta = boja();
    e.pb({u, v, sta});
}

void init(){
    for(auto c:e){
        graf[c.x].pb({c.y,c.b});
        graf[c.y].pb({c.x,c.b});
    }
}


void testiraj(){
    int dlt = 10000;
    while(dlt--){
        n = (rnd()%200) + 2;
        kliruj();
        ff(i,1,n-2)puf[i] = (rnd()%n)+1;
        gen();
        init();
        int p1 = brut();
        int p2 = moj();
        if(p1 != p2){
            cout << "KURAC\n";
            cout << n << "\n";
            for(auto c:e){
                cout << c.x << " " << c.y << " " << c.b << "\n";
            }
            cout << "\n";
            cout << p1 << " " << p2 << "\n";
            exit(0);
        }
    }
    cout << "ok\n";

}




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;
}
/*
4
1 2 S
2 3 I
3 4 O
6
2 3 3
5 2 2
1 4 2
5 1 3
5 6 1
5
2 3 2
1 2 1
5 1 1
4 5 3
6
4 2 1
1 4 3
6 1 1
3 5 1
3 6 2
4
2 1 3
4 2 1
3 4 2
4
1 2 S
1 3 I
3 4 O

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

*/