package main

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

func main() {
	CF1670C(os.Stdin, os.Stdout)

}

func CF1670C(in io.Reader, out io.Writer) {
	r := bufio.NewReader(in)
	w := bufio.NewWriter(out)
	defer w.Flush()

	const N = 500000

	mx := [N + 1]int{}
	my := [N + 1]int{}
	xr := [N + 1]int{}
	yr := [N + 1]int{}
	var n, q int
	fmt.Fscan(r, &n, &q)

	addX := func(idx, v int) {
		for i := idx; i <= n; i = i | (i + 1) {
			mx[i] += v
		}
	}
	addY := func(idx, v int) {
		for i := idx; i <= n; i = i | (i + 1) {
			my[i] += v
		}
	}
	prefixX := func(idx int) int {
		var tot int
		for ; idx >= 0; idx = (idx & (idx + 1)) - 1 {
			tot += mx[idx]
		}
		return tot
	}
	prefixY := func(idx int) int {
		var tot int
		for ; idx >= 0; idx = (idx & (idx + 1)) - 1 {
			tot += my[idx]
		}
		return tot
	}

	for ; q > 0; q-- {
		var t int64
		fmt.Fscan(r, &t)
		switch t {
		case 1:
			var x, y int
			fmt.Fscan(r, &x, &y)
			if xr[x] == 0 {
				addX(x, 1)
			}
			if yr[y] == 0 {
				addY(y, 1)
			}

			xr[x]++
			yr[y]++
		case 2:
			var x, y int
			fmt.Fscan(r, &x, &y)
			xr[x]--
			yr[y]--
			if xr[x] == 0 {
				addX(x, -1)
			}
			if yr[y] == 0 {
				addY(y, -1)
			}
		case 3:
			var x1, y1, x2, y2 int
			fmt.Fscan(r, &x1, &y1, &x2, &y2)

			var f bool
			if prefixX(x2)-prefixX(x1-1) >= x2-x1+1 {
				f = true
			}

			if !f {
				if prefixY(y2)-prefixY(y1-1) >= y2-y1+1 {
					f = true
				}
			}
			if f {
				fmt.Fprintln(out, "Yes")
			} else {
				fmt.Fprintln(out, "No")
			}
		}

	}

}

package main

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

const N = 500000

var mx = [N + 1]int{}
var my = [N + 1]int{}
var xr = [N + 1]int{}
var yr = [N + 1]int{}

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	var n, q int
	fmt.Fscan(in, &n, &q)
	var t, x, y, x2, y2 int
	addX := func(idx, v int) {
		for i := idx; i <= n; i = i | (i + 1) {
			mx[i] += v
		}
	}
	addY := func(idx, v int) {
		for i := idx; i <= n; i = i | (i + 1) {
			my[i] += v
		}
	}
	prefixX := func(idx int) int {
		var tot int
		for ; idx >= 0; idx = (idx & (idx + 1)) - 1 {
			tot += mx[idx]
		}
		return tot
	}
	prefixY := func(idx int) int {
		var tot int
		for ; idx >= 0; idx = (idx & (idx + 1)) - 1 {
			tot += my[idx]
		}
		return tot
	}
	for i := 0; i < q; i++ {
		fmt.Fscan(in, &t, &x, &y)
		if t == 1 {
			if xr[x] == 0 {
				addX(x, 1)
			}
			if yr[y] == 0 {
				addY(y, 1)
			}

			xr[x]++
			yr[y]++

		} else if t == 2 {
			xr[x]--
			yr[y]--
			if xr[x] == 0 {
				addX(x, -1)
			}
			if yr[y] == 0 {
				addY(y, -1)
			}
		} else if t == 3 {
			fmt.Fscan(in, &x2, &y2)
			var f bool
			if prefixX(x2)-prefixX(x-1) >= x2-x+1 {
				f = true
			}

			if !f {
				if prefixY(y2)-prefixY(y-1) >= y2-y+1 {
					f = true
				}
			}

			if f {
				fmt.Fprintln(out, "Yes")
			} else {
				fmt.Fprintln(out, "No")
			}
		}
	}
}

package main

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

func min(a, b int) int {
	if a < b {
		return a
	} else {
		return b
	}
}

func max(a, b int) int {
	if a < b {
		return b
	} else {
		return a
	}
}

type TreeElem interface {
	//Operation(a, b TreeElem) TreeElem
} // should support operation Operation

type Operation func(TreeElem, TreeElem) TreeElem // should have neutralElem; should be distributive

type Segtree struct {
	n           int
	lazyN       int
	op          Operation
	tree        []TreeElem
	neutralElem TreeElem
}

func nextPowerOfTwo(x int) int {
	x--
	x |= x >> 1
	x |= x >> 2
	x |= x >> 4
	x |= x >> 8
	x |= x >> 16
	x++
	return x
}

func NewTree(s []TreeElem, op Operation, neutralElem TreeElem) (*Segtree, error) {
	n := len(s)
	if n == 0 {
		return nil, errors.New("Error: slice is empty")
	}
	if n >= 1<<30 {
		return nil, errors.New("Error: slice is too large")
	}
	lazyN := nextPowerOfTwo(n)
	t := &Segtree{
		n:           n,
		lazyN:       lazyN,
		op:          op,
		tree:        make([]TreeElem, 4*lazyN),
		neutralElem: neutralElem,
	}
	t.build(s)
	return t, nil
}

func (t *Segtree) build(s []TreeElem) { // should only be called in NewTree function
	for i := 0; i < t.n; i++ {
		t.tree[t.lazyN-1+i] = s[i]
	}
	for i := t.n; i < t.lazyN; i++ {
		t.tree[t.lazyN-1+i] = t.neutralElem
	}
	for i := t.lazyN - 2; i >= 0; i-- {
		t.tree[i] = t.op(t.tree[2*i+1], t.tree[2*i+2])
	}
}

func (t Segtree) implQuery(left, right int) TreeElem {
	leftRes := t.neutralElem
	rightRes := t.neutralElem
	for left < right {
		if left%2 == 0 {
			leftRes = t.op(leftRes, t.tree[left])
		}
		//left--
		left /= 2
		if right%2 == 1 {
			rightRes = t.op(t.tree[right], rightRes)
		}
		//right--
		right /= 2
		right--
	}
	if left == right {
		leftRes = t.op(leftRes, t.tree[left]) //left
	}
	return t.op(leftRes, rightRes)
}

func (t Segtree) Query(left, right int) (TreeElem, error) {
	if left < 0 || right >= t.n {
		return nil, errors.New(fmt.Sprintf("Incorrect query range; indexes should be in [0, %d]", t.n-1))
	}
	return t.implQuery(left+t.lazyN-1, right+t.lazyN-1), nil
}

func (t *Segtree) Set(index int, value TreeElem) error {
	if index < 0 || index >= t.n {
		return errors.New(fmt.Sprintf("Incorrect query range; indexes should be in [0, %d]", t.n-1))
	}
	i := t.lazyN - 1 + index
	t.tree[i] = value
	for par := (i - 1) >> 1; par >= 0; par = (i - 1) >> 1 {
		if i%2 == 0 {
			t.tree[par] = t.op(t.tree[i], t.tree[i-1])
		} else {
			t.tree[par] = t.op(t.tree[i], t.tree[i+1])
		}
		i = par
	}
	return nil
}

func (t *Segtree) Apply(index int, value TreeElem) error { // Apply Operation(elem[index], value)
	if index < 0 || index >= t.n {
		return errors.New(fmt.Sprintf("Incorrect query range; indexes should be in [0, %d]", t.n-1))
	}
	i := t.lazyN - 1 + index
	t.tree[i] = t.op(t.tree[i], value)
	for par := (i - 1) >> 1; par >= 0; par = (i - 1) >> 1 {
		if i%2 == 0 {
			t.tree[par] = t.op(t.tree[i], t.tree[i-1])
		} else {
			t.tree[par] = t.op(t.tree[i], t.tree[i+1])
		}
		i = par
	}
	return nil
}

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()
	var n, q int
	fmt.Fscan(in, &n, &q)
	x := make([]TreeElem, n)
	y := make([]TreeElem, n)
	for i := 0; i < n; i++ {
		x[i] = 0
		y[i] = 0
	}
	tx, _ := NewTree(x, func(a, b TreeElem) TreeElem { return min(a.(int), b.(int)) }, 1000000)
	ty, _ := NewTree(y, func(a, b TreeElem) TreeElem { return min(a.(int), b.(int)) }, 1000000)
	for iii := 0; iii < q; iii++ {
		var qtype int
		fmt.Fscan(in, &qtype)
		switch qtype {
		case 1:
			var x1, y1 int
			fmt.Fscan(in, &x1, &y1)
			x1--
			y1--
			//fmt.Println("type1!!!", x1, y1)
			res, _ := tx.Query(x1, x1)
			tx.Set(x1, res.(int)+1)
			//fmt.Println("type1!!!", res)
			res, _ = ty.Query(y1, y1)
			ty.Set(y1, res.(int)+1)
			//fmt.Println("type1!!!", res)
		case 2:
			var x1, y1 int
			fmt.Fscan(in, &x1, &y1)
			x1--
			y1--
			//fmt.Println("type2!!!", x1, y1)
			res, _ := tx.Query(x1, x1)
			tx.Set(x1, res.(int)-1)
			//fmt.Println("type2!!!", res)
			res, _ = ty.Query(y1, y1)
			ty.Set(y1, res.(int)-1)
			//fmt.Println("type2!!!", res)
		case 3:
			var x1, x2, y1, y2 int
			fmt.Fscan(in, &x1, &y1, &x2, &y2)
			x1--
			x2--
			y1--
			y2--
			res1, _ := tx.Query(x1, x2)
			res2, _ := ty.Query(y1, y2)
			// fmt.Println("type3!!!", x1, x2, y1, y2, res1, res2)
			// tmp, _ := tx.Query(1, 1)
			// fmt.Println("!--!", tmp)
			// tmp, _ = tx.Query(2, 2)
			// fmt.Println("!--!", tmp)
			// tmp, _ = tx.Query(3, 3)
			// fmt.Println("!--!", tmp)
			// tmp, _ = tx.Query(1, 2)
			// fmt.Println("!--!", tmp)
			// tmp, _ = tx.Query(2, 3)
			// fmt.Println("!--!", tmp)
			// tmp, _ = tx.Query(1, 3)
			// fmt.Println("!--!", tmp)
			res := max(res1.(int), res2.(int))
			if res != 0 {
				fmt.Fprintln(out, "Yes")
			} else {
				fmt.Fprintln(out, "No")
			}
		}
	}
}

package main

import (
	"bufio"
	"errors"
	"fmt"
	"math"
	"os"
)

func min(a, b int) int {
	if a < b {
		return a
	} else {
		return b
	}
}

// code for tree is from  https://github.com/ideahitme/segment/blob/master/tree.go
//
// Tree implementation of segment tree

// Tree segment tree implementation
type Tree struct {
	realSize  int      // real size of the array on which queries are performed
	nodes     []int    // nodes stored in the tree. it is slice of size about ~2*realSize
	lazyNodes []int    // stores intermediate values on the tree for updates; for lazy propagation
	treeFunc  TreeFunc // defines the type of queries supported
}

// NewTree returns Tree object
// x - defines the array where queries will be performed
// fn - defines what kind of queries are to be performed
func NewTree(x []int, fn TreeFunc) (*Tree, error) {
	if len(x) == 0 {
		return nil, errors.New("segment tree cannot be instantiated on empty slice ")
	}
	//determine number of nodes
	size := calculateTreeSize(len(x))
	t := &Tree{
		nodes:     make([]int, size),
		lazyNodes: make([]int, size),
		treeFunc:  fn,
		realSize:  len(x),
	}
	t.init(0, 0, len(x)-1, x)
	return t, nil
}

// init recursively fills in values in the tree
func (t *Tree) init(curNode, curLeft, curRight int, x []int) {
	if curLeft == curRight {
		t.nodes[curNode] = x[curLeft]
		return
	}
	middle := (curLeft + curRight) / 2
	t.init(2*curNode+1, curLeft, middle, x)
	t.init(2*curNode+2, middle+1, curRight, x)
	t.nodes[curNode] = t.treeFunc.Select(t.nodes[2*curNode+1], t.nodes[2*curNode+2])
}

