#include <bits/stdc++.h>
using namespace std;
const long double EPS = 1e-10;
const long long MOD = 1e9 + 7;
const long double PI = 3.1415926535897932384626433832795028841;
long long powmod(long long a, long long b) {
  long long res = 1;
  a %= MOD;
  for (; b; b >>= 1) {
    if (b & 1) res = res * a % MOD;
    a = a * a % MOD;
  }
  return res;
}
ostream &operator<<(std::ostream &stream, const long long *arr) {
  int i = 0;
  cout << "{";
  while (arr[i] != INT_MAX) {
    cout << arr[i];
    if (arr[i + 1] != INT_MAX) cout << ",";
    i++;
  }
  cout << "}";
  return stream;
}
ostream &operator<<(std::ostream &stream, const vector<int> vec) {
  cout << "{";
  for (int i = 0; i < vec.size(); i++) {
    cout << vec[i];
    if (i != vec.size() - 1) cout << ",";
  }
  cout << "}";
  return stream;
}
ostream &operator<<(std::ostream &stream,
                    const pair<long long, long long> &vec) {
  cout << "(" << vec.first << ',' << vec.second << ")";
  return stream;
}
template <class T>
struct segtree_t {
  vector<T> t, lazy, flag_equal;
  int st, sz;
  T (*addition_fun)(T, T);
  T invalid_value;
  segtree_t() {}
  segtree_t(int start, int finish, T *arr, T (*add_fun)(T, T), T invalid_val) {
    int size = (finish + 1) * 2;
    int tree_size = 2;
    while (tree_size < size) tree_size *= 2;
    t = vector<T>(tree_size);
    lazy = vector<T>(tree_size);
    flag_equal = vector<T>(tree_size);
    st = start;
    sz = finish;
    addition_fun = add_fun;
    invalid_value = invalid_val;
    build(1, start, finish, arr);
  }
  void build(int i, int l, int r, T *arr) {
    if (l > r) return;
    lazy[i] = 0;
    flag_equal[i] = 0;
    if (l == r) {
      t[i] = arr[l];
    } else {
      build(i * 2, l, (l + r) / 2, arr);
      build(i * 2 + 1, (l + r) / 2 + 1, r, arr);
      t[i] = addition_fun(t[i * 2], t[i * 2 + 1]);
    }
  }
  void inc_range(int l, int r, T value) {
    if (l > r) return;
    inc_range_rec(1, st, sz, l, r, value);
  }
  void set_values(int l, int r, T value) {
    set_values_rec(1, st, sz, l, r, value);
  }
  void inc_range_rec(int i, int l, int r, int tl, int tr, T value) {
    if (lazy[i] != 0) {
      t[i] += lazy[i];
      if (l != r) {
        lazy[i * 2] += lazy[i];
        lazy[i * 2 + 1] += lazy[i];
      }
      lazy[i] = 0;
    }
    if (r < tl or l > tr) return;
    if (l > r) return;
    if (l >= tl and r <= tr) {
      if (l != r) {
        lazy[i * 2] += value;
        lazy[i * 2 + 1] += value;
      }
      t[i] += value;
    } else {
      inc_range_rec(i * 2, l, (l + r) / 2, tl, tr, value);
      inc_range_rec(i * 2 + 1, (l + r) / 2 + 1, r, tl, tr, value);
      t[i] = addition_fun(t[i * 2], t[i * 2 + 1]);
    }
  }
  T query_rec(int i, int l, int r, int tl, int tr) {
    if (flag_equal[i] != 0) {
      if (l != r) {
        t[i * 2] = t[i];
        t[i * 2 + 1] = t[i];
        flag_equal[i * 2] = 1;
        flag_equal[i * 2 + 1] = 1;
      }
      flag_equal[i] = 0;
    }
    if (r < tl or l > tr) return invalid_value;
    if (l > r) return invalid_value;
    if (lazy[i] != 0) {
      t[i] += lazy[i];
      if (l != r) {
        lazy[i * 2] += lazy[i];
        lazy[i * 2 + 1] += lazy[i];
      }
      lazy[i] = 0;
    }
    if (l >= tl and r <= tr) {
      return t[i];
    } else {
      T m1 = query_rec(i * 2, l, (l + r) / 2, tl, tr);
      T m2 = query_rec(i * 2 + 1, (l + r) / 2 + 1, r, tl, tr);
      if (m1 == invalid_value && m2 == invalid_value) return invalid_value;
      if (m1 == invalid_value) return m2;
      if (m2 == invalid_value) return m1;
      return addition_fun(m1, m2);
    }
  }
  T query(int l, int r) { return query_rec(1, st, sz, l, r); }
  void set_values_rec(int i, int l, int r, int tl, int tr, T value) {
    if (flag_equal[i] != 0) {
      if (l != r) {
        t[i * 2] = t[i];
        t[i * 2 + 1] = t[i];
        flag_equal[i * 2] = 1;
        flag_equal[i * 2 + 1] = 1;
      }
      flag_equal[i] = 0;
    }
    if (r < tl || l > tr) return;
    if (l > r) return;
    if (l >= tl and r <= tr) {
      t[i] = value;
      flag_equal[i] = 1;
    } else {
      set_values_rec(i * 2, l, (l + r) / 2, tl, tr, value);
      set_values_rec(i * 2 + 1, (l + r) / 2 + 1, r, tl, tr, value);
      t[i] = addition_fun(t[i * 2], t[i * 2 + 1]);
    }
  }
  ~segtree_t() {}
};
template <class T>
struct fenwick_t {
  vector<T> FW;
  fenwick_t(int n) { FW = vector<T>(n + 1); }
  void inc(int i, T v) {
    while (i <= FW.size() - 1) {
      FW[i] += v;
      i += i & (-i);
    }
  }
  T get(int i) {
    T rta = 0;
    while (i > 0) {
      rta += FW[i];
      i -= i & (-i);
    }
    return rta;
  }
};
struct dsu_t {
  vector<int> p, sz, depth;
  dsu_t() {}
  dsu_t(int n) {
    p = vector<int>(n + 1);
    sz = vector<int>(n + 1);
    depth = vector<int>(n + 1);
    for (int i = 1; i <= n; i++) {
      p[i] = i;
      sz[i] = 1;
      depth[i] = 1;
    }
  }
  void reset(int i) {
    p[i] = i;
    sz[i] = 1;
    depth[i] = 1;
  }
  int get(int i) {
    int j = i;
    while (p[i] != i) {
      i = p[i];
    }
    while (p[j] != j) {
      int aux = p[j];
      p[j] = i;
      j = aux;
    }
    return i;
  }
  void merge(int a, int b) {
    a = get(a);
    b = get(b);
    if (a == b) return;
    if (sz[a] > sz[b]) {
      p[b] = a;
      sz[a] += sz[b];
    } else {
      p[a] = b;
      sz[b] += sz[a];
      if (depth[a] == depth[b]) depth[b]++;
    }
  }
  void show() {
    for (int i = 1; i <= p.size() - 1; i++) {
      cout << i << ": " << p[i] << ' ' << sz[i] << ' ' << depth[i] << " \n";
    }
  }
};
const int maxm = 1e5 + 20;
int n, m, q;
struct node {
  int lft[10], rgt[10];
  int l, r;
  int sz;
  void copy_from(node &b) {
    l = b.l;
    r = b.r;
    sz = b.sz;
    for (int i = 0; i < n; i++) {
      lft[i] = b.lft[i];
      rgt[i] = b.rgt[i];
    }
  }
};
ostream &operator<<(std::ostream &stream, node &a) {
  cout << "(" << a.l << "," << a.r << ") => ";
  cout << "size = " << a.sz << '\n';
  for (int i = 0; i < n; i++) {
    cout << a.lft[i] << ' ' << a.rgt[i] << '\n';
  }
  return stream;
}
int data[10][maxm];
node t[(1 << 18) + 5];
int left_arr[maxm][10], right_arr[maxm][10], sizes[maxm];
dsu_t dsu;
void merge(node &a, node &b, node &ans) {
  for (int i = 0; i < n; i++) {
    dsu.reset(a.lft[i]);
    dsu.reset(b.lft[i]);
    dsu.reset(a.rgt[i]);
    dsu.reset(b.rgt[i]);
  }
  set<pair<int, int>> merges;
  for (int i = 0; i < n; i++) {
    if (data[i][a.r] == data[i][b.l]) {
      int u = b.lft[i];
      int v = a.rgt[i];
      dsu.merge(u, v);
      merges.insert(make_pair(min(u, v), max(u, v)));
    }
  }
  ans.l = a.l;
  ans.r = b.r;
  for (int i = 0; i < n; i++) {
    ans.lft[i] = dsu.get(a.lft[i]);
    ans.rgt[i] = dsu.get(b.rgt[i]);
  }
  ans.sz = a.sz + b.sz - merges.size();
}
void build(int i, int l, int r) {
  if (l == r) {
    for (int j = 0; j < n; j++) {
      t[i].lft[j] = left_arr[l][j];
      t[i].rgt[j] = right_arr[l][j];
      t[i].l = l;
      t[i].r = r;
      t[i].sz = sizes[l];
    }
    return;
  }
  build(i * 2, l, (l + r) / 2);
  build(i * 2 + 1, (l + r) / 2 + 1, r);
  merge(t[i * 2], t[i * 2 + 1], t[i]);
}
int query(int i, int l, int r, int tl, int tr, node &ans) {
  if (l > r) return 0;
  if (r < tl || l > tr) return 0;
  if (l >= tl && r <= tr) {
    ans.copy_from(t[i]);
    return 1;
  }
  node ans1, ans2;
  int q1 = query(i * 2, l, (l + r) / 2, tl, tr, ans1);
  int q2 = query(i * 2 + 1, (l + r) / 2 + 1, r, tl, tr, ans2);
  if (q1 == 0 && q2 == 0) return 0;
  if (q1 == 0) {
    ans.copy_from(ans2);
    return 1;
  } else if (q2 == 0) {
    ans.copy_from(ans1);
    return 1;
  }
  merge(ans1, ans2, ans);
  return 1;
}
int main() {
  scanf("%d%d%d", &n, &m, &q);
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) scanf("%d", &data[i][j]);
  }
  dsu = dsu_t(n * m);
  int comp_id = 0;
  for (int j = 0; j < m; j++) {
    for (int i = 0; i < n; i++) {
      if (i == 0 || data[i][j] != data[i - 1][j]) {
        comp_id++;
        sizes[j]++;
      }
      left_arr[j][i] = comp_id;
      right_arr[j][i] = comp_id;
    }
  }
  build(1, 0, m - 1);
  while (q--) {
    int l, r;
    scanf("%d%d", &l, &r);
    l--;
    r--;
    node ans;
    query(1, 0, m - 1, l, r, ans);
    printf("%d\n", ans.sz);
  }
}
