#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int v[10][N],col[10][N],lol,n,m,q;
int par[10*N + 5];
struct node{
	int sz,l,r;
	unordered_map<int,int>lp,rp;
	node(){
		sz = 0;l = r = -1;lp.clear(),rp.clear();
	}
}seg[4*N];
int get(int u){return par[u] == u ? u : par[u] = get(par[u]);}
node merge(const node &a,const node &b){
	node ret;
	for(auto i : a.lp)par[i.first] = i.second,par[i.second] = i.second;
	for(auto i : b.lp)par[i.first] = i.second,par[i.second] = i.second;
	for(auto i : a.rp)par[i.first] = i.second,par[i.second] = i.second;
	for(auto i : b.rp)par[i.first] = i.second,par[i.second] = i.second;
	ret.sz = a.sz + b.sz;
	for(int i = 0;i < n;i++){
		int x = get(col[i][a.r]),y = get(col[i][b.l]);
		if(x == y || v[i][a.r] != v[i][b.l])continue;
		par[x] = y;
		ret.sz--;
	}
	ret.l = a.l;
	ret.r = b.r;
	for(auto i : a.lp)ret.lp[i.first] = get(i.first);
	for(auto i : b.rp)ret.rp[i.first] = get(i.first);
	return ret;
}
void build(int c,int l,int r){
	if(l == r){
		seg[c].l = seg[c].r = l;
		for(int i = 0;i < n;i++)par[col[i][l]] = col[i][l];
		for(int i = 0;i < n - 1;i++)if(v[i][l] == v[i + 1][l])par[get(col[i + 1][l])] = get(col[i][l]);
		for(int i = 0;i < n;i++)seg[c].lp[col[i][l]] = seg[c].rp[col[i][l]] = get(col[i][l]),seg[c].sz+=col[i][l] == par[col[i][l]];
		return;
	}
	build(2*c + 1,l,(l + r)/2);
	build(2*c + 2,(l + r)/2 + 1,r);
	seg[c] = merge(seg[2*c + 1],seg[2*c + 2]);
}
node get(int c,int l,int r,int s,int e){
	node ret;
	if(l >= s && r <= e)return seg[c];
	if((l + r)/2 >= e)ret = get(2*c + 1,l,(l + r)/2,s,e);
	else if((l + r)/2 < s)ret = get(2*c + 2,(l + r)/2 + 1,r,s,e);
	else ret = merge(get(2*c + 1,l,(l + r)/2,s,e),get(2*c + 2,(l + r)/2 + 1,r,s,e));
	return ret;
}
int main(){
// 	freopen("readin.txt","r",stdin);
	scanf("%d%d%d",&n,&m,&q);
	for(int i = 0;i < n;i++)
		for(int j = 0;j < m;j++)
			scanf("%d",&v[i][j]),col[i][j] = lol++;
	build(0,0,m - 1);
	for(int i = 0;i < q;i++){
		int l,r;
		scanf("%d%d",&l,&r);
		printf("%d\n",get(0,0,m - 1,--l,--r).sz);
	}
}


#include <bits/stdc++.h>
using namespace std;
int col[10][100000];
int par[1000000];
vector<vector<int> >v;
int get(int u){
	return par[u] == u ? u : par[u] = get(par[u]);
}
struct node{
	int comp,l,r;
	map<int,int>lp,rp;
}seg[400000];
node merge(const node x,const node y){
	node a = x;
	node b = y;
	if(a.comp <= 0)return b;
	if(b.comp <= 0)return a;
	node temp;
	map<int,int> &mp = a.rp;
	for(map<int,int>::iterator i = mp.begin();i != mp.end();i++)
		par[i->first] = i->second;
	mp = a.lp;
	for(map<int,int>::iterator i = mp.begin();i != mp.end();i++)
		par[i->first] = i->second;
	mp = b.lp;
	for(map<int,int>::iterator i = mp.begin();i != mp.end();i++)
		par[i->first] = i->second;
	mp = b.rp;
	for(map<int,int>::iterator i = mp.begin();i != mp.end();i++)
		par[i->first] = i->second;
	temp.comp = a.comp + b.comp;
	for(int i = 0;i < v.size();i++){
		int c = col[i][a.r],d = col[i][b.l];
		if(v[i][a.r] == v[i][b.l] && get(c) != get(d)){
			temp.comp--;
			par[get(c)] = get(d);
		}
	}
	mp = temp.lp;
	for(int i = 0;i < v.size();i++){
		int c = col[i][b.r],d = col[i][b.l],e = col[i][a.l];
		temp.rp[c] = get(c);
		temp.lp[e] = get(e);
	}
	temp.l = a.l;
	temp.r = b.r;
	return temp;
}
void build(int c,int l,int r){
	seg[c].comp = 0;
	if(l == r){
		seg[c].l = seg[c].r = l;
		for(int i = 0;i < v.size() - 1;i++){
			int a = col[i][l],b = col[i + 1][l];
			if(v[i][l] == v[i + 1][l])
				par[get(a)] = get(b);
		}
		for(int i = 0;i < v.size();i++)
			seg[c].lp[col[i][l]] = par[col[i][l]];
		map<int,int> &mp = seg[c].lp;
		for(map<int,int>::iterator i = mp.begin();i != mp.end();i++)
			seg[c].rp[i->first] = i->second;
		for(map<int,int>::iterator i = mp.begin();i != mp.end();i++)
			seg[c].comp+=i->first ==i->second;
		return;
	}
	build(2*c + 1,l,(l + r)/2);
	build(2*c + 2,(l + r)/2 + 1,r);
	seg[c] = merge(seg[2*c + 1],seg[2*c + 2]);
	//cout << seg[c].l << " " << seg[c].r << endl;
	//cout << seg[c].comp << endl;
}
node get(int c,int l,int r,int s,int e){
	node ret;
	if(l > e || r < s){
		ret.comp = -1;
		return ret;
	}
	if(l >= s && r <= e){
		return seg[c];
	}
	node a = get(2*c + 1,l,(l + r)/2,s,e);
	node b = get(2*c + 2,(l + r)/2 + 1,r,s,e);
	ret = merge(a,b);
	return ret;
}
int main(){
	//freopen("readin.txt","r",stdin);
	int n,m,q,lel = 0;
	scanf("%d%d%d",&n,&m,&q);
	v.resize(n);
	for(int i = 0;i < n;i++)
		for(int j = 0;j < m;j++){
			int a;
			scanf("%d",&a);
			v[i].push_back(a);
			col[i][j] = lel++;
		}
	for(int i = 0;i < 1000000;i++)
		par[i] = i;
	build(0,0,v[0].size() - 1);
	//return 0;
	for(int i = 0;i < q;i++){
		int l,r;
		scanf("%d%d",&l,&r);
		l--;r--;
		printf("%d\n",get(0,0,v[0].size() - 1,l,r).comp);
	}
}


#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int v[10][N],col[10][N],lol,n,m,q;
struct node{
	int sz,l,r;
	unordered_map<int,int>lp,rp;
	node(){sz = 0;l = r = -1;lp.clear(),rp.clear();}
	int getl(int u){
		return lp[u] == u ? u : lp[u] = getl(lp[u]);
	}
	int getr(int u){
		return rp[u] == u ? u : rp[u] = getr(rp[u]);
	}
	void make(int u,int v,int t){
		if(t)lp[getl(u)] = getl(v);
		else rp[getr(u)] = getr(v);
	}
}calc,seg[N];
node merge(const node a,const node b){
	if(a.l == -1)return b;
	if(b.l == -1)return a;
	node ret;
	calc = node();
	for(auto i : a.lp)calc.lp[i.first] = i.second;
	for(auto i : b.lp)calc.lp[i.first] = i.second;
	for(auto i : a.rp)calc.lp[i.first] = i.second;
	for(auto i : b.rp)calc.lp[i.first] = i.second;
	calc.sz = a.sz + b.sz;
	for(int i = 0;i < n;i++){
		int x = calc.getl(col[i][a.r]),y = calc.getl(col[i][b.l]);
		if(x == y || v[i][a.r] != v[i][b.l])continue;
		calc.sz--;
		calc.make(x,y,1);
	}
	ret.sz = calc.sz;
	ret.l = a.l;
	ret.r = b.r;
	for(auto i : a.lp)ret.lp[i.first] = calc.getl(i.first);
	for(auto i : b.rp)ret.rp[i.first] = calc.getl(i.first);
	return ret;
}
void build(int c,int l,int r){
	if(l == r){
		seg[c].l = seg[c].r = l;
		for(int i = 0;i < n;i++)seg[c].lp[col[i][l]] = col[i][l];
		for(int i = 0;i < n - 1;i++)if(v[i][l] == v[i + 1][l])seg[c].make(col[i][l],col[i + 1][l],1);
		for(auto i : seg[c].lp)seg[c].rp[i.first] = i.second,seg[c].sz+=i.first == i.second;
		return;
	}
	build(2*c + 1,l,(l + r)/2);
	build(2*c + 2,(l + r)/2 + 1,r);
	seg[c] = merge(seg[2*c + 1],seg[2*c + 2]);
}
node get(int c,int l,int r,int s,int e){
	node ret;
	if(l > e || r < s)return ret;
	if(l == r)return seg[c];
	ret = merge(get(2*c + 1,l,(l + r)/2,s,e),get(2*c + 2,(l + r)/2 + 1,r,s,e));
	return ret;
}
int main(){
	//freopen("readin.txt","r",stdin);
	scanf("%d%d%d",&n,&m,&q);
	for(int i = 0;i < n;i++)
		for(int j = 0;j < m;j++)
			scanf("%d",&v[i][j]),col[i][j] = lol++;
	build(0,0,m - 1);
	for(int i = 0;i < q;i++){
		int l,r;
		scanf("%d%d",&l,&r);
		printf("%d\n",get(0,0,m - 1,--l,--r).sz);
	}
}


#include <bits/stdc++.h>
using namespace std;
int col[10][100000];
vector<vector<int> >v;
struct node{
	int comp,l,r;
	map<int,int>lp,rp;
	node(){
		comp = 0;
		l = 0;r = 0;
		lp.clear();rp.clear();
	}
	int getlp(int a){
		return lp[a] == a ? a : lp[a] = getlp(lp[a]);
	}
	int getrp(int a){
		return rp[a] == a? a : rp[a] == getrp(rp[a]);
	}
	void clear(){
		lp.clear();rp.clear();
	}
}seg[400000];
node merge(const node x,const node y){
	node a = x;
	node b = y;
	if(a.comp <= 0)return b;
	if(b.comp <= 0)return a;
	node temp;
	map<int,int> &mp = a.rp;
	for(map<int,int>::iterator i = mp.begin();i != mp.end();i++)
		temp.lp[i->first] = i->second;
	mp = a.lp;
	for(map<int,int>::iterator i = mp.begin();i != mp.end();i++)
		temp.lp[i->first] = i->second;
	mp = b.lp;
	for(map<int,int>::iterator i = mp.begin();i != mp.end();i++)
		temp.lp[i->first] = i->second;
	mp = b.rp;
	for(map<int,int>::iterator i = mp.begin();i != mp.end();i++)
		temp.lp[i->first] = i->second;
	int comp = a.comp + b.comp;
	for(int i = 0;i < v.size();i++){
		int c = col[i][a.r],d = col[i][b.l];
		if(v[i][a.r] == v[i][b.l] && temp.getlp(c) != temp.getlp(d)){
			comp--;
			temp.lp[temp.getlp(c)] = temp.getlp(d);
		}
	}
	node ret;
	mp = temp.lp;
	for(map<int,int>::iterator i = mp.begin();i != mp.end();i++)
		temp.lp[i->first] = temp.getlp(i->first);
	for(int i = 0;i < v.size();i++){
		int c = col[i][a.l];
		ret.lp[c] = temp.lp[c];
		temp.lp.erase(c);
	}
	for(int i = 0;i < v.size();i++){
		int c = col[i][b.r];
		ret.lp[c] = temp.getlp(c);
		temp.lp.erase(c);
	}
	temp.clear();
	ret.comp = comp;
	ret.l = a.l;
	ret.r = b.r;
	//cout << ret.l << " " << ret.r << endl;
	return ret;
}
void build(int c,int l,int r){
	seg[c].comp = 0;
	if(l == r){
		seg[c].l = seg[c].r = l;
		for(int i = 0;i < v.size();i++)
			seg[c].lp[col[i][l]] = seg[c].rp[col[i][l]] = col[i][l];
		for(int i = 0;i < v.size() - 1;i++){
			int a = col[i][l],b = col[i + 1][l];
			if(v[i][l] == v[i + 1][l])
				seg[c].lp[seg[c].getlp(a)] = seg[c].getlp(b);
		}
		for(int i = 0;i < v.size() - 1;i++){
			int a = col[i][l],b = col[i + 1][l];
			if(v[i][l] == v[i + 1][l])
				seg[c].rp[seg[c].getrp(a)] = seg[c].getrp(b);
		}
		map<int,int> &mp = seg[c].lp;
		for(map<int,int>::iterator i = mp.begin();i != mp.end();i++)
			if(i->first == seg[c].getlp(i->second))seg[c].comp++;
		return;
	}
	build(2*c + 1,l,(l + r)/2);
	build(2*c + 2,(l + r)/2 + 1,r);
	seg[c] = merge(seg[2*c + 1],seg[2*c + 2]);
	//cout << seg[2*c + 1].l << " " << seg[2*c + 2].r << endl;
	//cout << seg[c].comp << endl;
}
node get(int c,int l,int r,int s,int e){
	node ret;
	if(l > e || r < s){
		ret.comp = -1;
		return ret;
	}
	if(l >= s && r <= e){
		return seg[c];
	}
	node a = get(2*c + 1,l,(l + r)/2,s,e);
	node b = get(2*c + 2,(l + r)/2 + 1,r,s,e);
	ret = merge(a,b);
//	cout << l << " " << r << endl;
//	cout << a.comp << "  " << b.comp << endl;
//	cout << ret.comp << endl;
	return ret;
}
int main(){
	//freopen("readin.txt","r",stdin);
	int n,m,q,lel = 0;
	scanf("%d%d%d",&n,&m,&q);
	v.resize(n);
	for(int i = 0;i < n;i++)
		for(int j = 0;j < m;j++){
			int a;
			scanf("%d",&a);
			v[i].push_back(a);
			col[i][j] = lel++;
		}
	build(0,0,v[0].size() - 1);
	//return 0;
	//cout << get(0,0,v.size() - 1,0,1).comp << endl;
	for(int i = 0;i < q;i++){
		int l,r;
		scanf("%d%d",&l,&r);
		l--;r--;
		printf("%d\n",get(0,0,v[0].size() - 1,l,r).comp);
		//exit(0);
	}
}