// RQ - range query based on the specified TreeFunc
func (t *Tree) RQ(left, right int) (int, error) {
	if left > right || left < 0 || right >= t.realSize {
		return 0, errors.New("range out of bonds")
	}
	return t.callRQ(0, left, right, 0, t.realSize-1), nil
}

// callRQ recursively calculates the answer to range query
func (t *Tree) callRQ(curNode, rangeLeft, rangeRight, curLeft, curRight int) int {
	t.applyLazyPropagate(curNode) // respect range update
	if curLeft > rangeRight || curRight < rangeLeft {
		return t.treeFunc.Outlier()
	}
	if curLeft >= rangeLeft && curRight <= rangeRight {
		return t.nodes[curNode]
	}
	middle := (curLeft + curRight) / 2
	return t.treeFunc.Select(
		t.callRQ(2*curNode+1, rangeLeft, rangeRight, curLeft, middle),
		t.callRQ(2*curNode+2, rangeLeft, rangeRight, middle+1, curRight),
	)
}

// Add increments all numbers in the range [l:r] by x
func (t *Tree) Add(x, left, right int) error {
	if left > right || left < 0 || right >= t.realSize {
		return errors.New("range out of bonds")
	}
	t.callAdd(0, left, right, 0, t.realSize-1, x)
	return nil
}

// callAdd recursively adds `x` to all numbers in [rangeLeft:rangeRight]
func (t *Tree) callAdd(curNode, rangeLeft, rangeRight, curLeft, curRight, x int) {
	t.applyLazyPropagate(curNode)
	if curLeft > rangeRight || curRight < rangeLeft {
		return
	}
	if curLeft >= rangeLeft && curRight <= rangeRight {
		t.lazyNodes[curNode] += x
		t.applyLazyPropagate(curNode)
		return
	}
	middle := (curLeft + curRight) / 2
	t.callAdd(2*curNode+1, rangeLeft, rangeRight, curLeft, middle, x)
	t.callAdd(2*curNode+2, rangeLeft, rangeRight, middle+1, curRight, x)
	t.nodes[curNode] = t.treeFunc.Select(
		t.nodes[2*curNode+1],
		t.nodes[2*curNode+2],
	)
}

// applyLazyPropagate applies and propagates whatever is stored in the lazy node
func (t *Tree) applyLazyPropagate(curNode int) {
	t.nodes[curNode] += t.lazyNodes[curNode]
	if 2*curNode+2 < len(t.lazyNodes) {
		t.lazyNodes[2*curNode+1] += t.lazyNodes[curNode]
		t.lazyNodes[2*curNode+2] += t.lazyNodes[curNode]
	}
	t.lazyNodes[curNode] = 0
}

// calculateTreeSize returns the size of the supplementary array storing
// intermediate nodes and values, roughly equal to ~ 2*x - 1, where
// x is the size of the original array being operated on
func calculateTreeSize(x int) int {
	logX := math.Log2(float64(x))
	ceilLogX := uint(math.Ceil(logX))
	return 2*1<<ceilLogX - 1
}

// TreeFunc interface defines the type of queries to be performed on the tree
type TreeFunc interface {
	Outlier() int        //should return value which can be discarded when passed to Select
	Select(x, y int) int //should return selected value among two integers
}

// MinFunc implements TreeFunc and supports Range Minimum Query
type MinFunc struct{}

// Outlier returns maximum integer number; it is returned when we are out of boundary of the original array
func (f MinFunc) Outlier() int {
	return math.MaxInt32
}

// Select selects the minimum of two numbers
func (f MinFunc) Select(x, y int) int {
	if x < y {
		return x
	}
	return y
}

// MaxFunc implements TreeFunc and supports Range Maximum Query
type MaxFunc struct{}

// Outlier returns minimum integer number; it is returned when we are out of boundary of the original array
func (f MaxFunc) Outlier() int {
	return math.MinInt32
}

// Select selects the maximum of two numbers
func (f MaxFunc) Select(x, y int) int {
	if x > y {
		return x
	}
	return y
}

func main() {
	scanner := bufio.NewReader(os.Stdin)
	writer := bufio.NewWriter(os.Stdout)
	defer writer.Flush()
	var n, q int
	fmt.Fscan(scanner, &n, &q)
	xArr := make([]int, n+1)
	yArr := make([]int, n+1)
	xTree, _ := NewTree(xArr, MinFunc{})
	yTree, _ := NewTree(yArr, MinFunc{})
	for i := 0; i < q; i++ {
		var sw int
		fmt.Fscan(scanner, &sw)
		switch sw {
		case 1:
			var x, y int
			fmt.Fscan(scanner, &x, &y)
			xTree.Add(1, x, x)
			yTree.Add(1, y, y)
		case 2:
			var x, y int
			fmt.Fscan(scanner, &x, &y)
			xTree.Add(-1, x, x)
			yTree.Add(-1, y, y)
		case 3:
			var x1, y1, x2, y2 int
			fmt.Fscan(scanner, &x1, &y1, &x2, &y2)
			val1, _ := xTree.RQ(x1, x2)
			val2, _ := yTree.RQ(y1, y2)
			if val1 >= 1 || val2 >= 1 {
				fmt.Fprintln(writer, "Yes")
			} else {
				fmt.Fprintln(writer, "No")
			}
		}
	}
}

package main

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

var r = bufio.NewReader(os.Stdin)
var w = bufio.NewWriter(os.Stdout)

func main() {
	defer w.Flush()
	var n, q int
	fmt.Fscan(r, &n, &q)
	f1, f2 := newLazySegmentTree(make([]int64, n+1)), newLazySegmentTree(make([]int64, n+1))
	cnt1, cnt2 := make([]int, n+1), make([]int, n+1)
	for qq:=0;qq<q;qq++ {
		var t int
		fmt.Fscan(r, &t)
		if t == 1 {
			var x, y int
			fmt.Fscan(r, &x, &y)
			cnt1[x]++
			cnt2[y]++
			f1.update(1, x, x, 1)
			f2.update(1, y, y, 1)
		} else if t == 2 {
			var x, y int
			fmt.Fscan(r, &x, &y)
			cnt1[x]--
			if cnt1[x] == 0 {
				f1.update(1, x, x, 0)
			}
			cnt2[y]--
			if cnt2[y] == 0 {
				f2.update(1, y, y, 0)
			}
		} else {
			var x1, y1, x2, y2 int
			fmt.Fscan(r, &x1, &y1)
			fmt.Fscan(r, &x2, &y2)
			if int(f1.query(1, x1, x2)) < x2 - x1 + 1 && int(f2.query(1, y1, y2)) < y2 - y1 + 1 {
				fmt.Fprintln(w, "No")
			} else {
				fmt.Fprintln(w, "Yes")
			}
		}
	}
}

type lazyST []struct {
	l, r int
	todo int64
	lazy bool // 支持区间修改为某一个值
	sum  int64 // 根据需要修改
}

// 线段树定义的操作，可修改
func (lazyST) op(a, b int64) int64 {
	return a + b
}

// 根据子节点修改节点
func (t lazyST) maintain(o int) {
	lo, ro := t[o<<1], t[o<<1|1]
	t[o].sum = t.op(lo.sum, ro.sum)
}

// 根据数组构建线段树，下标从 1 开始
func (t lazyST) build(a []int64, o, l, r int) {
	t[o].l, t[o].r = l, r
	if l == r {
		t[o].sum = a[l-1]
		return
	}
	m := (l + r) >> 1
	t.build(a, o<<1, l, m)
	t.build(a, o<<1|1, m+1, r)
	t.maintain(o)
}

// 对节点 o 表示的区间的所有元素加上 add
// 如果要实现区间修改为某一个值而不是加上某一个值的话，将 += 变为 = 即可
func (t lazyST) do(o int, add int64) {
	to := &t[o]
	to.todo = add                     // % mod
	to.lazy = true
	to.sum = int64(to.r-to.l+1) * add // % mod
}

// 懒标记下放
func (t lazyST) spread(o int) {
	if t[o].lazy {
		add := t[o].todo
		t.do(o<<1, add)
		t.do(o<<1|1, add)
		t[o].todo = 0
		t[o].lazy = false
	}
}

// 对 o 表示的区间中属于 [l, r] 的元素进行修改
func (t lazyST) update(o, l, r int, add int64) {
	if l <= t[o].l && t[o].r <= r {
		// 是 [l, r] 的子集，全部修改
		t.do(o, add)
		return
	}
	t.spread(o)
	m := (t[o].l + t[o].r) >> 1
	if l <= m {
		t.update(o<<1, l, r, add)
	}
	if m < r {
		t.update(o<<1|1, l, r, add)
	}
	t.maintain(o)
}

// o=1  [l,r] 1<=l<=r<=n
func (t lazyST) query(o, l, r int) int64 {
	if l <= t[o].l && t[o].r <= r {
		return t[o].sum
	}
	t.spread(o)
	m := (t[o].l + t[o].r) >> 1
	if r <= m {
		return t.query(o<<1, l, r)
	}
	if m < l {
		return t.query(o<<1|1, l, r)
	}
	vl := t.query(o<<1, l, r)
	vr := t.query(o<<1|1, l, r)
	return t.op(vl, vr)
}

func (t lazyST) queryAll() int64 { return t[1].sum }

// a 从 0 开始
func newLazySegmentTree(a []int64) lazyST {
	t := make(lazyST, 4*len(a))
	t.build(a, 1, 1, len(a))
	return t
}

package main

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

// l 和 r 也可以写到方法参数上，实测二者在执行效率上无异
// 考虑到 debug 和 bug free 上的优点，写到结构体参数中
type seg []struct {
	l, r int
	val  int
}

// 单点更新：build 和 update 通用
func (t seg) set(o, val int) {
	t[o].val = val
}

// 合并两个节点上的数据：maintain 和 query 通用
// 要求操作满足区间可加性
// 例如 + * | & ^ min max gcd mulMatrix 摩尔投票 最大子段和 ...
func (seg) op(a, b int) int {
	if a > b {
		return b
	}
	return a
}

func (t seg) maintain(o int) {
	lo, ro := t[o<<1], t[o<<1|1]
	t[o].val = t.op(lo.val, ro.val)
}

func (t seg) build(a []int, o, l, r int) {
	t[o].l, t[o].r = l, r
	if l == r {
		t.set(o, a[l-1])
		return
	}
	m := (l + r) >> 1
	t.build(a, o<<1, l, m)
	t.build(a, o<<1|1, m+1, r)
	t.maintain(o)
}

// o=1  1<=i<=n
func (t seg) update(o, i, val int) {
	if t[o].l == t[o].r {
		t.set(o, val)
		return
	}
	if m := (t[o].l + t[o].r) >> 1; i <= m {
		t.update(o<<1, i, val)
	} else {
		t.update(o<<1|1, i, val)
	}
	t.maintain(o)
}

// o=1  [l,r] 1<=l<=r<=n
func (t seg) query(o, l, r int) int {
	if l <= t[o].l && t[o].r <= r {
		return t[o].val
	}
	m := (t[o].l + t[o].r) >> 1
	if r <= m {
		return t.query(o<<1, l, r)
	}
	if m < l {
		return t.query(o<<1|1, l, r)
	}
	vl := t.query(o<<1, l, r)
	vr := t.query(o<<1|1, l, r)
	return t.op(vl, vr)
}

func (t seg) queryAll() int { return t[1].val }

func newSegmentTree(a []int) seg {
	t := make(seg, 4*len(a))
	t.build(a, 1, 1, len(a))
	return t
}

