← Home
package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

type BIT struct {
	tree []int
	n    int
}

func newBIT(n int) *BIT {
	return &BIT{
		tree: make([]int, n+1),
		n:    n,
	}
}

func (b *BIT) add(i, delta int) {
	i++
	for i <= b.n {
		b.tree[i] += delta
		i += i & -i
	}
}

func (b *BIT) query(i int) int {
	if i < 0 {
		return 0
	}
	i++
	sum := 0
	for i > 0 {
		sum += b.tree[i]
		i -= i & -i
	}
	return sum
}

type Op struct {
	c1, c2, c3 byte
	p          int
}

func solve() {
	scanner := bufio.NewScanner(os.Stdin)
	buf := make([]byte, 1024*1024)
	scanner.Buffer(buf, 10*1024*1024)
	scanner.Split(bufio.ScanWords)

	if !scanner.Scan() {
		return
	}
	t, _ := strconv.Atoi(scanner.Text())

	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	for tc := 0; tc < t; tc++ {
		if !scanner.Scan() {
			break
		}
		s := scanner.Text()
		n := len(s)

		if n%3 != 0 {
			fmt.Fprintln(out, "NO")
			continue
		}

		valid := true
		for i := 0; i < n-1; i++ {
			if s[i] == s[i+1] {
				valid = false
				break
			}
		}
		if !valid {
			fmt.Fprintln(out, "NO")
			continue
		}

		counts := make(map[byte]int)
		for i := 0; i < n; i++ {
			counts[s[i]]++
		}
		if counts['Y'] != n/3 || counts['D'] != n/3 || counts['X'] != n/3 {
			fmt.Fprintln(out, "NO")
			continue
		}

		prev := make([]int, n)
		next := make([]int, n)
		isRemoved := make([]bool, n)
		inQueue := make([]bool, n)

		for i := 0; i < n; i++ {
			prev[i] = i - 1
			next[i] = i + 1
		}
		next[n-1] = -1

		isValid := func(u int) bool {
			if u == -1 || isRemoved[u] {
				return false
			}
			v := next[u]
			if v == -1 || isRemoved[v] {
				return false
			}
			w := next[v]
			if w == -1 || isRemoved[w] {
				return false
			}

			if s[u] == s[v] || s[v] == s[w] || s[u] == s[w] {
				return false
			}

			p := prev[u]
			nxt := next[w]
			if p != -1 && nxt != -1 && s[p] == s[nxt] {
				return false
			}

			return true
		}

		queue := make([]int, 0)
		for i := 0; i < n; i++ {
			if isValid(i) {
				queue = append(queue, i)
				inQueue[i] = true
			}
		}

		bit := newBIT(n)
		for i := 0; i < n; i++ {
			bit.add(i, 1)
		}

		ops := make([]Op, 0, n/3)
		removedCount := 0

		for head := 0; head < len(queue); head++ {
			u := queue[head]
			inQueue[u] = false

			if !isValid(u) {
				continue
			}

			v := next[u]
			w := next[v]

			idx := bit.query(u - 1)
			ops = append(ops, Op{s[u], s[v], s[w], idx})

			isRemoved[u] = true
			isRemoved[v] = true
			isRemoved[w] = true
			bit.add(u, -1)
			bit.add(v, -1)
			bit.add(w, -1)
			removedCount += 3

			p := prev[u]
			nxt := next[w]

			if p != -1 {
				next[p] = nxt
			}
			if nxt != -1 {
				prev[nxt] = p
			}

			start := nxt
			if start == -1 {
				start = p
			}
			if start != -1 {
				for i := 0; i < 4 && prev[start] != -1; i++ {
					start = prev[start]
				}
				for i := 0; i < 7 && start != -1; i++ {
					if !inQueue[start] && isValid(start) {
						queue = append(queue, start)
						inQueue[start] = true
					}
					start = next[start]
				}
			}
		}

		if removedCount != n {
			fmt.Fprintln(out, "NO")
		} else {
			fmt.Fprintln(out, "YES")
			fmt.Fprintln(out, s)
			for i := len(ops) - 1; i >= 0; i-- {
				op := ops[i]
				fmt.Fprintf(out, "%c %d %c %d %c %d\n", op.c1, op.p, op.c2, op.p+1, op.c3, op.p+2)
			}
		}
	}
}

func main() {
	solve()
}