1 1 1 2
5
1000000000 1 10000
19920401 1188 5566
1000000000 1 10000
1 1 10000
5 100 200
 6 15 7 15
9
6 15 15
7 14 14
6 15 15
9 14 14
7 14 16
6 15 15
6 15 15
7 14 14
8 15 15
 1 1 1000000000 2
5
1000000000 1 10000
19920401 1188 5566
1000000000 1 10000
1 1 10000
5 100 200
 89 29 88 30
16
87 31 31
14 95 95
98 88 89
96 88 88
14 97 97
13 97 98
100 88 88
88 32 32
99 88 89
90 29 29
87 31 31
15 94 96
89 29 29
88 32 32
97 89 89
88 29 30
 30 14 39 19
31
35 7 11
37 11 12
32 13 13
37 5 6
46 13 13
37 14 14
31 13 13
43 13 19
45 15 19
46 13 13
32 17 17
41 14 19
30 14 14
43 13 17
34 16 18
44 11 19
38 13 13
40 12 20
37 16 18
46 16 18
34 10 14
36 9 10
36 15 19
38 15 19
42 13 19
33 14 15
35 15 19
33 17 18
39 12 20
36 5 7
45 12 12
 9 8 7 8
9
10 6 6
10 6 6
7 7 8
9 5 6
8 9 9
9 5 5
9 8 8
8 5 6
9 10 10
 2 1 1 1
2
1 1 2
2 1 2
 13 16 20 10
18
13 16 16
20 10 10
19 10 10
12 15 15
20 10 10
18 11 11
19 10 10
19 10 10
20 10 10
19 10 10
20 10 10
20 10 10
19 10 10
18 11 11
13 16 16
12 15 15
19 10 10
19 10 10

1
 1
 -1
 1
 9
 2
 1
 -1

//package a2oj_ladder_C;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.InputMismatchException;
import java.util.LinkedList;
import java.util.Queue;


public class King242C {

	static class Point {
		int x , y;
		Point(int x , int y) {
			this.x = x;
			this.y = y;
		}	

		boolean equal(Point obj) {
			return obj!=null && obj.x == x && obj.y == y;
		}
	}

	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void sort2D(int a[][]) {

		Arrays.sort(a , new Comparator<int[]>() {
			public int compare(int x[] , int y[]) {
				return x[0] - y[0];
			}
		});

	}

	boolean searchInterval(int a[][] , int key) {
		int n = a.length;
		int l = 0 , r = n-1;
		while(l<=r) {
			int mid = (l+r)/2;
			if(a[mid][0] == key) {
				if(a[mid][1] >= key) return true;
				else return false;
			}
			else if(a[mid][0] > key) r = mid-1;
			else if(a[mid][0] < key && a[mid][1] < key) l = mid+1;
			else if(a[mid][0] < key && a[mid][1] >= key) return true;
		}
		return false;
	}

	int mod = (int)(Math.pow(10,9)+7);
	HashMap<Integer , HashSet<Integer>> visit = new HashMap<>();
	
	boolean visited(Point obj) {
		if(visit.containsKey(obj.x) && visit.get(obj.x).contains(obj.y)) return false;
		return true;
	}
	long dfs(Point obj , Point end , Point parent , HashMap<Integer , int[][]> hm , int c) {

		if(hm.containsKey(obj.x) && searchInterval(hm.get(obj.x), obj.y)
				&& visited(obj)) {
			//out.println(obj.x+" "+obj.y);
			
			
			if(obj.equal(end)) return c;
			else {
				
				if(!visit.containsKey(obj.x)) {
					HashSet<Integer> hs = new HashSet<>();
					hs.add(obj.y);
					visit.put(obj.x, hs);
				}
				else {
					HashSet<Integer> hs = visit.get(obj.x);
					hs.add(obj.y);
					visit.put(obj.x , hs);
				}
				
				long min = Long.MAX_VALUE;
				if(parent == null || (obj.x != parent.x || obj.y+1 != parent.y))
					min = Math.min(min, dfs(new Point(obj.x , obj.y+1) , end , obj , hm , c+1));
				if(parent == null || (obj.x != parent.x || obj.y-1 != parent.y))
					min = Math.min(min, dfs(new Point(obj.x , obj.y-1) , end , obj , hm , c+1));
				if(parent == null || (obj.x+1 != parent.x || obj.y+1 != parent.y))
					min = Math.min(min, dfs(new Point(obj.x+1 , obj.y+1) , end , obj , hm , c+1));
				if(parent == null || (obj.x+1 != parent.x || obj.y-1 != parent.y))
					min = Math.min(min, dfs(new Point(obj.x+1 , obj.y-1) , end , obj , hm , c+1));
				if(parent == null || (obj.x+1 != parent.x || obj.y != parent.y))
					min = Math.min(min, dfs(new Point(obj.x+1 , obj.y) , end , obj , hm , c+1));
				if(parent == null || (obj.x-1 != parent.x || obj.y+1 != parent.y))
					min = Math.min(min, dfs(new Point(obj.x-1 , obj.y+1) , end , obj , hm , c+1));
				if(parent == null || (obj.x-1 != parent.x || obj.y != parent.y))
					min = Math.min(min, dfs(new Point(obj.x-1 , obj.y) , end , obj , hm , c+1));
				if(parent == null || (obj.x-1 != parent.x || obj.y-1 != parent.y))
					min = Math.min(min, dfs(new Point(obj.x-1 , obj.y-1) , end , obj , hm , c+1));
				
				
				return min;
			}
		}
		else return Long.MAX_VALUE;
	}

