Language: C++

#include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cerr<<*i<<" "; cerr<<endl; }
inline bool valid(int x, int y, int W, int H){ return (x >= 0 && y >= 0 && x < W && y < H); }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
struct RMQ{
  vector<int> data;
  int N;
  RMQ(int n){
    N = 1;
    while(N < n) N *= 2;
    data = vector<int>(2 * N, INT_MAX);
  }
  void update(int k, int x){
    k += N - 1;
    data[k] = x;
    while(k > 0){
      k = (k - 1) / 2;
      data[k] = min(data[2 * k + 1], data[2 * k + 2]);
    }
  }
  int query(int a, int b){
    return query(a, b, 0, 0, N);
  }
  int query(int a, int b, int k, int l, int r){
    if(b <= l || r <= a) return INT_MAX;
    if(a <= l && r <= b){
      return data[k];
    }else{
      return min(query(a, b, 2 * k + 1, l, (l + r) / 2), query(a, b, 2 * k + 2, (l + r) / 2, r));
    }
  }
};

int main(){
  int H, W, Q;
  while(cin>>H>>W>>Q && H){
    if(H < W){
      //HlogW * Q = 10^7log10^3
      vector<RMQ> rmq(H, RMQ(W));
      REP(y, H){
        REP(x, W){
          int t; scanf("%d", &t);
          rmq[y].update(x, t);
        }
      }
      REP(i, Q){
        int y1, x1, y2, x2;
        scanf("%d %d %d %d", &y1, &x1, &y2, &x2);
        int res = INT_MAX;
        for(int y = y1; y <= y2; y++){
          res = min(res, rmq[y].query(x1, x2 + 1));
        }
        printf("%d\n", res);
      }
    }else{
      //WlogH * Q
      vector<RMQ> rmq(W, RMQ(H));
      REP(y, H){
        REP(x, W){
          int t; scanf("%d", &t);
          rmq[x].update(y, t);
        }
      }
      REP(i, Q){
        int y1, x1, y2, x2;
        scanf("%d %d %d %d", &y1, &x1, &y2, &x2);
        int res = INT_MAX;
        for(int x = x1; x <= x2; x++){
          res = min(res, rmq[x].query(y1, y2 + 1));
        }
        printf("%d\n", res);
      }
    }
  }
  return 0;
}

Compiler output:
a.cc: In constructor 'RMQ::RMQ(int)':
a.cc:37:31: error: 'INT_MAX' was not declared in this scope
   37 |     data = vector<int>(2 * N, INT_MAX);
      |                               ^~~~~~~
a.cc:15:1: note: 'INT_MAX' is defined in header '<climits>'; this is probably fixable by adding '#include <climits>'
   14 | #include <cassert>
  +++ |+#include <climits>
   15 | 
a.cc: In member function 'int RMQ::query(int, int, int, int, int)':
a.cc:51:33: error: 'INT_MAX' was not declared in this scope
   51 |     if(b <= l || r <= a) return INT_MAX;
      |                                 ^~~~~~~
a.cc:51:33: note: 'INT_MAX' is defined in header '<climits>'; this is probably fixable by adding '#include <climits>'
a.cc: In function 'int main()':
a.cc:75:19: error: 'INT_MAX' was not declared in this scope
   75 |         int res = INT_MAX;
      |                   ^~~~~~~
a.cc:75:19: note: 'INT_MAX' is defined in header '<climits>'; this is probably fixable by adding '#include <climits>'
a.cc:93:19: error: 'INT_MAX' was not declared in this scope
   93 |         int res = INT_MAX;
      |                   ^~~~~~~
a.cc:93:19: note: 'INT_MAX' is defined in header '<climits>'; this is probably fixable by adding '#include <climits>'