You are given four positive integers $$$n$$$, $$$m$$$, $$$a$$$, $$$b$$$ ($$$1 \le b \le n \le 50$$$; $$$1 \le a \le m \le 50$$$). Find any such rectangular matrix of size $$$n \times m$$$ that satisfies all of the following conditions:  each row of the matrix contains exactly $$$a$$$ ones;  each column of the matrix contains exactly $$$b$$$ ones;  all other elements are zeros. If the desired matrix does not exist, indicate this.For example, for $$$n=3$$$, $$$m=6$$$, $$$a=2$$$, $$$b=1$$$, there exists a matrix satisfying the conditions above:$$$$$$ \begin{vmatrix} 0 & 1 & 0 & 0 & 0 & 1 \\ 1 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 & 1 & 0 \end{vmatrix} $$$$$$

The first line contains an integer $$$t$$$ ($$$1 \le t \le 1000$$$) — the number of test cases. Then $$$t$$$ test cases follow. Each test case is described by four positive integers $$$n$$$, $$$m$$$, $$$a$$$, $$$b$$$ ($$$1 \le b \le n \le 50$$$; $$$1 \le a \le m \le 50$$$), where $$$n$$$ and $$$m$$$ are the sizes of the matrix, and $$$a$$$ and $$$b$$$ are the number of ones for rows and columns, respectively.

For each test case print:   "YES" (without quotes) and the required matrix (if there are several answers, print any) if it exists, or  "NO" (without quotes) if it does not exist.  To print the matrix $$$n \times m$$$, print $$$n$$$ rows, each of which consists of $$$m$$$ numbers $$$0$$$ or $$$1$$$ describing a row of the matrix. Numbers must be printed without spaces.

/*
URL:
https://codeforces.com/contest/1360/problem/G
*/

package main

import (
	"bufio"
	"errors"
	"fmt"
	"io"
	"math"
	"os"
	"strconv"
)

/********** FAU standard libraries **********/

//fmt.Sprintf("%b\n", 255) 	// binary expression

/********** I/O usage **********/

//str := ReadString()
//i := ReadInt()
//X := ReadIntSlice(n)
//S := ReadRuneSlice()
//a := ReadFloat64()
//A := ReadFloat64Slice(n)

//str := ZeroPaddingRuneSlice(num, 32)
//str := PrintIntsLine(X...)

/*******************************************************************/

const (
	// General purpose
	MOD          = 1000000000 + 7
	ALPHABET_NUM = 26
	INF_INT64    = math.MaxInt64
	INF_BIT60    = 1 << 60
	INF_INT32    = math.MaxInt32
	INF_BIT30    = 1 << 30
	NIL          = -1

	// for dijkstra, prim, and so on
	WHITE = 0
	GRAY  = 1
	BLACK = 2
)

func init() {
	// bufio.ScanWords <---> bufio.ScanLines
	ReadString = newReadString(os.Stdin, bufio.ScanWords)
	stdout = bufio.NewWriter(os.Stdout)
}

var (
	t    int
	n, m int
	a, b int
)

func main() {
	t = ReadInt()
	for i := 0; i < t; i++ {
		n, m, a, b = ReadInt4()
		solve(n, m, a, b)
	}
}

func solve(n, m, a, b int) {
	if n*a != m*b {
		fmt.Println("NO")
		return
	}
	fmt.Println("YES")

	A := make([][]rune, n)
	for i := 0; i < n; i++ {
		A[i] = make([]rune, m)
	}
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			A[i][j] = '0'
		}
	}

	p := 0
	for i := 0; i < n; i++ {
		for j := 0; j < a; j++ {
			A[i][p%m] = '1'
			p++
		}
	}

	for i := 0; i < n; i++ {
		fmt.Println(string(A[i]))
	}
}

/*******************************************************************/

/*********** I/O ***********/

var (
	// ReadString returns a WORD string.
	ReadString func() string
	stdout     *bufio.Writer
)

func newReadString(ior io.Reader, sf bufio.SplitFunc) func() string {
	r := bufio.NewScanner(ior)
	r.Buffer(make([]byte, 1024), int(1e+9)) // for Codeforces
	r.Split(sf)

	return func() string {
		if !r.Scan() {
			panic("Scan failed")
		}
		return r.Text()
	}
}

// ReadInt returns an integer.
func ReadInt() int {
	return int(readInt64())
}
func ReadInt2() (int, int) {
	return int(readInt64()), int(readInt64())
}
func ReadInt3() (int, int, int) {
	return int(readInt64()), int(readInt64()), int(readInt64())
}
func ReadInt4() (int, int, int, int) {
	return int(readInt64()), int(readInt64()), int(readInt64()), int(readInt64())
}

// ReadInt64 returns as integer as int64.
func ReadInt64() int64 {
	return readInt64()
}
func ReadInt64_2() (int64, int64) {
	return readInt64(), readInt64()
}
func ReadInt64_3() (int64, int64, int64) {
	return readInt64(), readInt64(), readInt64()
}
func ReadInt64_4() (int64, int64, int64, int64) {
	return readInt64(), readInt64(), readInt64(), readInt64()
}

func readInt64() int64 {
	i, err := strconv.ParseInt(ReadString(), 0, 64)
	if err != nil {
		panic(err.Error())
	}
	return i
}

// ReadIntSlice returns an integer slice that has n integers.
func ReadIntSlice(n int) []int {
	b := make([]int, n)
	for i := 0; i < n; i++ {
		b[i] = ReadInt()
	}
	return b
}

// ReadInt64Slice returns as int64 slice that has n integers.
func ReadInt64Slice(n int) []int64 {
	b := make([]int64, n)
	for i := 0; i < n; i++ {
		b[i] = ReadInt64()
	}
	return b
}

// ReadFloat64 returns an float64.
func ReadFloat64() float64 {
	return float64(readFloat64())
}

func readFloat64() float64 {
	f, err := strconv.ParseFloat(ReadString(), 64)
	if err != nil {
		panic(err.Error())
	}
	return f
}

// ReadFloatSlice returns an float64 slice that has n float64.
func ReadFloat64Slice(n int) []float64 {
	b := make([]float64, n)
	for i := 0; i < n; i++ {
		b[i] = ReadFloat64()
	}
	return b
}

// ReadRuneSlice returns a rune slice.
func ReadRuneSlice() []rune {
	return []rune(ReadString())
}

/*********** Debugging ***********/

// ZeroPaddingRuneSlice returns binary expressions of integer n with zero padding.
// For debugging use.
func ZeroPaddingRuneSlice(n, digitsNum int) []rune {
	sn := fmt.Sprintf("%b", n)

	residualLength := digitsNum - len(sn)
	if residualLength <= 0 {
		return []rune(sn)
	}

	zeros := make([]rune, residualLength)
	for i := 0; i < len(zeros); i++ {
		zeros[i] = '0'
	}

	res := []rune{}
	res = append(res, zeros...)
	res = append(res, []rune(sn)...)

	return res
}

// Strtoi is a wrapper of strconv.Atoi().
// If strconv.Atoi() returns an error, Strtoi calls panic.
func Strtoi(s string) int {
	if i, err := strconv.Atoi(s); err != nil {
		panic(errors.New("[argument error]: Strtoi only accepts integer string"))
	} else {
		return i
	}
}

// PrintIntsLine returns integers string delimited by a space.
func PrintIntsLine(A ...int) string {
	res := []rune{}

	for i := 0; i < len(A); i++ {
		str := strconv.Itoa(A[i])
		res = append(res, []rune(str)...)

		if i != len(A)-1 {
			res = append(res, ' ')
		}
	}

	return string(res)
}

// PrintIntsLine returns integers string delimited by a space.
func PrintInts64Line(A ...int64) string {
	res := []rune{}

	for i := 0; i < len(A); i++ {
		str := strconv.FormatInt(A[i], 10) // 64bit int version
		res = append(res, []rune(str)...)

		if i != len(A)-1 {
			res = append(res, ' ')
		}
	}

	return string(res)
}

// PrintfDebug is wrapper of fmt.Fprintf(os.Stderr, format, a...)
func PrintfDebug(format string, a ...interface{}) {
	fmt.Fprintf(os.Stderr, format, a...)
}

// PrintfBufStdout is function for output strings to buffered os.Stdout.
// You may have to call stdout.Flush() finally.
func PrintfBufStdout(format string, a ...interface{}) {
	fmt.Fprintf(stdout, format, a...)
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
)

// github.com/EndlessCheng/codeforces-go
func run(_r io.Reader, _w io.Writer) {
	in := bufio.NewReader(_r)
	out := bufio.NewWriter(_w)
	defer out.Flush()
	gcd := func(a, b int) int {
		for a != 0 {
			a, b = b%a, a
		}
		return b
	}

	var t, n, m, a, b int
	for Fscan(in, &t); t > 0; t-- {
		Fscan(in, &n, &m, &a, &b)
		if n*a != m*b {
			Fprintln(out, "NO")
			continue
		}
		Fprintln(out, "YES")
		g := gcd(m, a)
		for i := 0; i < n; i++ {
			ans := make([]byte, m)
			for j := range ans {
				ans[j] = '0'
			}
			for c := 0; c < a; c++ {
				ans[(g*i+c)%m] = '1'
			}
			Fprintln(out, string(ans))
		}
	}
}

func main() { run(os.Stdin, os.Stdout) }

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
)

