//一定得注意bfs标记的是状态而不是位置
//用baobao记录宝藏的位置
// 把宝物标号 例如4个宝物是标号为1 2 4 8 则不同的宝物在一起是按位与操作的结果不会相同
//dist[x][y][k]表示经过位置(x,y)时携带的宝物的“二进制按位与操作”结果为k;
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
#define N 600
char map[N][N];
int baobao[N][N];
int n,m,k,xx,yy,an;
struct node
{
int x,y;
int t;
int carry;
};
int dist[N][N][20];
int dir[4][2]={1,0, -1,0, 0,1, 0,-1};
void init()
{
int i,j,x,a,b;
for(i=0;i<n;i++)
{
scanf("%s",map[i]);
}
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
if(map[i][j]=='@')
{
xx=i;
yy=j;
}
}
scanf("%d",&k);
memset(baobao,0,sizeof(baobao));
x=1;
an=0;
for(i=1;i<=k;i++)
{
an=an|x;
scanf("%d%d",&a,&b);
a--;
b--;
baobao[a][b]=baobao[a][b]|x;
x=x*2;
}
memset(dist,0,sizeof(dist));
}
int ok(int x,int y)
{
if(x<0||x>=n)
return 0;
if(y<0||y>=m)
return 0;
return 1;
}
int bfs()
{
int i;
queue<node>q;
node cur,next;
cur.x=xx;
cur.y=yy;
cur.t=0;
cur.carry=baobao[xx][yy];
q.push(cur);
dist[xx][yy][cur.carry]=1;
while(!q.empty())
{
cur=q.front();
if(cur.carry==an)
return cur.t;
q.pop();
for(i=0;i<4;i++)
{
next.x=cur.x+dir[i][0];
next.y=cur.y+dir[i][1];
next.t=cur.t+1;
if(ok(next.x,next.y))
{
next.carry=cur.carry|baobao[next.x][next.y];
if(!dist[next.x][next.y][next.carry]&&map[next.x][next.y]!='#')
{
dist[next.x][next.y][next.carry]=1;
q.push(next);
}
}
}
}
return -1;
}
int main ()
{
while(scanf("%d%d",&n,&m),(n+m))
{
init();
int ans=bfs();
printf("%d\n",ans);
}
}
//用baobao记录宝藏的位置
// 把宝物标号 例如4个宝物是标号为1 2 4 8 则不同的宝物在一起是按位与操作的结果不会相同
//dist[x][y][k]表示经过位置(x,y)时携带的宝物的“二进制按位与操作”结果为k;
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
#define N 600
char map[N][N];
int baobao[N][N];
int n,m,k,xx,yy,an;
struct node
{
int x,y;
int t;
int carry;
};
int dist[N][N][20];
int dir[4][2]={1,0, -1,0, 0,1, 0,-1};
void init()
{
int i,j,x,a,b;
for(i=0;i<n;i++)
{
scanf("%s",map[i]);
}
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
if(map[i][j]=='@')
{
xx=i;
yy=j;
}
}
scanf("%d",&k);
memset(baobao,0,sizeof(baobao));
x=1;
an=0;
for(i=1;i<=k;i++)
{
an=an|x;
scanf("%d%d",&a,&b);
a--;
b--;
baobao[a][b]=baobao[a][b]|x;
x=x*2;
}
memset(dist,0,sizeof(dist));
}
int ok(int x,int y)
{
if(x<0||x>=n)
return 0;
if(y<0||y>=m)
return 0;
return 1;
}
int bfs()
{
int i;
queue<node>q;
node cur,next;
cur.x=xx;
cur.y=yy;
cur.t=0;
cur.carry=baobao[xx][yy];
q.push(cur);
dist[xx][yy][cur.carry]=1;
while(!q.empty())
{
cur=q.front();
if(cur.carry==an)
return cur.t;
q.pop();
for(i=0;i<4;i++)
{
next.x=cur.x+dir[i][0];
next.y=cur.y+dir[i][1];
next.t=cur.t+1;
if(ok(next.x,next.y))
{
next.carry=cur.carry|baobao[next.x][next.y];
if(!dist[next.x][next.y][next.carry]&&map[next.x][next.y]!='#')
{
dist[next.x][next.y][next.carry]=1;
q.push(next);
}
}
}
}
return -1;
}
int main ()
{
while(scanf("%d%d",&n,&m),(n+m))
{
init();
int ans=bfs();
printf("%d\n",ans);
}
}