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

int sz[300005];
vector <pair <int, char>> cgraf[300005];
vector <int> graf[300005];
pair <int, int> value[300005];

typedef long long ll;

pair <int, int> dodaj(pair <int, int> p, char c){
    if(c == 'S'){
        p.first++;
    }
    if(c == 'I'){
        p.first--;
        p.second++;
    }
    if(c == 'O') p.second--;
    return p;
}

pair <int, int> neg(pair <int, int> p){
    p.first = -p.first;
    p.second = -p.second;
    return p;
}

pair <int, int> dodaj(pair <int, int> p, pair <int, int> r){
    p.first += r.first;
    p.second += r.second;
    return p;
}

pair <int, int> mnozi(pair <int, int> p, int sk){
    p.first *= sk;
    p.second *= sk;
    return p;
}
void dfs_size(int v, int par){
    sz[v] = 1;
    for(auto t : cgraf[v]){
        int c = t.first;
        if(c == par) continue;
        value[c] = dodaj(value[v], t.second);
        graf[v].push_back(c);
        dfs_size(c, v);
        sz[v] += sz[c];
    }
}

int iz[300005];
map <pair <int, int>, int> br[300005];
ll res;


void dfs_calc(int v, int par){
    if(graf[v].empty()){
        iz[v] = v;
        br[v][value[v]]++;
        return;
    }
    int opt = graf[v][0];
    for(auto c : graf[v]){
        dfs_calc(c, v);
        res += br[iz[c]][value[v]];
        if(sz[c] > sz[opt]) c = opt;
    }
    iz[v] = iz[opt];
    pair <int, int> treba = mnozi(value[v], 2);
    for(auto c : graf[v]){
        if(c == opt) continue;
        for(auto g : br[iz[c]]){
            res += br[iz[v]][dodaj(treba, neg(g.first))]*1LL*g.second;
        }
        for(auto g : br[iz[c]]){
            br[iz[v]][g.first] += g.second;
        }
    }
    br[iz[v]][value[v]]++;
}

int main(){
    ios_base::sync_with_stdio(false), cin.tie(0);

    int n;
    cin >> n;
    for(int i=1; i<n; i++){
        int a, b;
        char c;
        cin >> a >> b >> c;
        cgraf[a].push_back({b, c});
        cgraf[b].push_back({a, c});
    }
    dfs_size(1, 0);
    dfs_calc(1, 0);
    cout << res;
    return 0;
}