package main

import (
	"bufio"
	"io"
	"os"
	. "fmt"
)

type color bool

const black, red color = true, false

// Tree holds elements of the red-black tree
type Tree struct {
	Root       *Node
	size       int
	Comparator func(int, int) int
}

// Node is a single element within the tree
type Node struct {
	Key    int
	Value  int
	color  color
	Left   *Node
	Right  *Node
	Parent *Node
}

func NewSet() *Tree {
	return &Tree{Comparator: func(x int, y int) int {
		if x > y {
			return 1
		}
		if x < y {
			return -1
		}
		return 0
	}}
}

// Put inserts node into the tree.
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (tree *Tree) Put(key, value int) {
	var insertedNode *Node
	if tree.Root == nil {
		// Assert key is of comparator's type for initial tree
		tree.Comparator(key, key)
		tree.Root = &Node{Key: key, Value: value, color: red}
		insertedNode = tree.Root
	} else {
		node := tree.Root
		loop := true
		for loop {
			compare := tree.Comparator(key, node.Key)
			switch {
			case compare == 0:
				node.Key = key
				node.Value = value
				return
			case compare < 0:
				if node.Left == nil {
					node.Left = &Node{Key: key, Value: value, color: red}
					insertedNode = node.Left
					loop = false
				} else {
					node = node.Left
				}
			case compare > 0:
				if node.Right == nil {
					node.Right = &Node{Key: key, Value: value, color: red}
					insertedNode = node.Right
					loop = false
				} else {
					node = node.Right
				}
			}
		}
		insertedNode.Parent = node
	}
	tree.insertCase1(insertedNode)
	tree.size++
}

// Remove remove the node from the tree by key.
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (tree *Tree) Remove(key int) {
	var child *Node
	node := tree.lookup(key)
	if node == nil {
		return
	}
	if node.Left != nil && node.Right != nil {
		pred := node.Left.maximumNode()
		node.Key = pred.Key
		node.Value = pred.Value
		node = pred
	}
	if node.Left == nil || node.Right == nil {
		if node.Right == nil {
			child = node.Left
		} else {
			child = node.Right
		}
		if node.color == black {
			node.color = nodeColor(child)
			tree.deleteCase1(node)
		}
		tree.replaceNode(node, child)
		if node.Parent == nil && child != nil {
			child.color = black
		}
	}
	tree.size--
}

func (tree *Tree) MultiPut(key int) {
	if o := tree.lookup(key); o != nil {
		o.Value++
	} else {
		tree.Put(key, 1)
	}
}

func (tree *Tree) MultiRemove(key int) {
	if o := tree.lookup(key); o != nil {
		o.Value--
		if o.Value == 0 {
			tree.Remove(key)
		}
	}
}

// Left returns the left-most (min) node or nil if tree is empty.
func (tree *Tree) Left() (o *Node) {
	for current := tree.Root; current != nil; current = current.Left {
		o = current
	}
	return
}

// Right returns the right-most (max) node or nil if tree is empty.
func (tree *Tree) Right() (o *Node) {
	for current := tree.Root; current != nil; current = current.Right {
		o = current
	}
	return
}

// Floor Finds floor node of the input key, return the floor node or nil if no floor is found.
// Second return parameter is true if floor was found, otherwise false.
//
// Floor node is defined as the largest node that is smaller than or equal to the given node.
// A floor node may not be found, either because the tree is empty, or because
// all nodes in the tree are larger than the given node.
func (tree *Tree) Floor(key int) (floor *Node, found bool) {
	for node := tree.Root; node != nil; {
		compare := tree.Comparator(key, node.Key)
		switch {
		case compare == 0:
			return node, true
		case compare < 0:
			node = node.Left
		case compare > 0:
			floor, found = node, true
			node = node.Right
		}
	}
	return
}

// Ceiling finds ceiling node of the input key, return the ceiling node or nil if no ceiling is found.
// Second return parameter is true if ceiling was found, otherwise false.
//
// Ceiling node is defined as the smallest node that is larger than or equal to the given node.
// A ceiling node may not be found, either because the tree is empty, or because
// all nodes in the tree are smaller than the given node.
func (tree *Tree) Ceiling(key int) (ceiling *Node, found bool) {
	for node := tree.Root; node != nil; {
		compare := tree.Comparator(key, node.Key)
		switch {
		case compare == 0:
			return node, true
		case compare < 0:
			ceiling, found = node, true
			node = node.Left
		case compare > 0:
			node = node.Right
		}
	}
	return
}

func (tree *Tree) lookup(key int) *Node {
	node := tree.Root
	for node != nil {
		compare := tree.Comparator(key, node.Key)
		switch {
		case compare == 0:
			return node
		case compare < 0:
			node = node.Left
		case compare > 0:
			node = node.Right
		}
	}
	return nil
}

func (node *Node) grandparent() *Node {
	if node != nil && node.Parent != nil {
		return node.Parent.Parent
	}
	return nil
}

func (node *Node) uncle() *Node {
	if node == nil || node.Parent == nil || node.Parent.Parent == nil {
		return nil
	}
	return node.Parent.sibling()
}

func (node *Node) sibling() *Node {
	if node == nil || node.Parent == nil {
		return nil
	}
	if node == node.Parent.Left {
		return node.Parent.Right
	}
	return node.Parent.Left
}

func (tree *Tree) rotateLeft(node *Node) {
	right := node.Right
	tree.replaceNode(node, right)
	node.Right = right.Left
	if right.Left != nil {
		right.Left.Parent = node
	}
	right.Left = node
	node.Parent = right
}

func (tree *Tree) rotateRight(node *Node) {
	left := node.Left
	tree.replaceNode(node, left)
	node.Left = left.Right
	if left.Right != nil {
		left.Right.Parent = node
	}
	left.Right = node
	node.Parent = left
}

func (tree *Tree) replaceNode(old *Node, new *Node) {
	if old.Parent == nil {
		tree.Root = new
	} else {
		if old == old.Parent.Left {
			old.Parent.Left = new
		} else {
			old.Parent.Right = new
		}
	}
	if new != nil {
		new.Parent = old.Parent
	}
}

func (tree *Tree) insertCase1(node *Node) {
	if node.Parent == nil {
		node.color = black
	} else {
		tree.insertCase2(node)
	}
}

func (tree *Tree) insertCase2(node *Node) {
	if nodeColor(node.Parent) == black {
		return
	}
	tree.insertCase3(node)
}

func (tree *Tree) insertCase3(node *Node) {
	uncle := node.uncle()
	if nodeColor(uncle) == red {
		node.Parent.color = black
		uncle.color = black
		node.grandparent().color = red
		tree.insertCase1(node.grandparent())
	} else {
		tree.insertCase4(node)
	}
}

func (tree *Tree) insertCase4(node *Node) {
	grandparent := node.grandparent()
	if node == node.Parent.Right && node.Parent == grandparent.Left {
		tree.rotateLeft(node.Parent)
		node = node.Left
	} else if node == node.Parent.Left && node.Parent == grandparent.Right {
		tree.rotateRight(node.Parent)
		node = node.Right
	}
	tree.insertCase5(node)
}

func (tree *Tree) insertCase5(node *Node) {
	node.Parent.color = black
	grandparent := node.grandparent()
	grandparent.color = red
	if node == node.Parent.Left && node.Parent == grandparent.Left {
		tree.rotateRight(grandparent)
	} else if node == node.Parent.Right && node.Parent == grandparent.Right {
		tree.rotateLeft(grandparent)
	}
}

func (node *Node) maximumNode() *Node {
	if node == nil {
		return nil
	}
	for node.Right != nil {
		node = node.Right
	}
	return node
}

func (tree *Tree) deleteCase1(node *Node) {
	if node.Parent == nil {
		return
	}
	tree.deleteCase2(node)
}

func (tree *Tree) deleteCase2(node *Node) {
	sibling := node.sibling()
	if nodeColor(sibling) == red {
		node.Parent.color = red
		sibling.color = black
		if node == node.Parent.Left {
			tree.rotateLeft(node.Parent)
		} else {
			tree.rotateRight(node.Parent)
		}
	}
	tree.deleteCase3(node)
}

func (tree *Tree) deleteCase3(node *Node) {
	sibling := node.sibling()
	if nodeColor(node.Parent) == black &&
		nodeColor(sibling) == black &&
		nodeColor(sibling.Left) == black &&
		nodeColor(sibling.Right) == black {
		sibling.color = red
		tree.deleteCase1(node.Parent)
	} else {
		tree.deleteCase4(node)
	}
}

func (tree *Tree) deleteCase4(node *Node) {
	sibling := node.sibling()
	if nodeColor(node.Parent) == red &&
		nodeColor(sibling) == black &&
		nodeColor(sibling.Left) == black &&
		nodeColor(sibling.Right) == black {
		sibling.color = red
		node.Parent.color = black
	} else {
		tree.deleteCase5(node)
	}
}

func (tree *Tree) deleteCase5(node *Node) {
	sibling := node.sibling()
	if node == node.Parent.Left &&
		nodeColor(sibling) == black &&
		nodeColor(sibling.Left) == red &&
		nodeColor(sibling.Right) == black {
		sibling.color = red
		sibling.Left.color = black
		tree.rotateRight(sibling)
	} else if node == node.Parent.Right &&
		nodeColor(sibling) == black &&
		nodeColor(sibling.Right) == red &&
		nodeColor(sibling.Left) == black {
		sibling.color = red
		sibling.Right.color = black
		tree.rotateLeft(sibling)
	}
	tree.deleteCase6(node)
}

func (tree *Tree) deleteCase6(node *Node) {
	sibling := node.sibling()
	sibling.color = nodeColor(node.Parent)
	node.Parent.color = black
	if node == node.Parent.Left && nodeColor(sibling.Right) == red {
		sibling.Right.color = black
		tree.rotateLeft(node.Parent)
	} else if nodeColor(sibling.Left) == red {
		sibling.Left.color = black
		tree.rotateRight(node.Parent)
	}
}

func nodeColor(node *Node) color {
	if node == nil {
		return black
	}
	return node.color
}

// Iterator holding the iterator's state
type Iterator struct {
	tree     *Tree
	node     *Node
	position position
}

type position byte

const (
	begin, between, end position = 0, 1, 2
)

// Iterator returns a stateful iterator whose elements are key/value pairs.
func (tree *Tree) Iterator(node *Node) *Iterator {
	return &Iterator{tree: tree, node: node, position: between}
}

// Next moves the iterator to the next element and returns true if there was a next element in the container.
// If Next() returns true, then next element's key and value can be retrieved by Key() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() *Iterator {
	if iterator.position == end {
		goto end
	}
	if iterator.position == begin {
		left := iterator.tree.Left()
		if left == nil {
			goto end
		}
		iterator.node = left
		goto between
	}
	if iterator.node.Right != nil {
		iterator.node = iterator.node.Right
		for iterator.node.Left != nil {
			iterator.node = iterator.node.Left
		}
		goto between
	}
	if iterator.node.Parent != nil {
		node := iterator.node
		for iterator.node.Parent != nil {
			iterator.node = iterator.node.Parent
			if iterator.tree.Comparator(node.Key, iterator.node.Key) <= 0 {
				goto between
			}
		}
	}

end:
	iterator.node = nil
	iterator.position = end
	return iterator

between:
	iterator.position = between
	return iterator
}

// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Prev() *Iterator {
	if iterator.position == begin {
		goto begin
	}
	if iterator.position == end {
		right := iterator.tree.Right()
		if right == nil {
			goto begin
		}
		iterator.node = right
		goto between
	}
	if iterator.node.Left != nil {
		iterator.node = iterator.node.Left
		for iterator.node.Right != nil {
			iterator.node = iterator.node.Right
		}
		goto between
	}
	if iterator.node.Parent != nil {
		node := iterator.node
		for iterator.node.Parent != nil {
			iterator.node = iterator.node.Parent
			if iterator.tree.Comparator(node.Key, iterator.node.Key) >= 0 {
				goto between
			}
		}
	}

begin:
	iterator.node = nil
	iterator.position = begin
	return iterator

between:
	iterator.position = between
	return iterator
}

// Key returns the current element's key.
// Does not modify the state of the iterator.
func (iterator *Iterator) Key() int {
	return iterator.node.Key
}

// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator
func (tree *Tree) First() *Iterator {
	it := &Iterator{tree, nil, begin}
	return it.Next()
}

// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
func (tree *Tree) Last() *Iterator {
	it := &Iterator{tree, nil, end}
	return it.Prev()
}

// github.com/EndlessCheng/codeforces-go
func Sol527C(reader io.Reader, writer io.Writer) {
	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	w, h, mw, mh := NewSet(), NewSet(), NewSet(), NewSet()

	var w0, h0, n int
	Fscan(in, &w0, &h0, &n)
	w.Put(0, 1)
	w.Put(w0, 1)
	h.Put(0, 1)
	h.Put(h0, 1)
	mw.Put(w0, 1)
	mh.Put(h0, 1)
	for ; n > 0; n-- {
		var op string
		var mid int
		Fscan(in, &op, &mid)
		if op[0] == 'H' {
			w, h = h, w
			mw, mh = mh, mw
		}

		o, _ := w.Floor(mid)
		it := w.Iterator(o)
		l := it.Key()
		r := it.Next().Key()
		mw.MultiRemove(r - l)
		mw.MultiPut(r - mid)
		mw.MultiPut(mid - l)
		w.Put(mid, 1)

		if op[0] == 'H' {
			w, h = h, w
			mw, mh = mh, mw
		}

		Fprintln(out, int64(mw.Last().Key())*int64(mh.Last().Key()))
	}
}

func main() {
	Sol527C(os.Stdin, os.Stdout)
}

package main

import (
	"bufio"
	"fmt"
	"os"
)

func I(i interface{}, delim string) error {
	_, err := fmt.Fscanf(r, "%v"+delim, i)
	return err
}

func O(o interface{}, delim string) {
	fmt.Fprintf(w, "%v"+delim, o)
}

var (
	r *bufio.Reader
	w *bufio.Writer
)

func init() {
	if f, err := os.Open("in.txt"); err == nil {
		r = bufio.NewReader(f)
	} else {
		r = bufio.NewReader(os.Stdin)
	}
	w = bufio.NewWriter(os.Stdout)
}

func main() {
	defer w.Flush()
	var x int
	for I(&x, " ") == nil {
		solve(x)
	}
}

var xx, yy []bool
var RX, RY, LX, LY []int

func solve(x int) {
	var y, n int
	I(&y, " ")
	I(&n, "\n")
	xx, yy = make([]bool, 200001), make([]bool, 200001)
	P := make([]int, n)
	RX = make([]int, 200001)
	RY = make([]int, 200001)
	LX = make([]int, 200001)
	LY = make([]int, 200001)
	S := make([]byte, n)
	for i := 0; i < n; i++ {
		var s string
		I(&s, " ")
		var o int
		I(&o, "\n")
		if s == "V" {
			xx[o] = true
		} else {
			yy[o] = true
		}
		P[i] = o
		S[i] = s[0]
	}
	maxx, maxy := oo(x, y)
	ans := []int64{}
	for i := len(P) - 1; i >= 0; i-- {
		ans = append(ans, int64(maxx)*int64(maxy))
		q := 0
		if S[i] == 'V' {
			LX[RX[P[i]]] = LX[P[i]]
			RX[LX[P[i]]] = RX[P[i]]
			q = LX[P[i]] - RX[P[i]]
			if q > maxx {
				maxx = q
			}
		} else {
			LY[RY[P[i]]] = LY[P[i]]
			RY[LY[P[i]]] = RY[P[i]]
			q = LY[P[i]] - RY[P[i]]
			if q > maxy {
				maxy = q
			}
		}
	}
	for i := len(ans) - 1; i >= 0; i-- {
		O(ans[i], "\n")
	}
}

func oo(x, y int) (int, int) {
	maxx := 1
	maxy := 1
	mx := 0
	my := 0
	rx := 0
	ry := 0
	for i := 1; i <= x; i++ {
		mx++
		if mx > maxx {
			maxx = mx
		}
		if xx[i] {
			RX[i] = rx
			LX[i] = x
			rx = i
			LX[RX[i]] = rx
			mx = 0
		}
	}
	for i := 1; i <= y; i++ {
		my++
		if my > maxy {
			maxy = my
		}
		if yy[i] {
			RY[i] = ry
			LY[i] = y
			ry = i
			LY[RY[i]] = ry
			my = 0
		}
	}
	return maxx, maxy
}

package main

import (
  "os"
  "bufio"
  "strconv"
  "fmt"
  "sort"
)

var scanner *bufio.Scanner

func getI64() int64 {
  scanner.Scan()
  x, _ := strconv.ParseInt(scanner.Text(), 10, 64)
  return x
}
func getI() int {
  return int(getI64())
}
func getS() string {
  scanner.Scan()
  return scanner.Text()
}

type Segment struct {
  Size int
  HeapPos int
}

type Cut struct {
  Left *Segment
  Prev, Next int
}

func insert(heap []*Segment, segment *Segment) []*Segment {
  heap = append(heap, segment)
  pos := len(heap)-1
  for pos != 0 {
    parentPos := (pos-1)/2
    if heap[parentPos].Size >= segment.Size {
      break
    }
    heap[parentPos], heap[pos] = heap[pos], heap[parentPos]
    heap[pos].HeapPos = pos
    pos = parentPos
  }
  segment.HeapPos = pos
  return heap
}

func delete(heap []*Segment, segment *Segment) []*Segment {
  pos := segment.HeapPos
  heap[pos] = heap[len(heap)-1]
  segment = heap[pos]
  heap = heap[:len(heap)-1]
  for {
    leftPos, rightPos := 2*pos+1, 2*pos+2
    if leftPos >= len(heap) {
      break
    }
    childPos := leftPos
    if rightPos < len(heap) && heap[rightPos].Size > heap[leftPos].Size {
      childPos = rightPos
    }
    if heap[childPos].Size <= segment.Size {
      break
    }
    heap[childPos], heap[pos] = heap[pos], heap[childPos]
    heap[pos].HeapPos = pos
    pos = childPos
  }
  segment.HeapPos = pos
  return heap
}

func main() {
  scanner = bufio.NewScanner(os.Stdin)
  scanner.Split(bufio.ScanWords)
  writer := bufio.NewWriter(os.Stdout)
  defer writer.Flush()

  w, h, n := getI(), getI(), getI()
  xs, ys := []int{}, []int{}
  input := make([]int, n)
  for i := 0; i < n; i++ {
    s, k := getS(), getI()
    if s == "H" {
      ys = append(ys, k)
      input[i] = -k
    } else {
      xs = append(xs, k)
      input[i] = k
    }
  }
  xs = append(xs, 0)
  xs = append(xs, w)
  ys = append(ys, 0)
  ys = append(ys, h)
  sort.Ints(xs)
  sort.Ints(ys)
  xCuts, yCuts := make([]*Cut, len(xs)), make([]*Cut, len(ys))
  xHeap, yHeap := []*Segment{}, []*Segment{}
  xCutPos, yCutPos := map[int]int{}, map[int]int{}
  previous := 0
  for i, x := range xs {
    left := &Segment{ Size: x-previous }
    xHeap = insert(xHeap, left)
    xCuts[i] = &Cut{ Left: left, Prev: i-1, Next: i+1 }
    previous = x
    xCutPos[x] = i
  }
  previous = 0
  for i, y := range ys {
    left := &Segment{ Size: y-previous }
    yHeap = insert(yHeap, left)
    yCuts[i] = &Cut{ Left: left, Prev: i-1, Next: i+1 }
    previous = y
    yCutPos[y] = i
  }
  results := make([]int64, n)
  for i := n-1; i >= 0; i-- {
    xMax, yMax := int64(xHeap[0].Size), int64(yHeap[0].Size)
    results[i] = xMax*yMax
    cut := input[i]
    if cut > 0 {
      pos := xCutPos[cut]
      thisCut := xCuts[pos]
      prevCut, nextCut := xCuts[thisCut.Prev], xCuts[thisCut.Next]
      prevCut.Next = thisCut.Next
      nextCut.Prev = thisCut.Prev
      leftSegment, rightSegment := thisCut.Left, nextCut.Left
      xHeap = delete(xHeap, leftSegment)
      xHeap = delete(xHeap, rightSegment)
      rightSegment.Size += leftSegment.Size
      xHeap = insert(xHeap, rightSegment)
    } else {
      cut = -cut
      pos := yCutPos[cut]
      thisCut := yCuts[pos]
      prevCut, nextCut := yCuts[thisCut.Prev], yCuts[thisCut.Next]
      prevCut.Next = thisCut.Next
      nextCut.Prev = thisCut.Prev
      leftSegment, rightSegment := thisCut.Left, nextCut.Left
      yHeap = delete(yHeap, leftSegment)
      yHeap = delete(yHeap, rightSegment)
      rightSegment.Size += leftSegment.Size
      yHeap = insert(yHeap, rightSegment)
    }
  }
  for _, result := range results {
    writer.WriteString(fmt.Sprintf("%d\n", result))
  }
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
	"time"
)

var _x = uint(time.Now().UnixNano())

func fastRand() uint {
	_x ^= _x << 13
	_x ^= _x >> 17
	_x ^= _x << 5
	return _x
}

type tNode struct {
	lr       [2]*tNode
	priority uint
	msz      int
	key      int
	value    int
}

func (o *tNode) pushUp() {
	msz := o.value
	if ol := o.lr[0]; ol != nil {
		msz += ol.msz
	}
	if or := o.lr[1]; or != nil {
		msz += or.msz
	}
	o.msz = msz
}

type treap struct {
	root       *tNode
	comparator func(a, b int) int
}

func newTreap() *treap {
	return &treap{comparator: func(a, b int) int {
		if a < b {
			return 0
		}
		if a > b {
			return 1
		}
		return -1
	}}
}

func (t *treap) rotate(o *tNode, d int) *tNode {
	x := o.lr[d^1]
	o.lr[d^1] = x.lr[d]
	x.lr[d] = o
	x.msz = o.msz
	o.pushUp()
	return x
}

func (t *treap) _put(o *tNode, key int) *tNode {
	if o == nil {
		return &tNode{priority: fastRand(), msz: 1, key: key, value: 1}
	}
	if cmp := t.comparator(key, o.key); cmp >= 0 {
		o.lr[cmp] = t._put(o.lr[cmp], key)
		if o.lr[cmp].priority > o.priority {
			o = t.rotate(o, cmp^1)
		}
	} else {
		o.value++
	}
	o.pushUp()
	return o
}

func (t *treap) put(key int) { t.root = t._put(t.root, key) }

func (t *treap) _delete(o *tNode, key int) *tNode {
	if o == nil {
		return nil
	}
	if cmp := t.comparator(key, o.key); cmp >= 0 {
		o.lr[cmp] = t._delete(o.lr[cmp], key)
	} else {
		if o.value > 1 {
			o.value--
		} else {
			if o.lr[1] == nil {
				return o.lr[0]
			}
			if o.lr[0] == nil {
				return o.lr[1]
			}
			cmp2 := 0
			if o.lr[0].priority > o.lr[1].priority {
				cmp2 = 1
			}
			o = t.rotate(o, cmp2)
			o.lr[cmp2] = t._delete(o.lr[cmp2], key)
		}
	}
	o.pushUp()
	return o
}

func (t *treap) delete(key int) { t.root = t._delete(t.root, key) }

func (t *treap) floor(key int) (floor *tNode) {
	for o := t.root; o != nil; {
		switch cmp := t.comparator(key, o.key); {
		case cmp == 0:
			o = o.lr[0]
		case cmp > 0:
			floor = o
			o = o.lr[1]
		default:
			return o
		}
	}
	return
}

func (t *treap) next(key int) (next *tNode) {
	for o := t.root; o != nil; {
		if cmp := t.comparator(key, o.key); cmp != 0 {
			o = o.lr[1]
		} else {
			next = o
			o = o.lr[0]
		}
	}
	return
}

func (t *treap) max() (max *tNode) {
	for o := t.root; o != nil; o = o.lr[1] {
		max = o
	}
	return
}

