You are given n segments [l_1, r_1], [l_2, r_2], ..., [l_n, r_n]. Each segment has one of two colors: the i-th segment's color is t_i.

Let's call a pair of segments i and j bad if the following two conditions are met:

  * t_i ≠ t_j; 
  * the segments [l_i, r_i] and [l_j, r_j] intersect, embed or touch, i. e. there exists an integer x such that x ∈ [l_i, r_i] and x ∈ [l_j, r_j]. 



Calculate the maximum number of segments that can be selected from the given ones, so that there is no bad pair among the selected ones.

Input

The first line contains a single integer n (1 ≤ n ≤ 2 ⋅ 10^5) — number of segments.

The next n lines contains three integers l_i, r_i, t_i (1 ≤ l_i ≤ r_i ≤ 10^9; t_i ∈ \{1, 2\}) — description of the i-th segment.

Output

Print the maximum number of segments that can be selected, so that there is no bad pair among the selected segments.

Examples

Input


3
1 3 1
4 6 2
2 5 1


Output


2


Input


5
5 8 1
1 3 2
3 4 2
6 6 1
2 10 2


Output


4


Input


7
19 20 1
13 15 2
6 11 2
4 10 1
14 17 1
13 13 2
5 9 1


Output


5
/**
 * author: derrick20
 * created: 9/4/20 8:06 PM
 */
import java.io.*;
import java.util.*;

public class BicoloredMatching implements Runnable {
    public static void main(String[] args) throws Exception {
        new Thread(null, new BicoloredMatching(), ": )", 1 << 28).start();
    }

    public void run() {
        FastScanner sc = new FastScanner();
        PrintWriter out = new PrintWriter(System.out);

        int N = sc.nextInt();
        int[] left = new int[N];
        int[] right = new int[N];
        int[] type = new int[N];
        for (int i = 0; i < N; i++) {
            left[i] = sc.nextInt();
            right[i] = sc.nextInt();
            type[i] = sc.nextInt() - 1;
        }
        Event[] events = new Event[2 * N];
        Arrays.setAll(events, i -> new Event(i / 2, i % 2 == 0 ? left[i / 2] : right[i / 2], i % 2 == 0 ? -1 : 1));
        Arrays.sort(events, (a, b) -> a.pos != b.pos ? Integer.compare(a.pos, b.pos) : Integer.compare(a.open, b.open));
        int ptr = 0;
        TreeMap<Integer, TreeSet<Integer>>[] segs = new TreeMap[2];
        Arrays.setAll(segs, i -> new TreeMap<>());
        boolean[] matched = new boolean[N];
        int matchingSize = 0;
        while (ptr < 2 * N) {
            int curr = events[ptr].pos;
            while (ptr < 2 * N && events[ptr].pos <= curr) {
//                System.out.println("0: " + segs[0]);
//                System.out.println("1: " + segs[1]);
                int id = events[ptr].id;
                int open = events[ptr].open;
//                System.out.println(type[id]);
                if (matched[id]) {
                    ptr++;
                    continue;
                }
                TreeMap<Integer, TreeSet<Integer>> group = segs[type[id]];
                TreeMap<Integer, TreeSet<Integer>> oppGroup = segs[1 - type[id]];
                TreeSet<Integer> mySet = group.computeIfAbsent(right[id], key -> new TreeSet<>());
                if (open == -1) {
                    mySet.add(id);
                } else {
                    if (!matched[id]) {
                        mySet.remove(id);
                        if (mySet.size() == 0) {
                            group.remove(right[id]);
                        }
                        // find the leftmost right endpoint available.
                        // by way of our sweeping method, right endpoints, if they
                        // exist, must have been processed if to the left.
                        // Any right endpoint to the right of us that has been added
                        // implies that their left point occurred earlier, so by definition
                        // it intersects! It's optimal to match with anything that's tightly
                        // hugging our current interval, so this works.
                        Integer match = oppGroup.ceilingKey(right[id]);
                        if (match != null) {
                            ASSERT(oppGroup.get(match).size() > 0);
                            int matchId = oppGroup.get(match).pollFirst();
//                            System.out.println("Matched " + id + " with " + matchId);
                            if (oppGroup.get(match).size() == 0) {
                                oppGroup.remove(match);
                            }
                            matched[matchId] = true;
                            matchingSize++;
                        }
                    }
                }
                ptr++;
            }
        }
        out.println(N - matchingSize);
        out.close();
    }

    static class Event {
        int id; int pos; int open;
        public Event(int ii, int pp, int oo) {
            id = ii; pos = pp; open = oo;
        }
        public String toString() {
             return "(" + id + ", " + pos + " = " + open + ")";
        }
    }

    static class FastScanner {
        private int BS = 1 << 16;
        private char NC = (char) 0;
        private byte[] buf = new byte[BS];
        private int bId = 0, size = 0;
        private char c = NC;
        private double cnt = 1;
        private BufferedInputStream in;

        public FastScanner() {
            in = new BufferedInputStream(System.in, BS);
        }

        public FastScanner(String s) {
            try {
                in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
            } catch (Exception e) {
                in = new BufferedInputStream(System.in, BS);
            }
        }

        private char getChar() {
            while (bId == size) {
                try {
                    size = in.read(buf);
                } catch (Exception e) {
                    return NC;
                }
                if (size == -1) return NC;
                bId = 0;
            }
            return (char) buf[bId++];
        }

        public int nextInt() {
            return (int) nextLong();
        }

        public int[] nextInts(int N) {
            int[] res = new int[N];
            for (int i = 0; i < N; i++) {
                res[i] = (int) nextLong();
            }
            return res;
        }

        public long[] nextLongs(int N) {
            long[] res = new long[N];
            for (int i = 0; i < N; i++) {
                res[i] = nextLong();
            }
            return res;
        }

        public long nextLong() {
            cnt = 1;
            boolean neg = false;
            if (c == NC) c = getChar();
            for (; (c < '0' || c > '9'); c = getChar()) {
                if (c == '-') neg = true;
            }
            long res = 0;
            for (; c >= '0' && c <= '9'; c = getChar()) {
                res = (res << 3) + (res << 1) + c - '0';
                cnt *= 10;
            }
            return neg ? -res : res;
        }

        public double nextDouble() {
            double cur = nextLong();
            return c != '.' ? cur : cur + nextLong() / cnt;
        }

        public double[] nextDoubles(int N) {
            double[] res = new double[N];
            for (int i = 0; i < N; i++) {
                res[i] = nextDouble();
            }
            return res;
        }

        public String next() {
            StringBuilder res = new StringBuilder();
            while (c <= 32) c = getChar();
            while (c > 32) {
                res.append(c);
                c = getChar();
            }
            return res.toString();
        }

        public String nextLine() {
            StringBuilder res = new StringBuilder();
            while (c <= 32) c = getChar();
            while (c != '\n') {
                res.append(c);
                c = getChar();
            }
            return res.toString();
        }

        public boolean hasNext() {
            if (c > 32) return true;
            while (true) {
                c = getChar();
                if (c == NC) return false;
                else if (c > 32) return true;
            }
        }
    }
    static void ASSERT(boolean assertion, String message) {
        if (!assertion) throw new AssertionError(message);
    }
    static void ASSERT(boolean assertion) {
        if (!assertion) throw new AssertionError();
    }
}