// github.com/EndlessCheng/codeforces-go
func CF1360G(_r io.Reader, _w io.Writer) {
	in := bufio.NewReader(_r)
	out := bufio.NewWriter(_w)
	defer out.Flush()

	min := func(a, b int) int {
		if a < b {
			return a
		}
		return b
	}
	type edge struct{ to, rev, cap int }

	solve := func(_case int) {
		var n, m, a, b, maxFlow int
		Fscan(in, &n, &m, &a, &b)
		if n*a != m*b {
			Fprintln(out, "NO")
			return
		}

		edges := make([][]edge, n+m+2)
		addEdge := func(from, to int, cap int) {
			edges[from] = append(edges[from], edge{to, len(edges[to]), cap})
			edges[to] = append(edges[to], edge{from, len(edges[from]) - 1, 0})
		}
		for i := 0; i < n; i++ {
			for j := 0; j < m; j++ {
				addEdge(i, n+j, 1)
			}
		}
		st, end := n+m, n+m+1
		for i := 0; i < n; i++ {
			addEdge(st, i, a)
		}
		for i := 0; i < m; i++ {
			addEdge(n+i, end, b)
		}

		level := make([]int, n+m+2)
		calcLevel := func() bool {
			for i := range level {
				level[i] = -1
			}
			level[st] = 0
			q := []int{st}
			for len(q) > 0 {
				v := q[0]
				q = q[1:]
				for _, e := range edges[v] {
					if w := e.to; e.cap > 0 && level[w] < 0 {
						level[w] = level[v] + 1
						q = append(q, w)
					}
				}
			}
			return level[end] >= 0
		}
		var iter []int
		var dfs func(int, int) int
		dfs = func(v int, mf int) int {
			if v == end {
				return mf
			}
			for i := iter[v]; i < len(edges[v]); i++ {
				e := &edges[v][i]
				if w := e.to; e.cap > 0 && level[w] > level[v] {
					if f := dfs(w, min(mf, e.cap)); f > 0 {
						e.cap -= f
						edges[w][e.rev].cap += f
						return f
					}
				}
				iter[v]++
			}
			return 0
		}
		const inf int = 1e9
		for calcLevel() {
			iter = make([]int, n+m+2)
			for {
				if f := dfs(st, inf); f > 0 {
					maxFlow += f
				} else {
					break
				}
			}
		}
		if maxFlow < n*a {
			Fprintln(out, "NO")
			return
		}
		Fprintln(out, "YES")
		for i := 0; i < n; i++ {
			ans := make([]byte, m)
			for j, e := range edges[i][:m] {
				ans[j] = '1' - byte(e.cap)
			}
			Fprintln(out, string(ans))
		}
	}

	var t int
	Fscan(in, &t)
	for _case := 1; _case <= t; _case++ {
		solve(_case)
	}
}

func main() { CF1360G(os.Stdin, os.Stdout) }

package main

import (
	"bufio"
	. "fmt"
	"os"
)

var (
	inn = bufio.NewScanner(os.Stdin)
	// in  = bufio.NewReader(os.Stdin)
	out = bufio.NewWriter(os.Stdout)
)

func main() {
	defer out.Flush()
	inn.Split(bufio.ScanWords)

	for tt := rd(); tt > 0; tt-- {
		n, m, a, b := rd(), rd(), rd(), rd()
		if n*a != b*m {
			Fprintln(out, "NO")
			continue
		}
		ans := make([][]int, n)
		c := 0
		for i := 0; i < n; i++ {
			ans[i] = make([]int, m)
			for j := 0; j < a; j++ {
				ans[i][c] = 1
				c = (c + 1) % m
			}
		}
		Fprintln(out, "YES")
		for _, i := range ans {
			for _, j := range i {
				Fprint(out, j)
			}
			Fprintln(out)
		}
	}
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}
func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}
func rd() (x int) {
	inn.Scan()
	data := inn.Bytes()
	f := 1
	if data[0] == '-' {
		f = -1
		data = data[1:]
	}
	for _, b := range data {
		x = x*10 + int(b&15)
	}
	return f * x
}
func rdll() (x int64) {
	inn.Scan()
	data := inn.Bytes()
	f := int64(1)
	if data[0] == '-' {
		f = -1
		data = data[1:]
	}
	for _, b := range data {
		x = x*10 + int64(b&15)
	}
	return f * x
}

package main

import (
	"fmt"
)

func main(){
	var T int
	fmt.Scan(&T)
	for t := 0; t < T; t++ {
		var n, m, a, b int
		fmt.Scan(&n, &m, &a, &b)
		if n*a != m*b {
			fmt.Println("NO")
		} else {
			fmt.Println("YES")
			G := make([][] rune, n)
			ctr := make([]int, m)
			cols := make([]int, m)
			for j := 0; j < m; j++ {
				cols[j] = j
			}
			for i := 0; i < n; i++ {
				G[i] = make([]rune, m)
				for j := 0; j < m; j++ {
					G[i][j] = '0'
				}

				for k := 0; k < m; k++ {
					q := k
					for q > 0 && ctr[cols[q-1]] > ctr[cols[q]] {
						a := cols[q-1]
						b := cols[q]
						cols[q-1] = b
						cols[q] = a
						q--
					}
				}

				for k := 0; k < a; k++ {
					j := cols[k]
					ctr[j]++
					G[i][j] = '1'
				}
				// fmt.Println(cols)
				// fmt.Println(ctr)
				fmt.Println(string(G[i]))
			}
		}
	}

}

package main

import (
	"bufio"
	"fmt"
	"io"
	"math"
	"os"
)

type BufferedWriter interface {
	Printf(format string, a ...interface{})
	Flush()
}

type writerImpl struct {
	*bufio.Writer
}

func NewBufferedWriter(writer io.Writer) BufferedWriter {
	return &writerImpl{Writer: bufio.NewWriter(writer)}
}

func (impl *writerImpl) Printf(f string, a ...interface{}) {
	fmt.Fprintf(impl.Writer, f, a...)
}

func (impl *writerImpl) Flush() {
	impl.Writer.Flush()
}

type WordScanner interface {
	NextInt64() int64
	NextUInt64() uint64
	NextString() string
}

type wordScannerImpl struct {
	*bufio.Scanner
}

func NewWordScanner(reader io.Reader) WordScanner {
	s := bufio.NewScanner(reader)
	s.Split(bufio.ScanWords)
	// adjust the following size as needed
	// 2 << 17 is good enough to scan strings of len 2*10^5
	// it could go as high as 2 << 26 before cf judge breaks
	size := 2 << 20
	buf := make([]byte, size)
	s.Buffer(buf, size)
	return &wordScannerImpl{Scanner: s}
}

func (impl *wordScannerImpl) NextInt64() int64 {
	impl.Scan()
	bb := impl.Bytes()
	i := int64(0)
	if bb[0] == '-' {
		for _, b := range bb[1:] {
			i *= 10
			i -= int64(b - '0')
		}
		return i
	}
	for _, b := range bb {
		i *= 10
		i += int64(b - '0')
	}
	return i
}

func (impl *wordScannerImpl) NextUInt64() uint64 {
	impl.Scan()
	bb := impl.Bytes()
	i := uint64(0)
	for _, b := range bb {
		i *= 10
		i += uint64(b - '0')
	}
	return i
}

func (impl *wordScannerImpl) NextString() string {
	impl.Scan()
	return impl.Text()
}

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

func lcm(a, b int64) int64 {
	return a * b / gcd(a, b)
}

func abs(a int64) int64 {
	if a < 0 {
		return a * -1
	}
	return a
}

func min(a int64, rest ...int64) int64 {
	for _, r := range rest {
		if r < a {
			a = r
		}
	}
	return a
}

func max(a int64, rest ...int64) int64 {
	for _, r := range rest {
		if r > a {
			a = r
		}
	}
	return a
}

const (
	INF = math.MaxInt64
	MOD = 1e9 + 7
)

var reader = NewWordScanner(os.Stdin)
var writer = NewBufferedWriter(os.Stdout)

func main() {
	defer writer.Flush()
	t := reader.NextInt64()
	for ; t > 0; t-- {
		n := reader.NextInt64()
		m := reader.NextInt64()
		a := reader.NextInt64()
		b := reader.NextInt64()
		res := sol(n, m, a, b)
		if res == nil {
			writer.Printf("NO\n")
		} else {
			writer.Printf("YES\n")
			for _, r := range res {
				writer.Printf("%s\n", string(r))
			}
		}
	}
}

func sol(n, m, a, b int64) [][]rune {
	// n rows, m cols
	// b corresponds to n
	// a corresponds to m
	if n * a != m * b {
		return nil
	}
	ret := make([][]rune, n)
	for i := range ret {
		ret[i] = make([]rune, m)
		for j := range ret[i] {
			ret[i][j] = '0'
		}
	}
	xpos := int64(0)
	for i := range ret {
		for j := int64(0); j < a; j++ {
			ret[i][xpos] = '1'
			xpos++
			xpos%=m
		}
	}
	return ret
}

package main

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

func readInt(bytes []byte, from int, val *int) int {
	i := from
	sign := 1
	if bytes[i] == '-' {
		sign = -1
		i++
	}
	tmp := 0
	for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' {
		tmp = tmp*10 + int(bytes[i]-'0')
		i++
	}
	*val = tmp * sign
	return i
}

func readNum(reader *bufio.Reader) (a int) {
	bs, _ := reader.ReadBytes('\n')
	readInt(bs, 0, &a)
	return
}

func readTwoNums(reader *bufio.Reader) (a int, b int) {
	res := readNNums(reader, 2)
	a, b = res[0], res[1]
	return
}

func readThreeNums(reader *bufio.Reader) (a int, b int, c int) {
	res := readNNums(reader, 3)
	a, b, c = res[0], res[1], res[2]
	return
}

func readNNums(reader *bufio.Reader, n int) []int {
	res := make([]int, n)
	x := 0
	bs, _ := reader.ReadBytes('\n')
	for i := 0; i < n; i++ {
		for x < len(bs) && (bs[x] < '0' || bs[x] > '9') && bs[x] != '-' {
			x++
		}
		x = readInt(bs, x, &res[i])
	}
	return res
}

