← Home
For problem statement at 1000-1999/1600-1699/1650-1659/1652/problemD.txt this is a correct solution, but verifier at 1000-1999/1600-1699/1650-1659/1652/verifierD.go ends with all tests passed can you fix the verifier? ```go
package main

import (
	"bufio"
	"io"
	"os"
	"strconv"
)

const MAXA = 200000
const MOD int64 = 998244353

type Edge struct {
	to  int
	num int
	den int
}

type Frame struct {
	v     int
	p     int
	num   int
	den   int
	state int
}

type NodeVal struct {
	v   int
	p   int
	val int64
}

var spf [MAXA + 1]int
var inv [MAXA + 1]int64
var curCnt [MAXA + 1]int
var minCnt [MAXA + 1]int
var seen [MAXA + 1]int

func gcd(a, b int) int {
	for b != 0 {
		a, b = b, a%b
	}
	return a
}

func modPow(a int64, e int) int64 {
	res := int64(1)
	for e > 0 {
		if e&1 == 1 {
			res = res * a % MOD
		}
		a = a * a % MOD
		e >>= 1
	}
	return res
}

func touch(p, id int, used *[]int) {
	if seen[p] != id {
		seen[p] = id
		curCnt[p] = 0
		minCnt[p] = 0
		*used = append(*used, p)
	}
}

func applyEnter(num, den, id int, used *[]int) {
	x := den
	for x > 1 {
		p := spf[x]
		c := 0
		for x%p == 0 {
			x /= p
			c++
		}
		touch(p, id, used)
		curCnt[p] -= c
		if curCnt[p] < minCnt[p] {
			minCnt[p] = curCnt[p]
		}
	}
	x = num
	for x > 1 {
		p := spf[x]
		c := 0
		for x%p == 0 {
			x /= p
			c++
		}
		touch(p, id, used)
		curCnt[p] += c
	}
}

func applyExit(num, den int) {
	x := num
	for x > 1 {
		p := spf[x]
		c := 0
		for x%p == 0 {
			x /= p
			c++
		}
		curCnt[p] -= c
	}
	x = den
	for x > 1 {
		p := spf[x]
		c := 0
		for x%p == 0 {
			x /= p
			c++
		}
		curCnt[p] += c
	}
}

func initData() {
	for i := 2; i <= MAXA; i++ {
		if spf[i] == 0 {
			for j := i; j <= MAXA; j += i {
				if spf[j] == 0 {
					spf[j] = i
				}
			}
		}
	}
	inv[1] = 1
	for i := 2; i <= MAXA; i++ {
		inv[i] = MOD - (MOD/int64(i))*inv[int(MOD%int64(i))]%MOD
	}
}

func main() {
	initData()

	data, _ := io.ReadAll(os.Stdin)
	idx := 0
	readInt := func() int {
		for idx < len(data) && (data[idx] < '0' || data[idx] > '9') {
			idx++
		}
		val := 0
		for idx < len(data) && data[idx] >= '0' && data[idx] <= '9' {
			val = val*10 + int(data[idx]-'0')
			idx++
		}
		return val
	}

	t := readInt()
	out := bufio.NewWriterSize(os.Stdout, 1<<20)
	defer out.Flush()

	for tc := 1; tc <= t; tc++ {
		n := readInt()
		adj := make([][]Edge, n+1)

		for i := 0; i < n-1; i++ {
			u := readInt()
			v := readInt()
			x := readInt()
			y := readInt()
			g := gcd(x, y)
			x /= g
			y /= g
			adj[u] = append(adj[u], Edge{to: v, num: y, den: x})
			adj[v] = append(adj[v], Edge{to: u, num: x, den: y})
		}

		used := make([]int, 0, 64)
		stack := make([]Frame, 0, 2*n)
		stack = append(stack, Frame{v: 1, p: 0, num: 1, den: 1, state: 0})

		for len(stack) > 0 {
			fr := stack[len(stack)-1]
			stack = stack[:len(stack)-1]

			if fr.state == 1 {
				if fr.p != 0 {
					applyExit(fr.num, fr.den)
				}
				continue
			}

			if fr.p != 0 {
				applyEnter(fr.num, fr.den, tc, &used)
			}
			stack = append(stack, Frame{v: fr.v, p: fr.p, num: fr.num, den: fr.den, state: 1})

			for _, e := range adj[fr.v] {
				if e.to == fr.p {
					continue
				}
				stack = append(stack, Frame{v: e.to, p: fr.v, num: e.num, den: e.den, state: 0})
			}
		}

		rootVal := int64(1)
		for _, p := range used {
			if minCnt[p] < 0 {
				rootVal = rootVal * modPow(int64(p), -minCnt[p]) % MOD
			}
		}

		sum := int64(0)
		stack2 := make([]NodeVal, 0, n)
		stack2 = append(stack2, NodeVal{v: 1, p: 0, val: rootVal})

		for len(stack2) > 0 {
			cur := stack2[len(stack2)-1]
			stack2 = stack2[:len(stack2)-1]

			sum += cur.val
			if sum >= MOD {
				sum -= MOD
			}

			for _, e := range adj[cur.v] {
				if e.to == cur.p {
					continue
				}
				nv := cur.val * int64(e.num) % MOD * inv[e.den] % MOD
				stack2 = append(stack2, NodeVal{v: e.to, p: cur.v, val: nv})
			}
		}

		out.WriteString(strconv.FormatInt(sum, 10))
		out.WriteByte('\n')
	}
}
```