Leonid wants to become a glass carver (the person who creates beautiful artworks by cutting the glass). He already has a rectangular w mm  ×  h mm sheet of glass, a diamond glass cutter and lots of enthusiasm. What he lacks is understanding of what to carve and how.In order not to waste time, he decided to practice the technique of carving. To do this, he makes vertical and horizontal cuts through the entire sheet. This process results in making smaller rectangular fragments of glass. Leonid does not move the newly made glass fragments. In particular, a cut divides each fragment of glass that it goes through into smaller fragments.After each cut Leonid tries to determine what area the largest of the currently available glass fragments has. Since there appear more and more fragments, this question takes him more and more time and distracts him from the fascinating process.Leonid offers to divide the labor — he will cut glass, and you will calculate the area of the maximum fragment after each cut. Do you agree?

The first line contains three integers w, h, n (2 ≤ w, h ≤ 200 000, 1 ≤ n ≤ 200 000). Next n lines contain the descriptions of the cuts. Each description has the form H y or V x. In the first case Leonid makes the horizontal cut at the distance y millimeters (1 ≤ y ≤ h - 1) from the lower edge of the original sheet of glass. In the second case Leonid makes a vertical cut at distance x (1 ≤ x ≤ w - 1) millimeters from the left edge of the original sheet of glass. It is guaranteed that Leonid won't make two identical cuts.

After each cut print on a single line the area of the maximum available glass fragment in mm2.

NotePicture for the first sample test:    Picture for the second sample test:

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"
	"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)
}


You are given a set of $$$2n+1$$$ integer points on a Cartesian plane. Points are numbered from $$$0$$$ to $$$2n$$$ inclusive. Let $$$P_i$$$ be the $$$i$$$-th point. The $$$x$$$-coordinate of the point $$$P_i$$$ equals $$$i$$$. The $$$y$$$-coordinate of the point $$$P_i$$$ equals zero (initially). Thus, initially $$$P_i=(i,0)$$$.The given points are vertices of a plot of a piecewise function. The $$$j$$$-th piece of the function is the segment $$$P_{j}P_{j + 1}$$$.In one move you can increase the $$$y$$$-coordinate of any point with odd $$$x$$$-coordinate (i.e. such points are $$$P_1, P_3, \dots, P_{2n-1}$$$) by $$$1$$$. Note that the corresponding segments also change.For example, the following plot shows a function for $$$n=3$$$ (i.e. number of points is $$$2\cdot3+1=7$$$) in which we increased the $$$y$$$-coordinate of the point $$$P_1$$$ three times and $$$y$$$-coordinate of the point $$$P_5$$$ one time:  Let the area of the plot be the area below this plot and above the coordinate axis OX. For example, the area of the plot on the picture above is 4 (the light blue area on the picture above is the area of the plot drawn on it).Let the height of the plot be the maximum $$$y$$$-coordinate among all initial points in the plot (i.e. points $$$P_0, P_1, \dots, P_{2n}$$$). The height of the plot on the picture above is 3.Your problem is to say which minimum possible height can have the plot consisting of $$$2n+1$$$ vertices and having an area equal to $$$k$$$. Note that it is unnecessary to minimize the number of moves.It is easy to see that any answer which can be obtained by performing moves described above always exists and is an integer number not exceeding $$$10^{18}$$$.

The first line of the input contains two integers $$$n$$$ and $$$k$$$ ($$$1 \le n, k \le 10^{18}$$$) — the number of vertices in a plot of a piecewise function and the area we need to obtain.

Print one integer — the minimum possible height of a plot consisting of $$$2n+1$$$ vertices and with an area equals $$$k$$$. It is easy to see that any answer which can be obtained by performing moves described above always exists and is an integer number not exceeding $$$10^{18}$$$.

NoteOne of the possible answers to the first example:  The area of this plot is 3, the height of this plot is 1.There is only one possible answer to the second example:  The area of this plot is 12, the height of this plot is 3.

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)
}