#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int v[10][N],col[10][N],lol,n,m,q;
int par[20*N + 5];
struct node{
	int sz,l,r;
	unordered_map<int,int>lp,rp;
	node(){
		sz = 0;l = r = -1;lp.clear(),rp.clear();
	}
}seg[N];
int get(int u){return par[u] == u ? u : par[u] = get(par[u]);}
node merge(const node a,const node b){
	node ret;
	for(auto i : a.lp)par[i.first] = i.second;
	for(auto i : b.lp)par[i.first] = i.second;
	for(auto i : a.rp)par[i.first] = i.second;
	for(auto i : b.rp)par[i.first] = i.second;
	ret.sz = a.sz + b.sz;
	for(int i = 0;i < n;i++){
		int x = get(col[i][a.r]),y = get(col[i][b.l]);
		if(x == y || v[i][a.r] != v[i][b.l])continue;
		par[x] = y;
		ret.sz--;
	}
	ret.l = a.l;
	ret.r = b.r;
	for(auto i : a.lp)ret.lp[i.first] = get(i.first);
	for(auto i : b.rp)ret.rp[i.first] = get(i.first);
	return ret;
}
void build(int c,int l,int r){
	if(l == r){
		seg[c].l = seg[c].r = l;
		for(int i = 0;i < n;i++)par[col[i][l]] = col[i][l];
		for(int i = 0;i < n - 1;i++)if(v[i][l] == v[i + 1][l])par[get(col[i + 1][l])] = get(col[i][l]);
		for(int i = 0;i < n;i++)seg[c].lp[col[i][l]] = seg[c].rp[col[i][l]] = get(col[i][l]),seg[c].sz+=col[i][l] == par[col[i][l]];
		return;
	}
	build(2*c + 1,l,(l + r)/2);
	build(2*c + 2,(l + r)/2 + 1,r);
	seg[c] = merge(seg[2*c + 1],seg[2*c + 2]);
}
node get(int c,int l,int r,int s,int e){
	node ret;
	if(l == r)return seg[c];
	if((l + r)/2 >= e)ret = get(2*c + 1,l,(l + r)/2,s,e);
	else if((l + r)/2 < s)ret = get(2*c + 2,(l + r)/2 + 1,r,s,e);
	else ret = merge(get(2*c + 1,l,(l + r)/2,s,e),get(2*c + 2,(l + r)/2 + 1,r,s,e));
	return ret;
}
int main(){
	//freopen("readin.txt","r",stdin);
	scanf("%d%d%d",&n,&m,&q);
	for(int i = 0;i < n;i++)
		for(int j = 0;j < m;j++)
			scanf("%d",&v[i][j]),col[i][j] = lol++;
	build(0,0,m - 1);
	for(int i = 0;i < q;i++){
		int l,r;
		scanf("%d%d",&l,&r);
		printf("%d\n",get(0,0,m - 1,--l,--r).sz);
	}
}


#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int v[10][N],col[10][N],lol,n,m,q;
struct node{
	int sz,l,r;
	unordered_map<int,int>lp,rp;
	node(){sz = 0;l = r = -1;lp.clear(),rp.clear();}
	int getl(int u){
		return lp[u] == u ? u : lp[u] = getl(lp[u]);
	}
	int getr(int u){
		return rp[u] == u ? u : rp[u] = getr(rp[u]);
	}
	void make(int u,int v,int t){
		if(t)lp[getl(u)] = getl(v);
		else rp[getr(u)] = getr(v);
	}
}calc,seg[N];
node merge(const node a,const node b){
	node ret;
	calc = node();
	for(auto i : a.lp)calc.lp[i.first] = i.second;
	for(auto i : b.lp)calc.lp[i.first] = i.second;
	for(auto i : a.rp)calc.lp[i.first] = i.second;
	for(auto i : b.rp)calc.lp[i.first] = i.second;
	calc.sz = a.sz + b.sz;
	for(int i = 0;i < n;i++){
		int x = calc.getl(col[i][a.r]),y = calc.getl(col[i][b.l]);
		if(x == y || v[i][a.r] != v[i][b.l])continue;
		calc.sz--;
		calc.make(x,y,1);
	}
	ret.sz = calc.sz;
	ret.l = a.l;
	ret.r = b.r;
	for(auto i : a.lp)ret.lp[i.first] = calc.getl(i.first);
	for(auto i : b.rp)ret.rp[i.first] = calc.getl(i.first);
	return ret;
}
void build(int c,int l,int r){
	if(l == r){
		seg[c].l = seg[c].r = l;
		for(int i = 0;i < n;i++)seg[c].lp[col[i][l]] = col[i][l];
		for(int i = 0;i < n - 1;i++)if(v[i][l] == v[i + 1][l])seg[c].make(col[i][l],col[i + 1][l],1);
		for(auto i : seg[c].lp)seg[c].rp[i.first] = i.second,seg[c].sz+=i.first == i.second;
		return;
	}
	build(2*c + 1,l,(l + r)/2);
	build(2*c + 2,(l + r)/2 + 1,r);
	seg[c] = merge(seg[2*c + 1],seg[2*c + 2]);
}
node get(int c,int l,int r,int s,int e){
	node ret;
	if(l == r)return seg[c];
	if((l + r)/2 >= e)ret = get(2*c + 1,l,(l + r)/2,s,e);
	else if((l + r)/2 < s)ret = get(2*c + 2,(l + r)/2 + 1,r,s,e);
	else ret = merge(get(2*c + 1,l,(l + r)/2,s,e),get(2*c + 2,(l + r)/2 + 1,r,s,e));
	return ret;
}
int main(){
	//freopen("readin.txt","r",stdin);
	scanf("%d%d%d",&n,&m,&q);
	for(int i = 0;i < n;i++)
		for(int j = 0;j < m;j++)
			scanf("%d",&v[i][j]),col[i][j] = lol++;
	build(0,0,m - 1);
	for(int i = 0;i < q;i++){
		int l,r;
		scanf("%d%d",&l,&r);
		printf("%d\n",get(0,0,m - 1,--l,--r).sz);
	}
}


#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int v[10][N],col[10][N],lol,n,m,q;
int par[10*N + 5];
struct node{
	int sz,l,r;
	unordered_map<int,int>lp,rp;
	node(){
		sz = 0;l = r = -1;lp.clear(),rp.clear();
	}
}seg[4*N];
int get(int u){return par[u] == u ? u : par[u] = get(par[u]);}
node merge(node &a,node &b){
	node ret;
	for(auto i : a.lp)par[i.first] = i.second,par[i.second] = i.second;
	for(auto i : b.lp)par[i.first] = i.second,par[i.second] = i.second;
	for(auto i : a.rp)par[i.first] = i.second,par[i.second] = i.second;
	for(auto i : b.rp)par[i.first] = i.second,par[i.second] = i.second;
	ret.sz = a.sz + b.sz;
	for(int i = 0;i < n;i++){
		int x = get(col[i][a.r]),y = get(col[i][b.l]);
		if(x == y || v[i][a.r] != v[i][b.l])continue;
		par[x] = y;
		ret.sz--;
	}
	ret.l = a.l;
	ret.r = b.r;
	for(auto i : a.lp)ret.lp[i.first] = get(i.first);
	for(auto i : b.rp)ret.rp[i.first] = get(i.first);
	return ret;
}
void build(int c,int l,int r){
	if(l == r){
		seg[c].l = seg[c].r = l;
		for(int i = 0;i < n;i++)par[col[i][l]] = col[i][l];
		for(int i = 0;i < n - 1;i++)if(v[i][l] == v[i + 1][l])par[get(col[i + 1][l])] = get(col[i][l]);
		for(int i = 0;i < n;i++)seg[c].lp[col[i][l]] = seg[c].rp[col[i][l]] = get(col[i][l]),seg[c].sz+=col[i][l] == par[col[i][l]];
		return;
	}
	build(2*c + 1,l,(l + r)/2);
	build(2*c + 2,(l + r)/2 + 1,r);
	seg[c] = merge(seg[2*c + 1],seg[2*c + 2]);
}
node get(int c,int l,int r,int s,int e){
	node ret;
	if(l >= s && r <= e)return seg[c];
	if((l + r)/2 >= e)ret = get(2*c + 1,l,(l + r)/2,s,e);
	else if((l + r)/2 < s)ret = get(2*c + 2,(l + r)/2 + 1,r,s,e);
	else ret = merge(get(2*c + 1,l,(l + r)/2,s,e),get(2*c + 2,(l + r)/2 + 1,r,s,e));
	return ret;
}
int main(){
// 	freopen("readin.txt","r",stdin);
	scanf("%d%d%d",&n,&m,&q);
	for(int i = 0;i < n;i++)
		for(int j = 0;j < m;j++)
			scanf("%d",&v[i][j]),col[i][j] = lol++;
	build(0,0,m - 1);
	for(int i = 0;i < q;i++){
		int l,r;
		scanf("%d%d",&l,&r);
		printf("%d\n",get(0,0,m - 1,--l,--r).sz);
	}
}


#include <bits/stdc++.h>
using namespace std;
vector<vector<int> >v;
int col[10][100000],par[1000000];
struct node{
	int comp,l,r;
	vector<pair<int,int> >v;
}seg[400000];
int get(int u){
	return par[u] == u ? u : par[u] = get(par[u]);
}
node merge(const node x,const node y){
	node ret;
	if(x.comp <= 0)return y;
	if(y.comp <= 0)return x;
	ret.comp = x.comp + y.comp;
	for(int i = 0;i < x.v.size();i++)
		par[x.v[i].first] = x.v[i].second;
	for(int i = 0;i < y.v.size();i++)
		par[y.v[i].first] = y.v[i].second;
	for(int i = 0;i < v.size();i++){
		int a = col[i][x.r],b = col[i][y.l];
		if(v[i][x.r] != v[i][y.l])continue;
		ret.comp-=get(a)!=get(b);
		par[get(a)] = get(b);
	}
	ret.l = x.l;ret.r = y.r;
	for(int i = 0;i < v.size();i++){
		int a = col[i][x.l],b = col[i][y.r];
		ret.v.push_back(make_pair(a,get(a)));
		ret.v.push_back(make_pair(b,get(b)));
	}
	return ret;
}
node get(int c,int l,int r,int s,int e){
	node ret;
	ret.comp = -1;
	if(l > e || r < s)return ret;
	if(l >= s && r <= e)return seg[c];
	node a = get(2*c + 1,l,(l + r)/2,s,e);
	node b = get(2*c + 2,(l + r)/2 + 1,r,s,e);
	return merge(a,b);
}
void build(int c,int l,int r){
	seg[c].comp = 0;
	if(l == r){
		seg[c].l = seg[c].r = l;
		for(int i = 0;i < v.size();i++){
			int x = col[i][l];
			par[x] = x;
		}
		for(int i = 0;i < v.size() - 1;i++){
			int x = col[i][l],y = col[i + 1][l];
			if(v[i][l] == v[i + 1][l])
				par[get(x)] = get(y);
		}
		for(int i = 0;i < v.size();i++){
			int x = col[i][l];
			seg[c].v.push_back(make_pair(x,get(x)));
			seg[c].comp+=x == get(x);
		}
		return;
	}
	build(2*c + 1,l,(l + r)/2);
	build(2*c + 2,(l + r)/2 + 1,r);
	seg[c] = merge(seg[2*c + 1],seg[2*c + 2]);
}
int main(){
	//freopen("readin.txt","r",stdin);
	int n,m,q,lol = 0;
	scanf("%d%d%d",&n,&m,&q);
 	v.resize(n);
	for(int i = 0;i < n;i++)
		for(int j = 0;j < m;j++){
			int a;
			scanf("%d",&a);
			v[i].push_back(a);
			col[i][j] = lol++;
		}
	build(0,0,n);
	for(int i = 0;i < q;i++){
		int l,r;
		scanf("%d%d",&l,&r);
		l--;r--;
		printf("%d\n",get(0,0,n,l,r).comp);
	}
}


#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int v[10][N],col[10][N],lol,n,m,q;
int par[40*N + 5];
struct node{
	int sz,l,r;
	unordered_map<int,int>lp,rp;
	node(){
		sz = 0;l = r = -1;lp.clear(),rp.clear();
	}
}seg[N];
int get(int u){return par[u] == u ? u : par[u] = get(par[u]);}
node merge(const node a,const node b){
	node ret;
	for(auto i : a.lp)par[i.first] = i.second,par[i.second] = i.second;
	for(auto i : b.lp)par[i.first] = i.second,par[i.second] = i.second;
	for(auto i : a.rp)par[i.first] = i.second,par[i.second] = i.second;
	for(auto i : b.rp)par[i.first] = i.second,par[i.second] = i.second;
	ret.sz = a.sz + b.sz;
	for(int i = 0;i < n;i++){
		int x = get(col[i][a.r]),y = get(col[i][b.l]);
		if(x == y || v[i][a.r] != v[i][b.l])continue;
		par[x] = y;
		ret.sz--;
	}
	ret.l = a.l;
	ret.r = b.r;
	for(auto i : a.lp)ret.lp[i.first] = get(i.first);
	for(auto i : b.rp)ret.rp[i.first] = get(i.first);
	return ret;
}
void build(int c,int l,int r){
	if(l == r){
		seg[c].l = seg[c].r = l;
		for(int i = 0;i < n;i++)par[col[i][l]] = col[i][l];
		for(int i = 0;i < n - 1;i++)if(v[i][l] == v[i + 1][l])par[get(col[i + 1][l])] = get(col[i][l]);
		for(int i = 0;i < n;i++)seg[c].lp[col[i][l]] = seg[c].rp[col[i][l]] = get(col[i][l]),seg[c].sz+=col[i][l] == par[col[i][l]];
		return;
	}
	build(2*c + 1,l,(l + r)/2);
	build(2*c + 2,(l + r)/2 + 1,r);
	seg[c] = merge(seg[2*c + 1],seg[2*c + 2]);
}
node get(int c,int l,int r,int s,int e){
	node ret;
	if(l >= s && r <= e)return seg[c];
	if((l + r)/2 >= e)ret = get(2*c + 1,l,(l + r)/2,s,e);
	else if((l + r)/2 < s)ret = get(2*c + 2,(l + r)/2 + 1,r,s,e);
	else ret = merge(get(2*c + 1,l,(l + r)/2,s,e),get(2*c + 2,(l + r)/2 + 1,r,s,e));
	return ret;
}
int main(){
// 	freopen("readin.txt","r",stdin);
	scanf("%d%d%d",&n,&m,&q);
	for(int i = 0;i < n;i++)
		for(int j = 0;j < m;j++)
			scanf("%d",&v[i][j]),col[i][j] = lol++;
	build(0,0,m - 1);
	for(int i = 0;i < q;i++){
		int l,r;
		scanf("%d%d",&l,&r);
		printf("%d\n",get(0,0,m - 1,--l,--r).sz);
	}
}


#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int v[10][N],col[10][N],lol,n,m,q;
int par[20*N + 5];
struct node{
	int sz,l,r;
	unordered_map<int,int>lp,rp;
	node(){
		sz = 0;l = r = -1;lp.clear(),rp.clear();
	}
}seg[N];
int get(int u){return par[u] == u ? u : par[u] = get(par[u]);}
node merge(const node a,const node b){
	node ret;
	for(auto i : a.lp)par[i.first] = i.second;
	for(auto i : b.lp)par[i.first] = i.second;
	for(auto i : a.rp)par[i.first] = i.second;
	for(auto i : b.rp)par[i.first] = i.second;
	ret.sz = a.sz + b.sz;
	for(int i = 0;i < n;i++){
		int x = get(col[i][a.r]),y = get(col[i][b.l]);
		if(x == y || v[i][a.r] != v[i][b.l])continue;
		par[x] = y;
		ret.sz--;
	}
	ret.l = a.l;
	ret.r = b.r;
	for(auto i : a.lp)ret.lp[i.first] = get(i.first);
	for(auto i : b.rp)ret.rp[i.first] = get(i.first);
	return ret;
}
void build(int c,int l,int r){
	if(l == r){
		seg[c].l = seg[c].r = l;
		for(int i = 0;i < n;i++)par[col[i][l]] = col[i][l];
		for(int i = 0;i < n - 1;i++)if(v[i][l] == v[i + 1][l])par[get(col[i + 1][l])] = get(col[i][l]);
		for(int i = 0;i < n;i++)seg[c].lp[col[i][l]] = seg[c].rp[col[i][l]] = get(col[i][l]),seg[c].sz+=col[i][l] == par[col[i][l]];
		return;
	}
	build(2*c + 1,l,(l + r)/2);
	build(2*c + 2,(l + r)/2 + 1,r);
	seg[c] = merge(seg[2*c + 1],seg[2*c + 2]);
}
node get(int c,int l,int r,int s,int e){
	node ret;
	if(l == r)return seg[c];
	if(l >= s && r <= e)return seg[c];
	if((l + r)/2 >= e)ret = get(2*c + 1,l,(l + r)/2,s,e);
	else if((l + r)/2 < s)ret = get(2*c + 2,(l + r)/2 + 1,r,s,e);
	else ret = merge(get(2*c + 1,l,(l + r)/2,s,e),get(2*c + 2,(l + r)/2 + 1,r,s,e));
	return ret;
}
int main(){
	//freopen("readin.txt","r",stdin);
	scanf("%d%d%d",&n,&m,&q);
	for(int i = 0;i < n;i++)
		for(int j = 0;j < m;j++)
			scanf("%d",&v[i][j]),col[i][j] = lol++;
	build(0,0,m - 1);
	for(int i = 0;i < q;i++){
		int l,r;
		scanf("%d%d",&l,&r);
		printf("%d\n",get(0,0,m - 1,--l,--r).sz);
	}
}


