← Home
package main

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

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

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

func (fs *FastScanner) nextUint64() uint64 {
	for fs.idx < fs.n && fs.data[fs.idx] <= ' ' {
		fs.idx++
	}
	var x uint64
	for fs.idx < fs.n {
		c := fs.data[fs.idx]
		if c <= ' ' {
			break
		}
		x = x*10 + uint64(c-'0')
		fs.idx++
	}
	return x
}

func update(tree []uint64, x, y, n, size int, v uint64) {
	for i := x; i <= n; i += i & -i {
		base := i * size
		for j := y; j <= n; j += j & -j {
			tree[base+j] ^= v
		}
	}
}

func query(tree []uint64, x, y, size int) uint64 {
	var res uint64
	for i := x; i > 0; i -= i & -i {
		base := i * size
		for j := y; j > 0; j -= j & -j {
			res ^= tree[base+j]
		}
	}
	return res
}

func addPoint(trees *[4][]uint64, x, y, n, size int, v uint64) {
	if x < 1 || y < 1 || x > n || y > n {
		return
	}
	idx := ((x & 1) << 1) | (y & 1)
	update(trees[idx], x, y, n, size, v)
}

func prefix(trees *[4][]uint64, x, y, size int) uint64 {
	if x <= 0 || y <= 0 {
		return 0
	}
	idx := ((x & 1) << 1) | (y & 1)
	return query(trees[idx], x, y, size)
}

func main() {
	fs := NewFastScanner()
	n := int(fs.nextUint64())
	m := int(fs.nextUint64())

	size := n + 1
	total := size * size
	var trees [4][]uint64
	for i := 0; i < 4; i++ {
		trees[i] = make([]uint64, total)
	}

	out := make([]byte, 0, m*4)

	for k := 0; k < m; k++ {
		t := int(fs.nextUint64())
		if t == 1 {
			x0 := int(fs.nextUint64())
			y0 := int(fs.nextUint64())
			x1 := int(fs.nextUint64())
			y1 := int(fs.nextUint64())

			ans := prefix(&trees, x1, y1, size) ^
				prefix(&trees, x0-1, y1, size) ^
				prefix(&trees, x1, y0-1, size) ^
				prefix(&trees, x0-1, y0-1, size)

			out = strconv.AppendUint(out, ans, 10)
			out = append(out, '\n')
		} else {
			x0 := int(fs.nextUint64())
			y0 := int(fs.nextUint64())
			x1 := int(fs.nextUint64())
			y1 := int(fs.nextUint64())
			v := fs.nextUint64()

			addPoint(&trees, x0, y0, n, size, v)
			addPoint(&trees, x0, y1+1, n, size, v)
			addPoint(&trees, x1+1, y0, n, size, v)
			addPoint(&trees, x1+1, y1+1, n, size, v)
		}
	}

	os.Stdout.Write(out)
}