#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cassert>
#include <cstdio>
#include <vector>
#include <cmath>
#include <ctime>
#include <set>
#include <map>

typedef long long ll;

using namespace std;
int x,y,X,Y,n;
ll p=1000000007ll;
map<ll,int> d;
vector<ll> g;
vector<ll>::iterator it;
map<ll,int>::iterator It;
void dfs(ll a,ll b,int l){
	ll i=a*p+b;
	bool ok=0;
	it=lower_bound(g.begin(),g.end(),i);
	if(*it==i){
		if(d.count(i)){
			It=d.lower_bound(i);
			if(d[i]>l)
				d[i]=l++,ok=1;
		}
		else
			d[a*p+b]=l++,ok=1;
		if(ok){
			dfs(a-1, b, l);
			dfs(a-1, b-1, l);
			dfs(a-1, b+1, l);
			dfs(a+1, b, l);
			dfs(a+1, b-1, l);
			dfs(a+1, b+1, l);
			dfs(a, b-1, l);
			dfs(a, b+1, l);
		}
	}
}
int main()
{
	scanf("%d %d %d %d\n",&x, &y, &X, &Y);
	scanf("%d\n",&n);
	vector< pair <int, pair<int,int> > > w(n);
	for(int i=0; i<n; i++){
		scanf("%d %d %d\n",&w[i].first, &w[i].second.first, &w[i].second.second);
	}
	sort(w.begin(), w.end());
	for(int i=0; i<n; i++)
	if(!i||(w[i].first!=w[i-1].first)){
		for(int j=w[i].second.first; j<=w[i].second.second; j++)
			g.push_back(w[i].first*1ll*p+j);
	}
	else{
		for(int j=max(w[i].second.first,w[i-1].second.second); j<=w[i].second.second; j++)
			g.push_back(w[i].first*1ll*p+j);

	}
//	sort(g.begin(),g.end());
	dfs(X,Y,0);
	if(d.count(x*1ll*p+y))
		cout<<d[x*1ll*p+y];
	else
		cout<<"-1";

	return 0;
}


#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cassert>
#include <cstdio>
#include <vector>
#include <cmath>
#include <ctime>
#include <set>
#include <map>

typedef long long ll;

using namespace std;
int x,y,X,Y,n;
ll p=1000000007ll;
map<ll,int> d;
vector<ll> g;
vector<ll>::iterator it;
map<ll,int>::iterator It;
void dfs(ll a,ll b,int l){
	ll i=a*p+b;
	bool ok=0;
	it=lower_bound(g.begin(),g.end(),i);
	if(*it==i){
		if(d.count(i)){
			It=d.lower_bound(i);
			if(d[i]>l)
				d[i]=l++,ok=1;
		}
		else
			d[a*p+b]=l++,ok=1;
		if(ok){
			dfs(a-1, b, l);
			dfs(a-1, b-1, l);
			dfs(a-1, b+1, l);
			dfs(a+1, b, l);
			dfs(a+1, b-1, l);
			dfs(a+1, b+1, l);
			dfs(a, b-1, l);
			dfs(a, b+1, l);
		}
	}
}
int main()
{
	scanf("%d %d %d %d\n",&x, &y, &X, &Y);
	scanf("%d\n",&n);
	vector< pair <int, pair<int,int> > > w(n+10);
	for(int i=0; i<n; i++){
		scanf("%d %d %d\n",&w[i].first, &w[i].second.first, &w[i].second.second);
	}
	w.resize(n);
	sort(w.begin(), w.end());
	for(int i=0; i<n; i++)
	if(!i||(w[i].first!=w[i-1].first))	{
		for(int j=w[i].second.first; j<=w[i].second.second; j++)
			g.push_back(w[i].first*1ll*p+j);
	}
	else{
		for(int j=max(w[i].second.first,w[i-1].second.second+1); j<=w[i].second.second; j++)
			g.push_back(w[i].first*1ll*p+j);

	}
//	sort(g.begin(),g.end());
	dfs(X,Y,0);
	if(d.count(x*1ll*p+y))
		cout<<d[x*1ll*p+y];
	else
		cout<<"-1";

	return 0;
}


#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cassert>
#include <cstdio>
#include <vector>
#include <cmath>
#include <ctime>
#include <set>
#include <map>

typedef long long ll;

using namespace std;
int x,y,X,Y,n;
ll p=1000000007ll;
map<ll,int> d;
vector<ll> g;
vector<ll>::iterator it;
map<ll,int>::iterator It;
void dfs(ll a,ll b,int l){
	ll i=a*p+b;
	bool ok=0;
	it=lower_bound(g.begin(),g.end(),i);
	if(*it==i){
		if(d.count(i)){
			It=d.lower_bound(i);
			if(d[i]>l)
				d[i]=l++,ok=1;
		}
		else
			d[a*p+b]=l++,ok=1;
		if(ok){
			dfs(a-1, b, l);
			dfs(a-1, b-1, l);
			dfs(a-1, b+1, l);
			dfs(a+1, b, l);
			dfs(a+1, b-1, l);
			dfs(a+1, b+1, l);
			dfs(a, b-1, l);
			dfs(a, b+1, l);
		}
	}
}
int main()
{
	scanf("%d %d %d %d\n",&x, &y, &X, &Y);
	scanf("%d\n",&n);
	vector< pair <int, pair<int,int> > > w(n);
	for(int i=0; i<n; i++){
		scanf("%d %d %d\n",&w[i].first, &w[i].second.first, &w[i].second.second);
	}
	sort(w.begin(), w.end());
	for(int i=0; i<n; i++)
	if(!i||(w[i].first!=w[i-1].first))	{
		for(int j=w[i].second.first; j<=w[i].second.second; j++)
			g.push_back(w[i].first*1ll*p+j);
	}
	else{
		for(int j=max(w[i].second.first,w[i-1].second.second+1); j<=w[i].second.second; j++)
			g.push_back(w[i].first*1ll*p+j);

	}
//	sort(g.begin(),g.end());
	dfs(X,Y,0);
	if(d.count(x*1ll*p+y))
		cout<<d[x*1ll*p+y];
	else
		cout<<"-1";

	return 0;
}


#include<cstdio>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<memory.h>
#define N 111111
#define F first
#define S second
using namespace std;
int n,i,r[N],a[N],b[N],ans[N];
int f1[8] = {+0,+0,-1,+1,+1,+1,-1,-1};
int f2[8] = {-1,+1,+0,+0,+1,-1,+1,-1};
pair < int , int > f[N];
int x0,y0,x1,y1;
vector<int>v[N],q[N];

void sortA(int ll, int rr){
 int l1 = ll,r1 = rr,k = r[(rr+ll)/2];
  do{
   while(k > r[l1])l1++;
   while(k < r[r1])r1--;
    if(l1<=r1){
     swap(r[l1],r[r1]);
     swap(a[l1],a[r1]);
     swap(b[l1],b[r1]);
     ++l1;
     --r1;
    }
  }while(l1 <= r1);
 if(l1 < rr)sortA(l1,rr);
 if(ll < r1)sortA(ll,r1);
}

int go(int x){
if ( x == 0 )return 1;
int ll = 1,rr = n;
 while(rr-ll>1){
  int k = (ll+rr)/2;
  if( r[k] > x )rr = k;
  else ll = k;
 }
if(r[rr] == x)ll=rr;
while(r[ll-1]==x)ll--;
return ll;
}

int key(int x){
return x / 100000 + x % 100000;
}

bool search(int x , int y){
int z = key(x + y);
for(int t=0;t<v[z].size();t++)if(v[z][t] == y && q[z][t] == x)
 return false;
int low = go(x);
 while(r[low] == x){
  if(a[low]<= y && b[low]>=y){
   v[z].push_back(y);
   q[z].push_back(x);
   return true;
  }
  ++low;
 }
return false;
}

main(){
//freopen("input.txt","r",stdin);
 //freopen("output.txt","w",stdout);
scanf("%d%d%d%d",&x0,&y0,&x1,&y1);
scanf("%d",&n);
 for(i=1;i<=n;i++){
  scanf("%d%d%d",&r[i],&a[i],&b[i]);
 }
sortA(1,n);
int begin = 0,end = 1;
f[1].F = x0;f[1].S = y0;
 while( begin < end ){
  begin++;
  int mark1 = f[begin].F , mark2 = f[begin].S;
   if(mark1 == x1 && mark2 == y1){
    printf("%d\n",ans[begin]);
    return 0;
   }
   for(int j=0;j<8;j++)
    if(search(mark1+f1[j],mark2+f2[j])){
     end++;
     f[end].F = mark1+f1[j];
     f[end].S = mark2+f2[j];
     ans[end] = ans[begin] + 1;
    }
 }
puts("-1");
}


#include<cstdio>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<memory.h>
#define N 110000
#define F first
#define S second
using namespace std;
int n,i,r[N],a[N],b[N],ans[N];
int f1[8] = {+0,+0,-1,+1,+1,+1,-1,-1};
int f2[8] = {-1,+1,+0,+0,+1,-1,+1,-1};
pair < int , int > f[N];
int x0,y0,x1,y1;
vector< pair < int , int > > v[N];

void sortA(int ll, int rr){
 int l1 = ll,r1 = rr,k = r[(rr+ll)/2];
  do{
   while(k > r[l1])l1++;
   while(k < r[r1])r1--;
    if(l1<=r1){
     swap(r[l1],r[r1]);
     swap(a[l1],a[r1]);
     swap(b[l1],b[r1]);
     ++l1;
     --r1;
    }
  }while(l1 <= r1);
 if(l1 < rr)sortA(l1,rr);
 if(ll < r1)sortA(ll,r1);
}

int key(int x){
return  x / 100000 + x % 100000;
}

int go(int x){
int ll = 1,rr = n;
 while(rr-ll>1){
  int k = (ll+rr)/2;
  if( r[k] > x )rr = k;
  else ll = k;
 }
if(r[rr] == x)ll=rr;
while(r[ll-1]==x)ll--;
return ll;
}

bool search(int x , int y){
int z = key(x);
for(int t=0;t<v[z].size();t++)if(v[z][t].F == x && v[z][t].S == y)return false;
int low = go(x);//int(lower_bound( r + 1 , r + n + 1 , x));
 while(r[low] == x){
  if(a[low]<= y && b[low]>=y){
   v[key(x)].push_back(make_pair(x,y));
   return true;
  }
  ++low;
 }
return false;
}

 main(){
//freopen("input.txt","r",stdin);
 //freopen("output.txt","w",stdout);
scanf("%d%d%d%d",&x0,&y0,&x1,&y1);
scanf("%d",&n);
 for(i=1;i<=n;i++){
  scanf("%d%d%d",&r[i],&a[i],&b[i]);
 }
sortA(1,n);
int begin = 0,end = 1;
f[1].F = x0;f[1].S = y0;
 while( begin < end ){
  begin++;
  int mark1 = f[begin].F , mark2 = f[begin].S;
   if(mark1 == x1 && mark2 == y1){
    printf("%d\n",ans[begin]);
    return 0;
   }
   for(int j=0;j<8;j++)
    if(search(mark1+f1[j],mark2+f2[j])){
     end++;
     f[end].F = mark1+f1[j];
     f[end].S = mark2+f2[j];
     ans[end] = ans[begin] + 1;
    }
 }
puts("-1");
}


#include<cstdio>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<memory.h>
#define N 1111111
#define F first
#define S second
using namespace std;
int n,i,r[N],a[N],b[N],ans[N];
int f1[8] = {+0,+0,-1,+1,+1,+1,-1,-1};
int f2[8] = {-1,+1,+0,+0,+1,-1,+1,-1};
pair < int , int > f[N];
int x0,y0,x1,y1;
vector<int>v[N],q[N];

void sortA(int ll, int rr){
 int l1 = ll,r1 = rr,k = r[(rr+ll)/2];
  do{
   while(k > r[l1])l1++;
   while(k < r[r1])r1--;
    if(l1<=r1){
     swap(r[l1],r[r1]);
     swap(a[l1],a[r1]);
     swap(b[l1],b[r1]);
     ++l1;
     --r1;
    }
  }while(l1 <= r1);
 if(l1 < rr)sortA(l1,rr);
 if(ll < r1)sortA(ll,r1);
}

int go(int x){
int ll = 1,rr = n;
 while(rr-ll>1){
  int k = (ll+rr)/2;
  if( r[k] > x )rr = k;
  else ll = k;
 }
if(r[rr] == x)ll=rr;
while(r[ll-1]==x)ll--;
return ll;
}

int key(int x){
return x / 100000 + x % 100000;
}

bool search(int x , int y){
int z = key(x);
for(int t=0;t<v[z].size();t++)if(v[z][t] == y && q[z][t] == x)return false;
int low = go(x);//int(lower_bound( r + 1 , r + n + 1 , x));
 while(r[low] == x){
  if(a[low]<= y && b[low]>=y){
   v[z].push_back(y);
   q[z].push_back(x);
   return true;
  }
  ++low;
 }
return false;
}

 main(){
//freopen("input.txt","r",stdin);
 //freopen("output.txt","w",stdout);
scanf("%d%d%d%d",&x0,&y0,&x1,&y1);
scanf("%d",&n);
 for(i=1;i<=n;i++){
  scanf("%d%d%d",&r[i],&a[i],&b[i]);
 }
sortA(1,n);
int begin = 0,end = 1;
f[1].F = x0;f[1].S = y0;
 while( begin < end ){
  begin++;
  int mark1 = f[begin].F , mark2 = f[begin].S;
   if(mark1 == x1 && mark2 == y1){
    printf("%d\n",ans[begin]);
    return 0;
   }
   for(int j=0;j<8;j++)
    if(search(mark1+f1[j],mark2+f2[j])){
     end++;
     f[end].F = mark1+f1[j];
     f[end].S = mark2+f2[j];
     ans[end] = ans[begin] + 1;
    }
 }
puts("-1");
}


#include<cstdio>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<memory.h>
#define N 111111
#define M 100011
#define F first
#define S second
using namespace std;
int n,i,r[M],a[M],b[M],ans[M];
int f1[8] = {+0,+0,-1,+1,+1,+1,-1,-1};
int f2[8] = {-1,+1,+0,+0,+1,-1,+1,-1};
pair < int , int > f[M];
int x0,y0,x1,y1;
vector<int>v[N],q[N];

void sortA(int ll, int rr){
 int l1 = ll,r1 = rr,k = r[(rr+ll)/2];
  do{
   while(k > r[l1])l1++;
   while(k < r[r1])r1--;
    if(l1<=r1){
     swap(r[l1],r[r1]);
     swap(a[l1],a[r1]);
     swap(b[l1],b[r1]);
     ++l1;
     --r1;
    }
  }while(l1 <= r1);
 if(l1 < rr)sortA(l1,rr);
 if(ll < r1)sortA(ll,r1);
}

int go(int x){
if ( x == 0 )return 1;
int ll = 1,rr = n;
 while(rr-ll>1){
  int k = (ll+rr)/2;
  if( r[k] > x )rr = k;
  else ll = k;
 }
if(r[rr] == x)ll=rr;
while(r[ll-1]==x)ll--;
return ll;
}

int key(long long x){
return x / 100000 + x % 100000;
}

bool search(int x , int y){
int z = key(x + y);
for(int t=0;t<v[z].size();t++)if(v[z][t] == y && q[z][t] == x)
 return false;
int low = go(x);
 while(r[low] == x){
  if(a[low]<= y && b[low]>=y){
   v[z].push_back(y);
   q[z].push_back(x);
   return true;
  }
  ++low;
 }
return false;
}

main(){
//freopen("input.txt","r",stdin);
 //freopen("output.txt","w",stdout);
scanf("%d%d%d%d",&x0,&y0,&x1,&y1);
scanf("%d",&n);
 for(i=1;i<=n;i++){
  scanf("%d%d%d",&r[i],&a[i],&b[i]);
 }
sortA(1,n);
int begin = 0,end = 1;
f[1].F = x0;f[1].S = y0;
 while( begin < end ){
  begin++;
  int mark1 = f[begin].F , mark2 = f[begin].S;
   if(mark1 == x1 && mark2 == y1){
    printf("%d\n",ans[begin]);
    return 0;
   }
   for(int j=0;j<8;j++)
    if(search(mark1+f1[j],mark2+f2[j])){
     end++;
     f[end].F = mark1+f1[j];
     f[end].S = mark2+f2[j];
     ans[end] = ans[begin] + 1;
    }
 }
puts("-1");
}