#include <bits/stdc++.h>
using namespace std;
int col[10][100000];
vector<vector<int> >v;
struct node{
	int comp,l,r;
	map<int,int>lp,rp;
	node(){
		comp = 0;
		l = 0;r = 0;
		lp.clear();rp.clear();
	}
	int getlp(int a){
		return lp[a] == a ? a : lp[a] = getlp(lp[a]);
	}
	int getrp(int a){
		return rp[a] == a? a : rp[a] == getrp(rp[a]);
	}
	void clear(){
		lp.clear();rp.clear();
	}
}seg[400000];
node merge(const node x,const node y){
	node a = x;
	node b = y;
	if(a.comp <= 0)return b;
	if(b.comp <= 0)return a;
	node temp;
	map<int,int> &mp = a.rp;
	for(map<int,int>::iterator i = mp.begin();i != mp.end();i++)
		temp.lp[i->first] = i->second;
	mp = a.lp;
	for(map<int,int>::iterator i = mp.begin();i != mp.end();i++)
		temp.lp[i->first] = i->second;
	mp = b.lp;
	for(map<int,int>::iterator i = mp.begin();i != mp.end();i++)
		temp.lp[i->first] = i->second;
	mp = b.rp;
	for(map<int,int>::iterator i = mp.begin();i != mp.end();i++)
		temp.lp[i->first] = i->second;
	temp.comp = a.comp + b.comp;
	for(int i = 0;i < v.size();i++){
		int c = col[i][a.r],d = col[i][b.l];
		if(v[i][a.r] == v[i][b.l] && temp.getlp(c) != temp.getlp(d)){
			temp.comp--;
			temp.lp[temp.getlp(c)] = temp.getlp(d);
		}
	}
	mp = temp.lp;
	for(map<int,int>::iterator i = mp.begin();i != mp.end();i++)
		temp.lp[i->first] = temp.getlp(i->first);
	for(int i = 0;i < v.size();i++){
		int c = col[i][b.r];
		temp.rp[c] = temp.lp[c];
		temp.lp.erase(c);
	}
	temp.l = a.l;
	temp.r = b.r;
	//cout << ret.l << " " << ret.r << endl;
	return temp;
}
void build(int c,int l,int r){
	seg[c].comp = 0;
	if(l == r){
		seg[c].l = seg[c].r = l;
		for(int i = 0;i < v.size();i++)
			seg[c].lp[col[i][l]] = seg[c].rp[col[i][l]] = col[i][l];
		for(int i = 0;i < v.size() - 1;i++){
			int a = col[i][l],b = col[i + 1][l];
			if(v[i][l] == v[i + 1][l])
				seg[c].lp[seg[c].getlp(a)] = seg[c].getlp(b);
		}
		for(int i = 0;i < v.size() - 1;i++){
			int a = col[i][l],b = col[i + 1][l];
			if(v[i][l] == v[i + 1][l])
				seg[c].rp[seg[c].getrp(a)] = seg[c].getrp(b);
		}
		map<int,int> &mp = seg[c].lp;
		for(map<int,int>::iterator i = mp.begin();i != mp.end();i++)
			if(i->first == seg[c].getlp(i->second))seg[c].comp++;
		return;
	}
	build(2*c + 1,l,(l + r)/2);
	build(2*c + 2,(l + r)/2 + 1,r);
	seg[c] = merge(seg[2*c + 1],seg[2*c + 2]);
	//cout << seg[2*c + 1].l << " " << seg[2*c + 2].r << endl;
	//cout << seg[c].comp << endl;
}
node get(int c,int l,int r,int s,int e){
	node ret;
	if(l > e || r < s){
		ret.comp = -1;
		return ret;
	}
	if(l >= s && r <= e){
		return seg[c];
	}
	node a = get(2*c + 1,l,(l + r)/2,s,e);
	node b = get(2*c + 2,(l + r)/2 + 1,r,s,e);
	ret = merge(a,b);
//	cout << l << " " << r << endl;
//	cout << a.comp << "  " << b.comp << endl;
//	cout << ret.comp << endl;
	return ret;
}
int main(){
	//freopen("readin.txt","r",stdin);
	int n,m,q,lel = 0;
	scanf("%d%d%d",&n,&m,&q);
	v.resize(n);
	for(int i = 0;i < n;i++)
		for(int j = 0;j < m;j++){
			int a;
			scanf("%d",&a);
			v[i].push_back(a);
			col[i][j] = lel++;
		}
	build(0,0,v[0].size() - 1);
	//return 0;
	//cout << get(0,0,v.size() - 1,0,1).comp << endl;
	for(int i = 0;i < q;i++){
		int l,r;
		scanf("%d%d",&l,&r);
		l--;r--;
		printf("%d\n",get(0,0,v[0].size() - 1,l,r).comp);
		//exit(0);
	}
}


#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int v[10][N],col[10][N],lol,n,m,q;
int par[10*N];
struct node{
	int sz,l,r;
	pair<int,int>lp[10],rp[10];
	node(){
		sz = 0;l = r = -1;
		for(int i = 0;i < 10;i++)lp[i] = rp[i] = {0,0};
	}
}seg[4*N];
int get(int u){return par[u] == u ? u : par[u] = get(par[u]);}
node merge(const node &a,const node &b){
	node ret;
	for(int i = 0;i < n;i++){
		par[a.lp[i].first] = a.lp[i].second,par[a.lp[i].second] = a.lp[i].second;
		par[b.lp[i].first] = b.lp[i].second,par[b.lp[i].second] = b.lp[i].second;
		par[a.rp[i].first] = a.rp[i].second,par[a.rp[i].second] = a.rp[i].second;
		par[b.rp[i].first] = b.rp[i].second,par[b.rp[i].second] = b.rp[i].second;
	}
	ret.sz = a.sz + b.sz;
	for(int i = 0;i < n;i++){
		int x = get(col[i][a.r]),y = get(col[i][b.l]);
		if(x == y || v[i][a.r] != v[i][b.l])continue;
		par[x] = y;
		ret.sz--;
	}
	ret.l = a.l;
	ret.r = b.r;
	for(int i = 0;i < n;i++)ret.lp[i] = {a.lp[i].first,get(a.lp[i].first)},ret.rp[i] = {b.rp[i].first,get(b.rp[i].first)};
	return ret;
}
void build(int c,int l,int r){
	if(l == r){
		seg[c].l = seg[c].r = l;
		for(int i = 0;i < n;i++)par[col[i][l]] = col[i][l];
		for(int i = 0;i < n - 1;i++)if(v[i][l] == v[i + 1][l])par[get(col[i + 1][l])] = get(col[i][l]);
		for(int i = 0;i < n;i++)seg[c].lp[i] = seg[c].rp[i] = {col[i][l],get(col[i][l])},seg[c].sz+=col[i][l] == par[col[i][l]];
		return;
	}
	build(2*c + 1,l,(l + r)/2);
	build(2*c + 2,(l + r)/2 + 1,r);
	seg[c] = merge(seg[2*c + 1],seg[2*c + 2]);
}
node get(int c,int l,int r,int s,int e){
	node ret;
	if(l >= s && r <= e)return seg[c];
	if((l + r)/2 >= e)ret = get(2*c + 1,l,(l + r)/2,s,e);
	else if((l + r)/2 < s)ret = get(2*c + 2,(l + r)/2 + 1,r,s,e);
	else ret = merge(get(2*c + 1,l,(l + r)/2,s,e),get(2*c + 2,(l + r)/2 + 1,r,s,e));
	return ret;
}
int main(){
// 	freopen("readin.txt","r",stdin);
	scanf("%d%d%d",&n,&m,&q);
	for(int i = 0;i < n;i++)
		for(int j = 0;j < m;j++)
			scanf("%d",&v[i][j]),col[i][j] = lol++;
	build(0,0,m - 1);
	for(int i = 0;i < q;i++){
		int l,r;
		scanf("%d%d",&l,&r);
		printf("%d\n",get(0,0,m - 1,--l,--r).sz);
	}
}


//CF 811E
#include<iostream>
#include<cstdio>
#include<fstream>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<cmath>
#include<cstring>
#include<cstdlib>
using namespace std;
typedef long long LL;
struct Tree{
	int x;
	int l;
	int r;
	int cl[11];
	int cr[11];
}T[222222];
int n,a[111111][11],ff;
pair<int,int> f[111];
void merg(int k,int le,int md,int ri)
{
	int i,j,t[11][2],p[44],u[44];
	for(i=0;i<44;i=i+1)
		p[i]=i,u[i]=0;
	T[k].x=T[le].x+T[ri].x;
	for(i=1;i<=n;i=i+1){
		T[k].cl[i]=T[le].cl[i];
		u[T[k].cl[i]]=1;
		t[i][0]=T[le].cr[i];
		t[i][1]=T[ri].cl[i]+22;
	}
	for(i=1;i<=n;i=i+1){
		if(a[md][i]==a[md+1][i]&&t[i][0]!=p[t[i][1]]){
			p[t[i][1]]=t[i][0];
			T[k].x--;
		}
	}
	for(i=1;i<=n;i=i+1){
		if(p[T[ri].cr[i]]<22){
			T[k].cr[i]=p[T[ri].cr[i]];
			u[T[k].cr[i]]=1;
		}
		else
			T[k].cr[i]=0;
	}
	j=1;
	for(i=1;i<=n;i=i+1)
		if(T[k].cr[i]==0){
			while(u[j]){
				j++;
			}
			T[k].cr[i]=j;
			u[j]=1;
		}
}
void build(int k,int ll,int rr)
{
	T[k].l=ll;
	T[k].r=rr;
	if(ll==rr){
		int i,s;
		s=0;
		T[k].cl[0]=0;
		for(i=1;i<=n;i=i+1){
			if(a[ll][i]==a[ll][i-1])
				T[k].cl[i]=T[k].cl[i-1];
			else{
				T[k].cl[i]=T[k].cl[i-1]+1;
				s++;
			}
			T[k].cr[i]=T[k].cl[i];
		}
		T[k].x=s;
		return;
	}
	int md;
	md=(ll+rr)/2;
	build(k*2,ll,md);
	build(k*2+1,md+1,rr);
	merg(k,k*2,md,k*2+1);
}
void query(int k,int ll,int rr)
{
	//cout<<k<<ll<<rr<<endl;
	if(ll>rr||T[k].l>rr||T[k].r<ll)
		return;
	if(T[k].l==ll&&T[k].r==rr){
		ff++;
		f[ff]=make_pair(T[k].l,k);
		return;
	}
	int md;
	md=(T[k].l+T[k].r)/2;
	if(ll<=md)
		query(k*2,ll,min(md,rr));
	if(md+1<=rr)
		query(k*2+1,max(ll,md+1),rr);
}
int main()
{
	int m,q,i,j,ql,qr;
	cin>>n>>m>>q;
	for(i=1;i<=n;i=i+1){
		for(j=1;j<=m;j=j+1)
			cin>>a[j][i];
	}
	build(1,1,m);
	//for(i=1;i<2*m;i=i+1)
	//	printf("%d %d %d %d\n",i,T[i].l,T[i].r,T[i].x);
	for(i=1;i<=q;i=i+1){
		cin>>ql>>qr;
		ff=0;
		query(1,ql,qr);
		sort(f+1,f+ff+1);
		T[2*m+1]=T[f[1].second];
		//for(j=1;j<=ff;j++)
		//	cout<<f[j].first<<' '<<f[j].second<<endl;
		for(j=2;j<=ff;j=j+1){
			merg(2*m+j,2*m+j-1,f[j].first-1,f[j].second);
			//cout<<T[f[j].second].x<<T[2*m+j].x<<endl;
		}
		cout<<T[2*m+ff].x<<endl;
		for(j=0;j<=ff+10;j=j+1)
			f[2*m+j]=make_pair(0,0);
	}
	return 0;
}
/*
4 5 4
1 1 1 1 1
1 2 2 3 3
1 1 1 2 5
4 4 5 5 5
1 5
2 5
1 2
4 5

*/


//CF 811E
#include<iostream>
#include<cstdio>
#include<fstream>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<cmath>
#include<cstring>
#include<cstdlib>
using namespace std;
typedef long long LL;
struct Tree{
	int x;
	int l;
	int r;
	int cl[11];
	int cr[11];
}T[888888];
int n,a[111111][11],ff;
pair<int,int> f[111];
int d[44];
int fnd(int k)
{
	if(d[k]==k)
		return k;
	d[k]=fnd(d[k]);
	return d[k];
}
void merg(int k,int le,int ri,int md)
{
	int i,j;
	T[k].x=T[le].x+T[ri].x;
	for(i=0;i<44;i=i+1){
		d[i]=i;
	}
	for(i=1;i<=n;i=i+1){
		if(a[md][i]==a[md+1][i]&&fnd(T[le].cr[i])!=fnd(T[ri].cl[i]+22)){
			T[k].x--;
			d[fnd(T[ri].cl[i]+22)]=fnd(T[le].cr[i]);
		}
	}
	for(i=1;i<=n;i=i+1){
		T[k].cl[i]=fnd(T[le].cl[i]);
		T[k].cr[i]=fnd(T[ri].cr[i]+22);
	}
	for(i=0;i<44;i=i+1)
		d[i]=0;
	j=0;
	for(i=1;i<=n;i=i+1){
		if(d[T[k].cl[i]]==0){
			j++;
			d[T[k].cl[i]]=j;
		}
		T[k].cl[i]=d[T[k].cl[i]];
		if(d[T[k].cr[i]]==0){
			j++;
			d[T[k].cr[i]]=j;
		}
		T[k].cr[i]=d[T[k].cr[i]];
	}
}
void build(int k,int ll,int rr)
{
	T[k].l=ll;
	T[k].r=rr;
	if(ll==rr){
		int i,s;
		s=0;
		T[k].cl[0]=0;
		for(i=1;i<=n;i=i+1){
			if(a[ll][i]==a[ll][i-1])
				T[k].cl[i]=T[k].cl[i-1];
			else{
				T[k].cl[i]=T[k].cl[i-1]+1;
				s++;
			}
			T[k].cr[i]=T[k].cl[i];
		}
		T[k].x=s;
		return;
	}
	int md;
	md=(ll+rr)/2;
	build(k*2,ll,md);
	build(k*2+1,md+1,rr);
	merg(k,k*2,k*2+1,md);
}
void query(int k,int ll,int rr)
{
	//cout<<k<<ll<<rr<<endl;
	if(ll>rr||T[k].l>rr||T[k].r<ll)
		return;
	if(T[k].l==ll&&T[k].r==rr){
		ff++;
		f[ff]=make_pair(T[k].l,k);
		return;
	}
	int md;
	md=(T[k].l+T[k].r)/2;
	if(ll<=md)
		query(k*2,ll,min(md,rr));
	if(md+1<=rr)
		query(k*2+1,max(ll,md+1),rr);
}
void print(int i)
{
	int j;
	printf("%d %d %d %d\n",i,T[i].l,T[i].r,T[i].x);
	for(j=1;j<=n;j=j+1)
		printf("%d ",T[i].cl[j]);
	printf("\n");
	for(j=1;j<=n;j=j+1)
		printf("%d ",T[i].cr[j]);
	printf("\n\n");
}
int main()
{
	int m,q,i,j,ql,qr,p;
	cin>>n>>m>>q;
	for(i=1;i<=n;i=i+1){
		for(j=1;j<=m;j=j+1)
			cin>>a[j][i];
	}
	build(1,1,m);
	//for(i=1;i<2*m;i=i+1)
	//	print(i);
	for(i=1;i<=q;i=i+1){
		cin>>ql>>qr;
		ff=0;
		query(1,ql,qr);
		sort(f+1,f+ff+1);
		p=800000;
		T[p+1]=T[f[1].second];
		//for(j=1;j<=ff;j++)
		//	cout<<f[j].first<<' '<<f[j].second<<endl;
		for(j=2;j<=ff;j=j+1){
			merg(p+j,p+j-1,f[j].second,f[j].first-1);
		}
		cout<<T[p+ff].x<<endl;
		for(j=0;j<=ff+10;j=j+1)
			f[j]=make_pair(0,0);
	}
	return 0;
}
/*
9 9 3
2 1 2 1 2 1 1 1 1
1 1 1 1 1 1 1 2 2
2 2 2 2 1 1 1 1 1
2 2 2 2 1 1 1 2 2
2 2 2 1 1 1 2 2 2
2 1 1 1 2 2 2 1 2
1 2 2 2 2 2 1 1 1
1 2 2 1 2 1 2 1 2
1 2 1 1 1 1 1 1 1
1 9
2 8
3 5
*/


