#include<vector>
#include<climits>
#include<algorithm>
//
const int INF = INT_MAX;
const int NIL = -1;
//
class SegmentTree {
public:
  SegmentTree(int x, int y);
  void update(int x, int y, int value);
  int query(int min_x, int min_y, int max_x, int max_y) const;
private:
  int update(int low_x, int low_y, int high_x, int high_y, int index, int x, int y, int value, int depth);
  int query(int low_x, int low_y, int high_x, int high_y, int index, int min_x, int min_y, int max_x, int max_y, int depth) const;
  int size_x_, size_y_;
  std::vector<int> node_;
};
//
SegmentTree::SegmentTree(int x, int y) : size_x_(x), size_y_(y) {
  while(x & x - 1) x += x & -x;
  while(y & y - 1) y += y & -y;
  node_.assign(x * y << 2, INF);
}
//
void SegmentTree::update(int x, int y, int value) {
  update(0, 0, size_x_ - 1, size_y_ - 1, 0, x, y, value, 0);
}
int SegmentTree::update(int low_x, int low_y, int high_x, int high_y, int index, int x, int y, int value, int depth) {
  if(x < low_x || high_x < x || y < low_y || high_y < y) return node_[index];
  if(low_x == high_x && low_y == high_y) return node_[index] = value;
  int middle_x = (low_x + high_x) >> 1;
  int middle_y = (low_y + high_y) >> 1;
  if(low_x == high_x) {
    int l = update(low_x, low_y, high_x, middle_y, (index << 1) + 1, x, y, value, depth ^ 1);
    int h = update(low_x, middle_y + 1, high_x, high_y, (index << 1) + 2, x, y, value, depth ^ 1);
    return node_[index] = std::min(l, h);
  }
  if(low_y == high_y) {
    int l = update(low_x, low_y, middle_x, high_y, (index << 1) + 1, x, y, value, depth ^ 1);
    int h = update(middle_x + 1, low_y, high_x, high_y, (index << 1) + 2, x, y, value, depth ^ 1);
    return node_[index] = std::min(l, h);
  }
  if(depth) {
    int l = update(low_x, low_y, high_x, middle_y, (index << 1) + 1, x, y, value, depth ^ 1);
    int h = update(low_x, middle_y + 1, high_x, high_y, (index << 1) + 2, x, y, value, depth ^ 1);
    return node_[index] = std::min(l, h);
  } else {
    int l = update(low_x, low_y, middle_x, high_y, (index << 1) + 1, x, y, value, depth ^ 1);
    int h = update(middle_x + 1, low_y, high_x, high_y, (index << 1) + 2, x, y, value, depth ^ 1);
    return node_[index] = std::min(l, h);
  }
}
//
int SegmentTree::query(int min_x, int min_y, int max_x, int max_y) const {
  query(0, 0, size_x_ - 1, size_y_ - 1, 0, min_x, min_y, max_x, max_y, 0);
}
int SegmentTree::query(int low_x, int low_y, int high_x, int high_y, int index, int min_x, int min_y, int max_x, int max_y, int depth) const {
  if(max_x < low_x || high_x < min_x || max_y < low_y || high_y < min_y) return INF;
  if(min_x <= low_x && high_x <= max_x && min_y <= low_y && high_y <= max_y) return node_[index];
  int middle_x = (low_x + high_x) >> 1;
  int middle_y = (low_y + high_y) >> 1;
  if(low_x == high_x) {
    int l = query(low_x, low_y, high_x, middle_y, (index << 1) + 1, min_x, min_y, max_x, max_y, depth ^ 1);
    int h = query(low_x, middle_y + 1, high_x, high_y, (index << 1) + 2, min_x, min_y, max_x, max_y, depth ^ 1);
    return std::min(l, h);
  }
  if(low_y == high_y) {
    int l = query(low_x, low_y, middle_x, high_y, (index << 1) + 1, min_x, min_y, max_x, max_y, depth ^ 1);
    int h = query(middle_x + 1, low_y, high_x, high_y, (index << 1) + 2, min_x, min_y, max_x, max_y, depth ^ 1);
    return std::min(l, h);
  }
  if(depth) {
    int l = query(low_x, low_y, high_x, middle_y, (index << 1) + 1, min_x, min_y, max_x, max_y, depth ^ 1);
    int h = query(low_x, middle_y + 1, high_x, high_y, (index << 1) + 2, min_x, min_y, max_x, max_y, depth ^ 1);
    return std::min(l, h);
  } else {
    int l = query(low_x, low_y, middle_x, high_y, (index << 1) + 1, min_x, min_y, max_x, max_y, depth ^ 1);
    int h = query(middle_x + 1, low_y, high_x, high_y, (index << 1) + 2, min_x, min_y, max_x, max_y, depth ^ 1);
    return std::min(l, h);
  }
}

#include<bits/stdc++.h>
using namespace std;
int main() {
  int r, c, q;
  while(cin >> r >> c >> q, r | c | q) {
    SegmentTree tree(c, r);
    for(int y = 0; y < r; ++y) for(int x = 0; x < c; ++x) {
      int grid;
      cin >> grid;
      tree.update(x, y, grid);
    }
    for(int i = 0; i < q; ++i) {
      int r1, c1, r2, c2;
      cin >> r1 >> c1 >> r2 >> c2;
      cout << tree.query(c1, r1, c2, r2) << endl;
    }
  }
}

Measured memory_bytes: 33828