package main
import (
"bufio"
"fmt"
"os"
"strconv"
)
type Op struct {
cnt int64
x int
y int
}
func main() {
scanner := bufio.NewScanner(os.Stdin)
buf := make([]byte, 1024*1024)
scanner.Buffer(buf, bufio.MaxScanTokenSize)
scanner.Split(bufio.ScanWords)
scanInt := func() int {
scanner.Scan()
res, _ := strconv.Atoi(scanner.Text())
return res
}
scanInt64 := func() int64 {
scanner.Scan()
res, _ := strconv.ParseInt(scanner.Text(), 10, 64)
return res
}
if !scanner.Scan() {
return
}
n, _ := strconv.Atoi(scanner.Text())
k := scanInt()
v := scanInt64()
a := make([]int64, n+1)
var totalSum int64
for i := 1; i <= n; i++ {
a[i] = scanInt64()
totalSum += a[i]
}
if totalSum < v {
fmt.Println("NO")
return
}
dp := make([]bool, k)
dp[0] = true
choice := make([][]int8, n+1)
for i := range choice {
choice[i] = make([]int8, k)
for j := range choice[i] {
choice[i][j] = -1
}
}
for i := 1; i <= n; i++ {
val := int(a[i] % int64(k))
if val == 0 {
for j := 0; j < k; j++ {
if dp[j] {
choice[i][j] = 0
}
}
continue
}
for j := 0; j < k; j++ {
if dp[j] {
choice[i][j] = 0
}
}
for j := 0; j < k; j++ {
if dp[j] {
nextMod := j + val
if nextMod >= k {
nextMod -= k
}
if choice[i][nextMod] == -1 {
choice[i][nextMod] = 1
}
}
}
for j := 0; j < k; j++ {
if choice[i][j] != -1 {
dp[j] = true
}
}
}
targetMod := int(v % int64(k))
if !dp[targetMod] {
fmt.Println("NO")
return
}
inS := make([]bool, n+1)
curr := targetMod
for i := n; i >= 1; i-- {
if choice[i][curr] == 1 {
inS[i] = true
val := int(a[i] % int64(k))
curr = curr - val
if curr < 0 {
curr += k
}
} else {
inS[i] = false
}
}
var S []int
var T []int
for i := 1; i <= n; i++ {
if inS[i] {
S = append(S, i)
} else {
T = append(T, i)
}
}
var t, u int
if len(S) > 0 {
t = S[0]
} else {
t = 1
}
if len(T) > 0 {
if T[0] != t {
u = T[0]
} else {
u = T[1]
}
} else {
if t != 1 {
u = 1
} else {
u = 2
}
}
var ops []Op
for _, x := range S {
if x != t {
if a[x] > 0 {
cnt := (a[x] + int64(k) - 1) / int64(k)
ops = append(ops, Op{cnt, x, t})
a[t] += a[x]
a[x] = 0
}
}
}
for _, y := range T {
if y != u {
if a[y] > 0 {
cnt := (a[y] + int64(k) - 1) / int64(k)
ops = append(ops, Op{cnt, y, u})
a[u] += a[y]
a[y] = 0
}
}
}
if a[t] < v {
diff := v - a[t]
cnt := diff / int64(k)
if cnt > 0 {
ops = append(ops, Op{cnt, u, t})
a[t] += diff
a[u] -= diff
}
} else if a[t] > v {
diff := a[t] - v
cnt := diff / int64(k)
if cnt > 0 {
ops = append(ops, Op{cnt, t, u})
a[t] -= diff
a[u] += diff
}
}
fmt.Println("YES")
for _, op := range ops {
fmt.Printf("%d %d %d\n", op.cnt, op.x, op.y)
}
}