package main
import (
"io"
"os"
"strconv"
)
const MOD int64 = 998244353
const MAXN = 500000
type FastScanner struct {
data []byte
idx int
n int
}
func NewFastScanner() *FastScanner {
data, _ := io.ReadAll(os.Stdin)
return &FastScanner{data: data, n: len(data)}
}
func (fs *FastScanner) NextInt() int {
for fs.idx < fs.n {
c := fs.data[fs.idx]
if c == '-' || (c >= '0' && c <= '9') {
break
}
fs.idx++
}
sign := 1
if fs.data[fs.idx] == '-' {
sign = -1
fs.idx++
}
val := 0
for fs.idx < fs.n {
c := fs.data[fs.idx]
if c < '0' || c > '9' {
break
}
val = val*10 + int(c-'0')
fs.idx++
}
return sign * val
}
var inv [MAXN + 1]int64
func comb(d int64, l int) int64 {
if d < 0 {
return 0
}
res := int64(1)
for i := 1; i <= l; i++ {
res = res * ((d + int64(i)) % MOD) % MOD
res = res * inv[i] % MOD
}
return res
}
func main() {
inv[1] = 1
for i := 2; i <= MAXN; i++ {
inv[i] = MOD - (MOD/int64(i))*inv[int(MOD%int64(i))]%MOD
}
fs := NewFastScanner()
t := fs.NextInt()
out := make([]byte, 0, t*12)
var L, R []int
var V []int64
var stack []int
for ; t > 0; t-- {
n := fs.NextInt()
C := int64(fs.NextInt())
if cap(L) < n+1 {
L = make([]int, n+1)
R = make([]int, n+1)
V = make([]int64, n+1)
} else {
L = L[:n+1]
R = R[:n+1]
V = V[:n+1]
}
for i := 1; i <= n; i++ {
L[i] = fs.NextInt()
R[i] = fs.NextInt()
V[i] = int64(fs.NextInt())
}
if cap(stack) < n {
stack = make([]int, 0, n)
} else {
stack = stack[:0]
}
ans := int64(1)
prevPos := 0
prevVal := int64(1)
pos := 0
cur := 1
for cur != -1 || len(stack) > 0 {
for cur != -1 {
stack = append(stack, cur)
cur = L[cur]
}
cur = stack[len(stack)-1]
stack = stack[:len(stack)-1]
pos++
val := V[cur]
if val != -1 {
if val < prevVal {
ans = 0
} else if ans != 0 {
ans = ans * comb(val-prevVal, pos-prevPos-1) % MOD
}
prevPos = pos
prevVal = val
}
cur = R[cur]
}
if prevVal > C {
ans = 0
} else if ans != 0 {
ans = ans * comb(C-prevVal, n-prevPos) % MOD
}
out = strconv.AppendInt(out, ans, 10)
out = append(out, '\n')
}
os.Stdout.Write(out)
}