// github.com/EndlessCheng/codeforces-go
func Sol527CTreap(reader io.Reader, writer io.Writer) {
	cut := func(t, mt *treap, mid int) {
		o := t.floor(mid)
		l := o.key
		r := t.next(l).key
		mt.delete(r - l)
		mt.put(r - mid)
		mt.put(mid - l)
		t.put(mid)
	}

	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	w, h, mw, mh := newTreap(), newTreap(), newTreap(), newTreap()
	var w0, h0, n int
	Fscan(in, &w0, &h0, &n)
	w.put(0)
	w.put(w0)
	mw.put(w0)
	h.put(0)
	h.put(h0)
	mh.put(h0)
	for ; n > 0; n-- {
		var op string
		var mid int
		Fscan(in, &op, &mid)
		if op[0] == 'V' {
			cut(w, mw, mid)
		} else {
			cut(h, mh, mid)
		}
		Fprintln(out, int64(mw.max().key)*int64(mh.max().key))
	}
}

func main() {
	Sol527CTreap(os.Stdin, os.Stdout)
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
)

var _x527C = uint(1) // uint(time.Now().UnixNano())

func fastRand527C() uint {
	_x527C ^= _x527C << 13
	_x527C ^= _x527C >> 17
	_x527C ^= _x527C << 5
	return _x527C
}

type node527C struct {
	lr       [2]*node527C
	priority uint
	msz      int
	key      int
	value    int
}

func (o *node527C) pushUp() {
	msz := o.value
	if ol := o.lr[0]; ol != nil {
		msz += ol.msz
	}
	if or := o.lr[1]; or != nil {
		msz += or.msz
	}
	o.msz = msz
}

type treap527C struct {
	root       *node527C
	comparator func(a, b int) int
}

func newTreap527C() *treap527C {
	return &treap527C{comparator: func(a, b int) int {
		if a < b {
			return 0
		}
		if a > b {
			return 1
		}
		return -1
	}}
}

func (t *treap527C) rotate(o *node527C, d int) *node527C {
	x := o.lr[d^1]
	o.lr[d^1] = x.lr[d]
	x.lr[d] = o
	x.msz = o.msz
	o.pushUp()
	return x
}

func (t *treap527C) _put(o *node527C, key int) *node527C {
	if o == nil {
		return &node527C{priority: fastRand527C(), msz: 1, key: key, value: 1}
	}
	if cmp := t.comparator(key, o.key); cmp >= 0 {
		o.lr[cmp] = t._put(o.lr[cmp], key)
		if o.lr[cmp].priority > o.priority {
			o = t.rotate(o, cmp^1)
		}
	} else {
		o.value++
	}
	o.pushUp()
	return o
}

func (t *treap527C) put(key int) { t.root = t._put(t.root, key) }

func (t *treap527C) _delete(o *node527C, key int) *node527C {
	if o == nil {
		return nil
	}
	if cmp := t.comparator(key, o.key); cmp >= 0 {
		o.lr[cmp] = t._delete(o.lr[cmp], key)
	} else {
		if o.value > 1 {
			o.value--
		} else {
			if o.lr[1] == nil {
				return o.lr[0]
			}
			if o.lr[0] == nil {
				return o.lr[1]
			}
			cmp2 := 0
			if o.lr[0].priority > o.lr[1].priority {
				cmp2 = 1
			}
			o = t.rotate(o, cmp2)
			o.lr[cmp2] = t._delete(o.lr[cmp2], key)
		}
	}
	o.pushUp()
	return o
}

func (t *treap527C) delete(key int) { t.root = t._delete(t.root, key) }

func (t *treap527C) floor(key int) (floor *node527C) {
	for o := t.root; o != nil; {
		switch cmp := t.comparator(key, o.key); {
		case cmp == 0:
			o = o.lr[0]
		case cmp > 0:
			floor = o
			o = o.lr[1]
		default:
			return o
		}
	}
	return
}

func (t *treap527C) next(key int) (next *node527C) {
	for o := t.root; o != nil; {
		if cmp := t.comparator(key, o.key); cmp != 0 {
			o = o.lr[1]
		} else {
			next = o
			o = o.lr[0]
		}
	}
	return
}

func (t *treap527C) max() (max *node527C) {
	for o := t.root; o != nil; o = o.lr[1] {
		max = o
	}
	return
}

// github.com/EndlessCheng/codeforces-go
func Sol527CTreap(reader io.Reader, writer io.Writer) {
	cut := func(t, mt *treap527C, mid int) {
		o := t.floor(mid)
		l := o.key
		r := t.next(l).key
		mt.delete(r - l)
		mt.put(r - mid)
		mt.put(mid - l)
		t.put(mid)
	}

	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	w, h, mw, mh := newTreap527C(), newTreap527C(), newTreap527C(), newTreap527C()
	var w0, h0, n int
	Fscan(in, &w0, &h0, &n)
	w.put(0)
	w.put(w0)
	mw.put(w0)
	h.put(0)
	h.put(h0)
	mh.put(h0)
	for ; n > 0; n-- {
		var op string
		var mid int
		Fscan(in, &op, &mid)
		if op[0] == 'V' {
			cut(w, mw, mid)
		} else {
			cut(h, mh, mid)
		}
		Fprintln(out, int64(mw.max().key)*int64(mh.max().key))
	}
}

func main() {
	Sol527CTreap(os.Stdin, os.Stdout)
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
	"time"
)

var seed = uint(time.Now().UnixNano())

func fastRand() uint {
	seed ^= seed << 13
	seed ^= seed >> 17
	seed ^= seed << 5
	return seed
}

type tNode struct {
	lr       [2]*tNode
	priority uint
	msz      int
	key      int
	value    int
}

func (o *tNode) pushUp() {
	msz := o.value
	if ol := o.lr[0]; ol != nil {
		msz += ol.msz
	}
	if or := o.lr[1]; or != nil {
		msz += or.msz
	}
	o.msz = msz
}

type treap struct {
	root       *tNode
	comparator func(a, b int) int
}

func newTreap() *treap {
	return &treap{comparator: func(a, b int) int {
		if a < b {
			return 0
		}
		if a > b {
			return 1
		}
		return -1
	}}
}

func (t *treap) rotate(o *tNode, d int) *tNode {
	x := o.lr[d^1]
	o.lr[d^1] = x.lr[d]
	x.lr[d] = o
	x.msz = o.msz
	o.pushUp()
	return x
}

func (t *treap) _put(o *tNode, key int) *tNode {
	if o == nil {
		return &tNode{priority: fastRand(), msz: 1, key: key, value: 1}
	}
	if cmp := t.comparator(key, o.key); cmp >= 0 {
		o.lr[cmp] = t._put(o.lr[cmp], key)
		if o.lr[cmp].priority > o.priority {
			o = t.rotate(o, cmp^1)
		}
	} else {
		o.value++
	}
	o.pushUp()
	return o
}

func (t *treap) put(key int) { t.root = t._put(t.root, key) }

func (t *treap) _delete(o *tNode, key int) *tNode {
	if o == nil {
		return nil
	}
	if cmp := t.comparator(key, o.key); cmp >= 0 {
		o.lr[cmp] = t._delete(o.lr[cmp], key)
	} else {
		if o.value > 1 {
			o.value--
		} else {
			if o.lr[1] == nil {
				return o.lr[0]
			}
			if o.lr[0] == nil {
				return o.lr[1]
			}
			cmp2 := 0
			if o.lr[0].priority > o.lr[1].priority {
				cmp2 = 1
			}
			o = t.rotate(o, cmp2)
			o.lr[cmp2] = t._delete(o.lr[cmp2], key)
		}
	}
	o.pushUp()
	return o
}

func (t *treap) delete(key int) { t.root = t._delete(t.root, key) }

func (t *treap) floor(key int) (floor *tNode) {
	for o := t.root; o != nil; {
		switch cmp := t.comparator(key, o.key); {
		case cmp == 0:
			o = o.lr[0]
		case cmp > 0:
			floor = o
			o = o.lr[1]
		default:
			return o
		}
	}
	return
}

func (t *treap) next(key int) (next *tNode) {
	for o := t.root; o != nil; {
		if cmp := t.comparator(key, o.key); cmp != 0 {
			o = o.lr[1]
		} else {
			next = o
			o = o.lr[0]
		}
	}
	return
}

func (t *treap) max() (max *tNode) {
	for o := t.root; o != nil; o = o.lr[1] {
		max = o
	}
	return
}

// github.com/EndlessCheng/codeforces-go
func Sol527CTreap(reader io.Reader, writer io.Writer) {
	cut := func(t, mt *treap, mid int) {
		o := t.floor(mid)
		l := o.key
		r := t.next(l).key
		mt.delete(r - l)
		mt.put(r - mid)
		mt.put(mid - l)
		t.put(mid)
	}

	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	w, h, mw, mh := newTreap(), newTreap(), newTreap(), newTreap()
	var w0, h0, n int
	Fscan(in, &w0, &h0, &n)
	w.put(0)
	w.put(w0)
	mw.put(w0)
	h.put(0)
	h.put(h0)
	mh.put(h0)
	for ; n > 0; n-- {
		var op string
		var mid int
		Fscan(in, &op, &mid)
		if op[0] == 'V' {
			cut(w, mw, mid)
		} else {
			cut(h, mh, mid)
		}
		Fprintln(out, int64(mw.max().key)*int64(mh.max().key))
	}
}

func main() {
	Sol527CTreap(os.Stdin, os.Stdout)
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
)

type keyType int
type valueType int

var zeroValue valueType = 0

type Tree struct {
	Root       *Node
	size       int
	comparator func(a, b keyType) int
}

type color bool

const black, red color = true, false

type Node struct {
	Left   *Node
	Right  *Node
	Parent *Node
	Key    keyType
	Value  valueType
	color  color
}

func newRBTree() *Tree {
	return &Tree{comparator: func(a, b keyType) int {
		if a < b {
			return -1
		}
		if a > b {
			return 1
		}
		return 0
	}}
}

func (t *Tree) Insert(key keyType, value valueType) {
	var insertedNode *Node
	if t.Root == nil {
		t.Root = &Node{Key: key, Value: value, color: red}
		insertedNode = t.Root
	} else {
		node := t.Root
	loop:
		for {
			compare := t.comparator(key, node.Key)
			switch {
			case compare < 0:
				if node.Left == nil {
					node.Left = &Node{Key: key, Value: value, color: red}
					insertedNode = node.Left
					break loop
				} else {
					node = node.Left
				}
			case compare > 0:
				if node.Right == nil {
					node.Right = &Node{Key: key, Value: value, color: red}
					insertedNode = node.Right
					break loop
				} else {
					node = node.Right
				}
			default:
				node.Key = key
				node.Value = value
				return
			}
		}
		insertedNode.Parent = node
	}
	t.insertCase1(insertedNode)
	t.size++
}

func (t *Tree) Lookup(key keyType) *Node {
	for o := t.Root; o != nil; {
		compare := t.comparator(key, o.Key)
		switch {
		case compare < 0:
			o = o.Left
		case compare > 0:
			o = o.Right
		default:
			return o
		}
	}
	return nil
}

func (t *Tree) Erase(key keyType) {
	node := t.Lookup(key)
	if node == nil {
		return
	}
	if node.Left != nil && node.Right != nil {
		pred := node.Left.maximumNode()
		node.Key = pred.Key
		node.Value = pred.Value
		node = pred
	}
	if node.Left == nil || node.Right == nil {
		var child *Node
		if node.Right == nil {
			child = node.Left
		} else {
			child = node.Right
		}
		if node.color == black {
			node.color = nodeColor(child)
			t.deleteCase1(node)
		}
		t.replaceNode(node, child)
		if node.Parent == nil && child != nil {
			child.color = black
		}
	}
	t.size--
}

func (t *Tree) MultiInsert(key keyType) {
	if o := t.Lookup(key); o != nil {
		o.Value++
	} else {
		t.Insert(key, 1)
	}
}

func (t *Tree) MultiErase(key keyType) {
	if o := t.Lookup(key); o != nil {
		o.Value--
		if o.Value == 0 {
			t.Erase(key)
		}
	}
}

