← Home
package main

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

type FastScanner struct {
	data []byte
	idx  int
	n    int
}

func NewFastScanner() *FastScanner {
	data, _ := io.ReadAll(os.Stdin)
	return &FastScanner{data: data, n: len(data)}
}

func (fs *FastScanner) NextInt() int {
	for fs.idx < fs.n {
		c := fs.data[fs.idx]
		if c >= '0' && c <= '9' {
			break
		}
		fs.idx++
	}
	val := 0
	for fs.idx < fs.n {
		c := fs.data[fs.idx]
		if c < '0' || c > '9' {
			break
		}
		val = val*10 + int(c-'0')
		fs.idx++
	}
	return val
}

func (fs *FastScanner) NextByte() byte {
	for fs.idx < fs.n {
		c := fs.data[fs.idx]
		if c != ' ' && c != '\n' && c != '\r' && c != '\t' {
			break
		}
		fs.idx++
	}
	b := fs.data[fs.idx]
	fs.idx++
	return b
}

type Solver struct {
	parent []int
	active []bool
	size   []int
	label  []int
	out    [][]int
	in     [][]int

	visF   []int
	visB   []int
	stampF int
	stampB int

	stack   []int
	tmpF    []int
	tmpB    []int
	tmpX    []int
	tmpSeq  []int
	tmpInts []int

	cost      int64
	nextLabel int
}

func NewSolver(n int) *Solver {
	parent := make([]int, n)
	size := make([]int, n)
	for i := 0; i < n; i++ {
		parent[i] = i
		size[i] = 1
	}
	return &Solver{
		parent:    parent,
		active:    make([]bool, n),
		size:      size,
		label:     make([]int, n),
		out:       make([][]int, n),
		in:        make([][]int, n),
		visF:      make([]int, n),
		visB:      make([]int, n),
		nextLabel: 1,
	}
}

func (s *Solver) find(x int) int {
	y := x
	for s.parent[y] != y {
		y = s.parent[y]
	}
	for s.parent[x] != x {
		p := s.parent[x]
		s.parent[x] = y
		x = p
	}
	return y
}

func (s *Solver) activate(x int) {
	s.active[x] = true
	s.label[x] = s.nextLabel
	s.nextLabel++
}

func (s *Solver) forward(start, up int) []int {
	s.stampF++
	s.tmpF = s.tmpF[:0]
	s.stack = s.stack[:0]
	s.stack = append(s.stack, start)
	for len(s.stack) > 0 {
		u := s.stack[len(s.stack)-1]
		s.stack = s.stack[:len(s.stack)-1]
		if s.visF[u] == s.stampF {
			continue
		}
		s.visF[u] = s.stampF
		s.tmpF = append(s.tmpF, u)
		for _, v0 := range s.out[u] {
			v := s.find(v0)
			if v == u || !s.active[v] || s.visF[v] == s.stampF {
				continue
			}
			if s.label[v] <= up {
				s.stack = append(s.stack, v)
			}
		}
	}
	return s.tmpF
}

func (s *Solver) backward(start, low int) []int {
	s.stampB++
	s.tmpB = s.tmpB[:0]
	s.stack = s.stack[:0]
	s.stack = append(s.stack, start)
	for len(s.stack) > 0 {
		u := s.stack[len(s.stack)-1]
		s.stack = s.stack[:len(s.stack)-1]
		if s.visB[u] == s.stampB {
			continue
		}
		s.visB[u] = s.stampB
		s.tmpB = append(s.tmpB, u)
		for _, v0 := range s.in[u] {
			v := s.find(v0)
			if v == u || !s.active[v] || s.visB[v] == s.stampB {
				continue
			}
			if s.label[v] >= low {
				s.stack = append(s.stack, v)
			}
		}
	}
	return s.tmpB
}

func (s *Solver) sortByLabel(a []int) {
	labels := s.label
	sort.Slice(a, func(i, j int) bool {
		return labels[a[i]] < labels[a[j]]
	})
}

func (s *Solver) relabel(seq []int) {
	if len(seq) <= 1 {
		return
	}
	s.tmpInts = s.tmpInts[:0]
	for _, x := range seq {
		s.tmpInts = append(s.tmpInts, s.label[x])
	}
	sort.Ints(s.tmpInts)
	for i, x := range seq {
		s.label[x] = s.tmpInts[i]
	}
}