//CF 811E
#include<iostream>
#include<cstdio>
#include<fstream>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<cmath>
#include<cstring>
#include<cstdlib>
using namespace std;
typedef long long LL;
struct Tree{
	int x;
	int l;
	int r;
	int cl[11];
	int cr[11];
}T[888888];
int n,a[111111][11],ff;
pair<int,int> f[111];
int d[44];
int fnd(int k)
{
	if(d[k]==k)
		return k;
	d[k]=fnd(d[k]);
	return d[k];
}
void merg(int k,int le,int ri,int md)
{
	int i,j;
	T[k].x=T[le].x+T[ri].x;
	for(i=0;i<44;i=i+1){
		d[i]=i;
	}
	for(i=1;i<=n;i=i+1){
		if(a[md][i]==a[md+1][i]&&fnd(T[le].cr[i])!=fnd(T[ri].cl[i]+22)){
			T[k].x--;
			d[fnd(T[ri].cl[i]+22)]=fnd(T[le].cr[i]);
		}
	}
	for(i=1;i<=n;i=i+1){
		T[k].cl[i]=fnd(T[le].cl[i]);
		T[k].cr[i]=fnd(T[ri].cr[i]+22);
	}
	for(i=0;i<44;i=i+1)
		d[i]=0;
	j=0;
	for(i=1;i<=n;i=i+1){
		if(d[T[k].cl[i]]==0){
			j++;
			d[T[k].cl[i]]=j;
		}
		T[k].cl[i]=d[T[k].cl[i]];
		if(d[T[k].cr[i]]==0){
			j++;
			d[T[k].cr[i]]=j;
		}
		T[k].cr[i]=d[T[k].cr[i]];
	}
}
void build(int k,int ll,int rr)
{
	T[k].l=ll;
	T[k].r=rr;
	if(ll==rr){
		int i,s;
		s=0;
		T[k].cl[0]=0;
		for(i=1;i<=n;i=i+1){
			if(a[ll][i]==a[ll][i-1])
				T[k].cl[i]=T[k].cl[i-1];
			else{
				T[k].cl[i]=T[k].cl[i-1]+1;
				s++;
			}
			T[k].cr[i]=T[k].cl[i];
		}
		T[k].x=s;
		return;
	}
	int md;
	md=(ll+rr)/2;
	build(k*2,ll,md);
	build(k*2+1,md+1,rr);
	merg(k,k*2,k*2+1,md);
}
void query(int k,int ll,int rr)
{
	//cout<<k<<ll<<rr<<endl;
	if(ll>rr||T[k].l>rr||T[k].r<ll)
		return;
	if(T[k].l==ll&&T[k].r==rr){
		ff++;
		f[ff]=make_pair(T[k].l,k);
		return;
	}
	int md;
	md=(T[k].l+T[k].r)/2;
	if(ll<=md)
		query(k*2,ll,min(md,rr));
	if(md+1<=rr)
		query(k*2+1,max(ll,md+1),rr);
}
void print(int i)
{
	int j;
	printf("%d %d %d %d\n",i,T[i].l,T[i].r,T[i].x);
	for(j=1;j<=n;j=j+1)
		printf("%d ",T[i].cl[j]);
	printf("\n");
	for(j=1;j<=n;j=j+1)
		printf("%d ",T[i].cr[j]);
	printf("\n\n");
}
int main()
{
	int m,q,i,j,ql,qr;
	cin>>n>>m>>q;
	for(i=1;i<=n;i=i+1){
		for(j=1;j<=m;j=j+1)
			cin>>a[j][i];
	}
	build(1,1,m);
	//for(i=1;i<2*m;i=i+1)
	//	print(i);
	for(i=1;i<=q;i=i+1){
		cin>>ql>>qr;
		ff=0;
		query(1,ql,qr);
		sort(f+1,f+ff+1);
		T[8*m+1]=T[f[1].second];
		//for(j=1;j<=ff;j++)
		//	cout<<f[j].first<<' '<<f[j].second<<endl;
		for(j=2;j<=ff;j=j+1){
			merg(8*m+j,8*m+j-1,f[j].second,f[j].first-1);
			//print(8*m+j);
		}
		cout<<T[8*m+ff].x<<endl;
		for(j=0;j<=ff+10;j=j+1)
			f[8*m+j]=make_pair(0,0);
	}
	return 0;
}
/*
9 9 3
2 1 2 1 2 1 1 1 1
1 1 1 1 1 1 1 2 2
2 2 2 2 1 1 1 1 1
2 2 2 2 1 1 1 2 2
2 2 2 1 1 1 2 2 2
2 1 1 1 2 2 2 1 2
1 2 2 2 2 2 1 1 1
1 2 2 1 2 1 2 1 2
1 2 1 1 1 1 1 1 1
1 9
2 8
3 5
*/


//CF 811E
#include<iostream>
#include<cstdio>
#include<fstream>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<cmath>
#include<cstring>
#include<cstdlib>
using namespace std;
typedef long long LL;
struct Tree{
	int x;
	int l;
	int r;
	int cl[11];
	int cr[11];
}T[888888];
int n,a[111111][11],ff;
pair<int,int> f[111];
int d[44];
int fnd(int k)
{
	if(d[k]==k)
		return k;
	d[k]=fnd(d[k]);
	return d[k];
}
void merg(int k,int le,int ri,int md)
{
	int i,j;
	T[k].x=T[le].x+T[ri].x;
	for(i=0;i<44;i=i+1){
		d[i]=i;
	}
	for(i=1;i<=n;i=i+1){
		if(a[md][i]==a[md+1][i]&&fnd(T[le].cr[i])!=fnd(T[ri].cl[i]+22)){
			T[k].x--;
			d[fnd(T[ri].cl[i]+22)]=fnd(T[le].cr[i]);
		}
	}
	for(i=1;i<=n;i=i+1){
		T[k].cl[i]=fnd(T[le].cl[i]);
		T[k].cr[i]=fnd(T[ri].cr[i]+22);
	}
	for(i=0;i<44;i=i+1)
		d[i]=0;
	j=0;
	for(i=1;i<=n;i=i+1){
		if(d[T[k].cl[i]]==0){
			j++;
			d[T[k].cl[i]]=j;
		}
		T[k].cl[i]=d[T[k].cl[i]];
		if(d[T[k].cr[i]]==0){
			j++;
			d[T[k].cr[i]]=j;
		}
		T[k].cr[i]=d[T[k].cr[i]];
	}
}
void build(int k,int ll,int rr)
{
	T[k].l=ll;
	T[k].r=rr;
	if(ll==rr){
		int i,s;
		s=0;
		T[k].cl[0]=0;
		for(i=1;i<=n;i=i+1){
			if(a[ll][i]==a[ll][i-1])
				T[k].cl[i]=T[k].cl[i-1];
			else{
				T[k].cl[i]=T[k].cl[i-1]+1;
				s++;
			}
			T[k].cr[i]=T[k].cl[i];
		}
		T[k].x=s;
		return;
	}
	int md;
	md=(ll+rr)/2;
	build(k*2,ll,md);
	build(k*2+1,md+1,rr);
	merg(k,k*2,k*2+1,md);
}
void query(int k,int ll,int rr)
{
	//cout<<k<<ll<<rr<<endl;
	if(ll>rr||T[k].l>rr||T[k].r<ll)
		return;
	if(T[k].l==ll&&T[k].r==rr){
		ff++;
		f[ff]=make_pair(T[k].l,k);
		return;
	}
	int md;
	md=(T[k].l+T[k].r)/2;
	if(ll<=md)
		query(k*2,ll,min(md,rr));
	if(md+1<=rr)
		query(k*2+1,max(ll,md+1),rr);
}
void print(int i)
{
	int j;
	printf("%d %d %d %d\n",i,T[i].l,T[i].r,T[i].x);
	for(j=1;j<=n;j=j+1)
		printf("%d ",T[i].cl[j]);
	printf("\n");
	for(j=1;j<=n;j=j+1)
		printf("%d ",T[i].cr[j]);
	printf("\n\n");
}
int main()
{
	int m,q,i,j,ql,qr,p;
	cin>>n>>m>>q;
	for(i=1;i<=n;i=i+1){
		for(j=1;j<=m;j=j+1)
			scanf("%d",&a[j][i]);
	}
	build(1,1,m);
	//for(i=1;i<2*m;i=i+1)
	//	print(i);
	for(i=1;i<=q;i=i+1){
		scanf("%d%d",&ql,&qr);
		ff=0;
		query(1,ql,qr);
		sort(f+1,f+ff+1);
		p=800000;
		T[p+1]=T[f[1].second];
		//for(j=1;j<=ff;j++)
		//	cout<<f[j].first<<' '<<f[j].second<<endl;
		for(j=2;j<=ff;j=j+1){
			merg(p+j,p+j-1,f[j].second,f[j].first-1);
		}
		cout<<T[p+ff].x<<endl;
		for(j=0;j<=ff;j=j+1)
			f[j]=make_pair(0,0);
	}
	return 0;
}
/*
9 9 3
2 1 2 1 2 1 1 1 1
1 1 1 1 1 1 1 2 2
2 2 2 2 1 1 1 1 1
2 2 2 2 1 1 1 2 2
2 2 2 1 1 1 2 2 2
2 1 1 1 2 2 2 1 2
1 2 2 2 2 2 1 1 1
1 2 2 1 2 1 2 1 2
1 2 1 1 1 1 1 1 1
1 9
2 8
3 5
*/


//CF 811E
#include<iostream>
#include<cstdio>
#include<fstream>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<cmath>
#include<cstring>
#include<cstdlib>
using namespace std;
typedef long long LL;
struct Tree{
	int x;
	int l;
	int r;
	int cl[11];
	int cr[11];
}T[444444];
int n,a[111111][11],ff;
pair<int,int> f[111];
int d[44];
int fnd(int k)
{
	if(d[k]==k)
		return k;
	d[k]=fnd(d[k]);
	return d[k];
}
void merg(int k,int le,int ri,int md)
{
	int i,j;
	T[k].x=T[le].x+T[ri].x;
	for(i=0;i<44;i=i+1){
		d[i]=i;
	}
	for(i=1;i<=n;i=i+1){
		if(a[md][i]==a[md+1][i]&&fnd(T[le].cr[i])!=fnd(T[ri].cl[i]+22)){
			T[k].x--;
			d[fnd(T[ri].cl[i]+22)]=fnd(T[le].cr[i]);
		}
	}
	for(i=1;i<=n;i=i+1){
		T[k].cl[i]=fnd(T[le].cl[i]);
		T[k].cr[i]=fnd(T[ri].cr[i]+22);
	}
	for(i=0;i<44;i=i+1)
		d[i]=0;
	j=0;
	for(i=1;i<=n;i=i+1){
		if(d[T[k].cl[i]]==0){
			j++;
			d[T[k].cl[i]]=j;
		}
		T[k].cl[i]=d[T[k].cl[i]];
		if(d[T[k].cr[i]]==0){
			j++;
			d[T[k].cr[i]]=j;
		}
		T[k].cr[i]=d[T[k].cr[i]];
	}
}
void build(int k,int ll,int rr)
{
	T[k].l=ll;
	T[k].r=rr;
	if(ll==rr){
		int i,s;
		s=0;
		T[k].cl[0]=0;
		for(i=1;i<=n;i=i+1){
			if(a[ll][i]==a[ll][i-1])
				T[k].cl[i]=T[k].cl[i-1];
			else{
				T[k].cl[i]=T[k].cl[i-1]+1;
				s++;
			}
			T[k].cr[i]=T[k].cl[i];
		}
		T[k].x=s;
		return;
	}
	int md;
	md=(ll+rr)/2;
	build(k*2,ll,md);
	build(k*2+1,md+1,rr);
	merg(k,k*2,k*2+1,md);
}
void query(int k,int ll,int rr)
{
	//cout<<k<<ll<<rr<<endl;
	if(ll>rr||T[k].l>rr||T[k].r<ll)
		return;
	if(T[k].l==ll&&T[k].r==rr){
		ff++;
		f[ff]=make_pair(T[k].l,k);
		return;
	}
	int md;
	md=(T[k].l+T[k].r)/2;
	if(ll<=md)
		query(k*2,ll,min(md,rr));
	if(md+1<=rr)
		query(k*2+1,max(ll,md+1),rr);
}
void print(int i)
{
	int j;
	printf("%d %d %d %d\n",i,T[i].l,T[i].r,T[i].x);
	for(j=1;j<=n;j=j+1)
		printf("%d ",T[i].cl[j]);
	printf("\n");
	for(j=1;j<=n;j=j+1)
		printf("%d ",T[i].cr[j]);
	printf("\n\n");
}
int main()
{
	int m,q,i,j,ql,qr;
	cin>>n>>m>>q;
	for(i=1;i<=n;i=i+1){
		for(j=1;j<=m;j=j+1)
			cin>>a[j][i];
	}
	build(1,1,m);
	//for(i=1;i<2*m;i=i+1)
	//	print(i);
	for(i=1;i<=q;i=i+1){
		cin>>ql>>qr;
		ff=0;
		query(1,ql,qr);
		sort(f+1,f+ff+1);
		T[4*m+1]=T[f[1].second];
		//for(j=1;j<=ff;j++)
		//	cout<<f[j].first<<' '<<f[j].second<<endl;
		for(j=2;j<=ff;j=j+1){
			merg(4*m+j,4*m+j-1,f[j].second,f[j].first-1);
			//print(4*m+j);
		}
		cout<<T[4*m+ff].x<<endl;
		for(j=0;j<=ff+10;j=j+1)
			f[4*m+j]=make_pair(0,0);
	}
	return 0;
}
/*
9 9 3
2 1 2 1 2 1 1 1 1
1 1 1 1 1 1 1 2 2
2 2 2 2 1 1 1 1 1
2 2 2 2 1 1 1 2 2
2 2 2 1 1 1 2 2 2
2 1 1 1 2 2 2 1 2
1 2 2 2 2 2 1 1 1
1 2 2 1 2 1 2 1 2
1 2 1 1 1 1 1 1 1
1 9
2 8
3 5
*/


