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,
M
i
,
L
i
and
K
i
.
M
i
is the time required for phone support,
L
i
is the maximum stand by time
until an operator answers the call, and
K
i
is the interval time from hanging up to calling back.
Let us put these in other words: It takes
M
i
unit times for an operator to support
i
-th customer.
If the
i
-th customer is not answered by operators for
L
i
unit times, he hangs up the call.
K
i
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
M
1
L
1
K
1
.
.
.
M
N
L
N
K
N
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,
M
i
,
L
i
and
K
i
(1 ≤
M
i
≤
T
, 1 ≤
L
i
≤ 1000, 1 ≤
K
i
≤ 1000), describing
i
-th customer's
information.
M
i
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

Submitted solutions:

code_snippet: #include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <queue>
#define FI first
#define SE second
using namespace std;
const double EPS = 1e-8;
const int MAXN = 1005;
const int INF = 1111111111;
const double PI = acos(-1.0);
struct Node{
    bool sta;
    int m,l,k;
}node[MAXN];
int t,n;

inline bool check(int m)
{
	int cnt = 0;

	bool flag;
    priority_queue<int,vector<int>,greater<int> >q;
    for(int i = 0; i < m; i++) q.push(0);
    for(int i = 0; i< n; i++) node[i].sta = 0;
    while(1)
	{
		int now,nt = INF,ni;
		now = q.top();
		flag = 0;
		for(int i = 0; i < n; i++)
		{
			if(node[i].sta==0)
			{
				if(now%(node[i].l+node[i].k)<=node[i].l&&now+node[i].m<=t)
				{
					node[i].sta = 1;
					q.pop();
					q.push(now+node[i].m);
					flag = 1,cnt++;
					break;
				}
				else if(nt>(now/(node[i].l+node[i].k)+1)*(node[i].l+node[i].k))
				{
					nt = (now/(node[i].l+node[i].k)+1)*(node[i].l+node[i].k);
					ni = i;
				}
			}
		}
		if(!flag&&node[ni].m+nt<=t)
		{
			node[ni].sta = 1;
			q.pop();
			q.push(node[ni].m+nt);
			flag = 1,cnt++;
		}
		if(!flag) return 0;
		if(cnt==n) return 1;
	}
	return 1;
}

int main()
{
    //freopen("/home/qitaishui/code/in.txt","r",stdin);
    int ans;
    while(scanf("%d%d",&n,&t)&&(n+t))
    {
        for(int i = 0; i < n; i++)
        {
            scanf("%d%d%d",&node[i].m,&node[i].l,&node[i].k);
        }
        for(int i = 1; i <= n; i++)
            if(check(i))
            {
                ans = i;
                break;
            }
        printf("%d\n",ans);
    }
    return 0;
}
accuracy: 1
time_ms: 1630
memory_kb: 3464
final_rank: 9

code_snippet: #include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <algorithm>
#include <stdlib.h>
#include <string>
#include <queue>
#include <vector>
#include <set>
#define maxn 1100
#define oo 1000000000
#define clearAll(a) memset(a,0,sizeof(a))
#define sq(a) ((a)*(a))

using namespace std;

typedef long long ll;

int n,t;

int M[maxn],L[maxn],K[maxn];
int S[maxn];
int T[maxn];
bool vis[maxn];

class cmp
{
	public :
	bool operator() (int x,int y)
	{
		return x>y;
	}
};

bool check(int x)
{
	priority_queue<int,vector<int>,cmp > ser;

	for (int i=1;i<=n;i++)
	{
		S[i]=0;
		T[i]=L[i];
	}

	for (int i=1;i<=x;i++)
		ser.push(0);

	int now = 0;
	int cnt=0;
	int i;
	clearAll(vis);

	while (true)
	{
		now = ser.top(); ser.pop();
		if (now>t) break;

		for (i=1;i<=n;i++)
			if (vis[i]==false)
			while (T[i]<now)
			{
				S[i]=T[i]+K[i];
				T[i]=S[i]+L[i];
				if (S[i]>t) return false;
			}

        int mi = oo;
        for (i=1;i<=n;i++)
            if (!vis[i])
                mi = min(S[i],mi);

        if (now<mi)
            now = mi;

		for (i=1;i<=n;i++)
			if (!vis[i]&&S[i]<=now&&now<=T[i])
				break;

        if (i>n) break;
		if (max(now,S[i])+M[i]>t) return false;
		vis[i] = true;
		cnt++;
		if (cnt==n) return true;
		ser.push(max(now,S[i])+M[i]);
	}

	return (cnt==n);
}

int main()
{
    //freopen("C:\\Users\\py\\Desktop\\input.txt","r",stdin);
    //freopen("C:\\Users\\py\\Desktop\\output.txt","w",stdout);

    while (scanf("%d%d",&n,&t)&&(n||t))
    {
    	for (int i=1;i<=n;i++)
    		scanf("%d%d%d",&M[i],&L[i],&K[i]);

        int l;
        for (int i=1;i<=n;i++)
            if (check(i))
            {
                l = i;
                break;
            }

		printf("%d\n",l);
    }

    return 0;
}
accuracy: 1
time_ms: 6100
memory_kb: 3520
final_rank: 16

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

void Solve(int N, int T) {
    vector<int> M(N), L(N), K(N);
    rep(i,0,N) cin >> M[i] >> L[i] >> K[i];
    auto Judge = [&](int X) -> bool {
        int Res = X;
        vector<int> End(T+1,0);
        set<int> st;
        rep(i,0,N) st.insert(i);
        rep(i,0,T+1) {
            if (st.empty()) break;
            Res += End[i];
            for (auto it = st.begin(); it != st.end();) {
                if (Res == 0) break;
                int j = *it;
                if (i % (L[j]+K[j]) <= L[j]) {
                    int Next = i + M[j];
                    if (Next > T) return false;
                    End[Next]++;
                    Res--;
                    it = st.erase(it);
                }
                else it++;
            }
        }
        if (st.empty()) return true;
        else return false;
    };
    rep(i,1,N+1) {
        if (Judge(i)) {
            cout << i << endl;
            return;
        }
    }
}

int main() {
while(1) {
    int N, T;
    cin >> N >> T;
    if (N == 0) return 0;
    Solve(N,T);
}
}
accuracy: 1
time_ms: 540
memory_kb: 3188
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
#define rep(i,n) for(ll i=0;i<ll(n);i++)

const ll mod = 1e9 + 7;

