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

import java.awt.Point;
import java.util.*;
import java.io.*;
import static java.lang.Math.*;

public class PracticeProblem
{
    /*
     * This FastReader code is taken from GeeksForGeeks.com
     * https://www.geeksforgeeks.org/fast-io-in-java-in-competitive-programming/
     *
     * The article was written by Rishabh Mahrsee
     */
    public static class FastReader
    {
        BufferedReader br;
        StringTokenizer st;

        public FastReader()
        {
            br = new BufferedReader(new
                    InputStreamReader(System.in));
        }

        String next()
        {
            while (st == null || !st.hasMoreElements())
            {
                try
                {
                    st = new StringTokenizer(br.readLine());
                }
                catch (IOException  e)
                {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt()
        {
            return Integer.parseInt(next());
        }

        long nextLong()
        {
            return Long.parseLong(next());
        }

        double nextDouble()
        {
            return Double.parseDouble(next());
        }

        String nextLine()
        {
            String str = "";
            try
            {
                str = br.readLine();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            return str;
        }
    }

    public static FastReader in = new FastReader();
    public static PrintWriter out = new PrintWriter(System.out);
    public static final int MOD = (int)1e9 + 7;
    public static int[] rDir = {-1, -1, -1, 0, 0, +1, +1, +1};
    public static int[] cDir = {-1, 0, +1, -1, +1, -1, 0, +1};
    public static int MAX = (int)1e9;

    public static void main(String[] args)
    {
        solve();

        out.close();
    }

    public static void solve()
    {
        int startR = in.nextInt(), startC = in.nextInt(), endR = in.nextInt(), endC = in.nextInt();

        Map<Integer, Set<Integer>> map = new HashMap<>();

        int n = in.nextInt();

        for (int i = 0; i < n; i++)
        {
            int r = in.nextInt(), a = in.nextInt(), b = in.nextInt();

            if (!map.containsKey(r))
                map.put(r, new HashSet<>());

            for (int j = a; j <= b ; j++)
            {
                map.get(r).add(j);
            }
        }

        // Do a BFS to find the shortest path from start to end using only the allowed spaces
        Queue<Integer> qR = new LinkedList<>();
        Queue<Integer> qC = new LinkedList<>();
        Set<Point> visited = new HashSet<>();
        int distance = -1;

        qR.add(startR);
        qC.add(startC);

        while (!qR.isEmpty())
        {
            distance++;
            int size = qR.size();
            for (int i = 0; i < size; i++)
            {
                int r = qR.poll();
                int c = qC.poll();

                if (r == endR && c == endC)
                {
                    out.println(distance);
                    return;
                }

                if (visited.contains(new Point(r, c)))
                    continue;

                visited.add(new Point(r, c));

                for (int dir = 0; dir < rDir.length; dir++)  // Foreach neighbor of this point
                {
                    int newR = r + rDir[dir];
                    int newC = c + cDir[dir];

                    if (newR <= MAX && newR >= 1 && newC <= MAX && newC >= 1 && !visited.contains(new Point(newR, newC))) // If this point is in bounds of the field and it has not already been visited
                    {
                        if (map.containsKey(newR) && map.get(newR).contains(newC)) // And If this neighbor is a valid point
                        {
                            // Add it to the queue
                            qR.add(newR);
                            qC.add(newC);
                        }
                    }
                }
            }
        }

        out.println(-1);
    }

}