#include<cstdio>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<memory.h>
#define N 999998
#define F first
#define S second
using namespace std;
int n,i,r[N],a[N],b[N],ans[N];
int f1[8] = {+0,+0,-1,+1,+1,+1,-1,-1};
int f2[8] = {-1,+1,+0,+0,+1,-1,+1,-1};
pair < int , int > f[N];
int x0,y0,x1,y1;
vector<int>v[N];

void sortA(int ll, int rr){
 int l1 = ll,r1 = rr,k = r[(rr+ll)/2];
  do{
   while(k > r[l1])l1++;
   while(k < r[r1])r1--;
    if(l1<=r1){
     swap(r[l1],r[r1]);
     swap(a[l1],a[r1]);
     swap(b[l1],b[r1]);
     ++l1;
     --r1;
    }
  }while(l1 <= r1);
 if(l1 < rr)sortA(l1,rr);
 if(ll < r1)sortA(ll,r1);
}

int go(int x){
int ll = 1,rr = n;
 while(rr-ll>1){
  int k = (ll+rr)/2;
  if( r[k] > x )rr = k;
  else ll = k;
 }
if(r[rr] == x)ll=rr;
while(r[ll-1]==x)ll--;
return ll;
}

main(){
//freopen("input.txt","r",stdin);
 //freopen("output.txt","w",stdout);
scanf("%d%d%d%d",&x0,&y0,&x1,&y1);
scanf("%d",&n);
 for(i=1;i<=n;i++){
  scanf("%d%d%d",&r[i],&a[i],&b[i]);
 }
sortA(1,n);
int begin_ = 0,end_ = 1;
f[1].F = x0;f[1].S = y0;
 while( begin_ < end_ ){
  begin_++;
  int mark1 = f[begin_].F , mark2 = f[begin_].S;
   if(mark1 == x1 && mark2 == y1){
    printf("%d\n",ans[begin_]);
    return 0;
   }
   for(int j=0;j<8;j++){
    int back=0;
    int x = mark1+f1[j], y = mark2+f2[j];
    for(int t=0;t<v[x].size();t++)if(v[x][t] == y)back = -1;
     if (back == 0){
      int low = go(x);
      while(r[low] == x){
       if(a[low]<= y && b[low]>=y){
        v[x].push_back(y);
        back = 1 ;
       }
       ++low;
      }
     if(back == 1){
     end_++;
     f[end_].F = mark1+f1[j];
     f[end_].S = mark2+f2[j];
     ans[end_] = ans[begin_] + 1;
    }
   }
  }
 }
puts("-1");
}


#include<cstdio>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<memory.h>
#define N 1111111
#define F first
#define S second
using namespace std;
int n,i,r[N],a[N],b[N],ans[N];
int f1[8] = {+0,+0,-1,+1,+1,+1,-1,-1};
int f2[8] = {-1,+1,+0,+0,+1,-1,+1,-1};
pair < int , int > f[N];
int x0,y0,x1,y1;
vector<int>v[N];

void sortA(int ll, int rr){
 int l1 = ll,r1 = rr,k = r[(rr+ll)/2];
  do{
   while(k > r[l1])l1++;
   while(k < r[r1])r1--;
    if(l1<=r1){
     swap(r[l1],r[r1]);
     swap(a[l1],a[r1]);
     swap(b[l1],b[r1]);
     ++l1;
     --r1;
    }
  }while(l1 <= r1);
 if(l1 < rr)sortA(l1,rr);
 if(ll < r1)sortA(ll,r1);
}

int go(int x){
int ll = 1,rr = n;
 while(rr-ll>1){
  int k = (ll+rr)/2;
  if( r[k] > x )rr = k;
  else ll = k;
 }
if(r[rr] == x)ll=rr;
while(r[ll-1]==x)ll--;
return ll;
}

bool search(int x , int y){
for(int t=0;t<v[x].size();t++)if(v[x][t] == y)return false;
int low = go(x);//int(lower_bound( r + 1 , r + n + 1 , x));
 while(r[low] == x){
  if(a[low]<= y && b[low]>=y){
   v[x].push_back(y);
   return true;
  }
  ++low;
 }
return false;
}

 main(){
//freopen("input.txt","r",stdin);
 //freopen("output.txt","w",stdout);
scanf("%d%d%d%d",&x0,&y0,&x1,&y1);
scanf("%d",&n);
 for(i=1;i<=n;i++){
  scanf("%d%d%d",&r[i],&a[i],&b[i]);
 }
sortA(1,n);
int begin = 0,end = 1;
f[1].F = x0;f[1].S = y0;
 while( begin < end ){
  begin++;
  int mark1 = f[begin].F , mark2 = f[begin].S;
   if(mark1 == x1 && mark2 == y1){
    printf("%d\n",ans[begin]);
    return 0;
   }
   for(int j=0;j<8;j++)
    if(search(mark1+f1[j],mark2+f2[j])){
     end++;
     f[end].F = mark1+f1[j];
     f[end].S = mark2+f2[j];
     ans[end] = ans[begin] + 1;
    }
 }
puts("-1");
}


#include<cstdio>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<memory.h>
#define N 110000
#define F first
#define S second
using namespace std;
int n,i,r[N],a[N],b[N],ans[N];
int f1[8] = {+0,+0,-1,+1,+1,+1,-1,-1};
int f2[8] = {-1,+1,+0,+0,+1,-1,+1,-1};
pair < int , int > f[N];
int x0,y0,x1,y1;
vector<int>v[N];

void sortA(int ll, int rr){
 int l1 = ll,r1 = rr,k = r[(rr+ll)/2];
  do{
   while(k > r[l1])l1++;
   while(k < r[r1])r1--;
    if(l1<=r1){
     swap(r[l1],r[r1]);
     swap(a[l1],a[r1]);
     swap(b[l1],b[r1]);
     ++l1;
     --r1;
    }
  }while(l1 <= r1);
 if(l1 < rr)sortA(l1,rr);
 if(ll < r1)sortA(ll,r1);
}

int go(int x){
int ll = 1,rr = n;
 while(rr-ll>1){
  int k = (ll+rr)/2;
  if( r[k] > x )rr = k;
  else ll = k;
 }
if(r[rr] == x)ll=rr;
while(r[ll-1]==x)ll--;
return ll;
}

bool search(int x , int y){
for(int t=0;t<v[x].size();t++)if(v[x][t] == y)return false;
int low = go(x);//int(lower_bound( r + 1 , r + n + 1 , x));
 while(r[low] == x){
  if(a[low]<= y && b[low]>=y){
   v[x].push_back(y);
   return true;
  }
  ++low;
 }
return false;
}

 main(){
//freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
scanf("%d%d%d%d",&x0,&y0,&x1,&y1);
scanf("%d",&n);
 for(i=1;i<=n;i++){
  scanf("%d%d%d",&r[i],&a[i],&b[i]);
 }
sortA(1,n);
int begin = 0,end = 1;
f[1].F = x0;f[1].S = y0;
 while( begin < end ){
  begin++;
  int mark1 = f[begin].F , mark2 = f[begin].S;
   if(mark1 == x1 && mark2 == y1){
    printf("%d\n",ans[begin]);
    return 0;
   }
   for(int j=1;j<9;j++)
    if(search(mark1+f1[j],mark2+f2[j])){
     end++;
     f[end].F = mark1+f1[j];
     f[end].S = mark2+f2[j];
     ans[end] = ans[begin] + 1;
    }
 }
puts("-1");
}


#include<cstdio>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<memory.h>
#define N 110000
#define F first
#define S second
using namespace std;
int n,i,r[N],a[N],b[N],ans[N];
int f1[8] = {+0,+0,-1,+1,+1,+1,-1,-1};
int f2[8] = {-1,+1,+0,+0,+1,-1,+1,-1};
pair < int , int > f[N];
int x0,y0,x1,y1;
vector<int>v[N];

void sortA(int ll, int rr){
 int l1 = ll,r1 = rr,k = r[(rr+ll)/2];
  do{
   while(k > r[l1])l1++;
   while(k < r[r1])r1--;
    if(l1<=r1){
     swap(r[l1],r[r1]);
     swap(a[l1],a[r1]);
     swap(b[l1],b[r1]);
     ++l1;
     --r1;
    }
  }while(l1 < r1);
 if(l1 < rr)sortA(l1,rr);
 if(ll < r1)sortA(ll,r1);
}

int go(int x){
int ll = 1,rr = n;
 while(rr-ll>1){
  int k = (ll+rr)/2;
  if( r[k] > x )rr = k;
  else ll = k;
 }
if(r[rr] == x)ll=rr;
while(r[ll-1]==x)ll--;
return ll;
}

bool search(int x , int y){
for(int t=0;t<v[x].size();t++)if(v[x][t] == y)return false;
int low = go(x);//int(lower_bound( r + 1 , r + n + 1 , x));
 while(r[low] == x){
  if(a[low]<= y && b[low]>=y){
   v[x].push_back(y);
   return true;
  }
  ++low;
 }
return false;
}

 main(){
freopen("input.txt","r",stdin);
 freopen("output.txt","w",stdout);
scanf("%d%d%d%d",&x0,&y0,&x1,&y1);
scanf("%d",&n);
 for(i=1;i<=n;i++){
  scanf("%d%d%d",&r[i],&a[i],&b[i]);
 }
sortA(1,n);
int begin = 0,end = 1;
f[1].F = x0;f[1].S = y0;
 while( begin < end ){
  begin++;
  int mark1 = f[begin].F , mark2 = f[begin].S;
   if(mark1 == x1 && mark2 == y1){
    printf("%d\n",ans[begin]);
    return 0;
   }
   for(int j=1;j<9;j++)
    if(search(mark1+f1[j],mark2+f2[j])){
     end++;
     f[end].F = mark1+f1[j];
     f[end].S = mark2+f2[j];
     ans[end] = ans[begin] + 1;
    }
 }
puts("-1");
}


#include<cstdio>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<memory.h>
#define N 110000
#define F first
#define S second
using namespace std;
int n,i,r[N],a[N],b[N],ans[N];
int f1[8] = {+0,+0,-1,+1,+1,+1,-1,-1};
int f2[8] = {-1,+1,+0,+0,+1,-1,+1,-1};
pair < int , int > f[N];
int x0,y0,x1,y1;
vector<int>v[N];

void sortA(int ll, int rr){
 int l1 = ll,r1 = rr,k = r[(rr+ll)/2];
  do{
   while(k > r[l1])l1++;
   while(k < r[r1])r1--;
    if(l1<=r1){
     swap(r[l1],r[r1]);
     swap(a[l1],a[r1]);
     swap(b[l1],b[r1]);
     ++l1;
     --r1;
    }
  }while(l1 < r1);
 if(l1 < rr)sortA(l1,rr);
 if(ll < r1)sortA(ll,r1);
}

int go(int x){
int ll = 1,rr = n;
 while(rr-ll>1){
  int k = (ll+rr)/2;
  if( r[k] > x )rr = k;
  else ll = k;
 }
if(r[rr] == x)ll=rr;
while(r[ll-1]==x)ll--;
return ll;
}

bool search(int x , int y){
for(int t=0;t<v[x].size();t++)if(v[x][t] == y)return false;
int low = go(x);//int(lower_bound( r + 1 , r + n + 1 , x));
 while(r[low] == x){
  if(a[low]<= y && b[low]>=y){
   v[x].push_back(y);
   return true;
  }
  ++low;
 }
return false;
}

 main(){
//freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
scanf("%d%d%d%d",&x0,&y0,&x1,&y1);
scanf("%d",&n);
 for(i=1;i<=n;i++){
  scanf("%d%d%d",&r[i],&a[i],&b[i]);
 }
sortA(1,n);
int begin = 0,end = 1;
f[1].F = x0;f[1].S = y0;
 while( begin < end ){
  begin++;
  int mark1 = f[begin].F , mark2 = f[begin].S;
   if(mark1 == x1 && mark2 == y1){
    printf("%d\n",ans[begin]);
    return 0;
   }
   for(int j=1;j<9;j++)
    if(search(mark1+f1[j],mark2+f2[j])){
     end++;
     f[end].F = mark1+f1[j];
     f[end].S = mark2+f2[j];
     ans[end] = ans[begin] + 1;
    }
 }
puts("-1");
}


#include<cstdio>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<memory.h>
#define N 1111111
#define F first
#define S second
using namespace std;
int n,i,r[N],a[N],b[N],ans[N];
int f1[8] = {+0,+0,-1,+1,+1,+1,-1,-1};
int f2[8] = {-1,+1,+0,+0,+1,-1,+1,-1};
pair < int , int > f[N];
int x0,y0,x1,y1;
vector < pair < int , int > > v[N];

void sortA(int ll, int rr){
 int l1 = ll,r1 = rr,k = r[(rr+ll)/2];
  do{
   while(k > r[l1])l1++;
   while(k < r[r1])r1--;
    if(l1<=r1){
     swap(r[l1],r[r1]);
     swap(a[l1],a[r1]);
     swap(b[l1],b[r1]);
     ++l1;
     --r1;
    }
  }while(l1 <= r1);
 if(l1 < rr)sortA(l1,rr);
 if(ll < r1)sortA(ll,r1);
}

int go(int x){
int ll = 1,rr = n;
 while(rr-ll>1){
  int k = (ll+rr)/2;
  if( r[k] > x )rr = k;
  else ll = k;
 }
if(r[rr] == x)ll=rr;
while(r[ll-1]==x)ll--;
return ll;
}

int key(int x){
return x / 100000 + x % 100000;
}

bool search(int x , int y){
int z = key(x);
for(int t=0;t<v[z].size();t++)if(v[z][t].S == y && v[z][t].F == x)return false;
int low = go(x);//int(lower_bound( r + 1 , r + n + 1 , x));
 while(r[low] == x){
  if(a[low]<= y && b[low]>=y){
   v[z].push_back(make_pair(x,y));
   return true;
  }
  ++low;
 }
return false;
}

 main(){
//freopen("input.txt","r",stdin);
 //freopen("output.txt","w",stdout);
scanf("%d%d%d%d",&x0,&y0,&x1,&y1);
scanf("%d",&n);
 for(i=1;i<=n;i++){
  scanf("%d%d%d",&r[i],&a[i],&b[i]);
 }
sortA(1,n);
int begin = 0,end = 1;
f[1].F = x0;f[1].S = y0;
 while( begin < end ){
  begin++;
  int mark1 = f[begin].F , mark2 = f[begin].S;
   if(mark1 == x1 && mark2 == y1){
    printf("%d\n",ans[begin]);
    return 0;
   }
   for(int j=0;j<8;j++)
    if(search(mark1+f1[j],mark2+f2[j])){
     end++;
     f[end].F = mark1+f1[j];
     f[end].S = mark2+f2[j];
     ans[end] = ans[begin] + 1;
    }
 }
puts("-1");
}


#include<cstdio>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<memory.h>
#define N 110000
#define F first
#define S second
using namespace std;
int n,i,r[N],a[N],b[N],ans[N];
int f1[8] = {+0,+0,-1,+1,+1,+1,-1,-1};
int f2[8] = {-1,+1,+0,+0,+1,-1,+1,-1};
pair < int , int > f[N];
int x0,y0,x1,y1;
vector<int>v[N];

void sortA(int ll, int rr){
 int l1 = ll,r1 = rr,k = r[(rr+ll)/2];
  do{
   while(k > r[l1])l1++;
   while(k < r[r1])r1--;
    if(l1<=r1){
     swap(r[l1],r[r1]);
     swap(a[l1],a[r1]);
     swap(b[l1],b[r1]);
     ++l1;
     --r1;
    }
  }while(l1 <= r1);
 if(l1 < rr)sortA(l1,rr);
 if(ll < r1)sortA(ll,r1);
}

int go(int x){
int ll = 1,rr = n;
 while(rr-ll>1){
  int k = (ll+rr)/2;
  if( r[k] > x )rr = k;
  else ll = k;
 }
if(r[rr] == x)ll=rr;
while(r[ll-1]==x)ll--;
return ll;
}

