package main
import (
"bufio"
"container/heap"
"fmt"
"os"
"sort"
)
type Edge struct {
to int
rev int
cap int
cost int64
}
type Item struct {
v int
d int64
}
type PQ []Item
func (p PQ) Len() int { return len(p) }
func (p PQ) Less(i, j int) bool { return p[i].d < p[j].d }
func (p PQ) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p *PQ) Push(x interface{}) {
*p = append(*p, x.(Item))
}
func (p *PQ) Pop() interface{} {
old := *p
n := len(old)
x := old[n-1]
*p = old[:n-1]
return x
}
var g [][]Edge
func addEdge(u, v, cap int, cost int64) int {
iu := len(g[u])
iv := len(g[v])
g[u] = append(g[u], Edge{to: v, rev: iv, cap: cap, cost: cost})
g[v] = append(g[v], Edge{to: u, rev: iu, cap: 0, cost: -cost})
return iu
}
func main() {
in := bufio.NewReaderSize(os.Stdin, 1<<20)
out := bufio.NewWriterSize(os.Stdout, 1<<20)
defer out.Flush()
var n, k int
fmt.Fscan(in, &n, &k)
s := make([]int64, n)
e := make([]int64, n)
c := make([]int64, n)
times := make([]int64, 0, 2*n)
for i := 0; i < n; i++ {
var si, ti, ci int64
fmt.Fscan(in, &si, &ti, &ci)
s[i] = si
e[i] = si + ti
c[i] = ci
times = append(times, s[i], e[i])
}
sort.Slice(times, func(i, j int) bool { return times[i] < times[j] })
uniq := times[:0]
for _, x := range times {
if len(uniq) == 0 || uniq[len(uniq)-1] != x {
uniq = append(uniq, x)
}
}
times = uniq
m := len(times)
g = make([][]Edge, m)
for i := 0; i+1 < m; i++ {
addEdge(i, i+1, k, 0)
}
jobU := make([]int, n)
jobIdx := make([]int, n)
for i := 0; i < n; i++ {
u := sort.Search(len(times), func(j int) bool { return times[j] >= s[i] })
v := sort.Search(len(times), func(j int) bool { return times[j] >= e[i] })
jobU[i] = u
jobIdx[i] = addEdge(u, v, 1, -c[i])
}
const INF int64 = 1 << 60
pot := make([]int64, m)
dist0 := make([]int64, m)
for i := 0; i < m; i++ {
dist0[i] = INF
}
dist0[0] = 0
for v := 0; v < m; v++ {
if dist0[v] == INF {
continue
}
for _, ed := range g[v] {
if ed.cap > 0 && dist0[v]+ed.cost < dist0[ed.to] {
dist0[ed.to] = dist0[v] + ed.cost
}
}
}
for i := 0; i < m; i++ {
if dist0[i] < INF {
pot[i] = dist0[i]
}
}
src, sink := 0, m-1
flow := 0
dist := make([]int64, m)
pv := make([]int, m)
pe := make([]int, m)
for flow < k {
for i := 0; i < m; i++ {
dist[i] = INF
pv[i] = -1
pe[i] = -1
}
dist[src] = 0
pq := &PQ{{v: src, d: 0}}
heap.Init(pq)
for pq.Len() > 0 {
it := heap.Pop(pq).(Item)
v := it.v
if it.d != dist[v] {
continue
}
for i, ed := range g[v] {
if ed.cap == 0 {
continue
}
nd := it.d + ed.cost + pot[v] - pot[ed.to]
if nd < dist[ed.to] {
dist[ed.to] = nd
pv[ed.to] = v
pe[ed.to] = i
heap.Push(pq, Item{v: ed.to, d: nd})
}
}
}
if dist[sink] == INF {
break
}
for i := 0; i < m; i++ {
if dist[i] < INF {
pot[i] += dist[i]
}
}
add := k - flow
for v := sink; v != src; v = pv[v] {
u := pv[v]
ei := pe[v]
if g[u][ei].cap < add {
add = g[u][ei].cap
}
}
for v := sink; v != src; v = pv[v] {
u := pv[v]
ei := pe[v]
to := g[u][ei].to
rev := g[u][ei].rev
g[u][ei].cap -= add
g[to][rev].cap += add
}
flow += add
}
ans := make([]int, n)
for i := 0; i < n; i++ {
if g[jobU[i]][jobIdx[i]].cap == 0 {
ans[i] = 1
}
}
for i := 0; i < n; i++ {
if i > 0 {
fmt.Fprint(out, " ")
}
fmt.Fprint(out, ans[i])
}
fmt.Fprintln(out)
}