/*
    題意:問海平面為d時,各個島嶼的income總和
           
    首先要注意d高于格子的高度時,未必被掩了,跟相鄰有關。
    方法就是類似最短路的先對所有的點重新標號,得到每個點真正被淹沒的時間。 
    用PQ的dijkstra 我用spfa好像有問題,應該我寫得有問題
    像數據    33333
            35553
            35153
            35553
            33333
    
    之后就是對查詢排序,然后從高到低,看那些格子升出了水面,這些格子可能會和周圍的格子練成島嶼,
    這個部分通過并查集來做就好了。
    用map<int, int>來記錄大小為first的島嶼有second個,以回答查詢。

    細節很多
    如:
        應該合并到較高位置;
        要先查詢、每個點高度排序,對每次查詢都掃描是否已經合并過就TLE了
    
*/

#include
<cstdio>
#include
<cstring>
#include
<algorithm>
#include
<map>
#include
<vector>
#include
<queue>

using namespace std;

const int MAXN = 510;

const int dx[4]={0,0,1,-1};
const int dy[4]={1,-1,0,0};

int R,C,Q;
long long ans[10010];
int height[MAXN][MAXN];
bool visit[MAXN][MAXN];
int fa[MAXN*MAXN],S[MAXN*MAXN];
map
<int,int>mp;

bool chk(int x,int y){return x>=0&&x<R&&y>=0&&y<C;}

/*
    計算1的個數 也可以遞推
    ones[0]=0
    for(int i=1;i<MAXN*MAXN;i++)
        ones[i]=ones[i>>1]+(i&1);
*/

inline 
int calc(int x)
{
    
int tot=0;
    
while(x)tot+=(x&1),x>>=1;
    
return tot;
}

int find(int x)
{
    
return fa[x]==x?x:fa[x]=find(fa[x]);
}

void unit(int x,int y)
{    
    x
=find(x),y=find(y);
    
if(x==y)return;
    
if(--mp[S[x]]==0)mp.erase(S[x]);//注意刪除掉!
    if(--mp[S[y]]==0)mp.erase(S[y]);
    fa[x]
=y;
    S[y]
+=S[x];
    mp[S[y]]
++;
}

int main()
{
    
while(~scanf("%d%d",&R,&C))
    
{
        mp.clear();
        memset(visit,
0,sizeof(visit));
        priority_queue
<pair<int,pair<int,int> > >PQ;
        
for(int i=0;i<R;i++)
            
for(int j=0;j<C;j++)
            
{
                scanf(
"%d",&height[i][j]);
                
if(i==R-1||i==0||j==C-1||j==0)
                
{
                    visit[i][j]
=1;
                    PQ.push(make_pair(
-height[i][j],make_pair(i,j)));
                }

            }

        
//dijkstra
        while(!PQ.empty())
        
{
            
int x=PQ.top().second.first,y=PQ.top().second.second;
            PQ.pop();    
            
for(int k=0;k<4;k++)
            
{
                
int xx=x+dx[k],yy=y+dy[k];
                
if(chk(xx,yy)&&!visit[xx][yy])
                
{
                    visit[xx][yy]
=1;//第一次遇到的就是答案了
                    height[xx][yy]=max(height[xx][yy],height[x][y]);
                    PQ.push(make_pair(
-height[xx][yy],make_pair(xx,yy)));
                }

            }

        }


        
/*    
            for(int i=0;i<R;i++)
                for(int j=0;j<C;j++)
                {
                    printf("%d%c",height[i][j],j==C-1?'\n':' ');
                }
        
*/


        scanf(
"%d",&Q);
        vector
<pair<int,pair<int,int> > > VQ,VT;
        VQ.resize(Q);
//
        for(int i=0;i<Q;i++)
        
{
            scanf(
"%d%d",&VQ[i].first,&VQ[i].second.first);
            VQ[i].second.second
=i;
        }

        
for(int i=0;i<R;i++)
            
for(int j=0;j<C;j++)
            
{
                fa[i
*C+j]=i*C+j;
                S[i
*C+j]=1;
                VT.push_back(make_pair(height[i][j],make_pair(i,j)));
            }


        
//按照查詢的d排序從大到小查詢
        
//然后VT也排序一下,這樣就不需多次合并了 用一個指針走下去就行了!
        sort(VQ.begin(),VQ.end());
        sort(VT.begin(),VT.end());

        memset(visit,
0,sizeof(visit));
        vector
<pair<int,pair<int,int> > >::reverse_iterator itQ=VQ.rbegin(),itT=VT.rbegin();
        
for(;itQ!=VQ.rend();itQ++)
        
{
            
int d=itQ->first,A=itQ->second.first,id=itQ->second.second;
            
while(itT!=VT.rend()&&itT->first>d)//
            {    
                
int x=itT->second.first,y=itT->second.second;
                visit[x][y]
=1;                
                mp[
1]++;
                
for(int k=0;k<4;k++)
                
{
                    
int xx=x+dx[k],yy=y+dy[k];
                    
//向高處(visit[,]=1)合并
                    if(chk(xx,yy)&&visit[xx][yy])unit(xx*C+yy,x*C+y);
                }

                itT
++;
            }

            ans[id]
=0;
            
for(map<int,int>::iterator it=mp.begin();it!=mp.end();it++)
            
{
                ans[id]
+=it->second*(1LL<<calc(it->first&A));
            }

        }

        
for(int i=0;i<Q;i++)
            printf(
"%lld\n",ans[i]);
    }

    
return 0;
}