bool search(int x , int y){
for(int t=0;t<v[x].size();t++)if(v[x][t] == y)return false;
int low = go(x);//int(lower_bound( r + 1 , r + n + 1 , x));
 while(r[low] == x){
  if(a[low]<= y && b[low]>=y){
   v[x].push_back(y);
   return true;
  }
  ++low;
 }
return false;
}

 main(){
//freopen("input.txt","r",stdin);
 //freopen("output.txt","w",stdout);
scanf("%d%d%d%d",&x0,&y0,&x1,&y1);
scanf("%d",&n);
 for(i=1;i<=n;i++){
  scanf("%d%d%d",&r[i],&a[i],&b[i]);
 }
sortA(1,n);
int begin = 0,end = 1;
f[1].F = x0;f[1].S = y0;
 while( begin < end ){
  begin++;
  int mark1 = f[begin].F , mark2 = f[begin].S;
   if(mark1 == x1 && mark2 == y1){
    printf("%d\n",ans[begin]);
    return 0;
   }
   for(int j=0;j<8;j++)
    if(search(mark1+f1[j],mark2+f2[j])){
     end++;
     f[end].F = mark1+f1[j];
     f[end].S = mark2+f2[j];
     ans[end] = ans[begin] + 1;
    }
 }
puts("-1");
}


#include<cstdio>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<memory.h>
#define N 1111111
#define F first
#define S second
using namespace std;
int n,i,r[N],a[N],b[N],ans[N];
int f1[8] = {+0,+0,-1,+1,+1,+1,-1,-1};
int f2[8] = {-1,+1,+0,+0,+1,-1,+1,-1};
pair < int , int > f[N];
int x0,y0,x1,y1;
vector<int>v[N],q[N];

void sortA(int ll, int rr){
 int l1 = ll,r1 = rr,k = r[(rr+ll)/2];
  do{
   while(k > r[l1])l1++;
   while(k < r[r1])r1--;
    if(l1<=r1){
     swap(r[l1],r[r1]);
     swap(a[l1],a[r1]);
     swap(b[l1],b[r1]);
     ++l1;
     --r1;
    }
  }while(l1 <= r1);
 if(l1 < rr)sortA(l1,rr);
 if(ll < r1)sortA(ll,r1);
}

int go(int x){
if ( x == 0 )return 1;
int ll = 1,rr = n;
 while(rr-ll>1){
  int k = (ll+rr)/2;
  if( r[k] > x )rr = k;
  else ll = k;
 }
if(r[rr] == x)ll=rr;
while(r[ll-1]==x)ll--;
return ll;
}

int key(int x){
return x / 100000 + x % 100000;
}

bool search(int x , int y){
int z = key(x + y);
for(int t=0;t<v[z].size();t++)if(v[z][t] == y && q[z][t] == x)
 return false;
int low = go(x);
 while(r[low] == x){
  if(a[low]<= y && b[low]>=y){
   v[z].push_back(y);
   q[z].push_back(x);
   return true;
  }
  ++low;
 }
return false;
}

main(){
//freopen("input.txt","r",stdin);
 //freopen("output.txt","w",stdout);
scanf("%d%d%d%d",&x0,&y0,&x1,&y1);
scanf("%d",&n);
 for(i=1;i<=n;i++){
  scanf("%d%d%d",&r[i],&a[i],&b[i]);
 }
sortA(1,n);
int begin = 0,end = 1;
f[1].F = x0;f[1].S = y0;
 while( begin < end ){
  begin++;
  int mark1 = f[begin].F , mark2 = f[begin].S;
   if(mark1 == x1 && mark2 == y1){
    printf("%d\n",ans[begin]);
    return 0;
   }
   for(int j=0;j<8;j++)
    if(search(mark1+f1[j],mark2+f2[j])){
     end++;
     f[end].F = mark1+f1[j];
     f[end].S = mark2+f2[j];
     ans[end] = ans[begin] + 1;
    }
 }
puts("-1");
}


#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<queue>
#define mp make_pair
using namespace std ;
int dir[8][2] = { 0 , 1 , 1 , 1 , 1 , 0 , 1 , -1 , 0 , -1 , -1 , -1 , -1 , 0 , -1 , 1 } ;

struct Point
{
    int x , y , step ;
};
struct Line
{
    int l , r , row ;
} line[100005] ;

map<pair<int ,int>,int >m ;
pair<int,int>;
queue<Point>q ;
int n , x1 , y1 , x2 , y2 ;
int bfs ()
{
    Point e , u ;
    int i ;
    e.x = x1 ; e.y = y1 ; e.step = 0 ;
    q.push(e) ;
    m[mp(x1,y1)] = 2 ;
    while ( !q.empty () )
    {
        u = q.front() ;
        q.pop() ;
        for ( i = 0 ; i < 8 ; i ++ )
        {
            e.x = u.x + dir[i][0] ;
            e.y = u.y + dir[i][1] ;
            if ( e.x == x2 && e.y == y2 )
                return u.step + 1 ;
            if ( !m[mp(e.x,e.y)] || m[mp(e.x,e.y)] == 2 )
                continue ;
            e.step = u.step + 1 ;
            m[mp(e.x,e.y)] = 2 ;
            q.push(e) ;
        }
    }
    return -1 ;
}
int main ()
{
    int i , j ;
    scanf ( "%d%d%d%d" , &x1 , &y1 , &x2 , &y2 ) ;
    scanf ( "%d" , &n ) ;
    m.clear() ;
    for ( i = 1 ; i <= n ; i ++ )
    {
        scanf ( "%d%d%d" , &line[i].row , &line[i].l , &line[i].r ) ;
        for ( j = line[i].l ; j <= line[i].r ; j ++ )
            m[mp(line[i].row,j)] = 1 ;
    }
    printf ( "%d\n" , bfs() ) ;
}


#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#define mp make_pair
using namespace std ;
int dir[8][2] = { 0 , 1 , 1 , 1 , 1 , 0 , 1 , -1 , 0 , -1 , -1 , -1 , -1 , 0 , -1 , 1 } ;

struct Point
{
    int x , y , step ;
};
struct Line
{
    int l , r , row ;
} line[100005] ;

map<pair<int ,int>,int >m ;
pair<int,int>;
queue<Point>q ;
int n , x1 , y1 , x2 , y2 ;
int bfs ()
{
    Point e , u ;
    int i ;
    e.x = x1 ; e.y = y1 ; e.step = 0 ;
    q.push(e) ;
    m[mp(x1,y1)] = 2 ;
    while ( !q.empty () )
    {
        u = q.front() ;
        q.pop() ;
        for ( i = 0 ; i < 8 ; i ++ )
        {
            e.x = u.x + dir[i][0] ;
            e.y = u.y + dir[i][1] ;
            if ( e.x == x2 && e.y == y2 )
                return u.step + 1 ;
            if ( !m[mp(e.x,e.y)] || m[mp(e.x,e.y)] == 2 )
                continue ;
            e.step = u.step + 1 ;
            m[mp(e.x,e.y)] = 2 ;
            q.push(e) ;
        }
    }
    return -1 ;
}
int main ()
{
    int i , j ;
    scanf ( "%d%d%d%d" , &x1 , &y1 , &x2 , &y2 ) ;
    scanf ( "%d" , &n ) ;
    m.clear() ;
    for ( i = 1 ; i <= n ; i ++ )
    {
        scanf ( "%d%d%d" , &line[i].row , &line[i].l , &line[i].r ) ;
        for ( j = line[i].l ; j <= line[i].r ; j ++ )
            m[mp(line[i].row,j)] = 1 ;
    }
    printf ( "%d\n" , bfs() ) ;
}


#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<queue>
#define mp make_pair
using namespace std ;
int dir[8][2] = { 0 , 1 , 1 , 1 , 1 , 0 , 1 , -1 , 0 , -1 , -1 , -1 , -1 , 0 , -1 , 1 } ;

struct Point
{
	int x , y , step ;
};
struct Line
{
	int l , r , row ;
} line[100005] ;

pair < int , int > ;
map<pair<int , int>,int >m ;
queue<Point>q ;
int n , x1 , y1 , x2 , y2 ;
int bfs ()
{
	Point e , u ;
	int i ;
	e.x = x1 ; e.y = y1 ; e.step = 0 ;
	q.push(e) ;
	m[mp(x1,y1)] = 2 ;
	while ( !q.empty () )
	{
		u = q.front() ;
		q.pop() ;
		for ( i = 0 ; i < 8 ; i ++ )
		{
			e.x = u.x + dir[i][0] ;
			e.y = u.y + dir[i][1] ;
			if ( e.x == x2 && e.y == y2 )
				return u.step + 1 ;
			if ( !m[mp(e.x,e.y)] || m[mp(e.x,e.y)] == 2 )
				continue ;
			e.step = u.step + 1 ;
			m[mp(e.x,e.y)] = 2 ;
			q.push(e) ;
		}
	}
	return -1 ;
}
int main ()
{
	int i , j ;
	m.clear() ;
	scanf ( "%d%d%d%d" , &x1 , &y1 , &x2 , &y2 ) ;
	scanf ( "%d" , &n ) ;
	for ( i = 1 ; i <= n ; i ++ )
	{
		scanf ( "%d%d%d" , &line[i].row , &line[i].l , &line[i].r ) ;
		for ( j = line[i].l ; j <= line[i].r ; j ++ )
			m[mp(line[i].row,j)] = 1 ;
	}
	printf ( "%d\n" , bfs() ) ;
}


#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<queue>
#define mp make_pair
using namespace std ;
int dir[8][2] = { 0 , 1 , 1 , 1 , 1 , 0 , 1 , -1 , 0 , -1 , -1 , -1 , -1 , 0 , -1 , 1 } ;

struct Point
{
    int x , y , step ;
};
struct Line
{
    int l , r , row ;
} line[100005] ;

pair < int , int > ;
map<pair<int , int>,int >m ;
queue<Point>q ;
int n , x1 , y1 , x2 , y2 ;
int bfs ()
{
    Point e , u ;
    int i ;
    e.x = x1 ; e.y = y1 ; e.step = 0 ;
    q.push(e) ;
    m[mp(x1,y1)] = 2 ;
    while ( !q.empty () )
    {
        u = q.front() ;
        q.pop() ;
        for ( i = 0 ; i < 8 ; i ++ )
        {
            e.x = u.x + dir[i][0] ;
            e.y = u.y + dir[i][1] ;
            if ( e.x == x2 && e.y == y2 )
                return u.step + 1 ;
            if ( !m[mp(e.x,e.y)] || m[mp(e.x,e.y)] == 2 )
                continue ;
            e.step = u.step + 1 ;
            m[mp(e.x,e.y)] = 2 ;
            q.push(e) ;
        }
    }
    return -1 ;
}
int main ()
{
    int i , j ;
    scanf ( "%d%d%d%d" , &x1 , &y1 , &x2 , &y2 ) ;
    scanf ( "%d" , &n ) ;
    for ( i = 1 ; i <= n ; i ++ )
    {
        scanf ( "%d%d%d" , &line[i].row , &line[i].l , &line[i].r ) ;
        for ( j = line[i].l ; j <= line[i].r ; j ++ )
            m[mp(line[i].row,j)] = 1 ;
    }
    printf ( "%d\n" , bfs() ) ;
}


#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#define mp make_pair
using namespace std ;
int dir[8][2] = { 0 , 1 , 1 , 1 , 1 , 0 , 1 , -1 , 0 , -1 , -1 , -1 , -1 , 0 , -1 , 1 } ;

struct Point
{
    int x , y , step ;
};
struct Line
{
    int l , r , row ;
} line[100005] ;

map<pair<int ,int>,int >m ;
queue<Point>q ;
int n , x1 , y1 , x2 , y2 ;
int bfs ()
{
    Point e , u ;
    int i ;
    e.x = x1 ; e.y = y1 ; e.step = 0 ;
    q.push(e) ;
    m[mp(x1,y1)] = 2 ;
    while ( !q.empty () )
    {
        u = q.front() ;
        q.pop() ;
        for ( i = 0 ; i < 8 ; i ++ )
        {
            e.x = u.x + dir[i][0] ;
            e.y = u.y + dir[i][1] ;
            if ( e.x == x2 && e.y == y2 )
                return u.step + 1 ;
            if ( !m[mp(e.x,e.y)] || m[mp(e.x,e.y)] == 2 )
                continue ;
            e.step = u.step + 1 ;
            m[mp(e.x,e.y)] = 2 ;
            q.push(e) ;
        }
    }
    return -1 ;
}
int main ()
{
    int i , j ;
    scanf ( "%d%d%d%d" , &x1 , &y1 , &x2 , &y2 ) ;
    scanf ( "%d" , &n ) ;
    m.clear() ;
    for ( i = 1 ; i <= n ; i ++ )
    {
        scanf ( "%d%d%d" , &line[i].row , &line[i].l , &line[i].r ) ;
        for ( j = line[i].l ; j <= line[i].r ; j ++ )
            m[mp(line[i].row,j)] = 1 ;
    }
    printf ( "%d\n" , bfs() ) ;
}


#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#define MOD 99991
using namespace std;
struct node
{
	int x,y;
}S,T,now;
struct nodep
{
	int x,y,step;
}head,tail;
int n,tot;
int movex[]={1,1,1,0,0,-1,-1,-1};
int movey[]={1,0,-1,1,-1,1,0,-1};
queue<nodep>q;
vector<node>hash1[100000],hash2[100000];
void read()
{
	scanf("%d %d %d %d %d",&S.x,&S.y,&T.x,&T.y,&n);
	int row,left,right;
	for(int i=1;i<=n;i++)
	{
		scanf("%d %d %d",&row,&left,&right);
		for(int j=left;j<=right;j++)
			now.x=row,now.y=j,hash1[now.x%MOD*now.y%MOD].push_back(now);
	}
}
int bfs()
{
	head.x=S.x,head.y=S.y,head.step=0;
	q.push(head);
	int hash=head.x%MOD*head.y%MOD;
	hash2[hash].push_back(S);
	while(q.empty()==false)
	{
		head=q.front(),q.pop();
		for(int i=0,j;i<8;i++)
		{
			tail.x=head.x+movex[i],tail.y=head.y+movey[i],tail.step=head.step+1,hash=tail.x%MOD*tail.y%MOD;
			for(j=0;j<hash1[hash].size();j++)
				if(hash1[hash][j].x==tail.x&&hash1[hash][j].y==tail.y)
					break;
			if(j==hash1[hash].size())  continue;
			for(j=0;j<hash2[hash].size();j++)
				if(hash2[hash][j].x==tail.x&&hash2[hash][j].y==tail.y)
					break;
			if(j<hash2[hash].size())  continue;
			now.x=tail.x,now.y=tail.y,hash2[hash].push_back(now),q.push(tail);
			if(now.x==T.x&&now.y==T.y)  return tail.step;
		}
	}
	return -1;
}
int main()
{
	read();
	printf("%d\n",bfs());
	return 0;
}


#include<stdio.h>
#include<stdlib.h>
int a,b,c,d,e,h,i,j,l,r,xx,yy,end[1000005];
int ee;
int fx[9][2]={{-1,1},{0,1},{1,1},{1,0},{1,-1},{-1,0},{-1,-1},{0,-1}};
struct node
{
	int x,y,an;
};
struct node f[1000005];

struct node1
{
	int hang,q,z;
};
struct node1 g[1000005];
struct node1 ch;

struct node2
{
	int v,next;
};
struct node ff[1000005];

void set(int u,int v)
{
	ff[++ee].v=v;
	ff[ee].next=end[u];end[u]=ee;
}

int check(int x,int y)
{
	int ii,jj,kk;
	jj=end[x];
	while(jj)
	{
	 	ii=ff[jj].v;
		if(g[ii].hang==x && g[ii].q<=y && g[ii].z>=y)
		{
			ch=g[ii];
			g[ii].z=y-1;
			if(y+1<=ch.z)
			{
			        g[++e]=ch;
			        g[e].q=y+1;
			        set(g[e].hang,e);
			}
			return 1;
		}
		jj=ff[jj].next;
	}
	return 0;
}

