The only difference between easy and hard versions is constraints.

You are given $n$ segments on the coordinate axis $OX$. Segments can intersect, lie inside each other and even coincide. The $i$-th segment is $[l_i; r_i]$ ($l_i \le r_i$) and it covers all integer points $j$ such that $l_i \le j \le r_i$.

The integer point is called bad if it is covered by strictly more than $k$ segments.

Your task is to remove the minimum number of segments so that there are no bad points at all.


-----Input-----

The first line of the input contains two integers $n$ and $k$ ($1 \le k \le n \le 2 \cdot 10^5$) — the number of segments and the maximum number of segments by which each integer point can be covered.

The next $n$ lines contain segments. The $i$-th line contains two integers $l_i$ and $r_i$ ($1 \le l_i \le r_i \le 2 \cdot 10^5$) — the endpoints of the $i$-th segment.


-----Output-----

In the first line print one integer $m$ ($0 \le m \le n$) — the minimum number of segments you need to remove so that there are no bad points.

In the second line print $m$ distinct integers $p_1, p_2, \dots, p_m$ ($1 \le p_i \le n$) — indices of segments you remove in any order. If there are multiple answers, you can print any of them.


-----Examples-----
Input
7 2
11 11
9 11
7 8
8 9
7 8
9 11
7 9

Output
3
4 6 7 

Input
5 1
29 30
30 30
29 29
28 30
30 30

Output
3
1 4 5 

Input
6 1
2 3
3 3
2 3
2 2
2 3
2 3

Output
4
1 3 5 6

Difficulty: introductory

Starter code:

Solutions:
from operator import itemgetter
import sys
input = sys.stdin.readline


n, m = map(int, input().split())
info = [list(map(int, input().split())) + [i] for i in range(n)]
info = sorted(info, key = itemgetter(1))
max_num = info[-1][1]

N = max_num
INF = 0
LV = (N-1).bit_length()
N0 = 2**LV
data = [0]*(2*N0)
lazy = [0]*(2*N0)

def gindex(l, r):
    L = (l + N0) >> 1; R = (r + N0) >> 1
    lc = 0 if l & 1 else (L & -L).bit_length()
    rc = 0 if r & 1 else (R & -R).bit_length()
    for i in range(LV):
        if rc <= i:
            yield R
        if L < R and lc <= i:
            yield L
        L >>= 1; R >>= 1

def propagates(*ids):
    for i in reversed(ids):
        v = lazy[i-1]
        if not v:
            continue
        lazy[2*i-1] += v; lazy[2*i] += v
        data[2*i-1] += v; data[2*i] += v
        lazy[i-1] = 0

def update(l, r, x):
    *ids, = gindex(l, r)
    propagates(*ids)

    L = N0 + l; R = N0 + r
    while L < R:
        if R & 1:
            R -= 1
            lazy[R-1] += x; data[R-1] += x
        if L & 1:
            lazy[L-1] += x; data[L-1] += x
            L += 1
        L >>= 1; R >>= 1
    for i in ids:
        data[i-1] = max(data[2*i-1], data[2*i])

def query(l, r):
    propagates(*gindex(l, r))
    L = N0 + l; R = N0 + r

    s = INF
    while L < R:
        if R & 1:
            R -= 1
            s = max(s, data[R-1])
        if L & 1:
            s = max(s, data[L-1])
            L += 1
        L >>= 1; R >>= 1
    return s

ans = []
for i in range(n):
    l, r, j = info[i]
    r += 1
    if query(l, r) < m:
        update(l, r, 1)
    else:
        ans.append(j+1)
print(len(ans))
print(*ans)

import heapq

n,k = list(map(int,input().split()))

llis = [ [] for i in range(2 * (10**5) + 1) ]
rlis = [ [] for i in range(2 * (10**5) + 1) ]
flag = [0] * (2 * (10**5) + 1)

for i in range(n):

    l,r = list(map(int,input().split()))
    
    llis[l].append([i+1,r])
    rlis[r].append([i+1,l])

now = 0
rq = []
ans = []
for i in range(2 * (10 ** 5)):
    
    i += 1

    for j in llis[i]:
        now += 1
        ind = j[0]
        r = j[1]
        flag[ind] = 1
        heapq.heappush(rq,[-1 * r,ind])

    for j in rlis[i-1]:
        
        ind = j[0]
        if flag[ind] == 1:
            now -= 1
            flag[ind] = 0

    while now > k:

        nowq = heapq.heappop(rq)
        ind = nowq[1]

        if flag[ind] == 1:
            ans.append(ind)
            now -= 1
            flag[ind] = 0


