#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();
  }
}
