#include <bits/stdc++.h>
using namespace std;
const int max_rows = 10;
const int max_columns = int(1e5);
int R, C;
array<array<int, max_rows>, max_columns> transpose;
struct Segment {
  int l, r;
  array<array<int, max_rows>, 2> colors;
  int components;
};
Segment operator*(Segment a, Segment b) {
  int merges = 0;
  for (int row = 0; row < R; row++)
    if (transpose[a.r][row] == transpose[b.l][row]) {
      const int c = a.colors[1][row], d = b.colors[0][row];
      merges += c != d;
      for (auto& xs : a.colors)
        for (auto& x : xs) x = x == c ? d : x;
      for (auto& xs : b.colors)
        for (auto& x : xs) x = x == c ? d : x;
    }
  return {a.l,
          b.r,
          {a.colors[0], b.colors[1]},
          a.components + b.components - merges};
}
array<Segment, 4 * max_columns> tree;
void build(const int i, const int l, const int r) {
  if (l == r) {
    int components = 0;
    array<int, max_rows> colors{};
    for (int row = 0; row < R; row++)
      if (row != 0 && transpose[l][row] == transpose[l][row - 1])
        colors[row] = colors[row - 1];
      else {
        colors[row] = R * l + row;
        components++;
      }
    tree[i] = {l, r, {colors, colors}, components};
  } else {
    const int mid = (l + r) / 2;
    build(2 * i, l, mid);
    build(2 * i + 1, mid + 1, r);
    tree[i] = tree[2 * i] * tree[2 * i + 1];
  }
}
Segment query(const int i, const int ql, const int qr) {
  const int l = tree[i].l, r = tree[i].r;
  if (ql <= l && r <= qr) return tree[i];
  const int mid = (l + r) / 2;
  if (qr <= mid)
    return query(2 * i, ql, qr);
  else if (ql >= mid + 1)
    return query(2 * i + 1, ql, qr);
  else
    return query(2 * i, ql, qr) * query(2 * i + 1, ql, qr);
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int Q;
  cin >> R >> C >> Q;
  for (int r = 0; r < R; r++)
    for (int c = 0; c < C; c++) cin >> transpose[c][r];
  build(1, 0, C);
  while (Q--) {
    int l, r;
    cin >> l >> r;
    l--;
    r--;
    cout << query(1, l, r).components << "\n";
  }
}