//CF 811E
#include<iostream>
#include<cstdio>
#include<fstream>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<cmath>
#include<cstring>
#include<cstdlib>
using namespace std;
typedef long long LL;
struct Tree{
	int x;
	int l;
	int r;
	int cl[11];
	int cr[11];
}T[222222];
int n,a[111111][11],ff;
pair<int,int> f[111];
int d[44];
int fnd(int k)
{
	if(d[k]==k)
		return k;
	d[k]=fnd(d[k]);
	return d[k];
}
void merg(int k,int le,int ri,int md)
{
	int i,j;
	T[k].x=T[le].x+T[ri].x;
	for(i=0;i<44;i=i+1){
		d[i]=i;
	}
	for(i=1;i<=n;i=i+1){
		if(a[md][i]==a[md+1][i]&&fnd(T[le].cr[i])!=fnd(T[ri].cl[i]+22)){
			T[k].x--;
			d[fnd(T[ri].cl[i]+22)]=fnd(T[le].cr[i]);
		}
	}
	for(i=1;i<=n;i=i+1){
		T[k].cl[i]=fnd(T[le].cl[i]);
		T[k].cr[i]=fnd(T[ri].cr[i]+22);
	}
	for(i=0;i<44;i=i+1)
		d[i]=0;
	j=0;
	for(i=1;i<=n;i=i+1){
		if(d[T[k].cl[i]]==0){
			j++;
			d[T[k].cl[i]]=j;
		}
		T[k].cl[i]=d[T[k].cl[i]];
		if(d[T[k].cr[i]]==0){
			j++;
			d[T[k].cr[i]]=j;
		}
		T[k].cr[i]=d[T[k].cr[i]];
	}
}
void build(int k,int ll,int rr)
{
	T[k].l=ll;
	T[k].r=rr;
	if(ll==rr){
		int i,s;
		s=0;
		T[k].cl[0]=0;
		for(i=1;i<=n;i=i+1){
			if(a[ll][i]==a[ll][i-1])
				T[k].cl[i]=T[k].cl[i-1];
			else{
				T[k].cl[i]=T[k].cl[i-1]+1;
				s++;
			}
			T[k].cr[i]=T[k].cl[i];
		}
		T[k].x=s;
		return;
	}
	int md;
	md=(ll+rr)/2;
	build(k*2,ll,md);
	build(k*2+1,md+1,rr);
	merg(k,k*2,k*2+1,md);
}
void query(int k,int ll,int rr)
{
	//cout<<k<<ll<<rr<<endl;
	if(ll>rr||T[k].l>rr||T[k].r<ll)
		return;
	if(T[k].l==ll&&T[k].r==rr){
		ff++;
		f[ff]=make_pair(T[k].l,k);
		return;
	}
	int md;
	md=(T[k].l+T[k].r)/2;
	if(ll<=md)
		query(k*2,ll,min(md,rr));
	if(md+1<=rr)
		query(k*2+1,max(ll,md+1),rr);
}
void print(int i)
{
	int j;
	printf("%d %d %d %d\n",i,T[i].l,T[i].r,T[i].x);
	for(j=1;j<=n;j=j+1)
		printf("%d ",T[i].cl[j]);
	printf("\n");
	for(j=1;j<=n;j=j+1)
		printf("%d ",T[i].cr[j]);
	printf("\n\n");
}
int main()
{
	int m,q,i,j,ql,qr;
	cin>>n>>m>>q;
	for(i=1;i<=n;i=i+1){
		for(j=1;j<=m;j=j+1)
			cin>>a[j][i];
	}
	build(1,1,m);
	//for(i=1;i<2*m;i=i+1)
	//	print(i);
	for(i=1;i<=q;i=i+1){
		cin>>ql>>qr;
		ff=0;
		query(1,ql,qr);
		sort(f+1,f+ff+1);
		T[2*m+1]=T[f[1].second];
		//for(j=1;j<=ff;j++)
		//	cout<<f[j].first<<' '<<f[j].second<<endl;
		for(j=2;j<=ff;j=j+1){
			merg(2*m+j,2*m+j-1,f[j].second,f[j].first-1);
			//print(2*m+j);
		}
		cout<<T[2*m+ff].x<<endl;
		for(j=0;j<=ff+10;j=j+1)
			f[2*m+j]=make_pair(0,0);
	}
	return 0;
}
/*
8 4 12
7 20 20 29
29 7 29 29
29 20 20 29
29 20 20 29
29 8 29 29
20 29 29 29
29 29 32 29
29 29 29 29
2 4
1 4
2 3
2 3
1 4
2 4
1 1
3 3
3 3
2 3
3 4
1 2
Output
5
8
7
7
8
5
4
6
6
7
4
8
Answer
6
9
7
7
9
6
4
6
6
7
4
8
*/


#include <bits/stdc++.h>
using namespace std;

#define mid ((left + right) >> 1)
#define lson rt<<1, left, mid
#define rson rt<<1|1, mid + 1, right

typedef long long ll;

const int N = 11;
const int M = 1e5 + 10;

int n, m, q;

struct Node {
    int cnt;
    vector<int> fa_l, fa_r;
    Node() {
        cnt = 0;
        fa_l = vector<int> (n, 0);
        fa_r = vector<int> (n, 0);
    }
    void print() {
        for (int x : fa_l) {
            cout << x << " ";
        }
        cout << endl;
        for (int x : fa_r) {
            cout << x << " ";
        }
        cout << endl;
    }
};

Node t[M << 2];
int length = 0;
int board[N][M], fa[M];

int get(int x) {
    if (fa[x] != x) return fa[x] = get(fa[x]);
    return fa[x];
}

Node merge(Node xa, Node xb, int md) {
    Node res;
    // init_union_set
    bool flag = true;
    if (xb.cnt ==  1) flag = false;
    for (int i = 0; i < n; i++) {
        fa[i] = xa.fa_l[i];
        fa[i + n] = xa.fa_r[i];
    }
    for (int i = 0; i < n; i++) {
        fa[2 * n + i] = xb.fa_l[i] + 2 * n;
        fa[3 * n + i] = xb.fa_r[i] + 2 * n;
    }
    int total = xa.cnt + xb.cnt;
    for (int i = 0; i < n; i++) {
        if (board[i + 1][md] == board[i + 1][md + 1]) {
            int u = get(n + i), v = get(2 * n + i);
            if (u != v) {
                if (u > v) swap(u, v);
                fa[v] = u;
                total -= 1;
            }
        }
    }
    res.cnt = total;
    map<int, int> ss;
    for (int i = 0; i < n; i++) {
        int u = get(fa[i]);
        if (ss[u] == 0) {
            ss[u] = i + 1;
        }
        res.fa_l[i] = ss[u] - 1;
    }
    for (int i = 0; i < n; i++) {
        int u = get(fa[3 * n + i]);
        if (ss[u] == 0) {
            ss[u] = n + i + 1;
        }
        res.fa_r[i] = ss[u] - 1;
    }
    return res;
}

void build(int rt, int left, int right) {
    t[rt] = Node();
    if (left == right) {
        t[rt].cnt = n;
        for (int i = 0; i < n; i++) {
            if (i > 0 && board[i + 1][left] == board[i][left]) {
                t[rt].fa_l[i] = t[rt].fa_l[i - 1];
                t[rt].cnt -= 1;
                continue;
            }
            t[rt].fa_l[i] = i;
        }
        for (int i = 0; i < n; i++) {
            t[rt].fa_r[i] = t[rt].fa_l[i];
        }
        return ;
    }
    build(lson), build(rson);
    t[rt] = merge(t[rt << 1], t[rt << 1 | 1], mid);
}

Node query(int rt, int left, int right, int l, int r) {
  if (left == l && r == right) return t[rt];
  if (mid >= r) return query(lson, l, r);
  else if (mid < l) return query(rson, l, r);
  else return merge(query(lson, l, mid), query(rson, mid + 1, r), mid);
}

int main() {
    ios::sync_with_stdio(false);
    cin >> n >> m >> q;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> board[i][j];
        }
    }
    build(1, 1, m);
    for (int i = 1; i <= q; i++) {
        int l, r;
        cin >> l >> r;
        cout << query(1, 1, m, l, r).cnt << endl;
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int N = 11;
const int M = 1e5 + 10;
const int SZ = 8e7+10;

int n, m, q, total = 1;
int t[N][M], a[N][M];
int dx[4] = {0, -1, 0, 1}, dy[4] = {1, 0, -1, 0};
int tree[SZ], version[M];

void dfs(int u, int v, int x) {
    a[u][v] = total;
    for (int i = 0; i < 4; i++) {
        int tx = u + dx[i], ty = v + dy[i];
        if (tx >= 1 && tx <= n && ty >= 1 && ty <= m && x == t[tx][ty] && !a[tx][ty]) {
            dfs(tx, ty, x);
        }
    }
}

void init() {
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (a[i][j]) continue;
            dfs(i, j, t[i][j]);
            total++;
        }
    }
}

int main() {
    scanf("%d%d%d", &n, &m, &q);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            scanf("%d", &t[i][j]);
        }
    }
    init();

    for (int i = 0; i < q; i++) {
        int l, r ;
        scanf("%d%d", &l, &r);
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define mid ((left + right) >> 1)
#define lson rt<<1, left, mid
#define rson rt<<1|1, mid + 1, right

typedef long long ll;

const int N = 11;
const int M = 1e5 + 10;

int n, m, q;

struct Node {
    int cnt;
    vector<int> fa_l, fa_r;
    Node() {
        cnt = 0;
        fa_l = vector<int> (n, 0);
        fa_r = vector<int> (n, 0);
    }
};

Node t[M << 2];
int length = 0;
int board[N][M];

int fa[M];

int get(int x) {
    if (fa[x] != x) return fa[x] = get(fa[x]);
    return fa[x];
}

Node merge(Node xa, Node xb, int md) {
    Node res;
    // init_union_set
    for (int i = 0; i < 4 * n; i++) fa[i] = i;
    for (int i = 0; i < n; i++) {
        fa[i] = xa.fa_l[i];
        fa[i + n] = xa.fa_r[i];
    }
    for (int i = 0; i < n; i++) {
        fa[2 * n + i] = xb.fa_l[i] + 2 * n;
        fa[3 * n + i] = xb.fa_r[i] + 2 * n;
    }
    int total = xa.cnt + xb.cnt;
    for (int i = 0; i < n; i++) {
        if (board[i + 1][md] == board[i + 1][md + 1]) {
            int u = get(n + i), v = get(2 * n + i);
            if (u != v) {
                fa[v] = u;
                total -= 1;
            }
        }
    }
    res.cnt = total;
    for (int i = 0; i < n; i++) {
        res.fa_l[i] = fa[i];
    }
    int vv = 0;
    map<int, int> ss;
    for (int i = 0; i < n; i++) {
        int u = get(fa[3 * n + i]);
        if (u < n) res.fa_r[i] = u;
        else {
            if (ss[u] == 0) ss[u] = ++vv;
            res.fa_r[i] = n + ss[u] - 1;
        }
    }
    return res;
}

void build(int rt, int left, int right) {
    t[rt] = Node();
    if (left == right) {
        t[rt].cnt = n;
        length = 0;
        for (int i = 0; i < n; i++) {
            if (i > 0 && board[i + 1][left] == board[i][left]) {
                t[rt].fa_l[i] = t[rt].fa_l[i - 1];
                t[rt].cnt -= 1;
                continue;
            }
            t[rt].fa_l[i] = length++;
        }
        for (int i = 0; i < n; i++) {
            t[rt].fa_r[i] = t[rt].fa_l[i];
        }
        return ;
    }
    build(lson), build(rson);
    t[rt] = merge(t[rt << 1], t[rt << 1 | 1], mid);
}

Node query(int rt, int left, int right, int l, int r) {
  if (left == l && r == right) return t[rt];
  if (mid >= r) return query(lson, l, r);
  else if (mid < l) return query(rson, l, r);
  else return merge(query(lson, l, mid), query(rson, mid + 1, r), mid);
}

int main() {
    ios::sync_with_stdio(false);
    cin >> n >> m >> q;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> board[i][j];
        }
    }
    build(1, 1, m);
    for (int i = 1; i <= q; i++) {
        int l, r;
        cin >> l >> r;
        cout << query(1, 1, m, l, r).cnt << endl;
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define mid ((left + right) >> 1)
#define lson rt<<1, left, mid
#define rson rt<<1|1, mid + 1, right

typedef long long ll;

const int N = 11;
const int M = 1e5 + 10;

int n, m, q;

struct Node {
    int cnt;
    vector<int> fa_l, fa_r;
    Node() {
        cnt = 0;
        fa_l = vector<int> (n, 0);
        fa_r = vector<int> (n, 0);
    }
    void print() {
        for (int x : fa_l) {
            cout << x << " ";
        }
        cout << endl;
        for (int x : fa_r) {
            cout << x << " ";
        }
        cout << endl;
    }
};

Node t[M << 2];
int length = 0;
int board[N][M], fa[M];

int get(int x) {
    if (fa[x] != x) return fa[x] = get(fa[x]);
    return fa[x];
}

Node merge(Node xa, Node xb, int md) {
    Node res;
    // init_union_set
    bool flag = true;
    if (xb.cnt ==  1) flag = false;
    for (int i = 0; i < n; i++) {
        fa[i] = xa.fa_l[i];
        fa[i + n] = xa.fa_r[i];
    }
    for (int i = 0; i < n; i++) {
        fa[2 * n + i] = xb.fa_l[i] + 2 * n;
        fa[3 * n + i] = xb.fa_r[i] + 2 * n;
    }
    int total = xa.cnt + xb.cnt;
    for (int i = 0; i < n; i++) {
        if (board[i + 1][md] == board[i + 1][md + 1]) {
            int u = get(n + i), v = get(2 * n + i);
            if (u != v) {
                if (u > v) swap(u, v);
                fa[v] = u;
                total -= 1;
            }
        }
    }
    res.cnt = total;
    map<int, int> ss;
    for (int i = 0; i < n; i++) {
        int u = get(fa[i]);
        if (ss[u] == 0) {
            ss[u] = i + 1;
        }
        res.fa_l[i] = ss[u] - 1;
    }
    ss.clear();
    for (int i = 0; i < n; i++) {
        int u = get(fa[3 * n + i]);
        if (ss[u] == 0) {
            ss[u] = n + i + 1;
        }
        res.fa_r[i] = ss[u] - 1;
    }
    return res;
}

void build(int rt, int left, int right) {
    t[rt] = Node();
    if (left == right) {
        t[rt].cnt = n;
        for (int i = 0; i < n; i++) {
            if (i > 0 && board[i + 1][left] == board[i][left]) {
                t[rt].fa_l[i] = t[rt].fa_l[i - 1];
                t[rt].cnt -= 1;
                continue;
            }
            t[rt].fa_l[i] = i;
        }
        for (int i = 0; i < n; i++) {
            t[rt].fa_r[i] = t[rt].fa_l[i];
        }
        return ;
    }
    build(lson), build(rson);
    t[rt] = merge(t[rt << 1], t[rt << 1 | 1], mid);
}

Node query(int rt, int left, int right, int l, int r) {
  if (left == l && r == right) return t[rt];
  if (mid >= r) return query(lson, l, r);
  else if (mid < l) return query(rson, l, r);
  else return merge(query(lson, l, mid), query(rson, mid + 1, r), mid);
}

int main() {
    ios::sync_with_stdio(false);
    cin >> n >> m >> q;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> board[i][j];
        }
    }

    build(1, 1, m);
    for (int i = 1; i <= q; i++) {
        int l, r;
        cin >> l >> r;
        cout << query(1, 1, m, l, r).cnt << endl;
    }
    return 0;
}

/*

8 4 1

1 3 3 2
2 1 2 2
2 3 3 2
2 3 3 2
2 5 2 2
3 2 2 2
2 2 4 2
2 2 2 2

2 4

*/


#include <bits/stdc++.h>
using namespace std;

#define mid ((left + right) >> 1)
#define lson rt<<1, left, mid
#define rson rt<<1|1, mid + 1, right

typedef long long ll;

const int N = 11;
const int M = 1e5 + 10;

int n, m, q;