func readUint64(bytes []byte, from int, val *uint64) int {
	i := from

	var tmp uint64
	for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' {
		tmp = tmp*10 + uint64(bytes[i]-'0')
		i++
	}
	*val = tmp

	return i
}

func main() {
	reader := bufio.NewReader(os.Stdin)

	tc := readNum(reader)

	for tc > 0 {
		tc--
		line := readNNums(reader, 4)
		n, m, a, b := line[0], line[1], line[2], line[3]
		ok, g := solve(n, m, a, b)
		if ok {
			fmt.Println("YES")
			for i := 0; i < n; i++ {
				fmt.Println(string(g[i]))
			}
		} else {
			fmt.Println("NO")
		}
	}
}

func solve(n, m, a, b int) (bool, [][]byte) {
	if n*a != b*m {
		return false, nil
	}

	G := make([][]byte, n)
	var d = 1
	for (d*n)%m != 0 {
		d++
	}

	var j int
	for i := 0; i < n; i++ {
		G[i] = make([]byte, m)
		var x int
		for k := 0; k < m; k++ {
			if x < a {
				G[i][(j+k)%m] = '1'
				x++
			} else {
				G[i][(j+k)%m] = '0'
			}
		}
		j = (j + d) % m
	}

	return true, G
}

package main

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

func readInt(bytes []byte, from int, val *int) int {
	i := from
	sign := 1
	if bytes[i] == '-' {
		sign = -1
		i++
	}
	tmp := 0
	for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' {
		tmp = tmp*10 + int(bytes[i]-'0')
		i++
	}
	*val = tmp * sign
	return i
}

func readNum(reader *bufio.Reader) (a int) {
	bs, _ := reader.ReadBytes('\n')
	readInt(bs, 0, &a)
	return
}

func readTwoNums(reader *bufio.Reader) (a int, b int) {
	res := readNNums(reader, 2)
	a, b = res[0], res[1]
	return
}

func readThreeNums(reader *bufio.Reader) (a int, b int, c int) {
	res := readNNums(reader, 3)
	a, b, c = res[0], res[1], res[2]
	return
}

func readNNums(reader *bufio.Reader, n int) []int {
	res := make([]int, n)
	x := 0
	bs, _ := reader.ReadBytes('\n')
	for i := 0; i < n; i++ {
		for x < len(bs) && (bs[x] < '0' || bs[x] > '9') && bs[x] != '-' {
			x++
		}
		x = readInt(bs, x, &res[i])
	}
	return res
}

func readUint64(bytes []byte, from int, val *uint64) int {
	i := from

	var tmp uint64
	for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' {
		tmp = tmp*10 + uint64(bytes[i]-'0')
		i++
	}
	*val = tmp

	return i
}

func main() {
	reader := bufio.NewReader(os.Stdin)

	tc := readNum(reader)

	for tc > 0 {
		tc--
		line := readNNums(reader, 4)
		n, m, a, b := line[0], line[1], line[2], line[3]
		ok, g := solve(n, m, a, b)
		if ok {
			fmt.Println("YES")
			for i := 0; i < n; i++ {
				fmt.Println(string(g[i]))
			}
		} else {
			fmt.Println("NO")
		}
	}
}

func solve(n, m, a, b int) (bool, [][]byte) {
	if n*a != b*m {
		return false, nil
	}

	G := make([][]byte, n)
	cnt := make([]int, m)

	for i := 0; i < n; i++ {
		G[i] = make([]byte, m)
		var x int
		// put a ones in this column
		for j := 0; j < m; j++ {
			if cnt[j] < b && x < a {
				G[i][j] = '1'
				cnt[j]++
				x++
			} else {
				G[i][j] = '0'
			}
		}
	}

	return true, G
}

/*
URL:
https://codeforces.com/contest/1360/problem/G
*/

package main

import (
	"bufio"
	"errors"
	"fmt"
	"io"
	"math"
	"os"
	"strconv"
)

/********** FAU standard libraries **********/

//fmt.Sprintf("%b\n", 255) 	// binary expression

/********** I/O usage **********/

//str := ReadString()
//i := ReadInt()
//X := ReadIntSlice(n)
//S := ReadRuneSlice()
//a := ReadFloat64()
//A := ReadFloat64Slice(n)

//str := ZeroPaddingRuneSlice(num, 32)
//str := PrintIntsLine(X...)

/*******************************************************************/

const (
	// General purpose
	MOD          = 1000000000 + 7
	ALPHABET_NUM = 26
	INF_INT64    = math.MaxInt64
	INF_BIT60    = 1 << 60
	INF_INT32    = math.MaxInt32
	INF_BIT30    = 1 << 30
	NIL          = -1

	// for dijkstra, prim, and so on
	WHITE = 0
	GRAY  = 1
	BLACK = 2
)

func init() {
	// bufio.ScanWords <---> bufio.ScanLines
	ReadString = newReadString(os.Stdin, bufio.ScanWords)
	stdout = bufio.NewWriter(os.Stdout)
}

var (
	t    int
	n, m int
	a, b int
)

func main() {
	t = ReadInt()
	for i := 0; i < t; i++ {
		n, m, a, b = ReadInt4()
		solve(n, m, a, b)
	}
}

func solve(n, m, a, b int) {
	if a == 0 && b == 0 {
		sub(n, m, a, b)
		return
	}

	if n*a != m*b {
		fmt.Println("NO")
		return
	}
	if !(n%b == 0 && m%a == 0) {
		fmt.Println("NO")
		return
	}

	res := [][]rune{}

	C := make([]int, m)

	for i := 0; i < n; i++ {
		row := []rune{}

		nokori := a
		for j := 0; j < m; j++ {
			if C[j] < b && nokori > 0 {
				row = append(row, '1')
				C[j]++
				nokori--
			} else {
				row = append(row, '0')
			}
		}

		res = append(res, row)
	}

	for i := 0; i < n; i++ {
		tmp := 0
		for j := 0; j < m; j++ {
			if res[i][j] == '1' {
				tmp++
			}
		}
		if tmp != a {
			fmt.Println("NO")
			return
		}
	}
	for j := 0; j < m; j++ {
		tmp := 0
		for i := 0; i < n; i++ {
			if res[i][j] == '1' {
				tmp++
			}
		}
		if tmp != b {
			fmt.Println("NO")
			return
		}
	}

	// sum := 0
	// for i := 0; i < n; i++ {
	// 	for j := 0; j < m; j++ {
	// 		if res[i][j] == '1' {
	// 			sum++
	// 		}
	// 	}
	// }
	// if sum != n*a || sum != m*b {
	// 	fmt.Println("NO")
	// 	return
	// }

	fmt.Println("YES")
	for i := 0; i < n; i++ {
		fmt.Println(string(res[i]))
	}
}

func sub(n, m, a, b int) {
	res := [][]rune{}
	for i := 0; i < n; i++ {
		row := []rune{}
		for j := 0; j < m; j++ {
			row = append(row, '0')
		}
		res = append(res, row)
	}

	fmt.Println("YES")
	for i := 0; i < n; i++ {
		fmt.Println(string(res[i]))
	}
}

/*******************************************************************/

/*********** I/O ***********/

var (
	// ReadString returns a WORD string.
	ReadString func() string
	stdout     *bufio.Writer
)

func newReadString(ior io.Reader, sf bufio.SplitFunc) func() string {
	r := bufio.NewScanner(ior)
	r.Buffer(make([]byte, 1024), int(1e+9)) // for Codeforces
	r.Split(sf)

	return func() string {
		if !r.Scan() {
			panic("Scan failed")
		}
		return r.Text()
	}
}

// ReadInt returns an integer.
func ReadInt() int {
	return int(readInt64())
}
func ReadInt2() (int, int) {
	return int(readInt64()), int(readInt64())
}
func ReadInt3() (int, int, int) {
	return int(readInt64()), int(readInt64()), int(readInt64())
}
func ReadInt4() (int, int, int, int) {
	return int(readInt64()), int(readInt64()), int(readInt64()), int(readInt64())
}

// ReadInt64 returns as integer as int64.
func ReadInt64() int64 {
	return readInt64()
}
func ReadInt64_2() (int64, int64) {
	return readInt64(), readInt64()
}
func ReadInt64_3() (int64, int64, int64) {
	return readInt64(), readInt64(), readInt64()
}
func ReadInt64_4() (int64, int64, int64, int64) {
	return readInt64(), readInt64(), readInt64(), readInt64()
}

func readInt64() int64 {
	i, err := strconv.ParseInt(ReadString(), 0, 64)
	if err != nil {
		panic(err.Error())
	}
	return i
}

// ReadIntSlice returns an integer slice that has n integers.
func ReadIntSlice(n int) []int {
	b := make([]int, n)
	for i := 0; i < n; i++ {
		b[i] = ReadInt()
	}
	return b
}

// ReadInt64Slice returns as int64 slice that has n integers.
func ReadInt64Slice(n int) []int64 {
	b := make([]int64, n)
	for i := 0; i < n; i++ {
		b[i] = ReadInt64()
	}
	return b
}

// ReadFloat64 returns an float64.
func ReadFloat64() float64 {
	return float64(readFloat64())
}

func readFloat64() float64 {
	f, err := strconv.ParseFloat(ReadString(), 64)
	if err != nil {
		panic(err.Error())
	}
	return f
}

// ReadFloatSlice returns an float64 slice that has n float64.
func ReadFloat64Slice(n int) []float64 {
	b := make([]float64, n)
	for i := 0; i < n; i++ {
		b[i] = ReadFloat64()
	}
	return b
}

