← Home
package main

import (
	"io"
	"os"
	"strconv"
)

var data []byte
var ptr int

func nextInt() int {
	for ptr < len(data) && (data[ptr] < '0' || data[ptr] > '9') {
		ptr++
	}
	v := 0
	for ptr < len(data) && data[ptr] >= '0' && data[ptr] <= '9' {
		v = v*10 + int(data[ptr]-'0')
		ptr++
	}
	return v
}

func nextByte() byte {
	for ptr < len(data) && (data[ptr] == ' ' || data[ptr] == '\n' || data[ptr] == '\r' || data[ptr] == '\t') {
		ptr++
	}
	b := data[ptr]
	ptr++
	return b
}

var up [][]int
var rk [][]int
var stateLen []int
var stateCh []int
var K int

func charAtC(s, pos int) int {
	d := pos - 1
	bit := 0
	for d > 0 {
		if d&1 == 1 {
			s = up[bit][s]
		}
		d >>= 1
		bit++
	}
	return stateCh[s]
}

func lcpC(u, v int) int {
	if u == v {
		return stateLen[u]
	}
	ru := stateLen[u]
	rv := stateLen[v]
	ans := 0
	for k := K; k >= 0; k-- {
		step := 1 << k
		if ru >= step && rv >= step && rk[k][u] == rk[k][v] {
			ans += step
			ru -= step
			rv -= step
			u = up[k][u]
			v = up[k][v]
		}
	}
	return ans
}

type BIT struct {
	n   int
	bit []int64
}

func NewBIT(n int) *BIT {
	return &BIT{n: n, bit: make([]int64, n+2)}
}

func (b *BIT) Add(i int, v int64) {
	for i <= b.n {
		b.bit[i] += v
		i += i & -i
	}
}

func (b *BIT) Sum(i int) int64 {
	var r int64
	for i > 0 {
		r += b.bit[i]
		i -= i & -i
	}
	return r
}

