#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<cmath>
#include<string>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const ll N=5001;
struct node{
ll x,y;
};
queue<node> p;
ll m,n,fa[N*N],num[N*N];
char mp[N][N];
ll next_s[4][2]={1,0,-1,0,0,1,0,-1};
//将二维坐标化为一维坐标
inline ll getid(ll i,ll j){
return (i-1)*m+j;
}
//寻找并更新根
ll find(ll x){
return fa[x]==x?x:fa[x]=find(fa[x]);
}
//将不同的连通集合并
void merge(ll rt,ll temp){
ll tu=find(rt);
ll tv=find(temp);
if(tu==tv)return ;
fa[tv]=tu;
num[tu]+=num[tv];
num[tv]=0;
return ;
}
//广搜
void bfs(ll x,ll y,ll rt){
node h;
h.x=x;
h.y=y;
while(p.size()){
p.pop();
}
p.push(h);
while(!p.empty()){
h=p.front();
p.pop();
for(ll k=0;k<4;k++){
ll tx=h.x+next_s[k][0];
ll ty=h.y+next_s[k][1];
if(tx<1||tx>n||ty<1||ty>m||mp[tx][ty]=='#')//墙
continue;
ll temp=getid(tx,ty);
if(tx==x&&ty==y||fa[temp]!=temp)continue;//改点已经遍历过或是起始点
merge(rt,temp);//将rt和temp所在的连通集合并
p.push(node{tx,ty});
}
}
}
//初始化
void init(){
for(ll i=1;i<=n;i++){
for(ll j=1;j<=m;j++){
ll id=getid(i,j);
fa[id]=id;//初始化fa
num[id]=1;//初始化num
}
}
//初始化连通集
for(ll i=1;i<=n;i++){
for(ll j=1;j<=m;j++){
ll id=getid(i,j);
if(mp[i][j]=='#'||fa[id]!=id)continue;//改点已在所遍历出的连通集中或者改点是墙
bfs(i,j,id);//求(i,j)所在的连通集
}
}
}
int main(){
ll t;
scanf("%lld%lld",&n,&m);
for(ll i=1;i<=n;i++){
scanf("%s",mp[i]+1);
}
init();
ll q;
scanf("%lld",&q);
while(q--){
ll x,y;
scanf("%lld%lld",&x,&y);
ll id=getid(x,y);
//合并以(x,y)为起点能到达的连通集
for(ll k=0;k<4;k++){
ll tx=x+next_s[k][0];
ll ty=y+next_s[k][1];
if(tx<1||tx>n||ty<1||ty>m||mp[tx][ty]=='#')continue;
ll cn=find(getid(tx,ty));
merge(cn,id);
}
mp[x][y]='.';//将该墙倒塌
printf("%lld\n",num[find(id)]);//id即点(x,y)在的连通集的点的个数
}
return 0;
}