int main()
{
	scanf("%d%d%d%d",&a,&b,&c,&d);
	scanf("%d",&e);
	for(i=1;i<=e;i++)
	{
		scanf("%d%d%d",&g[i].hang,&g[i].q,&g[i].z);
		set(g[i].hang,i);
	}
	f[1].x=a;
	f[1].y=b;
	f[1].an=0;
	l=0;r=1;
	while(l<r)
	{
	        l++;
	    for(i=0;i<8;i++)
	       {
	                   xx=f[l].x+fx[i][0];
	                   yy=f[l].y+fx[i][1];
	          if(check(xx,yy)==1)
	         	   {
	     	             f[++r].x=xx;
	     	             f[r].y=yy;
	     	             f[r].an=f[l].an+1;
	     	             if(xx==c && yy==d)
	     	                         {
	     	                                 printf("%d\n",f[r].an);
	     	                                 return 0;
	     	                          }
	                   }
	       }
	}
	printf("-1\n");
	return 0;
}


#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#define MOD 40009
using namespace std;
struct node
{
	int x,y;
}S,T,now;
struct nodep
{
	int x,y,step;
}head,tail;
int n,tot;
int movex[]={1,1,1,0,0,-1,-1,-1};
int movey[]={1,0,-1,1,-1,1,0,-1};
queue<nodep>q;
vector<node>hash1[50000],hash2[50000];
void read()
{
	scanf("%d %d %d %d %d",&S.x,&S.y,&T.x,&T.y,&n);
	int row,left,right;
	for(int i=1;i<=n;i++)
	{
		scanf("%d %d %d",&row,&left,&right);
		for(int j=left;j<=right;j++)
			now.x=row,now.y=j,hash1[now.x%MOD*(now.y%MOD)%MOD].push_back(now);
	}
}
int bfs()
{
	head.x=S.x,head.y=S.y,head.step=0;
	q.push(head);
	int hash=head.x%MOD*(head.y%MOD)%MOD;
	hash2[hash].push_back(S);
	while(q.empty()==false)
	{
		head=q.front(),q.pop();
		for(int i=0,j;i<8;i++)
		{
			tail.x=head.x+movex[i],tail.y=head.y+movey[i],tail.step=head.step+1,hash=tail.x%MOD*(tail.y%MOD)%MOD;
			for(j=0;j<hash1[hash].size();j++)
				if(hash1[hash][j].x==tail.x&&hash1[hash][j].y==tail.y)
					break;
			if(j==hash1[hash].size())  continue;
			for(j=0;j<hash2[hash].size();j++)
				if(hash2[hash][j].x==tail.x&&hash2[hash][j].y==tail.y)
					break;
			if(j<hash2[hash].size())  continue;
			now.x=tail.x,now.y=tail.y,hash2[hash].push_back(now),q.push(tail);
			if(now.x==T.x&&now.y==T.y)  return tail.step;
		}
	}
	return -1;
}
int main()
{
	read();
	printf("%d\n",bfs());
	return 0;
}


#include<stdio.h>
#include<stdlib.h>
#define MAXN 100005
#define INF 0x7fffffff
#define max(a ,b) (a > b ? a : b)

typedef struct
{
	int x ;
	int next ;
} road ;
typedef struct
{
	int k1 ;
	int l1 ;
	int r1 ;
} line ;
typedef struct
{
	int x ;
	int y ;
} point ;

point p[MAXN] ;
road r[MAXN*8] ;
line lin[MAXN] ;
int N ,w ,tot;
int x0 ,y0 ,x1 ,y1 ;
int sta ,end ;
int st[MAXN] ,dist[MAXN] ,v[MAXN] ;
int q[MAXN*10] ;

int abs1(int x)
{
	return x>0 ? x : -x ;
}
void add(int x ,int y)
{
	w ++ ;
	r[w].x = y ;
	r[w].next = st[x] ;
	st[x] = w ;
}

int cmp(const void* a ,const void* b)
{
	point c = *(point *)a ,d = *(point *)b ;
	if(c.x > d.x) return 1 ;
	if(c.x < d.x) return -1 ;
	if(c.y > d.y) return 1 ;
	return -1 ;
}
int cmp1(const void* a ,const void* b)
{
	line c = *(line *)a ,d = *(line *)b ;
	if(c.k1 > d.k1) return 1 ;
	if(c.k1 < d.k1) return -1 ;
	if(c.l1 > d.l1) return 1 ;
	return -1 ;
}

void INPUT()
{
	int i ,j ,tmp ,l1 ,r1 ,k1 ;
	scanf("%d %d %d %d" ,&x0 ,&y0 ,&x1 ,&y1) ;
	scanf("%d" ,&N) ;
	for(i = 1 ;i <= N ;i ++)
		scanf("%d %d %d" ,&lin[i].k1 ,&lin[i].l1 ,&lin[i].r1) ;

	qsort(lin ,N+1 ,sizeof(line) ,cmp1) ;
	for(i = 1 ;i <= N ;i ++)
	{
		if(lin[i].k1 != lin[i-1].k1) tmp = lin[i].l1 ;
		else tmp = max(lin[i].l1 ,lin[i-1].r1 + 1) ;
		for(j = tmp ;j <= lin[i].r1 ;j ++)
		{
			p[++tot].x = lin[i].k1 ;
			p[tot].y = j ;
		}
	}

 	qsort(p ,tot+1 ,sizeof(point) ,cmp) ;
	for(i = 1 ;i <= tot ;i ++)
	{
		if(p[i].x == x0 && p[i].y == y0) sta = i ;
		if(p[i].x == x1 && p[i].y == y1) end = i ;
	}
}

void make()
{
	int i ,j ;
	for(i = 1 ;i <= tot ;i ++)
	{
		for(j = i+1 ;p[j].x-p[i].x <= 1 && j <= tot ;j ++)
			if(abs1(p[i].y-p[j].y) <= 1)
			{
				add(i , j) ;
				add(j , i) ;
			}
	}
}

void SPFA()
{
	int i ,x ,f1=0 ,r1=1 ;
	for(i = 1 ;i <= tot ;i ++)
		dist[i] = INF ;
	dist[sta] = 0 ;
	q[1] = sta ;
	while(f1 < r1)
	{
		f1 ++ ;
		x = st[q[f1]] ;
		v[q[f1]] = 0 ;
		while(x)
		{
			if(dist[r[x].x] > dist[q[f1]] + 1)
			{
				dist[r[x].x] = dist[q[f1]] + 1 ;
				if(v[r[x].x] == 0)
				{
					v[r[x].x] = 1 ;
					q[++r1] = r[x].x ;
				}
			}
			x = r[x].next ;
		}
	}
}

void OUTPUT()
{
	if(dist[end] == INF) printf("-1\n") ;
	else printf("%d\n" ,dist[end]) ;
}

int main()
{
	int i ;
	INPUT() ;
	make() ;
	SPFA() ;
	OUTPUT() ;
	return 0 ;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
typedef struct
{
	int r,a,b;
}line;
line p[10000001];
typedef struct
{
	int x,y,step;
}qoo;
qoo a[10000001];
int sx,sy,ex,ey;
int h=0,t=1;
int n;
int d[8][2]={{0,1},{0,-1},{1,0},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1}};
bool cmp(const line& g,const line& h)
{
	return ((g.r<h.r)||(g.r==h.r && g.a<h.a)||(g.r==g.r && g.a==h.a && g.b<h.b));
}
int check(int x,int y)
{
	int biaoji=0;
	for (int i=1;i<=n;i++)
	   if (p[i].r==x)
	   {
			biaoji=1;
			if (p[i].a<=y && p[i].b>=y)
			     return 1;
	   }
	   else if (p[i].r>x) return 0;
	return 0;
}
int judge(int x,int y)
{
	for (int i=1;i<=t;i++)
	   if (a[i].x==x && a[i].y==y) return 1;
	return 0;
}
int main( )
{
	int px,py,newx,newy;
	int flag=0;
	scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	    scanf("%d%d%d",&p[i].r,&p[i].a,&p[i].b);
	sort(p+1,p+1+n,cmp);
	h=0,t=1;
	a[t].x=sx,a[t].y=sy;
	while (h<t)
	{
	    h++;
	    px=a[h].x,py=a[h].y;
		for (int k=0;k<8;k++)
		{
			newx=px+d[k][0];
			newy=py+d[k][1];
			if (check(newx,newy)==1)
			{
				if (judge(newx,newy)==0)
				{
					t++;
					a[t].x=newx,a[t].y=newy;
					a[t].step=a[h].step+1;
					if (newx==ex && newy==ey)
					{
						flag=1;
						printf("%d\n",a[t].step);
						break;
					}
				}
			}
		}
       if (flag==1) break;
	}
	if (!flag) printf("-1\n");
	return 0;
}


#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#define MOD 50021
using namespace std;
struct node
{
	int x,y;
}S,T,now;
struct nodep
{
	int x,y,step;
}head,tail;
int n,tot;
int movex[]={1,1,1,0,0,-1,-1,-1};
int movey[]={1,0,-1,1,-1,1,0,-1};
queue<nodep>q;
vector<node>hash1[100000],hash2[100000];
void read()
{
	scanf("%d %d %d %d %d",&S.x,&S.y,&T.x,&T.y,&n);
	int row,left,right;
	for(int i=1;i<=n;i++)
	{
		scanf("%d %d %d",&row,&left,&right);
		for(int j=left;j<=right;j++)
			now.x=row,now.y=j,hash1[now.x%MOD*(now.y%MOD)%MOD].push_back(now);
	}
}
int bfs()
{
	head.x=S.x,head.y=S.y,head.step=0;
	q.push(head);
	int hash=head.x%MOD*(head.y%MOD)%MOD;
	hash2[hash].push_back(S);
	while(q.empty()==false)
	{
		head=q.front(),q.pop();
		for(int i=0,j;i<8;i++)
		{
			tail.x=head.x+movex[i],tail.y=head.y+movey[i],tail.step=head.step+1,hash=tail.x%MOD*(tail.y%MOD)%MOD;
			for(j=0;j<hash1[hash].size();j++)
				if(hash1[hash][j].x==tail.x&&hash1[hash][j].y==tail.y)
					break;
			if(j==hash1[hash].size())  continue;
			for(j=0;j<hash2[hash].size();j++)
				if(hash2[hash][j].x==tail.x&&hash2[hash][j].y==tail.y)
					break;
			if(j<hash2[hash].size())  continue;
			now.x=tail.x,now.y=tail.y,hash2[hash].push_back(now),q.push(tail);
			if(now.x==T.x&&now.y==T.y)  return tail.step;
		}
	}
	return -1;
}
int main()
{
	read();
	printf("%d\n",bfs());
	return 0;
}


#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <map>
using namespace std;

#define N 101000
#define MAXL 1000000000LL
typedef long long LL;

map<LL, bool> all, hash;
struct State
{
	int x, y, dis;
	State(): x(0), y(0), dis(0) {
	}
	State(int x, int y, int dis): x(x), y(y), dis(dis) {
	}

	LL calc() {
		return (LL) x * MAXL + (LL) y;
	}
	bool operator ==(const State &p) {
		return (p.x == x && p.y == y);
	}
	void Read() {
		scanf("%d%d", &x, &y); dis = 0;
	}
}que[N], S, T;
int head, tail, n;
int d[8][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {-1, 1}, {1, -1}, {-1, -1}};

void init()
{
	S.Read(), T.Read();
	cin >> n;
	for (int i = 1; i <= n; i ++) {
		int r, a, b;
		scanf("%d%d%d", &r, &a, &b);
		for (int j = a; j <= b; j ++) if (!all[State(r, j, 0).calc()]) all[State(r, j, 0).calc()] = true;
	}
}
void BFS()
{
	head = 0, tail = 1, que[1] = S;
	while (head < tail) {
		State now = que[++ head];
		for (int j = 0; j < 8; j ++) {
			State p = State(now.x + d[j][0], now.y + d[j][1], now.dis + 1);
			if (all[p.calc()] && !hash[p.calc()]) {
				hash[p.calc()] = true;
				tail ++, que[tail] = p;
				if (p == T) {
					cout << p.dis << endl;
					return ;
				}
			}
		}
	}
	puts("-1");
	return ;
}
int main()
{
	init();
	BFS();
	return 0;
}


#include<stdio.h>
#include<stdlib.h>
int a,b,c,d,e,h,i,j,l,r,xx,yy,end[1000005];
int ee;
int fx[9][2]={{-1,1},{0,1},{1,1},{1,0},{1,-1},{-1,0},{-1,-1},{0,-1}};
struct node
{
	int x,y,an;
};
struct node f[5000005];

struct node1
{
	int hang,q,z;
};
struct node1 g[5000005];
struct node1 ch;

struct node2
{
	int v,next;
};
struct node2 ff[5000005];

void set(int u,int v)
{
	ff[++ee].v=v;
	ff[ee].next=end[u];end[u]=ee;
}

int check(int x,int y)
{
	int ii,jj;
	jj=end[x];
	while(jj)
	{
	 	ii=ff[jj].v;
		if(g[ii].hang==x && g[ii].q<=y && g[ii].z>=y)
		{
			ch=g[ii];
			g[ii].z=y-1;
			if(y+1<=ch.z)
			{
			        g[++e]=ch;
			        g[e].q=y+1;
			        set(g[e].hang,e);
			}
			return 1;
		}
		jj=ff[jj].next;
	}
	return 0;
}

int main()
{
	scanf("%d%d%d%d",&a,&b,&c,&d);
	scanf("%d",&e);
	for(i=1;i<=e;i++)
	{
		scanf("%d%d%d",&g[i].hang,&g[i].q,&g[i].z);
		set(g[i].hang,i);
	}
	f[1].x=a;
	f[1].y=b;
	f[1].an=0;
	l=0;r=1;
	while(l<r)
	{
	        l++;
	    for(i=0;i<8;i++)
	       {
	                   xx=f[l].x+fx[i][0];
	                   yy=f[l].y+fx[i][1];
	          if(check(xx,yy)==1)
	         	   {
	     	             f[++r].x=xx;
	     	             f[r].y=yy;
	     	             f[r].an=f[l].an+1;
	     	             if(xx==c && yy==d)
	     	                         {
	     	                                 printf("%d\n",f[r].an);
	     	                                 return 0;
	     	                          }
	                   }
	       }
	}
	printf("-1\n");
	return 0;
}


#include<stdio.h>
#include<stdlib.h>
int a,b,c,d,e,h,i,j,l,r,xx,yy,end[1000005];
int ee;
int fx[9][2]={{-1,1},{0,1},{1,1},{1,0},{1,-1},{-1,0},{-1,-1},{0,-1}};
struct node
{
	int x,y,an;
};
struct node f[1000005];

struct node1
{
	int hang,q,z;
};
struct node1 g[1000005];
struct node1 ch;

struct node2
{
	int v,next;
};
struct node2 ff[3000005];

void set(int u,int v)
{
	ff[++ee].v=v;
	ff[ee].next=end[u];end[u]=ee;
}

int check(int x,int y)
{
	int ii,jj;
	jj=end[x];
	while(jj)
	{
	 	ii=ff[jj].v;
		if(g[ii].hang==x && g[ii].q<=y && g[ii].z>=y)
		{
			ch=g[ii];
			g[ii].z=y-1;
			if(y+1<=ch.z)
			{
			        g[++e]=ch;
			        g[e].q=y+1;
			        set(g[e].hang,e);
			}
			return 1;
		}
		jj=ff[jj].next;
	}
	return 0;
}

int main()
{
	scanf("%d%d%d%d",&a,&b,&c,&d);
	scanf("%d",&e);
	for(i=1;i<=e;i++)
	{
		scanf("%d%d%d",&g[i].hang,&g[i].q,&g[i].z);
		set(g[i].hang,i);
	}
	f[1].x=a;
	f[1].y=b;
	f[1].an=0;
	l=0;r=1;
	while(l<r)
	{
	        l++;
	    for(i=0;i<8;i++)
	       {
	                   xx=f[l].x+fx[i][0];
	                   yy=f[l].y+fx[i][1];
	          if(check(xx,yy)==1)
	         	   {
	     	             f[++r].x=xx;
	     	             f[r].y=yy;
	     	             f[r].an=f[l].an+1;
	     	             if(xx==c && yy==d)
	     	                         {
	     	                                 printf("%d\n",f[r].an);
	     	                                 return 0;
	     	                          }
	                   }
	       }
	}
	printf("-1\n");
	return 0;
}