// Floor Finds floor node of the input key, return the floor node or nil if no floor is found.
//
// Floor node is defined as the largest node that is smaller than or equal to the given node.
// A floor node may not be found, either because the tree is empty, or because
// all nodes in the tree are larger than the given node.
func (t *Tree) Floor(key keyType) (floor *Node) {
	for o := t.Root; o != nil; {
		compare := t.comparator(key, o.Key)
		switch {
		case compare < 0:
			o = o.Left
		case compare > 0:
			floor = o
			o = o.Right
		default:
			return o
		}
	}
	return
}

func (node *Node) grandparent() *Node {
	if node != nil && node.Parent != nil {
		return node.Parent.Parent
	}
	return nil
}

func (node *Node) uncle() *Node {
	if node == nil || node.Parent == nil || node.Parent.Parent == nil {
		return nil
	}
	return node.Parent.sibling()
}

func (node *Node) sibling() *Node {
	if node == nil || node.Parent == nil {
		return nil
	}
	if node == node.Parent.Left {
		return node.Parent.Right
	}
	return node.Parent.Left
}

func (t *Tree) rotateLeft(node *Node) {
	right := node.Right
	t.replaceNode(node, right)
	node.Right = right.Left
	if right.Left != nil {
		right.Left.Parent = node
	}
	right.Left = node
	node.Parent = right
}

func (t *Tree) rotateRight(node *Node) {
	left := node.Left
	t.replaceNode(node, left)
	node.Left = left.Right
	if left.Right != nil {
		left.Right.Parent = node
	}
	left.Right = node
	node.Parent = left
}

func (t *Tree) replaceNode(old *Node, new *Node) {
	if old.Parent == nil {
		t.Root = new
	} else {
		if old == old.Parent.Left {
			old.Parent.Left = new
		} else {
			old.Parent.Right = new
		}
	}
	if new != nil {
		new.Parent = old.Parent
	}
}

func (t *Tree) insertCase1(node *Node) {
	if node.Parent == nil {
		node.color = black
	} else {
		t.insertCase2(node)
	}
}

func (t *Tree) insertCase2(node *Node) {
	if nodeColor(node.Parent) == black {
		return
	}
	t.insertCase3(node)
}

func (t *Tree) insertCase3(node *Node) {
	uncle := node.uncle()
	if nodeColor(uncle) == red {
		node.Parent.color = black
		uncle.color = black
		node.grandparent().color = red
		t.insertCase1(node.grandparent())
	} else {
		t.insertCase4(node)
	}
}

func (t *Tree) insertCase4(node *Node) {
	grandparent := node.grandparent()
	if node == node.Parent.Right && node.Parent == grandparent.Left {
		t.rotateLeft(node.Parent)
		node = node.Left
	} else if node == node.Parent.Left && node.Parent == grandparent.Right {
		t.rotateRight(node.Parent)
		node = node.Right
	}
	t.insertCase5(node)
}

func (t *Tree) insertCase5(node *Node) {
	node.Parent.color = black
	grandparent := node.grandparent()
	grandparent.color = red
	if node == node.Parent.Left && node.Parent == grandparent.Left {
		t.rotateRight(grandparent)
	} else if node == node.Parent.Right && node.Parent == grandparent.Right {
		t.rotateLeft(grandparent)
	}
}

func (node *Node) maximumNode() *Node {
	if node == nil {
		return nil
	}
	for node.Right != nil {
		node = node.Right
	}
	return node
}

func (t *Tree) deleteCase1(node *Node) {
	if node.Parent == nil {
		return
	}
	t.deleteCase2(node)
}

func (t *Tree) deleteCase2(node *Node) {
	sibling := node.sibling()
	if nodeColor(sibling) == red {
		node.Parent.color = red
		sibling.color = black
		if node == node.Parent.Left {
			t.rotateLeft(node.Parent)
		} else {
			t.rotateRight(node.Parent)
		}
	}
	t.deleteCase3(node)
}

func (t *Tree) deleteCase3(node *Node) {
	sibling := node.sibling()
	if nodeColor(node.Parent) == black &&
		nodeColor(sibling) == black &&
		nodeColor(sibling.Left) == black &&
		nodeColor(sibling.Right) == black {
		sibling.color = red
		t.deleteCase1(node.Parent)
	} else {
		t.deleteCase4(node)
	}
}

func (t *Tree) deleteCase4(node *Node) {
	sibling := node.sibling()
	if nodeColor(node.Parent) == red &&
		nodeColor(sibling) == black &&
		nodeColor(sibling.Left) == black &&
		nodeColor(sibling.Right) == black {
		sibling.color = red
		node.Parent.color = black
	} else {
		t.deleteCase5(node)
	}
}

func (t *Tree) deleteCase5(node *Node) {
	sibling := node.sibling()
	if node == node.Parent.Left &&
		nodeColor(sibling) == black &&
		nodeColor(sibling.Left) == red &&
		nodeColor(sibling.Right) == black {
		sibling.color = red
		sibling.Left.color = black
		t.rotateRight(sibling)
	} else if node == node.Parent.Right &&
		nodeColor(sibling) == black &&
		nodeColor(sibling.Right) == red &&
		nodeColor(sibling.Left) == black {
		sibling.color = red
		sibling.Right.color = black
		t.rotateLeft(sibling)
	}
	t.deleteCase6(node)
}

func (t *Tree) deleteCase6(node *Node) {
	sibling := node.sibling()
	sibling.color = nodeColor(node.Parent)
	node.Parent.color = black
	if node == node.Parent.Left && nodeColor(sibling.Right) == red {
		sibling.Right.color = black
		t.rotateLeft(node.Parent)
	} else if nodeColor(sibling.Left) == red {
		sibling.Left.color = black
		t.rotateRight(node.Parent)
	}
}

func nodeColor(node *Node) color {
	if node == nil {
		return black
	}
	return node.color
}

type position byte

const begin, between, end position = 0, 1, 2

// Iterator holding the iterator's state
type Iterator struct {
	tree     *Tree
	node     *Node
	position position
}

// Iterator returns a stateful iterator whose elements are key/value pairs.
func (t *Tree) NewIterator(node *Node) *Iterator {
	return &Iterator{tree: t, node: node, position: between}
}

// Min returns the left-most (min) node or nil if tree is empty.
func (t *Tree) Min() (min *Node) {
	for o := t.Root; o != nil; o = o.Left {
		min = o
	}
	return
}

// Max returns the right-most (max) node or nil if tree is empty.
func (t *Tree) Max() (max *Node) {
	for o := t.Root; o != nil; o = o.Right {
		max = o
	}
	return
}

// Next moves the iterator to the next element and returns itself.
// Modifies the state of the iterator.
func (it *Iterator) Next() *Iterator {
	if it.position == end {
		goto end
	}
	if it.position == begin {
		left := it.tree.Min()
		if left == nil {
			goto end
		}
		it.node = left
		goto between
	}
	if it.node.Right != nil {
		it.node = it.node.Right
		for it.node.Left != nil {
			it.node = it.node.Left
		}
		goto between
	}
	if it.node.Parent != nil {
		node := it.node
		for it.node.Parent != nil {
			it.node = it.node.Parent
			if it.tree.comparator(node.Key, it.node.Key) <= 0 {
				goto between
			}
		}
	}

end:
	it.node = nil
	it.position = end
	return it

between:
	it.position = between
	return it
}

// github.com/EndlessCheng/codeforces-go
func Sol527C(reader io.Reader, writer io.Writer) {
	cut := func(t, mt *Tree, mid keyType) {
		it := t.NewIterator(t.Floor(mid))
		l := it.node.Key
		r := it.Next().node.Key
		mt.MultiErase(r - l)
		mt.MultiInsert(r - mid)
		mt.MultiInsert(mid - l)
		t.Insert(mid, 1)
	}

	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	w, h, mw, mh := newRBTree(), newRBTree(), newRBTree(), newRBTree()
	var w0, h0 keyType
	var n int
	Fscan(in, &w0, &h0, &n)
	w.Insert(0, 1)
	w.Insert(w0, 1)
	mw.MultiInsert(w0)
	h.Insert(0, 1)
	h.Insert(h0, 1)
	mh.MultiInsert(h0)
	for ; n > 0; n-- {
		var op string
		var mid keyType
		Fscan(in, &op, &mid)
		if op[0] == 'V' {
			cut(w, mw, mid)
		} else {
			cut(h, mh, mid)
		}
		Fprintln(out, int64(mw.Max().Key)*int64(mh.Max().Key))
	}
}

func main() {
	Sol527C(os.Stdin, os.Stdout)
}

package main

import (
	"bufio"
	"io"
	"os"
	. "fmt"
)

type color bool

const black, red color = true, false

// Tree holds elements of the red-black tree
type Tree struct {
	Root       *Node
	size       int
	Comparator func(int, int) int
}

// Node is a single element within the tree
type Node struct {
	Key    int
	Value  int
	color  color
	Left   *Node
	Right  *Node
	Parent *Node
}

func NewSet() *Tree {
	return &Tree{Comparator: func(x int, y int) int {
		if x > y {
			return 1
		}
		if x < y {
			return -1
		}
		return 0
	}}
}

// Put inserts node into the tree.
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (tree *Tree) Put(key, value int) {
	var insertedNode *Node
	if tree.Root == nil {
		// Assert key is of comparator's type for initial tree
		tree.Comparator(key, key)
		tree.Root = &Node{Key: key, Value: value, color: red}
		insertedNode = tree.Root
	} else {
		node := tree.Root
		loop := true
		for loop {
			compare := tree.Comparator(key, node.Key)
			switch {
			case compare == 0:
				node.Key = key
				node.Value = value
				return
			case compare < 0:
				if node.Left == nil {
					node.Left = &Node{Key: key, Value: value, color: red}
					insertedNode = node.Left
					loop = false
				} else {
					node = node.Left
				}
			case compare > 0:
				if node.Right == nil {
					node.Right = &Node{Key: key, Value: value, color: red}
					insertedNode = node.Right
					loop = false
				} else {
					node = node.Right
				}
			}
		}
		insertedNode.Parent = node
	}
	tree.insertCase1(insertedNode)
	tree.size++
}

// Remove remove the node from the tree by key.
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (tree *Tree) Remove(key int) {
	var child *Node
	node := tree.lookup(key)
	if node == nil {
		return
	}
	if node.Left != nil && node.Right != nil {
		pred := node.Left.maximumNode()
		node.Key = pred.Key
		node.Value = pred.Value
		node = pred
	}
	if node.Left == nil || node.Right == nil {
		if node.Right == nil {
			child = node.Left
		} else {
			child = node.Right
		}
		if node.color == black {
			node.color = nodeColor(child)
			tree.deleteCase1(node)
		}
		tree.replaceNode(node, child)
		if node.Parent == nil && child != nil {
			child.color = black
		}
	}
	tree.size--
}

func (tree *Tree) MultiPut(key int) {
	if o := tree.lookup(key); o != nil {
		o.Value++
	} else {
		tree.Put(key, 1)
	}
}

func (tree *Tree) MultiRemove(key int) {
	if o := tree.lookup(key); o != nil {
		o.Value--
		if o.Value == 0 {
			tree.Remove(key)
		}
	}
}

// Left returns the left-most (min) node or nil if tree is empty.
func (tree *Tree) Left() (o *Node) {
	for current := tree.Root; current != nil; current = current.Left {
		o = current
	}
	return
}

// Right returns the right-most (max) node or nil if tree is empty.
func (tree *Tree) Right() (o *Node) {
	for current := tree.Root; current != nil; current = current.Right {
		o = current
	}
	return
}

// Floor Finds floor node of the input key, return the floor node or nil if no floor is found.
// Second return parameter is true if floor was found, otherwise false.
//
// Floor node is defined as the largest node that is smaller than or equal to the given node.
// A floor node may not be found, either because the tree is empty, or because
// all nodes in the tree are larger than the given node.
func (tree *Tree) Floor(key int) (floor *Node, found bool) {
	for node := tree.Root; node != nil; {
		compare := tree.Comparator(key, node.Key)
		switch {
		case compare == 0:
			return node, true
		case compare < 0:
			node = node.Left
		case compare > 0:
			floor, found = node, true
			node = node.Right
		}
	}
	return
}