struct Node {
    int cnt;
    vector<int> fa_l, fa_r;
    Node() {
        cnt = 0;
        fa_l = vector<int> (n, 0);
        fa_r = vector<int> (n, 0);
    }
    void print() {
        for (int x : fa_l) {
            cout << x << " ";
        }
        cout << endl;
        for (int x : fa_r) {
            cout << x << " ";
        }
        cout << endl;
    }
};

Node t[M << 2];
int length = 0;
int board[N][M], fa[M];

int get(int x) {
    if (fa[x] != x) return fa[x] = get(fa[x]);
    return fa[x];
}

Node merge(Node xa, Node xb, int md) {
    Node res;
    // init_union_set
    bool flag = true;
    if (xb.cnt ==  1) flag = false;
    for (int i = 0; i < n; i++) {
        fa[i] = xa.fa_l[i];
        fa[i + n] = xa.fa_r[i];
    }
    for (int i = 0; i < n; i++) {
        fa[2 * n + i] = xb.fa_l[i] + 2 * n;
        fa[3 * n + i] = xb.fa_r[i] + 2 * n;
    }
    int total = xa.cnt + xb.cnt;
    for (int i = 0; i < n; i++) {
        if (board[i + 1][md] == board[i + 1][md + 1]) {
            int u = get(n + i), v = get(2 * n + i);
            if (u != v) {
                if (u > v) swap(u, v);
                fa[v] = u;
                total -= 1;
            }
        }
    }
    res.cnt = total;
    map<int, int> ss;
    for (int i = 0; i < n; i++) {
        int u = get(fa[i]);
        if (ss[u] == 0) {
            ss[u] = i + 1;
        }
        res.fa_l[i] = ss[u] - 1;
    }
    ss.clear();
    for (int i = 0; i < n; i++) {
        int u = get(fa[3 * n + i]);
        if (ss[u] == 0) {
            ss[u] = n + i + 1;
        }
        res.fa_r[i] = ss[u] - 1;
    }
    return res;
}

void build(int rt, int left, int right) {
    t[rt] = Node();
    if (left == right) {
        t[rt].cnt = n;
        for (int i = 0; i < n; i++) {
            if (i > 0 && board[i + 1][left] == board[i][left]) {
                t[rt].fa_l[i] = t[rt].fa_l[i - 1];
                t[rt].cnt -= 1;
                continue;
            }
            t[rt].fa_l[i] = i;
        }
        for (int i = 0; i < n; i++) {
            t[rt].fa_r[i] = t[rt].fa_l[i];
        }
        return ;
    }
    build(lson), build(rson);
    t[rt] = merge(t[rt << 1], t[rt << 1 | 1], mid);
}

Node query(int rt, int left, int right, int l, int r) {
  if (left == l && r == right) return t[rt];
  if (mid >= r) return query(lson, l, r);
  else if (mid < l) return query(rson, l, r);
  else return merge(query(lson, l, mid), query(rson, mid + 1, r), mid);
}

int main() {
    ios::sync_with_stdio(false);
    cin >> n >> m >> q;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> board[i][j];
        }
    }

    build(1, 1, m);
    t[2].print();
    t[3].print();
    t[6].print();
    for (int i = 1; i <= q; i++) {
        int l, r;
        cin >> l >> r;
        cout << query(1, 1, m, l, r).cnt << endl;
    }
    return 0;
}

/*

8 4 1

1 3 3 2
2 1 2 2
2 3 3 2
2 3 3 2
2 5 2 2
3 2 2 2
2 2 4 2
2 2 2 2

2 4

*/


#include <bits/stdc++.h>
using namespace std;

#define mid ((left + right) >> 1)
#define lson rt<<1, left, mid
#define rson rt<<1|1, mid + 1, right

typedef long long ll;

const int N = 11;
const int M = 1e5 + 10;

int n, m, q;

struct Node {
    int cnt;
    vector<int> fa_l, fa_r;
    Node() {
        cnt = 0;
        fa_l = vector<int> (n, 0);
        fa_r = vector<int> (n, 0);
    }
    void print() {
        for (int x : fa_l) {
            cout << x << " ";
        }
        cout << endl;
        for (int x : fa_r) {
            cout << x << " ";
        }
        cout << endl;
    }
};

Node t[M << 2];
int length = 0;
int board[N][M], fa[M], ss[M];

int get(int x) {
    if (fa[x] != x) return fa[x] = get(fa[x]);
    return fa[x];
}

Node merge(Node xa, Node xb, int md) {
    Node res;
    // init_union_set
    bool flag = true;
    if (xb.cnt ==  1) flag = false;
    for (int i = 0; i < n; i++) {
        fa[i] = xa.fa_l[i];
        fa[i + n] = xa.fa_r[i];
    }
    for (int i = 0; i < n; i++) {
        fa[2 * n + i] = xb.fa_l[i] + 2 * n;
        fa[3 * n + i] = xb.fa_r[i] + 2 * n;
    }
    int total = xa.cnt + xb.cnt;
    for (int i = 0; i < n; i++) {
        if (board[i + 1][md] == board[i + 1][md + 1]) {
            int u = get(n + i), v = get(2 * n + i);
            if (u != v) {
                if (u > v) swap(u, v);
                fa[v] = u;
                total -= 1;
            }
        }
    }
    res.cnt = total;
    for (int i = 0; i < 4 * n; i++) ss[i] = 0;
    for (int i = 0; i < n; i++) {
        int u = get(fa[i]);
        if (ss[u] == 0) {
            ss[u] = i + 1;
        }
        res.fa_l[i] = ss[u] - 1;
    }
    for (int i = 0; i < n; i++) {
        int u = get(fa[3 * n + i]);
        if (ss[u] == 0) {
            ss[u] = n + i + 1;
        }
        res.fa_r[i] = ss[u] - 1;
    }
    return res;
}

void build(int rt, int left, int right) {
    t[rt] = Node();
    if (left == right) {
        t[rt].cnt = n;
        for (int i = 0; i < n; i++) {
            if (i > 0 && board[i + 1][left] == board[i][left]) {
                t[rt].fa_l[i] = t[rt].fa_l[i - 1];
                t[rt].cnt -= 1;
                continue;
            }
            t[rt].fa_l[i] = i;
        }
        for (int i = 0; i < n; i++) {
            t[rt].fa_r[i] = t[rt].fa_l[i];
        }
        return ;
    }
    build(lson), build(rson);
    t[rt] = merge(t[rt << 1], t[rt << 1 | 1], mid);
}

Node query(int rt, int left, int right, int l, int r) {
  if (left == l && r == right) return t[rt];
  if (mid >= r) return query(lson, l, r);
  else if (mid < l) return query(rson, l, r);
  else return merge(query(lson, l, mid), query(rson, mid + 1, r), mid);
}

int main() {
    ios::sync_with_stdio(false);
    cin >> n >> m >> q;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> board[i][j];
        }
    }
    build(1, 1, m);
    map<pair<int, int>, int> answer;
    for (int i = 1; i <= q; i++) {
        int l, r;
        cin >> l >> r;
        if (answer[{l, r}] != 0) {
            cout << answer[{l, r}] << endl;
        } else {
            int ans = query(1, 1, m, l, r).cnt;
            cout << ans << endl;
            answer[{l, r}] = ans;
        }
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define mid ((left + right) >> 1)
#define lson rt<<1, left, mid
#define rson rt<<1|1, mid + 1, right

typedef long long ll;

const int N = 11;
const int M = 1e5 + 10;

int n, m, q;

struct Node {
    int cnt;
    vector<int> fa_l, fa_r;
    Node() {
        cnt = 0;
        fa_l = vector<int> (n, 0);
        fa_r = vector<int> (n, 0);
    }
};

Node t[M << 2];
int length = 0;
int board[N][M];
int fa[M];

int get(int x) {
    if (fa[x] != x) return fa[x] = get(fa[x]);
    return fa[x];
}

Node merge(Node xa, Node xb, int md) {
    Node res;
    // init_union_set
    bool flag = true;
    if (xb.cnt ==  1) flag = false;

    for (int i = 0; i < n; i++) {
        fa[i] = xa.fa_l[i];
        fa[i + n] = xa.fa_r[i];
    }
    for (int i = 0; i < n; i++) {
        fa[2 * n + i] = xb.fa_l[i] + 2 * n;
        fa[3 * n + i] = xb.fa_r[i] + 2 * n;
    }
    int total = xa.cnt + xb.cnt;
    for (int i = 0; i < n; i++) {
        if (board[i + 1][md] == board[i + 1][md + 1]) {
            int u = get(n + i), v = get(2 * n + i);
            if (u != v) {
                if (u > v) swap(u, v);
                fa[v] = u;
                total -= 1;
            }
        }
    }

    res.cnt = total;
    for (int i = 0; i < n; i++) {
        res.fa_l[i] = fa[i];
    }
    int vv = 0;
    map<int, int> ss;
    for (int i = 0; i < n; i++) {
        int u = get(fa[3 * n + i]);
        if (u < n) res.fa_r[i] = u;
        else {
            if (ss[u] == 0) ss[u] = ++vv;
            res.fa_r[i] = n + ss[u] - 1;
        }
    }
    return res;
}

void build(int rt, int left, int right) {
    t[rt] = Node();
    if (left == right) {
        t[rt].cnt = n;
        for (int i = 0; i < n; i++) {
            if (i > 0 && board[i + 1][left] == board[i][left]) {
                t[rt].fa_l[i] = t[rt].fa_l[i - 1];
                t[rt].cnt -= 1;
                continue;
            }
            t[rt].fa_l[i] = i;
        }
        for (int i = 0; i < n; i++) {
            t[rt].fa_r[i] = t[rt].fa_l[i];
        }
        return ;
    }
    build(lson), build(rson);
    t[rt] = merge(t[rt << 1], t[rt << 1 | 1], mid);
}

Node query(int rt, int left, int right, int l, int r) {
  if (left == l && r == right) return t[rt];
  if (mid >= r) return query(lson, l, r);
  else if (mid < l) return query(rson, l, r);
  else return merge(query(lson, l, mid), query(rson, mid + 1, r), mid);
}

int main() {
    ios::sync_with_stdio(false);
    cin >> n >> m >> q;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> board[i][j];
        }
    }
    build(1, 1, m);
    for (int i = 1; i <= q; i++) {
        int l, r;
        cin >> l >> r;
        cout << query(1, 1, m, l, r).cnt << endl;
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int N = 11;
const int M = 1e5 + 10;
const int SZ = 4e7+10;

int n, m, q, total = 1;
int t[N][M], a[N][M];
int dx[4] = {0, -1, 0, 1}, dy[4] = {1, 0, -1, 0};
int tree[SZ], version[M];

void dfs(int u, int v, int x) {
    a[u][v] = total;
    for (int i = 0; i < 4; i++) {
        int tx = u + dx[i], ty = v + dy[i];
        if (tx >= 1 && tx <= n && ty >= 1 && ty <= m && x == t[tx][ty] && !a[tx][ty]) {
            dfs(tx, ty, x);
        }
    }
}

void init() {
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (a[i][j]) continue;
            dfs(i, j, t[i][j]);
            total++;
        }
    }
}

int main() {
    scanf("%d%d%d", &n, &m, &q);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            scanf("%d", &t[i][j]);
        }
    }
    init();

    for (int i = 0; i < q; i++) {
        int l, r ;
        scanf("%d%d", &l, &r);
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int N = 11;
const int M = 1e5 + 10;
const int SZ = 2e7+10;

int n, m, q, total = 1;
int t[N][M], a[N][M];
int dx[4] = {0, -1, 0, 1}, dy[4] = {1, 0, -1, 0};
int tree[SZ], version[M], N;

void dfs(int u, int v, int x) {
    a[u][v] = total;
    for (int i = 0; i < 4; i++) {
        int tx = u + dx[i], ty = v + dy[i];
        if (tx >= 1 && tx <= n && ty >= 1 && ty <= m && x == t[tx][ty] && !a[tx][ty]) {
            dfs(tx, ty, x);
        }
    }
}

void init() {
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (a[i][j]) continue;
            dfs(i, j, t[i][j]);
            total++;
        }
    }
}

int main() {
    scanf("%d%d%d", &n, &m, &q);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            scanf("%d", &t[i][j]);
        }
    }
    init();

    for (int i = 0; i < q; i++) {
        int l, r ;
        scanf("%d%d", &l, &r);
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int N = 11;
const int M = 1e5 + 10;
const int SZ = (4e6+10 + (int)1e5*20);

int n, m, q, total = 1;
int t[N][M], a[N][M];
int dx[4] = {0, -1, 0, 1}, dy[4] = {1, 0, -1, 0};
int tree[SZ], version[M];

void dfs(int u, int v, int x) {
    a[u][v] = total;
    for (int i = 0; i < 4; i++) {
        int tx = u + dx[i], ty = v + dy[i];
        if (tx >= 1 && tx <= n && ty >= 1 && ty <= m && x == t[tx][ty] && !a[tx][ty]) {
            dfs(tx, ty, x);
        }
    }
}

void init() {
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (a[i][j]) continue;
            dfs(i, j, t[i][j]);
            total++;
        }
    }
}

int main() {
    scanf("%d%d%d", &n, &m, &q);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            scanf("%d", &t[i][j]);
        }
    }
    init();

    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define mid ((left + right) >> 1)
#define lson rt<<1, left, mid
#define rson rt<<1|1, mid + 1, right

typedef long long ll;

const int N = 11;
const int M = 1e5 + 10;

int n, m, q;

struct Node {
    int cnt;
    vector<int> fa_l, fa_r;
    Node() {
        cnt = 0;
        fa_l = vector<int> (n, 0);
        fa_r = vector<int> (n, 0);
    }
};

Node t[M << 2];
int length = 0;
int board[N][M], fa[M];

int get(int x) {
    if (fa[x] != x) return fa[x] = get(fa[x]);
    return fa[x];
}

Node merge(Node xa, Node xb, int md) {
    Node res;
    // init_union_set
    bool flag = true;
    if (xb.cnt ==  1) flag = false;
    for (int i = 0; i < n; i++) {
        fa[i] = xa.fa_l[i];
        fa[i + n] = xa.fa_r[i] + n;
    }
    for (int i = 0; i < n; i++) {
        fa[2 * n + i] = xb.fa_l[i] + 2 * n;
        fa[3 * n + i] = xb.fa_r[i] + 3 * n;
    }
    int total = xa.cnt + xb.cnt;
    for (int i = 0; i < n; i++) {
        if (board[i + 1][md] == board[i + 1][md + 1]) {
            int u = get(n + i), v = get(2 * n + i);
            if (u != v) {
                if (u > v) swap(u, v);
                fa[v] = u;
                total -= 1;
            }
        }
    }
    res.cnt = total;
    map<int, int> ss;
    for (int i = 0; i < n; i++) {
        res.fa_l[i] = fa[i];
        int u = get(fa[3 * n + i]);
        if (ss[u] == 0) {
            ss[u] = i + 1;
        }
        res.fa_r[i] = ss[u] - 1;
    }
    return res;
}

void build(int rt, int left, int right) {
    t[rt] = Node();
    if (left == right) {
        t[rt].cnt = n;
        for (int i = 0; i < n; i++) {
            if (i > 0 && board[i + 1][left] == board[i][left]) {
                t[rt].fa_l[i] = t[rt].fa_l[i - 1];
                t[rt].cnt -= 1;
                continue;
            }
            t[rt].fa_l[i] = i;
        }
        for (int i = 0; i < n; i++) {
            t[rt].fa_r[i] = t[rt].fa_l[i];
        }
        return ;
    }
    build(lson), build(rson);
    t[rt] = merge(t[rt << 1], t[rt << 1 | 1], mid);
}

Node query(int rt, int left, int right, int l, int r) {
  if (left == l && r == right) return t[rt];
  if (mid >= r) return query(lson, l, r);
  else if (mid < l) return query(rson, l, r);
  else return merge(query(lson, l, mid), query(rson, mid + 1, r), mid);
}