func main_div2_791_C() {
	_in, _out := os.Stdin, os.Stdout
	in, out := bufio.NewReader(_in), bufio.NewWriter(_out)
	defer out.Flush()
	var cas int = 1
	//Fscan(in, &cas)
	var sol func()
	// Coding...beg!
	sol = func() {
		var n, q int
		Fscan(in, &n, &q)
		row := newSegmentTree(make([]int, n+10))
		col := newSegmentTree(make([]int, n+10))
		for i := 0; i < q; i++ {
			var t, x, y, x1, y1, x2, y2 int
			Fscan(in, &t)
			if t == 1 {
				Fscan(in, &x, &y)
				row.update(1, x, 1+row.query(1, x, x))
				col.update(1, y, 1+col.query(1, y, y))
			} else if t == 2 {
				Fscan(in, &x, &y)
				row.update(1, x, row.query(1, x, x)-1)
				col.update(1, y, col.query(1, y, y)-1)
			} else {
				Fscan(in, &x1, &y1, &x2, &y2)
				if row.query(1, x1, x2) > 0 || col.query(1, y1, y2) > 0 {
					Fprintln(out, "Yes")
				} else {
					Fprintln(out, "No")
				}
			}
		}
	}
	// Coding...ove!
	for i := 0; i < cas; i++ {
		sol()
	}
}

func main() {
	main_div2_791_C()
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)
var wrtr = bufio.NewWriterSize(os.Stdout, 10_000_000)
var rdr = bufio.NewScanner(os.Stdin)
func gs() string  { rdr.Scan(); return rdr.Text() }
func gi() int     { i,e := strconv.Atoi(gs()); if e != nil {panic(e)}; return i }
func min(a,b int) int { if a > b { return b }; return a }
type segtree struct { n, size, log int; op func(int, int) int; e int; d []int }
func Newsegtree(n int, op func(int, int) int, e int) *segtree {
	v := make([]int, n); for i := 0; i < n; i++ { v[i] = e }; return NewsegtreeVec(v, op, e)
}
func NewsegtreeVec(v []int, op func(int, int) int, e int) *segtree {
	n, sz, log := len(v), 1, 0; for sz < n { sz <<= 1; log += 1 }; d := make([]int, 2*sz); d[0] = e
	for i := 0; i < n; i++ { d[sz+i] = v[i] }; st := &segtree{n, sz, log, op, e, d}
	for i := sz - 1; i >= 1; i-- { st.update(i) }; return st
}
func (q *segtree) Set(p int, v int) {
	p += q.size; q.d[p] = v; for i := 1; i <= q.log; i++ { q.update(p >> uint(i)) }
}
func (q *segtree) Get(p int) int { return q.d[p+q.size] }
func (q *segtree) Prod(l int, r int) int {
	if r < l { return q.e }; r += 1; sml, smr := q.e, q.e; l += q.size; r += q.size
	for l < r {
		if l&1 != 0 { sml = q.op(sml, q.d[l]); l++ }; if r&1 != 0 { r--; smr = q.op(q.d[r], smr) }; l >>= 1; r >>= 1
	}
	return q.op(sml, smr)
}
func (q *segtree) Allprod() int { return q.d[1] }
func (q *segtree) MaxRight(l int, f func(int) bool) int {
	if l == q.n { return q.n - 1 }; l += q.size; sm := q.e
	for {
		for l%2 == 0 { l >>= 1 }
		if !f(q.op(sm, q.d[l])) {
			for l < q.size { l *= 2; if f(q.op(sm, q.d[l])) { sm = q.op(sm, q.d[l]); l++ } }; return l - q.size - 1
		}
		sm = q.op(sm, q.d[l]); l++; if l&-l == l { break }
	}
	return q.n - 1
}
func (q *segtree) MinLeft(r int, f func(int) bool) int {
	if r < 0 { return 0 }; r += q.size; sm := q.e; r++
	for {
		r--; for r > 1 && r%2 == 1 { r >>= 1 }
		if !f(q.op(q.d[r], sm)) {
			for r < q.size { r = 2*r + 1; if f(q.op(q.d[r], sm)) { sm = q.op(q.d[r], sm); r-- } }; return r + 1 - q.size
		}
		sm = q.op(q.d[r], sm); if r&-r == r { break }
	}
	return 0
}
func (q *segtree) update(k int) { q.d[k] = q.op(q.d[2*k], q.d[2*k+1]) }

func main() {
	//f1, _ := os.Create("cpu.prof"); pprof.StartCPUProfile(f1); defer pprof.StopCPUProfile()
	defer wrtr.Flush()
	infn := ""; if infn == "" && len(os.Args) > 1 {	infn = os.Args[1] }
	if infn != "" {	f, e := os.Open(infn); if e != nil { panic(e) }; rdr = bufio.NewScanner(f) }
	rdr.Split(bufio.ScanWords); rdr.Buffer(make([]byte,1024),1_000_000_000)
	// PROGRAM STARTS HERE
	N,Q := gi(),gi()
	v := make([]int,N+1)
	rowst := NewsegtreeVec(v,min,1000000000)
	colst := NewsegtreeVec(v,min,1000000000)
	for i:=0;i<Q;i++ {
		t := gi()
		if t == 1 {
			x,y := gi(),gi(); v1 := rowst.Get(x); v2 := colst.Get(y); rowst.Set(x,v1+1); colst.Set(y,v2+1)
		} else if t == 2 {
			x,y := gi(),gi(); v1 := rowst.Get(x); v2 := colst.Get(y); rowst.Set(x,v1-1); colst.Set(y,v2-1)
		} else {
			x1,y1,x2,y2 := gi(),gi(),gi(),gi(); m1 := rowst.Prod(x1,x2); m2 := colst.Prod(y1,y2)
			ans := "Yes"; if m1 == 0 && m2 == 0 { ans = "No" }; fmt.Fprintln(wrtr,ans)
		}
	}
}

package main

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

const N = 500000

var mx = [N + 1]bool{}
var my = [N + 1]bool{}

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	var n, q int
	fmt.Fscan(in, &n, &q)
	for i := 0; i < q; i++ {
		var t int
		fmt.Fscan(in, &t)
		if t == 1 {
			var x, y int64
			fmt.Fscan(in, &x, &y)
			mx[x] = true
			my[y] = true
		} else if t == 2 {
			var x, y int64
			fmt.Fscan(in, &x, &y)
			mx[x] = false
			my[y] = false
		} else if t == 3 {
			var x1, y1, x2, y2 int64
			fmt.Fscan(in, &x1, &y1, &x2, &y2)

			f := true
			for k := x1; k <= x2; k++ {
				if !mx[k] {
					f = false
					break
				}
			}

			if !f {
				f = true
				for k := y1; k <= y2; k++ {
					if !my[k] {
						f = false
						break
					}
				}
			}

			if f {
				fmt.Fprintln(out, "Yes")
			} else {
				fmt.Fprintln(out, "No")
			}
		}
	}
}

package main

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

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	var n, q int
	fmt.Fscan(in, &n, &q)
	mx := make([]bool, n+1)
	my := make([]bool, n+1)
	for i := 0; i < q; i++ {
		var t int
		fmt.Fscan(in, &t)
		if t == 1 {
			var x, y int64
			fmt.Fscan(in, &x, &y)
			mx[x] = true
			my[y] = true
		} else if t == 2 {
			var x, y int64
			fmt.Fscan(in, &x, &y)
			mx[x] = false
			my[y] = false
		} else if t == 3 {
			var x1, y1, x2, y2 int64
			fmt.Fscan(in, &x1, &y1, &x2, &y2)

			f1 := true
			for k := x1; k <= x2; k++ {
				if !mx[k] {
					f1 = false
					break
				}
			}

			f2 := true
			for k := y1; k <= y2; k++ {
				if !my[k] {
					f2 = false
					break
				}
			}

			if f1 || f2 {
				fmt.Fprintln(out, "Yes")
			} else {
				fmt.Fprintln(out, "No")
			}
		}
	}
}

package main

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

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	var n, q int
	fmt.Fscan(in, &n, &q)
	mx := make([]bool, n)
	my := make([]bool, n)
	for i := 0; i < q; i++ {
		var t int
		fmt.Fscan(in, &t)
		if t == 1 {
			var x, y int64
			fmt.Fscan(in, &x, &y)
			x--
			y--
			mx[x] = true
			my[y] = true
		} else if t == 2 {
			var x, y int64
			fmt.Fscan(in, &x, &y)
			mx[x] = false
			my[y] = false
		} else if t == 3 {
			var x1, y1, x2, y2 int64
			fmt.Fscan(in, &x1, &y1, &x2, &y2)

			f1 := true
			for k := x1; k <= x2; k++ {
				if !mx[k] {
					f1 = false
					break
				}
			}

			f2 := true
			for k := y1; k <= y2; k++ {
				if !my[k] {
					f2 = false
					break
				}
			}

			if f1 || f2 {
				fmt.Fprintln(out, "Yes")
			} else {
				fmt.Fprintln(out, "No")
			}
		}
	}
}

package main

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

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	var n, q int
	fmt.Fscan(in, &n, &q)
	mx := make([]int, n)
	my := make([]int, n)
	for i := 0; i < q; i++ {
		var t int
		fmt.Fscan(in, &t)
		if t == 1 {
			var x, y int
			fmt.Fscan(in, &x, &y)
			x--
			y--
			mx[x] = 1
			my[y] = 1
		} else if t == 2 {
			var x, y int
			fmt.Fscan(in, &x, &y)
			x--
			y--
			mx[x] = 0
			my[y] = 0
		} else if t == 3 {
			var x1, y1, x2, y2 int
			fmt.Fscan(in, &x1, &y1, &x2, &y2)
			x1--
			y1--
			x2--
			y2--

			f1 := true
			for k := x1; k <= x2; k++ {
				if mx[k] == 0 {
					f1 = false
					break
				}
			}

			f2 := true
			for k := y1; k <= y2; k++ {
				if my[k] == 0 {
					f2 = false
					break
				}
			}

			if f1 || f2 {
				fmt.Fprintln(out, "Yes")
			} else {
				fmt.Fprintln(out, "No")
			}
		}
	}
}

package main

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

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	var n, q int
	fmt.Fscan(in, &n, &q)
	mx := make([]bool, n+1)
	my := make([]bool, n+1)
	for i := 0; i < q; i++ {
		var t int
		fmt.Fscan(in, &t)
		if t == 1 {
			var x, y int
			fmt.Fscan(in, &x, &y)
			mx[x] = true
			my[y] = true
		} else if t == 2 {
			var x, y int
			fmt.Fscan(in, &x, &y)
			mx[x] = false
			my[y] = false
		} else if t == 3 {
			var x1, y1, x2, y2 int
			fmt.Fscan(in, &x1, &y1, &x2, &y2)

			f1 := true
			for k := x1; k <= x2; k++ {
				if !mx[k] {
					f1 = false
					break
				}
			}

			f2 := true
			for k := y1; k <= y2; k++ {
				if !my[k] {
					f2 = false
					break
				}
			}

			if f1 || f2 {
				fmt.Fprintln(out, "Yes")
			} else {
				fmt.Fprintln(out, "No")
			}
		}
	}
}

package main

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

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	var n, q int
	fmt.Fscan(in, &n, &q)
	mx := make([]bool, n+1)
	my := make([]bool, n+1)
	for i := 0; i < q; i++ {
		var t int
		fmt.Fscan(in, &t)
		if t == 1 {
			var x, y int
			fmt.Fscan(in, &x, &y)
			mx[x] = true
			my[y] = true
		} else if t == 2 {
			var x, y int
			fmt.Fscan(in, &x, &y)
			mx[x] = false
			my[y] = false
		} else if t == 3 {
			var x1, y1, x2, y2 int
			fmt.Fscan(in, &x1, &y1, &x2, &y2)

			f := true
			for k := x1; k <= x2; k++ {
				if !mx[k] {
					f = false
					break
				}
			}

			if !f {
				f = true
				for k := y1; k <= y2; k++ {
					if !my[k] {
						f = false
						break
					}
				}
			}
			if f {
				fmt.Fprintln(out, "Yes")
			} else {
				fmt.Fprintln(out, "No")
			}
		}
	}
}