// ReadRuneSlice returns a rune slice.
func ReadRuneSlice() []rune {
	return []rune(ReadString())
}

/*********** Debugging ***********/

// ZeroPaddingRuneSlice returns binary expressions of integer n with zero padding.
// For debugging use.
func ZeroPaddingRuneSlice(n, digitsNum int) []rune {
	sn := fmt.Sprintf("%b", n)

	residualLength := digitsNum - len(sn)
	if residualLength <= 0 {
		return []rune(sn)
	}

	zeros := make([]rune, residualLength)
	for i := 0; i < len(zeros); i++ {
		zeros[i] = '0'
	}

	res := []rune{}
	res = append(res, zeros...)
	res = append(res, []rune(sn)...)

	return res
}

// Strtoi is a wrapper of strconv.Atoi().
// If strconv.Atoi() returns an error, Strtoi calls panic.
func Strtoi(s string) int {
	if i, err := strconv.Atoi(s); err != nil {
		panic(errors.New("[argument error]: Strtoi only accepts integer string"))
	} else {
		return i
	}
}

// PrintIntsLine returns integers string delimited by a space.
func PrintIntsLine(A ...int) string {
	res := []rune{}

	for i := 0; i < len(A); i++ {
		str := strconv.Itoa(A[i])
		res = append(res, []rune(str)...)

		if i != len(A)-1 {
			res = append(res, ' ')
		}
	}

	return string(res)
}

// PrintIntsLine returns integers string delimited by a space.
func PrintInts64Line(A ...int64) string {
	res := []rune{}

	for i := 0; i < len(A); i++ {
		str := strconv.FormatInt(A[i], 10) // 64bit int version
		res = append(res, []rune(str)...)

		if i != len(A)-1 {
			res = append(res, ' ')
		}
	}

	return string(res)
}

// PrintfDebug is wrapper of fmt.Fprintf(os.Stderr, format, a...)
func PrintfDebug(format string, a ...interface{}) {
	fmt.Fprintf(os.Stderr, format, a...)
}

// PrintfBufStdout is function for output strings to buffered os.Stdout.
// You may have to call stdout.Flush() finally.
func PrintfBufStdout(format string, a ...interface{}) {
	fmt.Fprintf(stdout, format, a...)
}

/*
URL:
https://codeforces.com/contest/1360/problem/G
*/

package main

import (
	"bufio"
	"errors"
	"fmt"
	"io"
	"math"
	"os"
	"strconv"
)

/********** FAU standard libraries **********/

//fmt.Sprintf("%b\n", 255) 	// binary expression

/********** I/O usage **********/

//str := ReadString()
//i := ReadInt()
//X := ReadIntSlice(n)
//S := ReadRuneSlice()
//a := ReadFloat64()
//A := ReadFloat64Slice(n)

//str := ZeroPaddingRuneSlice(num, 32)
//str := PrintIntsLine(X...)

/*******************************************************************/

const (
	// General purpose
	MOD          = 1000000000 + 7
	ALPHABET_NUM = 26
	INF_INT64    = math.MaxInt64
	INF_BIT60    = 1 << 60
	INF_INT32    = math.MaxInt32
	INF_BIT30    = 1 << 30
	NIL          = -1

	// for dijkstra, prim, and so on
	WHITE = 0
	GRAY  = 1
	BLACK = 2
)

func init() {
	// bufio.ScanWords <---> bufio.ScanLines
	ReadString = newReadString(os.Stdin, bufio.ScanWords)
	stdout = bufio.NewWriter(os.Stdout)
}

var (
	t    int
	n, m int
	a, b int
)

func main() {
	t = ReadInt()
	for i := 0; i < t; i++ {
		n, m, a, b = ReadInt4()
		solve(n, m, a, b)
	}
}

func solve(n, m, a, b int) {
	if n*a != m*b {
		fmt.Println("NO")
		return
	}

	res := [][]rune{}

	C := make([]int, m)

	for i := 0; i < n; i++ {
		row := []rune{}

		nokori := a
		for j := 0; j < m; j++ {
			if C[j] < b && nokori > 0 {
				row = append(row, '1')
				C[j]++
				nokori--
			} else {
				row = append(row, '0')
			}
		}

		res = append(res, row)
	}

	fmt.Println("YES")
	for i := 0; i < n; i++ {
		fmt.Println(string(res[i]))
	}
}

/*******************************************************************/

/*********** I/O ***********/

var (
	// ReadString returns a WORD string.
	ReadString func() string
	stdout     *bufio.Writer
)

func newReadString(ior io.Reader, sf bufio.SplitFunc) func() string {
	r := bufio.NewScanner(ior)
	r.Buffer(make([]byte, 1024), int(1e+9)) // for Codeforces
	r.Split(sf)

	return func() string {
		if !r.Scan() {
			panic("Scan failed")
		}
		return r.Text()
	}
}

// ReadInt returns an integer.
func ReadInt() int {
	return int(readInt64())
}
func ReadInt2() (int, int) {
	return int(readInt64()), int(readInt64())
}
func ReadInt3() (int, int, int) {
	return int(readInt64()), int(readInt64()), int(readInt64())
}
func ReadInt4() (int, int, int, int) {
	return int(readInt64()), int(readInt64()), int(readInt64()), int(readInt64())
}

// ReadInt64 returns as integer as int64.
func ReadInt64() int64 {
	return readInt64()
}
func ReadInt64_2() (int64, int64) {
	return readInt64(), readInt64()
}
func ReadInt64_3() (int64, int64, int64) {
	return readInt64(), readInt64(), readInt64()
}
func ReadInt64_4() (int64, int64, int64, int64) {
	return readInt64(), readInt64(), readInt64(), readInt64()
}

func readInt64() int64 {
	i, err := strconv.ParseInt(ReadString(), 0, 64)
	if err != nil {
		panic(err.Error())
	}
	return i
}

// ReadIntSlice returns an integer slice that has n integers.
func ReadIntSlice(n int) []int {
	b := make([]int, n)
	for i := 0; i < n; i++ {
		b[i] = ReadInt()
	}
	return b
}

// ReadInt64Slice returns as int64 slice that has n integers.
func ReadInt64Slice(n int) []int64 {
	b := make([]int64, n)
	for i := 0; i < n; i++ {
		b[i] = ReadInt64()
	}
	return b
}

// ReadFloat64 returns an float64.
func ReadFloat64() float64 {
	return float64(readFloat64())
}

func readFloat64() float64 {
	f, err := strconv.ParseFloat(ReadString(), 64)
	if err != nil {
		panic(err.Error())
	}
	return f
}

// ReadFloatSlice returns an float64 slice that has n float64.
func ReadFloat64Slice(n int) []float64 {
	b := make([]float64, n)
	for i := 0; i < n; i++ {
		b[i] = ReadFloat64()
	}
	return b
}

// ReadRuneSlice returns a rune slice.
func ReadRuneSlice() []rune {
	return []rune(ReadString())
}

/*********** Debugging ***********/

// ZeroPaddingRuneSlice returns binary expressions of integer n with zero padding.
// For debugging use.
func ZeroPaddingRuneSlice(n, digitsNum int) []rune {
	sn := fmt.Sprintf("%b", n)

	residualLength := digitsNum - len(sn)
	if residualLength <= 0 {
		return []rune(sn)
	}

	zeros := make([]rune, residualLength)
	for i := 0; i < len(zeros); i++ {
		zeros[i] = '0'
	}

	res := []rune{}
	res = append(res, zeros...)
	res = append(res, []rune(sn)...)

	return res
}

// Strtoi is a wrapper of strconv.Atoi().
// If strconv.Atoi() returns an error, Strtoi calls panic.
func Strtoi(s string) int {
	if i, err := strconv.Atoi(s); err != nil {
		panic(errors.New("[argument error]: Strtoi only accepts integer string"))
	} else {
		return i
	}
}

// PrintIntsLine returns integers string delimited by a space.
func PrintIntsLine(A ...int) string {
	res := []rune{}

	for i := 0; i < len(A); i++ {
		str := strconv.Itoa(A[i])
		res = append(res, []rune(str)...)

		if i != len(A)-1 {
			res = append(res, ' ')
		}
	}

	return string(res)
}

// PrintIntsLine returns integers string delimited by a space.
func PrintInts64Line(A ...int64) string {
	res := []rune{}

	for i := 0; i < len(A); i++ {
		str := strconv.FormatInt(A[i], 10) // 64bit int version
		res = append(res, []rune(str)...)

		if i != len(A)-1 {
			res = append(res, ' ')
		}
	}

	return string(res)
}

// PrintfDebug is wrapper of fmt.Fprintf(os.Stderr, format, a...)
func PrintfDebug(format string, a ...interface{}) {
	fmt.Fprintf(os.Stderr, format, a...)
}

// PrintfBufStdout is function for output strings to buffered os.Stdout.
// You may have to call stdout.Flush() finally.
func PrintfBufStdout(format string, a ...interface{}) {
	fmt.Fprintf(stdout, format, a...)
}

/*
URL:
https://codeforces.com/contest/1360/problem/G
*/

package main

import (
	"bufio"
	"errors"
	"fmt"
	"io"
	"math"
	"os"
	"strconv"
)

/********** FAU standard libraries **********/

//fmt.Sprintf("%b\n", 255) 	// binary expression

/********** I/O usage **********/

//str := ReadString()
//i := ReadInt()
//X := ReadIntSlice(n)
//S := ReadRuneSlice()
//a := ReadFloat64()
//A := ReadFloat64Slice(n)

//str := ZeroPaddingRuneSlice(num, 32)
//str := PrintIntsLine(X...)

/*******************************************************************/