void solve(ll N,ll T){
    vll M(N),L(N),K(N);
    rep(i,N)cin>>M[i]>>L[i]>>K[i];

    for(ll i=1;i<=N;i++){
        ll cnt=0;
        vll H(T,0);
        H[0]=i;
        vector<bool> US(N,0);
        rep(t,T){
            rep(h,H[t]){
                ll m=1e18,id=-1;
                rep(n,N){
                    if(US[n])continue;
                    if(t%(L[n]+K[n])<=L[n]&&m>t){
                        m=t;
                        id=n;
                        break;
                    }
                    else{
                        ll nt=((t+L[n]+K[n]-1)/(L[n]+K[n]))*(L[n]+K[n]);
                        if(m>nt){
                            m=nt;
                            id=n;
                        }
                    }
                }
                if(m+M[id]>T)break;
                cnt++;
                US[id]=1;
                if(m+M[id]<T)H[m+M[id]]++;
            }
        }
        if(cnt==N){
            cout<<i<<endl;
            return;
        }
    }
}

int main() {
    ll N,T;
    while(cin>>N>>T,N+T!=0)solve(N,T);

}
accuracy: 1
time_ms: 2060
memory_kb: 3104
final_rank: 10

code_snippet: /*	author:  Kite_kuma
	created: 2022.03.03 20:50:51 */

// #ifdef LOCAL
// #define _GLIBCXX_DEBUG
// #endif
#include <bits/stdc++.h>
using namespace std;

#pragma region macros

#define foa(s, v) for(auto &s : v)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define popcnt(n) __builtin_popcountll((long long)n)

#define REPname(a, b, c, d, e, ...) e
#define rep(...) REPname(__VA_ARGS__, REP3, REP2, REP1, REP0)(__VA_ARGS__)
#define REP0(x) for(int Counter_in_rep_macro = 0; Counter_in_rep_macro < (x); ++Counter_in_rep_macro)
#define REP1(i, x) for(int i = 0; i < (x); ++i)
#define REP2(i, l, r) for(int i = (l); i < (r); ++i)
#define REP3(i, l, r, c) for(int i = (l); i < (r); i += (c))

#define DREPname(a, b, c, d, e, ...) e
#define drep(...) DREPname(__VA_ARGS__, DREP3, DREP2, DREP1)(__VA_ARGS__)
#define DREP1(i, x) for(int i = (x)-1; i >= 0; --i)
#define DREP2(i, l, r) for(int i = (r)-1; i >= (l); --i)
#define DREP3(i, l, r, c) for(int i = (r)-1; i >= (l); i -= (c))

#pragma endregion

#pragma region aliases

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = std::vector<int>;
using vvi = std::vector<std::vector<int>>;
using vvvi = std::vector<std::vector<std::vector<int>>>;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vvvll = std::vector<vvll>;
using pii = std::pair<int, int>;
using pll = std::pair<long long, long long>;
template <class T = ll>
using V = std::vector<T>;
template <class T = ll>
using VV = V<V<T>>;
template <class T = ll>
using VVV = V<V<V<T>>>;
template <class T = ll>
using pqup = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <class T = ll>
using pqdn = std::priority_queue<T>;

#pragma endregion

#pragma region constants

const int inf = 1e9;
const long long INF = 1e18;
const long double pi = acos(-1);
const char dl = '\n';
const char sp = ' ';
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};

const int mod_1000000007 = 1000000007;
const int mod_998244353 = 998244353;

#pragma endregion

#pragma region basic_operation

template <class T0, class T1, class T2>
inline bool in_range(T0 x, T1 lef, T2 rig) {
	return ((lef <= x) && (x < rig));
}

