#include<iostream.h>
const int INF=100000000;
const int MAX_SIZE=256;
struct PriorityQueueNode{
int x,y;
int p;
};
int M, N;
int x,y,d,t;
double f1,f2;
int vEdge[MAX_SIZE][MAX_SIZE];
int hEdge[MAX_SIZE][MAX_SIZE];
int dist[MAX_SIZE][MAX_SIZE];
int xmax, ymax;
int xd, yd;
int PriorityQueueSize;
PriorityQueueNode priorityQueue[MAX_SIZE*MAX_SIZE];
//初始化优先队列为空队列,即置其长度为0.
inline void InitPriorityQueue();
//返回优先队列队首元素的只读引用,不改变优先队列状态.
inline const PriorityQueueNode& PeekPriorityQueue();
//判断优先队列是否为空,是返回tru额,否返回false.
inline bool IsEmptyPriorityQueue();
//出队
void DeletePriorityQueue();
//入队
void EnterPriorityQueue(const PriorityQueueNode& pqn);
//广度优先遍历求解.
int Bfs();
int main()
{
int i, j;
while(cin>>M>>N&&!(M==-1&&N==-1)){
//初始化各边的权值为0
for(i=0;i<MAX_SIZE;i++){
for(j=0;j<MAX_SIZE;j++){
vEdge[i][j]=hEdge[i][j]=0;
}
}
//读入每一个墙的信息
for(i=0;i<M;i++){
cin>>x>>y>>d>>t;
if(d==0){
for(j=0;j<t;j++){
vEdge[x+j][y]=INF;
}
if(xmax<x+t){
xmax=x+t;
}
if(ymax<y){
ymax=y;
}
}
else{
for(j=0;j<t;j++){
hEdge[x][y+j]=INF;
}
if(xmax<x){
xmax=x;
}
if(ymax<y+t){
ymax=y+t;
}
}
}
//读入每一个门的信息
for(i=0;i<N;i++){
cin>>x>>y>>d;
if(d==0){
hEdge[x][j]=1;
}
else{
vEdge[x][y]=1;
}
}
cin>>f1>>f2;
//求解并输出结果.
if(f1>xmax||f2>ymax){
cout<<'0'<<endl;
}
else{
xd=(int)f1;
yd=(int)f2;
cout<<Bfs()<<endl;
}
}
return 0;
}
inline void InitPriorityQueue()
{
PriorityQueueSize=0;
}
inline const PriorityQueueNode& PeekPriorityQueue()
{
return priorityQueue[0];
}
inline bool IsEmptyPriorityQueue()
{
if(PriorityQueueSize>0){
return false;
}
return true;
}
void DeletePriorityQueue()
{
PriorityQueueNode t=priorityQueue[PriorityQueueSize-1];
PriorityQueueSize--;
int par=0,chi=1;
while(chi<PriorityQueueSize)
{
if(chi+1<PriorityQueueSize&&priorityQueue[chi+1].p<priorityQueue[chi].p){
chi++;
}
if(priorityQueue[chi].p<t.p){
priorityQueue[par]=priorityQueue[chi];
par=chi;
chi=2*par+1;
}
else{
break;
}
}
priorityQueue[par]=t;
}
void EnterPriorityQueue(const PriorityQueueNode& pqn)
{
PriorityQueueSize++;
int chi=PriorityQueueSize-1, par=(chi-1)/2;//下标从0开始
while(chi>0&&pqn.p<priorityQueue[par].p){
priorityQueue[chi]=priorityQueue[par];
chi=par;
par=(chi-1)/2;
}
priorityQueue[chi]=pqn;
}
int Bfs()
{
PriorityQueueNode pqn;
int i,j;
for(i=0;i<=xmax;i++){
for(j=0;j<=ymax;j++){
dist[i][j]=INF;
}
}
dist[0][0]=0;
InitPriorityQueue();
pqn.x=0;
pqn.y=0;
pqn.p=0;
EnterPriorityQueue(pqn);
while(!IsEmptyPriorityQueue()){
pqn=PeekPriorityQueue();
DeletePriorityQueue();
int x=pqn.x, y=pqn.y;
//广度优先遍历到目标顶点.
if(x==xd&&y==yd){
return dist[x][y];
}
//检查网格(x,y)上方网格对应图G的顶点.
if(y+1<=ymax&&dist[x][y+1]>dist[x][y]+vEdge[x][y+1]){
dist[x][y+1]=dist[x][y]+vEdge[x][y+1];
pqn.x=x;
pqn.y=y+1;
pqn.p=dist[x][y+1];
EnterPriorityQueue(pqn);
}
//检查网格(x,y)右方网格对应图G的顶点.
if(x+1<=xmax&&dist[x+1][y]>dist[x][y]+hEdge[x+1][y]){
dist[x+1][y]=dist[x][y]+hEdge[x+1][y];
pqn.x=x+1;
pqn.y=y;
pqn.p=dist[x+1][y];
EnterPriorityQueue(pqn);
}
//检查网格(x,y)下方网格对应图G的顶点.
if(y-1>=0&&dist[x][y-1]>dist[x][y]+vEdge[x][y]){
dist[x][y-1]=dist[x][y]+vEdge[x][y-1];
pqn.x=x;
pqn.y=y-1;
pqn.p=dist[x][y-1];
EnterPriorityQueue(pqn);
}
//检查网格(x,y)左方网格对应图G的顶点.
if(x-1>=0&&dist[x-1][y]>dist[x][y]+hEdge[x][y]){
dist[x-1][y]=dist[x][y]+hEdge[x][y];
pqn.x=x-1;
pqn.y=y;
pqn.p=dist[x-1][y];
EnterPriorityQueue(pqn);
}
}
return -1;
}