const (
	// General purpose
	MOD          = 1000000000 + 7
	ALPHABET_NUM = 26
	INF_INT64    = math.MaxInt64
	INF_BIT60    = 1 << 60
	INF_INT32    = math.MaxInt32
	INF_BIT30    = 1 << 30
	NIL          = -1

	// for dijkstra, prim, and so on
	WHITE = 0
	GRAY  = 1
	BLACK = 2
)

func init() {
	// bufio.ScanWords <---> bufio.ScanLines
	ReadString = newReadString(os.Stdin, bufio.ScanWords)
	stdout = bufio.NewWriter(os.Stdout)
}

var (
	t    int
	n, m int
	a, b int
)

func main() {
	t = ReadInt()
	for i := 0; i < t; i++ {
		n, m, a, b = ReadInt4()
		solve(n, m, a, b)
	}
}

func solve(n, m, a, b int) {
	// if a == 0 && b == 0 {
	// 	sub(n, m, a, b)
	// 	return
	// }

	// if n*a != m*b {
	// 	fmt.Println("NO")
	// 	return
	// }
	// if !(n%b == 0 && m%a == 0) {
	// 	fmt.Println("NO")
	// 	return
	// }

	res := [][]rune{}

	C := make([]int, m)

	for i := 0; i < n; i++ {
		row := []rune{}

		nokori := a
		for j := 0; j < m; j++ {
			if C[j] < b && nokori > 0 {
				row = append(row, '1')
				C[j]++
				nokori--
			} else {
				row = append(row, '0')
			}
		}

		res = append(res, row)
	}

	for i := 0; i < n; i++ {
		tmp := 0
		for j := 0; j < m; j++ {
			if res[i][j] == '1' {
				tmp++
			}
		}
		if tmp != a {
			fmt.Println("NO")
			return
		}
	}
	for j := 0; j < m; j++ {
		tmp := 0
		for i := 0; i < n; i++ {
			if res[i][j] == '1' {
				tmp++
			}
		}
		if tmp != b {
			fmt.Println("NO")
			return
		}
	}

	// sum := 0
	// for i := 0; i < n; i++ {
	// 	for j := 0; j < m; j++ {
	// 		if res[i][j] == '1' {
	// 			sum++
	// 		}
	// 	}
	// }
	// if sum != n*a || sum != m*b {
	// 	fmt.Println("NO")
	// 	return
	// }

	fmt.Println("YES")
	for i := 0; i < n; i++ {
		fmt.Println(string(res[i]))
	}
}

func sub(n, m, a, b int) {
	res := [][]rune{}
	for i := 0; i < n; i++ {
		row := []rune{}
		for j := 0; j < m; j++ {
			row = append(row, '0')
		}
		res = append(res, row)
	}

	fmt.Println("YES")
	for i := 0; i < n; i++ {
		fmt.Println(string(res[i]))
	}
}

/*******************************************************************/

/*********** I/O ***********/

var (
	// ReadString returns a WORD string.
	ReadString func() string
	stdout     *bufio.Writer
)

func newReadString(ior io.Reader, sf bufio.SplitFunc) func() string {
	r := bufio.NewScanner(ior)
	r.Buffer(make([]byte, 1024), int(1e+9)) // for Codeforces
	r.Split(sf)

	return func() string {
		if !r.Scan() {
			panic("Scan failed")
		}
		return r.Text()
	}
}

// ReadInt returns an integer.
func ReadInt() int {
	return int(readInt64())
}
func ReadInt2() (int, int) {
	return int(readInt64()), int(readInt64())
}
func ReadInt3() (int, int, int) {
	return int(readInt64()), int(readInt64()), int(readInt64())
}
func ReadInt4() (int, int, int, int) {
	return int(readInt64()), int(readInt64()), int(readInt64()), int(readInt64())
}

// ReadInt64 returns as integer as int64.
func ReadInt64() int64 {
	return readInt64()
}
func ReadInt64_2() (int64, int64) {
	return readInt64(), readInt64()
}
func ReadInt64_3() (int64, int64, int64) {
	return readInt64(), readInt64(), readInt64()
}
func ReadInt64_4() (int64, int64, int64, int64) {
	return readInt64(), readInt64(), readInt64(), readInt64()
}

func readInt64() int64 {
	i, err := strconv.ParseInt(ReadString(), 0, 64)
	if err != nil {
		panic(err.Error())
	}
	return i
}

// ReadIntSlice returns an integer slice that has n integers.
func ReadIntSlice(n int) []int {
	b := make([]int, n)
	for i := 0; i < n; i++ {
		b[i] = ReadInt()
	}
	return b
}

// ReadInt64Slice returns as int64 slice that has n integers.
func ReadInt64Slice(n int) []int64 {
	b := make([]int64, n)
	for i := 0; i < n; i++ {
		b[i] = ReadInt64()
	}
	return b
}

// ReadFloat64 returns an float64.
func ReadFloat64() float64 {
	return float64(readFloat64())
}

func readFloat64() float64 {
	f, err := strconv.ParseFloat(ReadString(), 64)
	if err != nil {
		panic(err.Error())
	}
	return f
}

// ReadFloatSlice returns an float64 slice that has n float64.
func ReadFloat64Slice(n int) []float64 {
	b := make([]float64, n)
	for i := 0; i < n; i++ {
		b[i] = ReadFloat64()
	}
	return b
}

// ReadRuneSlice returns a rune slice.
func ReadRuneSlice() []rune {
	return []rune(ReadString())
}

/*********** Debugging ***********/

// ZeroPaddingRuneSlice returns binary expressions of integer n with zero padding.
// For debugging use.
func ZeroPaddingRuneSlice(n, digitsNum int) []rune {
	sn := fmt.Sprintf("%b", n)

	residualLength := digitsNum - len(sn)
	if residualLength <= 0 {
		return []rune(sn)
	}

	zeros := make([]rune, residualLength)
	for i := 0; i < len(zeros); i++ {
		zeros[i] = '0'
	}

	res := []rune{}
	res = append(res, zeros...)
	res = append(res, []rune(sn)...)

	return res
}

// Strtoi is a wrapper of strconv.Atoi().
// If strconv.Atoi() returns an error, Strtoi calls panic.
func Strtoi(s string) int {
	if i, err := strconv.Atoi(s); err != nil {
		panic(errors.New("[argument error]: Strtoi only accepts integer string"))
	} else {
		return i
	}
}

// PrintIntsLine returns integers string delimited by a space.
func PrintIntsLine(A ...int) string {
	res := []rune{}

	for i := 0; i < len(A); i++ {
		str := strconv.Itoa(A[i])
		res = append(res, []rune(str)...)

		if i != len(A)-1 {
			res = append(res, ' ')
		}
	}

	return string(res)
}

// PrintIntsLine returns integers string delimited by a space.
func PrintInts64Line(A ...int64) string {
	res := []rune{}

	for i := 0; i < len(A); i++ {
		str := strconv.FormatInt(A[i], 10) // 64bit int version
		res = append(res, []rune(str)...)

		if i != len(A)-1 {
			res = append(res, ' ')
		}
	}

	return string(res)
}

// PrintfDebug is wrapper of fmt.Fprintf(os.Stderr, format, a...)
func PrintfDebug(format string, a ...interface{}) {
	fmt.Fprintf(os.Stderr, format, a...)
}

// PrintfBufStdout is function for output strings to buffered os.Stdout.
// You may have to call stdout.Flush() finally.
func PrintfBufStdout(format string, a ...interface{}) {
	fmt.Fprintf(stdout, format, a...)
}

/*
URL:
https://codeforces.com/contest/1360/problem/G
*/

package main

import (
	"bufio"
	"errors"
	"fmt"
	"io"
	"math"
	"os"
	"strconv"
)

/********** FAU standard libraries **********/

//fmt.Sprintf("%b\n", 255) 	// binary expression

/********** I/O usage **********/

//str := ReadString()
//i := ReadInt()
//X := ReadIntSlice(n)
//S := ReadRuneSlice()
//a := ReadFloat64()
//A := ReadFloat64Slice(n)

//str := ZeroPaddingRuneSlice(num, 32)
//str := PrintIntsLine(X...)

/*******************************************************************/

const (
	// General purpose
	MOD          = 1000000000 + 7
	ALPHABET_NUM = 26
	INF_INT64    = math.MaxInt64
	INF_BIT60    = 1 << 60
	INF_INT32    = math.MaxInt32
	INF_BIT30    = 1 << 30
	NIL          = -1

	// for dijkstra, prim, and so on
	WHITE = 0
	GRAY  = 1
	BLACK = 2
)

func init() {
	// bufio.ScanWords <---> bufio.ScanLines
	ReadString = newReadString(os.Stdin, bufio.ScanWords)
	stdout = bufio.NewWriter(os.Stdout)
}

var (
	t    int
	n, m int
	a, b int
)

func main() {
	t = ReadInt()
	for i := 0; i < t; i++ {
		n, m, a, b = ReadInt4()
		solve(n, m, a, b)
	}
}

func solve(n, m, a, b int) {
	if n*a != m*b {
		fmt.Println("NO")
		return
	}

	res := [][]rune{}

	C := make([]int, m)

	for i := 0; i < n; i++ {
		row := []rune{}

		nokori := a
		for j := 0; j < m; j++ {
			if C[j] < b && nokori > 0 {
				row = append(row, '1')
				C[j]++
				nokori--
			} else {
				row = append(row, '0')
			}
		}

		res = append(res, row)
	}

	sum := 0
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if res[i][j] == '1' {
				sum++
			}
		}
	}
	if sum != n*a || sum != m*b {
		fmt.Println("NO")
		return
	}

	fmt.Println("YES")
	for i := 0; i < n; i++ {
		fmt.Println(string(res[i]))
	}
}

/*******************************************************************/