// Ceiling finds ceiling node of the input key, return the ceiling node or nil if no ceiling is found.
// Second return parameter is true if ceiling was found, otherwise false.
//
// Ceiling node is defined as the smallest node that is larger than or equal to the given node.
// A ceiling node may not be found, either because the tree is empty, or because
// all nodes in the tree are smaller than the given node.
func (tree *Tree) Ceiling(key int) (ceiling *Node, found bool) {
	for node := tree.Root; node != nil; {
		compare := tree.Comparator(key, node.Key)
		switch {
		case compare == 0:
			return node, true
		case compare < 0:
			ceiling, found = node, true
			node = node.Left
		case compare > 0:
			node = node.Right
		}
	}
	return
}

func (tree *Tree) lookup(key int) *Node {
	node := tree.Root
	for node != nil {
		compare := tree.Comparator(key, node.Key)
		switch {
		case compare == 0:
			return node
		case compare < 0:
			node = node.Left
		case compare > 0:
			node = node.Right
		}
	}
	return nil
}

func (node *Node) grandparent() *Node {
	if node != nil && node.Parent != nil {
		return node.Parent.Parent
	}
	return nil
}

func (node *Node) uncle() *Node {
	if node == nil || node.Parent == nil || node.Parent.Parent == nil {
		return nil
	}
	return node.Parent.sibling()
}

func (node *Node) sibling() *Node {
	if node == nil || node.Parent == nil {
		return nil
	}
	if node == node.Parent.Left {
		return node.Parent.Right
	}
	return node.Parent.Left
}

func (tree *Tree) rotateLeft(node *Node) {
	right := node.Right
	tree.replaceNode(node, right)
	node.Right = right.Left
	if right.Left != nil {
		right.Left.Parent = node
	}
	right.Left = node
	node.Parent = right
}

func (tree *Tree) rotateRight(node *Node) {
	left := node.Left
	tree.replaceNode(node, left)
	node.Left = left.Right
	if left.Right != nil {
		left.Right.Parent = node
	}
	left.Right = node
	node.Parent = left
}

func (tree *Tree) replaceNode(old *Node, new *Node) {
	if old.Parent == nil {
		tree.Root = new
	} else {
		if old == old.Parent.Left {
			old.Parent.Left = new
		} else {
			old.Parent.Right = new
		}
	}
	if new != nil {
		new.Parent = old.Parent
	}
}

func (tree *Tree) insertCase1(node *Node) {
	if node.Parent == nil {
		node.color = black
	} else {
		tree.insertCase2(node)
	}
}

func (tree *Tree) insertCase2(node *Node) {
	if nodeColor(node.Parent) == black {
		return
	}
	tree.insertCase3(node)
}

func (tree *Tree) insertCase3(node *Node) {
	uncle := node.uncle()
	if nodeColor(uncle) == red {
		node.Parent.color = black
		uncle.color = black
		node.grandparent().color = red
		tree.insertCase1(node.grandparent())
	} else {
		tree.insertCase4(node)
	}
}

func (tree *Tree) insertCase4(node *Node) {
	grandparent := node.grandparent()
	if node == node.Parent.Right && node.Parent == grandparent.Left {
		tree.rotateLeft(node.Parent)
		node = node.Left
	} else if node == node.Parent.Left && node.Parent == grandparent.Right {
		tree.rotateRight(node.Parent)
		node = node.Right
	}
	tree.insertCase5(node)
}

func (tree *Tree) insertCase5(node *Node) {
	node.Parent.color = black
	grandparent := node.grandparent()
	grandparent.color = red
	if node == node.Parent.Left && node.Parent == grandparent.Left {
		tree.rotateRight(grandparent)
	} else if node == node.Parent.Right && node.Parent == grandparent.Right {
		tree.rotateLeft(grandparent)
	}
}

func (node *Node) maximumNode() *Node {
	if node == nil {
		return nil
	}
	for node.Right != nil {
		node = node.Right
	}
	return node
}

func (tree *Tree) deleteCase1(node *Node) {
	if node.Parent == nil {
		return
	}
	tree.deleteCase2(node)
}

func (tree *Tree) deleteCase2(node *Node) {
	sibling := node.sibling()
	if nodeColor(sibling) == red {
		node.Parent.color = red
		sibling.color = black
		if node == node.Parent.Left {
			tree.rotateLeft(node.Parent)
		} else {
			tree.rotateRight(node.Parent)
		}
	}
	tree.deleteCase3(node)
}

func (tree *Tree) deleteCase3(node *Node) {
	sibling := node.sibling()
	if nodeColor(node.Parent) == black &&
		nodeColor(sibling) == black &&
		nodeColor(sibling.Left) == black &&
		nodeColor(sibling.Right) == black {
		sibling.color = red
		tree.deleteCase1(node.Parent)
	} else {
		tree.deleteCase4(node)
	}
}

func (tree *Tree) deleteCase4(node *Node) {
	sibling := node.sibling()
	if nodeColor(node.Parent) == red &&
		nodeColor(sibling) == black &&
		nodeColor(sibling.Left) == black &&
		nodeColor(sibling.Right) == black {
		sibling.color = red
		node.Parent.color = black
	} else {
		tree.deleteCase5(node)
	}
}

func (tree *Tree) deleteCase5(node *Node) {
	sibling := node.sibling()
	if node == node.Parent.Left &&
		nodeColor(sibling) == black &&
		nodeColor(sibling.Left) == red &&
		nodeColor(sibling.Right) == black {
		sibling.color = red
		sibling.Left.color = black
		tree.rotateRight(sibling)
	} else if node == node.Parent.Right &&
		nodeColor(sibling) == black &&
		nodeColor(sibling.Right) == red &&
		nodeColor(sibling.Left) == black {
		sibling.color = red
		sibling.Right.color = black
		tree.rotateLeft(sibling)
	}
	tree.deleteCase6(node)
}

func (tree *Tree) deleteCase6(node *Node) {
	sibling := node.sibling()
	sibling.color = nodeColor(node.Parent)
	node.Parent.color = black
	if node == node.Parent.Left && nodeColor(sibling.Right) == red {
		sibling.Right.color = black
		tree.rotateLeft(node.Parent)
	} else if nodeColor(sibling.Left) == red {
		sibling.Left.color = black
		tree.rotateRight(node.Parent)
	}
}

func nodeColor(node *Node) color {
	if node == nil {
		return black
	}
	return node.color
}

// Iterator holding the iterator's state
type Iterator struct {
	tree     *Tree
	node     *Node
	position position
}

type position byte

const (
	begin, between, end position = 0, 1, 2
)

// Iterator returns a stateful iterator whose elements are key/value pairs.
func (tree *Tree) Iterator(node *Node) *Iterator {
	return &Iterator{tree: tree, node: node, position: between}
}

// Next moves the iterator to the next element and returns true if there was a next element in the container.
// If Next() returns true, then next element's key and value can be retrieved by Key() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() *Iterator {
	if iterator.position == end {
		goto end
	}
	if iterator.position == begin {
		left := iterator.tree.Left()
		if left == nil {
			goto end
		}
		iterator.node = left
		goto between
	}
	if iterator.node.Right != nil {
		iterator.node = iterator.node.Right
		for iterator.node.Left != nil {
			iterator.node = iterator.node.Left
		}
		goto between
	}
	if iterator.node.Parent != nil {
		node := iterator.node
		for iterator.node.Parent != nil {
			iterator.node = iterator.node.Parent
			if iterator.tree.Comparator(node.Key, iterator.node.Key) <= 0 {
				goto between
			}
		}
	}

end:
	iterator.node = nil
	iterator.position = end
	return iterator

between:
	iterator.position = between
	return iterator
}

// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Prev() *Iterator {
	if iterator.position == begin {
		goto begin
	}
	if iterator.position == end {
		right := iterator.tree.Right()
		if right == nil {
			goto begin
		}
		iterator.node = right
		goto between
	}
	if iterator.node.Left != nil {
		iterator.node = iterator.node.Left
		for iterator.node.Right != nil {
			iterator.node = iterator.node.Right
		}
		goto between
	}
	if iterator.node.Parent != nil {
		node := iterator.node
		for iterator.node.Parent != nil {
			iterator.node = iterator.node.Parent
			if iterator.tree.Comparator(node.Key, iterator.node.Key) >= 0 {
				goto between
			}
		}
	}

begin:
	iterator.node = nil
	iterator.position = begin
	return iterator

between:
	iterator.position = between
	return iterator
}

// Key returns the current element's key.
// Does not modify the state of the iterator.
func (iterator *Iterator) Key() int {
	return iterator.node.Key
}

// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator
func (tree *Tree) First() *Iterator {
	it := &Iterator{tree, nil, begin}
	return it.Next()
}

// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
func (tree *Tree) Last() *Iterator {
	it := &Iterator{tree, nil, end}
	return it.Prev()
}

// github.com/EndlessCheng/codeforces-go
func Sol527C(reader io.Reader, writer io.Writer) {
	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	w, h, mw, mh := NewSet(), NewSet(), NewSet(), NewSet()

	var w0, h0, n int
	Fscan(in, &w0, &h0, &n)
	w.Put(0, 1)
	w.Put(w0, 1)
	h.Put(0, 1)
	h.Put(h0, 1)
	mw.Put(w0, 1)
	mh.Put(h0, 1)
	for ; n > 0; n-- {
		var op string
		var mid int
		Fscan(in, &op, &mid)
		if op[0] == 'H' {
			w, h = h, w
			mw, mh = mh, mw
		}

		w.Put(mid, 1)
		o := w.lookup(mid)
		l := w.Iterator(o).Prev().Key()
		r := w.Iterator(o).Next().Key()
		mw.MultiRemove(r - l)
		mw.MultiPut(r - mid)
		mw.MultiPut(mid - l)

		if op[0] == 'H' {
			w, h = h, w
			mw, mh = mh, mw
		}

		Fprintln(out, int64(mw.Last().Key())*int64(mh.Last().Key()))
	}
}

func main() {
	Sol527C(os.Stdin, os.Stdout)
}

package main

import (
	"bufio"
	"io"
	"os"
	"time"
	. "fmt"
)

var x = uint(time.Now().UnixNano())

func fastRand() uint {
	x ^= x << 13
	x ^= x >> 17
	x ^= x << 5
	return x
}

type tNode struct {
	lr       [2]*tNode
	priority uint
	msz      int
	key      int
	value    int
}

func (o *tNode) mSize() int {
	if o != nil {
		return o.msz
	}
	return 0
}

func (o *tNode) maintain() {
	msz := o.value
	if ol := o.lr[0]; ol != nil {
		msz += ol.msz
	}
	if or := o.lr[1]; or != nil {
		msz += or.msz
	}
	o.msz = msz
}

type treap struct {
	root       *tNode
	comparator func(a, b int) int
}

func newTreap() *treap {
	return &treap{comparator: func(a, b int) int {
		if a < b {
			return 0
		}
		if a > b {
			return 1
		}
		return -1
	}}
}

func (t *treap) rotate(o *tNode, d int) *tNode {
	x := o.lr[d^1]
	o.lr[d^1] = x.lr[d]
	x.lr[d] = o
	x.msz = o.msz
	o.maintain()
	return x
}

func (t *treap) _put(o *tNode, key int) *tNode {
	if o == nil {
		return &tNode{priority: fastRand(), msz: 1, key: key, value: 1}
	}
	if cmp := t.comparator(key, o.key); cmp >= 0 {
		o.lr[cmp] = t._put(o.lr[cmp], key)
		if o.lr[cmp].priority > o.priority {
			o = t.rotate(o, cmp^1)
		}
	} else {
		o.value++
	}
	o.maintain()
	return o
}

func (t *treap) put(key int) { t.root = t._put(t.root, key) }

func (t *treap) get(key int) *tNode {
	for o := t.root; o != nil; {
		if cmp := t.comparator(key, o.key); cmp >= 0 {
			o = o.lr[cmp]
		} else {
			return o
		}
	}
	return nil
}

