← Home
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)
	}
}