print(len(ans))
print(" ".join(map(str,ans)))

        


import sys
input = sys.stdin.readline

n,k=list(map(int,input().split()))

S=[tuple(map(int,input().split()))+(i+1,) for i in range(n)]
S.sort()

segtemp=2*10**5
seg_el=1<<((segtemp).bit_length())# Segment treeの台の要素数
SEG=[0]*(2*seg_el)# 1-indexedなので、要素数2*seg_el.Segment treeの初期値で初期化

def getvalue(n,seg_el):# 一点の値を取得
    i=n+seg_el
    ANS=0
    
    ANS+=SEG[i]
    i>>=1# 子ノードへ
    
    while i!=0:
        ANS+=SEG[i]
        i>>=1

    return ANS

def updates(l,r,x):# 区間[l,r)のminを更新.
    L=l+seg_el
    R=r+seg_el

    while L<R:
        if L & 1:
            SEG[L]+=x
            L+=1

        if R & 1:
            R-=1
            SEG[R]+=x
        L>>=1
        R>>=1

ind=0
SH=[]
ANS=[]
import heapq

for point in range(segtemp):
    while ind<n and S[ind][0]<=point:
        l,r,x=S[ind]
        updates(l,r+1,1)
        ind+=1

        heapq.heappush(SH,(-r,l,x))

    #print(getvalue(point,seg_el),SH)

    while getvalue(point,seg_el)>k:
        r,l,x=heapq.heappop(SH)
        r=-r
        ANS.append(x)
        updates(l,r+1,-1)

    #print(point,ANS,getvalue(point,seg_el))
        
print(len(ANS))
print(*ANS)
        


from heapq import *


def main():
    n, k = map(int, input().split())
    E = []
    opent = {}
    for i in range(n):
        l, r = map(int, input().split())
        E.append([l, 1, i])
        E.append([r, -1, i])
        opent[i] = r
    E.sort(key=lambda x: (x[0], -x[1]))
    now_r = []
    heapify(now_r)
    cnt_delet = 0
    ans = []
    deleted = set()
    for x, t, i in E:
        if t == 1:
            heappush(now_r, -(opent[i] * 10 ** 6 + i))
        else:
            if i not in deleted:
                cnt_delet += 1
        if len(now_r) - cnt_delet > k:
            for _ in range(len(now_r) - cnt_delet - k):
                nm = heappop(now_r)
                ind = (-nm) % 10 ** 6
                ans.append(ind + 1)
                deleted.add(ind)
    print(len(ans))
    print(' '.join(list(map(str, ans))))


main()

# -*- coding: utf-8 -*-

import sys