func (s *Solver) merge(xs []int) int {
	h := xs[0]
	best := len(s.out[h]) + len(s.in[h])
	for _, x := range xs[1:] {
		cur := len(s.out[x]) + len(s.in[x])
		if cur > best {
			best = cur
			h = x
		}
	}
	total := 0
	for _, x := range xs {
		sz := s.size[x]
		total += sz
		if sz > 1 {
			s.cost -= int64(sz) * int64(sz)
		}
	}
	for _, x := range xs {
		if x == h {
			continue
		}
		s.parent[x] = h
		s.active[x] = false
		if len(s.out[x]) > 0 {
			s.out[h] = append(s.out[h], s.out[x]...)
			s.out[x] = nil
		}
		if len(s.in[x]) > 0 {
			s.in[h] = append(s.in[h], s.in[x]...)
			s.in[x] = nil
		}
	}
	s.size[h] = total
	if total > 1 {
		s.cost += int64(total) * int64(total)
	}
	return h
}

func (s *Solver) addEdge(a, b int) {
	ra := s.find(a)
	rb := s.find(b)
	if ra == rb || !s.active[ra] || !s.active[rb] {
		return
	}
	if s.label[ra] < s.label[rb] {
		s.out[ra] = append(s.out[ra], rb)
		s.in[rb] = append(s.in[rb], ra)
		return
	}

	up := s.label[ra]
	low := s.label[rb]

	F := s.forward(rb, up)
	B := s.backward(ra, low)

	s.tmpX = s.tmpX[:0]
	for _, x := range F {
		if s.visB[x] == s.stampB {
			s.tmpX = append(s.tmpX, x)
		}
	}

	s.sortByLabel(F)
	s.sortByLabel(B)

	if len(s.tmpX) == 0 {
		s.out[ra] = append(s.out[ra], rb)
		s.in[rb] = append(s.in[rb], ra)
		s.tmpSeq = s.tmpSeq[:0]
		s.tmpSeq = append(s.tmpSeq, B...)
		s.tmpSeq = append(s.tmpSeq, F...)
		s.relabel(s.tmpSeq)
		return
	}

	h := s.merge(s.tmpX)

	s.tmpSeq = s.tmpSeq[:0]
	for _, x := range B {
		if s.visF[x] != s.stampF {
			s.tmpSeq = append(s.tmpSeq, x)
		}
	}
	s.tmpSeq = append(s.tmpSeq, h)
	for _, x := range F {
		if s.visB[x] != s.stampB {
			s.tmpSeq = append(s.tmpSeq, x)
		}
	}
	s.relabel(s.tmpSeq)
}

func main() {
	fs := NewFastScanner()
	n := fs.NextInt()
	m := fs.NextInt()
	q := fs.NextInt()

	solver := NewSolver(n + m)

	rowActive := make([]bool, n)
	colActive := make([]bool, m)

	rowCells := make([][]int, n)
	colCells := make([][]int, m)

	qx := make([]int, q)
	qy := make([]int, q)
	qc := make([]byte, q)
	edgeActive := make([]bool, q)
	ans := make([]int64, q)

	for i := 0; i < q; i++ {
		x := fs.NextInt() - 1
		y := fs.NextInt() - 1
		c := fs.NextByte()

		qx[i] = x
		qy[i] = y
		qc[i] = c

		rowCells[x] = append(rowCells[x], i)
		colCells[y] = append(colCells[y], i)

		if c == 'R' {
			if !rowActive[x] {
				rowActive[x] = true
				solver.activate(x)
				for _, id := range rowCells[x] {
					if edgeActive[id] {
						continue
					}
					cy := qy[id]
					if !colActive[cy] {
						continue
					}
					if qc[id] == 'R' {
						solver.addEdge(n+cy, qx[id])
					} else {
						solver.addEdge(qx[id], n+cy)
					}
					edgeActive[id] = true
				}
			}
			if colActive[y] && !edgeActive[i] {
				solver.addEdge(n+y, x)
				edgeActive[i] = true
			}
		} else {
			if !colActive[y] {
				colActive[y] = true
				solver.activate(n + y)
				for _, id := range colCells[y] {
					if edgeActive[id] {
						continue
					}
					rx := qx[id]
					if !rowActive[rx] {
						continue
					}
					if qc[id] == 'R' {
						solver.addEdge(n+y, rx)
					} else {
						solver.addEdge(rx, n+y)
					}
					edgeActive[id] = true
				}
			}
			if rowActive[x] && !edgeActive[i] {
				solver.addEdge(x, n+y)
				edgeActive[i] = true
			}
		}

		ans[i] = solver.cost
	}

	out := make([]byte, 0, q*12)
	for i := 0; i < q; i++ {
		out = strconv.AppendInt(out, ans[i], 10)
		out = append(out, '\n')
	}
	os.Stdout.Write(out)
}