package main

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

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	var n, q int
	fmt.Fscan(in, &n, &q)
	mx := make([]bool, n+1)
	my := make([]bool, n+1)
	for i := 0; i < q; i++ {
		var t int
		fmt.Fscan(in, &t)
		if t == 1 {
			var x, y int
			fmt.Fscan(in, &x, &y)
			mx[x] = true
			my[y] = true
		} else if t == 2 {
			var x, y int
			fmt.Fscan(in, &x, &y)
			mx[x] = false
			my[y] = false
		} else if t == 3 {
			var x1, y1, x2, y2 int
			fmt.Fscan(in, &x1, &y1, &x2, &y2)

			f := true
			for k := x1; k <= x2; k++ {
				if !mx[k] {
					f = false
					break
				}
			}

			if !f {
				f = true
				for k := y1; k <= y2; k++ {
					if !my[k] {
						f = false
						break
					}
				}
			}
			if !f {
				fmt.Fprintln(out, "No")
			} else {
				fmt.Fprintln(out, "Yes")
			}
		}
	}
}

package main

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

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	var n, q int
	fmt.Fscan(in, &n, &q)
	mx := make([]bool, n+1)
	my := make([]bool, n+1)
	for i := 0; i < q; i++ {
		var t int
		fmt.Fscan(in, &t)
		if t == 1 {
			var x, y int
			fmt.Fscan(in, &x, &y)
			mx[x] = true
			my[y] = true
		} else if t == 2 {
			var x, y int
			fmt.Fscan(in, &x, &y)
			mx[x] = false
			my[y] = false
		} else if t == 3 {
			var x1, y1, x2, y2 int
			fmt.Fscan(in, &x1, &y1, &x2, &y2)

			f := true
			for i := x1; i <= x2; i++ {
				if !mx[i] {
					f = false
					break
				}
			}

			if !f {
				f = true
				for i := y1; i <= y2; i++ {
					if !my[i] {
						f = false
						break
					}
				}
			}
			if !f {
				fmt.Fprintln(out, "No")
			} else {
				fmt.Fprintln(out, "Yes")
			}
		}
	}
}

package main

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

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	var n, q int
	fmt.Fscan(in, &n, &q)
	mx := make([]bool, n+1)
	my := make([]bool, n+1)
	var t, x, y int
	for i := 0; i < q; i++ {
		fmt.Fscan(in, &t)
		if t == 1 {
			fmt.Fscan(in, &x, &y)
			mx[x] = true
			my[y] = true
		} else if t == 2 {
			fmt.Fscan(in, &x, &y)
			mx[x] = false
			my[y] = false
		} else {
			var x1, y1, x2, y2 int
			fmt.Fscan(in, &x1, &y1, &x2, &y2)

			f := true
			for i := x1; i <= x2; i++ {
				if !mx[i] {
					f = false
					break
				}
			}

			if !f {
				f = true
				for i := y1; i <= y2; i++ {
					if !my[i] {
						f = false
						break
					}
				}
			}
			if !f {
				fmt.Fprintln(out, "No")
			} else {
				fmt.Fprintln(out, "Yes")
			}

		}
	}
}

package main

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

func main() {
	CF1670C(os.Stdin, os.Stdout)

}

func CF1670C(in io.Reader, out io.Writer) {
	r := bufio.NewReader(in)
	w := bufio.NewWriter(out)
	defer w.Flush()

	const N = 500000

	mx := [N + 1]int{}
	my := [N + 1]int{}
	xr := [N + 1]int{}
	yr := [N + 1]int{}
	var n, q int
	fmt.Fscan(r, &n, &q)

	addX := func(idx, v int) {
		for i := idx; i <= n; i++ {
			mx[i] += v
		}
	}
	addY := func(idx, v int) {
		for i := idx; i <= n; i++ {
			my[i] += v
		}
	}
	prefixX := func(idx int) int {
		var tot int
		for ; idx >= 0; idx-- {
			tot += mx[idx]
		}
		return tot
	}
	prefixY := func(idx int) int {
		var tot int
		for ; idx >= 0; idx-- {
			tot += my[idx]
		}
		return tot
	}

	for ; q > 0; q-- {
		var t int64
		fmt.Fscan(r, &t)
		switch t {
		case 1:
			var x, y int
			fmt.Fscan(r, &x, &y)
			if xr[x] == 0 {
				addX(x, 1)
			}
			if yr[y] == 0 {
				addY(y, 1)
			}

			xr[x]++
			yr[y]++
		case 2:
			var x, y int
			fmt.Fscan(r, &x, &y)
			xr[x]--
			yr[y]--
			if xr[x] == 0 {
				addX(x, -1)
			}
			if yr[y] == 0 {
				addY(y, -1)
			}
		case 3:
			var x1, y1, x2, y2 int
			fmt.Fscan(r, &x1, &y1, &x2, &y2)

			var f bool
			if prefixX(x2)-prefixX(x1-1) >= x2-x1+1 {
				f = true
			}

			if !f {
				if prefixY(y2)-prefixY(y1-1) >= y2-y1+1 {
					f = true
				}
			}
			if f {
				fmt.Fprintln(out, "Yes")
			} else {
				fmt.Fprintln(out, "No")
			}
		}

	}

}

package main

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

func min(a, b int) int {
	if a < b {
		return a
	} else {
		return b
	}
}

func max(a, b int) int {
	if a < b {
		return b
	} else {
		return a
	}
}

type TreeElem interface {
	//Operation(a, b TreeElem) TreeElem
} // should support operation Operation

type Operation func(TreeElem, TreeElem) TreeElem // should have neutralElem; should be distributive

type Segtree struct {
	n           int
	lazyN       int
	op          Operation
	tree        []TreeElem
	neutralElem TreeElem
}

func nextPowerOfTwo(x int) int {
	x--
	x |= x >> 1
	x |= x >> 2
	x |= x >> 4
	x |= x >> 8
	x |= x >> 16
	x++
	return x
}

func NewTree(s []TreeElem, op Operation, neutralElem TreeElem) (*Segtree, error) {
	n := len(s)
	if n == 0 {
		return nil, errors.New("Error: slice is empty")
	}
	if n >= 1<<30 {
		return nil, errors.New("Error: slice is too large")
	}
	lazyN := nextPowerOfTwo(n)
	t := &Segtree{
		n:           n,
		lazyN:       lazyN,
		op:          op,
		tree:        make([]TreeElem, 4*lazyN),
		neutralElem: neutralElem,
	}
	t.build(s)
	return t, nil
}

func (t *Segtree) build(s []TreeElem) { // should only be called in NewTree function
	for i := 0; i < t.n; i++ {
		t.tree[t.lazyN-1+i] = s[i]
	}
	for i := t.n; i < t.lazyN; i++ {
		t.tree[t.lazyN-1+i] = t.neutralElem
	}
	for i := t.lazyN - 2; i >= 0; i-- {
		t.tree[i] = t.op(t.tree[2*i+1], t.tree[2*i+2])
	}
}

func (t Segtree) implQuery(left, right int) TreeElem {
	leftRes := t.neutralElem
	rightRes := t.neutralElem
	for left < right {
		if left%2 == 0 {
			leftRes = t.op(leftRes, t.tree[left])
		}
		//left--
		left /= 2
		if right%2 == 1 {
			rightRes = t.op(t.tree[right], rightRes)
		}
		//right--
		right /= 2
		right--
	}
	if left == right {
		leftRes = t.op(leftRes, t.tree[left]) //left
	}
	return t.op(leftRes, rightRes)
}

func (t Segtree) Query(left, right int) (TreeElem, error) {
	if left < 0 || right >= t.n {
		return nil, errors.New(fmt.Sprintf("Incorrect query range; indexes should be in [0, %d]", t.n-1))
	}
	return t.implQuery(left+t.lazyN-1, right+t.lazyN-1), nil
}

func (t *Segtree) Set(index int, value TreeElem) error {
	if index < 0 || index >= t.n {
		return errors.New(fmt.Sprintf("Incorrect query range; indexes should be in [0, %d]", t.n-1))
	}
	i := t.lazyN - 1 + index
	t.tree[i] = value
	for par := (i - 1) >> 1; par >= 0; par = (i - 1) >> 1 {
		if i%2 == 0 {
			t.tree[par] = t.op(t.tree[i], t.tree[i-1])
		} else {
			t.tree[par] = t.op(t.tree[i-1], t.tree[i])
		}
		i = par
	}
	return nil
}

func (t *Segtree) Apply(index int, value TreeElem) error { // Apply Operation(elem[index], value)
	if index < 0 || index >= t.n {
		return errors.New(fmt.Sprintf("Incorrect query range; indexes should be in [0, %d]", t.n-1))
	}
	i := t.lazyN - 1 + index
	t.tree[i] = t.op(t.tree[i], value)
	for par := (i - 1) >> 1; par >= 0; par = (i - 1) >> 1 {
		if i%2 == 0 {
			t.tree[par] = t.op(t.tree[i], t.tree[i-1])
		} else {
			t.tree[par] = t.op(t.tree[i-1], t.tree[i])
		}
		i = par
	}
	return nil
}

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()
	var n, q int
	fmt.Fscan(in, &n, &q)
	x := make([]TreeElem, n)
	y := make([]TreeElem, n)
	for i := 0; i < n; i++ {
		x[i] = 0
		y[i] = 0
	}
	tx, _ := NewTree(x, func(a, b TreeElem) TreeElem { return min(a.(int), b.(int)) }, 1000000)
	ty, _ := NewTree(y, func(a, b TreeElem) TreeElem { return min(a.(int), b.(int)) }, 1000000)
	for iii := 0; iii < q; iii++ {
		var qtype int
		fmt.Fscan(in, &qtype)
		switch qtype {
		case 1:
			var x1, y1 int
			fmt.Fscan(in, &x1, &y1)
			x1--
			y1--
			//fmt.Println("type1!!!", x1, y1)
			res, _ := tx.Query(x1, x1)
			tx.Set(x1, res.(int)+1)
			//fmt.Println("type1!!!", res)
			res, _ = ty.Query(y1, y1)
			ty.Set(y1, res.(int)+1)
			//fmt.Println("type1!!!", res)
		case 2:
			var x1, y1 int
			fmt.Fscan(in, &x1, &y1)
			x1--
			y1--
			//fmt.Println("type2!!!", x1, y1)
			res, _ := tx.Query(x1, x1)
			tx.Set(x1, res.(int)-1)
			//fmt.Println("type2!!!", res)
			res, _ = ty.Query(y1, y1)
			ty.Set(y1, res.(int)-1)
			//fmt.Println("type2!!!", res)
		case 3:
			var x1, x2, y1, y2 int
			fmt.Fscan(in, &x1, &y1, &x2, &y2)
			x1--
			x2--
			y1--
			y2--
			res1, _ := tx.Query(x1, x2)
			res2, _ := ty.Query(y1, y2)
			//fmt.Println("type3!!!", x1, x2, y1, y2, res1, res2)
			// tmp, _ := tx.Query(1, 1)
			// //fmt.Println("!--!", tmp)
			// tmp, _ = tx.Query(2, 2)
			// //fmt.Println("!--!", tmp)
			// tmp, _ = tx.Query(3, 3)
			// //fmt.Println("!--!", tmp)
			// tmp, _ = tx.Query(1, 2)
			// //fmt.Println("!--!", tmp)
			// tmp, _ = tx.Query(2, 3)
			// //fmt.Println("!--!", tmp)
			// tmp, _ = tx.Query(1, 3)
			// //fmt.Println("!--!", tmp)
			res := max(res1.(int), res2.(int))
			if res != 0 {
				fmt.Fprintln(out, "Yes")
			} else {
				fmt.Fprintln(out, "No")
			}
		}
	}
}

package main

import (
	"bufio"
	"errors"
	"fmt"
	"math"
	"os"
)

func min(a, b int) int {
	if a < b {
		return a
	} else {
		return b
	}
}

// code for tree is from  https://github.com/ideahitme/segment/blob/master/tree.go
//
// Tree implementation of segment tree

// Tree segment tree implementation
type Tree struct {
	realSize  int      // real size of the array on which queries are performed
	nodes     []int    // nodes stored in the tree. it is slice of size about ~2*realSize
	lazyNodes []int    // stores intermediate values on the tree for updates; for lazy propagation
	treeFunc  TreeFunc // defines the type of queries supported
}