#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>

using namespace std;

#define MOD 4000005
#define delta 1024
#define N 100005
int hash1[MOD][3];
int hash2[MOD][3],team[N][3],inc[N];
int dy[9][2]={{0,0},{1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,-1},{-1,1}};
void cr(int x,int y)
{
	long long u1=(long long)(x)*(long long)(y)%MOD;
	long long k=0;
	while(k<MOD)
	{
		if(hash1[u1][0]==0)
		{
			hash1[u1][1]=x;
			hash1[u1][2]=y;
			hash1[u1][0]=1;
			break;
		}
		if(hash1[u1][1]==x&&hash1[u1][2]==y)
			break;
		u1+=delta;
		k+=delta;
		if(u1>=MOD)
		   u1-=MOD;
	}
}
void work_hash1(int x,int a,int b)
{
	for(int i=a;i<=b;i++)
		cr(x,i);
}
void work_hash2(int x,int y)
{
	long long u1=(long long)(x)*(long long)(y)%MOD;
	long long k=0;
	while(1)
	{
		if(hash2[u1][0]==0)
		{
			hash2[u1][1]=x;
			hash2[u1][2]=y;
			hash2[u1][0]=1;
			break;
		}
		if(hash2[u1][1]==x&&hash2[u1][2]==y)
			break;
		u1+=delta;
		if(u1>=MOD)
			u1-=MOD;
		k+=delta;
	}
}
bool ok1(int x,int y)
{
	long long u1=(long long)(x)*(long long)(y)%MOD;
	while(1)
	{
		if(hash1[u1][1]==x&&hash1[u1][2]==y)
			return true;
		if(hash1[u1][0]==0)
			return false;
		u1+=delta;
		if(u1>=MOD)
			u1-=MOD;
	}
}
bool ok2(int x,int y)
{
	long long u1=(long long)(x)*(long long)(y)%MOD;
	while(1)
	{
		if(hash2[u1][1]==x&&hash2[u1][2]==y)
			return true;
		if(hash2[u1][0]==0)
			return false;
		u1+=delta;
		if(u1>=MOD)
			u1-=MOD;
	}
}
int main()
{
	/*freopen("di3.in","r",stdin);
	freopen("di3.out","w",stdout);*/
	int x0,x1,y0,y1;
	scanf("%d%d%d%d",&x0,&y0,&x1,&y1);
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		int p,q,t;
		scanf("%d%d%d",&p,&q,&t);
		work_hash1(p,q,t);
	}
	int head=0,tail=1;
	inc[1]=0;
	team[1][0]=x0,team[1][1]=y0;
	work_hash2(x0,y0);
	while(head<tail)
	{
		int ux=team[++head][0];
		int uy=team[head][1];
		for(int i=1;i<=8;i++)
		{
			int ux1=ux+dy[i][0];
			int uy1=uy+dy[i][1];
			if(ok1(ux1,uy1)==true&&ok2(ux1,uy1)==false)
			{
				tail++;
				team[tail][0]=ux1,team[tail][1]=uy1;
				work_hash2(ux1,uy1);
				inc[tail]=inc[head]+1;
				if(ux1==x1&&uy1==y1)
				{
					printf("%d\n",inc[tail]);
					return 0;
				}
			}
		}
	}
	printf("-1\n");
	return 0;
}


#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<ctime>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<sstream>
#include<cmath>
#include<deque>
#include<queue>

#define nx(x) (x | (x+1))
#define pr(x) (x & (x+1))

#define fi first
#define MAXN 222222
#define se second
#define len(a) (int(a.length()))
#define all(c) (c).begin(),(c).end()
#define mp make_pair
#define forit(c,i) for(typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)

#define pb push_back
#define pf push_front
#define mem(a,b) memset(a,b,sizeof a)
#define eps 1e-8
using namespace std;
typedef long long ll;

struct esep
{
    int x,y,d;
    esep(int d,int x,int y):d(d),x(x),y(y){}
};
int px[10]={1,1,1,0,-1,-1,-1,0};
int py[10]={-1,0,1,1,1,0,-1,-1};
int main()
{
    ios::sync_with_stdio(0);
    srand(time(NULL));

    int i,j,n,x1,x2,y1,y2,l,r,x,y,d;
    cin>>x1>>y1>>x2>>y2;
    cin>>n;
    map<pair<int,int> , int> was,w;
    for(i=1;i<=n;i++)
    {
        cin>>x>>l>>r;
        for(j=l;j<=r;j++)
          w[mp(x,j)]=1;
    }

    queue<esep> q;
    q.push(esep(0,x1,y1));

    while(!q.empty())
    {

        x=q.front().x;
        y=q.front().y;
        d=q.front().d;

        if(x==x2 && y==y2){cout<<d;return 0;}

        was[mp(x,y)]=1;
        q.pop();

        for(i=0;i<8;i++)
        {
            int nx=x+px[i];
            int ny=y+py[i];
            if(w.count(mp(nx,ny)) && !was[mp(nx,ny)])
                q.push(esep(d+1,nx,ny));
        }

    }
    cout<<-1;

return 0;
}


#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<ctime>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<sstream>
#include<cmath>
#include<deque>
#include<queue>

#define nx(x) (x | (x+1))
#define pr(x) (x & (x+1))

#define fi first
#define MAXN 222222
#define se second
#define len(a) (int(a.length()))
#define all(c) (c).begin(),(c).end()
#define mp make_pair
#define forit(c,i) for(typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)

#define pb push_back
#define pf push_front
#define mem(a,b) memset(a,b,sizeof a)
#define eps 1e-8
using namespace std;
typedef long long ll;

struct esep
{
    int x,y,d;
    esep(int d,int x,int y):d(d),x(x),y(y){}
};
struct otr
{
    int l,r;
    otr(int l,int r):l(l),r(r){}
    bool operator<(otr b)const
    {
        if(l!=b.l)return l<b.l;
        else return r>b.r;
    }
};
bool comp1(otr a,otr b)
{
    return a.l>b.l;
}
bool comp2(otr a,otr b)
{
    return a.r<b.r;
}
map<int,vector<otr> > a;
int px[10]={1,1,1,0,-1,-1,-1,0};
int py[10]={-1,0,1,1,1,0,-1,-1};
int main()
{
    ios::sync_with_stdio(0);
    srand(time(NULL));

    int i,j,n,m,x1,x2,y1,y2,l,r,x,y,d,num;
    cin>>x1>>y1>>x2>>y2;
    cin>>n;
    for(i=1;i<=n;i++)
    {
        cin>>x>>l>>r;
        a[x].pb(otr(l,r));
    }

    forit(a,it)
        sort(it->second.begin(),it->second.end());
    for (i=0;i<a[x1].size();i++)
        if(a[x1][i].l<=y1 && y1<=a[x1][i].r)
           num=i;

    queue<esep> q;
    q.push(esep(0,x1,y1));
    map<pair<int,int> , int> was;

    while(!q.empty())
    {

        x=q.front().x;
        y=q.front().y;
        d=q.front().d;

        //cout<<x<<' '<<y<<endl;

        if(x==x2 && y==y2){cout<<d;return 0;}

        was[mp(x,y)]=1;
        q.pop();

        for(i=0;i<8;i++)
        {
            int nx=x+px[i];
            int ny=y+py[i];
            if(a.count(nx) && !was[mp(nx,ny)])
              {
                  int pos1=lower_bound(a[nx].begin(),a[nx].end(),otr(ny,ny),comp1)-a[nx].begin(),
                      pos2=lower_bound(a[nx].begin(),a[nx].end(),otr(ny,ny),comp2)-a[nx].begin()
                      ,pos;

                   for(pos=pos1;pos<a[nx].size();pos++)
                   {
                       if(a[nx][pos].l <= ny && ny<=a[nx][pos].r)break;
                   }
                   if(pos==a[nx].size())
                   for(pos=0;pos<=pos2;pos++)
                   {
                       if(a[nx][pos].l <= ny && ny<=a[nx][pos].r)break;
                   }

                  if(pos!=a[nx].size() && pos!=pos2+1)
                  {
                      q.push(esep(d+1,nx,ny));
                  }

              }
        }

    }
    cout<<-1;

return 0;
}


#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<ctime>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<sstream>
#include<cmath>
#include<deque>
#include<queue>

#define nx(x) (x | (x+1))
#define pr(x) (x & (x+1))

#define fi first
#define MAXN 222222
#define se second
#define len(a) (int(a.length()))
#define all(c) (c).begin(),(c).end()
#define mp make_pair
#define forit(c,i) for(typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)

#define pb push_back
#define pf push_front
#define mem(a,b) memset(a,b,sizeof a)
#define eps 1e-8
using namespace std;
typedef long long ll;
struct esep
{
    int d;
    pair<int,int> p;
    esep(int d,pair<int,int>p):d(d),p(p){}
};
int px[10]={1,1,1,0,-1,-1,-1,0};
int py[10]={-1,0,1,1,1,0,-1,-1};
int main()
{
    ios::sync_with_stdio(0);
    srand(time(NULL));

    int i,j,n,x1,x2,y1,y2,l,r,x,y,d;
    cin>>x1>>y1>>x2>>y2;
    cin>>n;
    map<pair<int,int>,int> was,w;
    for(i=1;i<=n;i++)
    {
        cin>>x>>l>>r;
        for(j=l;j<=r;j++)
          w[mp(x,j)]=1;
    }

    queue<esep> q;
    q.push(esep(0,mp(x1,y1)));

    pair<int,int> ser=mp(x2,y2);

    while(!q.empty())
    {
        pair<int,int> p=q.front().p;
        d=q.front().d;

        was[p]=1;
        q.pop();

        for(i=0;i<8;i++)
        {
            pair<int,int> np;
            np.fi=p.fi+px[i];
            np.se=p.se+py[i];
            if(w.count(np) && !was[np])
            {
                q.push(esep(d+1,np));
                if(np==ser)
                {
                    cout<<d+1;return 0;
                }
            }

        }

    }
    cout<<-1;

return 0;
}


#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<ctime>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<sstream>
#include<cmath>
#include<deque>
#include<queue>

#define nx(x) (x | (x+1))
#define pr(x) (x & (x+1))

#define fi first
#define MAXN 222222
#define se second
#define len(a) (int(a.length()))
#define all(c) (c).begin(),(c).end()
#define mp make_pair
#define forit(c,i) for(typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)

#define pb push_back
#define pf push_front
#define mem(a,b) memset(a,b,sizeof a)
#define eps 1e-8
using namespace std;
typedef long long ll;
struct esep
{
    int x,y,d;
    esep(int d,int x,int y):d(d),x(x),y(y){}
};
int px[10]={1,1,1,0,-1,-1,-1,0};
int py[10]={-1,0,1,1,1,0,-1,-1};
int main()
{
    ios::sync_with_stdio(0);
    srand(time(NULL));

    int i,j,n,x1,x2,y1,y2,l,r,x,y,d;
    cin>>x1>>y1>>x2>>y2;
    cin>>n;
    map<pair<int,int>,int> was,w;
    for(i=1;i<=n;i++)
    {
        cin>>x>>l>>r;
        for(j=l;j<=r;j++)
          w[mp(x,j)]=1;
    }

    queue<esep> q;
    q.push(esep(0,x1,y1));

    while(!q.empty())
    {

        x=q.front().x;
        y=q.front().y;
        d=q.front().d;

        was[mp(x,y)]=1;
        q.pop();

        for(i=0;i<8;i++)
        {
            int nx=x+px[i];
            int ny=y+py[i];
            if(w.count(mp(nx,ny)) && !was[mp(nx,ny)])
            {
                q.push(esep(d+1,nx,ny));
                if(nx==x2 && ny==y2)
                {
                    cout<<d+1;return 0;
                }
            }

        }

    }
    cout<<-1;

return 0;
}


#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<ctime>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<sstream>
#include<cmath>
#include<deque>
#include<queue>

#define nx(x) (x | (x+1))
#define pr(x) (x & (x+1))

#define fi first
#define MAXN 222222
#define se second
#define len(a) (int(a.length()))
#define all(c) (c).begin(),(c).end()
#define mp make_pair
#define forit(c,i) for(typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)

#define pb push_back
#define pf push_front
#define mem(a,b) memset(a,b,sizeof a)
#define eps 1e-8
using namespace std;
typedef long long ll;

struct esep
{
    int x,y,d;
    esep(int d,int x,int y):d(d),x(x),y(y){}
};
struct otr
{
    int l,r;
    otr(int l,int r):l(l),r(r){}
    bool operator<(otr b)const
    {
        if(l!=b.l)return l<b.l;
        else return r>b.r;
    }
};
bool comp1(otr a,otr b)
{
    return a.l>b.l;
}
bool comp2(otr a,otr b)
{
    return a.r<b.r;
}
map<int,vector<otr> > a;
int px[10]={1,1,1,0,-1,-1,-1,0};
int py[10]={-1,0,1,1,1,0,-1,-1};
int main()
{
    ios::sync_with_stdio(0);
    srand(time(NULL));

    int i,j,n,m,x1,x2,y1,y2,l,r,x,y,d,num;
    cin>>x1>>y1>>x2>>y2;
    cin>>n;
    for(i=1;i<=n;i++)
    {
        cin>>x>>l>>r;
        a[x].pb(otr(l,r));
    }

    forit(a,it)
        sort(it->second.begin(),it->second.end());
    for (i=0;i<a[x1].size();i++)
        if(a[x1][i].l<=y1 && y1<=a[x1][i].r)
           num=i;

    queue<esep> q;
    q.push(esep(0,x1,y1));
    map<pair<int,int> , int> was;

    while(!q.empty())
    {

        x=q.front().x;
        y=q.front().y;
        d=q.front().d;

        //cout<<x<<' '<<y<<endl;

        if(x==x2 && y==y2){cout<<d;return 0;}

        was[mp(x,y)]=1;
        q.pop();

        for(i=0;i<8;i++)
        {
            int nx=x+px[i];
            int ny=y+py[i];
            if(a.count(nx) && !was[mp(nx,ny)])
              {
                  int pos1=lower_bound(a[nx].begin(),a[nx].end(),otr(ny,ny),comp1)-a[nx].begin(),
                      pos2=lower_bound(a[nx].begin(),a[nx].end(),otr(ny,ny),comp2)-a[nx].begin()
                      ,pos;

                   for(pos=pos1;pos<a[nx].size();pos++)
                   {
                       if(a[nx][pos].l <= ny && ny<=a[nx][pos].r)break;
                   }
                  if(pos!=a[nx].size())
                  {
                      q.push(esep(d+1,nx,ny));
                  }

              }
        }

    }
    cout<<-1;

return 0;
}


#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<ctime>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<sstream>
#include<cmath>
#include<deque>
#include<queue>

#define nx(x) (x | (x+1))
#define pr(x) (x & (x+1))

#define fi first
#define MAXN 222222
#define se second
#define len(a) (int(a.length()))
#define all(c) (c).begin(),(c).end()
#define mp make_pair
#define forit(c,i) for(typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)

#define pb push_back
#define pf push_front
#define mem(a,b) memset(a,b,sizeof a)
#define eps 1e-8
using namespace std;
typedef long long ll;

