Problem:
Problem I: Operator

The customer telephone support center of the computer sales company called JAG is now in-
credibly confused. There are too many customers who request the support, and they call the
support center all the time. So, the company wants to figure out how many operators needed
to handle this situation.

For simplicity, let us focus on the following simple simulation.

Let N be a number of customers. The i-th customer has id i, and is described by three numbers,
Mi, Li and Ki. Mi is the time required for phone support, Li is the maximum stand by time
until an operator answers the call, and Ki is the interval time from hanging up to calling back.
Let us put these in other words: It takes Mi unit times for an operator to support i-th customer.
If the i-th customer is not answered by operators for Li unit times, he hangs up the call. Ki
unit times after hanging up, he calls back.

One operator can support only one customer simultaneously. When an operator finish a call, he
can immediately answer another call. If there are more than one customer waiting, an operator
will choose the customer with the smallest id.

At the beginning of the simulation, all customers call the support center at the same time. The
simulation succeeds if operators can finish answering all customers within T unit times.

Your mission is to calculate the minimum number of operators needed to end this simulation
successfully.

Input

The input contains multiple datasets. Each dataset has the following format:

N T

M1 L1 K1

.

.

.

MN LN KN

The first line of a dataset contains two positive integers, N and T (1 ≤ N ≤ 1000, 1 ≤ T ≤ 1000).
N indicates the number of customers in the dataset, and T indicates the time limit of the
simulation.

The following N lines describe the information of customers. The i-th line contains three integers,
Mi, Li and Ki (1 ≤ Mi ≤ T , 1 ≤ Li ≤ 1000, 1 ≤ Ki ≤ 1000), describing i-th customer's
information. Mi indicates the time required for phone support, Li indicates the maximum stand
by time until an operator answers the call, and Ki indicates the is the interval time from hanging
up to calling back.

The end of input is indicated by a line containing two zeros. This line is not part of any dataset
and hence should not be processed.

Output

For each dataset, print the minimum number of operators needed to end the simulation successfully in a line.

Sample Input

3 300
100 50 150
100 50 150
100 50 150
3 300
100 50 150
100 50 150
200 50 150
9 18
3 1 1
3 1 1
3 1 1
4 100 1
5 100 1
5 100 1
10 5 3
10 5 3
1 7 1000
10 18
1 2 3
2 3 4
3 4 5
4 5 6
5 6 7
6 7 8
7 8 9
8 9 10
9 10 11
10 11 12
0 0

Output for the Sample Input

2
3
3
4

Solution in Ruby (judge verdict: Wrong Answer)

class Heap
	require 'forwardable'
	extend Forwardable

	def initialize
		@array = []
		@index = {}
	end

	def add(obj, key)
		@array << [obj, key]
		@index[obj] = @array.size - 1
		lift_up(@array.size - 1)
	end

	def swap(i, j)
		u = @array[i]
		v = @array[j]
		@index[u[0]], @index[v[0]] = j, i
		@array[i], @array[j] = v, u
	end

	def lift_up(i)
		return if i == 0
		j = (i - 1) / 2
		if (@array[i][1] <=> @array[j][1]) < 0
			swap(i, j)
			lift_up(j)
		end
	end

	def del_min
		raise "heap is empty!" if empty?
		min = @array[0]
		if size > 1
			swap(0, @array.size-1)
			@array.pop
			lift_down(0)
		else
			@array.pop
		end
		@index.delete(min[0])
		min
	end

	def inc_key(obj, diff)
		i = @index[obj]
		@array[i][1] += diff
		lift_down(i)
	end

	def dec_key(obj, diff)
		i = @index[obj]
		@array[i][1] -= diff
		lift_up(i)
	end

	def del(obj)
		dec_key(obj, Float::INFINITY)
		del_min
	end

	def update_key(obj, new_key)
		i = @index[obj]
		return unless i
		return if (new_key <=> @array[i][1]) >= 0
		@array[i][1] = new_key
		lift_up(i)
	end

	def min_obj
		@array[0][0]
	end

	def min_key
		@array[0][1]
	end

	def lift_down(i)
		j = 2 * i + 1
		k = j + 1
		if k >= size
			return if j >= size
			if (@array[i][1] <=> @array[j][1]) > 0
				swap(i, j)
				lift_down(j)
			end
		else
			l = ((@array[j][1] <=> @array[k][1]) < 0 ? j : k)
			if (@array[i][1] <=> @array[l][1]) > 0
				swap(i, l)
				lift_down(l)
			end
		end
	end

	def_delegators :@array, :empty?, :size
end

class Array
	def bsearch_first_index(l = 0, r = size - 1, &pred)
		return nil if l > r
		c = (l + r) / 2 
		if pred[self[c]]
			bsearch_first_index(l, c-1, &pred) || c
		else
			bsearch_first_index(c+1, r, &pred)
		end
	end

	def bsearch_first_item(l = 0, r = size - 1, &pred)
		i = bsearch_first_index(l, r, &pred)
		i ? self[i] : nil
	end

	def bsearch_last_index(l = 0, r = size - 1, &pred)
		return nil if l > r
		c = (l + r) / 2 
		if pred[self[c]]
			bsearch_last_index(c+1, r, &pred) || c
		else
			bsearch_last_index(l, c-1, &pred)
		end
	end

	def bsearch_last_item(l = 0, r = size - 1, &pred)
		i = bsearch_last_index(l, r, &pred)
		i ? self[i] : nil
	end
end

def check(ope_num, customers, deadline)
	queue_heap = Heap.new
	supported = {}
	finished = {}
	working = 0

	start_events = (0..deadline).map { [] }
	giveup_events = (0..deadline).map { [] }
	finish_events = (0..deadline).map { [] }
	start_events[0] = (0..customers.size-1).to_a

	(0..deadline).each do |t|
		start_events[t].each do |id|
			support_time, wait_time, recall_time = customers[id]
			queue_heap.add(id, id)
			gt = t + wait_time
			giveup_events[gt] << id if gt <= deadline
		end

		finish_events[t].each do |id|
			finished[id] = 1
			working -= 1
		end

		until working == ope_num || queue_heap.empty?
			id, _ = queue_heap.del_min
			support_time, wait_time, recall_time = customers[id]
			ft = t + support_time
			finish_events[ft] << id if ft <= deadline
			supported[id] = 1
			working += 1
		end

		giveup_events[t].each do |id|
			next if supported[id]
			support_time, wait_time, recall_time = customers[id]
			queue_heap.del(id)
			st = t + recall_time
			start_events[st] << id if st <= deadline
		end
	end

	return finished.size == customers.size
end

loop do
	n, deadline = gets.split.map(&:to_i)
	break if n == 0
	customers = (1..n).map { gets.split.map(&:to_i) }		
	
	p x = (1..n).to_a.bsearch_first_item {|o| check(o, customers, deadline)}
end