#include <bits/stdc++.h>
#define ll unsigned long long
using namespace std;
ll br=0, res=0;
ll ts(char c){
    if(c=='S') return 1000000007;
    if(c=='I') return 1000000009;
    if(c=='O') return 1000000021;
    return 1000000033;
}
int f(vector<char> str, ll n)
{
    map< pair<int, int>, int > mp;
    mp[make_pair(0, 0)] = 1;
    int zc = 0, oc = 0, tc = 0;
    res = 0;
    for (int i = 0; i < n; ++i)
    {
        if (str[i] == 'O') zc++;
        else if (str[i] == 'I') oc++;
        else tc++;
        pair<int, int> tmp = make_pair(zc - oc, zc - tc);
        res = res + mp[tmp];
        mp[tmp]++;
    }
    return res;
}
class Graph
{
public:

  Graph(int V)
  {
    this->V = V;
    visited.resize(V);
    fill(visited.begin(), visited.end(), false);
    adjacency_list.resize(V);
    found = false;
  }
  void add_edge(int u, int v, char c)
  {
    adjacency_list[u].push_back(make_pair(v, c));
    adjacency_list[v].push_back(make_pair(u, c));
  }
  void filuj(){
      fill(visited.begin(), visited.end(), false);
      found=false;
  }
  void DFS(int u, int v)
  {
    if (u == v) {
      //result.push_back(v);
      found = true;
      res=br;
      return;
    }
    visited[u] = true;
    //result.push_back(u);
    auto begin = adjacency_list[u].begin();
    auto end = adjacency_list[u].end();

    while (begin != end) {
      if (!visited[(*begin).first] && !found){
        br+=ts((*begin).second);
        DFS((*begin).first, v);
        br-=ts((*begin).second);
      }
      begin++;
    }
  }
  bool get_found()
  {
    return found;
  }
  bool isLinear() {
      if (V == 1)
         return true;
      int count = 0;
      for (int i = 0; i < V; i++) {
         if (adjacency_list[i].size() == 2)
         count++;
      }
      if (count == V - 2)
         return true;
      else
         return false;
   }
  int nadji(int u, char c){
      int ooo=0;
      for(auto x : adjacency_list[u]){
        if(x.second==c)
            ooo++;
      }
      return ooo;
  }
  int trazi(int u){
      int ooo=0;
      for(auto x : adjacency_list[u]){
        if(x.second=='I')
            ooo+=nadji(x.first, 'O');
        if(x.second=='O')
            ooo+=nadji(x.first, 'I');
      }
      return ooo;
  }

private:
  vector<vector<pair<int, char> > > adjacency_list;
  int V;
  vector<bool> visited;
  bool found;
};

int main ()
{
  ios::sync_with_stdio(false);
  cin.tie(0); cout.tie(0);
  ll n, meda=0, a, b, s=0, sa, sb;
  char c;
  cin>>n;
  vector<char> str(n-1);
  Graph g(n);

  for(int i=1; i<n; i++){
    cin>>a>>b>>c;
    g.add_edge(a-1, b-1, c);
    if(c=='S'){
        s++;
        sa=a;
        sb=b;
    }
    str[min(a, b)-1]=c;
  }
  if(s==1){
    ll o1=0, i1=0, o2=0, i2=0;
    sa--; sb--;
    o1=g.nadji(sa, 'O');
    o2=g.nadji(sb, 'O');
    i1=g.nadji(sa, 'I');
    i2=g.nadji(sb, 'I');

    cout<<o1*i2+o2*i1+g.trazi(sa)+g.trazi(sb);
    return 0;
  }
  else if(g.isLinear()){
    cout<<f(str, n-1);
  }

  /*g.add_edge(3, 0, 'S');
  g.add_edge(4, 5, 'O');
  g.add_edge(0, 4, 'I');
  g.add_edge(0, 1, 'S');
  g.add_edge(2, 0, 'S');*/
  ll z=ts('S')+ts('I')+ts('O');
  for(int u=0; u<n; u++){
    for(int v=u+1; v<n; v++){
        br=0; res=0;
        g.filuj();
        g.DFS(u, v);
        //cout<<u<<' '<<v<<' '<<res<<endl;
        meda+=((res%z)==0);
    }
  }
  cout<<meda;
  return 0;
}