/* Problem URL: https://codeforces.com/contest/920/problem/D */ #include #include #include using namespace std; using namespace __gnu_pbds; template > using ordered_set = tree; #define V vector #define rmin(a, b) a = min(a, b) #define rmax(a, b) a = max(a, b) #define rep(i, lim) for (int i = 0; i < (lim); i++) #define nrep(i, s, lim) for (int i = s; i < (lim); i++) #define repv(i, v) for (auto &i : (v)) #define fillv(v) for (auto &itr_ : (v)) { cin >> itr_; } #define sortv(v) sort(v.begin(), v.end()) #define all(v) (v).begin(), (v).end() using vi = vector; using vvi = vector; using vvvi = vector; using vvvvi = vector; using ll = long long; using vl = vector; using vvl = vector; using vvvl = vector; using vvvvl = vector; template auto operator<<(ostream &os, const vector &vec)->ostream& { os << vec[0]; for (size_t i = 1; i < vec.size(); i++) { os << ' ' << vec[i]; } os << '\n'; return os; } template auto operator>>(istream &is, vector &vec)->istream& { for (auto &i : vec) { is >> i; } return is; } template auto operator<<(ostream &os, const vector> &vec)->ostream& { for (auto &i : vec) { os << i[0]; for (size_t j = 1; j < i.size(); j++) { os << ' ' << i[j]; } os << '\n'; } return os; } template auto operator>>(istream &is, vector> &vec)->istream& { for (auto &i : vec) { for (auto &j : i) { is >> j; } } return is; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, k; ll v; cin >> n >> k >> v; vl a(n); cin >> a; if (v == 0) { cout << "YES\n"; cout << (ll)1e9 << ' ' << 1 << ' ' << 2 << '\n'; return 0; } if (accumulate(all(a), 0LL) < v) { cout << "NO\n"; return 0; } auto printans = [&](V> &ans) { for (auto [c, i, j] : ans) { if (c == 0) { continue; } cout << c << ' ' << i << ' ' << j << '\n'; } }; ll mod = v % k; vi ans; if (mod == 0) { cout << "YES\n"; V> lol; int choice = 0; int other = 1; nrep(i, 1, n) { lol.emplace_back(1e9, i + 1, choice + 1); } lol.emplace_back(v / k, choice + 1, other + 1); printans(lol); return 0; } ll oo = INT64_MAX >> 1; V> dp(n + 1, V(k)); nrep(i, 1, n + 1) { dp[i][a[i - 1] % k] = true; rep(j, k) { dp[i][j] = dp[i][j] || dp[i - 1][j] || dp[i - 1][((j - a[i - 1]) % k + k) % k]; } } auto getans1 = [&](ll mod) { if (!dp[n][mod]) { return false; } int ind = n - 1; int act = mod; while (ind >= 0) { while (dp[ind][act]) { ind--; } if (!dp[ind + 1][act]) { break; } ans.push_back(ind); act = ((act - a[ind]) % k + k) % k; ind--; } return !ans.empty(); }; if (!getans1(mod)) { cout << "NO\n"; return 0; } if (ans.empty()) { cout << "NO\n"; return 0; } // // if (ans.size() == 1) { // ll total = a[ans[0]]; // V> lol; // // ll other = ans[0] == 0 ? 1 : 0; // // rep(i, n) { // if (i == ans[0]) { // continue; // } // // lol.emplace_back(a[i] / k, i + 1, ans[0] + 1); // total += (a[i] / k) * k; // } // // if (total < v) { // cout << "NO\n"; // return 0; // } // // cout << "YES\n"; // ll diff = total - v; // lol.emplace_back(diff / k, ans[0] == 0 ? 2 : 1, ans[0] + 1); // printans(lol); // // return 0; // } // V> lol; set ignore; ignore.insert(ans[0]); nrep(i, 1, ans.size()) { a[ans[0]] += a[ans[i]]; a[ans[i]] = 0; lol.emplace_back(1e9, ans[i] + 1, ans[0] + 1); ignore.insert(ans[i]); } int other = ans[0] == 0 ? 1 : 0; ignore.insert(other); rep(i, n) { if (ignore.count(i)) { continue; } lol.emplace_back(1e9, i + 1, other + 1); a[other] += a[i]; a[i] = 0; } lol.emplace_back(a[other] / k, other + 1, ans[0] + 1); a[ans[0]] += a[other] / k * k; if (a[ans[0]] < v) { cout << "NO\n"; return 0; } ll diff = a[ans[0]] - v; cout << "YES\n"; lol.emplace_back(diff / k, ans[0] + 1, ans[0] == 0 ? 2 : 1); printans(lol); }