// NewTree returns Tree object
// x - defines the array where queries will be performed
// fn - defines what kind of queries are to be performed
func NewTree(x []int, fn TreeFunc) (*Tree, error) {
	if len(x) == 0 {
		return nil, errors.New("segment tree cannot be instantiated on empty slice ")
	}
	//determine number of nodes
	size := calculateTreeSize(len(x))
	t := &Tree{
		nodes:     make([]int, size),
		lazyNodes: make([]int, size),
		treeFunc:  fn,
		realSize:  len(x),
	}
	t.init(0, 0, len(x)-1, x)
	return t, nil
}

// init recursively fills in values in the tree
func (t *Tree) init(curNode, curLeft, curRight int, x []int) {
	if curLeft == curRight {
		t.nodes[curNode] = x[curLeft]
		return
	}
	middle := (curLeft + curRight) / 2
	t.init(2*curNode+1, curLeft, middle, x)
	t.init(2*curNode+2, middle+1, curRight, x)
	t.nodes[curNode] = t.treeFunc.Select(t.nodes[2*curNode+1], t.nodes[2*curNode+2])
}

// RQ - range query based on the specified TreeFunc
func (t *Tree) RQ(left, right int) (int, error) {
	if left > right || left < 0 || right >= t.realSize {
		return 0, errors.New("range out of bonds")
	}
	return t.callRQ(0, left, right, 0, t.realSize-1), nil
}

// callRQ recursively calculates the answer to range query
func (t *Tree) callRQ(curNode, rangeLeft, rangeRight, curLeft, curRight int) int {
	t.applyLazyPropagate(curNode) // respect range update
	if curLeft > rangeRight || curRight < rangeLeft {
		return t.treeFunc.Outlier()
	}
	if curLeft >= rangeLeft && curRight <= rangeRight {
		return t.nodes[curNode]
	}
	middle := (curLeft + curRight) / 2
	return t.treeFunc.Select(
		t.callRQ(2*curNode+1, rangeLeft, rangeRight, curLeft, middle),
		t.callRQ(2*curNode+2, rangeLeft, rangeRight, middle+1, curRight),
	)
}

// Add increments all numbers in the range [l:r] by x
func (t *Tree) Add(x, left, right int) error {
	if left > right || left < 0 || right >= t.realSize {
		return errors.New("range out of bonds")
	}
	t.callAdd(0, left, right, 0, t.realSize-1, x)
	return nil
}

// callAdd recursively adds `x` to all numbers in [rangeLeft:rangeRight]
func (t *Tree) callAdd(curNode, rangeLeft, rangeRight, curLeft, curRight, x int) {
	t.applyLazyPropagate(curNode)
	if curLeft > rangeRight || curRight < rangeLeft {
		return
	}
	if curLeft >= rangeLeft && curRight <= rangeRight {
		t.lazyNodes[curNode] += x
		t.applyLazyPropagate(curNode)
		return
	}
	middle := (curLeft + curRight) / 2
	t.callAdd(2*curNode+1, rangeLeft, rangeRight, curLeft, middle, x)
	t.callAdd(2*curNode+2, rangeLeft, rangeRight, middle+1, curRight, x)
	t.nodes[curNode] = t.treeFunc.Select(
		t.nodes[2*curNode+1],
		t.nodes[2*curNode+2],
	)
}

// applyLazyPropagate applies and propagates whatever is stored in the lazy node
func (t *Tree) applyLazyPropagate(curNode int) {
	t.nodes[curNode] += t.lazyNodes[curNode]
	if 2*curNode+2 < len(t.lazyNodes) {
		t.lazyNodes[2*curNode+1] += t.lazyNodes[curNode]
		t.lazyNodes[2*curNode+2] += t.lazyNodes[curNode]
	}
	t.lazyNodes[curNode] = 0
}

// calculateTreeSize returns the size of the supplementary array storing
// intermediate nodes and values, roughly equal to ~ 2*x - 1, where
// x is the size of the original array being operated on
func calculateTreeSize(x int) int {
	logX := math.Log2(float64(x))
	ceilLogX := uint(math.Ceil(logX))
	return 2*1<<ceilLogX - 1
}

// TreeFunc interface defines the type of queries to be performed on the tree
type TreeFunc interface {
	Outlier() int        //should return value which can be discarded when passed to Select
	Select(x, y int) int //should return selected value among two integers
}

// MinFunc implements TreeFunc and supports Range Minimum Query
type MinFunc struct{}

// Outlier returns maximum integer number; it is returned when we are out of boundary of the original array
func (f MinFunc) Outlier() int {
	return math.MaxInt32
}

// Select selects the minimum of two numbers
func (f MinFunc) Select(x, y int) int {
	if x < y {
		return x
	}
	return y
}

// MaxFunc implements TreeFunc and supports Range Maximum Query
type MaxFunc struct{}

// Outlier returns minimum integer number; it is returned when we are out of boundary of the original array
func (f MaxFunc) Outlier() int {
	return math.MinInt32
}

// Select selects the maximum of two numbers
func (f MaxFunc) Select(x, y int) int {
	if x > y {
		return x
	}
	return y
}

func main() {
	scanner := bufio.NewReader(os.Stdin)
	writer := bufio.NewWriter(os.Stdout)
	defer writer.Flush()
	var n, q int
	fmt.Fscan(scanner, &n, &q)
	xArr := make([]int, n+1)
	yArr := make([]int, n+1)
	xTree, _ := NewTree(xArr, MinFunc{})
	yTree, _ := NewTree(yArr, MinFunc{})
	for i := 0; i < q; i++ {
		var sw int
		fmt.Fscan(scanner, &sw)
		switch sw {
		case 1:
			var x, y int
			fmt.Fscan(scanner, &x, &y)
			xTree.Add(1, x, x)
			yTree.Add(1, y, y)
		case 2:
			var x, y int
			fmt.Fscan(scanner, &x, &y)
			xTree.Add(-1, x, x)
			yTree.Add(-1, y, y)
		case 3:
			var x1, y1, x2, y2 int
			fmt.Fscan(scanner, &x1, &y1, &x2, &y2)
			val1, _ := xTree.RQ(x1, x2)
			val2, _ := yTree.RQ(y1, y2)
			if val1 == 1 || val2 == 1 {
				fmt.Fprintln(writer, "Yes")
			} else {
				fmt.Fprintln(writer, "No")
			}
		}
	}
}

package main

import (
	"bufio"
	"errors"
	"fmt"
	"math"
	"os"
)

func min(a, b int) int {
	if a < b {
		return a
	} else {
		return b
	}
}

// code for tree is from  https://github.com/ideahitme/segment/blob/master/tree.go
//
// Tree implementation of segment tree

// Tree segment tree implementation
type Tree struct {
	realSize  int      // real size of the array on which queries are performed
	nodes     []int    // nodes stored in the tree. it is slice of size about ~2*realSize
	lazyNodes []int    // stores intermediate values on the tree for updates; for lazy propagation
	treeFunc  TreeFunc // defines the type of queries supported
}

// NewTree returns Tree object
// x - defines the array where queries will be performed
// fn - defines what kind of queries are to be performed
func NewTree(x []int, fn TreeFunc) (*Tree, error) {
	if len(x) == 0 {
		return nil, errors.New("segment tree cannot be instantiated on empty slice ")
	}
	//determine number of nodes
	size := calculateTreeSize(len(x))
	t := &Tree{
		nodes:     make([]int, size),
		lazyNodes: make([]int, size),
		treeFunc:  fn,
		realSize:  len(x),
	}
	t.init(0, 0, len(x)-1, x)
	return t, nil
}

// init recursively fills in values in the tree
func (t *Tree) init(curNode, curLeft, curRight int, x []int) {
	if curLeft == curRight {
		t.nodes[curNode] = x[curLeft]
		return
	}
	middle := (curLeft + curRight) / 2
	t.init(2*curNode+1, curLeft, middle, x)
	t.init(2*curNode+2, middle+1, curRight, x)
	t.nodes[curNode] = t.treeFunc.Select(t.nodes[2*curNode+1], t.nodes[2*curNode+2])
}

// RQ - range query based on the specified TreeFunc
func (t *Tree) RQ(left, right int) (int, error) {
	if left > right || left < 0 || right >= t.realSize {
		return 0, errors.New("range out of bonds")
	}
	return t.callRQ(0, left, right, 0, t.realSize-1), nil
}

// callRQ recursively calculates the answer to range query
func (t *Tree) callRQ(curNode, rangeLeft, rangeRight, curLeft, curRight int) int {
	t.applyLazyPropagate(curNode) // respect range update
	if curLeft > rangeRight || curRight < rangeLeft {
		return t.treeFunc.Outlier()
	}
	if curLeft >= rangeLeft && curRight <= rangeRight {
		return t.nodes[curNode]
	}
	middle := (curLeft + curRight) / 2
	return t.treeFunc.Select(
		t.callRQ(2*curNode+1, rangeLeft, rangeRight, curLeft, middle),
		t.callRQ(2*curNode+2, rangeLeft, rangeRight, middle+1, curRight),
	)
}

// Add increments all numbers in the range [l:r] by x
func (t *Tree) Add(x, left, right int) error {
	if left > right || left < 0 || right >= t.realSize {
		return errors.New("range out of bonds")
	}
	t.callAdd(0, left, right, 0, t.realSize-1, x)
	return nil
}

// callAdd recursively adds `x` to all numbers in [rangeLeft:rangeRight]
func (t *Tree) callAdd(curNode, rangeLeft, rangeRight, curLeft, curRight, x int) {
	t.applyLazyPropagate(curNode)
	if curLeft > rangeRight || curRight < rangeLeft {
		return
	}
	if curLeft >= rangeLeft && curRight <= rangeRight {
		t.lazyNodes[curNode] += x
		t.applyLazyPropagate(curNode)
		return
	}
	middle := (curLeft + curRight) / 2
	t.callAdd(2*curNode+1, rangeLeft, rangeRight, curLeft, middle, x)
	t.callAdd(2*curNode+2, rangeLeft, rangeRight, middle+1, curRight, x)
	t.nodes[curNode] = t.treeFunc.Select(
		t.nodes[2*curNode+1],
		t.nodes[2*curNode+2],
	)
}

// applyLazyPropagate applies and propagates whatever is stored in the lazy node
func (t *Tree) applyLazyPropagate(curNode int) {
	t.nodes[curNode] += t.lazyNodes[curNode]
	if 2*curNode+2 < len(t.lazyNodes) {
		t.lazyNodes[2*curNode+1] += t.lazyNodes[curNode]
		t.lazyNodes[2*curNode+2] += t.lazyNodes[curNode]
	}
	t.lazyNodes[curNode] = 0
}

// calculateTreeSize returns the size of the supplementary array storing
// intermediate nodes and values, roughly equal to ~ 2*x - 1, where
// x is the size of the original array being operated on
func calculateTreeSize(x int) int {
	logX := math.Log2(float64(x))
	ceilLogX := uint(math.Ceil(logX))
	return 2*1<<ceilLogX - 1
}

// TreeFunc interface defines the type of queries to be performed on the tree
type TreeFunc interface {
	Outlier() int        //should return value which can be discarded when passed to Select
	Select(x, y int) int //should return selected value among two integers
}

// MinFunc implements TreeFunc and supports Range Minimum Query
type MinFunc struct{}

// Outlier returns maximum integer number; it is returned when we are out of boundary of the original array
func (f MinFunc) Outlier() int {
	return math.MaxInt32
}

// Select selects the minimum of two numbers
func (f MinFunc) Select(x, y int) int {
	if x < y {
		return x
	}
	return y
}

// MaxFunc implements TreeFunc and supports Range Maximum Query
type MaxFunc struct{}

// Outlier returns minimum integer number; it is returned when we are out of boundary of the original array
func (f MaxFunc) Outlier() int {
	return math.MinInt32
}

