#include <bits/stdc++.h>   using namespace std;   template <typename num_t>   inline void addmod(num_t& a, const long long& b, const int& m) {     a = (a + b) % m;     if (a < 0) a += m;   }   template <typename num_t>   inline void update_max(num_t& a, const num_t& b) {     a = max(a, b);   }   template <typename num_t>   inline void update_min(num_t& a, const num_t& b) {     a = min(a, b);   }   template <typename num_t>   num_t gcd(num_t lhs, num_t rhs) {     return !lhs ? rhs : gcd(rhs % lhs, lhs);   }   template <typename num_t>   num_t pw(num_t n, num_t k, num_t mod) {     num_t res = 1;     for (; k > 0; k >>= 1) {       if (k & 1) res = 1ll * res * n % mod;       n = 1ll * n * n % mod;     }     return res;   }   const int inf = 1e9 + 7;   const int mod = inf;   const int MAX_N = 200000 + 7;   const long long ll_inf = 9ll * inf * inf;   int n, k;   array<int, 5> arr[MAX_N];   int pre_calc[32][MAX_N];   int calc(array<int, 5>& arr, int mask) {     int sum = 0;     for (int i = (0), _b = (k); i < _b; ++i)       if (mask & (1 << i))         sum += arr[i];       else         sum -= arr[i];     return sum;   }   void update(int i, array<int, 5>& temp) {     arr[i] = temp;     for (int mask = (0), _b = (1 << k); mask < _b; ++mask) {       pre_calc[mask][i] = calc(temp, mask);     }   }   template <typename num_t>   class SegmentTree {    public:     void init(int l, int r) {       tree.resize((r - l + 1) << 1);       node_index = 0;       build_tree(tree[node_index++], l, r);     }     void update(int left_index, int right_index) {       update_(tree[0], left_index, right_index);     }     num_t get(int left_index, int right_index) {       if (right_index < left_index) return 0;       return get(tree[0], left_index, right_index).best_value;     }       private:     struct node {       static const num_t nil = 0;       node *left_child, *right_child;       int left_index, right_index;       array<int, 32> min_value;       array<int, 32> max_value;       int best_value = 0;       bool inited = false;       void push_down() {         for (int i = (0), _b = (1 << k); i < _b; ++i) {           min_value[i] = max_value[i] = left_index;         }         best_value = 0;         inited = true;       }       inline int dist(array<int, 5>& lhs, array<int, 5>& rhs) {         int sum = 0;         for (int i = (0), _b = (k); i < _b; ++i) sum += abs(lhs[i] - rhs[i]);         return sum;       }       void merge_node() {         node &lhs = *left_child, &rhs = *right_child;         merge_node(lhs, rhs);       }       void merge_node(node& lhs, node& rhs) {         best_value = max(lhs.best_value, rhs.best_value);         inited = true;         if (lhs.inited && rhs.inited) {           for (int i = (0), _b = (1 << k); i < _b; ++i) {             update_max(best_value,                        dist(arr[lhs.max_value[i]], arr[rhs.min_value[i]]));             update_max(best_value,                        dist(arr[rhs.max_value[i]], arr[lhs.min_value[i]]));             if (pre_calc[i][lhs.max_value[i]] <= pre_calc[i][rhs.max_value[i]])               max_value[i] = rhs.max_value[i];             else               max_value[i] = lhs.max_value[i];             if (pre_calc[i][lhs.min_value[i]] <= pre_calc[i][rhs.min_value[i]])               min_value[i] = lhs.min_value[i];             else               min_value[i] = rhs.min_value[i];           }         } else if (lhs.inited) {           min_value = lhs.min_value;           max_value = lhs.max_value;         } else {           min_value = rhs.min_value;           max_value = rhs.max_value;         }       }       void lazy_update() {}       inline void init(int left, int right, node* left_child_,                        node* right_child_) {         left_index = left;         right_index = right;         left_child = left_child_;         right_child = right_child_;       }       int size() const { return right_index - left_index + 1; }     };     vector<node> tree;     int node_index = 0;     void build_tree(node& root, int left, int right) {       if (left == right) {         root.init(left, right, nullptr, nullptr);         root.push_down();         return;       }       int mid = (left + right) >> 1, lhs = node_index++, rhs = node_index++;       build_tree(tree[lhs], left, mid);       build_tree(tree[rhs], mid + 1, right);       root.init(left, right, &tree[lhs], &tree[rhs]);       root.merge_node();     }     void update_(node& root, int u, int v) {       if (u > root.right_index || v < root.left_index) return;       if (u <= root.left_index && root.right_index <= v) {         root.push_down();       } else {         root.lazy_update();         update_(*root.left_child, u, v);         update_(*root.right_child, u, v);         root.merge_node();       }     }     node get(node& root, int u, int v) {       if (u <= root.left_index && root.right_index <= v) return root;       if (u > root.right_index || v < root.left_index) return node();       root.lazy_update();       auto lhs = get(*root.left_child, u, v);       auto rhs = get(*root.right_child, u, v);       node ans;       ans.merge_node(lhs, rhs);       return ans;     }   };   SegmentTree<int> segment_tree;   void solve() {     cin >> n >> k;     for (int i = (0), _b = (n); i < _b; ++i) {       array<int, 5> cur;       for (int j = (0), _b = (k); j < _b; ++j) cin >> cur[j];       update(i, cur);     }     segment_tree.init(0, n - 1);     int q;     cin >> q;     while (q-- > 0) {       int op;       cin >> op;       if (op == 1) {         int u;         cin >> u;         --u;         array<int, 5> cur;         for (int j = (0), _b = (k); j < _b; ++j) cin >> cur[j];         update(u, cur);         segment_tree.update(u, u);       } else {         int u, v;         cin >> u >> v;         cout << segment_tree.get(u - 1, v - 1) <<   n ;       }     }   }   int main() {     ios_base::sync_with_stdio(0);     cin.tie(0);     const bool multiple_test = false;     int test = 1;     if (multiple_test) cin >> test;     for (int i = 0; i < test; ++i) {       solve();     }   }