#include <iostream>
#include <queue>
using namespace std;
/**************************/
int n;
int maze[6][6][2]; //存储迷宫的墙
struct state
{
int mx,my; //木乃伊
int px,py; //人
bool useful; //这个节点是否有效
}; //无效条件:越界、重复、被抓
state start,target;
queue <state> q;
int used[6][6][6][6]; //判重
int walk[4][2]= //人走一格
{
0, -1, //左
+1, 0, //下
0, +1, //右
-1, 0 //上
};
/**************************/
void init();
bool bfs();
state move(state cur, int i); //返回节点cur扩展的下一个节点next
bool isWall(int x, int y, int i); //判断方格[x,y]方向是否是墙
/*************************/
int main()
{
init();
if(bfs())
{
cout<<"Yes"<<endl;
}
else
{
cout<<"No"<<endl;
}
return 0;
}
void init()
{
cin>>n;
int i,j,x;
for(int k=0; k<n; k++)
{
cin>>i>>j>>x;
maze[i][j][x]=1; //1代表是墙
}
cin>>start.mx>>start.my;
cin>>start.px>>start.py;
cin>>target.px>>target.py;
used[start.mx][start.my][start.px][start.px]=1;
q.push(start);
}
bool bfs()
{
state now,next;
while(!q.empty())
{
now=q.front();
q.pop();
for(int i=0; i<4; i++)
{
next=move(now, i);
if(next.useful==true)
{
if(next.px==target.px&&next.py==target.py)
{
return true;
}
else
{
q.push(next);
}
}
}
}
return false;
}
//人要向i方向走一步,木乃伊要向人靠近两步
//节点无效条件:人越界、人撞墙、人被木乃伊抓到、节点next重复
state move(state now, int i)
{
state next;
next.px=now.px+walk[i][0];
next.py=now.py+walk[i][1];
if((next.px<0||next.px>=6||next.py<0||next.py>=6)||(isWall(now.px, now.py, i)))
{
next.useful=false; //该节点无效,直接返回
return next;
}
//木乃伊走两步
next.mx=now.mx;
next.my=now.my;
int step=2;
while(step--)
{
//若列数不相等,则先到达同一列
if(next.py>next.my&&!isWall(next.mx, next.my, 2))
{
next.my++;
}
else if(next.py<next.my&&!isWall(next.mx, next.my, 0))
{
next.my--;
}
//若列数相等,则再到达同一行
else if(next.py==next.my)
{
if(next.px>next.mx&&!isWall(next.mx, next.my, 1))
{
next.mx++;
}
else if(next.px<next.mx&&!isWall(next.mx, next.my, 3))
{
next.mx--;
}
//若同行同列
else if(next.px==next.mx)
{
//cout<<next.px<<' '<<next.py<<"catch"<<endl;
next.useful=false;
return next;
}
}
}
if(used[next.mx][next.my][next.px][next.py])
{
//cout<<next.px<<' '<<next.py<<"used"<<endl;
next.useful=false;
}
else
{
used[next.mx][next.my][next.px][next.py]=1;
next.useful=true;
}
return next;
}
bool isWall(int x, int y, int i)
{
switch(i)
{
case 0: //向左走
return maze[x][y-1][1]; //判断左边的方格的右侧是否是墙
case 1: //向下走
return maze[x][y][0]; //判断本格的下侧是否是墙
case 2: //向右走
return maze[x][y][1]; //判断本格的右侧是否是墙
case 3: //向上走
return maze[x-1][y][0]; //判断上边的方格的下侧是否是墙
}
return -1;
}