#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
int a[1005][1005],vis[1005][1005];
int dic[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int n,m;
struct node
{
int x,y,dir,corner;
};
node start,end;
void bfs()
{
queue<node> q;
int i;
node pre,cur;
pre.x=start.x;
pre.y=start.y;
pre.dir=-1;
pre.corner=0;
q.push(pre);
while(!q.empty())
{
pre=q.front();
vis[pre.x][pre.y]=1;
q.pop();
if(pre.x==end.x&&pre.y==end.y)//目标判断
{
printf("YES\n");
return ;
}
// printf("%d %d %d\n",pre.x,pre.y,pre.corner);
//printf("kkkkk\n");
for(i=0;i<4;i++)//利用搜索条件限制插入
{
//printf("jjjjj\n");
cur.x=pre.x+dic[i][0];
cur.y=pre.y+dic[i][1];
cur.dir=i;
cur.corner=pre.corner;
//判断是否越界
if(cur.x<1||cur.y<1||cur.x>n||cur.y>m)
{
//printf("1\n");
continue;
}
//当前点是棋子,但不是目标棋子
if(a[cur.x][cur.y]&&(cur.x!=end.x||cur.y!=end.y))
{//printf("3\n");
continue;
}
if(pre.dir!=cur.dir&&pre.dir!=-1)
cur.corner++;
//判断转折次数
if(cur.corner>2)
{
//printf("4\n");
continue;
}
if(cur.corner<vis[cur.x][cur.y])
{
vis[cur.x][cur.y] = cur.corner;
q.push(cur);
}
//printf("%d %d %d %d\n",cur.x,cur.y,cur.corner,i);
}
//printf("iiiiii\n");
}
printf("NO\n");
}
int main()
{
int i,j;
int q;
while(scanf("%d%d",&n,&m),n+m)
{
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&a[i][j]);
scanf("%d",&q);
for(i=0;i<q;i++)
{
scanf("%d%d%d%d",&start.x,&start.y,&end.x,&end.y);
//不是棋子,棋子不相等
if(!a[start.x][start.y]||!a[end.x][end.y]||a[start.x][start.y]!=a[end.x][end.y])
{
printf("NO\n");
continue;
}
//相同位置
if(start.x==end.x&&start.y==end.y)
{
printf("NO\n");
continue;
}
memset(vis,10000,sizeof(vis));
bfs();
}
}
return 0;
}