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()
}