	void solve()
	{	
		int startx = ni();
		int starty = ni();
		int endx = ni();
		int endy = ni();
		int n = ni();
		HashMap<Integer,int[][]> hm = new HashMap<>();
		HashMap<Integer,Integer> ct = new HashMap<>();
		int a[][] = new int[n][3];

		for(int i = 0 ; i<n ; i++) {
			a[i][0] = ni();
			a[i][1] = ni();
			a[i][2] = ni();
			if(!ct.containsKey(a[i][0])) ct.put(a[i][0], 1);
			else ct.put(a[i][0], ct.get(a[i][0])+1);
		}

		for(int i = 0 ; i<n ; i++) {
			if(!hm.containsKey(a[i][0])) {
				int size = ct.get(a[i][0]);
				int arr[][] = new int[size][2];
				arr[--size][0] = a[i][1];
				arr[size][1] = a[i][2];
				hm.put(a[i][0], arr);
				ct.put(a[i][0], size);
			}
			else {
				int size = ct.get(a[i][0]);
				int arr[][] = hm.get(a[i][0]);
				arr[--size][0] = a[i][1];
				arr[size][1] = a[i][2];
				hm.put(a[i][0], arr);
				ct.put(a[i][0], size);
			}
		}
		
		for(int i : hm.keySet()) {
			sort2D(hm.get(i));
		}


		Point start = new Point(startx , starty);
		Point end = new Point(endx , endy);
		
		//out.println(searchInterval(hm.get(6), 11));
		long min = dfs(start , end , null , hm , 0);
		if(min == Long.MAX_VALUE) out.println(-1);
		else out.println(min);
	}


	void run() throws Exception
	{
		is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		if(!INPUT.isEmpty())tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new King242C().run(); }

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int[][] na(int n , int m)
	{
		int[][] a = new int[n][m];
		for(int i = 0;i < n;i++) 
			for(int j = 0 ; j<m ; j++) a[i][j] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	void display2D(int a[][]) {
		for(int i[] : a) {
			for(int j : i) {
				out.print(j+" ");
			}
			out.println();
		}
	}

	int[][] creategraph(int n , int m) {
		int g[][] = new int[n+1][];

		int from[] = new int[m];
		int to[] = new int[m];
		int ct[] = new int[n+1];

		for(int i = 0 ; i<m; i++) {
			from[i] = ni();
			to[i] = ni();
			ct[from[i]]++;
			ct[to[i]]++;
		}

		int parent[] = new int[n+1];

		for(int i = 0 ; i<n+1 ; i++) g[i] = new int[ct[i]];

		for(int i = 0 ; i<m ; i++) {
			g[from[i]][--ct[from[i]]] = to[i];
			g[to[i]][--ct[to[i]]] = from[i];
		}

		return g;
	}

	static long __gcd(long a, long b)
	{

		if(b == 0) 
		{
			return a;
		}
		else
		{
			return __gcd(b, a % b);
		}
	}

	// To compute x^y under modulo m
	static long power(long x, long y, long p)
	{

		// Initialize result
		long res = 1;

		// Update x if it is more than or
		// equal to p
		x = x % p;

		while (y > 0)
		{

			// If y is odd, multiply x
			// with result
			if (y % 2 == 1)
				res = (res * x) % p;

			// y must be even now
			y = y >> 1; // y = y/2
		x = (x * x) % p;
		}

		return res;
	}

	// Function to find modular 
	// inverse of a under modulo m
	// Assumption: m is prime
	static long modInverse(long a, int m)
	{
		if (__gcd(a, m) != 1) {
			//System.out.print("Inverse doesn't exist");
			return -1;
		}

		else {

			// If a and m are relatively prime, then
			// modulo inverse is a^(m-2) mode m
			//			System.out.println("Modular multiplicative inverse is "
			//											+power(a, m - 2, m));
			return power(a, m - 2, m);
		}
	}

	static long nCrModPFermat(int n, int r,
			int p , long fac[])
	{

		// Base case
		if (r == 0)
			return 1;

		// Fill factorial array so that we
		// can find all factorial of r, n
		// and n-r
		long t = (fac[n]* modInverse(fac[r], p))%p;

		return ( (t* modInverse(fac[n-r], p))% p);
	}


	private static void tr(Object... o) { System.out.println(Arrays.deepToString(o)); }
}