// Select selects the maximum of two numbers
func (f MaxFunc) Select(x, y int) int {
	if x > y {
		return x
	}
	return y
}

func main() {
	scanner := bufio.NewReader(os.Stdin)
	writer := bufio.NewWriter(os.Stdout)
	defer writer.Flush()
	var n, q int
	fmt.Fscan(scanner, &n, &q)
	xArr := make([]int, n)
	yArr := make([]int, n)
	xTree, _ := NewTree(xArr, MinFunc{})
	yTree, _ := NewTree(yArr, MinFunc{})
	for i := 0; i < q; i++ {
		var sw int
		fmt.Fscan(scanner, &sw)
		switch sw {
		case 1:
			var x, y int
			fmt.Fscan(scanner, &x, &y)
			xTree.Add(1, x, x)
			yTree.Add(1, y, y)
		case 2:
			var x, y int
			fmt.Fscan(scanner, &x, &y)
			xTree.Add(-1, x, x)
			yTree.Add(-1, y, y)
		case 3:
			var x1, y1, x2, y2 int
			fmt.Fscan(scanner, &x1, &y1, &x2, &y2)
			val1, _ := xTree.RQ(x1, x2)
			val2, _ := yTree.RQ(y1, y2)
			if val1 == 1 || val2 == 1 {
				fmt.Fprintln(writer, "Yes")
			} else {
				fmt.Fprintln(writer, "No")
			}
		}
	}
}

package main

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

var r = bufio.NewReader(os.Stdin)
var w = bufio.NewWriter(os.Stdout)

func main() {
	defer w.Flush()
	var n, q int
	fmt.Fscan(r, &n, &q)
	f1, f2 := newLazySegmentTree(make([]int64, n+1)), newLazySegmentTree(make([]int64, n+1))
	cnt1, cnt2 := make([]int, n+1), make([]int, n+1)
	for qq:=0;qq<q;qq++ {
		var t int
		fmt.Fscan(r, &t)
		if t == 1 {
			var x, y int
			fmt.Fscan(r, &x, &y)
			cnt1[x]++
			cnt2[x]++
			f1.update(1, x, x, 1)
			f2.update(1, y, y, 1)
		} else if t == 2 {
			var x, y int
			fmt.Fscan(r, &x, &y)
			cnt1[x]--
			if cnt1[x] == 0 {
				f1.update(1, x, x, 0)
			}
			cnt2[x]--
			if cnt2[y] == 0 {
				f2.update(1, y, y, 0)
			}
		} else {
			var x1, y1, x2, y2 int
			fmt.Fscan(r, &x1, &y1)
			fmt.Fscan(r, &x2, &y2)
			if int(f1.query(1, x1, x2)) < x2 - x1 + 1 && int(f2.query(1, y1, y2)) < y2 - y1 + 1 {
				fmt.Fprintln(w, "No")
			} else {
				fmt.Fprintln(w, "Yes")
			}
		}
	}
}

type lazyST []struct {
	l, r int
	todo int64
	lazy bool // 支持区间修改为某一个值
	sum  int64 // 根据需要修改
}

// 线段树定义的操作，可修改
func (lazyST) op(a, b int64) int64 {
	return a + b
}

// 根据子节点修改节点
func (t lazyST) maintain(o int) {
	lo, ro := t[o<<1], t[o<<1|1]
	t[o].sum = t.op(lo.sum, ro.sum)
}

// 根据数组构建线段树，下标从 1 开始
func (t lazyST) build(a []int64, o, l, r int) {
	t[o].l, t[o].r = l, r
	if l == r {
		t[o].sum = a[l-1]
		return
	}
	m := (l + r) >> 1
	t.build(a, o<<1, l, m)
	t.build(a, o<<1|1, m+1, r)
	t.maintain(o)
}

// 对节点 o 表示的区间的所有元素加上 add
// 如果要实现区间修改为某一个值而不是加上某一个值的话，将 += 变为 = 即可
func (t lazyST) do(o int, add int64) {
	to := &t[o]
	to.todo = add                     // % mod
	to.lazy = true
	to.sum = int64(to.r-to.l+1) * add // % mod
}

// 懒标记下放
func (t lazyST) spread(o int) {
	if t[o].lazy {
		add := t[o].todo
		t.do(o<<1, add)
		t.do(o<<1|1, add)
		t[o].todo = 0
		t[o].lazy = false
	}
}

// 对 o 表示的区间中属于 [l, r] 的元素进行修改
func (t lazyST) update(o, l, r int, add int64) {
	if l <= t[o].l && t[o].r <= r {
		// 是 [l, r] 的子集，全部修改
		t.do(o, add)
		return
	}
	t.spread(o)
	m := (t[o].l + t[o].r) >> 1
	if l <= m {
		t.update(o<<1, l, r, add)
	}
	if m < r {
		t.update(o<<1|1, l, r, add)
	}
	t.maintain(o)
}

// o=1  [l,r] 1<=l<=r<=n
func (t lazyST) query(o, l, r int) int64 {
	if l <= t[o].l && t[o].r <= r {
		return t[o].sum
	}
	t.spread(o)
	m := (t[o].l + t[o].r) >> 1
	if r <= m {
		return t.query(o<<1, l, r)
	}
	if m < l {
		return t.query(o<<1|1, l, r)
	}
	vl := t.query(o<<1, l, r)
	vr := t.query(o<<1|1, l, r)
	return t.op(vl, vr)
}

func (t lazyST) queryAll() int64 { return t[1].sum }

// a 从 0 开始
func newLazySegmentTree(a []int64) lazyST {
	t := make(lazyST, 4*len(a))
	t.build(a, 1, 1, len(a))
	return t
}

package main

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

var r = bufio.NewReader(os.Stdin)
var w = bufio.NewWriter(os.Stdout)

func main() {
	defer w.Flush()
	var n, q int
	fmt.Fscan(r, &n, &q)
	f1, f2 := newLazySegmentTree(make([]int64, n+5)), newLazySegmentTree(make([]int64, n+5))
	for qq:=0;qq<q;qq++ {
		var t int
		fmt.Fscan(r, &t)
		if t == 1 {
			var x, y int
			fmt.Fscan(r, &x, &y)
			f1.update(1, x, x, 1)
			f2.update(1, y, y, 1)
		} else if t == 2 {
			var x, y int
			fmt.Fscan(r, &x, &y)
			f1.update(1, x, x, -1)
			f2.update(1, y, y, -1)
		} else {
			var x1, y1, x2, y2 int
			fmt.Fscan(r, &x1, &y1)
			fmt.Fscan(r, &x2, &y2)
			if (f1.query(1, x1, x2)) == int64(x2 - x1 + 1) || (f2.query(1, y1, y2)) == int64(y2 - y1 + 1) {
				fmt.Fprintln(w, "Yes")
			} else {
				fmt.Fprintln(w, "No")
			}
		}
	}
}

type lazyST []struct {
	l, r int
	todo int64
	lazy bool // 支持区间修改为某一个值
	sum  int64 // 根据需要修改
}

// 线段树定义的操作，可修改
func (lazyST) op(a, b int64) int64 {
	return a + b // % mod
}

// 根据子节点修改节点
func (t lazyST) maintain(o int) {
	lo, ro := t[o<<1], t[o<<1|1]
	t[o].sum = t.op(lo.sum, ro.sum)
}

// 根据数组构建线段树，下标从 1 开始
func (t lazyST) build(a []int64, o, l, r int) {
	t[o].l, t[o].r = l, r
	if l == r {
		t[o].sum = a[l-1]
		return
	}
	m := (l + r) >> 1
	t.build(a, o<<1, l, m)
	t.build(a, o<<1|1, m+1, r)
	t.maintain(o)
}

// 对节点 o 表示的区间的所有元素加上 add
// 如果要实现区间修改为某一个值而不是加上某一个值的话，将 += 变为 = 即可
func (t lazyST) do(o int, add int64) {
	to := &t[o]
	to.todo += add                     // % mod
	to.lazy = true
	to.sum += int64(to.r-to.l+1) * add // % mod
}

// 懒标记下放
func (t lazyST) spread(o int) {
	if t[o].lazy {
		add := t[o].todo
		t.do(o<<1, add)
		t.do(o<<1|1, add)
		t[o].todo = 0
		t[o].lazy = false
	}
}

// 对 o 表示的区间中属于 [l, r] 的元素进行修改
func (t lazyST) update(o, l, r int, add int64) {
	if l <= t[o].l && t[o].r <= r {
		// 是 [l, r] 的子集，全部修改
		t.do(o, add)
		return
	}
	t.spread(o)
	m := (t[o].l + t[o].r) >> 1
	if l <= m {
		t.update(o<<1, l, r, add)
	}
	if m < r {
		t.update(o<<1|1, l, r, add)
	}
	t.maintain(o)
}

// o=1  [l,r] 1<=l<=r<=n
func (t lazyST) query(o, l, r int) int64 {
	if l <= t[o].l && t[o].r <= r {
		return t[o].sum
	}
	t.spread(o)
	m := (t[o].l + t[o].r) >> 1
	if r <= m {
		return t.query(o<<1, l, r)
	}
	if m < l {
		return t.query(o<<1|1, l, r)
	}
	vl := t.query(o<<1, l, r)
	vr := t.query(o<<1|1, l, r)
	return t.op(vl, vr)
}

func (t lazyST) queryAll() int64 { return t[1].sum }

// a 从 0 开始
func newLazySegmentTree(a []int64) lazyST {
	t := make(lazyST, 4*len(a))
	t.build(a, 1, 1, len(a))
	return t
}

package main

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

var r = bufio.NewReader(os.Stdin)
var w = bufio.NewWriter(os.Stdout)

func main() {
	defer w.Flush()
	var n, q int
	fmt.Fscan(r, &n, &q)
	f1, f2 := newLazySegmentTree(make([]int64, n+1)), newLazySegmentTree(make([]int64, n+1))
	for qq:=0;qq<q;qq++ {
		var t int
		fmt.Fscan(r, &t)
		if t == 1 {
			var x, y int
			fmt.Fscan(r, &x, &y)
			f1.update(1, x, x, 1)
			f2.update(1, y, y, 1)
		} else if t == 2 {
			var x, y int
			fmt.Fscan(r, &x, &y)
			f1.update(1, x, x, 0)
			f2.update(1, y, y, 0)
		} else {
			var x1, y1, x2, y2 int
			fmt.Fscan(r, &x1, &y1)
			fmt.Fscan(r, &x2, &y2)
			if int(f1.query(1, x1, x2)) < x2 - x1 + 1 && int(f2.query(1, y1, y2)) < y2 - y1 + 1 {
				fmt.Fprintln(w, "No")
			} else {
				fmt.Fprintln(w, "Yes")
			}
		}
	}
}

type lazyST []struct {
	l, r int
	todo int64
	lazy bool // 支持区间修改为某一个值
	sum  int64 // 根据需要修改
}

// 线段树定义的操作，可修改
func (lazyST) op(a, b int64) int64 {
	return a + b // % mod
}

// 根据子节点修改节点
func (t lazyST) maintain(o int) {
	lo, ro := t[o<<1], t[o<<1|1]
	t[o].sum = t.op(lo.sum, ro.sum)
}

// 根据数组构建线段树，下标从 1 开始
func (t lazyST) build(a []int64, o, l, r int) {
	t[o].l, t[o].r = l, r
	if l == r {
		t[o].sum = a[l-1]
		return
	}
	m := (l + r) >> 1
	t.build(a, o<<1, l, m)
	t.build(a, o<<1|1, m+1, r)
	t.maintain(o)
}

// 对节点 o 表示的区间的所有元素加上 add
// 如果要实现区间修改为某一个值而不是加上某一个值的话，将 += 变为 = 即可
func (t lazyST) do(o int, add int64) {
	to := &t[o]
	to.todo = add                     // % mod
	to.lazy = true
	to.sum = int64(to.r-to.l+1) * add // % mod
}

// 懒标记下放
func (t lazyST) spread(o int) {
	if t[o].lazy {
		add := t[o].todo
		t.do(o<<1, add)
		t.do(o<<1|1, add)
		t[o].todo = 0
		t[o].lazy = false
	}
}