struct esep
{
    int x,y,d;
    esep(int d,int x,int y):d(d),x(x),y(y){}
};
struct otr
{
    int l,r;
    otr(int l,int r):l(l),r(r){}
    bool operator<(otr b)const
    {
        if(l!=b.l)return l<b.l;
        else return r>b.r;
    }
};
bool comp1(otr a,otr b)
{
    return a.l>b.l;
}
bool comp2(otr a,otr b)
{
    return a.r<b.r;
}
map<int,vector<otr> > a;
int px[10]={1,1,1,0,-1,-1,-1,0};
int py[10]={-1,0,1,1,1,0,-1,-1};
int main()
{
    ios::sync_with_stdio(0);
    srand(time(NULL));

    int i,j,n,m,x1,x2,y1,y2,l,r,x,y,d,num;
    cin>>x1>>y1>>x2>>y2;
    cin>>n;
    for(i=1;i<=n;i++)
    {
        cin>>x>>l>>r;
        a[x].pb(otr(l,r));
    }

    forit(a,it)
        sort(it->second.begin(),it->second.end());
    for (i=0;i<a[x1].size();i++)
        if(a[x1][i].l<=y1 && y1<=a[x1][i].r)
           num=i;

    queue<esep> q;
    q.push(esep(0,x1,y1));
    map<pair<int,int> , int> was;

    while(!q.empty())
    {

        x=q.front().x;
        y=q.front().y;
        d=q.front().d;

        //cout<<x<<' '<<y<<endl;

        if(x==x2 && y==y2){cout<<d;return 0;}

        was[mp(x,y)]=1;
        q.pop();

        for(i=0;i<8;i++)
        {
            int nx=x+px[i];
            int ny=y+py[i];
            if(a.count(nx) && !was[mp(nx,ny)])
              {
                  int pos1=lower_bound(a[nx].begin(),a[nx].end(),otr(ny,ny),comp1)-a[nx].begin(),
                      pos2=lower_bound(a[nx].begin(),a[nx].end(),otr(ny,ny),comp2)-a[nx].begin()
                      ,pos;
                   for(pos=pos1;pos<=min(pos2,int(a[nx].size())-1);pos++)
                   {
                       if(a[nx][pos].l <= ny && ny<=a[nx][pos].r)break;
                   }
                  if(pos!=a[nx].size() && pos!=pos2+1)
                  {
                      q.push(esep(d+1,nx,ny));
                  }

              }
        }

    }
    cout<<-1;

return 0;
}


#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<ctime>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<sstream>
#include<cmath>
#include<deque>
#include<queue>

#define nx(x) (x | (x+1))
#define pr(x) (x & (x+1))

#define fi first
#define MAXN 222222
#define se second
#define len(a) (int(a.length()))
#define all(c) (c).begin(),(c).end()
#define mp make_pair
#define forit(c,i) for(typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)

#define pb push_back
#define pf push_front
#define mem(a,b) memset(a,b,sizeof a)
#define eps 1e-8
using namespace std;
typedef long long ll;

struct esep
{
    int x,y,d;
    esep(int d,int x,int y):d(d),x(x),y(y){}
};
struct otr
{
    int l,r;
    otr(int l,int r):l(l),r(r){}
    bool operator<(otr b)const
    {
        if(l!=b.l)return l<b.l;
        else return r>b.r;
    }
};
bool comp1(otr a,otr b)
{
    return a.l>b.l;
}
bool comp2(otr a,otr b)
{
    return a.r<b.r;
}
map<int,vector<otr> > a;
int px[10]={1,1,1,0,-1,-1,-1,0};
int py[10]={-1,0,1,1,1,0,-1,-1};
int main()
{
    ios::sync_with_stdio(0);
    srand(time(NULL));

    int i,j,n,m,x1,x2,y1,y2,l,r,x,y,d,num;
    cin>>x1>>y1>>x2>>y2;
    cin>>n;
    for(i=1;i<=n;i++)
    {
        cin>>x>>l>>r;
        a[x].pb(otr(l,r));
    }

    forit(a,it)
        sort(it->second.begin(),it->second.end());
    for (i=0;i<a[x1].size();i++)
        if(a[x1][i].l<=y1 && y1<=a[x1][i].r)
           num=i;

    queue<esep> q;
    q.push(esep(0,x1,y1));
    map<pair<int,int> , int> was;

    while(!q.empty())
    {

        x=q.front().x;
        y=q.front().y;
        d=q.front().d;

        //cout<<x<<' '<<y<<endl;

        if(x==x2 && y==y2){cout<<d;return 0;}

        was[mp(x,y)]=1;
        q.pop();

        for(i=0;i<8;i++)
        {
            int nx=x+px[i];
            int ny=y+py[i];
            if(a.count(nx) && !was[mp(nx,ny)])
              {
                  //int pos1=lower_bound(a[nx].begin(),a[nx].end(),otr(ny,ny),comp1)-a[nx].begin(),
                  //    pos2=lower_bound(a[nx].begin(),a[nx].end(),otr(ny,ny),comp2)-a[nx].begin()
                  //    ,pos;
                  int pos;
                   for(pos=0;pos<a[nx].size();pos++)
                   {
                       if(a[nx][pos].l <= ny && ny<=a[nx][pos].r)break;
                   }
                  if(pos!=a[nx].size())
                  {
                      q.push(esep(d+1,nx,ny));
                  }

              }
        }

    }
    cout<<-1;

return 0;
}


#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<ctime>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<sstream>
#include<cmath>
#include<deque>
#include<queue>

#define nx(x) (x | (x+1))
#define pr(x) (x & (x+1))

#define fi first
#define MAXN 222222
#define se second
#define len(a) (int(a.length()))
#define all(c) (c).begin(),(c).end()
#define mp make_pair
#define forit(c,i) for(typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)

#define pb push_back
#define pf push_front
#define mem(a,b) memset(a,b,sizeof a)
#define eps 1e-8
using namespace std;
typedef long long ll;
int px[10]={1,1,1,0,-1,-1,-1,0};
int py[10]={-1,0,1,1,1,0,-1,-1};
int main()
{
    ios::sync_with_stdio(0);
    srand(time(NULL));

    int i,j,n,x1,x2,y1,y2,l,r,x,y,d;
    cin>>x1>>y1>>x2>>y2;
    cin>>n;
    map<pair<int,int>,int> was,w;
    for(i=1;i<=n;i++)
    {
        cin>>x>>l>>r;
        for(j=l;j<=r;j++)
          w[mp(x,j)]=1;
    }

    queue<pair<int,int> > q;
    q.push(mp(x1,y1));

    pair<int,int> ser=mp(x2,y2),p,np;

    while(!q.empty())
    {
        p=q.front();
        q.pop();

        for(i=0;i<8;i++)
        {
            np.fi=p.fi+px[i];
            np.se=p.se+py[i];
            if(w.count(np) && !was[np])
            {
                was[np]=was[p]+1;
                q.push(np);
                if(np==ser)
                {
                    cout<<was[np];return 0;
                }
            }

        }

    }
    cout<<-1;

return 0;
}


#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<ctime>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<sstream>
#include<cmath>
#include<deque>
#include<queue>

#define nx(x) (x | (x+1))
#define pr(x) (x & (x+1))

#define fi first
#define MAXN 222222
#define se second
#define len(a) (int(a.length()))
#define all(c) (c).begin(),(c).end()
#define mp make_pair
#define forit(c,i) for(typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)

#define pb push_back
#define pf push_front
#define mem(a,b) memset(a,b,sizeof a)
#define eps 1e-8
using namespace std;
typedef long long ll;
struct esep
{
    int d;
    pair<int,int> p;
    esep(int d,pair<int,int>p):d(d),p(p){}
};
int px[10]={1,1,1,0,-1,-1,-1,0};
int py[10]={-1,0,1,1,1,0,-1,-1};
int main()
{
    ios::sync_with_stdio(0);
    srand(time(NULL));

    int i,j,n,x1,x2,y1,y2,l,r,x,y,d;
    cin>>x1>>y1>>x2>>y2;
    cin>>n;
    map<pair<int,int>,int> was,w;
    for(i=1;i<=n;i++)
    {
        cin>>x>>l>>r;
        for(j=l;j<=r;j++)
          w[mp(x,j)]=1;
    }

    queue<esep> q;
    q.push(esep(0,mp(x1,y1)));

    pair<int,int> ser=mp(x2,y2);

    while(!q.empty())
    {
        pair<int,int> p=q.front().p;
        d=q.front().d;

        was[mp(x,y)]=1;
        q.pop();

        for(i=0;i<8;i++)
        {
            pair<int,int> np;
            np.fi=p.fi+px[i];
            np.se=p.se+py[i];
            if(w.count(np) && !was[np])
            {
                q.push(esep(d+1,np));
                if(np==ser)
                {
                    cout<<d+1;return 0;
                }
            }

        }

    }
    cout<<-1;

return 0;
}


#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<ctime>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<sstream>
#include<cmath>
#include<deque>
#include<queue>

#define nx(x) (x | (x+1))
#define pr(x) (x & (x+1))

#define fi first
#define MAXN 222222
#define se second
#define len(a) (int(a.length()))
#define all(c) (c).begin(),(c).end()
#define mp make_pair
#define forit(c,i) for(typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)

#define pb push_back
#define pf push_front
#define mem(a,b) memset(a,b,sizeof a)
#define eps 1e-8
using namespace std;
typedef long long ll;

struct esep
{
    int x,y,d;
    esep(int d,int x,int y):d(d),x(x),y(y){}
};
struct otr
{
    int l,r;
    otr(int l,int r):l(l),r(r){}
    bool operator<(otr b)const
    {
        if(l!=b.l)return l<b.l;
        else return r>b.r;
    }
};
bool comp(otr a,otr b)
{
    return a.r<b.r;
}
map<int,vector<otr> > a;
int px[10]={1,1,1,0,-1,-1,-1,0};
int py[10]={-1,0,1,1,1,0,-1,-1};
int main()
{
    ios::sync_with_stdio(0);
    srand(time(NULL));

    int i,j,n,m,x1,x2,y1,y2,l,r,x,y,d,num;
    cin>>x1>>y1>>x2>>y2;
    cin>>n;
    for(i=1;i<=n;i++)
    {
        cin>>x>>l>>r;
        a[x].pb(otr(l,r));
    }

    forit(a,it)
        sort(it->second.begin(),it->second.end());
    for (i=0;i<a[x1].size();i++)
        if(a[x1][i].l<=y1 && y1<=a[x1][i].r)
           num=i;

    queue<esep> q;
    q.push(esep(0,x1,y1));
    map<pair<int,int> , int> was;

    while(!q.empty())
    {

        x=q.front().x;
        y=q.front().y;
        d=q.front().d;

        //cout<<x<<' '<<y<<endl;

        if(x==x2 && y==y2){cout<<d;return 0;}

        was[mp(x,y)]=1;
        q.pop();

        for(i=0;i<8;i++)
        {
            int nx=x+px[i];
            int ny=y+py[i];
            if(a.count(nx) && !was[mp(nx,ny)])
              {
                  int pos=lower_bound(a[nx].begin(),a[nx].end(),otr(ny,ny),comp)-a[nx].begin();
                  if(pos!=a[nx].size() && a[nx][pos].l <= ny && ny<=a[nx][pos].r)
                  {
                      q.push(esep(d+1,nx,ny));
                  }

              }
        }

    }
    cout<<-1;

return 0;
}


#include<iostream>
#include<queue>
#include<cstring>
using namespace std;

typedef long long LL;
typedef pair<int,int> ii;
typedef pair<ii, int> pii;

const LL MAXINT = 1000000001;

int main(){
    int s_x, s_y, t_x, t_y;
    cin>>s_x>>s_y>>t_x>>t_y;
    int max_x = max(s_x,t_x);
    int max_y = max(s_y,t_y);
    bool isAllowed[max_x+1][max_y+1];
    memset(isAllowed,false,sizeof(isAllowed));

    int n;
    cin>>n;
    int r,a,b;
    for(int i=0; i<n; i++){
        cin>>r>>a>>b;
        for(int j=a; j<=b; j++){
            isAllowed[r][j] = true;
        }
    }

    vector<ii> coord;
    coord.push_back({-1,-1});
    coord.push_back({-1,0});
    coord.push_back({-1,1});
    coord.push_back({0,1});
    coord.push_back({1,1});
    coord.push_back({1,0});
    coord.push_back({1,-1});
    coord.push_back({0,-1});

    queue<pii> q;
    q.push({ii(s_x,s_y),0});

    while(!q.empty()){
        pii top = q.front();
        int u_x = top.first.first;
        int u_y = top.first.second;
        int u_level = top.second;
        q.pop();

        for(int i=0; i<coord.size(); i++){
            int v_x = u_x+coord[i].first;
            int v_y = u_y+coord[i].second;
            int v_level = (u_level+1);
            if(v_x == t_x && v_y == t_y){
                cout<<v_level<<endl;
                return 0;
            }
            if(isAllowed[v_x][v_y]){
                q.push({ii(v_x,v_y),v_level});
            }
        }
    }
    cout<<-1<<endl;
    return 0;
}


#include<iostream>
#include<queue>
#include<cstring>
#include<stdio.h>
using namespace std;

typedef long long LL;
typedef pair<int,int> ii;
typedef pair<ii, int> pii;

const LL MAXINT = 1000000001;

int main(){
    int s_x, s_y, t_x, t_y;
    scanf("%d%d%d%d",&s_x,&s_y,&t_x,&t_y);

    int max_x = max(s_x,t_x);
    int max_y = max(s_y,t_y);
    bool isAllowed[max_x+1][max_y+1];
    memset(isAllowed,false,sizeof(isAllowed));

    int n;
    scanf("%d",&n);
    int r,a,b;
    for(int i=0; i<n; i++){
        scanf("%d%d%d",&r,&a,&b);
        for(int j=a; j<=b; j++){
            isAllowed[r][j] = true;
        }
    }

    vector<ii> coord;
    coord.push_back({-1,-1});
    coord.push_back({-1,0});
    coord.push_back({-1,1});
    coord.push_back({0,1});
    coord.push_back({1,1});
    coord.push_back({1,0});
    coord.push_back({1,-1});
    coord.push_back({0,-1});

    queue<pii> q;
    q.push({ii(s_x,s_y),0});

    while(!q.empty()){
        pii top = q.front();
        int u_x = top.first.first;
        int u_y = top.first.second;
        //cout<<u_x<<" "<<u_y<<endl;
        int u_level = top.second;
        q.pop();
        isAllowed[u_x][u_y] = false;

        for(int i=0; i<coord.size(); i++){
            int v_x = u_x+coord[i].first;
            int v_y = u_y+coord[i].second;
            int v_level = (u_level+1);
            if(v_x == t_x && v_y == t_y){
                cout<<v_level<<endl;
                return 0;
            }
            if(isAllowed[v_x][v_y]){
                q.push({ii(v_x,v_y),v_level});
            }
        }
    }
    cout<<-1<<endl;
    return 0;
}


#include<iostream>
#include<queue>
#include<cstring>
using namespace std;

typedef long long LL;
typedef pair<int,int> ii;
typedef pair<ii, int> pii;

const LL MAXINT = 1000000001;

int main(){
    int s_x, s_y, t_x, t_y;
    cin>>s_x>>s_y>>t_x>>t_y;
    int max_x = max(s_x,t_x);
    int max_y = max(s_y,t_y);
    bool isAllowed[max_x+1][max_y+1];
    memset(isAllowed,false,sizeof(isAllowed));

    int n;
    cin>>n;
    int r,a,b;
    for(int i=0; i<n; i++){
        cin>>r>>a>>b;
        for(int j=a; j<=b; j++){
            isAllowed[r][j] = true;
        }
    }

    vector<ii> coord;
    coord.push_back({-1,-1});
    coord.push_back({-1,0});
    coord.push_back({-1,1});
    coord.push_back({0,1});
    coord.push_back({1,1});
    coord.push_back({1,0});
    coord.push_back({1,-1});
    coord.push_back({0,-1});

    queue<pii> q;
    q.push({ii(s_x,s_y),0});

    while(!q.empty()){
        pii top = q.front();
        int u_x = top.first.first;
        int u_y = top.first.second;
        //cout<<u_x<<" "<<u_y<<endl;
        int u_level = top.second;
        q.pop();
        isAllowed[u_x][u_y] = false;

        for(int i=0; i<coord.size(); i++){
            int v_x = u_x+coord[i].first;
            int v_y = u_y+coord[i].second;
            int v_level = (u_level+1);
            if(v_x == t_x && v_y == t_y){
                cout<<v_level<<endl;
                return 0;
            }
            if(isAllowed[v_x][v_y]){
                q.push({ii(v_x,v_y),v_level});
            }
        }
    }
    cout<<-1<<endl;
    return 0;
}


#include<iostream>
#include<queue>
#include<cstring>
#include<stdio.h>
#include<map>
using namespace std;

