using System;
using System.Collections.Generic;
using System.Linq;

namespace Zadatak5
{
    class Program
    {

        static void Main(string[] args)
        {
            var brCvorova = int.Parse(Console.ReadLine());

            var grane = new List<Tuple<int, int>>();

            var slovaDict = new Dictionary<string, char>();


            var cvorovi = Enumerable.Range(1, brCvorova).ToArray();

            for (int i = 1; i < brCvorova; i++)
            {
                var inputArr = Console.ReadLine().Split(' ');
                if (inputArr.Length != 3)
                {
                    Console.WriteLine("Morate uneti dva cvora i slovo");
                    return;
                }

                var cvorA = int.Parse(inputArr[0]);
                var cvorB = int.Parse(inputArr[1]);
                var slovo = inputArr[2].ToCharArray()[0];

                grane.Add(Tuple.Create(cvorA, cvorB));
                slovaDict.Add(string.Format("{0}{1}", cvorA, cvorB), slovo);
                slovaDict.Add(string.Format("{0}{1}", cvorB, cvorA), slovo);
            }

            var adjList = new Dictionary<int, HashSet<int>>();
            foreach (var cvor in cvorovi)
            {
                adjList[cvor] = new HashSet<int>();
            }

            foreach(var grana in grane)
            {
                adjList[grana.Item1].Add(grana.Item2);
                adjList[grana.Item2].Add(grana.Item1);
            }


            var graph = new Graph(cvorovi, grane);

            var brojSioCvorova = 0;

            for (int i = 0; i < cvorovi.Length; i++)
            {
                var currCvor = cvorovi[i];
                var f = graph.ShortestPath(currCvor);
                for(int j = i+1; j < cvorovi.Length; j++)
                {
                    var cvor = cvorovi[j];
                    var putanja = f(cvor).ToArray();
                    var countS = 0;
                    var countI = 0;
                    var countO = 0;

                    for(int k = 1; k < putanja.Length; k++)
                    {

                        var trenutni = putanja[k];
                        var prethodni = putanja[k - 1];
                        var slovo = slovaDict[string.Format("{0}{1}", trenutni, prethodni)];

                        if (slovo == 'S')
                            countS += 1;
                        if (slovo == 'I')
                            countI += 1;
                        if (slovo == 'O')
                            countO += 1;
                    }
                    if (countS == countI && countI == countO && countO != 0)
                    {
                        brojSioCvorova += 1;
                        //Console.WriteLine("Cvor ({0}, {1}) je SIO cvor({2})", currCvor, cvor, countI);
                    }
                }
            }

        }
    }

    public class Graph
    {
        public Graph(IEnumerable<int> vertices, IEnumerable<Tuple<int, int>> edges)
        {
            foreach (var vertex in vertices)
                AddVertex(vertex);
            foreach (var edge in edges)
                AddEdge(edge);
        }

        public Dictionary<int, HashSet<int>> AdjacencyList { get; } = new Dictionary<int, HashSet<int>>();

        public void AddVertex(int vertex)
        {
            AdjacencyList[vertex] = new HashSet<int>();
        }

        public void AddEdge(Tuple<int, int> edge)
        {
            if (AdjacencyList.ContainsKey(edge.Item1) && AdjacencyList.ContainsKey(edge.Item2))
            {
                AdjacencyList[edge.Item1].Add(edge.Item2);
                AdjacencyList[edge.Item2].Add(edge.Item1);
            }
        }

        public Func<int, IEnumerable<int>> ShortestPath(int start)
        {
            var previous = new Dictionary<int, int>();
            var queue = new Queue<int>();
            queue.Enqueue(start);

            while(queue.Count > 0)
            {
                var vertex = queue.Dequeue();
                foreach(var neighbor in AdjacencyList[vertex])
                {
                    if (previous.ContainsKey(neighbor))
                        continue;
                    previous[neighbor] = vertex;
                    queue.Enqueue(neighbor);
                }
            }

            Func<int, IEnumerable<int>> shortestPath = v =>
            {
                var path = new List<int> { };
                var current = v;
                while (!current.Equals(start))
                {
                    path.Add(current);
                    current = previous[current];
                };
                path.Add(start);

                return path;
            };
            return shortestPath;
        }
    }
}