← Home
```go
package main

import (
	"bufio"
	"os"
)

func readInt(r *bufio.Reader) int {
	var n int
	var c byte
	var err error
	for {
		c, err = r.ReadByte()
		if err != nil {
			return n
		}
		if c >= '0' && c <= '9' {
			n = int(c - '0')
			break
		}
	}
	for {
		c, err = r.ReadByte()
		if err != nil {
			return n
		}
		if c >= '0' && c <= '9' {
			n = n*10 + int(c-'0')
		} else {
			break
		}
	}
	return n
}

func main() {
	reader := bufio.NewReaderSize(os.Stdin, 65536)
	writer := bufio.NewWriterSize(os.Stdout, 65536)
	defer writer.Flush()

	t := readInt(reader)
	for i := 0; i < t; i++ {
		n := readInt(reader)
		m := readInt(reader)

		adj := make([][]int, n+1)
		for j := 0; j < m; j++ {
			u := readInt(reader)
			v := readInt(reader)
			adj[u] = append(adj[u], v)
		}

		state := make([]int, n+1)
		ans := make([]int, n+1)
		cycleNodes := make([]int, 0)

		var dfs func(int)
		dfs = func(u int) {
			state[u] = 1
			ans[u] = 1
			for _, v := range adj[u] {
				if state[v] == 0 {
					dfs(v)
				} else if state[v] == 1 {
					cycleNodes = append(cycleNodes, v)
				}
			}
			state[u] = 2
		}

		dfs(1)

		isInf := make([]bool, n+1)
		queue := make([]int, 0, n)
		for _, v := range cycleNodes {
			if !isInf[v] {
				isInf[v] = true
				queue = append(queue, v)
			}
		}

		for head := 0; head < len(queue); head++ {
			u := queue[head]
			for _, v := range adj[u] {
				if ans[v] != 0 && !isInf[v] {
					isInf[v] = true
					queue = append(queue, v)
				}
			}
		}

		inDegree := make([]int, n+1)
		for u := 1; u <= n; u++ {
			if ans[u] != 0 && !isInf[u] {
				for _, v := range adj[u] {
					if ans[v] != 0 && !isInf[v] {
						inDegree[v]++
					}
				}
			}
		}

		q2 := make([]int, 0, n)
		for u := 1; u <= n; u++ {
			if ans[u] != 0 && !isInf[u] && inDegree[u] == 0 {
				q2 = append(q2, u)
			}
		}

		paths := make([]int, n+1)
		if ans[1] != 0 && !isInf[1] {
			paths[1] = 1
		}

		for head := 0; head < len(q2); head++ {
			u := q2[head]
			for _, v := range adj[u] {
				if ans[v] != 0 && !isInf[v] {
					paths[v] += paths[u]
					if paths[v] > 2 {
						paths[v] = 2
					}
					inDegree[v]--
					if inDegree[v] == 0 {
						q2 = append(q2, v)
					}
				}
			}
		}

		for j := 1; j <= n; j++ {
			if ans[j] == 0 {
				writer.WriteString("0 ")
			} else if isInf[j] {
				writer.WriteString("-1 ")
			} else {
				if paths[j] == 1 {
					writer.WriteString("1 ")
				} else {
					writer.WriteString("2 ")
				}
			}
		}
		writer.WriteByte('\n')
	}
}
```