#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
template<int (*comp)(int, int), int def>
struct TwoDSegTree {
int n, m;
std::vector<int> v;
// Assumes the entire matrix is 0 in the beginning.
TwoDSegTree(int n, int m) : n(n), m(m), v(1 + 4 * n * m, def) {}
void set(int i, int j, int val) {
set_elem(1, 1, n, 1, m, i, j, val);
}
int get(int rli, int rlf, int cli, int clf) {
return get_elem(1, 1, n, 1, m, rli, rlf, cli, clf);
}
int get_elem(int node,
int rowli, int rowlf,
int colli, int collf,
int rli, int rlf,
int cli, int clf) {
// Area doesn't overlap with current node.
if (rli > rowlf || rlf < rowli || cli > collf || clf < colli) {
return def;
}
// Area covers current node.
if (rli <= rowli && rlf >= rowlf && cli <= colli && clf >= collf) {
return v[node];
}
// Split into four areas.
int sol = def;
sol = comp(sol, get_elem(node * 4 - 2,
rowli, (rowli + rowlf) / 2,
colli, (colli + collf) / 2,
rli, rlf, cli, clf));
sol = comp(sol, get_elem(node * 4 - 1,
rowli, (rowli + rowlf) / 2,
(colli + collf) / 2 + 1, collf,
rli, rlf, cli, clf));
sol = comp(sol, get_elem(node * 4 - 0,
(rowli + rowlf) / 2 + 1, rowlf,
colli, (colli + collf) / 2,
rli, rlf, cli, clf));
sol = comp(sol, get_elem(node * 4 + 1,
(rowli + rowlf) / 2 + 1, rowlf,
(colli + collf) / 2 + 1, collf,
rli, rlf, cli, clf));
return sol;
}
int set_elem(int node,
int rowli, int rowlf,
int colli, int collf,
int row, int col, int val) {
// Out of bounds (shouldn't really happen, but alas).
if (row < rowli || row > rowlf || col < colli || col > collf) {
return def;
}
// Strict bounds.
if (row == rowli && row == rowlf && col == colli && col == collf) {
v[node] = val;
return val;
}
// Split into four quads.
if (row <= (rowli + rowlf) / 2) {
if (col <= (colli + collf) / 2) {
v[node] = comp(v[node], set_elem(node * 4 - 2,
rowli, (rowli + rowlf) / 2,
colli, (colli + collf) / 2,
row, col, val));
} else {
v[node] = comp(v[node], set_elem(node * 4 - 1,
rowli, (rowli + rowlf) / 2,
(colli + collf) / 2 + 1, collf,
row, col, val));
}
} else {
if (col <= (colli + collf) / 2) {
v[node] = comp(v[node], set_elem(node * 4 + 0,
(rowli + rowlf) / 2 + 1, rowlf,
colli, (colli + collf) / 2,
row, col, val));
} else {
v[node] = comp(v[node], set_elem(node * 4 + 1,
(rowli + rowlf) / 2 + 1, rowlf,
(colli + collf) / 2 + 1, collf,
row, col, val));
}
}
}
};
inline int fmax(int a, int b) {
return a > b ? a : b;
}
inline int fmin(int a, int b) {
return a < b ? a : b;
}
int main()
{
std::ifstream in("struti.in");
std::ofstream out("struti.out");
int n, m, p;
in >> n >> m >> p;
TwoDSegTree<fmax, 0> max(n, m);
TwoDSegTree<fmin, 1000000> min(n, m);
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
int x;
in >> x;
max.set(i, j, x);
min.set(i, j, x);
}
}
for (int i = 0; i < p; ++i) {
int dx, dy;
in >> dx >> dy;
int sol = 1000000;
int count = 0;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
if (i >= dx && j >= dy) {
int dif = max.get(i - dx + 1, i, j - dy + 1, j) -
min.get(i - dx + 1, i, j - dy + 1, j);
if (dif == sol) {
count++;
} else if (dif < sol) {
count = 1;
sol = dif;
}
}
if (i >= dy && j >= dx && dy != dx) {
int dif = max.get(i - dy + 1, i, j - dx + 1, j) -
min.get(i - dy + 1, i, j - dx + 1, j);
if (dif == sol) {
count++;
} else if (dif < sol) {
count = 1;
sol = dif;
}
}
}
}
out << sol << " " << count << std::endl;
}
in.close();
out.close();
return 0;
}