func (t *treap) _delete(o *tNode, key int) *tNode {
	if o == nil {
		return nil
	}
	if cmp := t.comparator(key, o.key); cmp >= 0 {
		o.lr[cmp] = t._delete(o.lr[cmp], key)
	} else {
		if o.value > 1 {
			o.value--
		} else {
			if o.lr[1] == nil {
				return o.lr[0]
			}
			if o.lr[0] == nil {
				return o.lr[1]
			}
			cmp2 := 0
			if o.lr[0].priority > o.lr[1].priority {
				cmp2 = 1
			}
			o = t.rotate(o, cmp2)
			o.lr[cmp2] = t._delete(o.lr[cmp2], key)
		}
	}
	o.maintain()
	return o
}

func (t *treap) delete(key int) { t.root = t._delete(t.root, key) }

func (t *treap) floor(key int) (floor *tNode) {
	for o := t.root; o != nil; {
		switch cmp := t.comparator(key, o.key); {
		case cmp == 0:
			o = o.lr[0]
		case cmp > 0:
			floor = o
			o = o.lr[1]
		default:
			return o
		}
	}
	return
}

func (t *treap) mRank(key int) (cnt int, o *tNode) {
	for o = t.root; o != nil; {
		switch cmp := t.comparator(key, o.key); {
		case cmp == 0:
			o = o.lr[0]
		case cmp > 0:
			cnt += o.value + o.lr[0].mSize()
			o = o.lr[1]
		default:
			cnt += o.lr[0].mSize()
			return
		}
	}
	return
}

func (t *treap) mSelect(k int) (o *tNode) {
	for o = t.root; o != nil; {
		switch ls := o.lr[0].mSize(); {
		case k < ls:
			o = o.lr[0]
		case k > ls:
			k -= o.value + ls
			if k < 0 {
				return
			}
			o = o.lr[1]
		default:
			return
		}
	}
	return
}

func (t *treap) next(key int) *tNode {
	rank, o := t.mRank(key)
	if o != nil {
		rank += o.value
	}
	return t.mSelect(rank)
}

func (t *treap) max() (max *tNode) {
	for o := t.root; o != nil; o = o.lr[1] {
		max = o
	}
	return
}

// github.com/EndlessCheng/codeforces-go
func Sol527CTreap(reader io.Reader, writer io.Writer) {
	cut := func(t, mt *treap, mid int) {
		o := t.floor(mid)
		l := o.key
		r := t.next(l).key
		mt.delete(r - l)
		mt.put(r - mid)
		mt.put(mid - l)
		t.put(mid)
	}

	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	w, h, mw, mh := newTreap(), newTreap(), newTreap(), newTreap()
	var w0, h0, n int
	Fscan(in, &w0, &h0, &n)
	w.put(0)
	w.put(w0)
	mw.put(w0)
	h.put(0)
	h.put(h0)
	mh.put(h0)
	for ; n > 0; n-- {
		var op string
		var mid int
		Fscan(in, &op, &mid)
		if op[0] == 'V' {
			cut(w, mw, mid)
		} else {
			cut(h, mh, mid)
		}
		Fprintln(out, int64(mw.max().key)*int64(mh.max().key))
	}
}

func main() {
	Sol527CTreap(os.Stdin, os.Stdout)
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
	"time"
)

var seed = uint32(time.Now().UnixNano())

func fastRand() uint {
	x := seed
	x ^= x << 13
	x ^= x >> 17
	x ^= x << 5
	seed = x
	return uint(x)
}

type tNode struct {
	lr       [2]*tNode
	priority uint
	msz      int
	key      int
	value    int
}

func (o *tNode) mSize() int {
	if o != nil {
		return o.msz
	}
	return 0
}

func (o *tNode) maintain() {
	msz := o.value
	if ol := o.lr[0]; ol != nil {
		msz += ol.msz
	}
	if or := o.lr[1]; or != nil {
		msz += or.msz
	}
	o.msz = msz
}

type treap struct {
	root       *tNode
	comparator func(a, b int) int
}

func newTreap() *treap {
	return &treap{comparator: func(a, b int) int {
		if a < b {
			return 0
		}
		if a > b {
			return 1
		}
		return -1
	}}
}

func (t *treap) rotate(o *tNode, d int) *tNode {
	x := o.lr[d^1]
	o.lr[d^1] = x.lr[d]
	x.lr[d] = o
	x.msz = o.msz
	o.maintain()
	return x
}

func (t *treap) _put(o *tNode, key int) *tNode {
	if o == nil {
		return &tNode{priority: fastRand(), msz: 1, key: key, value: 1}
	}
	if cmp := t.comparator(key, o.key); cmp >= 0 {
		o.lr[cmp] = t._put(o.lr[cmp], key)
		if o.lr[cmp].priority > o.priority {
			o = t.rotate(o, cmp^1)
		}
	} else {
		o.value++
	}
	o.maintain()
	return o
}

func (t *treap) put(key int) { t.root = t._put(t.root, key) }

func (t *treap) get(key int) *tNode {
	for o := t.root; o != nil; {
		if cmp := t.comparator(key, o.key); cmp >= 0 {
			o = o.lr[cmp]
		} else {
			return o
		}
	}
	return nil
}

func (t *treap) _delete(o *tNode, key int) *tNode {
	if o == nil {
		return nil
	}
	if cmp := t.comparator(key, o.key); cmp >= 0 {
		o.lr[cmp] = t._delete(o.lr[cmp], key)
	} else {
		if o.value > 1 {
			o.value--
		} else {
			if o.lr[1] == nil {
				return o.lr[0]
			}
			if o.lr[0] == nil {
				return o.lr[1]
			}
			cmp2 := 0
			if o.lr[0].priority > o.lr[1].priority {
				cmp2 = 1
			}
			o = t.rotate(o, cmp2)
			o.lr[cmp2] = t._delete(o.lr[cmp2], key)
		}
	}
	o.maintain()
	return o
}

func (t *treap) delete(key int) { t.root = t._delete(t.root, key) }

func (t *treap) floor(key int) (floor *tNode) {
	for o := t.root; o != nil; {
		switch cmp := t.comparator(key, o.key); {
		case cmp == 0:
			o = o.lr[0]
		case cmp > 0:
			floor = o
			o = o.lr[1]
		default:
			return o
		}
	}
	return
}

func (t *treap) mRank(key int) (cnt int, o *tNode) {
	for o = t.root; o != nil; {
		switch cmp := t.comparator(key, o.key); {
		case cmp == 0:
			o = o.lr[0]
		case cmp > 0:
			cnt += o.value + o.lr[0].mSize()
			o = o.lr[1]
		default:
			cnt += o.lr[0].mSize()
			return
		}
	}
	return
}

func (t *treap) mSelect(k int) (o *tNode) {
	for o = t.root; o != nil; {
		switch ls := o.lr[0].mSize(); {
		case k < ls:
			o = o.lr[0]
		case k > ls:
			k -= o.value + ls
			if k < 0 {
				return
			}
			o = o.lr[1]
		default:
			return
		}
	}
	return
}

func (t *treap) next(key int) *tNode {
	rank, o := t.mRank(key)
	if o != nil {
		rank += o.value
	}
	return t.mSelect(rank)
}

func (t *treap) max() (max *tNode) {
	for o := t.root; o != nil; o = o.lr[1] {
		max = o
	}
	return
}

// github.com/EndlessCheng/codeforces-go
func Sol527CTreap(reader io.Reader, writer io.Writer) {
	cut := func(t, mt *treap, mid int) {
		o := t.floor(mid)
		l := o.key
		r := t.next(l).key
		mt.delete(r - l)
		mt.put(r - mid)
		mt.put(mid - l)
		t.put(mid)
	}

	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	w, h, mw, mh := newTreap(), newTreap(), newTreap(), newTreap()
	var w0, h0, n int
	Fscan(in, &w0, &h0, &n)
	w.put(0)
	w.put(w0)
	mw.put(w0)
	h.put(0)
	h.put(h0)
	mh.put(h0)
	for ; n > 0; n-- {
		var op string
		var mid int
		Fscan(in, &op, &mid)
		if op[0] == 'V' {
			cut(w, mw, mid)
		} else {
			cut(h, mh, mid)
		}
		Fprintln(out, int64(mw.max().key)*int64(mh.max().key))
	}
}

func main() {
	Sol527CTreap(os.Stdin, os.Stdout)
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
	"time"
)

var x = uint(time.Now().UnixNano())

func fastRand() uint {
	x ^= x << 13
	x ^= x >> 17
	x ^= x << 5
	return x
}

type tNode struct {
	lr       [2]*tNode
	priority uint
	msz      int
	key      int
	value    int
}

func (o *tNode) mSize() int {
	if o != nil {
		return o.msz
	}
	return 0
}

func (o *tNode) maintain() {
	msz := o.value
	if ol := o.lr[0]; ol != nil {
		msz += ol.msz
	}
	if or := o.lr[1]; or != nil {
		msz += or.msz
	}
	o.msz = msz
}

type treap struct {
	root       *tNode
	comparator func(a, b int) int
}

func newTreap() *treap {
	return &treap{comparator: func(a, b int) int {
		if a < b {
			return 0
		}
		if a > b {
			return 1
		}
		return -1
	}}
}

func (t *treap) rotate(o *tNode, d int) *tNode {
	x := o.lr[d^1]
	o.lr[d^1] = x.lr[d]
	x.lr[d] = o
	x.msz = o.msz
	o.maintain()
	return x
}

func (t *treap) _put(o *tNode, key int) *tNode {
	if o == nil {
		return &tNode{priority: fastRand(), msz: 1, key: key, value: 1}
	}
	if cmp := t.comparator(key, o.key); cmp >= 0 {
		o.lr[cmp] = t._put(o.lr[cmp], key)
		if o.lr[cmp].priority > o.priority {
			o = t.rotate(o, cmp^1)
		}
	} else {
		o.value++
	}
	o.maintain()
	return o
}

func (t *treap) put(key int) { t.root = t._put(t.root, key) }

func (t *treap) get(key int) *tNode {
	for o := t.root; o != nil; {
		if cmp := t.comparator(key, o.key); cmp >= 0 {
			o = o.lr[cmp]
		} else {
			return o
		}
	}
	return nil
}

func (t *treap) _delete(o *tNode, key int) *tNode {
	if o == nil {
		return nil
	}
	if cmp := t.comparator(key, o.key); cmp >= 0 {
		o.lr[cmp] = t._delete(o.lr[cmp], key)
	} else {
		if o.value > 1 {
			o.value--
		} else {
			if o.lr[1] == nil {
				return o.lr[0]
			}
			if o.lr[0] == nil {
				return o.lr[1]
			}
			cmp2 := 0
			if o.lr[0].priority > o.lr[1].priority {
				cmp2 = 1
			}
			o = t.rotate(o, cmp2)
			o.lr[cmp2] = t._delete(o.lr[cmp2], key)
		}
	}
	o.maintain()
	return o
}

func (t *treap) delete(key int) { t.root = t._delete(t.root, key) }

func (t *treap) floor(key int) (floor *tNode) {
	for o := t.root; o != nil; {
		switch cmp := t.comparator(key, o.key); {
		case cmp == 0:
			o = o.lr[0]
		case cmp > 0:
			floor = o
			o = o.lr[1]
		default:
			return o
		}
	}
	return
}

func (t *treap) mRank(key int) (cnt int, o *tNode) {
	for o = t.root; o != nil; {
		switch cmp := t.comparator(key, o.key); {
		case cmp == 0:
			o = o.lr[0]
		case cmp > 0:
			cnt += o.value + o.lr[0].mSize()
			o = o.lr[1]
		default:
			cnt += o.lr[0].mSize()
			return
		}
	}
	return
}

func (t *treap) mSelect(k int) (o *tNode) {
	for o = t.root; o != nil; {
		switch ls := o.lr[0].mSize(); {
		case k < ls:
			o = o.lr[0]
		case k > ls:
			k -= o.value + ls
			if k < 0 {
				return
			}
			o = o.lr[1]
		default:
			return
		}
	}
	return
}

func (t *treap) next(key int) *tNode {
	rank, o := t.mRank(key)
	if o != nil {
		rank += o.value
	}
	return t.mSelect(rank)
}

func (t *treap) max() (max *tNode) {
	for o := t.root; o != nil; o = o.lr[1] {
		max = o
	}
	return
}