// 对 o 表示的区间中属于 [l, r] 的元素进行修改
func (t lazyST) update(o, l, r int, add int64) {
	if l <= t[o].l && t[o].r <= r {
		// 是 [l, r] 的子集，全部修改
		t.do(o, add)
		return
	}
	t.spread(o)
	m := (t[o].l + t[o].r) >> 1
	if l <= m {
		t.update(o<<1, l, r, add)
	}
	if m < r {
		t.update(o<<1|1, l, r, add)
	}
	t.maintain(o)
}

// o=1  [l,r] 1<=l<=r<=n
func (t lazyST) query(o, l, r int) int64 {
	if l <= t[o].l && t[o].r <= r {
		return t[o].sum
	}
	t.spread(o)
	m := (t[o].l + t[o].r) >> 1
	if r <= m {
		return t.query(o<<1, l, r)
	}
	if m < l {
		return t.query(o<<1|1, l, r)
	}
	vl := t.query(o<<1, l, r)
	vr := t.query(o<<1|1, l, r)
	return t.op(vl, vr)
}

func (t lazyST) queryAll() int64 { return t[1].sum }

// a 从 0 开始
func newLazySegmentTree(a []int64) lazyST {
	t := make(lazyST, 4*len(a))
	t.build(a, 1, 1, len(a))
	return t
}

package main

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

// 结构体写法
type fenwick struct {
	tree []int64
}

func newFenwickTree(n int) fenwick {
	return fenwick{make([]int64, n+1)}
}

// 位置 i 增加 val
// 1<=i<=n
func (f fenwick) add(i int, val int64) {
	for ; i < len(f.tree); i += i & -i {
		f.tree[i] += val
	}
}

// 求前缀和 [0,i]
// 0<=i<=n
func (f fenwick) sum(i int) (res int64) {
	for ; i > 0; i &= i - 1 {
		res += f.tree[i]
	}
	return
}

// 求区间和 [l,r]
// 1<=l<=r<=n
func (f fenwick) query(l, r int) int64 {
	return f.sum(r) - f.sum(l-1)
}

func main_div2_791_C() {
	_in, _out := os.Stdin, os.Stdout
	in, out := bufio.NewReader(_in), bufio.NewWriter(_out)
	defer out.Flush()
	var cas int = 1
	//Fscan(in, &cas)
	var sol func()
	// Coding...beg!
	sol = func() {
		var n, q int
		Fscan(in, &n, &q)
		row := newFenwickTree(n)
		col := newFenwickTree(n)
		for i := 0; i < q; i++ {
			var t, x, y, x1, y1, x2, y2 int
			Fscan(in, &t)
			if t == 1 {
				Fscan(in, &x, &y)
				row.add(x, -row.query(x, x))
				row.add(x, 1)
				col.add(y, -col.query(y, y))
				col.add(y, 1)
			} else if t == 2 {
				Fscan(in, &x, &y)
				row.add(x, -1)
				col.add(y, -1)
			} else {
				Fscan(in, &x1, &y1, &x2, &y2)
				if row.query(x1, x2) == int64(x2-x1+1) || col.query(y1, y2) == int64(y2-y1+1) {
					Fprintln(out, "Yes")
				} else {
					Fprintln(out, "No")
				}
			}
		}
	}
	// Coding...ove!
	for i := 0; i < cas; i++ {
		sol()
	}
}

func main() {
	main_div2_791_C()
}

package main

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

// 结构体写法
type fenwick struct {
	tree []int64
}

func newFenwickTree(n int) fenwick {
	return fenwick{make([]int64, n+1)}
}

// 位置 i 增加 val
// 1<=i<=n
func (f fenwick) add(i int, val int64) {
	for ; i < len(f.tree); i += i & -i {
		f.tree[i] += val
	}
}

// 求前缀和 [0,i]
// 0<=i<=n
func (f fenwick) sum(i int) (res int64) {
	for ; i > 0; i &= i - 1 {
		res += f.tree[i]
	}
	return
}

// 求区间和 [l,r]
// 1<=l<=r<=n
func (f fenwick) query(l, r int) int64 {
	return f.sum(r) - f.sum(l-1)
}

func main_div2_791_C() {
	_in, _out := os.Stdin, os.Stdout
	in, out := bufio.NewReader(_in), bufio.NewWriter(_out)
	defer out.Flush()
	var cas int = 1
	//Fscan(in, &cas)
	var sol func()
	// Coding...beg!
	sol = func() {
		var n, q int
		Fscan(in, &n, &q)
		row := newFenwickTree(n)
		col := newFenwickTree(n)
		for i := 0; i < q; i++ {
			var t, x, y, x1, y1, x2, y2 int
			Fscan(in, &t)
			if t == 1 {
				Fscan(in, &x, &y)
				row.add(x, 1)
				col.add(y, 1)
			} else if t == 2 {
				Fscan(in, &x, &y)
				row.add(x, -1)
				col.add(y, -1)
			} else {
				Fscan(in, &x1, &y1, &x2, &y2)
				if row.query(x1, x2) == int64(x2-x1+1) || col.query(y1, y2) == int64(y2-y1+1) {
					Fprintln(out, "Yes")
				} else {
					Fprintln(out, "No")
				}
			}
		}
	}
	// Coding...ove!
	for i := 0; i < cas; i++ {
		sol()
	}
}

func main() {
	main_div2_791_C()
}


package main

import (
	"bufio"

	"io"
	"os"
	"sort"
	"strconv"
)

type Scanner struct {
	r            io.Reader
	split        bufio.SplitFunc
	maxTokenSize int
	token, buf   []byte
	start, end   int
}

func NewScanner(r io.Reader) *Scanner {
	return &Scanner{
		r:            r,
		split:        bufio.ScanWords,
		maxTokenSize: 16777216,
		buf:          make([]byte, 4096),
	}
}

func (s *Scanner) advance(n int) bool {
	if n < 0 || n > s.end-s.start {
		return false
	}
	s.start += n
	return true
}

func (s *Scanner) Text() string {
	return string(s.token)
}

func (s *Scanner) Scan() bool {
	for {
		if s.end > s.start {
			advance, token, err := s.split(s.buf[s.start:s.end], false)
			if err != nil || !s.advance(advance) {
				return false
			}
			s.token = token
			if token != nil {
				return true
			}
		}
		if s.start > 0 && (s.end == len(s.buf) || s.start > len(s.buf)/2) {
			copy(s.buf, s.buf[s.start:s.end])
			s.end -= s.start
			s.start = 0
		}
		if s.end == len(s.buf) {
			if len(s.buf) >= s.maxTokenSize {
				return false
			}
			newSize := len(s.buf) * 2
			if newSize > s.maxTokenSize {
				newSize = s.maxTokenSize
			}
			newBuf := make([]byte, newSize)
			copy(newBuf, s.buf[s.start:s.end])
			s.buf = newBuf
			s.end -= s.start
			s.start = 0
			continue
		}
		for loop := 0; ; {
			n, _ := s.r.Read(s.buf[s.end:len(s.buf)])
			s.end += n
			if n > 0 {
				break
			}
			loop++
			if loop > 100 {
				break
			}
		}
	}
}

func (s *Scanner) Split(split bufio.SplitFunc) {
	s.split = split
}

var w *bufio.Writer = bufio.NewWriter(os.Stdout)
var sc *Scanner = NewScanner(os.Stdin)

func next() string { sc.Scan(); return sc.Text() }

func ni32() int {
	sc.Scan()
	n, _ := strconv.Atoi(sc.Text())
	return n
}

func ni64() int64 {
	sc.Scan()
	n, _ := strconv.ParseInt(sc.Text(), 10, 64)
	return n
}

func pri32(i ...int) {
	for _, ii := range i {
		w.WriteString(strconv.Itoa(ii))
		// sp()
	}
}
func pri64(i ...int64) {
	for _, ii := range i {
		w.WriteString(strconv.FormatInt(ii, 10))
		sp()
	}
}
func sp()   { w.WriteByte(' ') }
func endl() { w.WriteByte('\n') }

func min(i, j int) int {
	if i < j {
		return i
	}
	return j
}

func max(i, j int) int {
	if i > j {
		return i
	}
	return j
}

type Int64Slice []int64

func (slice Int64Slice) Len() int           { return len(slice) }
func (slice Int64Slice) Less(i, j int) bool { return slice[i] < slice[j] }
func (slice Int64Slice) Swap(i, j int)      { slice[i], slice[j] = slice[j], slice[i] }

func main() {
	defer w.Flush()
	s := next()
	a := []int{}
	h1, h6, h8, h9 := false, false, false, false
	for i := 0; i < len(s); i++ {
		switch s[i] {
		case '1':
			if h1 {
				a = append(a, 1)
			} else {
				h1 = true
			}
		case '6':
			if h6 {
				a = append(a, 6)
			} else {
				h6 = true
			}
		case '8':
			if h8 {
				a = append(a, 8)
			} else {
				h8 = true
			}
		case '9':
			if h9 {
				a = append(a, 9)
			} else {
				h9 = true
			}
		default:
			a = append(a, int(s[i])-int('0'))
		}
	}

	oldlen := len(a)
	if oldlen%3 != 0 {
		for i := 0; i < 3-oldlen%3; i++ {
			a = append(a, 0)
		}
	}
	sort.Ints(a[:oldlen])
	b := a[:oldlen]
	if len(b) == 0 || b[len(b)-1] == 0 { //b == "00000..."
		w.WriteString("9681")
		pri32(b...)
		endl()
		return
	}
	rem := 0

	for i := 0; i < len(b)/2; i++ {
		b[i], b[len(b)-1-i] = b[len(b)-1-i], b[i]
	}

	for i := 0; i < len(b); i++ {
		rem = (rem*10 + b[i]) % 7
	}

	rem = (rem * 10000) % 7

	switch rem {
	case 0:
		b = append(b, []int{9, 6, 8, 1}...)
	case 1:
		b = append(b, []int{8, 1, 9, 6}...)
	case 2:
		b = append(b, []int{9, 8, 6, 1}...)
	case 3:
		b = append(b, []int{8, 6, 9, 1}...)
	case 4:
		b = append(b, []int{6, 8, 9, 1}...)
	case 5:
		b = append(b, []int{9, 8, 1, 6}...)
	default:
		b = append(b, []int{8, 9, 6, 1}...)
	}
	pri32(b...)
	endl()
}

package main

import (
	"bufio"
	"fmt"
	"math/rand"
	"os"
	"unicode"
)

func main() {
	var f1, f6, f8, f9 bool
	zero := 0

	in := bufio.NewReaderSize(os.Stdin, 1000001)
	s, _ := in.ReadBytes('\n')

	x := make([]byte, len(s))
	xn := 0

	for _, c := range s {
		switch c {
		case '0':
			zero++
		case '1':
			if f1 {
				x[xn] = c
				xn++
			} else {
				f1 = true
			}
		case '6':
			if f6 {
				x[xn] = c
				xn++
			} else {
				f6 = true
			}
		case '8':
			if f8 {
				x[xn] = c
				xn++
			} else {
				f8 = true
			}
		case '9':
			if f9 {
				x[xn] = c
				xn++
			} else {
				f9 = true
			}
		default:
			if unicode.IsDigit(rune(c)) {
				x[xn] = c
				xn++
			}
		}
	}

	pre := 0
	for i := 0; i < xn; i++ {
		pre = (pre*10 + int(x[i]-'0')) % 7
	}

	b := []int{1, 6, 8, 9}
	e := []int{1000, 100, 10, 1}
	val := func() int {
		sum := 0
		for i := 0; i < 4; i++ {
			sum += e[i] * b[i]
		}
		return (pre*10000 + sum) % 7
	}
	mod := val()
	for mod != 0 {
		i, j := rand.Intn(4), rand.Intn(4)
		if i == j {
			j = (j + 1) % 4
		}
		b[i], b[j] = b[j], b[i]
		mod = val()
	}

	fmt.Printf("%s%d%d%d%d", x[:xn], b[0], b[1], b[2], b[3])
	for i := 0; i < zero; i++ {
		fmt.Print("0")
	}
}

