#include <bits/stdc++.h>
using namespace std;
template <class X, class Y>
bool minimize(X &x, const Y &y) {
  X eps = 1e-9;
  if (x > y + eps) {
    x = y;
    return true;
  } else
    return false;
}
template <class X, class Y>
bool maximize(X &x, const Y &y) {
  X eps = 1e-9;
  if (x + eps < y) {
    x = y;
    return true;
  } else
    return false;
}
template <class T>
T Abs(const T &x) {
  return (x < 0 ? -x : x);
}
const int INF = (int)1e9 + 7;
class SegmentTree {
 private:
  vector<int> tree;
  int n;
  void update(int i, int l, int r, int pos, int value) {
    if (l == r) {
      tree[i] = value;
      return;
    }
    int m = (l + r) >> 1;
    if (pos > m)
      update(2 * i + 1, m + 1, r, pos, value);
    else
      update(2 * i, l, m, pos, value);
    tree[i] = max(tree[2 * i], tree[2 * i + 1]);
  }
  int getMax(int i, int l, int r, int u, int v) const {
    if (l > v || r < u || l > r || v < u) return -INF;
    if (u <= l && r <= v) return tree[i];
    int m = (l + r) >> 1;
    int L = getMax(2 * i, l, m, u, v);
    int R = getMax(2 * i + 1, m + 1, r, u, v);
    return max(L, R);
  }

 public:
  SegmentTree(int n = 0) {
    this->n = n;
    tree.assign(4 * n + 7, 0);
  }
  void update(int pos, int value) { update(1, 1, n, pos, value); }
  int getMax(int l, int r) const { return getMax(1, 1, n, l, r); }
};
SegmentTree myit[(1LL << (7))];
int cord[200200][7];
int numPoint, dim;
void addPoint(int id) {
  for (int mask = 0, _n = ((1LL << (dim))); mask < _n; mask++) {
    int sum = 0;
    for (int j = 0, _n = (dim); j < _n; j++)
      sum += (((mask) >> (j)) & 1) ? cord[id][j] : -cord[id][j];
    myit[mask].update(id, sum);
  }
}
int query(int l, int r) {
  int res = -INF;
  for (int mask = 0, _n = ((1LL << (dim))); mask < _n; mask++) {
    int rev = ((1LL << (dim)) - 1) ^ mask;
    maximize(res, myit[mask].getMax(l, r) + myit[rev].getMax(l, r));
  }
  return res;
}
void process(void) {
  scanf("%d%d", &numPoint, &dim);
  for (int i = (1), _b = (numPoint); i <= _b; i++)
    for (int j = 0, _n = (dim); j < _n; j++) scanf("%d", &cord[i][j]);
  for (int mask = 0, _n = ((1LL << (dim))); mask < _n; mask++)
    myit[mask] = SegmentTree(numPoint);
  for (int i = (1), _b = (numPoint); i <= _b; i++) addPoint(i);
  int numQuery;
  scanf("%d", &numQuery);
  for (int love = 0, _n = (numQuery); love < _n; love++) {
    int type;
    scanf("%d", &type);
    if (type == 1) {
      int pos;
      scanf("%d", &pos);
      for (int i = 0, _n = (dim); i < _n; i++) scanf("%d", &cord[pos][i]);
      addPoint(pos);
    } else {
      int l, r;
      scanf("%d%d", &l, &r);
      printf("%d\n", query(l, r));
    }
  }
}
int main(void) {
  process();
  return 0;
}