func main() {
	data, _ = io.ReadAll(os.Stdin)
	n := nextInt()

	par1 := make([]int, n+2)
	par2 := make([]int, n+2)
	lab1 := make([]byte, n+2)
	lab2 := make([]byte, n+2)
	opsTree := make([]byte, n)
	opsNew := make([]int, n)

	m1, m2 := 1, 1
	for i := 0; i < n; i++ {
		t := nextInt()
		v := nextInt()
		c := nextByte()
		if t == 1 {
			m1++
			par1[m1] = v
			lab1[m1] = c
			opsTree[i] = 1
			opsNew[i] = m1
		} else {
			m2++
			par2[m2] = v
			lab2[m2] = c
			opsTree[i] = 2
			opsNew[i] = m2
		}
	}

	frontChild := make([][26]int, m2+2)
	cStateOfVertex := make([]int, m2+2)
	stateLen = make([]int, m2+2)
	stateCh = make([]int, m2+2)
	stateParent := make([]int, m2+2)

	stateCnt := 1
	maxLen := 0
	for v := 2; v <= m2; v++ {
		ps := cStateOfVertex[par2[v]]
		ci := int(lab2[v] - 'a')
		ns := frontChild[ps][ci]
		if ns == 0 {
			ns = stateCnt
			stateCnt++
			frontChild[ps][ci] = ns
			stateParent[ns] = ps
			stateCh[ns] = ci + 1
			stateLen[ns] = stateLen[ps] + 1
			if stateLen[ns] > maxLen {
				maxLen = stateLen[ns]
			}
		}
		cStateOfVertex[v] = ns
	}
	stateLen = stateLen[:stateCnt]
	stateCh = stateCh[:stateCnt]
	stateParent = stateParent[:stateCnt]

	K = 0
	for (1 << K) <= maxLen {
		K++
	}

	up = make([][]int, K+1)
	rk = make([][]int, K+1)
	up[0] = make([]int, stateCnt)
	rk[0] = make([]int, stateCnt)
	for i := 0; i < stateCnt; i++ {
		up[0][i] = stateParent[i]
		rk[0][i] = stateCh[i]
	}

	rankCnt := 27
	order := make([]int, stateCnt)
	tmp := make([]int, stateCnt)
	cntSize := stateCnt
	if cntSize < 27 {
		cntSize = 27
	}
	cnt := make([]int, cntSize)

	for k := 1; k <= K; k++ {
		prevR := rk[k-1]
		prevUp := up[k-1]
		curUp := make([]int, stateCnt)
		curR := make([]int, stateCnt)
		up[k] = curUp
		rk[k] = curR

		for i := 0; i < stateCnt; i++ {
			curUp[i] = prevUp[prevUp[i]]
		}

		for i := 0; i < rankCnt; i++ {
			cnt[i] = 0
		}
		for i := 0; i < stateCnt; i++ {
			cnt[prevR[prevUp[i]]]++
		}
		s := 0
		for i := 0; i < rankCnt; i++ {
			c := cnt[i]
			cnt[i] = s
			s += c
		}
		for i := 0; i < stateCnt; i++ {
			key := prevR[prevUp[i]]
			tmp[cnt[key]] = i
			cnt[key]++
		}

		for i := 0; i < rankCnt; i++ {
			cnt[i] = 0
		}
		for i := 0; i < stateCnt; i++ {
			cnt[prevR[tmp[i]]]++
		}
		s = 0
		for i := 0; i < rankCnt; i++ {
			c := cnt[i]
			cnt[i] = s
			s += c
		}
		for i := 0; i < stateCnt; i++ {
			id := tmp[i]
			key := prevR[id]
			order[cnt[key]] = id
			cnt[key]++
		}

		curRank := 0
		curR[order[0]] = 0
		for i := 1; i < stateCnt; i++ {
			a := order[i-1]
			b := order[i]
			if prevR[a] != prevR[b] || prevR[prevUp[a]] != prevR[prevUp[b]] {
				curRank++
			}
			curR[b] = curRank
		}
		rankCnt = curRank + 1
	}

	orderByRank := make([]int, stateCnt)
	for i := 0; i < stateCnt; i++ {
		orderByRank[rk[K][i]] = i
	}
	sortedC := make([]int, 0, stateCnt-1)
	for i := 0; i < stateCnt; i++ {
		if orderByRank[i] != 0 {
			sortedC = append(sortedC, orderByRank[i])
		}
	}

	maxNodes := 2*stateCnt + m1 + 5
	childTrie := make([][26]int, maxNodes)
	nodeDepth := make([]int, maxNodes)
	nodeRep := make([]int, maxNodes)
	cStateNode := make([]int, stateCnt)
	cStateNode[0] = 1
	nodeCnt := 1

	if len(sortedC) > 0 {
		stack := make([]int, 0, maxNodes)

		s0 := sortedC[0]
		nodeCnt++
		leaf := nodeCnt
		nodeDepth[leaf] = stateLen[s0]
		nodeRep[leaf] = s0
		childTrie[1][charAtC(s0, 1)-1] = leaf
		cStateNode[s0] = leaf
		stack = append(stack, 1, leaf)
		prev := s0

		for i := 1; i < len(sortedC); i++ {
			cur := sortedC[i]
			l := lcpC(prev, cur)

			child := 0
			for nodeDepth[stack[len(stack)-1]] > l {
				child = stack[len(stack)-1]
				stack = stack[:len(stack)-1]
			}
			p := stack[len(stack)-1]

			if nodeDepth[p] < l {
				nodeCnt++
				mid := nodeCnt
				nodeDepth[mid] = l
				nodeRep[mid] = nodeRep[child]
				idx1 := charAtC(nodeRep[child], nodeDepth[p]+1) - 1
				childTrie[p][idx1] = mid
				idx2 := charAtC(nodeRep[child], l+1) - 1
				childTrie[mid][idx2] = child
				stack = append(stack, mid)
				p = mid
			}

			nodeCnt++
			leaf = nodeCnt
			nodeDepth[leaf] = stateLen[cur]
			nodeRep[leaf] = cur
			idx := charAtC(cur, nodeDepth[p]+1) - 1
			childTrie[p][idx] = leaf
			cStateNode[cur] = leaf
			stack = append(stack, leaf)
			prev = cur
		}
	}

	map1 := make([]int, m1+1)
	map1[1] = 1
	for v := 2; v <= m1; v++ {
		p := map1[par1[v]]
		if p == 0 {
			continue
		}
		ci := int(lab1[v] - 'a')
		ch := childTrie[p][ci]
		if ch == 0 {
			continue
		}
		if nodeDepth[ch] == nodeDepth[p]+1 {
			map1[v] = ch
		} else {
			nodeCnt++
			mid := nodeCnt
			nodeDepth[mid] = nodeDepth[p] + 1
			nodeRep[mid] = nodeRep[ch]
			childTrie[p][ci] = mid
			idx2 := charAtC(nodeRep[ch], nodeDepth[p]+2) - 1
			childTrie[mid][idx2] = ch
			map1[v] = mid
		}
	}

	tin := make([]int, nodeCnt+1)
	tout := make([]int, nodeCnt+1)
	stNodes := make([]int, 0, nodeCnt)
	stPos := make([]int, 0, nodeCnt)
	stNodes = append(stNodes, 1)
	stPos = append(stPos, 0)
	timer := 0
	for len(stNodes) > 0 {
		top := len(stNodes) - 1
		u := stNodes[top]
		pos := stPos[top]
		if pos == 0 {
			timer++
			tin[u] = timer
		}
		for pos < 26 && childTrie[u][pos] == 0 {
			pos++
		}
		if pos == 26 {
			tout[u] = timer
			stNodes = stNodes[:top]
			stPos = stPos[:top]
		} else {
			stPos[top] = pos + 1
			v := childTrie[u][pos]
			stNodes = append(stNodes, v)
			stPos = append(stPos, 0)
		}
	}

	bitAnc := NewBIT(timer)
	bitSub := NewBIT(timer)

	bitAnc.Add(tin[1], 1)
	bitSub.Add(tin[1], 1)

	var ans int64 = 1
	out := make([]byte, 0, n*12)

	for i := 0; i < n; i++ {
		if opsTree[i] == 1 {
			v := opsNew[i]
			node := map1[v]
			if node != 0 {
				ans += bitSub.Sum(tout[node]) - bitSub.Sum(tin[node]-1)
				bitAnc.Add(tin[node], 1)
				if tout[node]+1 <= timer {
					bitAnc.Add(tout[node]+1, -1)
				}
			}
		} else {
			v := opsNew[i]
			node := cStateNode[cStateOfVertex[v]]
			ans += bitAnc.Sum(tin[node])
			bitSub.Add(tin[node], 1)
		}
		out = strconv.AppendInt(out, ans, 10)
		out = append(out, '\n')
	}

	os.Stdout.Write(out)
}