typedef long long LL;
typedef pair<int,int> ii;
typedef pair<ii, int> pii;
map<ii, LL> path;
#define mp make_pair
#define f first
#define s second

const LL MAXINT = 1000000001;
int x[] = {-1,-1,-1,0,1,1,1,0};
int y[] = {-1,0,1,1,1,0,-1,-1};

int main(){
    int s_x, s_y, t_x, t_y;
    scanf("%d%d%d%d",&s_x,&s_y,&t_x,&t_y);

    int n;
    scanf("%d",&n);
    int r,a,b;
    for(int i=0; i<n; i++){
        scanf("%d%d%d",&r,&a,&b);
        for(int j=a; j<=b; j++){
            path[mp(r,j)] = -1;
        }
    }

    queue<ii> q;
    path[mp(s_x,s_y)] = 0;
    q.push(mp(s_x,s_y));

    while(!q.empty()){
        ii top = q.front();
        int u_x = top.f;
        int u_y = top.s;

        q.pop();
        int u_level = path[mp(u_x,u_y)];

        for(int i=0; i<8; i++){
            int v_x = u_x+x[i];
            int v_y = u_y+y[i];
            if(path[mp(v_x,v_y)] < 0){
                q.push(mp(v_x,v_y));
                path[mp(v_x,v_y)] = (u_level+1);
            }
        }
    }
    cout<<path[mp(t_x,t_y)]<<endl;
    return 0;
}


#include <iostream>
#include <queue>
using namespace std;
int	len [500] [500]  = {0} ;
bool vis [500] [500] = {false} ;
int cost [500][500] ={10000};
int ni = 0;
int prevx [500][500]= {0} ;

int prevy [500][500]= {0} ;
int lin [500] = {0};
int count = 0 ;
	queue <int> q ;
	queue <int> q2 ;
int BFS (int x , int y , int x1 , int y1)
{
	int a = x;
	int b = y;
	cost[x][y] = -1 ;

     prevx [a][b]= a ;
     prevy [a][b]= b ;
	q.push (x);
	q2.push(y) ;
	while (q.empty () == false)
	{

		 a = q.front() ;
		 b = q2.front() ;

		if (a==x1 && b==y1)
		return cost[a][b] ;

		q.pop() ;
		q2.pop() ;
		if(vis[a][b] == true)
		{
			continue ;
		}

		else
		{
			vis[a][b] = true ;
		}

		//if (len[a][b] ==1 )
		{

		if (len[a][b+1]==1)
		{

			if (vis[a][b+1]==false)
			{q.push (a);
			q2.push(b+1) ;
			prevx [a][b+1]= a ;
     prevy [a][b+1]= b ;

				cost[a][b+1] = cost[a][b] +1 ;

						if ((prevx[a][b]== a+1 ||prevx[a][b] == a-1 )&& prevy[a][b] == b)--cost[a][b+1] ;
				}
			else
			if (cost[a][b]+1>cost[a][b+1])
			ni = ni + cost[a][b]+1 - cost[a][b+1] ;

		}
		if (len[a][b-1]==1)
		{
				if (vis[a][b-1]==false)
		{	q.push (a);
			q2.push(b-1) ;
				prevx [a][b-1]= a ;
     prevy [a][b-1]= b ;
				cost[a][b-1] = cost[a][b] +1 ;
					if ((prevx[a][b]== a+1 ||prevx[a][b] == a-1 )&& prevy[a][b] == b)--cost[a][b-1] ;
		}
				else
			if (cost[a][b]+1>cost[a][b-1])
			ni = ni + cost[a][b]+1 - cost[a][b-1] ;
		}

		if (len[a+1][b]==1)
		{
				if (vis[a+1][b]==false)
				{

			q.push (a+1);
			q2.push(b) ;
				prevx [a+1][b]= a ;
     prevy [a+1][b]= b ;
				cost[a+1][b] = cost[a][b] +1 ;
					if ((prevy[a][b]== b+1 ||prevy[a][b] == b-1 )&& prevx[a][b] == a)--cost[a+1][b] ;
				}
					else{

			if (cost[a][b]+1>cost[a+1][b])
			ni = ni + cost[a][b]+1 - cost[a+1][b] ;
		}
		}

		if (len[a-1][b]==1)
		{
			if (vis[a-1][b]==false)
				{
			q.push (a-1);
			q2.push(b) ;
				prevx [a-1][b]= a ;
     prevy [a-1][b]= b ;
				cost[a-1][b] = cost[a][b] +1 ;
					if ((prevy[a][b]== b+1 ||prevy[a][b] == b-1 )&& prevx[a][b] == a)--cost[a-1][b] ;
				}
					else
			if (cost[a][b]+1>cost[a-1][b])
			ni = ni + cost[a][b]+1 - cost[a-1][b] ;
		}
		if (len[a-1][b-1]==1)
		{
			if (vis[a-1][b-1]==false)
				{
			q.push (a-1);
			q2.push(b-1) ;
				cost[a-1][b-1] = cost[a][b] +1 ;
				}
					else
			if (cost[a][b]+1>cost[a-1][b-1])
			ni = ni + cost[a][b]+1 - cost[a-1][b-1] ;
		}
		if (len[a+1][b+1]==1)
		{
			//cout<<a+1<<b+1<<"*" ;
				if (vis[a+1][b+1]==false)
				{
			q.push (a+1);
			q2.push(b+1) ;
				cost[a+1][b+1] = cost[a][b] +1 ;

				}
					else

			if (cost[a][b]+1>cost[a+1][b+1])
		{	ni = ni + cost[a][b]+1 - cost[a+1][b+1] ;}

		}
		if (len[a-1][b+1]==1)
		{	if (vis[a-1][b+1]==false)
				{
			q.push (a-1);
			q2.push(b+1) ;
				cost[a-1][b+1] = cost[a][b] +1 ;
				}
					else
			if (cost[a][b]+1>cost[a-1][b+1])
		{	ni = ni + cost[a][b]+1 - cost[a-1][b+1] ;}
		}
		if (len[a+1][b-1]==1)
		{

			if (vis[a+1][b-1]==false)
				{
			q.push (a+1);
			q2.push(b-1) ;
				cost[a+1][b-1] = cost[a][b] +1 ;
				}
					else
			if (cost[a][b]+1>cost[a+1][b-1])
		{	ni = ni + cost[a][b]+1 - cost[a+1][b-1]  ;}
		}

	//	cost[a+1][b+1] = cost[a+1][b-1] = cost [a-1][b+1] = cost [a-1][b-1] =
	//	cost[a-1][b] = cost[a+1][b] = cost[a][b+1] = cost [a][b-1] = cost[a][b] + 1 ;

	//	cout<<ni<<"--";

		}
	}

		return lin[count];
	return 0;
}
int main() {
int x , y , x1 , y1 ;
cin>>x>>y>>x1>>y1 ;
len[x][y] = 1 ;
len[x1][y1] = 1 ;
int s , d, f ;
int c = 0;
cin>>c;
for (int i = 0 ; i<c ; i++)
{

	cin>> s>>d>>f;
	for (int j = d ; j<=f ; j++)
	{len[s][j] = 1 ;
	}

}

cout<<BFS (x , y , x1 , y1) ;
	// your code goes here
	return 0;
}


#include <iostream>
#include <queue>
#include <map>
using namespace std;
map<int,map<int,bool> > len   ;
map<int,map<int,bool> > vis  ;

map<int,map<int,int> > cost ;
int ni = 0;

int count = 0 ;
	queue <int> q ;
	queue <int> q2 ;
int BFS (int x , int y , int x1 , int y1)
{

	int a = x;
	int b = y;
	cost[x][y] = 0 ;

	q.push (x);
	q2.push(y) ;
	while (q.empty () == false)
	{
		if (cost[a][b] > 100001)
		break ;

		 a = q.front() ;
		 b = q2.front() ;

		if (a==x1 && b==y1)
	{
		return cost[a][b] ;
	}

		q.pop() ;
		q2.pop() ;
		if(vis[a][b] == true)
		{
			continue ;
		}

		else
		{
			vis[a][b] = true ;
		}

		//if (len[a][b] ==1 )
		{

		if (len[a][b+1]==1)
		{

			if (vis[a][b+1]==false)
			{q.push (a);
			q2.push(b+1) ;

				cost[a][b+1] = min (cost[a][b] +1 , cost[a][b+1]) ;
		//		cout<<a<<b<<cost[a][b]<<"*" ;

					//	if ((prevx[a][b]== a+1 ||prevx[a][b] == a-1 )&& prevy[a][b] == b)--cost[a][b+1] ;
				}

		}
		if (len[a][b-1]==1)
		{
				if (vis[a][b-1]==false)
		{	q.push (a);
			q2.push(b-1) ;

				cost[a][b-1] =  min (cost[a][b] +1 ,cost[a][b-1]);
					//if ((prevx[a][b]== a+1 ||prevx[a][b] == a-1 )&& prevy[a][b] == b)--cost[a][b-1] ;
		}

		}

		if (len[a+1][b]==1)
		{
				if (vis[a+1][b]==false)
				{

			q.push (a+1);
			q2.push(b) ;

				cost[a+1][b] =min (cost[a][b] +1 ,cost[a+1][b]);

					//if ((prevy[a][b]== b+1 ||prevy[a][b] == b-1 )&& prevx[a][b] == a)--cost[a+1][b] ;
				}

		}

		if (len[a-1][b]==1)
		{
			if (vis[a-1][b]==false)
				{
			q.push (a-1);
			q2.push(b) ;

				cost[a-1][b] = min (cost[a][b] +1 ,cost[a-1][b]);
					//if ((prevy[a][b]== b+1 ||prevy[a][b] == b-1 )&& prevx[a][b] == a)--cost[a-1][b] ;
				}

		}
		if (len[a-1][b-1]==1)
		{
			if (vis[a-1][b-1]==false)
				{
			q.push (a-1);
			q2.push(b-1) ;
				cost[a-1][b-1] = min (cost[a][b] +1 ,cost[a-1][b-1]);
				}

		}
		if (len[a+1][b+1]==1)
		{
			//cout<<a+1<<b+1<<"*" ;
				if (vis[a+1][b+1]==false)
				{
			q.push (a+1);
			q2.push(b+1) ;
				cost[a+1][b+1] = min (cost[a][b] +1 ,cost[a+1][b+1]);

				}

		}
		if (len[a-1][b+1]==1)
		{	if (vis[a-1][b+1]==false)
				{
			q.push (a-1);
			q2.push(b+1) ;
				cost[a-1][b+1] = min (cost[a][b] +1 ,cost[a-1][b+1]);
				}

		}
		if (len[a+1][b-1]==1)
		{

			if (vis[a+1][b-1]==false)
				{
			q.push (a+1);
			q2.push(b-1) ;
				cost[a+1][b-1] = min (cost[a][b] +1 ,cost[a+1][b-1]);
				}

		}

	//	cout<<ni<<"--";

		}
	}

	return -1;
}
int main() {
int x , y , x1 , y1 ;
cin>>x>>y>>x1>>y1 ;
len[x][y] = 1 ;
len[x1][y1] = 1 ;
int s , d, f ;
int c = 0;
cin>>c;
for (int i = 0 ; i<c ; i++)
{

	cin>> s>>d>>f;
	for (int j = d ; j<=f ; j++)
	{len[s][j] = true ;
	 cost[s][j] = 100005 ;
	}

}

cout<<BFS (x , y , x1 , y1) ;
	// your code goes here
	return 0;
}


#include <iostream>
#include <queue>
#include <vector>
#include<algorithm>
using namespace std;
bool  len  [10000][10000] = {false} ;

vector < vector <int> >cost ;
//vector < vector <int> >cost2 ;
bool vis [1000] [1000] = {false} ;
//int cost [1000][1000] ={10000};
int ni = 0;

int count = 0 ;
	queue <int> q ;
	queue <int> q2 ;

int BFS (int x , int y , int x1 , int y1)
{

	for (int j = 0 ; j<1000 ; j++)
        for (int k = 0 ; k<1000 ; k++)
       { cost[j][k] = 10000 ;
       len[j][k] = 0 ;
       }
	int a = x;
	int b = y;
	cost[x][y] = 0 ;

	q.push (x);
	q2.push(y) ;
	while (q.empty () == false)
	{

		 a = q.front() ;
		 b = q2.front() ;

		if (a==x1 && b==y1)
	{		return cost[a][b] ;
	}

		q.pop() ;
		q2.pop() ;
		if(vis[a][b] == true)
		{
			continue ;
		}

		else
		{
			vis[a][b] = true ;
		}

		//if (len[a][b] ==1 )
		{

		if (len[a][b+1]==1)
		{

			if (vis[a][b+1]==false)
			{q.push (a);
			q2.push(b+1) ;

				cost[a][b+1] = min (cost[a][b] +1 , cost[a][b+1]) ;

					}

		}
		if (len[a][b-1]==1)
		{
				if (vis[a][b-1]==false)
		{	q.push (a);
			q2.push(b-1) ;

				cost[a][b-1] =  min (cost[a][b] +1 ,cost[a][b-1]);
					//if ((prevx[a][b]== a+1 ||prevx[a][b] == a-1 )&& prevy[a][b] == b)--cost[a][b-1] ;
		}

		}

		if (len[a+1][b]==1)
		{
				if (vis[a+1][b]==false)
				{

			q.push (a+1);
			q2.push(b) ;

				cost[a+1][b] =min (cost[a][b] +1 ,cost[a+1][b]);

					//if ((prevy[a][b]== b+1 ||prevy[a][b] == b-1 )&& prevx[a][b] == a)--cost[a+1][b] ;
				}

		}

		if (len[a-1][b]==1)
		{
			if (vis[a-1][b]==false)
				{
			q.push (a-1);
			q2.push(b) ;

				cost[a-1][b] = min (cost[a][b] +1 ,cost[a-1][b]);
					//if ((prevy[a][b]== b+1 ||prevy[a][b] == b-1 )&& prevx[a][b] == a)--cost[a-1][b] ;
				}

		}
		if (len[a-1][b-1]==1)
		{
			if (vis[a-1][b-1]==false)
				{
			q.push (a-1);
			q2.push(b-1) ;
				cost[a-1][b-1] = min (cost[a][b] +1 ,cost[a-1][b-1]);
				}

		}
		if (len[a+1][b+1]==1)
		{
			//cout<<a+1<<b+1<<"*" ;
				if (vis[a+1][b+1]==false)
				{
			q.push (a+1);
			q2.push(b+1) ;
				cost[a+1][b+1] = min (cost[a][b] +1 ,cost[a+1][b+1]);

				}

		}
		if (len[a-1][b+1]==1)
		{	if (vis[a-1][b+1]==false)
				{
			q.push (a-1);
			q2.push(b+1) ;
				cost[a-1][b+1] = min (cost[a][b] +1 ,cost[a-1][b+1]);
				}

		}
		if (len[a+1][b-1]==1)
		{

			if (vis[a+1][b-1]==false)
				{
			q.push (a+1);
			q2.push(b-1) ;
				cost[a+1][b-1] = min (cost[a][b] +1 ,cost[a+1][b-1]);
				}

		}

	//	cout<<ni<<"--";

		}
	}

	return -1;
}

int main() {

	cost.resize(1005) ;
	for (int j= 0 ; j<1000 ; j++)
	{
	cost[j].resize(1000);

	}
int x , y , x1 , y1 ;
cin>>x>>y>>x1>>y1 ;
len[x][y] = 1 ;
len[x1][y1] = 1 ;
int s , d, f ;
int c = 0;

cin>>c;
for (int i = 0 ; i<c ; i++)
{

	cin>> s>>d>>f;
	for (int j = d ; j<=f ; j++)
	{len[s][j] = true ;
	}

}

cout<<BFS (x , y , x1 , y1) ;
	// your code goes here
	return 0;
}


#include <iostream>
#include <queue>
#include <vector>
#include<algorithm>
using namespace std;
bool  len  [9999][9999] = {false} ;

vector < vector <int> >cost ;
//vector < vector <int> >cost2 ;
bool vis [9999] [9999] = {false} ;
//int cost [1000][1000] ={10000};
int ni = 0;