/*********** I/O ***********/

var (
	// ReadString returns a WORD string.
	ReadString func() string
	stdout     *bufio.Writer
)

func newReadString(ior io.Reader, sf bufio.SplitFunc) func() string {
	r := bufio.NewScanner(ior)
	r.Buffer(make([]byte, 1024), int(1e+9)) // for Codeforces
	r.Split(sf)

	return func() string {
		if !r.Scan() {
			panic("Scan failed")
		}
		return r.Text()
	}
}

// ReadInt returns an integer.
func ReadInt() int {
	return int(readInt64())
}
func ReadInt2() (int, int) {
	return int(readInt64()), int(readInt64())
}
func ReadInt3() (int, int, int) {
	return int(readInt64()), int(readInt64()), int(readInt64())
}
func ReadInt4() (int, int, int, int) {
	return int(readInt64()), int(readInt64()), int(readInt64()), int(readInt64())
}

// ReadInt64 returns as integer as int64.
func ReadInt64() int64 {
	return readInt64()
}
func ReadInt64_2() (int64, int64) {
	return readInt64(), readInt64()
}
func ReadInt64_3() (int64, int64, int64) {
	return readInt64(), readInt64(), readInt64()
}
func ReadInt64_4() (int64, int64, int64, int64) {
	return readInt64(), readInt64(), readInt64(), readInt64()
}

func readInt64() int64 {
	i, err := strconv.ParseInt(ReadString(), 0, 64)
	if err != nil {
		panic(err.Error())
	}
	return i
}

// ReadIntSlice returns an integer slice that has n integers.
func ReadIntSlice(n int) []int {
	b := make([]int, n)
	for i := 0; i < n; i++ {
		b[i] = ReadInt()
	}
	return b
}

// ReadInt64Slice returns as int64 slice that has n integers.
func ReadInt64Slice(n int) []int64 {
	b := make([]int64, n)
	for i := 0; i < n; i++ {
		b[i] = ReadInt64()
	}
	return b
}

// ReadFloat64 returns an float64.
func ReadFloat64() float64 {
	return float64(readFloat64())
}

func readFloat64() float64 {
	f, err := strconv.ParseFloat(ReadString(), 64)
	if err != nil {
		panic(err.Error())
	}
	return f
}

// ReadFloatSlice returns an float64 slice that has n float64.
func ReadFloat64Slice(n int) []float64 {
	b := make([]float64, n)
	for i := 0; i < n; i++ {
		b[i] = ReadFloat64()
	}
	return b
}

// ReadRuneSlice returns a rune slice.
func ReadRuneSlice() []rune {
	return []rune(ReadString())
}

/*********** Debugging ***********/

// ZeroPaddingRuneSlice returns binary expressions of integer n with zero padding.
// For debugging use.
func ZeroPaddingRuneSlice(n, digitsNum int) []rune {
	sn := fmt.Sprintf("%b", n)

	residualLength := digitsNum - len(sn)
	if residualLength <= 0 {
		return []rune(sn)
	}

	zeros := make([]rune, residualLength)
	for i := 0; i < len(zeros); i++ {
		zeros[i] = '0'
	}

	res := []rune{}
	res = append(res, zeros...)
	res = append(res, []rune(sn)...)

	return res
}

// Strtoi is a wrapper of strconv.Atoi().
// If strconv.Atoi() returns an error, Strtoi calls panic.
func Strtoi(s string) int {
	if i, err := strconv.Atoi(s); err != nil {
		panic(errors.New("[argument error]: Strtoi only accepts integer string"))
	} else {
		return i
	}
}

// PrintIntsLine returns integers string delimited by a space.
func PrintIntsLine(A ...int) string {
	res := []rune{}

	for i := 0; i < len(A); i++ {
		str := strconv.Itoa(A[i])
		res = append(res, []rune(str)...)

		if i != len(A)-1 {
			res = append(res, ' ')
		}
	}

	return string(res)
}

// PrintIntsLine returns integers string delimited by a space.
func PrintInts64Line(A ...int64) string {
	res := []rune{}

	for i := 0; i < len(A); i++ {
		str := strconv.FormatInt(A[i], 10) // 64bit int version
		res = append(res, []rune(str)...)

		if i != len(A)-1 {
			res = append(res, ' ')
		}
	}

	return string(res)
}

// PrintfDebug is wrapper of fmt.Fprintf(os.Stderr, format, a...)
func PrintfDebug(format string, a ...interface{}) {
	fmt.Fprintf(os.Stderr, format, a...)
}

// PrintfBufStdout is function for output strings to buffered os.Stdout.
// You may have to call stdout.Flush() finally.
func PrintfBufStdout(format string, a ...interface{}) {
	fmt.Fprintf(stdout, format, a...)
}

/*
URL:
https://codeforces.com/contest/1360/problem/G
*/

package main

import (
	"bufio"
	"errors"
	"fmt"
	"io"
	"math"
	"os"
	"strconv"
)

/********** FAU standard libraries **********/

//fmt.Sprintf("%b\n", 255) 	// binary expression

/********** I/O usage **********/

//str := ReadString()
//i := ReadInt()
//X := ReadIntSlice(n)
//S := ReadRuneSlice()
//a := ReadFloat64()
//A := ReadFloat64Slice(n)

//str := ZeroPaddingRuneSlice(num, 32)
//str := PrintIntsLine(X...)

/*******************************************************************/

const (
	// General purpose
	MOD          = 1000000000 + 7
	ALPHABET_NUM = 26
	INF_INT64    = math.MaxInt64
	INF_BIT60    = 1 << 60
	INF_INT32    = math.MaxInt32
	INF_BIT30    = 1 << 30
	NIL          = -1

	// for dijkstra, prim, and so on
	WHITE = 0
	GRAY  = 1
	BLACK = 2
)

func init() {
	// bufio.ScanWords <---> bufio.ScanLines
	ReadString = newReadString(os.Stdin, bufio.ScanWords)
	stdout = bufio.NewWriter(os.Stdout)
}

var (
	t    int
	n, m int
	a, b int
)

func main() {
	t = ReadInt()
	for i := 0; i < t; i++ {
		n, m, a, b = ReadInt4()
		solve(n, m, a, b)
	}
}

func solve(n, m, a, b int) {
	if n*a != m*b {
		fmt.Println("NO")
		return
	}
	if !(n%b == 0 && m%a == 0) {
		fmt.Println("NO")
		return
	}

	res := [][]rune{}

	C := make([]int, m)

	for i := 0; i < n; i++ {
		row := []rune{}

		nokori := a
		for j := 0; j < m; j++ {
			if C[j] < b && nokori > 0 {
				row = append(row, '1')
				C[j]++
				nokori--
			} else {
				row = append(row, '0')
			}
		}

		res = append(res, row)
	}

	// sum := 0
	// for i := 0; i < n; i++ {
	// 	for j := 0; j < m; j++ {
	// 		if res[i][j] == '1' {
	// 			sum++
	// 		}
	// 	}
	// }
	// if sum != n*a || sum != m*b {
	// 	fmt.Println("NO")
	// 	return
	// }

	fmt.Println("YES")
	for i := 0; i < n; i++ {
		fmt.Println(string(res[i]))
	}
}

/*******************************************************************/

/*********** I/O ***********/

var (
	// ReadString returns a WORD string.
	ReadString func() string
	stdout     *bufio.Writer
)

func newReadString(ior io.Reader, sf bufio.SplitFunc) func() string {
	r := bufio.NewScanner(ior)
	r.Buffer(make([]byte, 1024), int(1e+9)) // for Codeforces
	r.Split(sf)

	return func() string {
		if !r.Scan() {
			panic("Scan failed")
		}
		return r.Text()
	}
}

// ReadInt returns an integer.
func ReadInt() int {
	return int(readInt64())
}
func ReadInt2() (int, int) {
	return int(readInt64()), int(readInt64())
}
func ReadInt3() (int, int, int) {
	return int(readInt64()), int(readInt64()), int(readInt64())
}
func ReadInt4() (int, int, int, int) {
	return int(readInt64()), int(readInt64()), int(readInt64()), int(readInt64())
}

// ReadInt64 returns as integer as int64.
func ReadInt64() int64 {
	return readInt64()
}
func ReadInt64_2() (int64, int64) {
	return readInt64(), readInt64()
}
func ReadInt64_3() (int64, int64, int64) {
	return readInt64(), readInt64(), readInt64()
}
func ReadInt64_4() (int64, int64, int64, int64) {
	return readInt64(), readInt64(), readInt64(), readInt64()
}

func readInt64() int64 {
	i, err := strconv.ParseInt(ReadString(), 0, 64)
	if err != nil {
		panic(err.Error())
	}
	return i
}

// ReadIntSlice returns an integer slice that has n integers.
func ReadIntSlice(n int) []int {
	b := make([]int, n)
	for i := 0; i < n; i++ {
		b[i] = ReadInt()
	}
	return b
}

// ReadInt64Slice returns as int64 slice that has n integers.
func ReadInt64Slice(n int) []int64 {
	b := make([]int64, n)
	for i := 0; i < n; i++ {
		b[i] = ReadInt64()
	}
	return b
}

// ReadFloat64 returns an float64.
func ReadFloat64() float64 {
	return float64(readFloat64())
}

func readFloat64() float64 {
	f, err := strconv.ParseFloat(ReadString(), 64)
	if err != nil {
		panic(err.Error())
	}
	return f
}

// ReadFloatSlice returns an float64 slice that has n float64.
func ReadFloat64Slice(n int) []float64 {
	b := make([]float64, n)
	for i := 0; i < n; i++ {
		b[i] = ReadFloat64()
	}
	return b
}