template <class T>
inline bool chmin(T &a, T b) {
	if(a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T>
inline bool chmax(T &a, T b) {
	if(a < b) {
		a = b;
		return true;
	}
	return false;
}

void Yes(bool f = 1) { std::cout << (f ? "Yes" : "No") << '\n'; }
void No() { std::cout << "No\n"; }
void YES(bool f = 1) { std::cout << (f ? "YES" : "NO") << '\n'; }
void NO() { std::cout << "NO\n"; }

template <class T>
void drop(T answer) {
	std::cout << answer << '\n';
	exit(0);
}

void err(bool flag = true) {
	if(!flag) return;
	std::cout << -1 << '\n';
	exit(0);
}

template <class T>
void vout(std::vector<T> const &v, bool vertically = 0) {
	if(vertically) {
		for(auto const &a : v) {
			std::cout << a << '\n';
		}
		return;
	}
	for(auto it = v.begin(); it != v.end(); it++) {
		std::cout << (*it);
		if(it != v.end() - 1) {
			std::cout << ' ';
		}
	}
	std::cout << '\n';
	return;
}

inline void print() { std::cout << '\n'; }
template <class T>
inline void print(T x) {
	std::cout << x << '\n';
	return;
}
template <typename Head, typename... Tail>
void print(Head H, Tail... T) {
	std::cout << H << " ";
	print(T...);
}

template <class T>
void add(std::vector<T> &v, T val) {
	for(auto &a : v) a += val;
	return;
}

template <class T>
T dup(T a, T b) {
	assert(b != 0);
	return (a + b - 1) / b;
}

template <class T>
T greatest_lower_multiple(T x, T d) {
	if(d == 0) return 0;
	if(d < 0) d *= -1;
	T y = x % d;
	if(y < 0) y += d;
	return x - y;
}

template <class T>
T least_upper_multiple(T x, T d) {
	return -greatest_lower_multiple(-x, d);
}

long long POW(long long a, long long n) {
	long long res = 1;
	while(n > 0) {
		if(n & 1) res = res * a;
		a = a * a;
		n >>= 1;
	}
	return res;
}

long long modpow(long long a, long long n, long long mod) {	 // a^n mod
	assert(n >= 0 && mod);
	if(mod == 1) return 0LL;
	long long res = 1;
	a %= mod;
	while(n > 0) {
		if(n & 1) res = res * a % mod;
		a = a * a % mod;
		n >>= 1;
	}
	return res < 0 ? res + mod : res;
}

// return x which satisfies a * x % mod == gcd(a, mod)
// not (mod | a)
long long modinv(long long a, long long mod) {
	long long b = mod, u = 1, v = 0;
	while(b) {
		long long t = a / b;
		a -= t * b;
		std::swap(a, b);
		u -= t * v;
		std::swap(u, v);
	}
	u %= mod;
	if(u < 0) u += mod;
	return u;
}

template <class T>
int lb(const std::vector<T> &a, const T x) {
	return std::distance(a.begin(), std::lower_bound(a.begin(), a.end(), x));
}
template <class T>
int ub(const std::vector<T> &a, const T x) {
	return std::distance(a.begin(), std::upper_bound(a.begin(), a.end(), x));
}
template <class T>
void unq_sort(std::vector<T> &a) {
	std::sort(a.begin(), a.end());
	a.erase(std::unique(a.begin(), a.end()), a.end());
}
template <class T>
std::vector<int> press(std::vector<T> &a) {
	auto vec = a;
	unq_sort(vec);
	std::vector<int> ret;
	for(auto &v : a) ret.push_back(lb(vec, v));
	return ret;
}

#pragma endregion

#pragma region input
#define VEC(type, name, size) \
	vector<type> name(size);  \
	scanner::INPUT(name)
#define VVEC(type, name, h, w)                     \
	vector<vector<type>> name(h, vector<type>(w)); \
	scanner::INPUT(name)
#define INT(...)     \
	int __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LL(...)            \
	long long __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define STR(...)        \
	string __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define CHR(...)      \
	char __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define DBL(...)        \
	double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LD(...)              \
	long double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define TPL3(type0, type1, type2, name)   \
	std::tuple<type0, type1, type2> name; \
	scanner::INPUT(name);
#define TPL4(type0, type1, type2, type3, name)   \
	std::tuple<type0, type1, type2, type3> name; \
	scanner::INPUT(name);

namespace scanner {
template <class T>
void scan(T &a) {
	std::cin >> a;
}

template <class T, class L>
void scan(std::pair<T, L> &p) {
	scan(p.first);
	scan(p.second);
}

template <class T0, class T1, class T2>
void scan(std::tuple<T0, T1, T2> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	scan(t0);
	scan(t1);
	scan(t2);
	p = std::make_tuple(t0, t1, t2);
}

template <class T0, class T1, class T2, class T3>
void scan(std::tuple<T0, T1, T2, T3> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	T3 t3;
	scan(t0);
	scan(t1);
	scan(t2);
	scan(t3);
	p = std::make_tuple(t0, t1, t2, t3);
}

template <class T>
void scan(std::vector<T> &a) {
	for(auto &i : a) scan(i);
}

void INPUT() {}
template <class Head, class... Tail>
void INPUT(Head &head, Tail &... tail) {
	scan(head);
	INPUT(tail...);
}
}  // namespace scanner

template <typename T1, typename T2>
std::istream &operator>>(std::istream &is, std::pair<T1, T2> &p) {
	is >> p.first >> p.second;
	return is;
}
#pragma endregion

#pragma region debug

#pragma region output
template <typename T1, typename T2>
std::ostream &std::operator<<(std::ostream &os, const std::pair<T1, T2> &p) {
	os << p.first << " " << p.second;
	return os;
}
template <class T>
std::ostream &std::operator<<(std::ostream &os, const std::vector<T> &v) {
	for(int i = 0; i < (int)v.size(); i++) {
		if(i) os << " ";
		os << v[i];
	}
	return os;
}
#pragma endregion

#pragma region view

namespace viewer {
void view(const long long e) {
	if(e == INF)
		std::cerr << "INF";
	else if(e == -INF)
		std::cerr << "-INF";
	else
		std::cerr << e;
}

void view(const int e) {
	if(e == inf)
		std::cerr << "inf";
	else if(e == -inf)
		std::cerr << "-inf";
	else
		std::cerr << e;
}

template <typename T>
void view(const T e) {
	std::cerr << e;
}

template <typename T, typename U>
void view(const std::pair<T, U> &p) {
	std::cerr << "(";
	view(p.first);
	std::cerr << ", ";
	view(p.second);
	std::cerr << ")";
}

template <class T0, class T1, class T2>
void view(const std::tuple<T0, T1, T2> &p) {
	std::cerr << "(";
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ")";
}

template <class T0, class T1, class T2, class T3>
void view(const std::tuple<T0, T1, T2, T3> &p) {
	std::cerr << "(";
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ", ";
	view(std::get<3>(p));
	std::cerr << ")";
}

template <typename T>
void view(const std::set<T> &s) {
	if(s.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(auto &t : s) {
		view(t);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::unordered_set<T> &s) {
	if(s.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(auto &t : s) {
		view(t);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::vector<T> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(const auto &e : v) {
		view(e);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::vector<std::vector<T>> &vv) {
	std::cerr << "{\n";
	for(const auto &v : vv) {
		std::cerr << "\t";
		view(v);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::vector<std::pair<T, U>> &v) {
	std::cerr << "{\n";
	for(const auto &c : v) {
		std::cerr << "\t(";
		view(c.first);
		std::cerr << ", ";
		view(c.second);
		std::cerr << ")\n";
	}
	std::cerr << "}";
}

template <class T0, class T1, class T2>
void view(const std::vector<std::tuple<T0, T1, T2>> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << '{';
	for(const auto &t : v) {
		std::cerr << "\n\t";
		view(t);
		std::cerr << ",";
	}
	std::cerr << "\n}";
}

template <class T0, class T1, class T2, class T3>
void view(const std::vector<std::tuple<T0, T1, T2, T3>> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << '{';
	for(const auto &t : v) {
		std::cerr << "\n\t";
		view(t);
		std::cerr << ",";
	}
	std::cerr << "\n}";
}

template <typename T, typename U>
void view(const std::map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &t : m) {
		std::cerr << "\t[";
		view(t.first);
		std::cerr << "] : ";
		view(t.second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::unordered_map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &t : m) {
		std::cerr << "\t[";
		view(t.first);
		std::cerr << "] : ";
		view(t.second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}
}  // namespace viewer

#pragma endregion

// when debugging : g++ foo.cpp -DLOCAL
#ifdef LOCAL
void debug_out() {}
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	viewer::view(H);
	std::cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                                \
	do {                                                          \
		std::cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                                   \
		std::cerr << "\b\b]\n";                                   \
	} while(0)
#define dump(x)                                      \
	do {                                             \
		std::cerr << __LINE__ << " " << #x << " : "; \
		viewer::view(x);                             \
		std::cerr << '\n';                           \
	} while(0)

#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif

#pragma endregion

struct call {
	int complete, wait, interval;
	call(int complete, int waite, int interval) : complete(complete), wait(waite), interval(interval) {}
};

int solve(int n) {
	int timelimit;
	cin >> timelimit;

	vector<call> calls;

	debug(n, timelimit);
	rep(n) {
		int a, b, c;
		cin >> a >> b >> c;
		calls.emplace_back(a, b, c);
		debug(a, b, c);
	}

	auto nextcall = [](int time, int wait, int interval) -> int {
		const int loopsize = wait + interval;
		int m = greatest_lower_multiple(time, loopsize);
		assert(m <= time);
		if(time <= m + wait) return time;
		return m + loopsize;
	};

	vector<int> waiting(n, 1);

	auto enough = [&](int supporter) -> bool {
		pqup<int> q;
		rep(supporter) q.push(0);
		waiting.assign(n, 1);
		debug(supporter);
		while(q.size()) {
			pair<int, int> time_id(inf, -1);
			int now = q.top();
			if(now > timelimit) return false;
			q.pop();
			debug(now);
			rep(costomerid, n) {
				if(waiting[costomerid]) {
					const call &cl = calls[costomerid];
					int nxttime = nextcall(now, cl.wait, cl.interval);
					debug(time_id, nxttime, costomerid, cl.wait, cl.interval, cl.complete);
					chmin(time_id, make_pair(nxttime, costomerid));
					if(time_id.first == now) break;
				}
			}
			int nxttime, costomerid;
			tie(nxttime, costomerid) = time_id;
			if(costomerid < 0) continue;
			q.push(nxttime + calls[costomerid].complete);
			waiting[costomerid] = 0;
			// if(n == 9 && supporter == 4) debug(costomerid);
			debug(costomerid);
		}
		return true;
	};

	// int ng = 0;
	// int ok = n;
	// while(ok - ng > 1) {
	// 	int mid = ok + ng;
	// 	mid /= 2;
	// 	if(enough(mid)) {
	// 		ok = mid;
	// 	} else
	// 		ng = mid;
	// }

	rep(person, 1, n) if(enough(person)) return person;
	return n;
}

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout << std::fixed << std::setprecision(15);
	srand((unsigned)time(NULL));

	int n;
	while(cin >> n && n) {
		cout << solve(n) << dl;
	}

	return 0;
}
accuracy: 1
time_ms: 4400
memory_kb: 3348
final_rank: 14

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define eps 1e-9
#define INF 2000000000              // 2e9
#define LLINF 2000000000000000000ll // 2e18 (llmax:9e18)
#define all(x) (x).begin(), (x).end()
#define sq(x) ((x) * (x))

#define rep(i, x) for (int i = 0; i < (int)(x); i++)
#define drep(i, x) for (int i = ((int)(x)-1); i >= 0; i--)

#define popcount __builtin_popcount
#define next __next
#define prev __prev

#ifndef LOCAL
#define dmp(...) ;
#else
#define dmp(...)                                                               \
  cerr << "[ " << #__VA_ARGS__ << " ] : " << dump_str(__VA_ARGS__) << endl
#endif

// ---------------- Utility ------------------

template <class T>
bool chmin(T &a, const T &b) {
  if (a <= b) return false;
  a = b;
  return true;
}

template <class T>
bool chmax(T &a, const T &b) {
  if (a >= b) return false;
  a = b;
  return true;
}

template <class T>
using MaxHeap = priority_queue<T>;

template <class T>
using MinHeap = priority_queue<T, vector<T>, greater<T>>;

template <class T>
vector<T> vect(int len, T elem) {
  return vector<T>(len, elem);
}

// ----------------- Input -------------------

template <class T, class U>
istream &operator>>(istream &is, pair<T, U> &p) {
  return is >> p.first >> p.second;
}

template <class T>
istream &operator>>(istream &is, vector<T> &vec) {
  for (int i = 0; i < vec.size(); i++) is >> vec[i];
  return is;
}

// ----------------- Output ------------------

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  return os << p.first << ',' << p.second;
}

template <class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (const T &e : v) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const deque<T> &d) {
  for (const T &e : d) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const set<T> &s) {
  os << "{ ";
  for (const T &e : s) os << e << " ";
  return os << "}";
}

template <class T, class U>
ostream &operator<<(ostream &os, const map<T, U> &m) {
  os << "{ ";
  for (const auto &[key, val] : m) os << "( " << key << " -> " << val << " ) ";
  return os << "}";
}

template <class TupleTy, size_t... I>
void dump_tuple(ostream &os, const TupleTy t, std::index_sequence<I...>) {
  (..., (os << (I == 0 ? "" : ",") << std::get<I>(t)));
}

template <class... Args>
ostream &operator<<(ostream &os, const tuple<Args...> &t) {
  os << "(";
  dump_tuple(os, t, std::make_index_sequence<sizeof...(Args)>());
  return os << ")";
}

void dump_str_rec(ostringstream &) {}

template <class Head, class... Tail>
void dump_str_rec(ostringstream &oss, Head &&head, Tail &&... tail) {
  oss << ", " << head;
  dump_str_rec(oss, forward<Tail>(tail)...);
}

template <class T, class... U>
string dump_str(T &&arg, U &&... args) {
  ostringstream oss;
  oss << arg;
  dump_str_rec(oss, forward<U>(args)...);
  return oss.str();
}

// --------------- Fast I/O ------------------

void fastio() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  cout << fixed << setprecision(20);
}

// ------------------ ACL --------------------

// #include <atcoder/modint>
// constexpr int MOD = 998244353;
// constexpr int MOD = 1000000007;
// using mint = atcoder::static_modint<MOD>;
// ostream &operator<<(ostream &os, const mint &v) {
//   return os << v.val();
// }

// ------------ End of template --------------

#define endl "\n"
using ll = long long;
using pii = pair<int, int>;

const bool multitest = false;

bool solve() {
  int N, T;
  cin >> N >> T;
  if (N == 0 && T == 0) return false;

  vector<int> M(N), L(N), K(N);
  for (int i = 0; i < N; i++) { cin >> M[i] >> L[i] >> K[i]; }

  auto check = [&](int X) {
    vector<bool> used(N, false);
    MinHeap<int> q;
    for (int i = 0; i < X; i++) { q.push(0); }
    int cnt = 0;
    for (int t = 0; t <= T; t++) {
      for (int j = 0; j < N; j++) {
        if (used[j]) continue;
        if (t % (L[j] + K[j]) <= L[j]) {
          if (q.top() > t) break;
          q.pop();
          q.push(t + M[j]);
          if (t + M[j] > T) return false;
          used[j] = true;
          cnt++;
        }
      }
    }
    if (cnt < N) return false;
    return true;
  };

  for (int i = 1; i < N; i++) {
    if (check(i)) {
      cout << i << endl;
      return true;
    }
  }

  cout << N << endl;
  return true;
}

int main() {
  fastio();
  if (!multitest) {
    while (solve()) {}
  } else {
    cerr << "[Warning] Multi testcase mode on" << endl;
    int t;
    cin >> t;
    while (t--) solve();
  }
  return 0;
}
accuracy: 1
time_ms: 750
memory_kb: 3356
final_rank: 6

code_snippet: #include<iostream>
#include<bitset>
using namespace std;
int N,T;
bitset<1000>B[1000];
int M[1000];
int add[1001];
bool check(int n)
{
	for(int i=0;i<=T;i++)add[i]=0;
	bitset<1000>now;
	for(int i=0;i<N;i++)now[i]=1;
	for(int i=0;i<T;i++)
	{
		n+=add[i];
		if(n==0)continue;
		bitset<1000>tmp=now&B[i];
		while(n>0)
		{
			int id=tmp._Find_first();
			if(id>=1000)break;
			if(i+M[id]<=T)add[i+M[id]]++,tmp[id]=now[id]=0,n--;
			else return false;
		}
	}
	return now.none();
}
int main()
{
	while(cin>>N>>T,N)
	{
		for(int i=0;i<T;i++)B[i].reset();
		for(int i=0;i<N;i++)
		{
			int L,K;
			cin>>M[i]>>L>>K;
			L++;
			K--;
			for(int j=0;j<T;j++)
			{
				if(j%(L+K)<L)B[j][i]=1;
			}
		}
		int t=1;
		while(!check(t))t++;
		cout<<t<<endl;
	}
}
accuracy: 1
time_ms: 60
memory_kb: 3484
final_rank: 2

code_snippet: #pragma GCC ta g("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 510000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
const double pi = acos(-1);
const double eps = 1e-7;
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
//#include <atcoder/maxflow>
//using namespace atcoder;
//const int mod = 1e9 + 7;
const int mod = 998244353;

int main(){
    bitset<1010> can;
    while(1){
        int n,t; cin >> n >> t;
        if(!n) break;
        vl m(n),l(n),k(n);
        rep(i,n) cin >> m[i] >> l[i] >> k[i];
        vector<vvl> ev(2,vvl(t+1));
        rep(i,n){
            for(int j=0; j<=t; j+=l[i]+k[i]){
                ev[0][j].push_back(i);
                if(j+l[i]<=t) ev[1][j+l[i]].push_back(i);
            }
        }
        for(int i=(accumulate(all(m),0)+t-1)/t; i<=n; i++){
            vb done(n,0);
            vector<int> ope(t+1,0);
            ope[0] = i;
            bool f = true;
            rep(j,t+1){
                for(auto x : ev[0][j]) if(!done[x]) can[x] = 1;
                if(j>0) ope[j] += ope[j-1];
                while(ope[j] > 0){
                    int id = can._Find_first();
                    if(id == 1010) break;
                    if(j+m[id] > t){
                        f = false;
                        break;
                    }
                    done[id] = 1;
                    can[id] = 0;
                    ope[j+m[id]]++;
                    ope[j]--;
                }
                for(auto x : ev[1][j]) can[x] = 0; 
            }
            rep(i,n) can[i] = 0;
            rep(j,n){
                if(!done[j]) f = false;
            }
            if(f){
                cout << i << endl;
                break;
            }
        }
    }
}
accuracy: 1
time_ms: 530
memory_kb: 11360
final_rank: 17

code_snippet: #pragma GCC ta g("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 510000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
const double pi = acos(-1);
const double eps = 1e-7;
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
//#include <atcoder/maxflow>
//using namespace atcoder;
//const int mod = 1e9 + 7;
const int mod = 998244353;

int main(){
    while(1){
        int n,t; cin >> n >> t;
        if(!n) break;
        vl m(n),l(n),k(n);
        rep(i,n) cin >> m[i] >> l[i] >> k[i];
        vector<vvl> ev(2,vvl(t+1));
        rep(i,n){
            for(int j=0; j<=t; j+=l[i]+k[i]){
                ev[0][j].push_back(i);
                if(j+l[i]<=t) ev[1][j+l[i]].push_back(i);
            }
        }
        for(int i=(accumulate(all(m),0)+t-1)/t; i<=n; i++){
            vb can(n,0);
            vb done(n,0);
            vector<int> ope(i,0);
            rep(j,t+1){
                for(auto x : ev[0][j]) can[x] = 1;
                vector<int> ls;
                for(int k=n-1; k>=0; k--){
                    if(!done[k] && can[k]) ls.push_back(k);
                }
                rep(j,i){
                    if(ope[j] > 0) ope[j]--;
                    if(ope[j] == 0){
                        if(!ls.empty()){
                            ope[j] = m[ls.back()];
                            done[ls.back()] = 1;
                            ls.pop_back();
                        }
                    }
                }
                for(auto x : ev[1][j]) can[x] = 0; 
            }
            bool f = true;
            rep(j,n){
                if(!done[j]) f = false;
            }
            rep(j,i){
                if(ope[j] > 0) f = false;
            }
            if(f){
                cout << i << endl;
                break;
            }
        }
    }
}
accuracy: 1
time_ms: 3760
memory_kb: 11128
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=1000000007,MAX=1005,INF=1<<30;

vector<pair<int,int>> wh[MAX];

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    while(1){
        int N,T;cin>>N>>T;
        if(N==0) break;
        for(int t=0;t<MAX;t++) wh[t].clear();
        
        for(int i=0;i<N;i++){
            int a,b,c;cin>>a>>b>>c;
            int d=(b+c);
            for(int j=0;j+a<=T;j++){
                if(j%d<=b){
                    wh[j].push_back(mp(i,j+a));
                }
            }
        }
        
        for(int mid=1;mid<=N;mid++){
            vector<int> done(N),revi(T+1);
            int alive=mid;
            for(int t=0;t<=T;t++){
                alive+=revi[t];
                for(auto x:wh[t]){
                    if(alive==0) break;
                    if(done[x.fi]) continue;
                    done[x.fi]=true;
                    alive--;
                    revi[x.se]++;
                }
            }
            bool ok=true;
            for(int i=0;i<N;i++) ok&=done[i];
            if(ok){
                cout<<mid<<"\n";
                break;
            }
        }
    }
    
}
accuracy: 1
time_ms: 600
memory_kb: 11268
final_rank: 18

code_snippet: #include <iostream>
#include <vector>
#include <queue>
#include <tuple>

template <class T>
using MinHeap = std::priority_queue<T, std::vector<T>, std::greater<T>>;

using namespace std;
constexpr int INF = 1 << 30;

bool solve() {
    int n, tmax;
    cin >> n >> tmax;
    if (n == 0) return false;

    vector<tuple<int, int, int>> ts(n);
    for (auto& [m, l, k] : ts) cin >> m >> l >> k;

    auto judge = [&](int p) -> bool {
        MinHeap<int> heap;
        while (p--) heap.push(0);

        vector<bool> done(n, false);
        for (int q = 0; q < n; ++q) {
            auto t = heap.top();
            heap.pop();

            int ni = -1, nt = INF;
            for (int i = 0; i < n; ++i) {
                if (done[i]) continue;

                auto [m, l, k] = ts[i];
                auto p = l + k;

                if (l < t % p) {
                    auto pt = (t + p - 1) / p * p;
                    if (pt < nt) {
                        ni = i;
                        nt = pt;
                    }
                } else {
                    ni = i;
                    nt = t;
                    break;
                }
            }

            done[ni] = true;
            auto [m, l, k] = ts[ni];
            heap.push(nt + m);
        }

        while (!heap.empty()) {
            if (heap.top() > tmax) return false;
            heap.pop();
        }

        return true;
    };

    // int ok = n, ng = 0;
    // while (ok - ng > 1) {
    //     auto mid = (ok + ng) / 2;

    //     if (judge(mid)) {
    //         ok = mid;
    //     } else {
    //         ng = mid;
    //     }
    // }

    // cout << ok << "\n";

    for (int p = 1; p <= n; ++p) {
        if (judge(p)) {
            cout << p << "\n";
            break;
        }
    }
    return true;
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    while (solve()) {}

    return 0;
}
accuracy: 1
time_ms: 4810
memory_kb: 3372
final_rank: 15

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;

int solve(int n, int t, vector<int> &m, vector<int> &l, vector<int> &k){
    for(int i=1; i<n; i++){
        priority_queue<int> wait;
        for(int j=0; j<i; j++){
            wait.push(0);
        }
        vector<bool> used(n, false);
        bool ok = true;
        for(int j=0; j<n and ok; j++){
            int curr = -wait.top();
            wait.pop();
            int mintime = 1e9;
            int minidx = -1;
            for(int r=0; r<n; r++){
                if(used[r]) continue;
                if(curr%(l[r]+k[r]) <= l[r]){
                    used[r] = true;
                    wait.push(-(curr+m[r]));
                    if(curr+m[r] > t) ok = false;
                    break;
                }
                int time = curr +(l[r]+k[r] -curr%(l[r]+k[r]));
                if(time < mintime){
                    mintime = time;
                    minidx = r;
                }
            }
            if((int)wait.size() == i) continue;
            used[minidx] = true;
            wait.push(-(mintime +m[minidx]));
            if(mintime+m[minidx] > t) ok = false;
        }
        if(ok) return i;
    }
    return n;
}

int main(){
    while(1){
        int n,t;
        cin >> n >> t;
        if(n == 0) break;

        vector<int> m(n),l(n),k(n);
        for(int i=0; i<n; i++){
            cin >> m[i] >> l[i] >> k[i];
        }
        cout << solve(n, t, m, l, k) << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 1380
memory_kb: 3064
final_rank: 7

code_snippet: #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<cmath>
#include<algorithm>
#include<map>
#include<queue>
#include<deque>
#include<iomanip>
#include<tuple>
#include<cassert>
#include<set>
#include<bitset>
using namespace std;
typedef long long int LL;
typedef pair<int,int> P;
typedef pair<LL,int> LP;
const int INF=1<<30;
const LL MAX=1e9+7;

void array_show(int *array,int array_n,char middle=' '){
	for(int i=0;i<array_n;i++)printf("%d%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(LL *array,int array_n,char middle=' '){
	for(int i=0;i<array_n;i++)printf("%lld%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(vector<int> &vec_s,int vec_n=-1,char middle=' '){
	if(vec_n==-1)vec_n=vec_s.size();
	for(int i=0;i<vec_n;i++)printf("%d%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}
void array_show(vector<LL> &vec_s,int vec_n=-1,char middle=' '){
	if(vec_n==-1)vec_n=vec_s.size();
	for(int i=0;i<vec_n;i++)printf("%lld%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}

const int B=64,N=1100;
bitset<N> bt[1100];
LL bt2[1100][20];
int t[1100][3];
bitset<N> used;
LL used2[20];

int main(){
	int n,m;
	int i,j,k;
	int a,b,c;
	while(cin>>n>>m){
		if(n==0)break;
		for(i=0;i<=m;i++){
			bt[i].reset();
		}
		memset(bt2,0,sizeof(bt2));
		memset(t,0,sizeof(t));
		for(i=0;i<n;i++){
			for(j=0;j<3;j++){
				cin>>t[i][j];
			}
			for(j=0;j<m;j+=t[i][1]+t[i][2]){
				for(k=0;k<=t[i][1] && j+k<m;k++){
					bt[j+k][i]=1;
					bt2[j+k][i/B]|=1LL<<(i%B);
				}
			}
		}
		for(i=1;i<n;i++){
			vector<int> cnt(m+10,0);
			cnt[0]=i;
			used.reset();
			used.flip();
			memset(used2,-1,sizeof(used2));
			for(j=0;j<m;j++){
				for(k=0,a=0;k<cnt[j];k++){
					if((used&bt[j]).none()){
						cnt[j+1]+=cnt[j]-k;
						break;
					}
					for(;a<20;a++){
						if(used2[a]&bt2[j][a])break;
					}
					b=__builtin_ctzll(used2[a]&bt2[j][a]);
					used2[a]-=1LL<<b;
					c=a*B+b;
					used[c]=0;
					if(j+t[c][0]>m){
						a=-1;break;
					}
					cnt[j+t[c][0]]++;
				}
				if(a==-1)break;
			}
			if(a==-1)continue;
			// for(k=0;k<n;k++){
			// 	cout<<used[k];
			// }
			// cout<<endl;
			for(j=0;j<n;j++){
				if(used[j])break;
			}
			if(j==n)break;
		}
		cout<<i<<endl;
	}
}
accuracy: 1
time_ms: 160
memory_kb: 3352
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> l_l;
typedef pair<int, int> i_i;
template<class T>
inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return true;
    }
    return false;
}

template<class T>
inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return true;
    }
    return false;
}

const long double EPS = 1e-10;
const long long INF = 1e18;
const long double PI = acos(-1.0L);
//const ll mod = 1000000007;
ll N, T;
ll M[1005], L[1005], K[1005];

bool f(ll border) {
    ll op = border;
    ll clear = 0;
    vector<ll> mpop(2020);
    vector<bool> cleared(N);
    for(int t = 0; t <= T; t++) {
        clear += mpop[t];
        op += mpop[t];
        int idx = -1;
        while(op and idx < N) {
            idx++;
            if(idx == N) break;
            if(cleared[idx]) continue;
            //cerr << t << " " << op << " " << idx << endl;
            ll timer = t % (L[idx] + K[idx]);
            if(timer > L[idx]) continue;
            mpop[t+M[idx]]++;
            op--;
            cleared[idx] = true;
        }
    }
    return clear == N;
}

void solve() {
    for(int i = 0; i < N; i++) {
        cin >> M[i] >> L[i] >> K[i];
    }
    for(int i = 1; i <= N; i++) {
        if(f(i)) {
            cout << i << endl;
            return;
        }
    }
}

int main() {
    while(cin >> N >> T) {
        if(N == 0) break;
        solve();
    }
    return 0;
}
accuracy: 1
time_ms: 3180
memory_kb: 3112
final_rank: 11

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 1000000007;
const ll INF = (1e+18) + 7;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acos(-1.0);
//typedef vector<vector<ll>> mat;
typedef vector<int> vec;

ll mod_pow(ll a, ll n, ll m) {
	ll res = 1;
	while (n) {
		if (n & 1)res = res * a%m;
		a = a * a%m; n >>= 1;
	}
	return res;
}

struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n%mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint &a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint &a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint &a, modint b) { a.n = ((ll)a.n*b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, int n) {
	if (n == 0)return modint(1);
	modint res = (a*a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p%a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }

const int max_n = 1 << 18;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}
using mP = pair<modint, modint>;

int dx[4] = { 0,1,0,-1 };
int dy[4] = { 1,0,-1,0 };

int take_first(bitset<1000> bt) {
	int c = bt.count();
	int res = 0;
	per(i, 10) {
		if ((bt >> (1 << i)).count() == c) {
			res += (1 << i);
			bt >>= (1 << i);
		}
	}
	return res;
}

int n, t;
void solve() {
	vector<vector<bool>> exi(n, vector<bool>(t + 1));
	vector<int> m(n);

	vector<bitset<1000>> loc(t + 1);
	rep(i, n) {
		cin >> m[i];
		int l, k; cin >> l >> k;
		int cur = 0;
		while (cur <= t) {
			Rep1(j, cur, cur + l) {
				if (j > t)break;
				exi[i][j] = true;
				loc[j][i] = 1;
			}
			cur += l + k;
		}
	}
	for (int x = 1; x <= n; x++) {
		bitset<1000> rest; rep(i, n)rest[i] = 1;
		vector<int> ad(t + 1, 0);
		int cur = x;
		rep(i, t + 1) {
			cur += ad[i];
			if (cur == 0)continue;
			bitset<1000> bt = rest & loc[i];
			int c = bt.count();
			bool fin = false;
			int len = min(c, cur);
			rep(j, len) {
				int f = bt._Find_first();
				//cout << "! " << x << " " << i << " " << f << endl;
				if (i + m[f] <= t) {
					rest[f] = 0;
					bt[f] = 0;
					cur--;
					ad[i + m[f]]++;
				}
				else {
					fin = true; break;
				}
			}
			if (fin)break;
		}
		bool valid = true;
		rep(i, n)if (rest[i])valid = false;
		if (valid) {
			//cout << "ans is ";
			cout << x << endl; return;
		}
	}
}


signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	//init_f();
	//init();
	//int t; cin >> t; rep(i, t)solve();
	while (cin >> n >> t, n) {
		solve();
	}
	//solve();
	//stop
	return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 7540
final_rank: 12

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 1000000007;
const ll INF = (1e+18) + 7;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acos(-1.0);
//typedef vector<vector<ll>> mat;
typedef vector<int> vec;

ll mod_pow(ll a, ll n, ll m) {
	ll res = 1;
	while (n) {
		if (n & 1)res = res * a%m;
		a = a * a%m; n >>= 1;
	}
	return res;
}

struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n%mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint &a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint &a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint &a, modint b) { a.n = ((ll)a.n*b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, int n) {
	if (n == 0)return modint(1);
	modint res = (a*a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p%a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }

const int max_n = 1 << 18;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}
using mP = pair<modint, modint>;

int dx[4] = { 0,1,0,-1 };
int dy[4] = { 1,0,-1,0 };

int take_first(bitset<1000> bt) {
	int c = bt.count();
	int res = 0;
	per(i, 10) {
		if ((bt >> (1<<i)).count() == c) {
			res += (1 << i);
			bt >>= (1<<i);
		}
	}
	return res;
}

int n, t;
void solve() {
	vector<vector<bool>> exi(n, vector<bool>(t+1));
	vector<int> m(n);

	vector<bitset<1000>> loc(t + 1);
	rep(i, n) {
		cin >> m[i];
		int l, k; cin >> l >> k;
		int cur = 0;
		while (cur <= t) {
			Rep1(j, cur, cur + l) {
				if (j > t)break;
				exi[i][j] = true;
				loc[j][i] = 1;
			}
			cur += l + k;
		}
	}
	for(int x=1;x<=n;x++){
		bitset<1000> rest; rep(i, n)rest[i] = 1;
		vector<int> ad(t + 1, 0);
		int cur = x;
		rep(i, t + 1) {
			cur += ad[i];
			if (cur == 0)continue;
			bitset<1000> bt = rest & loc[i];
			int c = bt.count();
			bool fin = false;
			int len = min(c, cur);
			rep(j, len) {
				int f = take_first(bt);
				//cout << "! " << x << " " << i << " " << f << endl;
				if (i + m[f] <= t) {
					rest[f] = 0;
					bt[f] = 0;
					cur--;
					ad[i + m[f]]++;
				}
				else {
					fin = true; break;
				}
			}
			if (fin)break;
		}
		bool valid = true;
		rep(i, n)if (rest[i])valid = false;
		if (valid) {
			//cout << "ans is ";
			cout << x << endl; return;
		}
	}
}


signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	//init_f();
	//init();
	//int t; cin >> t; rep(i, t)solve();
	while (cin >> n >> t, n) {
		solve();
	}
	//solve();
	//stop
		return 0;
}
accuracy: 1
time_ms: 3860
memory_kb: 7436
final_rank: 19

code_snippet: #include<deque>
#include<queue>
#include<vector>
#include<algorithm>
#include<iostream>
#include<set>
#include<cmath>
#include<tuple>
#include<string>
#include<chrono>
#include<functional>
#include<iterator>
#include<random>
#include<unordered_set>
#include<array>
#include<map>
#include<iomanip>
#include<assert.h>
#include<list>
#include<bitset>
#include<stack>
#include<memory>
#include<numeric>
using namespace std;
using namespace std::chrono;
typedef long long int llint;
typedef long double lldo;
#define mp make_pair
#define mt make_tuple
#define pub push_back
#define puf push_front
#define pob pop_back
#define pof pop_front
#define fir first
#define sec second
#define res resize
#define ins insert
#define era erase
/*cout<<fixed<<setprecision(20);cin.tie(0);ios::sync_with_stdio(false);*/
const int mod=998244353 ;
const llint big=2.19e15+1;
const long double pai=3.141592653589793238462643383279502884197;
const long double eps=1e-4;
template <class T,class U>bool mineq(T& a,U b){if(a>b){a=b;return true;}return false;}
template <class T,class U>bool maxeq(T& a,U b){if(a<b){a=b;return true;}return false;}
llint gcd(llint a,llint b){if(a%b==0){return b;}else return gcd(b,a%b);}
llint lcm(llint a,llint b){if(a==0){return b;}return a/gcd(a,b)*b;}
template<class T> void SO(T& ve){sort(ve.begin(),ve.end());}
template<class T> void REV(T& ve){reverse(ve.begin(),ve.end());}
template<class T>llint LBI(const vector<T>&ar,T in){return lower_bound(ar.begin(),ar.end(),in)-ar.begin();}
template<class T>llint UBI(const vector<T>&ar,T in){return upper_bound(ar.begin(),ar.end(),in)-ar.begin();}

bool solve(void){
	int i,n,j,T;cin>>n>>T;
	if(n==0){return false;}
	static bool call[1001][1001];
	vector<int>M(n),L(n),K(n);
	for(i=0;i<n;i++){cin>>M[i]>>L[i]>>K[i];}
	for(i=0;i<n;i++){
		for(j=0;j<T;j++){call[j][i]=((j%(L[i]+K[i]))<=L[i]);}
	}
	
	int bmin=0,bmax=n;
	while(bmax-bmin>1){
		int bgen=(bmin+bmax)/2;
		int ope=bgen;
		vector<int>owa(T+1);
		vector<bool>finC(n);
		bool can=true;
		for(i=0;i<T;i++){
			ope+=owa[i];
			for(j=0;j<n;j++){
				if(finC[j]||ope==0||(!call[i][j])){continue;}
				if(i+M[j]>T){can=false;break;}
				ope--;
				owa[i+M[j]]++;
				finC[j]=1;
			}
			
		}
		for(j=0;j<n;j++){
			if(!finC[j]){can=false;break;}
		}
		if(can){bmax=bgen;}
		else{bmin=bgen;}
	}
	for(int bgen=bmax-1;bgen>=1&&bmax-bgen<100;bgen-=5){
		int ope=bgen;
		vector<int>owa(T+1);
		vector<bool>finC(n);
		bool can=true;
		for(i=0;i<T;i++){
			ope+=owa[i];
			for(j=0;j<n;j++){
				if(finC[j]||ope==0||(!call[i][j])){continue;}
				if(i+M[j]>T){can=false;break;}
				ope--;
				//cerr<<"i,j"<<i<<' '<<j<<endl;
				owa[i+M[j]]++;
				finC[j]=1;
			}
			
		}
		for(j=0;j<n;j++){
			if(!finC[j]){can=false;break;}
		}
		if(can){bmax=bgen;}
		
	}
	for(int bgen=bmax-1;bgen>=1&&bmax-bgen<100;bgen--){
		int ope=bgen;
		vector<int>owa(T+1);
		vector<bool>finC(n);
		bool can=true;
		for(i=0;i<T;i++){
			ope+=owa[i];
			for(j=0;j<n;j++){
				if(finC[j]||ope==0||(!call[i][j])){continue;}
				if(i+M[j]>T){can=false;break;}
				ope--;
				//cerr<<"i,j"<<i<<' '<<j<<endl;
				owa[i+M[j]]++;
				finC[j]=1;
			}
			
		}
		for(j=0;j<n;j++){
			if(!finC[j]){can=false;break;}
		}
		if(can){bmax=bgen;}
		
	}
	cout<<bmax<<endl;
	return true;
}
int main(void){
	cout<<fixed<<setprecision(20);cin.tie(0);ios::sync_with_stdio(false);
	while(solve()){}
	return 0;
}
accuracy: 1
time_ms: 800
memory_kb: 4092
final_rank: 8

code_snippet: #include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
#include <tuple>
#include <queue>
#include <list>
using namespace std;
// #define fprintf(...) void(0)

bool judge(int N, int T,
           const vector< tuple<int, int, int> > &info, int O) {
    priority_queue< int, vector<int>, greater<int> > op;
    list< pair<int, int> > cs;
    for(int i=0; i<O; i++) op.emplace(0);
    for(int i=0; i<N; i++) cs.emplace_back(0, i);

    // fprintf(stderr, "# num of operators = %d\n", O);
    for(int t=0; t<=T and cs.size(); t++) {
        // customer 選ぶ
        for(auto itr = cs.begin(); itr!=cs.end(); ) {
            int p, k; tie(p, k) = *itr;
            int M, L, K; tie(M, L, K) = info[k];

            bool inc = false;
            if(p <= t and t + M <= T) {
                int o = op.top(); op.pop();
                if(o > t) {
                    // 対応できる operator がいない
                    op.emplace(o);
                    inc = true;
                }
                else {
                    // 対応
                    // fprintf(stderr, "t = %d, customer = %d, op time = %d\n", t, k + 1, o);
                    itr = cs.erase(itr);
                    op.emplace(t + M);
                }
            }
            else if(t + M > T) {
                return false;
            }
            else {
                inc = true;
            }
            
            if(inc) {
                // update time
                if(t - L == p) {
                    // fprintf(stderr, "t = %d, update: customer = %d, time = %d\n", t, k+1, t+K);
                    *itr = make_pair(t+K, k);
                    if(t + K > T) return false;
                }
                itr++;
            }
        }
    }

    return cs.empty();
}

int solve_testcase() {
    int N, T; cin >> N >> T;
    if(N == 0 and T == 0) return 1;

    vector< tuple<int, int, int> > info;
    for(int i=0; i<N; i++) {
        int M, L, K; cin >> M >> L >> K;
        info.emplace_back(M, L, K);
    }

    for(int m=1; m<=N; m++) {
        if(judge(N, T, info, m)) {
            cout << m << endl;
            return 0;
        }
    }
    return 0;
}

int main() {
    while(!solve_testcase());
    return 0;
}
accuracy: 1
time_ms: 3490
memory_kb: 3108
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;

using pii = pair<int, int>;

int main() {
    int n, t;
    while(cin >> n >> t, n) {
        vector<int> m(n), l(n), k(n);
        for(int i = 0; i < n; ++i) {
            cin >> m[i] >> l[i] >> k[i];
        }

        auto check = [&] (int num) {
            vector<int> restore(t + 1);
            list<int> ls;
            for(int i = 0; i < n; ++i) ls.push_back(i);
            int remain = num;
            for(int i = 0; i <= t; ++i) {
                remain += restore[i];
                auto it = ls.begin();
                while(remain > 0 && it != ls.end()) {
                    const int idx = *it;
                    if(i % (l[idx] + k[idx]) <= l[idx]) {
                        --remain;
                        if(i + m[idx] > t) return false;
                        restore[i + m[idx]] += 1;
                        it = ls.erase(it);
                    } else {
                        ++it;
                    }
                }
            }
            return ls.empty();
        };
        for(int i = 1; i <= n; ++i) {
            if(check(i)) {
                cout << i << endl;
                break;
            }
        }
    }
}
accuracy: 1
time_ms: 290
memory_kb: 3064
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

const int N = 1010;

int n,t;
int M[N],L[N],K[N];
int mod[N];

int c[N];
int ed[N];

const int INF = 191919;
inline bool check(int x){
    fill(c,c+N,INF);
    fill(ed,ed+N,0);
    int op = x;

    rep(i,t+1){
        // end operation
        op += ed[i];

        rep(j,n)if(c[j]==INF){
            if(i+M[j]>t) return false;

            int mt = i%mod[j];
            if(mt<=L[j] && op>0){
                --op;
                int et = i+M[j];
                c[j] = et;

                if(et<=t) ++ed[et];
            }
        }
    }

    rep(i,n)if(c[i]>t) return false;
    return true;
}

int main(){
    while(scanf(" %d %d", &n, &t),n){
        rep(i,n){
            scanf(" %d %d %d", &M[i], &L[i], &K[i]);
            mod[i] = (L[i]+K[i]);
        }

        int ok=1;
        while(ok<=n && !check(ok)) ++ok;
        printf("%d\n",ok);
    }
    return 0;
}
accuracy: 1
time_ms: 330
memory_kb: 3116
final_rank: 3