http://www.codeforces.com/contest/119/problem/C
// 90 MS
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<stack>
using namespace std;
struct Data {
__int64 a, b, c;
int len, pos; // len是作業量的最大增量,pos記錄當前科目的原始位置
}o[100];
__int64 dp[110][110][110];
pair<int, __int64> pre[110][110][110];
// 分別記錄前驅狀態的科目、作業量增量
int f[110];
int n, m, k;
bool cmp(Data a, Data b) { return a.c < b.c; }
int main() {
while(cin>>n>>m>>k) {
memset(dp, 0, sizeof(dp));
for(int i = 1; i <= m; ++i) {
cin>>o[i].a>>o[i].b>>o[i].c;
o[i].len = o[i].b - o[i].a;
o[i].pos = i;
}
sort(o+1, o+m+1, cmp);
for(int i = 1; i <= m; ++i) {
for(int j = 1; j <= m; ++j)
if(o[j].pos == i) {
f[j] = i; break;
}
}
//------------------------------初始化
for(int i = 1; i <= m; ++i) {
for(int j = 0; j <= o[i].len; ++j) {
dp[1][i][j] = o[i].a + j;
}
}
// 核心DP遞推部分
for(int dep = 1; dep < n; ++dep) {
// 當前已經安排了科目的天數
for(int i = dep+1; i <= m; ++i) {
// 枚舉有可能更新狀態的科目
for(int j = 1; j < i; ++j) {
// 枚舉難度係數更小的科目,嘗試更新第i個科目的狀態
if(o[i].c == o[j].c) continue;
for(int jj = 0; jj <= o[j].len; ++jj) {
// 枚舉第j個科目的作業量爲aj + jj時的狀態
if(dp[dep][j][jj] == 0) continue;
__int64 t = o[j].a + jj;
if(o[i].a <= t+k && t+k <= o[i].b) {
__int64 u = t+k - o[i].a;
if(dp[dep][j][jj] + o[i].a + u > dp[dep+1][i][u]) {
dp[dep+1][i][u] = dp[dep][j][jj] + o[i].a + u;
pre[dep+1][i][u].first = j;
pre[dep+1][i][u].second = jj;
}
}
// 兩種轉移的情況、記錄路徑
if(o[i].a <= t*k && t*k <= o[i].b) {
__int64 u = t*k - o[i].a;
if(dp[dep][j][jj] + o[i].a + u > dp[dep+1][i][u]) {
dp[dep+1][i][u] = dp[dep][j][jj] + o[i].a + u;
pre[dep+1][i][u].first = j;
pre[dep+1][i][u].second = jj;
}
}
}
}
}
}
//-------------------------------------找出作業量最大的狀態
int x, y;
__int64 Max = 0;
for(int i = 1; i <= m; ++i) {
for(int j = 0; j <= o[i].len; ++j) {
//cout<<dp[n][i][j]<<" ";
if(dp[n][i][j] > Max) {
Max = dp[n][i][j];
x = i; y = j;
}
}
//cout<<endl;
}
//------------------------------判斷是否有合適方案,回溯輸出
if(!Max) {
cout<<"NO"<<endl;
continue;
}
cout<<"YES"<<endl;
stack< pair<int, __int64> > sta;
for(int i = n; i >= 1; --i) {
int t1 = x, t2 = y;
x = pre[i][t1][t2].first;
y = pre[i][t1][t2].second;
if(i == 1)
sta.push(make_pair(t1, dp[i][t1][t2]));
else
sta.push(make_pair(t1, dp[i][t1][t2] - dp[i-1][x][y]));
}
while(!sta.empty()) {
cout<<f[sta.top().first]<<" "<<sta.top().second<<endl;
sta.pop();
}
}
return 0;
}