#include <bits/stdc++.h>
using namespace std;
long long int MOD = 1e9 + 7;
const int N = 15, M = 1e5 + 10, NM1 = N - 1;
long long int OO = 1e18 + 8;
int oo = 1e9 + 8;
void readFile() {}
struct DSU {
  vector<int> par, sz;
  DSU(int n) {
    par.resize(n), sz.resize(n), iota(par.begin(), par.end(), 0),
        fill(sz.begin(), sz.end(), 1);
  }
  int leader(int u) { return (par[u] == u) ? u : par[u] = leader(par[u]); }
  bool join(int u, int v) {
    int p1 = leader(u), p2 = leader(v);
    if (p1 == p2) return false;
    if (sz[p1] < sz[p2]) swap(p1, p2);
    par[p2] = p1;
    sz[p1] += sz[p2];
    return true;
  }
} dsu(1);
struct node {
  vector<int> left, right;
  int compCnt;
  node() {}
  node(int n) {
    left = right = vector<int>(n, 0);
    compCnt = 0;
  }
} tree[M * 4];
int grid[N][M], id[N * 4], n, m, q;
node merge(const node &left, const node &right, int mid) {
  node res;
  res.left = left.left;
  res.right = right.right;
  res.compCnt = left.compCnt + right.compCnt;
  for (int i = 0; i < n; i++) {
    dsu.par[i] = left.left[i];
    dsu.par[i + n] = left.right[i];
    dsu.par[i + n + n] = n + n + right.left[i];
    dsu.par[i + n + n + n] = n + n + right.right[i];
  }
  for (int i = 0; i < n; i++) {
    if (grid[i][mid] == grid[i][mid + 1])
      res.compCnt -= dsu.join(i + n, i + n + n);
  }
  for (int i = 0; i < 4 * n; i++) id[i] = -1;
  for (int i = 0; i < n; i++) {
    if (id[dsu.leader(i)] < 0) id[dsu.leader(i)] = i;
    res.left[i] = id[dsu.leader(i)];
  }
  for (int i = n; i < n + n; i++) {
    if (id[dsu.leader(i + n + n)] < 0) id[dsu.leader(i + n + n)] = i;
    res.right[i - n] = id[dsu.leader(i + n + n)];
  }
  return res;
}
void build(int ni = 0, int ns = 0, int ne = m - 1) {
  if (ns == ne) {
    tree[ni].compCnt = 1;
    tree[ni].left.resize(n);
    for (int i = 1; i < n; i++) {
      if (grid[i][ns] == grid[i - 1][ns])
        tree[ni].left[i] = tree[ni].left[i - 1];
      else
        tree[ni].left[i] = i, tree[ni].compCnt++;
    }
    tree[ni].right = tree[ni].left;
    return;
  }
  int left = ni * 2 + 1, right = left + 1, mid = ns + (ne - ns) / 2;
  build(left, ns, mid);
  build(right, mid + 1, ne);
  tree[ni] = merge(tree[left], tree[right], mid);
}
node query(int qs, int qe, int ni = 0, int ns = 0, int ne = m - 1) {
  if (ns == qs && ne == qe) return tree[ni];
  int md = ns + (ne - ns) / 2;
  node res;
  if (qs <= md) {
    res = query(qs, min(qe, md), ni * 2 + 1, ns, md);
    if (qe > md) {
      auto cur = query(md + 1, qe, ni * 2 + 2, md + 1, ne);
      res = merge(res, cur, md);
    }
  } else
    res = query(qs, qe, ni * 2 + 2, md + 1, ne);
  return res;
}
int main() {
  readFile();
  scanf("%d%d%d", &n, &m, &q);
  dsu = DSU(4 * n + 5);
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) scanf("%d", grid[i] + j);
  }
  int l, r;
  build();
  while (q--) {
    scanf("%d%d", &l, &r);
    printf("%d\n", query(--l, --r).compCnt);
  }
  return 0;
}