int main() {
    ios::sync_with_stdio(false);
    cin >> n >> m >> q;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> board[i][j];
        }
    }
    build(1, 1, m);
    for (int i = 1; i <= q; i++) {
        int l, r;
        cin >> l >> r;
        cout << query(1, 1, m, l, r).cnt << endl;
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define mid ((left + right) >> 1)
#define lson rt<<1, left, mid
#define rson rt<<1|1, mid + 1, right

typedef long long ll;

const int N = 11;
const int M = 1e5 + 10;

int n, m, q;

struct Node {
    int cnt;
    vector<int> fa_l, fa_r;
    Node() {
        cnt = 0;
        fa_l = vector<int> (n, 0);
        fa_r = vector<int> (n, 0);
    }
};

Node t[M << 2];
int length = 0;
int board[N][M], fa[M];

int get(int x) {
    if (fa[x] != x) return fa[x] = get(fa[x]);
    return fa[x];
}

Node merge(Node xa, Node xb, int md) {
    Node res;
    // init_union_set
    bool flag = true;
    if (xb.cnt ==  1) flag = false;
    for (int i = 0; i < n; i++) {
        fa[i] = xa.fa_l[i];
        fa[i + n] = xa.fa_r[i];
    }
    for (int i = 0; i < n; i++) {
        fa[2 * n + i] = xb.fa_l[i] + 2 * n;
        fa[3 * n + i] = xb.fa_r[i] + 2 * n;
    }
    int total = xa.cnt + xb.cnt;
    for (int i = 0; i < n; i++) {
        if (board[i + 1][md] == board[i + 1][md + 1]) {
            int u = get(n + i), v = get(2 * n + i);
            if (u != v) {
                if (u > v) swap(u, v);
                fa[v] = u;
                total -= 1;
            }
        }
    }
    res.cnt = total;
    map<int, int> ss;
    for (int i = 0; i < n; i++) {
        res.fa_l[i] = fa[i];
        int u = get(fa[3 * n + i]);
        if (ss[u] == 0) {
            ss[u] = i + 1;
        }
        res.fa_r[i] = ss[u] - 1;
    }
    return res;
}

void build(int rt, int left, int right) {
    t[rt] = Node();
    if (left == right) {
        t[rt].cnt = n;
        for (int i = 0; i < n; i++) {
            if (i > 0 && board[i + 1][left] == board[i][left]) {
                t[rt].fa_l[i] = t[rt].fa_l[i - 1];
                t[rt].cnt -= 1;
                continue;
            }
            t[rt].fa_l[i] = i;
        }
        for (int i = 0; i < n; i++) {
            t[rt].fa_r[i] = t[rt].fa_l[i];
        }
        return ;
    }
    build(lson), build(rson);
    t[rt] = merge(t[rt << 1], t[rt << 1 | 1], mid);
}

Node query(int rt, int left, int right, int l, int r) {
  if (left == l && r == right) return t[rt];
  if (mid >= r) return query(lson, l, r);
  else if (mid < l) return query(rson, l, r);
  else return merge(query(lson, l, mid), query(rson, mid + 1, r), mid);
}

int main() {
    ios::sync_with_stdio(false);
    cin >> n >> m >> q;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> board[i][j];
        }
    }
    build(1, 1, m);
    for (int i = 1; i <= q; i++) {
        int l, r;
        cin >> l >> r;
        cout << query(1, 1, m, l, r).cnt << endl;
    }
    return 0;
}


#include <cstdio>
#include <cctype>
using namespace std;

const int N=1e5+10;
struct tree{
	int l[11],r[11],w;
}t[N<<2];
int n,m,ti,a[11][N],size,f[N*11],x,y;

inline char nc(void){
	static char ch[100010],*p1=ch,*p2=ch;
	return p1==p2&&(p2=(p1=ch)+fread(ch,1,100010,stdin),p1==p2)?EOF:*p1++;
}

inline void read(int &a){
	char c=nc();int f=1;
	for (;!isdigit(c);c=nc()) if (c=='-') f=-1;
	for (a=0;isdigit(c);a=(a<<3)+(a<<1)+c-'0',c=nc());
	return (void)(a*=f);
}

inline int gf(int x){return x==f[x]?x:f[x]=gf(f[x]);}
inline void merge(int x,int y){
	x=gf(x),y=gf(y);
	if (x!=y) f[x]=y;
}

#define lt (k<<1)
#define rt (k<<1|1)
#define mid (l+r>>1)
inline tree updata(tree lson,tree rson,int l,int r){
	tree ret; ret.w=lson.w+rson.w;
	for (int i=1; i<=m; ++i)
		f[lson.l[i]]=lson.l[i],f[lson.r[i]]=lson.r[i],f[rson.l[i]]=rson.l[i],f[rson.r[i]]=rson.r[i];
	for (int i=1; i<=m; ++i)
		if (a[i][mid]==a[i][mid+1]&&gf(lson.r[i])!=gf(rson.l[i]))
			--ret.w,merge(lson.r[i],rson.l[i]);
	for (int i=1; i<=m; ++i) ret.l[i]=lson.l[i],ret.r[i]=rson.r[i];
	return ret;
}

inline void build(int k,int l,int r){
	if (l==r){
		for (int i=1; i<=m; ++i)
			if (a[i-1][l]==a[i][l]) t[k].l[i]=t[k].r[i]=t[k].l[i-1];
			else t[k].l[i]=t[k].r[i]=++size,++t[k].w;
		return;
	}
	build(lt,l,mid),build(rt,mid+1,r);
	t[k]=updata(t[lt],t[rt],l,r);
}

inline tree query(int k,int l,int r,int ql,int qr){
	if (l>=ql&&r<=qr) return t[k];
	if (qr<=mid) return query(lt,l,mid,ql,qr);
	else if (ql>mid) return query(rt,mid+1,r,ql,qr);
	else return updata(query(lt,l,mid,ql,mid),query(rt,mid+1,r,mid+1,qr),l,r);
}

int main(void){
	read(m),read(n),read(ti);
	for (int i=1; i<=m; ++i)
		for (int j=1; j<=n; ++j)
			read(a[i][j]);
	for (build(1,1,n); ti; --ti) read(x),read(y),printf("%d\n",query(1,1,n,x,y).w);
	return 0;
}


#include <cstdio>
#include <cctype>
using namespace std;

const int N=1e5+10;
struct tree{
	int l[11],r[11],w;
}t[N<<2];
int n,m,ti,a[11][N],size,f[N*11],x,y;

inline char nc(void){
	static char ch[100010],*p1=ch,*p2=ch;
	return p1==p2&&(p2=(p1=ch)+fread(ch,1,100010,stdin),p1==p2)?EOF:*p1++;
}

inline void read(int &a){
	char c=nc();int f=1;
	for (;!isdigit(c);c=nc()) if (c=='-') f=-1;
	for (a=0;isdigit(c);a=(a<<3)+(a<<1)+c-'0',c=nc());
	return (void)(a*=f);
}

inline int gf(int x){return x==f[x]?x:f[x]=gf(f[x]);}
inline void merge(int x,int y){
	x=gf(x),y=gf(y);
	if (x!=y) f[x]=y;
}

#define lt (k<<1)
#define rt (k<<1|1)
#define mid (l+r>>1)
inline tree updata(tree lson,tree rson,int l,int r){
	tree ret={0}; ret.w=lson.w+rson.w;
	for (int i=1; i<=m; ++i)
		f[lson.l[i]]=lson.l[i],f[lson.r[i]]=lson.r[i],f[rson.l[i]]=rson.l[i],f[rson.r[i]]=rson.r[i];
	for (int i=1; i<=m; ++i)
		if (a[i][mid]==a[i][mid+1]&&gf(lson.r[i])!=gf(rson.l[i]))
			--ret.w,merge(lson.r[i],rson.l[i]);
	for (int i=1; i<=m; ++i) ret.l[i]=gf(lson.l[i]),ret.r[i]=gf(rson.r[i]);
	return ret;
}

inline void build(int k,int l,int r){
	if (l==r){
		for (int i=1; i<=m; ++i)
			if (a[i-1][l]==a[i][l]) t[k].l[i]=t[k].r[i]=t[k].l[i-1];
			else t[k].l[i]=t[k].r[i]=++size,++t[k].w;
		return;
	}
	build(lt,l,mid),build(rt,mid+1,r);
	t[k]=updata(t[lt],t[rt],l,r);
}

inline tree query(int k,int l,int r,int ql,int qr){
	if (l>=ql&&r<=qr) return t[k];
	if (qr<=mid) return query(lt,l,mid,ql,qr);
	else if (ql>mid) return query(rt,mid+1,r,ql,qr);
	else return updata(query(lt,l,mid,ql,mid),query(rt,mid+1,r,mid+1,qr),l,r);
}

int main(void){
	read(m),read(n),read(ti);
	for (int i=1; i<=m; ++i)
		for (int j=1; j<=n; ++j)
			read(a[i][j]);
	for (build(1,1,n); ti; --ti) read(x),read(y),printf("%d\n",query(1,1,n,x,y).w);
	return 0;
}


#include <cstdio>
#include <cctype>
using namespace std;

const int N=1e5+10;
int n,m,q,a[11][N],l[N<<2][11],r[N<<2][11],t[N<<2],size,x,y,l_wz[N<<2],r_wz[N<<2];

inline char nc(void){
	static char ch[100010],*p1=ch,*p2=ch;
	return p1==p2&&(p2=(p1=ch)+fread(ch,1,100010,stdin),p1==p2)?EOF:*p1++;
}

inline void read(int &a){
	char c=nc();int f=1;
	for (;!isdigit(c);c=nc()) if (c=='-') f=-1;
	for (a=0;isdigit(c);a=(a<<3)+(a<<1)+c-'0',c=nc());
	return void(a*=f);
}

#define lt (i<<1)
#define rt (i<<1|1)
inline void build(int n){
	for (size=1; size<n+2; size<<=1);
	for (int i=1; i<=n; ++i)
		for (int j=1; j<=m; ++j)
			l[i+size][j]=r[i+size][j]=a[j][i],t[i+size]+=a[j][i]!=a[j-1][i];
	for (int i=0; i<size; ++i) l_wz[i+size]=r_wz[i+size]=i;
	for (int i=size-1; i; --i){
		t[i]=t[lt]+t[rt],l_wz[i]=l_wz[lt],r_wz[i]=r_wz[rt];
		for (int j=1; j<=m; ++j)
			l[i][j]=l[lt][j],r[i][j]=r[rt][j],t[i]-=(r[lt][j]==l[rt][j]&&r[lt][j]>0);
	}
	return;
}

inline int query(int X,int Y){
	int L[11]={0},R[11]={0},ans=0,x,y;
	for (x=X+size-1,y=Y+size+1; x^y^1; x>>=1,y>>=1){
		if (~x&1){
			ans+=t[x^1];
			for (int i=1; i<=m; ++i) ans-=L[i]==l[x^1][i],L[i]=r[x^1][i];
		}
		if (y&1){
			ans+=t[y^1];
			for (int i=1; i<=m; ++i) ans-=R[i]==r[y^1][i],R[i]=l[y^1][i];
		}
	}
	if (r_wz[x]>=X&&l_wz[y]<=Y) for (int i=1; i<=m; ++i) ans-=r[x][i]==l[y][i];
	return ans;
}

int main(void){
	read(m),read(n),read(q);
	for (int i=1; i<=m; ++i)
		for (int j=1; j<=n; ++j)
			read(a[i][j]);
	for (build(n); q; --q) read(x),read(y),printf("%d\n",query(x,y));
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); i--)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int INF = (int) 1e9;
const ll LINF = (ll) 1e18;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
inline ll isqrt(ll k) {ll r = sqrt(k) + 1; while (r * r > k) r--; return r;}
inline ll icbrt(ll k) {ll r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}
#define db(x) cerr << #x << " = " << (x) << ", ";
#define endln cerr << "\n";
#define chkpt cerr << "-----\n";

const int maxn = 10 + 1;
const int maxm = 1e5 + 5;
const int logm = 20;
int n, m, q;
int a[maxn][maxm];
int f[logm][maxm];
int g[maxm];

int dj[maxm];

int id(int u, int v) {
    return u * m + v;
}

void init(vi v) {
    FOR(i, 0, sz(v)) dj[v[i]] = v[i];
}
int find(int u) {
    return dj[u] == u ? dj[u] : dj[u] = find(dj[u]);
}
int join(int u, int v) {
    int p = find(u);
    int q = find(v);
    if (p != q) {
        dj[p] = q;
        return 1;
    }
    return 0;
}

void solve() {
    cin >> n >> m >> q;
    FOR(i, 0, n) FOR(j, 0, m) cin >> a[i][j];
    FOR(i, 0, m) {
        f[0][i] = 1;
        FOR(j, 0, n - 1) {
            f[0][i] += a[j][i] != a[j + 1][i];
        }
    }
    FOR(i, 0, m - 1) {
        vi v;
        FOR(j, 0, n) {
            v.pb(id(j, i));
            v.pb(id(j, i + 1));
        }
        init(v);
        g[i] = sz(v);
        FOR(j, 0, n - 1) {
            if (a[j][i] == a[j + 1][i]) {
                if (join(id(j, i), id(j + 1, i))) {
                    g[i]--;
                }
            }
        }
        FOR(j, 0, n - 1) {
            if (a[j][i + 1] == a[j + 1][i + 1]) {
                if (join(id(j, i + 1), id(j + 1, i + 1))) {
                    g[i]--;
                }
            }
        }
        FOR(j, 0, n) {
            if (a[j][i] == a[j][i + 1]) {
                if (join(id(j, i), id(j, i + 1))) {
                    g[i]--;
                }
            }
        }
        g[i] = f[0][i] + f[0][i + 1] - g[i];
    }
    FOR(k, 1, logm) {
        FOR(i, 0, m) {
            int j = i + (1 << k - 1);
            if (j >= m) continue;
            f[k][i] = f[k - 1][i] + f[k - 1][j] - g[i];
        }
    }
    while (q--) {
        int l, r; cin >> l >> r; l--, r--;
        if (l == r) {
            cout << f[0][l] << "\n";
            continue;
        }
        int ans = 0;
        FORd(i, logm, 0) {
            while (l + (1 << i) <= r) {
                if (!ans) {
                    ans = f[i][l];
                }
                else {
                    ans += f[i][l] - g[l - 1];
                }
                l += (1 << i);
            }
        }
        ans += f[0][l] - g[l - 1];
        cout << ans << "\n";
    }
}