// ReadRuneSlice returns a rune slice.
func ReadRuneSlice() []rune {
	return []rune(ReadString())
}

/*********** Debugging ***********/

// ZeroPaddingRuneSlice returns binary expressions of integer n with zero padding.
// For debugging use.
func ZeroPaddingRuneSlice(n, digitsNum int) []rune {
	sn := fmt.Sprintf("%b", n)

	residualLength := digitsNum - len(sn)
	if residualLength <= 0 {
		return []rune(sn)
	}

	zeros := make([]rune, residualLength)
	for i := 0; i < len(zeros); i++ {
		zeros[i] = '0'
	}

	res := []rune{}
	res = append(res, zeros...)
	res = append(res, []rune(sn)...)

	return res
}

// Strtoi is a wrapper of strconv.Atoi().
// If strconv.Atoi() returns an error, Strtoi calls panic.
func Strtoi(s string) int {
	if i, err := strconv.Atoi(s); err != nil {
		panic(errors.New("[argument error]: Strtoi only accepts integer string"))
	} else {
		return i
	}
}

// PrintIntsLine returns integers string delimited by a space.
func PrintIntsLine(A ...int) string {
	res := []rune{}

	for i := 0; i < len(A); i++ {
		str := strconv.Itoa(A[i])
		res = append(res, []rune(str)...)

		if i != len(A)-1 {
			res = append(res, ' ')
		}
	}

	return string(res)
}

// PrintIntsLine returns integers string delimited by a space.
func PrintInts64Line(A ...int64) string {
	res := []rune{}

	for i := 0; i < len(A); i++ {
		str := strconv.FormatInt(A[i], 10) // 64bit int version
		res = append(res, []rune(str)...)

		if i != len(A)-1 {
			res = append(res, ' ')
		}
	}

	return string(res)
}

// PrintfDebug is wrapper of fmt.Fprintf(os.Stderr, format, a...)
func PrintfDebug(format string, a ...interface{}) {
	fmt.Fprintf(os.Stderr, format, a...)
}

// PrintfBufStdout is function for output strings to buffered os.Stdout.
// You may have to call stdout.Flush() finally.
func PrintfBufStdout(format string, a ...interface{}) {
	fmt.Fprintf(stdout, format, a...)
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
)

// github.com/EndlessCheng/codeforces-go
func run(_r io.Reader, _w io.Writer) {
	in := bufio.NewReader(_r)
	out := bufio.NewWriter(_w)
	defer out.Flush()

	var t, n, m, a, b int
o:
	for Fscan(in, &t); t > 0; t-- {
		Fscan(in, &n, &m, &a, &b)
		if n%b != 0 || m%a != 0 {
			Fprintln(out, "NO")
			continue
		}
		ans := make([][]byte, n)
		for i := range ans {
			ans[i] = make([]byte, m)
			for j := range ans[i] {
				ans[i][j] = '0'
			}
		}
		for i := 0; i < n; i++ {
			st := i / b * a
			for j := st; j < st+a; j++ {
				if j >= m {
					Fprintln(out, "NO")
					continue o
				}
				ans[i][j] = '1'
			}
		}
		Fprintln(out, "YES")
		for _, an := range ans {
			Fprintln(out, string(an))
		}
	}
}

func main() { run(os.Stdin, os.Stdout) }

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
)

// github.com/EndlessCheng/codeforces-go
func run(_r io.Reader, _w io.Writer) {
	in := bufio.NewReader(_r)
	out := bufio.NewWriter(_w)
	defer out.Flush()

	var t, n, m, a, b int
	for Fscan(in, &t); t > 0; t-- {
		Fscan(in, &n, &m, &a, &b)
		if n%b != 0 || m%a != 0 || n*a != m*b {
			Fprintln(out, "NO")
			continue
		}
		ans := make([][]byte, n)
		for i := range ans {
			ans[i] = make([]byte, m)
			for j := range ans[i] {
				ans[i][j] = '0'
			}
		}
		for i := 0; i < n; i++ {
			st := i / b * a
			for j := st; j < st+a; j++ {
				ans[i][j] = '1'
			}
		}
		Fprintln(out, "YES")
		for _, an := range ans {
			Fprintln(out, string(an))
		}
	}
}

func main() { run(os.Stdin, os.Stdout) }

package main

import (
	"bufio"
	. "fmt"
	"os"
)

var (
	inn = bufio.NewScanner(os.Stdin)
	// in  = bufio.NewReader(os.Stdin)
	out = bufio.NewWriter(os.Stdout)
)

func main() {
	defer out.Flush()
	inn.Split(bufio.ScanWords)

	for tt := rd(); tt > 0; tt-- {
		n, m, a, b := rd(), rd(), rd(), rd()
		if n*a != b*m {
			Fprintln(out, "NO")
			continue
		}
		ans := make([][]int, n)
		c := 0
		for i := 0; i < n; i++ {
			ans[i] = make([]int, m)
			ans[i][c] = 1
			c = (c + 1) % m
		}
		Fprintln(out, "YES")
		for _, i := range ans {
			for _, j := range i {
				Fprint(out, j)
			}
			Fprintln(out)
		}
	}
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}
func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}
func rd() (x int) {
	inn.Scan()
	data := inn.Bytes()
	f := 1
	if data[0] == '-' {
		f = -1
		data = data[1:]
	}
	for _, b := range data {
		x = x*10 + int(b&15)
	}
	return f * x
}
func rdll() (x int64) {
	inn.Scan()
	data := inn.Bytes()
	f := int64(1)
	if data[0] == '-' {
		f = -1
		data = data[1:]
	}
	for _, b := range data {
		x = x*10 + int64(b&15)
	}
	return f * x
}


Cirno has a DAG (Directed Acyclic Graph) with $$$n$$$ nodes and $$$m$$$ edges. The graph has exactly one node that has no out edges. The $$$i$$$-th node has an integer $$$a_i$$$ on it.Every second the following happens: Let $$$S$$$ be the set of nodes $$$x$$$ that have $$$a_x > 0$$$. For all $$$x \in S$$$, $$$1$$$ is subtracted from $$$a_x$$$, and then for each node $$$y$$$, such that there is an edge from $$$x$$$ to $$$y$$$, $$$1$$$ is added to $$$a_y$$$.Find the first moment of time when all $$$a_i$$$ become $$$0$$$. Since the answer can be very large, output it modulo $$$998\,244\,353$$$.

The first line contains a single integer $$$t$$$ ($$$1 \leq t \leq 1000$$$) — the number of test cases. Description of test cases follows. The first line of each test case contains two integers $$$n, m$$$ ($$$1 \leq n, m \leq 1000$$$) — the number of vertices and edges in the graph. The second line of each test case contains $$$n$$$ integers $$$a_1, a_2, \ldots, a_n$$$ ($$$0 \leq a_i \leq 10^9$$$) — the integer on vertices. Each line of the following $$$m$$$ lines contains two integers $$$x, y$$$ ($$$1 \leq x, y \leq n$$$), represent a directed edge from $$$x$$$ to $$$y$$$. It is guaranteed that the graph is a DAG with no multi-edges, and there is exactly one node that has no out edges. It is guaranteed that both sum of $$$n$$$ and sum of $$$m$$$ over all test cases are less than or equal to $$$10\,000$$$.

For each test case, print an integer in a separate line — the first moment of time when all $$$a_i$$$ become $$$0$$$, modulo $$$998\,244\,353$$$.

NoteIn the first test case: At time $$$0$$$, the values of the nodes are $$$[1, 1, 1]$$$.  At time $$$1$$$, the values of the nodes are $$$[0, 1, 1]$$$.  At time $$$2$$$, the values of the nodes are $$$[0, 0, 1]$$$.  At time $$$3$$$, the values of the nodes are $$$[0, 0, 0]$$$.So the answer is $$$3$$$. In the second test case:  At time $$$0$$$, the values of the nodes are $$$[1, 0, 0, 0, 0]$$$.  At time $$$1$$$, the values of the nodes are $$$[0, 1, 0, 0, 1]$$$.  At time $$$2$$$, the values of the nodes are $$$[0, 0, 1, 0, 0]$$$.  At time $$$3$$$, the values of the nodes are $$$[0, 0, 0, 1, 0]$$$.  At time $$$4$$$, the values of the nodes are $$$[0, 0, 0, 0, 1]$$$.  At time $$$5$$$, the values of the nodes are $$$[0, 0, 0, 0, 0]$$$.  So the answer is $$$5$$$.In the third test case:The first moment of time when all $$$a_i$$$ become $$$0$$$ is $$$6\cdot 998244353 + 4$$$.

package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
)

var _, _, _ = main, rw, do

func main() {
	r, w := bufio.NewReader(os.Stdin), bufio.NewWriter(os.Stdout)
	defer w.Flush()
	rw(r, w)
}

func rw(r io.Reader, w io.Writer) {
	var t int
	fmt.Fscan(r, &t)
	for ti := 0; ti < t; ti++ {
		var n, m int
		fmt.Fscan(r, &n, &m)
		a := make([]int32, n)
		for i := range a {
			fmt.Fscan(r, &a[i])
		}
		b := make([][2]int, m)
		for i := range b {
			fmt.Fscan(r, &b[i][0], &b[i][1])
		}
		w1 := do(n, m, a, b)
		fmt.Fprintln(w, w1)
	}
}

