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