package main

import (
	"bufio"
	"fmt"
	"math/rand"
	"os"
	"unicode"
)

func main() {
	var f1, f6, f8, f9 bool
	zero := 0

	in := bufio.NewReaderSize(os.Stdin, 1000001)
	s, _ := in.ReadBytes('\n')

	x := make([]byte, len(s))
	xn := 0

	for _, c := range s {
		switch c {
		case '0':
			zero++
		case '1':
			if f1 {
				x[xn] = c
				xn++
			} else {
				f1 = true
			}
		case '6':
			if f6 {
				x[xn] = c
				xn++
			} else {
				f6 = true
			}
		case '8':
			if f8 {
				x[xn] = c
				xn++
			} else {
				f8 = true
			}
		case '9':
			if f9 {
				x[xn] = c
				xn++
			} else {
				f9 = true
			}
		default:
			if unicode.IsDigit(rune(c)) {
				x[xn] = c
				xn++
			}
		}
	}

	pre := 0
	for i := 0; i < xn; i++ {
		pre = (pre*10 + int(x[i]-'0')) % 7
	}

	b := []int{1, 6, 8, 9}
	e := []int{1000, 100, 10, 1}
	val := func() int {
		sum := 0
		for i := 0; i < 4; i++ {
			sum += e[i] * b[i]
		}
		return (pre*10000 + sum) % 7
	}
	mod := val()
	for mod != 0 {
		i, j := rand.Intn(4), rand.Intn(4)
		if i == j {
			j = (j + 1) % 4
		}
		b[i], b[j] = b[j], b[i]
		mod = val()
	}

	fmt.Printf("%s%d%d%d%d", x[:xn], b[0], b[1], b[2], b[3])
	w := bufio.NewWriter(os.Stdout)
	for i := 0; i < zero; i++ {
		w.WriteByte('0')
	}
	w.Flush()
}

package main

import (
	"fmt"
	"sort"
)

func isPerm(x int) bool {
	ds := []int{}
	for i := 0; i < 4; i++ {
		ds = append(ds, x%10)
		x /= 10
	}
	sort.Ints(ds)
	return ds[0] == 1 && ds[1] == 6 && ds[2] == 8 && ds[3] == 9
}

func main() {
	var s string
	fmt.Scanf("%s", &s)

	mark := [7]int{}
	for x := 1689; x <= 9999; x++ {
		if isPerm(x) {
			mark[x % 7] = x
		}
	}
//	fmt.Println(mark)

	n := len(s)
	t := []byte{}
	p := [10]bool{}
	for i := 0; i < n; i++ {
		c := s[i]
		d := int(c - '0')
		switch d {
		case 1, 6, 8, 9:
			if !p[d] {
				p[d] = true
			} else {
				t = append(t, c)
			}
		default:
			t = append(t, c)
		}
	}

	r := 0
	b := 1
	for i := 0; i < len(t); i++ {
		c := t[i]
		r = (r * 10 + int(c - '0')) % 7
		b = b * 10 % 7
	}
//	fmt.Println(r, b)

	x := -1
	for z := 0; z < 7; z++ {
		if (z * b + r) % 7 == 0 {
			x = mark[z]
		}
	}
//	fmt.Println(x)

	ds := []byte(fmt.Sprintf("%d", x))
	t = append(ds, t...)
	fmt.Println(string(t))
}

package main

import (
	"bufio"
	"fmt"
	"math/rand"
	"os"
	"unicode"
)

func main() {
	var f1, f6, f8, f9 bool
	zero := 0

	in := bufio.NewReaderSize(os.Stdin, 1000001)
	s, _ := in.ReadBytes('\n')

	x := make([]byte, len(s))
	xn := 0

	for _, c := range s {
		switch c {
		case '0':
			zero++
		case '1':
			if f1 {
				x[xn] = c
				xn++
			} else {
				f1 = true
			}
		case '6':
			if f6 {
				x[xn] = c
				xn++
			} else {
				f6 = true
			}
		case '8':
			if f8 {
				x[xn] = c
				xn++
			} else {
				f8 = true
			}
		case '9':
			if f9 {
				x[xn] = c
				xn++
			} else {
				f9 = true
			}
		default:
			if unicode.IsDigit(rune(c)) {
				x[xn] = c
				xn++
			}
		}
	}

	pre := 0
	for i := 0; i < xn; i++ {
		pre = (pre*10 + int(x[i]-'0')) % 7
	}

	b := []int{1, 6, 8, 9}
	e := []int{1000, 100, 10, 1}
	val := func() int {
		sum := pre
		for i := 0; i < 4; i++ {
			sum += e[i] * b[i]
		}
		return sum % 7
	}
	mod := val()
	for mod != 0 {
		i, j := rand.Intn(4), rand.Intn(4)
		if i == j {
			j = (j + 1) % 4
		}
		b[i], b[j] = b[j], b[i]
		mod = val()
	}

	fmt.Printf("%s%d%d%d%d", x[:xn], b[0], b[1], b[2], b[3])
	for i := 0; i < zero; i++ {
		fmt.Print("0")
	}
}

package main

import (
	"bufio"
	"fmt"
	"math/rand"
	"os"
)

func main() {
	var f1, f6, f8, f9 bool
	zero := 0

	in := bufio.NewReaderSize(os.Stdin, 1000001)
	s, _ := in.ReadBytes('\n')
	n := len(s) - 1

	x := make([]byte, len(s))
	xn := 0

	for i := 0; i < n; i++ {
		c := s[i]
		switch c {
		case '0':
			zero++
		case '1':
			if f1 {
				x[xn] = c
				xn++
			} else {
				f1 = true
			}
		case '6':
			if f6 {
				x[xn] = c
				xn++
			} else {
				f6 = true
			}
		case '8':
			if f8 {
				x[xn] = c
				xn++
			} else {
				f8 = true
			}
		case '9':
			if f9 {
				x[xn] = c
				xn++
			} else {
				f9 = true
			}
		default:
			x[xn] = c
			xn++
		}
	}

	pre := 0
	for i := 0; i < xn; i++ {
		pre = (pre*10 + int(x[i]-'0')) % 7
	}

	b := []int{1, 6, 8, 9}
	e := []int{1000, 100, 10, 1}
	val := func() int {
		sum := pre
		for i := 0; i < 4; i++ {
			sum += e[i] * b[i]
		}
		return sum % 7
	}
	mod := val()
	for mod != 0 {
		i, j := rand.Intn(4), rand.Intn(4)
		if i == j {
			j = (j + 1) % 4
		}
		b[i], b[j] = b[j], b[i]
		mod = val()
	}

	fmt.Printf("%s%d%d%d%d", x[:xn], b[0], b[1], b[2], b[3])
	for i := 0; i < zero; i++ {
		fmt.Print("0")
	}
}

package main

import (
	"bufio"

	"io"
	"os"
	"sort"
	"strconv"
)

type Scanner struct {
	r            io.Reader
	split        bufio.SplitFunc
	maxTokenSize int
	token, buf   []byte
	start, end   int
}

func NewScanner(r io.Reader) *Scanner {
	return &Scanner{
		r:            r,
		split:        bufio.ScanWords,
		maxTokenSize: 16777216,
		buf:          make([]byte, 4096),
	}
}

func (s *Scanner) advance(n int) bool {
	if n < 0 || n > s.end-s.start {
		return false
	}
	s.start += n
	return true
}

func (s *Scanner) Text() string {
	return string(s.token)
}

func (s *Scanner) Scan() bool {
	for {
		if s.end > s.start {
			advance, token, err := s.split(s.buf[s.start:s.end], false)
			if err != nil || !s.advance(advance) {
				return false
			}
			s.token = token
			if token != nil {
				return true
			}
		}
		if s.start > 0 && (s.end == len(s.buf) || s.start > len(s.buf)/2) {
			copy(s.buf, s.buf[s.start:s.end])
			s.end -= s.start
			s.start = 0
		}
		if s.end == len(s.buf) {
			if len(s.buf) >= s.maxTokenSize {
				return false
			}
			newSize := len(s.buf) * 2
			if newSize > s.maxTokenSize {
				newSize = s.maxTokenSize
			}
			newBuf := make([]byte, newSize)
			copy(newBuf, s.buf[s.start:s.end])
			s.buf = newBuf
			s.end -= s.start
			s.start = 0
			continue
		}
		for loop := 0; ; {
			n, _ := s.r.Read(s.buf[s.end:len(s.buf)])
			s.end += n
			if n > 0 {
				break
			}
			loop++
			if loop > 100 {
				break
			}
		}
	}
}

func (s *Scanner) Split(split bufio.SplitFunc) {
	s.split = split
}

var w *bufio.Writer = bufio.NewWriter(os.Stdout)
var sc *Scanner = NewScanner(os.Stdin)

func next() string { sc.Scan(); return sc.Text() }

func ni32() int {
	sc.Scan()
	n, _ := strconv.Atoi(sc.Text())
	return n
}

func ni64() int64 {
	sc.Scan()
	n, _ := strconv.ParseInt(sc.Text(), 10, 64)
	return n
}

func pri32(i ...int) {
	for _, ii := range i {
		w.WriteString(strconv.Itoa(ii))
		// sp()
	}
}
func pri64(i ...int64) {
	for _, ii := range i {
		w.WriteString(strconv.FormatInt(ii, 10))
		sp()
	}
}
func sp()   { w.WriteByte(' ') }
func endl() { w.WriteByte('\n') }

func min(i, j int) int {
	if i < j {
		return i
	}
	return j
}

func max(i, j int) int {
	if i > j {
		return i
	}
	return j
}

type Int64Slice []int64

func (slice Int64Slice) Len() int           { return len(slice) }
func (slice Int64Slice) Less(i, j int) bool { return slice[i] < slice[j] }
func (slice Int64Slice) Swap(i, j int)      { slice[i], slice[j] = slice[j], slice[i] }

func main() {
	defer w.Flush()
	s := next()
	a := []int{}
	h1, h6, h8, h9 := false, false, false, false
	for i := 0; i < len(s); i++ {
		switch s[i] {
		case '1':
			if h1 {
				a = append(a, 1)
			} else {
				h1 = true
			}
		case '6':
			if h6 {
				a = append(a, 6)
			} else {
				h6 = true
			}
		case '8':
			if h8 {
				a = append(a, 8)
			} else {
				h8 = true
			}
		case '9':
			if h9 {
				a = append(a, 9)
			} else {
				h9 = true
			}
		default:
			a = append(a, int(s[i])-int('0'))
		}
	}

	oldlen := len(a)
	if oldlen%3 != 0 {
		for i := 0; i < 3-oldlen%3; i++ {
			a = append(a, 0)
		}
	}
	sort.Ints(a[:oldlen])

	sumeven, sumodd := int64(0), int64(0)
	for i := 0; i < len(a); i += 3 {
		if i/3%2 == 0 {
			sumeven += int64(a[i]*100 + a[i+1]*10 + a[i+2])
		} else {
			sumodd += int64(a[i]*100 + a[i+1]*10 + a[i+2])
		}
	}
	rem := (sumeven - sumodd) * 10000 % 7
	b := a[:oldlen]

	if len(b) == 0 || b[len(b)-1] == 0 { //b == "00000..."
		w.WriteString("9681")
		pri32(b...)
		endl()
		return
	}
	for i := 0; i < len(b)/2; i++ {
		b[i], b[len(b)-1-i] = b[len(b)-1-i], b[i]
	}

	switch rem {
	case 0:
		b = append(b, []int{9, 6, 8, 1}...)
	case 1:
		b = append(b, []int{8, 1, 9, 6}...)
	case 2:
		b = append(b, []int{9, 8, 6, 1}...)
	case 3:
		b = append(b, []int{8, 6, 9, 1}...)
	case 4:
		b = append(b, []int{6, 8, 9, 1}...)
	case 5:
		b = append(b, []int{9, 8, 1, 6}...)
	default:
		b = append(b, []int{8, 9, 6, 1}...)
	}
	pri32(b...)
	endl()
}