← Home
package main

import (
	"bufio"
	"os"
)

const (
	MaxN     = 200005
	MaxMasks = 16 
	Inf      = 2000000000
)

var (
	treeMin  [4 * MaxN * MaxMasks]int32
	treeMax  [4 * MaxN * MaxMasks]int32
	n, k     int
	numMasks int
)

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

	scanInt := func() int {
		scanner.Scan()
		b := scanner.Bytes()
		val, idx, neg := 0, 0, false
		if b[0] == '-' {
			neg = true
			idx++
		}
		for ; idx < len(b); idx++ {
			val = val*10 + int(b[idx]-'0')
		}
		if neg {
			return -val
		}
		return val
	}

	n = scanInt()
	k = scanInt()
	numMasks = 1 << (k - 1)

	points := make([][]int32, n)
	for i := 0; i < n; i++ {
		points[i] = make([]int32, k)
		for j := 0; j < k; j++ {
			points[i][j] = int32(scanInt())
		}
	}

	build(1, 0, n-1, points)

	q := scanInt()
	newPt := make([]int32, k)

	for i := 0; i < q; i++ {
		t := scanInt()
		if t == 1 {
			idx := scanInt() - 1
			for j := 0; j < k; j++ {
				newPt[j] = int32(scanInt())
			}
			update(1, 0, n-1, idx, newPt)
		} else {
			l, r := scanInt()-1, scanInt()-1
			minRes, maxRes := query(1, 0, n-1, l, r)
			ans := int32(0)
			for m := 0; m < numMasks; m++ {
				d := maxRes[m] - minRes[m]
				if d > ans {
					ans = d
				}
			}
			writeInt(out, int(ans))
			out.WriteByte('\n')
		}
	}
}

func build(v, tl, tr int, pts [][]int32) {
	if tl == tr {
		base := v * numMasks
		p := pts[tl]
		for m := 0; m < numMasks; m++ {
			val := p[k-1]
			for j := 0; j < k-1; j++ {
				if (m>>j)&1 == 1 {
					val += p[j]
				} else {
					val -= p[j]
				}
			}
			treeMin[base+m] = val
			treeMax[base+m] = val
		}
		return
	}
	tm := (tl + tr) >> 1
	build(2*v, tl, tm, pts)
	build(2*v+1, tm+1, tr, pts)
	pull(v)
}

func update(v, tl, tr, pos int, p []int32) {
	if tl == tr {
		base := v * numMasks
		for m := 0; m < numMasks; m++ {
			val := p[k-1]
			for j := 0; j < k-1; j++ {
				if (m>>j)&1 == 1 {
					val += p[j]
				} else {
					val -= p[j]
				}
			}
			treeMin[base+m] = val
			treeMax[base+m] = val
		}
		return
	}
	tm := (tl + tr) >> 1
	if pos <= tm {
		update(2*v, tl, tm, pos, p)
	} else {
		update(2*v+1, tm+1, tr, pos, p)
	}
	pull(v)
}

func pull(v int) {
	base := v * numMasks
	left := 2 * v * numMasks
	right := (2*v + 1) * numMasks
	for m := 0; m < numMasks; m++ {
		lMin, rMin := treeMin[left+m], treeMin[right+m]
		if lMin < rMin {
			treeMin[base+m] = lMin
		} else {
			treeMin[base+m] = rMin
		}
		lMax, rMax := treeMax[left+m], treeMax[right+m]
		if lMax > rMax {
			treeMax[base+m] = lMax
		} else {
			treeMax[base+m] = rMax
		}
	}
}

func query(v, tl, tr, l, r int) (minRes, maxRes [MaxMasks]int32) {
	if l > r {
		for i := 0; i < MaxMasks; i++ {
			minRes[i], maxRes[i] = Inf, -Inf
		}
		return
	}
	if l == tl && r == tr {
		base := v * numMasks
		for m := 0; m < numMasks; m++ {
			minRes[m] = treeMin[base+m]
			maxRes[m] = treeMax[base+m]
		}
		return
	}
	tm := (tl + tr) >> 1
	if r <= tm {
		return query(2*v, tl, tm, l, r)
	}
	if l > tm {
		return query(2*v+1, tm+1, tr, l, r)
	}
	lMin, lMax := query(2*v, tl, tm, l, tm)
	rMin, rMax := query(2*v+1, tm+1, tr, tm+1, r)
	for m := 0; m < numMasks; m++ {
		if lMin[m] < rMin[m] {
			minRes[m] = lMin[m]
		} else {
			minRes[m] = rMin[m]
		}
		if lMax[m] > rMax[m] {
			maxRes[m] = lMax[m]
		} else {
			maxRes[m] = rMax[m]
		}
	}
	return
}

func writeInt(w *bufio.Writer, x int) {
	if x < 0 {
		w.WriteByte('-')
		x = -x
	}
	var b [20]byte
	i := 20
	if x == 0 {
		w.WriteByte('0')
		return
	}
	for x > 0 {
		i--
		b[i] = byte(x%10 + '0')
		x /= 10
	}
	w.Write(b[i:])
}