def input(): return sys.stdin.readline().strip()
def list2d(a, b, c): return [[c] * b for i in range(a)]
def list3d(a, b, c, d): return [[[d] * c for j in range(b)] for i in range(a)]
def list4d(a, b, c, d, e): return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]
def ceil(x, y=1): return int(-(-x // y))
def INT(): return int(input())
def MAP(): return list(map(int, input().split()))
def LIST(N=None): return list(MAP()) if N is None else [INT() for i in range(N)]
def Yes(): print('Yes')
def No(): print('No')
def YES(): print('YES')
def NO(): print('NO')
sys.setrecursionlimit(10 ** 7)
INF = 10 ** 18
MOD = 10 ** 9 + 7

class SegTreeIndex:
 
    def __init__(self, n, func, init):

        self.n = n
        self.func = func
        self.init = init
        n2 = 1
        while n2 < n:
            n2 <<= 1
        self.n2 = n2
        self.tree = [self.init] * (n2 << 1)
        self.index = [self.init] * (n2 << 1)
        for i in range(n2):
            self.index[i+n2] = i
        for i in range(n2-1, -1, -1):
            self.index[i] = self.index[i*2]

    def update(self, i, x):

        i += self.n2
        self.tree[i] = x
        while i > 1:
            left, right = min(i, i^1), max(i, i^1)
            if self.func(self.tree[left], self.tree[right]) == self.tree[left]:
                self.tree[i >> 1] = self.tree[left]
                self.index[i >> 1] = self.index[left]
            else:
                self.tree[i >> 1] = self.tree[right]
                self.index[i >> 1] = self.index[right]
            i >>= 1
 
    def query(self, a, b):

        l = a + self.n2
        r = b + self.n2
        s = (self.init, -1)
        while l < r:
            if r & 1:
                r -= 1
                res = self.func(s[0], self.tree[r])
                if res == s[0]:
                    pass
                else:
                    s = (self.tree[r], self.index[r])
            if l & 1:
                res = self.func(self.tree[l], s[0])
                if res == self.tree[l]:
                    s = (self.tree[l], self.index[l])
                else:
                    pass
                l += 1
            l >>= 1
            r >>= 1
        return s

N, K = MAP()
MAX = 200007

LRs = [[] for i in range(MAX+2)]
R = [0] * (N+1)
for i in range(N):
    l, r = MAP()
    LRs[l].append(i+1)
    LRs[r+1].append(-(i+1))
    R[i+1] = r

sti = SegTreeIndex(N+1, max, -INF)
segcnt = 0
ans = []
removed = set()
for i in range(1, MAX+2):
    for idx in LRs[i]:
        if idx > 0:
            sti.update(idx, R[idx])
            segcnt += 1
        else:
            idx = abs(idx)
            if idx not in removed:
                sti.update(idx, -INF)
                segcnt -= 1
    while segcnt > K:
        mx, idx = sti.query(0, N+1)
        sti.update(idx, -INF)
        ans.append(idx)
        removed.add(idx)
        segcnt -= 1
print(len(ans))
print(*ans)


'''
template author-: Pyduper
'''
import sys

# stdin = open("testdata.txt", "r")
# ip = stdin
# def input():
# 	return ip.readline().strip()

def input():
	return sys.stdin.readline().strip()

import heapq
maxn = 200005
def lowbit(x):
	return x&-x
def add(t,i,v):
	while i<len(t):
		t[i]+=v
		i += lowbit(i)
def sum(t,i):
	ans = 0
	while i>0:
		ans += t[i]
		i -= lowbit(i)
	return ans
trees = [0]*maxn
 
n,k = map(int,input().split(" "))
seg = []
points = [0]*maxn
cand = []
for i in range(n):
	l,r = map(int,input().split(" "))
	seg.append((l,r,i+1))
	points[l]   += 1
	points[r+1] -= 1
st = 0
for i in range(maxn):
	st += points[i]
	if st > k:
		cand.append((i,st-k))
 
seg.sort(key = lambda x:(x[0],x[1]))
pq = []
j = 0
ans = []
for i,v in cand:
	v = v-sum(trees,i)
	if v <= 0:
		continue
	while j<n and seg[j][0] <= i:
		heapq.heappush(pq,(-seg[j][1],seg[j][0],seg[j][2]))
		j += 1
 
	for t in range(v):
		r,l,idx = heapq.heappop(pq)
		ans.append(idx)
		add(trees,l,1)
		add(trees,-r+1,-1)
 
print(len(ans))
print(*ans)

# -*- coding: utf-8 -*-

import sys
import bisect
import heapq

line_count = 0
segments = [None]
num_points = 200000
for line in sys.stdin.readlines():
    inputs = line.split()
    if line_count == 0:
        n = int(inputs[0])
        k = int(inputs[1])
        opening = {}
        closing = {}
        removed_right = {}
        segment_index = 0
        for i in range(1, num_points + 1):
            opening[i] = []
            closing[i] = []
            removed_right[i] = 0
    else:
        l = int(inputs[0])
        r = int(inputs[1])
        segment_index += 1
        segments.append((l, r))
        opening[l].append(segment_index)
        closing[r].append(segment_index)
    if line_count == n:
        break
    line_count += 1

working = []
working_count = 0
removed = []
for i in range(1, num_points + 1):
    for segment_index in opening[i]:
        _, r = segments[segment_index]
        heapq.heappush(working, (- r, segment_index))
        working_count += 1
#        bisect.insort_right(working, (r, segment_index))
    while working_count > k:
        r, segment_index = heapq.heappop(working)
#        r, segment_index = working.pop()
        working_count -= 1
        removed.append(segment_index)
        removed_right[- r] += 1
    squeezed_out = len(closing[i]) - removed_right[i]
    working_count -= squeezed_out
#    working = working[squeezed_out: ]

print(len(removed))
for j in removed:
    print(j, end = " ")

import heapq
n, k = list(map(int, input().split()))
length = 2 * (10 ** 5)
llist = [[] for x in range(length + 1)]
rlist = [[] for x in range(length + 1)]
flag = [0] * (length + 1)
for i in range(n):
    l, r = list(map(int, input().split()))
    llist[l].append([i + 1, r])
    rlist[r].append([i + 1, l])
heap = []
ans = []
now = 0
for i in range(length):
    i += 1
    for j in llist[i]:
        now += 1
        currents = j[0]
        r = j[1]
        flag[currents] = 1
        heapq.heappush(heap, [-1 * r, currents])
    for j in rlist[i - 1]:
        currents = j[0]
        if flag[currents] == 1:
            now -= 1
            flag[currents] = 0
    while now > k:
        removing = heapq.heappop(heap)
        currents = removing[1]
        if flag[currents] == 1:
            ans.append(currents)
            now -= 1
            flag[currents] = 0
print(len(ans))
print(" ".join(map(str, ans)))


import heapq

N, K = [int(x) for x in input().split()]
L2RI = [[] for i in range(200000)]
for i in range(N):
    l, r = [int(x) for x in input().split()]
    L2RI[l-1].append([-(r-1), i+1])

ans = []
que = []
heapq.heapify(que)

hist = [0]*200000
exited = 0

for l in range(200000):
    for ri in L2RI[l]:
        heapq.heappush(que, ri)
        hist[-ri[0]] += 1
    while len(que) - exited > K:
        top = heapq.heappop(que)
        hist[-top[0]] -= 1
        ans.append(top[1])
    exited += hist[l]

print(len(ans))
print(*ans)

import sys
from heapq import *
n, k = list(map(int, input().split()))
N = int(2e5+2)
ll = [[] for _ in range(N)]
rr = [[] for _ in range(N)]
vis = [0] * N

for i in range(n):
    l, r = list(map(int, sys.stdin.readline().split()))
    ll[l].append((-r, i+1))
    rr[r].append(i+1)

q = []
ans = []
size = 0

for i in range(1, N):
    for j in ll[i]:
        heappush(q, j)
        size += 1

    while size > k:
        cur = heappop(q)
        while vis[cur[1]]:
            cur = heappop(q)
        vis[cur[1]] = 1
        ans.append(cur[1])
        size -= 1
    for j in rr[i]:
        if not vis[j]:
            vis[j] = 1
            size -= 1

print(len(ans))
print(*ans)




import heapq
 
N, K = [int(x) for x in input().split()]
L2RI = [[] for i in range(200000)]
for i in range(N):
    l, r = [int(x) for x in input().split()]
    L2RI[l-1].append([-(r-1), i+1])
 
ans = []
que = []
heapq.heapify(que)
 
hist = [0]*200000
exited = 0
 
for l in range(200000):
    for ri in L2RI[l]:
        heapq.heappush(que, ri)
        hist[-ri[0]] += 1
    while len(que) - exited > K:
        top = heapq.heappop(que)
        hist[-top[0]] -= 1
        ans.append(top[1])
    exited += hist[l]
 
print(len(ans))
print(*ans)

# DPっぽいな
# 愚直に書く

import sys
reader = (s.rstrip() for s in sys.stdin)
input = reader.__next__

from heapq import heappop, heappush

class RangeAddQuery:
    def __init__(self, n):
        self.n0 = 2**(n-1).bit_length()
        self.data = [0]*(2*self.n0-1)

    def add(self, l,r,v):
        l += self.n0
        r += self.n0
        while l < r:
            if r&1:
                r -= 1
                self.data[r-1] += v
            if l&1:
                self.data[l-1] += v
                l += 1
            l >>=1
            r >>=1

    def query(self, i):
        i += self.n0-1
        res = 0
        while i+1:
            if self.data[i]:
                res += self.data[i]
            i = ~-i//2
        return res

n,k = list(map(int, input().split()))
m = 2*10**5
RAQ = RangeAddQuery(m+10)

segments = []
for i in range(n):
    a,b = list(map(int, input().split()))
    a,b = a-1,b-1
    RAQ.add(a,b+1, 1)
    segments.append((a,b,i+1))

segments.sort()
cursor = 0
# 右端、左端
heap = []
ans = []
# 前からみていく
for i in range(m):
    # segments足すかどうか
    # 全体でO(N)
    while cursor != n and segments[cursor][0] == i:
        # -右端, 左端
        heappush(heap, (-segments[cursor][1], segments[cursor][0], segments[cursor][2]))
        cursor += 1
    cnt = max(0, RAQ.query(i)-k)
    #ans += cnt
    # cnt個セグメントを消さなきゃいけない
    while cnt:
        r,l,p = heappop(heap)
        r = -r
        if r<i:
            continue
        RAQ.add(l, r+1, -1)
        cnt -= 1
        ans.append(p)
print(len(ans))
print(*ans)



import heapq
 
N, K = [int(x) for x in input().split()]
L2RI = [[] for i in range(200000)]
for i in range(N):
    l, r = [int(x) for x in input().split()]
    L2RI[l-1].append([-(r-1), i+1])
 
ans = []
que = []
heapq.heapify(que)
 
hist = [0]*200000
exited = 0
 
for l in range(200000):
    for ri in L2RI[l]:
        heapq.heappush(que, ri)
        hist[-ri[0]] += 1
    while len(que) - exited > K:
        top = heapq.heappop(que)
        hist[-top[0]] -= 1
        ans.append(top[1])
    exited += hist[l]
 
print(len(ans))
print(*ans)

from bisect import bisect_right, bisect_left
# instead of AVLTree
class BITbisect():
    def __init__(self, InputProbNumbers):
        # 座圧
        self.ind_to_co = [-10**18]
        self.co_to_ind = {}
        for ind, num in enumerate(sorted(list(set(InputProbNumbers)))):
            self.ind_to_co.append(num)
            self.co_to_ind[num] = ind+1
        self.max = len(self.co_to_ind)
        self.data = [0]*(self.max+1)
    
    def __str__(self):
        retList = []
        for i in range(1, self.max+1):
            x = self.ind_to_co[i]
            if self.count(x):
                c = self.count(x)
                for _ in range(c):
                    retList.append(x)
        return "[" + ", ".join([str(a) for a in retList]) + "]"
    
    def __getitem__(self, key):
        key += 1
        s = 0
        ind = 0
        l = self.max.bit_length()
        for i in reversed(range(l)):
            if ind + (1<<i) <= self.max:
                if s + self.data[ind+(1<<i)] < key:
                    s += self.data[ind+(1<<i)]
                    ind += (1<<i)
        if ind == self.max or key < 0:
            raise IndexError("BIT index out of range")
        return self.ind_to_co[ind+1]
    
    def __len__(self):
        return self._query_sum(self.max)
    
    def __contains__(self, num):
        if not num in self.co_to_ind:
            return False
        return self.count(num) > 0
    
    # 0からiまでの区間和
    # 左に進んでいく
    def _query_sum(self, i):
        s = 0
        while i > 0:
            s += self.data[i]
            i -= i & -i
        return s

    # i番目の要素にxを足す
    # 上に登っていく
    def _add(self, i, x):
        while i <= self.max:
            self.data[i] += x
            i += i & -i
    
    # 値xを挿入
    def push(self, x):
        if not x in self.co_to_ind:
            raise KeyError("The pushing number didnt initialized")
        self._add(self.co_to_ind[x], 1)
            
    # 値xを削除
    def delete(self, x):
        if not x in self.co_to_ind:
            raise KeyError("The deleting number didnt initialized")
        if self.count(x) <= 0:
            raise ValueError("The deleting number doesnt exist")
        self._add(self.co_to_ind[x], -1)

    # 要素xの個数
    def count(self, x):
        return self._query_sum(self.co_to_ind[x]) - self._query_sum(self.co_to_ind[x]-1)
    
    # 値xを超える最低ind
    def bisect_right(self, x):
        if x in self.co_to_ind:
            i = self.co_to_ind[x]
        else:
            i = bisect_right(self.ind_to_co, x) - 1
        return self._query_sum(i)

    # 値xを下回る最低ind
    def bisect_left(self, x):
        if x in self.co_to_ind:
            i = self.co_to_ind[x]
        else:
            i = bisect_left(self.ind_to_co, x)
        if i == 1:
            return 0
        return self._query_sum(i-1)


import sys
input = sys.stdin.readline
from collections import Counter
MAX = 2*10**5+3

N, K = map(int, input().split())
Query = [list(map(int, input().split())) for _ in range(N)]
A = [[] for _ in range(MAX)]
B = BITbisect(list(range(MAX)))
P = [[] for _ in range(MAX)]
for i, (l, r) in enumerate(Query):
    A[l].append(r)
    P[r].append((l, i+1))

mustL = []
for n in range(MAX):
    for r in A[n]:
        B.push(r)
    while len(B) > 0:
        b = B[0]
        if b < n:
            B.delete(b)
        else:
            break
    l = len(B)
    d = l - K
    if d > 0:
        for _ in range(d):
            b = B[l-1]
            B.delete(b)
            mustL.append(b)
            l -= 1

C = Counter(mustL)
ans = []
for r, c in C.items():
    P[r].sort()
    for i in range(c):
        ans.append(P[r][i][1])
    
print(len(ans))
print(*ans)

class FTree:
    def __init__(self, f):
        self.n = len(f)
        self.ft = [0] * (self.n + 1)

        for i in range(1, self.n + 1):
            self.ft[i] += f[i - 1]
            if i + self.lsone(i) <= self.n:
                self.ft[i + self.lsone(i)] += self.ft[i]

    def lsone(self, s):
        return s & (-s)

    def query(self, i, j):
        if i > 1:
            return self.query(1, j) - self.query(1, j - 1)

        s = 0
        while j > 0:
            s += self.ft[j]
            j -= self.lsone(j)

        return s

    def update(self, i, v):
        while i <= self.n:
            self.ft[i] += v
            i += self.lsone(i)

    def select(self, k):
        lo = 1
        hi = self.n

        for i in range(30):
            mid = (lo + hi) // 2
            if self.query(1, mid) < k:
                lo = mid
            else:
                hi = mid

        return hi

class RUPQ:
    def __init__(self, n):
        self.ftree = FTree([0] * n)

    def query(self, i):
        return self.ftree.query(1, i)

    def update(self, i, j, v):
        self.ftree.update(i, v)
        self.ftree.update(j + 1, -v)

class RURQ:
    def __init__(self, n):
        self.f = FTree([0] * n)
        self.r = RUPQ(n)

    def query(self, i, j):
        if i > 1:
            return self.query(1, j) - self.query(1, i - 1)
        return self.r.query(j) * j - self.f.query(1, j)

    def update(self, i, j, v):
        self.r.update(i, j, v)
        self.f.update(i, v * (i - 1))
        self.f.update(j + 1, -1 * v * j)


# f = [0, 1, 0, 1, 2, 3, 2, 1, 1, 0]
# ft = FTree(f)
# print(ft.query(1, 6) == 7)
# print(ft.query(1, 3) == 1)
# print(ft.select(7) == 6)
# ft.update(5, 1)
# print(ft.query(1, 10) == 12)

# r = RUPQ(10)
# r.update(2, 9, 7)
# r.update(6, 7, 3)
# print(r.query(1) == 0)
# print(r.query(2) == 7)
# print(r.query(3) == 7)
# print(r.query(4) == 7)
# print(r.query(5) == 7)
# print(r.query(6) == 10)
# print(r.query(7) == 10)
# print(r.query(8) == 7)
# print(r.query(9) == 7)
# print(r.query(10) == 0)


import sys, heapq
n, k = [int(i) for i in sys.stdin.readline().split()]

mmn = 1
mmx = 200000
ftree = RUPQ(mmx)
lns = sys.stdin.readlines()
bds = []
qqq = 0
for ln in lns:
    qqq += 1
    t = [int(i) for i in ln.split()]
    t.append(qqq)
    bds.append(t)
    ftree.update(bds[-1][0], bds[-1][1], 1)

# bds.sort(key=lambda a: mmx*a[0] - a[1])
bds.sort()

bind = 0
heap = []
ans = []
for i in range(1, mmx+1):
    while bind < n and bds[bind][0] == i:
        heapq.heappush(heap, (-1*bds[bind][1], bds[bind][2]))
        bind += 1

    while ftree.query(i) > k:
        bd, bnd = heapq.heappop(heap) 
        ans.append(bnd)
        ftree.update(i,-1*bd, -1)
print(len(ans))
print(*ans)

    







# r = RURQ(10)
# r.update(2, 9, 7)
# r.update(6, 7, 3)
# print(r.query(3, 5) == 21)
# print(r.query(7, 8) == 17)

# Example for https://open.kattis.com/problems/fenwick
# from sys import stdin, stdout
#
# def main():
#     n, q = [int(i) for i in stdin.readline().split(' ')]
#     f = FTree([0] * n)
#     for l in stdin.read()[:-1].split('\n'):
#         a = l.split(' ')
#         if a[0] == '?':
#             if a[1] == '0':
#                 stdout.write("0\n")
#             else:
#                 stdout.write("{}\n".format(f.q(1, int(a[1]))))
#         else:
#             f.u(int(a[1]) + 1, int(a[2]))
#
# main()


import sys, heapq
mmx = 200000
ftree = [0]*(mmx+1)
def uu(i, j, v):
    while i <= mmx:
        ftree[i] += v
        i += (i&-i)
    j += 1
    while j <= mmx:
        ftree[j] -= v
        j += (j&-j)
def qq(j):
    s = 0
    while j > 0:
        s += ftree[j]
        j -= (j & -j)
    return s
n, k = [int(i) for i in sys.stdin.readline().split()]
lns = sys.stdin.readlines()
bds = []
for j in range(n):
    t = [int(i) for i in lns[j].split()]
    t.append(j+1)
    bds.append(t)
    uu(bds[-1][0], bds[-1][1], 1)
bds.sort()
bind = 0
heap = []
ans = []
for i in range(1, mmx+1):
    while bind < n and bds[bind][0] == i:
        heapq.heappush(heap, (-1*bds[bind][1], bds[bind][2]))
        bind += 1
    while qq(i) > k:
        bd, bnd = heapq.heappop(heap) 
        ans.append(str(bnd))
        uu(i,-1*bd, -1)
print(len(ans))
print(" ".join(ans))


import heapq
N, K = [int(x) for x in input().split()]
h = [[] for i in range(200000)]
for i in range(N):
    l, r = [int(x) for x in input().split()]
    h[l-1].append([-(r-1), i+1])
g = []
t = []
heapq.heapify(t)
hist = [0]*200000
exited = 0
for l in range(200000):
    for ri in h[l]:
        heapq.heappush(t, ri)
        hist[-ri[0]] += 1
    while len(t) - exited > K:
        top = heapq.heappop(t)
        hist[-top[0]] -= 1
        g.append(top[1])
    exited += hist[l]
print(len(g))
print(*g)

import sys
from heapq import *

n, k = map(int, input().split())
N = int(2e5 + 2)
ll = [[] for _ in range(N)]
rr = [[] for _ in range(N)]
vis = [0] * N

for i in range(n):
    l, r = map(int, sys.stdin.readline().split())
    ll[l].append((-r, i + 1))
    rr[r].append(i + 1)
# print(ll)
# print(rr)

q = []
ans = []
size = 0

for i in range(1, N):
    for j in ll[i]:
        heappush(q, j)
        # print(q)
        size += 1

    while size > k:
        cur = heappop(q)
        # while vis[cur[1]]:
        #     print(vis[cur],"pao")
        #     cur = heappop(q)
        vis[cur[1]] = 1
        ans.append(cur[1])
        size -= 1
    for j in rr[i]:
        if not vis[j]:
            vis[j] = 1
            size -= 1

print(len(ans))
print(*ans)

import sys
from heapq import *
#sys.stdin = open('in', 'r')
#n = int(input())
n,k = list(map(int, input().split()))
seg = []
for i in range(n):
    l, r = list(map(int, input().split()))
    seg.append((l, r, i+1))
seg.sort()
c = 0
res = []
i = 0
hmin = []
hmax = []
rem = set()
while i < n:
    l,r,si = seg[i]
    while i < n and seg[i][0] == l:
        _,r,si = seg[i]
        heappush(hmax, (-r, si))
        heappush(hmin, (r, si))
        i += 1
        c += 1
    while len(hmin) > 0 and hmin[0][0] < l:
        mr,ind = heappop(hmin)
        if ind not in rem:
            c -= 1
    while c > k:
        mr,ind = heappop(hmax)
        res.append(ind)
        rem.add(ind)
        c -= 1
print(len(res))
if len(res) > 0:
    print(' '.join(map(str, res)))
        
        





#sys.stdout.write('YES\n')
#sys.stdout.write(f'{res}\n')
#sys.stdout.write(f'{y1} {x1} {y2} {x2}\n')