← Home
package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

type Segment struct {
	l, r int
}

type Node struct {
	val     int
	idx     int
	lazyVal int
	lazyIdx int
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Buffer(make([]byte, 1024*1024), 64*1024*1024)
	scanner.Split(bufio.ScanWords)

	readInt := func() int {
		scanner.Scan()
		res, _ := strconv.Atoi(scanner.Text())
		return res
	}

	if !scanner.Scan() {
		return
	}
	n, _ := strconv.Atoi(scanner.Text())
	m := readInt()

	rows := make([][]Segment, n+1)
	coords := make([]int, 0, 2*m)

	for k := 0; k < m; k++ {
		i := readInt()
		l := readInt()
		r := readInt()
		rows[i] = append(rows[i], Segment{l, r})
		coords = append(coords, l, r)
	}

	sort.Ints(coords)
	unique := make([]int, 0, len(coords))
	for i, c := range coords {
		if i == 0 || c != coords[i-1] {
			unique = append(unique, c)
		}
	}

	K := len(unique)
	tree := make([]Node, 4*K+1)

	var pushDown func(node int)
	pushDown = func(node int) {
		if tree[node].lazyVal > 0 {
			v, id := tree[node].lazyVal, tree[node].lazyIdx
			if v > tree[2*node].val {
				tree[2*node].val = v
				tree[2*node].idx = id
				tree[2*node].lazyVal = v
				tree[2*node].lazyIdx = id
			}
			if v > tree[2*node+1].val {
				tree[2*node+1].val = v
				tree[2*node+1].idx = id
				tree[2*node+1].lazyVal = v
				tree[2*node+1].lazyIdx = id
			}
			tree[node].lazyVal = 0
			tree[node].lazyIdx = 0
		}
	}

	var query func(node, start, end, l, r int) (int, int)
	query = func(node, start, end, l, r int) (int, int) {
		if l <= start && end <= r {
			return tree[node].val, tree[node].idx
		}
		pushDown(node)
		mid := (start + end) / 2
		maxVal, maxIdx := 0, 0
		if l <= mid {
			v, id := query(2*node, start, mid, l, r)
			if v > maxVal {
				maxVal, maxIdx = v, id
			}
		}
		if r > mid {
			v, id := query(2*node+1, mid+1, end, l, r)
			if v > maxVal {
				maxVal, maxIdx = v, id
			}
		}
		return maxVal, maxIdx
	}

	var update func(node, start, end, l, r, val, idx int)
	update = func(node, start, end, l, r, val, idx int) {
		if l <= start && end <= r {
			if val > tree[node].val {
				tree[node].val = val
				tree[node].idx = idx
				tree[node].lazyVal = val
				tree[node].lazyIdx = idx
			}
			return
		}
		pushDown(node)
		mid := (start + end) / 2
		if l <= mid {
			update(2*node, start, mid, l, r, val, idx)
		}
		if r > mid {
			update(2*node+1, mid+1, end, l, r, val, idx)
		}
		if tree[2*node].val > tree[2*node+1].val {
			tree[node].val = tree[2*node].val
			tree[node].idx = tree[2*node].idx
		} else {
			tree[node].val = tree[2*node+1].val
			tree[node].idx = tree[2*node+1].idx
		}
	}

	dp := make([]int, n+1)
	parent := make([]int, n+1)

	for i := 1; i <= n; i++ {
		if len(rows[i]) == 0 {
			continue
		}
		maxDp, bestJ := 0, 0
		for _, seg := range rows[i] {
			l := sort.SearchInts(unique, seg.l) + 1
			r := sort.SearchInts(unique, seg.r) + 1
			v, id := query(1, 1, K, l, r)
			if v > maxDp {
				maxDp = v
				bestJ = id
			}
		}
		dp[i] = maxDp + 1
		parent[i] = bestJ
		for _, seg := range rows[i] {
			l := sort.SearchInts(unique, seg.l) + 1
			r := sort.SearchInts(unique, seg.r) + 1
			update(1, 1, K, l, r, dp[i], i)
		}
	}

	maxDp := 0
	lastRow := 1
	for i := 1; i <= n; i++ {
		if dp[i] > maxDp {
			maxDp = dp[i]
			lastRow = i
		}
	}

	keep := make([]bool, n+1)
	curr := lastRow
	for curr != 0 {
		keep[curr] = true
		curr = parent[curr]
	}

	remove := make([]int, 0)
	for i := 1; i <= n; i++ {
		if !keep[i] {
			remove = append(remove, i)
		}
	}

	fmt.Println(len(remove))
	out := bufio.NewWriter(os.Stdout)
	for i, r := range remove {
		if i > 0 {
			out.WriteString(" ")
		}
		out.WriteString(strconv.Itoa(r))
	}
	out.WriteString("\n")
	out.Flush()
}