← Home
package main

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

var scanner *bufio.Scanner

func init() {
	scanner = bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	buf := make([]byte, 1024*1024)
	scanner.Buffer(buf, 10*1024*1024)
}

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

func nextInt64() int64 {
	scanner.Scan()
	res, _ := strconv.ParseInt(scanner.Text(), 10, 64)
	return res
}

type Person struct {
	id      int
	t       int64
	s       int
	f       int
	waiting bool
}

var tree []int

func add(node, l, r, idx, val int) {
	if l == r {
		tree[node] += val
		return
	}
	mid := l + (r-l)/2
	if idx <= mid {
		add(2*node, l, mid, idx, val)
	} else {
		add(2*node+1, mid+1, r, idx, val)
	}
	tree[node] = tree[2*node] + tree[2*node+1]
}

func query(node, l, r, ql, qr int) int {
	if ql > qr {
		return 0
	}
	if l > qr || r < ql {
		return 0
	}
	if ql <= l && r <= qr {
		return tree[node]
	}
	mid := l + (r-l)/2
	return query(2*node, l, mid, ql, qr) + query(2*node+1, mid+1, r, ql, qr)
}

func find_first(node, l, r, ql, qr int) int {
	if ql > qr {
		return -1
	}
	if l > qr || r < ql || tree[node] == 0 {
		return -1
	}
	if l == r {
		return l
	}
	mid := l + (r-l)/2
	res := find_first(2*node, l, mid, ql, qr)
	if res != -1 {
		return res
	}
	return find_first(2*node+1, mid+1, r, ql, qr)
}

func find_last(node, l, r, ql, qr int) int {
	if ql > qr {
		return -1
	}
	if l > qr || r < ql || tree[node] == 0 {
		return -1
	}
	if l == r {
		return l
	}
	mid := l + (r-l)/2
	res := find_last(2*node+1, mid+1, r, ql, qr)
	if res != -1 {
		return res
	}
	return find_last(2*node, l, mid, ql, qr)
}

func main() {
	n := nextInt()
	m := nextInt()

	tree = make([]int, 4*m+4)
	target_lists := make([][]int, m+1)
	people := make([]Person, n)
	sortedPeople := make([]*Person, n)

	for i := 0; i < n; i++ {
		people[i] = Person{
			id:      i,
			t:       nextInt64(),
			s:       nextInt(),
			f:       nextInt(),
			waiting: true,
		}
		sortedPeople[i] = &people[i]
	}

	sort.Slice(sortedPeople, func(i, j int) bool {
		return sortedPeople[i].t < sortedPeople[j].t
	})

	ans := make([]int64, n)

	var active_targets int
	var next_arr int
	T := int64(0)
	X := 1

	for active_targets > 0 || next_arr < n {
		for next_arr < n && sortedPeople[next_arr].t <= T {
			p := sortedPeople[next_arr]
			target_lists[p.s] = append(target_lists[p.s], p.id)
			add(1, 1, m, p.s, 1)
			active_targets++
			next_arr++
		}

		if len(target_lists[X]) > 0 {
			list := target_lists[X]
			target_lists[X] = nil
			for _, pid := range list {
				add(1, 1, m, X, -1)
				p := &people[pid]
				if p.waiting {
					p.waiting = false
					target_lists[p.f] = append(target_lists[p.f], p.id)
					add(1, 1, m, p.f, 1)
				} else {
					ans[p.id] = T
					active_targets--
				}
			}
		}

		if active_targets == 0 {
			if next_arr < n {
				if T < sortedPeople[next_arr].t {
					T = sortedPeople[next_arr].t
				}
				continue
			} else {
				break
			}
		}

		pup := query(1, 1, m, X+1, m)
		pdown := query(1, 1, m, 1, X-1)

		var dir int
		var Y int
		if pup >= pdown {
			dir = 1
			Y = find_first(1, 1, m, X+1, m)
		} else {
			dir = -1
			Y = find_last(1, 1, m, 1, X-1)
		}

		var dist int
		if dir == 1 {
			dist = Y - X
		} else {
			dist = X - Y
		}

		time_to_Y := T + int64(dist)

		if next_arr < n && sortedPeople[next_arr].t < time_to_Y {
			t_arr := sortedPeople[next_arr].t
			dist_moved := int(t_arr - T)
			X = X + dir*dist_moved
			T = t_arr
		} else {
			X = Y
			T = time_to_Y
		}
	}

	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	for i := 0; i < n; i++ {
		fmt.Fprintln(out, ans[i])
	}
}