int count = 0 ;
	queue <int> q ;
	queue <int> q2 ;

int BFS (int x , int y , int x1 , int y1)
{

	for (int j = 0 ; j<1000 ; j++)
        for (int k = 0 ; k<1000 ; k++)
       { cost[j][k] = 10000 ;
       len[j][k] = 0 ;
       }
	int a = x;
	int b = y;
	cost[x][y] = 0 ;

	q.push (x);
	q2.push(y) ;
	while (q.empty () == false)
	{

		 a = q.front() ;
		 b = q2.front() ;

		if (a==x1 && b==y1)
	{		return cost[a][b] ;
	}

		q.pop() ;
		q2.pop() ;
		if(vis[a][b] == true)
		{
			continue ;
		}

		else
		{
			vis[a][b] = true ;
		}

		//if (len[a][b] ==1 )
		{

		if (len[a][b+1]==1)
		{

			if (vis[a][b+1]==false)
			{q.push (a);
			q2.push(b+1) ;

				cost[a][b+1] = min (cost[a][b] +1 , cost[a][b+1]) ;

					}

		}
		if (len[a][b-1]==1)
		{
				if (vis[a][b-1]==false)
		{	q.push (a);
			q2.push(b-1) ;

				cost[a][b-1] =  min (cost[a][b] +1 ,cost[a][b-1]);
					//if ((prevx[a][b]== a+1 ||prevx[a][b] == a-1 )&& prevy[a][b] == b)--cost[a][b-1] ;
		}

		}

		if (len[a+1][b]==1)
		{
				if (vis[a+1][b]==false)
				{

			q.push (a+1);
			q2.push(b) ;

				cost[a+1][b] =min (cost[a][b] +1 ,cost[a+1][b]);

					//if ((prevy[a][b]== b+1 ||prevy[a][b] == b-1 )&& prevx[a][b] == a)--cost[a+1][b] ;
				}

		}

		if (len[a-1][b]==1)
		{
			if (vis[a-1][b]==false)
				{
			q.push (a-1);
			q2.push(b) ;

				cost[a-1][b] = min (cost[a][b] +1 ,cost[a-1][b]);
					//if ((prevy[a][b]== b+1 ||prevy[a][b] == b-1 )&& prevx[a][b] == a)--cost[a-1][b] ;
				}

		}
		if (len[a-1][b-1]==1)
		{
			if (vis[a-1][b-1]==false)
				{
			q.push (a-1);
			q2.push(b-1) ;
				cost[a-1][b-1] = min (cost[a][b] +1 ,cost[a-1][b-1]);
				}

		}
		if (len[a+1][b+1]==1)
		{
			//cout<<a+1<<b+1<<"*" ;
				if (vis[a+1][b+1]==false)
				{
			q.push (a+1);
			q2.push(b+1) ;
				cost[a+1][b+1] = min (cost[a][b] +1 ,cost[a+1][b+1]);

				}

		}
		if (len[a-1][b+1]==1)
		{	if (vis[a-1][b+1]==false)
				{
			q.push (a-1);
			q2.push(b+1) ;
				cost[a-1][b+1] = min (cost[a][b] +1 ,cost[a-1][b+1]);
				}

		}
		if (len[a+1][b-1]==1)
		{

			if (vis[a+1][b-1]==false)
				{
			q.push (a+1);
			q2.push(b-1) ;
				cost[a+1][b-1] = min (cost[a][b] +1 ,cost[a+1][b-1]);
				}

		}

	//	cout<<ni<<"--";

		}
	}

	return -1;
}

int main() {

	cost.resize(5005) ;
	for (int j= 0 ; j<5000 ; j++)
	{
	cost[j].resize(5000);

	}
int x , y , x1 , y1 ;
cin>>x>>y>>x1>>y1 ;
len[x][y] = 1 ;
len[x1][y1] = 1 ;
int s , d, f ;
int c = 0;

cin>>c;
for (int i = 0 ; i<c ; i++)
{

	cin>> s>>d>>f;
	for (int j = d ; j<=f ; j++)
	{len[s][j] = true ;
	}

}

cout<<BFS (x , y , x1 , y1) ;
	// your code goes here
	return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

struct segm { int r; int a; int b; };

struct point {
    int x; int y;
    point(int x, int y):x(x), y(y) {}
};

bool compare1(segm a, segm b) {
    if (a.r != b.r) return (a.r<b.r);
    else return (a.a<b.a);
}

bool compare2(point a, point b) {
    if (a.x != b.x) return (a.x<b.x);
    else return (a.y<b.y);
}

vector<vector<int> > graph;

void add_edge(int i, int j) {
    graph[i].push_back(j);
    graph[j].push_back(i);
}

int main()
{
    int x0, y0, x1, y1, n;
    vector<segm> segments;
    vector<point> points;
    points.reserve(100000);
    cin >> x0 >> y0 >> x1 >> y1 >> n;
    segments.resize(n);
    for (int i=0; i<n; i++) cin >> segments[i].r >> segments[i].a >> segments[i].b;
    sort(segments.begin(), segments.end(), compare1);
    int now = 0, right = 0;
    for (int i=0; i<n; i++) {
        if (now != segments[i].r) {
            now = segments[i].r;
            right = 0;
        }
        for (int j=max(segments[i].a, right+1); j<=segments[i].b; j++) points.push_back(*(new point(now, j)));
        if (segments[i].b > right) right = segments[i].b;
    }
    sort(points.begin(), points.end(), compare2);
    graph.resize(points.size(), *(new vector<int>(8, -1)));
    for (int i=0; i<points.size(); i++) {
        vector<point>::iterator a;
        a = lower_bound(points.begin(), points.end(), point(points[i].x-1, points[i].y-1), compare2);
        if (a->x == points[i].x-1 && a->y == points[i].y-1) add_edge(int(a-points.begin()), i);
        a = lower_bound(points.begin(), points.end(), point(points[i].x, points[i].y-1), compare2);
        if (a->x == points[i].x && a->y == points[i].y-1) add_edge(int(a-points.begin()), i);
        a = lower_bound(points.begin(), points.end(), point(points[i].x+1, points[i].y-1), compare2);
        if (a->x == points[i].x+1 && a->y == points[i].y-1) add_edge(int(a-points.begin()), i);
        a = lower_bound(points.begin(), points.end(), point(points[i].x-1, points[i].y), compare2);
        if (a->x == points[i].x-1 && a->y == points[i].y) add_edge(int(a-points.begin()), i);
    }
    vector<int> time(points.size());
    vector<bool> used(n);
    queue<int> q;
    q.push((int)(lower_bound(points.begin(), points.end(), point(x0, y0), compare2) - points.begin()));
    used[q.front()] = true;
    while(!q.empty()) {
        int v=q.front();
        q.pop();
        for (int i=0; i<graph[v].size(); i++) {
            if (!used[graph[v][i]] && graph[v][i] != -1) {
                q.push(graph[v][i]);
                time[graph[v][i]] = time[v] + 1;
                used[graph[v][i]] = true;
            }
        }
    }
    int k = time[(int)(lower_bound(points.begin(), points.end(), point(x1, y1), compare2) - points.begin())];
    if (k == 0) cout << -1;
    else cout << k;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

struct segm { int r; int a; int b; };

struct point {
    int x; int y;
    point(int x, int y):x(x), y(y) {}
};

bool compare1(segm a, segm b) {
    if (a.r != b.r) return (a.r<b.r);
    else return (a.a<b.a);
}

bool compare2(point a, point b) {
    if (a.x != b.x) return (a.x<b.x);
    else return (a.y<b.y);
}

vector<vector<int> > graph;

void add_edge(int i, int j) {
    graph[i].push_back(j);
    graph[j].push_back(i);
}

int main()
{
    int x0, y0, x1, y1, n;
    vector<segm> segments;
    vector<point> points;
    points.reserve(100000);
    cin >> x0 >> y0 >> x1 >> y1 >> n;
    segments.resize(n);
    for (int i=0; i<n; i++) cin >> segments[i].r >> segments[i].a >> segments[i].b;
    sort(segments.begin(), segments.end(), compare1);
    int now = 0, right = 0;
    for (int i=0; i<n; i++) {
        if (now != segments[i].r) {
            now = segments[i].r;
            right = 0;
        }
        for (int j=max(segments[i].a, right+1); j<=segments[i].b; j++) points.push_back(*(new point(now, j)));
        if (segments[i].b > right) right = segments[i].b;
    }
    sort(points.begin(), points.end(), compare2);
    graph.resize(points.size());
    for (int i=0; i<points.size(); i++) {
        vector<point>::iterator a;
        a = lower_bound(points.begin(), points.end(), point(points[i].x-1, points[i].y-1), compare2);
        if (a->x == points[i].x-1 && a->y == points[i].y-1) add_edge(int(a-points.begin()), i);
        a = lower_bound(points.begin(), points.end(), point(points[i].x, points[i].y-1), compare2);
        if (a->x == points[i].x && a->y == points[i].y-1) add_edge(int(a-points.begin()), i);
        a = lower_bound(points.begin(), points.end(), point(points[i].x+1, points[i].y-1), compare2);
        if (a->x == points[i].x+1 && a->y == points[i].y-1) add_edge(int(a-points.begin()), i);
        a = lower_bound(points.begin(), points.end(), point(points[i].x-1, points[i].y), compare2);
        if (a->x == points[i].x-1 && a->y == points[i].y) add_edge(int(a-points.begin()), i);
    }
    vector<int> time(points.size());
    vector<bool> used(n);
    queue<int> q;
    q.push((int)(lower_bound(points.begin(), points.end(), point(x0, y0), compare2) - points.begin()));
    used[q.front()] = true;
    while(!q.empty()) {
        int v=q.front();
        q.pop();
        for (int i=0; i<graph[v].size(); i++) {
            if (!used[graph[v][i]]) {
                q.push(graph[v][i]);
                time[graph[v][i]] = time[v] + 1;
                used[graph[v][i]] = true;
            }
        }
    }
    int k = time[(int)(lower_bound(points.begin(), points.end(), point(x1, y1), compare2) - points.begin())];
    if (k == 0) cout << -1;
    else cout << k;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

struct segm { int r; int a; int b; };

struct point {
    int x; int y;
    point(int x, int y):x(x), y(y) {}
};

bool compare1(segm a, segm b) {
    if (a.r != b.r) return (a.r<b.r);
    else return (a.a<b.a);
}

bool compare2(point a, point b) {
    if (a.x != b.x) return (a.x<b.x);
    else return (a.y<b.y);
}

vector<vector<int> > graph;
vector<int> c;

void add_edge(int i, int j) {
    graph[i][c[i]]=j;
    graph[j][c[j]]=i;
    c[i]++;
    c[j]++;
}

int main()
{
    int x0, y0, x1, y1, n;
    vector<segm> segments;
    vector<point> points;
    points.reserve(100000);
    cin >> x0 >> y0 >> x1 >> y1 >> n;
    segments.resize(n);
    for (int i=0; i<n; i++) cin >> segments[i].r >> segments[i].a >> segments[i].b;
    sort(segments.begin(), segments.end(), compare1);
    int now = 0, right = 0;
    for (int i=0; i<n; i++) {
        if (now != segments[i].r) {
            now = segments[i].r;
            right = 0;
        }
        for (int j=max(segments[i].a, right+1); j<=segments[i].b; j++) points.push_back(*(new point(now, j)));
        if (segments[i].b > right) right = segments[i].b;
    }
    sort(points.begin(), points.end(), compare2);
    graph.resize(points.size(), *(new vector<int>(8, -1)));
    c.resize(points.size());
    for (int i=0; i<points.size(); i++) {
        vector<point>::iterator a;
        a = lower_bound(points.begin(), points.end(), point(points[i].x-1, points[i].y-1), compare2);
        if (a->x == points[i].x-1 && a->y == points[i].y-1) add_edge(int(a-points.begin()), i);
        a = lower_bound(points.begin(), points.end(), point(points[i].x, points[i].y-1), compare2);
        if (a->x == points[i].x && a->y == points[i].y-1) add_edge(int(a-points.begin()), i);
        a = lower_bound(points.begin(), points.end(), point(points[i].x+1, points[i].y-1), compare2);
        if (a->x == points[i].x+1 && a->y == points[i].y-1) add_edge(int(a-points.begin()), i);
        a = lower_bound(points.begin(), points.end(), point(points[i].x-1, points[i].y), compare2);
        if (a->x == points[i].x-1 && a->y == points[i].y) add_edge(int(a-points.begin()), i);
    }
    vector<int> time(points.size());
    vector<bool> used(n);
    queue<int> q;
    q.push((int)(lower_bound(points.begin(), points.end(), point(x0, y0), compare2) - points.begin()));
    used[q.front()] = true;
    while(!q.empty()) {
        int v=q.front();
        q.pop();
        for (int i=0; i<c[v]; i++) {
            if (!used[graph[v][i]]) {
                q.push(graph[v][i]);
                time[graph[v][i]] = time[v] + 1;
                used[graph[v][i]] = true;
            }
        }
    }
    int k = time[(int)(lower_bound(points.begin(), points.end(), point(x1, y1), compare2) - points.begin())];
    if (k == 0) cout << -1;
    else cout << k;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

struct segm { int r; int a; int b; };

struct point {
    int x; int y;
    point(int x, int y):x(x), y(y) {}
};

bool compare1(segm a, segm b) {
    if (a.r != b.r) return (a.r<b.r);
    else return (a.a<b.a);
}

bool compare2(point a, point b) {
    if (a.x != b.x) return (a.x<b.x);
    else return (a.y<b.y);
}

vector<vector<int> > graph;

void add_edge(int i, int j) {
    graph[i].push_back(j);
    graph[j].push_back(i);
}

int main()
{
    int x0, y0, x1, y1, n;
    vector<segm> segments;
    vector<point> points;
    points.reserve(100000);
    cin >> x0 >> y0 >> x1 >> y1 >> n;
    segments.resize(n);
    for (int i=0; i<n; i++) cin >> segments[i].r >> segments[i].a >> segments[i].b;
    sort(segments.begin(), segments.end(), compare1);
    int now = 0, right = 0;
    for (int i=0; i<n; i++) {
        if (now != segments[i].r) {
            now = segments[i].r;
            right = 0;
        }
        for (int j=max(segments[i].a, right+1); j<=segments[i].b; j++) points.push_back(*(new point(now, j)));
        if (segments[i].b > right) right = segments[i].b;
    }
    sort(points.begin(), points.end(), compare2);
    graph.resize(points.size());
    for (int i=0; i<points.size(); i++) graph[i].reserve(8);
    for (int i=0; i<points.size(); i++) {
        vector<point>::iterator a;
        a = lower_bound(points.begin(), points.end(), point(points[i].x-1, points[i].y-1), compare2);
        if (a->x == points[i].x-1 && a->y == points[i].y-1) add_edge(int(a-points.begin()), i);
        a = lower_bound(points.begin(), points.end(), point(points[i].x, points[i].y-1), compare2);
        if (a->x == points[i].x && a->y == points[i].y-1) add_edge(int(a-points.begin()), i);
        a = lower_bound(points.begin(), points.end(), point(points[i].x+1, points[i].y-1), compare2);
        if (a->x == points[i].x+1 && a->y == points[i].y-1) add_edge(int(a-points.begin()), i);
        a = lower_bound(points.begin(), points.end(), point(points[i].x-1, points[i].y), compare2);
        if (a->x == points[i].x-1 && a->y == points[i].y) add_edge(int(a-points.begin()), i);
    }
    vector<int> time(points.size());
    vector<bool> used(n);
    queue<int> q;
    q.push((int)(lower_bound(points.begin(), points.end(), point(x0, y0), compare2) - points.begin()));
    used[q.front()] = true;
    while(!q.empty()) {
        int v=q.front();
        q.pop();
        for (int i=0; i<graph[v].size(); i++) {
            if (!used[graph[v][i]]) {
                q.push(graph[v][i]);
                time[graph[v][i]] = time[v] + 1;
                used[graph[v][i]] = true;
            }
        }
    }
    int k = time[(int)(lower_bound(points.begin(), points.end(), point(x1, y1), compare2) - points.begin())];
    if (k == 0) cout << -1;
    else cout << k;
}