func do(n, m int, a []int32, b [][2]int) int32 {
	topo := func() ([]int, map[int][]int) {
		g := make(map[int][]int)
		in := make([]int, n)
		for _, e := range b {
			e[0]--
			e[1]--
			g[e[0]] = append(g[e[0]], e[1])
			in[e[1]]++
		}
		q := []int{}
		for x := range in {
			if in[x] == 0 {
				q = append(q, x)
			}
		}
		for i := 0; i < len(q); i++ {
			x := q[i]
			for _, y := range g[x] {
				in[y]--
				if in[y] == 0 {
					q = append(q, y)
				}
			}
		}
		return q, g
	}
	var mod int32 = 998244353
	upd := func(x int, v int32) {
		a[x] = ((a[x])%mod + v) % mod
	}
	// inc := func(x int) {
	// 	upd(x, 1)
	// }
	// dec := func(x int) {
	// 	upd(x, -1)
	// }
	q, g := topo()
	var k int32 = 0
	for k < int32(n) {
		end := true
		for i := len(q) - 1; i >= 0; i-- {
			x := q[i]
			if a[x] <= 0 {
				continue
			}
			end = false
			a[x]--
			// dec(x)
			for _, y := range g[x] {
				a[y]++
				// inc(y)
			}
		}
		if end {
			return k
		}
		k++
	}
	for _, x := range q {
		for _, y := range g[x] {
			upd(y, a[x])
		}
	}
	return (k + a[q[len(q)-1]]) % mod
}

package main

import (
	"bufio"
	"bytes"
	"fmt"
	"os"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	var buf bytes.Buffer

	tc := readNum(reader)

	for tc > 0 {
		tc--
		n, m := readTwoNums(reader)
		A := readNNums(reader, n)
		edges := make([][]int, m)
		for i := 0; i < m; i++ {
			edges[i] = readNNums(reader, 2)
		}
		res := solve(n, edges, A)

		buf.WriteString(fmt.Sprintf("%d\n", res))
	}

	fmt.Print(buf.String())
}

func readString(reader *bufio.Reader) string {
	s, _ := reader.ReadString('\n')
	for i := 0; i < len(s); i++ {
		if s[i] == '\n' || s[i] == '\r' {
			return s[:i]
		}
	}
	return s
}

func normalize(s string) string {

	for i := len(s); i > 0; i-- {
		if s[i-1] >= 'a' && s[i-1] <= 'z' {
			return s[:i]
		}
	}
	return ""
}

func readInt(bytes []byte, from int, val *int) int {
	i := from
	sign := 1
	if bytes[i] == '-' {
		sign = -1
		i++
	}
	tmp := 0
	for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' {
		tmp = tmp*10 + int(bytes[i]-'0')
		i++
	}
	*val = tmp * sign
	return i
}

func readNum(reader *bufio.Reader) (a int) {
	bs, _ := reader.ReadBytes('\n')
	readInt(bs, 0, &a)
	return
}

func readTwoNums(reader *bufio.Reader) (a int, b int) {
	res := readNNums(reader, 2)
	a, b = res[0], res[1]
	return
}

func readThreeNums(reader *bufio.Reader) (a int, b int, c int) {
	res := readNNums(reader, 3)
	a, b, c = res[0], res[1], res[2]
	return
}

func readNNums(reader *bufio.Reader, n int) []int {
	res := make([]int, n)
	x := 0
	bs, _ := reader.ReadBytes('\n')
	for i := 0; i < n; i++ {
		for x < len(bs) && (bs[x] < '0' || bs[x] > '9') && bs[x] != '-' {
			x++
		}
		x = readInt(bs, x, &res[i])
	}
	return res
}

func readUint64(bytes []byte, from int, val *uint64) int {
	i := from

	var tmp uint64
	for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' {
		tmp = tmp*10 + uint64(bytes[i]-'0')
		i++
	}
	*val = tmp

	return i
}

const M = 998244353

func solve(n int, edges [][]int, a []int) int {
	g := make([][]int, n+1)
	z := make([][]int, n+1)
	for i := 0; i <= n; i++ {
		g[i] = make([]int, 0, 2)
		z[i] = make([]int, 0, 2)
	}

	D := make([]int, n+1)

	for _, edge := range edges {
		u, v := edge[0], edge[1]
		g[u] = append(g[u], v)
		z[v] = append(z[v], u)
		D[u]++
	}
	A := make([]int, n+1)
	copy(A[1:], a)
	B := make([]int, n+1)
	copy(B, A)

	C := make([]int, n+1)

	for i := 1; i <= n; i++ {
		var flow bool
		for j := 1; j <= n; j++ {
			if B[j] > 0 {
				flow = true
				break
			}
		}
		if !flow {
			return i - 1
		}

		for u := 1; u <= n; u++ {
			if B[u] > 0 {
				// C[j] 可能被其他的j增加，所以不能直接等于
				C[u] += B[u] - 1
				for _, v := range g[u] {
					C[v]++
				}
			}
		}

		for u := 1; u <= n; u++ {
			if C[u] >= M {
				// 如果C[u] = M, B[u] = 0, 将得到错误的结果
				B[u] = C[u]%M + M
			} else {
				B[u] = C[u] % M
			}
			C[u] = 0
		}
	}

	// not ending before n iterations
	que := make([]int, n+1)
	var end int
	for u := 1; u <= n; u++ {
		if D[u] == 0 {
			end++
			que[end] = u
		}
	}

	s := make([]int, n+1)
	s[que[end]] = 1

	for i := 1; i <= end; i++ {
		s[que[i]] %= M
		for _, v := range z[que[i]] {
			D[v]--
			s[v] += s[que[i]]
			if D[v] == 0 {
				end++
				que[end] = v
			}
		}
	}

	var ans int64 = int64(n)

	for i := 1; i <= n; i++ {
		ans = (ans + int64(B[i])*int64(s[i])%M) % M
	}

	return int(ans)
}

package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
)

var _, _, _ = main, rw, do

func main() {
	r, w := bufio.NewReader(os.Stdin), bufio.NewWriter(os.Stdout)
	defer w.Flush()
	rw(r, w)
}

func rw(r io.Reader, w io.Writer) {
	var t int
	fmt.Fscan(r, &t)
	for ti := 0; ti < t; ti++ {
		var n, m int
		fmt.Fscan(r, &n, &m)
		a := make([]int32, n)
		for i := range a {
			fmt.Fscan(r, &a[i])
		}
		b := make([][2]int, m)
		for i := range b {
			fmt.Fscan(r, &b[i][0], &b[i][1])
		}
		w1 := do(n, m, a, b)
		fmt.Fprintln(w, w1)
	}
}

func do(n, m int, a []int32, b [][2]int) int32 {
	topo := func() ([]int, map[int][]int) {
		g := make(map[int][]int)
		in := make([]int, n)
		for _, e := range b {
			e[0]--
			e[1]--
			g[e[0]] = append(g[e[0]], e[1])
			in[e[1]]++
		}
		q := []int{}
		for x := range in {
			if in[x] == 0 {
				q = append(q, x)
			}
		}
		for i := 0; i < len(q); i++ {
			x := q[i]
			for _, y := range g[x] {
				in[y]--
				if in[y] == 0 {
					q = append(q, y)
				}
			}
		}
		return q, g
	}
	var mod int32 = 998244353
	upd := func(x int, v int32) {
		a[x] = ((a[x]+v)%mod + mod) % mod
	}
	inc := func(x int) {
		upd(x, 1)
	}
	dec := func(x int) {
		upd(x, -1)
	}
	q, g := topo()
	var k int32 = 0
	for k < int32(n) {
		end := true
		for i := len(q) - 1; i >= 0; i-- {
			x := q[i]
			if a[x] <= 0 {
				continue
			}
			end = false
			dec(x)
			for _, y := range g[x] {
				inc(y)
			}
		}
		if end {
			return k % mod
		}
		k++
	}
	for _, x := range q {
		for _, y := range g[x] {
			upd(y, a[x])
		}
	}
	return (k + a[q[len(q)-1]]) % mod
}

package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
)

var _, _, _ = main, rw, do

func main() {
	r, w := bufio.NewReader(os.Stdin), bufio.NewWriter(os.Stdout)
	defer w.Flush()
	rw(r, w)
}

func rw(r io.Reader, w io.Writer) {
	var t int
	fmt.Fscan(r, &t)
	for ti := 0; ti < t; ti++ {
		var n, m int
		fmt.Fscan(r, &n, &m)
		a := make([]int, n)
		for i := range a {
			fmt.Fscan(r, &a[i])
		}
		b := make([][2]int, m)
		for i := range b {
			fmt.Fscan(r, &b[i][0], &b[i][1])
		}
		w1 := do(n, m, a, b)
		fmt.Fprintln(w, w1)
	}
}

func do(n, m int, a []int, b [][2]int) int {
	topo := func() ([]int, map[int][]int) {
		g := make(map[int][]int)
		in := make([]int, n)
		for _, e := range b {
			e[0]--
			e[1]--
			g[e[0]] = append(g[e[0]], e[1])
			in[e[1]]++
		}
		q := []int{}
		for x := range in {
			if in[x] == 0 {
				q = append(q, x)
			}
		}
		for i := 0; i < len(q); i++ {
			x := q[i]
			for _, y := range g[x] {
				in[y]--
				if in[y] == 0 {
					q = append(q, y)
				}
			}
		}
		return q, g
	}
	mod := 998244353
	upd := func(x, v int) {
		a[x] = (a[x] + mod + v) % mod
	}
	inc := func(x int) {
		upd(x, 1)
	}
	dec := func(x int) {
		upd(x, -1)
	}
	q, g := topo()
	k := 0
	for k < n {
		end := true
		for i := len(q) - 1; i >= 0; i-- {
			x := q[i]
			if a[x] <= 0 {
				continue
			}
			end = false
			dec(x)
			for _, y := range g[x] {
				inc(y)
			}
		}
		if end {
			return k % mod
		}
		k++
	}
	for _, x := range q {
		for _, y := range g[x] {
			upd(y, a[x])
		}
	}
	return (k + a[q[len(q)-1]]) % mod
}