int main() {
    int JUDGE_ONLINE = 1;
    if (fopen("in.txt", "r")) {
        JUDGE_ONLINE = 0;
        assert(freopen("in.txt", "r", stdin));
        //assert(freopen("out.txt", "w", stdout));
    }
    else {
        //ios_base::sync_with_stdio(0), cin.tie(0);
    }
    solve();
    if (!JUDGE_ONLINE) {
        //cout << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); i--)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int INF = (int) 1e9;
const ll LINF = (ll) 1e18;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
inline ll isqrt(ll k) {ll r = sqrt(k) + 1; while (r * r > k) r--; return r;}
inline ll icbrt(ll k) {ll r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}
#define db(x) cerr << #x << " = " << (x) << ", ";
#define endln cerr << "\n";
#define chkpt cerr << "-----\n";

struct Node {
    int left, right;
    int num;
    int l[10], r[10];
    Node() : num(0) {}
};

const int maxn = 10 + 1;
const int maxm = 1e5 + 5;
const int logm = 20;
int n, m, q;
int a[maxn][maxm];
Node f[logm][maxm];
int dj[maxn * maxm];
vector<pair<int*, int> > rc;

inline int id(int u, int v) {
    return u * m + v;
}

void init() {
    FOR(i, 0, n) FOR(j, 0, m) dj[id(i, j)] = id(i, j);
}

int find(int u) {
    return dj[u] == u ? dj[u] : dj[u] = find(dj[u]);
}

void change(int x, int v) {
    rc.pb(mp(&dj[x], dj[x]));
    dj[x] = v;
}

int join(int u, int v) {
    int p = find(u);
    int q = find(v);
    if (p != q) {
        change(p, q);
        return 1;
    }
    return 0;
}

void rollback() {
    while (sz(rc)) {
        *rc.back().fi = rc.back().se;
        rc.pop_back();
    }
}

Node join(Node x, Node y) {
    Node res;
    res.left = x.left, res.right = y.right;
    res.num = x.num + y.num;
    FOR(i, 0, n) {
        if (a[i][x.right] == a[i][y.left]) {
            if (join(x.r[i], y.l[i])) {
                res.num--;
            }
        }
    }
    FOR(i, 0, n) {
        res.l[i] = find(x.l[i]);
        res.r[i] = find(y.r[i]);
    }
    rollback();
    return res;
}

void solve() {
    cin >> n >> m >> q;
    FOR(i, 0, n) FOR(j, 0, m) cin >> a[i][j];
    init();
    FOR(j, 0, m) {
        f[0][j].left = f[0][j].right = j;
        f[0][j].num = n;
        FOR(i, 0, n - 1) {
            if (a[i][j] == a[i + 1][j] && join(id(i, j), id(i + 1, j))) {
                f[0][j].num--;
            }
        }
        FOR(i, 0, n) {
            f[0][j].l[i] = f[0][j].r[i] = find(id(i, j));
        }
        rollback();
    }
    FOR(k, 1, logm) {
        FOR(i, 0, m) if (i + (1 << k) <= m) {
            int j = i + (1 << k - 1);
            f[k][i] = join(f[k - 1][i], f[k - 1][j]);
        }
    }
    while (q--) {
        int l, r; cin >> l >> r; l--, r--;
        Node p;
        FORd(i, logm, 0) {
            if (l + (1 << i) <= r + 1) {
                if (!p.num) {
                    p = f[i][l];
                }
                else {
                    p = join(p, f[i][l]);
                }
                l += 1 << i;
            }
        }
        cout << p.num << "\n";
    }
}

int main() {
    int JUDGE_ONLINE = 1;
    if (fopen("in.txt", "r")) {
        JUDGE_ONLINE = 0;
        assert(freopen("in.txt", "r", stdin));
        //assert(freopen("out.txt", "w", stdout));
    }
    else {
        ios_base::sync_with_stdio(0), cin.tie(0);
    }
    solve();
    if (!JUDGE_ONLINE) {
        //cout << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); i--)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int INF = (int) 1e9;
const ll LINF = (ll) 1e18;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
inline ll isqrt(ll k) {ll r = sqrt(k) + 1; while (r * r > k) r--; return r;}
inline ll icbrt(ll k) {ll r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}
#define db(x) cerr << #x << " = " << (x) << ", ";
#define endln cerr << "\n";
#define chkpt cerr << "-----\n";

struct Node {
    int left, right;
    int num;
    int l[10], r[10];
    Node() : num(0) {}
};

const int maxn = 10 + 1;
const int maxm = 1e5 + 5;
const int logm = 20;
int n, m, q;
int a[maxn][maxm];
Node f[logm][maxm];
int dj[maxn * maxm];
vector<pair<int*, int> > rc;

inline int id(int u, int v) {
    return u * m + v;
}

void init() {
    FOR(i, 0, n) FOR(j, 0, m) dj[id(i, j)] = id(i, j);
}

int find(int u) {
    return dj[u] == u ? dj[u] : dj[u] = find(dj[u]);
}

void change(int x, int v) {
    rc.pb(mp(&dj[x], dj[x]));
    dj[x] = v;
}

int join(int u, int v) {
    int p = find(u);
    int q = find(v);
    if (p != q) {
        change(p, q);
        return 1;
    }
    return 0;
}

void rollback() {
    while (sz(rc)) {
        *rc.back().fi = rc.back().se;
        rc.pop_back();
    }
}

Node join(Node x, Node y) {
    Node res;
    res.left = x.left, res.right = y.right;
    res.num = x.num + y.num;
    FOR(i, 0, n) {
        if (a[i][x.right] == a[i][y.left]) {
            if (join(x.r[i], y.l[i])) {
                res.num--;
            }
        }
    }
    FOR(i, 0, n) {
        res.l[i] = find(x.l[i]);
        res.r[i] = find(y.r[i]);
    }
    rollback();
    return res;
}

void solve() {
    cin >> n >> m >> q;
    FOR(i, 0, n) FOR(j, 0, m) cin >> a[i][j];
    init();
    FOR(j, 0, m) {
        f[0][j].left = f[0][j].right = j;
        f[0][j].num = n;
        FOR(i, 0, n - 1) {
            if (a[i][j] == a[i + 1][j] && join(id(i, j), id(i + 1, j))) {
                f[0][j].num--;
            }
        }
        FOR(i, 0, n) {
            f[0][j].l[i] = f[0][j].r[i] = find(id(i, j));
        }
        rollback();
    }
    FOR(k, 1, logm) {
        FOR(i, 0, m) if (i + (1 << k) <= m) {
            int j = i + (1 << k - 1);
            f[k][i] = join(f[k - 1][i], f[k - 1][j]);
        }
    }
    while (q--) {
        int l, r; cin >> l >> r; l--, r--;
        Node p;
        FORd(i, logm, 0) {
            if (l + (1 << i) <= r + 1) {
                if (!p.num) {
                    p = f[i][l];
                }
                else {
                    p = join(p, f[i][l]);
                }
                l += 1 << i;
            }
        }
        cout << p.num << "\n";
    }
}

int main() {
    int JUDGE_ONLINE = 1;
    if (fopen("in.txt", "r")) {
        JUDGE_ONLINE = 0;
        assert(freopen("in.txt", "r", stdin));
        //assert(freopen("out.txt", "w", stdout));
    }
    else {
        //ios_base::sync_with_stdio(0), cin.tie(0);
    }
    solve();
    if (!JUDGE_ONLINE) {
        //cout << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

// Segment Tree
// Tested here: http://codeforces.com/contest/597/submission/14216114
const int N = 1e5+5; // N -> max size of base array
int n, m, b[10][N];

struct node {
	int t[2][10], sz;
	node (): sz(0) {};
};

void uno (node &x, int l) {
	x.sz = 0;
	for (int i=0;i<n;i++) {
		x.t[0][i] = x.t[1][i] = x.sz;
		if (i == 0 || b[i][l] != b[i-1][l]) x.sz++;
	}
}

void combine (node &x, node y, node z, int mid) {
	if (y.sz == 0) x = z;
	else if (z.sz == 0) x = y;
	else {
		map<int, int> areSame;
		for (int i=0;i<n;i++) {
			x.t[0][i] = y.t[0][i];
			x.t[1][i] = z.t[1][i];
			if (b[i][mid] == b[i][mid+1]) areSame[z.t[0][i]] = y.t[1][i];
		}
		for (int i=0;i<n;i++)
			if (areSame.count(x.t[1][i])) x.t[1][i] = areSame[x.t[1][i]];
		x.sz = y.sz + z.sz - areSame.size();
	}
}

node t[4*N];
struct segtree { //max segtree
	int n;
	// n -> size of base array, t[i] -> value of segtree nodes, d[i] -> lazy update
	segtree(int _n = 0){
		n = _n;
		// memset(t,0,sizeof(int)*4*n); // 0 -> default value
		init(1, 0, n-1);
	}
	void init (int k, int l, int r) {
		if (l == r) {
			uno(t[k], l);
		}
		else {
			int mid = (l+r)>>1;
			init (k<<1, l, mid);
			init (k<<1|1, mid+1, r);
			combine(t[k], t[k<<1], t[k<<1|1], mid);
		}
		// cout << "Init: " << l << " " << r << ": " << t[k] << endl;
	}
	node _query(int k, int l, int r, int x, int y) {
	// k -> node number, [l,r] -> segtree interval, [x,y] -> query interval
	    node ret;
	    if(l > y || r < x) {
	        // ret = 0; // return identity here
	    }
	    else if(l >= x && r <= y) {
	        ret = t[k];
	    } else {
		    int mid = (l+r)>>1;
		    // replace max with your function
		    combine(ret, _query(k<<1, l, mid, x, y),
		    			_query(k<<1|1, mid+1, r, x, y), mid);
	    }
	    // cout << "Q: " << l << " " << r << " " << x << " " << y << ": " << ret << endl;
	    return ret;
	}
	int query(int l, int r){ // [l,r] -> query interval
		return _query(1,0,n-1,l,r).sz;
	}
};
int main(){
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	int q; cin >> n >> m >> q;
	for (int i=0;i<n;i++)
		for (int j=0;j<m;j++) cin >> b[i][j];
	segtree s(m);
	while (q--) {
		int l, r; cin >> l >> r; l--; r--;
		cout << s.query(l,r) << "\n";
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

// Segment Tree
// Tested here: http://codeforces.com/contest/597/submission/14216114
const int N = 1e5+5; // N -> max size of base array
int n, m, b[10][N];

struct node {
	int t[2][10], sz;
	node (): sz(0) {};
};

void uno (node &x, int l) {
	x.sz = 0;
	for (int i=0;i<n;i++) {
		if (i == 0 || b[i][l] != b[i-1][l]) x.sz++;
		x.t[0][i] = x.t[1][i] = x.sz;
	}
}

void combine (node &x, node y, node z, int mid) {
	if (y.sz == 0) x = z;
	else if (z.sz == 0) x = y;
	else {
		map<int, int> areSame;
		for (int i=0;i<n;i++) {
			x.t[0][i] = y.t[0][i];
			x.t[1][i] = z.t[1][i];
			if (b[i][mid] == b[i][mid+1]) areSame[z.t[0][i]] = y.t[1][i];
		}
		for (int i=0;i<n;i++)
			if (areSame.count(x.t[1][i])) x.t[1][i] = areSame[x.t[1][i]];
		x.sz = y.sz + z.sz - areSame.size();
	}
}

void print (node &x) {
	cout << "S: " << x.sz << endl;
	for (int i=0;i<n;i++) cout << x.t[0][i] << " " << x.t[1][i] << endl;
}
node t[4*N];
struct segtree { //max segtree
	int n;
	// n -> size of base array, t[i] -> value of segtree nodes, d[i] -> lazy update
	segtree(int _n = 0){
		n = _n;
		// memset(t,0,sizeof(int)*4*n); // 0 -> default value
		init(1, 0, n-1);
	}
	void init (int k, int l, int r) {
		if (l == r) {
			uno(t[k], l);
		}
		else {
			int mid = (l+r)>>1;
			init (k<<1, l, mid);
			init (k<<1|1, mid+1, r);
			combine(t[k], t[k<<1], t[k<<1|1], mid);
		}
		// cout << "Init: " << l << " " << r << ": " << endl;
		// print(t[k]);
	}
	node _query(int k, int l, int r, int x, int y) {
	// k -> node number, [l,r] -> segtree interval, [x,y] -> query interval
	    node ret;
	    if(l > y || r < x) {
	        // ret = 0; // return identity here
	    }
	    else if(l >= x && r <= y) {
	        ret = t[k];
	    } else {
		    int mid = (l+r)>>1;
		    // replace max with your function
		    combine(ret, _query(k<<1, l, mid, x, y),
		    			_query(k<<1|1, mid+1, r, x, y), mid);
	    }
	    // cout << "Q: " << l << " " << r << " " << x << " " << y << ": " << endl;
	    // print(ret);
	    return ret;
	}
	int query(int l, int r){ // [l,r] -> query interval
		node ret = _query(1,0,n-1,l,r);
		return ret.sz;
	}
};
int main(){
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	int q; cin >> n >> m >> q;
	for (int i=0;i<n;i++)
		for (int j=0;j<m;j++) cin >> b[i][j];
	segtree s(m);
	while (q--) {
		int l, r; cin >> l >> r; l--; r--;
		cout << s.query(l,r) << "\n";
	}
	return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define F first
#define S second
using namespace std;

// Segment Tree
// Tested here: http://codeforces.com/contest/597/submission/14216114
const int N = 1e5+5; // N -> max size of base array
int n, m, b[10][N], par[40];

struct node {
	int t[2][10], sz;
	node (): sz(0) {};
};

void uno (node &x, int l) {
	x.sz = 0;
	for (int i=0;i<n;i++) {
		x.t[0][i] = x.t[1][i] = x.sz;
		if (i == n-1 || b[i][l] != b[i+1][l]) x.sz++;
	}
}

void compress (node &x) {
	map<int,int> rank; int cnt = 0;
	for (int i=0;i<2;i++)
		for (int j=0;j<n;j++) rank[x.t[i][j]] = 0;
	for (auto &p: rank) p.S = cnt++;
	for (int i=0;i<2;i++)
		for (int j=0;j<n;j++) x.t[i][j] = rank[x.t[i][j]];
}

int parent(int u) {
	return par[u] == u ? u : par[u] = parent(par[u]);
}

void combine (node &x, node y, node z, int mid) {
	if (y.sz == 0) x = z;
	else if (z.sz == 0) x = y;
	else {
		x.sz = y.sz + z.sz;
		for (int i=0;i<4*n;i++) par[i] = i;
		for (int i=0;i<n;i++) {
			z.t[0][i] += 2*n; z.t[1][i] += 2*n;
			x.t[0][i] = y.t[0][i];
			x.t[1][i] = z.t[1][i];
			if (b[i][mid] == b[i][mid+1]) if (parent(z.t[0][i]) != parent(y.t[1][i])) {
				par[parent(z.t[0][i])] = parent(y.t[1][i]); x.sz--;
			}
		}

		for (int i=0;i<n;i++)
			for (int j=0;j<2;j++)
				x.t[j][i] = parent(x.t[j][i]);
		compress (x);
	}
}

void print (node &x) {
	cout << "S: " << x.sz << endl;
	for (int i=0;i<n;i++) cout << x.t[0][i] << " " << x.t[1][i] << endl;
}
node t[4*N];
struct segtree { //max segtree
	int n;
	// n -> size of base array, t[i] -> value of segtree nodes, d[i] -> lazy update
	segtree(int _n = 0){
		n = _n;
		// memset(t,0,sizeof(int)*4*n); // 0 -> default value
		init(1, 0, n-1);
	}
	void init (int k, int l, int r) {
		if (l == r) {
			uno(t[k], l);
		}
		else {
			int mid = (l+r)>>1;
			init (k<<1, l, mid);
			init (k<<1|1, mid+1, r);
			combine(t[k], t[k<<1], t[k<<1|1], mid);
		}
		// cout << "Init: " << l << " " << r << ": " << endl;
		// print(t[k]);
	}
	node _query(int k, int l, int r, int x, int y) {
	// k -> node number, [l,r] -> segtree interval, [x,y] -> query interval
	    node ret;
	    if(l > y || r < x) {
	        // ret = 0; // return identity here
	    }
	    else if(l >= x && r <= y) {
	        ret = t[k];
	    } else {
		    int mid = (l+r)>>1;
		    // replace max with your function
		    combine(ret, _query(k<<1, l, mid, x, y),
		    			_query(k<<1|1, mid+1, r, x, y), mid);
	    }
	    // cout << "Q: " << l << " " << r << " " << x << " " << y << ": " << endl;
	    // print(ret);
	    return ret;
	}
	int query(int l, int r){ // [l,r] -> query interval
		node ret = _query(1,0,n-1,l,r);
		return ret.sz;
	}
};
int main(){
	// ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	int q; scanf("%d %d %d", &n, &m, &q);
	for (int i=0;i<n;i++)
		for (int j=0;j<m;j++) scanf("%d", &b[i][j]);
	segtree s(m);
	while (q--) {
		int l, r; scanf("%d %d", &l, &r); l--; r--;
		cout << s.query(l,r) << "\n";
	}
	return 0;
}