#include <bits/stdc++.h>   using namespace std;   const int INF = 0x3f3f3f3f;   const long long LINF = 0x3f3f3f3f3f3f3f3fll;   const long double pi = acos(-1);   const int MOD = 1e9 + 7;   const int N = 2e5 + 100;   int tr_min[4 * N][1 << 5];   int tr_max[4 * N][1 << 5];   vector<int> cara[N];   int n, k;   void build(int node, int b, int e) {     if (b == e) {       for (int cord = 0; cord < (1 << k); cord++) {         long long x = 0;         for (int i = 0; i < k; i++) {           if (cord & (1 << i))             x += cara[b][i];           else             x -= cara[b][i];         }         tr_max[node][cord] = tr_min[node][cord] = x;       }     } else {       int mid = (b + e) / 2;       build(2 * node, b, mid);       build(2 * node + 1, mid + 1, e);       for (int i = 0; i < (1 << k); i++) {         tr_max[node][i] = max(tr_max[2 * node][i], tr_max[2 * node + 1][i]);         tr_min[node][i] = min(tr_min[2 * node][i], tr_min[2 * node + 1][i]);       }     }   }   void update(int node, int b, int e, int i, vector<int> &cara) {     if (e < i or b > i) return;     if (b == e and b == i) {       for (int cord = 0; cord < (1 << k); cord++) {         long long x = 0;         for (int i = 0; i < k; i++) {           if (cord & (1 << i))             x += cara[i];           else             x -= cara[i];         }         tr_max[node][cord] = tr_min[node][cord] = x;       }       return;     }     int mid = (b + e) / 2;     update(2 * node, b, mid, i, cara);     update(2 * node + 1, mid + 1, e, i, cara);     for (int i = 0; i < (1 << k); i++) {       tr_max[node][i] = max(tr_max[2 * node][i], tr_max[2 * node + 1][i]);       tr_min[node][i] = min(tr_min[2 * node][i], tr_min[2 * node + 1][i]);     }   }   int query(int node, int b, int e, int i, int j, int cord) {     if (e < i or b > j) return -INF;     if (i <= b and j >= e) {       return tr_max[node][cord];     }     int mid = (b + e) / 2;     return max(query(2 * node, b, mid, i, j, cord),                query(2 * node + 1, mid + 1, e, i, j, cord));   }   int query2(int node, int b, int e, int i, int j, int cord) {     if (e < i or b > j) return INF;     if (i <= b and j >= e) {       return tr_min[node][cord];     }     int mid = (b + e) / 2;     return min(query2(2 * node, b, mid, i, j, cord),                query2(2 * node + 1, mid + 1, e, i, j, cord));   }   int proc(int cord, int l, int r) {     int maxi = query(1, 1, n, l, r, cord);     int mini = query2(1, 1, n, l, r, cord);     return abs(mini - maxi);   }   int main() {     scanf( %d %d , &n, &k);     for (int i = 1; i <= n; i++) {       for (int j = 0; j < k; j++) {         int x;         scanf( %d , &x);         cara[i].push_back(x);       }     }     int q;     build(1, 1, n);     scanf( %d , &q);     while (q--) {       int op;       scanf( %d , &op);       if (op == 1) {         int idx;         scanf( %d , &idx);         vector<int> val;         for (int j = 0; j < k; j++) {           int x;           scanf( %d , &x);           val.push_back(x);         }         update(1, 1, n, idx, val);       } else {         int l, r;         scanf( %d %d , &l, &r);         int resp = 0;         for (int i = 0; i < (1 << k); i++) resp = max(proc(i, l, r), resp);         printf( %d n , resp);       }     }   }   