// github.com/EndlessCheng/codeforces-go
func Sol527CTreap(reader io.Reader, writer io.Writer) {
	cut := func(t, mt *treap, mid int) {
		o := t.floor(mid)
		l := o.key
		r := t.next(l).key
		mt.delete(r - l)
		mt.put(r - mid)
		mt.put(mid - l)
		t.put(mid)
	}

	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	w, h, mw, mh := newTreap(), newTreap(), newTreap(), newTreap()
	var w0, h0, n int
	Fscan(in, &w0, &h0, &n)
	w.put(0)
	w.put(w0)
	mw.put(w0)
	h.put(0)
	h.put(h0)
	mh.put(h0)
	for ; n > 0; n-- {
		var op string
		var mid int
		Fscan(in, &op, &mid)
		if op[0] == 'V' {
			cut(w, mw, mid)
		} else {
			cut(h, mh, mid)
		}
		Fprintln(out, int64(mw.max().key)*int64(mh.max().key))
	}
}

func main() {
	Sol527CTreap(os.Stdin, os.Stdout)
}

package main

import (
	"io"
	"os"
	"time"
	. "fmt"
	"bufio"
)

var x = uint(time.Now().UnixNano())

func fastRand() uint {
	x ^= x << 13
	x ^= x >> 17
	x ^= x << 5
	return x
}

type tNode struct {
	lr       [2]*tNode
	priority uint
	msz      int
	key      int
	value    int
}

func (o *tNode) mSize() int {
	if o != nil {
		return o.msz
	}
	return 0
}

func (o *tNode) maintain() {
	msz := o.value
	if ol := o.lr[0]; ol != nil {
		msz += ol.msz
	}
	if or := o.lr[1]; or != nil {
		msz += or.msz
	}
	o.msz = msz
}

type treap struct {
	root       *tNode
	comparator func(a, b int) int
}

func newTreap() *treap {
	return &treap{comparator: func(a, b int) int {
		if a < b {
			return 0
		}
		if a > b {
			return 1
		}
		return -1
	}}
}

func (t *treap) rotate(o *tNode, d int) *tNode {
	x := o.lr[d^1]
	o.lr[d^1] = x.lr[d]
	x.lr[d] = o
	x.msz = o.msz
	o.maintain()
	return x
}

func (t *treap) _put(o *tNode, key int) *tNode {
	if o == nil {
		return &tNode{priority: fastRand(), msz: 1, key: key, value: 1}
	}
	if cmp := t.comparator(key, o.key); cmp >= 0 {
		o.lr[cmp] = t._put(o.lr[cmp], key)
		if o.lr[cmp].priority > o.priority {
			o = t.rotate(o, cmp^1)
		}
	} else {
		o.value++
	}
	o.maintain()
	return o
}

func (t *treap) put(key int) { t.root = t._put(t.root, key) }

func (t *treap) get(key int) *tNode {
	for o := t.root; o != nil; {
		if cmp := t.comparator(key, o.key); cmp >= 0 {
			o = o.lr[cmp]
		} else {
			return o
		}
	}
	return nil
}

func (t *treap) _delete(o *tNode, key int) *tNode {
	if o == nil {
		return nil
	}
	if cmp := t.comparator(key, o.key); cmp >= 0 {
		o.lr[cmp] = t._delete(o.lr[cmp], key)
	} else {
		if o.value > 1 {
			o.value--
		} else {
			if o.lr[1] == nil {
				return o.lr[0]
			}
			if o.lr[0] == nil {
				return o.lr[1]
			}
			cmp2 := 0
			if o.lr[0].priority > o.lr[1].priority {
				cmp2 = 1
			}
			o = t.rotate(o, cmp2)
			o.lr[cmp2] = t._delete(o.lr[cmp2], key)
		}
	}
	o.maintain()
	return o
}

func (t *treap) delete(key int) { t.root = t._delete(t.root, key) }

func (t *treap) floor(key int) (floor *tNode) {
	for o := t.root; o != nil; {
		switch cmp := t.comparator(key, o.key); {
		case cmp == 0:
			o = o.lr[0]
		case cmp > 0:
			floor = o
			o = o.lr[1]
		default:
			return o
		}
	}
	return
}

func (t *treap) mRank(key int) (cnt int, o *tNode) {
	for o = t.root; o != nil; {
		switch cmp := t.comparator(key, o.key); {
		case cmp == 0:
			o = o.lr[0]
		case cmp > 0:
			cnt += o.value + o.lr[0].mSize()
			o = o.lr[1]
		default:
			cnt += o.lr[0].mSize()
			return
		}
	}
	return
}

func (t *treap) mSelect(k int) (o *tNode) {
	for o = t.root; o != nil; {
		switch ls := o.lr[0].mSize(); {
		case k < ls:
			o = o.lr[0]
		case k > ls:
			k -= o.value + ls
			if k < 0 {
				return
			}
			o = o.lr[1]
		default:
			return
		}
	}
	return
}

func (t *treap) next(key int) *tNode {
	rank, o := t.mRank(key)
	if o != nil {
		rank += o.value
	}
	return t.mSelect(rank)
}

func (t *treap) max() (max *tNode) {
	for o := t.root; o != nil; o = o.lr[1] {
		max = o
	}
	return
}

// github.com/EndlessCheng/codeforces-go
func Sol527CTreap(reader io.Reader, writer io.Writer) {
	cut := func(t, mt *treap, mid int) {
		o := t.floor(mid)
		l := o.key
		r := t.next(l).key
		mt.delete(r - l)
		mt.put(r - mid)
		mt.put(mid - l)
		t.put(mid)
	}

	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	w, h, mw, mh := newTreap(), newTreap(), newTreap(), newTreap()
	var w0, h0, n int
	Fscan(in, &w0, &h0, &n)
	w.put(0)
	w.put(w0)
	mw.put(w0)
	h.put(0)
	h.put(h0)
	mh.put(h0)
	for ; n > 0; n-- {
		var op string
		var mid int
		Fscan(in, &op, &mid)
		if op[0] == 'V' {
			cut(w, mw, mid)
		} else {
			cut(h, mh, mid)
		}
		Fprintln(out, int64(mw.max().key)*int64(mh.max().key))
	}
}

func main() {
	Sol527CTreap(os.Stdin, os.Stdout)
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
)

type color bool

const red, black color = true, false

type rbNode struct {
	lr    [2]*rbNode
	msz   int
	key   int
	value int
	c     color
}

func (o *rbNode) isRed() bool {
	if o == nil {
		return false
	}
	return o.c == red
}

func (o *rbNode) pushUp() {
	msz := o.value
	if ol := o.lr[0]; ol != nil {
		msz += ol.msz
	}
	if or := o.lr[1]; or != nil {
		msz += or.msz
	}
	o.msz = msz
}

func (o *rbNode) rotate(d int) *rbNode {
	x := o.lr[d^1]
	o.lr[d^1] = x.lr[d]
	x.lr[d] = o
	x.c = x.lr[d].c
	x.lr[d].c = red
	x.msz = o.msz
	o.pushUp()
	return x
}

func (o *rbNode) flipColors() {
	o.c = !o.c
	o.lr[0].c = !o.lr[0].c
	o.lr[1].c = !o.lr[1].c
}

func (o *rbNode) moveRedLeft() *rbNode {
	o.flipColors()
	if o.lr[1].lr[0].isRed() {
		o.lr[1] = o.lr[1].rotate(1)
		o = o.rotate(0)
		o.flipColors()
	}
	return o
}

func (o *rbNode) moveRedRight() *rbNode {
	o.flipColors()
	if o.lr[0].lr[0].isRed() {
		o = o.rotate(1)
		o.flipColors()
	}
	return o
}

func (o *rbNode) balance() *rbNode {
	if o.lr[1].isRed() {
		o = o.rotate(0)
	}
	if o.lr[0].isRed() && o.lr[0].lr[0].isRed() {
		o = o.rotate(1)
	}
	if o.lr[0].isRed() && o.lr[1].isRed() {
		o.flipColors()
	}
	o.pushUp()
	return o
}

func (o *rbNode) min() *rbNode {
	for o.lr[0] != nil {
		o = o.lr[0]
	}
	return o
}

func (o *rbNode) deleteMin() *rbNode {
	if o.lr[0] == nil {
		return nil
	}
	if !o.lr[0].isRed() && !o.lr[0].lr[0].isRed() {
		o = o.moveRedLeft()
	}
	o.lr[0] = o.lr[0].deleteMin()
	return o.balance()
}

type rbTree struct {
	root       *rbNode
	comparator func(a, b int) int
}

func newRBTree() *rbTree {
	return &rbTree{comparator: func(a, b int) int {
		if a < b {
			return 0
		}
		if a > b {
			return 1
		}
		return -1
	}}
}

func (t *rbTree) _put(o *rbNode, key int) *rbNode {
	if o == nil {
		return &rbNode{msz: 1, key: key, value: 1, c: red}
	}
	if cmp := t.comparator(key, o.key); cmp >= 0 {
		o.lr[cmp] = t._put(o.lr[cmp], key)
		if o.lr[1].isRed() && !o.lr[0].isRed() {
			o = o.rotate(0)
		}
		if o.lr[0].isRed() && o.lr[0].lr[0].isRed() {
			o = o.rotate(1)
		}
		if o.lr[0].isRed() && o.lr[1].isRed() {
			o.flipColors()
		}
	} else {
		o.value++
	}
	o.pushUp()
	return o
}

func (t *rbTree) put(key int) {
	t.root = t._put(t.root, key)
	t.root.c = black
}

func (t *rbTree) _delete(o *rbNode, key int) *rbNode {
	if cmp := t.comparator(key, o.key); cmp == 0 {
		if !o.lr[0].isRed() && !o.lr[0].lr[0].isRed() {
			o = o.moveRedLeft()
		}
		o.lr[0] = t._delete(o.lr[0], key)
	} else {
		if o.lr[0].isRed() {
			o = o.rotate(1)
		}
		if t.comparator(key, o.key) == -1 && o.lr[1] == nil {
			return nil
		}
		if !o.lr[1].isRed() && !o.lr[1].lr[0].isRed() {
			o = o.moveRedRight()
		}
		if t.comparator(key, o.key) == -1 {
			x := o.lr[1].min()
			o.key = x.key
			o.value = x.value
			o.lr[1] = o.lr[1].deleteMin()
		} else {
			o.lr[1] = t._delete(o.lr[1], key)
		}
	}
	return o.balance()
}

func (t *rbTree) get(key int) *rbNode {
	for o := t.root; o != nil; {
		if cmp := t.comparator(key, o.key); cmp >= 0 {
			o = o.lr[cmp]
		} else {
			return o
		}
	}
	return nil
}

func (t *rbTree) delete(key int) {
	if o := t.get(key); o != nil && o.value > 1 {
		o.value--
		return
	}
	if !t.root.lr[0].isRed() && !t.root.lr[1].isRed() {
		t.root.c = red
	}
	t.root = t._delete(t.root, key)
	if t.root != nil {
		t.root.c = black
	}
}

func (t *rbTree) floor(key int) (floor *rbNode) {
	for o := t.root; o != nil; {
		switch cmp := t.comparator(key, o.key); {
		case cmp == 0:
			o = o.lr[0]
		case cmp > 0:
			floor = o
			o = o.lr[1]
		default:
			return o
		}
	}
	return
}

func (t *rbTree) next(key int) (next *rbNode) {
	for o := t.root; o != nil; {
		if cmp := t.comparator(key, o.key); cmp != 0 {
			o = o.lr[1]
		} else {
			next = o
			o = o.lr[0]
		}
	}
	return
}

func (t *rbTree) max() (max *rbNode) {
	for o := t.root; o != nil; o = o.lr[1] {
		max = o
	}
	return
}

// github.com/EndlessCheng/codeforces-go
func Sol527CRBTree(reader io.Reader, writer io.Writer) {
	cut := func(t, mt *rbTree, mid int) {
		o := t.floor(mid)
		l := o.key
		r := t.next(l).key
		mt.delete(r - l)
		mt.put(r - mid)
		mt.put(mid - l)
		t.put(mid)
	}

	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	w, h, mw, mh := newRBTree(), newRBTree(), newRBTree(), newRBTree()
	var w0, h0, n int
	Fscan(in, &w0, &h0, &n)
	w.put(0)
	w.put(w0)
	mw.put(w0)
	h.put(0)
	h.put(h0)
	mh.put(h0)
	for ; n > 0; n-- {
		var op string
		var mid int
		Fscan(in, &op, &mid)
		if op[0] == 'V' {
			cut(w, mw, mid)
		} else {
			cut(h, mh, mid)
		}
		Fprintln(out, int64(mw.max().key)*int64(mh.max().key))
	}
}

