#include <bits/stdc++.h>
using namespace std;
/* custom dq structure which allows querying for smallest element according to cmp_func */
template <typename F>
struct custom_dq {
deque<int> dq;
F cmp_func;
/* cmp_func(a, b) gives the (weak) ordering in the deque */
custom_dq(F& cmp_func) : cmp_func(cmp_func) {}
void clear() {
while (!dq.empty()) {
dq.pop_back();
}
}
void add_element(int x) {
while (!dq.empty() && !cmp_func(dq.back(), x)) {
dq.pop_back();
}
dq.push_back(x);
}
void remove_element(int x) {
if (dq.front() == x) {
dq.pop_front();
}
}
int get_best() {
return dq.front();
}
};
int main() {
if (fopen("struti.in", "r")) {
freopen("struti.in", "r", stdin);
freopen("struti.out", "w", stdout);
}
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m, q;
cin >> n >> m >> q;
vector<vector<int>> a(n, vector<int>(m));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> a[i][j];
}
}
auto compress_rows = [&](int h, int w, const vector<vector<int>>& b, auto cmp_func) {
int n = b.size(), m = b[0].size();
vector<vector<int>> compressed_mat(n, vector<int>(m - w + 1));
custom_dq dq(cmp_func);
for (int i = 0; i < n; i++) {
dq.clear();
for (int j = 0; j < w; j++) {
dq.add_element(b[i][j]);
}
for (int j = w; j < m; j++) {
compressed_mat[i][j - w] = dq.get_best();
dq.remove_element(b[i][j - w]);
dq.add_element(b[i][j]);
}
compressed_mat[i][m - w] = dq.get_best();
}
return compressed_mat;
};
auto compress_cols = [&](int h, int w, const vector<vector<int>>& b, auto cmp_func) {
int n = b.size(), m = b[0].size();
vector<vector<int>> compressed_mat(n - h + 1, vector<int>(m));
custom_dq dq(cmp_func);
for (int j = 0; j < m; j++) {
dq.clear();
for (int i = 0; i < h; i++) {
dq.add_element(b[i][j]);
}
for (int i = h; i < n; i++) {
compressed_mat[i - h][j] = dq.get_best();
dq.remove_element(b[i - h][j]);
dq.add_element(b[i][j]);
}
compressed_mat[n - h][j] = dq.get_best();
}
return compressed_mat;
};
auto compress_matrix = [&](int h, int w, const vector<vector<int>>& b, auto cmp_func) {
vector<vector<int>> mat = compress_rows(h, w, b, cmp_func);
return compress_cols(h, w, mat, cmp_func);
};
auto compute_answer = [&](int h, int w) {
vector<vector<int>> compressed_max_mat = compress_matrix(h, w, a, [](int x, int y) {
return x >= y;
});
vector<vector<int>> compressed_min_mat = compress_matrix(h, w, a, [](int x, int y) {
return x <= y;
});
int n = compressed_max_mat.size(), m = compressed_max_mat[0].size();
int mn = numeric_limits<int>::max(), cnt_mn = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
int delta = compressed_max_mat[i][j] - compressed_min_mat[i][j];
if (delta < mn) {
mn = delta;
cnt_mn = 1;
} else if (delta == mn) {
cnt_mn += 1;
}
}
}
return make_pair(mn, cnt_mn);
};
while (q--) {
int nx, ny;
cin >> nx >> ny;
pair<int, int> answer = compute_answer(nx, ny);
if (nx != ny) {
pair<int, int> alternative_answer = compute_answer(ny, nx);
if (alternative_answer.first == answer.first) {
answer.second += alternative_answer.second;
} else {
answer = min(answer, alternative_answer);
}
}
cout << answer.first << ' ' << answer.second << '\n';
}
return 0;
}