func main() {
	Sol527CRBTree(os.Stdin, os.Stdout)
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
	"time"
)

var seed = uint32(time.Now().UnixNano())

func fastRand() uint {
	x := seed
	x ^= x << 13
	x ^= x >> 17
	x ^= x << 5
	seed = x
	return uint(x)
}

type tNode struct {
	lr       [2]*tNode
	priority uint
	msz      int
	key      int
	value    int
}

func (o *tNode) mSize() int {
	if o != nil {
		return o.msz
	}
	return 0
}

func (o *tNode) maintain() {
	msz := o.value
	if ol := o.lr[0]; ol != nil {
		msz += ol.msz
	}
	if or := o.lr[1]; or != nil {
		msz += or.msz
	}
	o.msz = msz
}

type treap struct {
	root       *tNode
	comparator func(a, b int) int
}

func newTreap() *treap {
	return &treap{comparator: func(a, b int) int {
		if a < b {
			return 0
		}
		if a > b {
			return 1
		}
		return -1
	}}
}

func (t *treap) rotate(o *tNode, d int) *tNode {
	x := o.lr[d^1]
	o.lr[d^1] = x.lr[d]
	x.lr[d] = o
	o.maintain()
	x.maintain()
	return x
}

func (t *treap) _put(o *tNode, key int) *tNode {
	if o == nil {
		return &tNode{priority: fastRand(), msz: 1, key: key, value: 1}
	}
	if cmp := t.comparator(key, o.key); cmp >= 0 {
		o.lr[cmp] = t._put(o.lr[cmp], key)
		if o.lr[cmp].priority > o.priority {
			o = t.rotate(o, cmp^1)
		}
	} else {
		o.value++
	}
	o.maintain()
	return o
}

func (t *treap) put(key int) { t.root = t._put(t.root, key) }

func (t *treap) get(key int) *tNode {
	for o := t.root; o != nil; {
		if cmp := t.comparator(key, o.key); cmp >= 0 {
			o = o.lr[cmp]
		} else {
			return o
		}
	}
	return nil
}

func (t *treap) _delete(o *tNode, key int) *tNode {
	if o == nil {
		return nil
	}
	if cmp := t.comparator(key, o.key); cmp >= 0 {
		o.lr[cmp] = t._delete(o.lr[cmp], key)
	} else {
		if o.value > 1 {
			o.value--
		} else {
			if o.lr[1] == nil {
				return o.lr[0]
			}
			if o.lr[0] == nil {
				return o.lr[1]
			}
			cmp2 := 0
			if o.lr[0].priority > o.lr[1].priority {
				cmp2 = 1
			}
			o = t.rotate(o, cmp2)
			o.lr[cmp2] = t._delete(o.lr[cmp2], key)
		}
	}
	o.maintain()
	return o
}

func (t *treap) delete(key int) { t.root = t._delete(t.root, key) }

func (t *treap) floor(key int) (floor *tNode) {
	for o := t.root; o != nil; {
		switch cmp := t.comparator(key, o.key); {
		case cmp == 0:
			o = o.lr[0]
		case cmp > 0:
			floor = o
			o = o.lr[1]
		default:
			return o
		}
	}
	return
}

func (t *treap) ceiling(key int) (ceiling *tNode) {
	for o := t.root; o != nil; {
		switch cmp := t.comparator(key, o.key); {
		case cmp == 0:
			ceiling = o
			o = o.lr[0]
		case cmp > 0:
			o = o.lr[1]
		default:
			return o
		}
	}
	return
}

func (t *treap) mRank(key int) (cnt int, o *tNode) {
	for o = t.root; o != nil; {
		switch cmp := t.comparator(key, o.key); {
		case cmp == 0:
			o = o.lr[0]
		case cmp > 0:
			cnt += o.value + o.lr[0].mSize()
			o = o.lr[1]
		default:
			cnt += o.lr[0].mSize()
			return
		}
	}
	return
}

func (t *treap) mSelect(k int) (o *tNode) {
	for o = t.root; o != nil; {
		switch ls := o.lr[0].mSize(); {
		case k < ls:
			o = o.lr[0]
		case k > ls:
			k -= o.value + ls
			if k < 0 {
				return
			}
			o = o.lr[1]
		default:
			return
		}
	}
	return
}

func (t *treap) next(key int) *tNode {
	rank, o := t.mRank(key)
	if o != nil {
		rank += o.value
	}
	return t.mSelect(rank)
}

func (t *treap) max() (max *tNode) {
	for o := t.root; o != nil; o = o.lr[1] {
		max = o
	}
	return
}

// github.com/EndlessCheng/codeforces-go
func Sol527CTreap(reader io.Reader, writer io.Writer) {
	cut := func(t, mt *treap, mid int) {
		o := t.floor(mid)
		l := o.key
		r := t.next(l).key
		mt.delete(r - l)
		mt.put(r - mid)
		mt.put(mid - l)
		t.put(mid)
	}

	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	w, h, mw, mh := newTreap(), newTreap(), newTreap(), newTreap()
	var w0, h0, n int
	Fscan(in, &w0, &h0, &n)
	w.put(0)
	w.put(w0)
	mw.put(w0)
	h.put(0)
	h.put(h0)
	mh.put(h0)
	for ; n > 0; n-- {
		var op string
		var mid int
		Fscan(in, &op, &mid)
		if op[0] == 'V' {
			cut(w, mw, mid)
		} else {
			cut(h, mh, mid)
		}
		Fprintln(out, int64(mw.max().key)*int64(mh.max().key))
	}
}

func main() {
	Sol527CTreap(os.Stdin, os.Stdout)
}

package main

import (
  "os"
  "bufio"
  "strconv"
  "fmt"
  "sort"
)

var scanner *bufio.Scanner

func getI64() int64 {
  scanner.Scan()
  x, _ := strconv.ParseInt(scanner.Text(), 10, 64)
  return x
}
func getI() int {
  return int(getI64())
}
func getS() string {
  scanner.Scan()
  return scanner.Text()
}

type Cut struct {
  LeftSize, Prev, Next int
}

func main() {
  scanner = bufio.NewScanner(os.Stdin)
  scanner.Split(bufio.ScanWords)
  writer := bufio.NewWriter(os.Stdout)
  defer writer.Flush()

  w, h, n := getI(), getI(), getI()
  xs, ys := []int{}, []int{}
  input := make([]int, n)
  for i := 0; i < n; i++ {
    s, k := getS(), getI()
    if s == "H" {
      ys = append(ys, k)
      input[i] = -k
    } else {
      xs = append(xs, k)
      input[i] = k
    }
  }
  xs = append(xs, 0)
  xs = append(xs, w)
  ys = append(ys, 0)
  ys = append(ys, h)
  sort.Ints(xs)
  sort.Ints(ys)
  xCuts, yCuts := make([]*Cut, len(xs)), make([]*Cut, len(ys))
  xCutPos, yCutPos := map[int]int{}, map[int]int{}
  previous := 0
  xMax := 0
  for i, x := range xs {
    size := x-previous
    if size > xMax {
      xMax = size
    }
    xCuts[i] = &Cut{ LeftSize: size, Prev: i-1, Next: i+1 }
    previous = x
    xCutPos[x] = i
  }
  previous = 0
  yMax := 0
  for i, y := range ys {
    size := y-previous
    if size > yMax {
      yMax = size
    }
    yCuts[i] = &Cut{ LeftSize: size, Prev: i-1, Next: i+1 }
    previous = y
    yCutPos[y] = i
  }
  results := make([]int64, n)
  for i := n-1; i >= 0; i-- {
    results[i] = int64(xMax)*int64(yMax)
    cut := input[i]
    if input[i] > 0 {
      thisCut := xCuts[xCutPos[cut]]
      prevCut, nextCut := xCuts[thisCut.Prev], xCuts[thisCut.Next]
      prevCut.Next = thisCut.Next
      nextCut.Prev = thisCut.Prev
      size := nextCut.LeftSize + thisCut.LeftSize
      nextCut.LeftSize = size
      if size > xMax {
        xMax = size
      }
    } else {
      thisCut := yCuts[yCutPos[-cut]]
      prevCut, nextCut := yCuts[thisCut.Prev], yCuts[thisCut.Next]
      prevCut.Next = thisCut.Next
      nextCut.Prev = thisCut.Prev
      size := nextCut.LeftSize + thisCut.LeftSize
      nextCut.LeftSize = size
      if size > yMax {
        yMax = size
      }
    }
  }
  for _, result := range results {
    writer.WriteString(fmt.Sprintf("%d\n", result))
  }
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func ReadArray() ([]int64) {
	in := bufio.NewReader(os.Stdin)
	line, _ := in.ReadString('\n')

	strs := strings.Split(strings.TrimSpace(line[:len(line)-1]), " ")
	nums := make([]int64, len(strs))
	for i, str := range strs {
		nums[i], _ = strconv.ParseInt(str, 10 ,64)
	}
	return nums
}

func main() {
	nums := ReadArray()
	res := nums[1] / nums[0]
	if (nums[1] % nums[0]) != 0 {
		res += 1
	}
	fmt.Println(res)
}

package main

import "fmt"

func calculate(n, k uint64) uint64 {
	r := k / n;
	if 0 != k % n {
		r++
	}

	return r
}

func main() {
	var n,k uint64
	fmt.Scanf("%v %v", &n, &k)
	fmt.Printf("%v", calculate(n, k))
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func ReadArray() ([]int) {
	in := bufio.NewReader(os.Stdin)
	line, _ := in.ReadString('\n')

	strs := strings.Split(strings.TrimSpace(line[:len(line)-1]), " ")
	nums := make([]int, len(strs))
	for i, str := range strs {
		nums[i], _ = strconv.Atoi(str)
	}
	return nums
}

func main() {
	nums := ReadArray()
	res := nums[1] / nums[0]
	if (nums[1] % nums[0]) != 0 {
		res++
	}
	fmt.Println(res)
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func ReadArray() ([]int) {
	in := bufio.NewReader(os.Stdin)
	line, _ := in.ReadString('\n')

	strs := strings.Split(strings.TrimSpace(line[:len(line)-1]), " ")
	nums := make([]int, len(strs))
	for i, str := range strs {
		nums[i], _ = strconv.Atoi(str)
	}
	return nums
}

func main() {
	nums := ReadArray()
	res := nums[1] / nums[0]
	if nums[1] % nums[0] != 0 {
		res++
	}
	fmt.Println(res)
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func ReadArray() ([]int) {
	in := bufio.NewReader(os.Stdin)
	line, _ := in.ReadString('\n')

	strs := strings.Split(strings.TrimSpace(line[:len(line)-1]), " ")
	nums := make([]int, len(strs))
	for i, str := range strs {
		nums[i], _ = strconv.Atoi(str)
	}
	return nums
}

func main() {
	nums := ReadArray()
	res := nums[1] / nums[0]
	fmt.Println(nums[1] % nums[0])
	if (nums[1] % nums[0]) != 0 {
		fmt.Println("plus the 1")
		res += 1
	}
	fmt.Println(res)
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func ReadArray() ([]int) {
	in := bufio.NewReader(os.Stdin)
	line, _ := in.ReadString('\n')

	strs := strings.Split(strings.TrimSpace(line[:len(line)-1]), " ")
	nums := make([]int, len(strs))
	for i, str := range strs {
		nums[i], _ = strconv.Atoi(str)
	}
	return nums
}

func main() {
	nums := ReadArray()
	res := nums[1] / nums[0]
	if strconv.Itoa(nums[0]) == "1000000000000000000" {
		fmt.Println(nums[1] % nums[0])
	}
	if (nums[1] % nums[0]) != 0 {
		if strconv.Itoa(nums[0]) == "1000000000000000000" {
			fmt.Println("plus the 1")
		}
		res += 1
	}
	fmt.Println(res)
}