← Home
package main

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

func nextInt(reader *bufio.Reader) int {
	var res int
	for {
		b, err := reader.ReadByte()
		if err != nil {
			return 0
		}
		if b >= '0' && b <= '9' {
			res = int(b - '0')
			break
		}
	}
	for {
		b, err := reader.ReadByte()
		if err != nil {
			break
		}
		if b >= '0' && b <= '9' {
			res = res*10 + int(b-'0')
		} else {
			break
		}
	}
	return res
}

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

	n := nextInt(reader)
	if n == 0 {
		return
	}

	MOD := int64(998244353)

	type Edge struct{ u, v int }
	maxW := n * (n - 1) / 2
	edgeList := make([]Edge, maxW+1)

	for i := 1; i <= n; i++ {
		for j := 1; j <= n; j++ {
			w := nextInt(reader)
			if i < j {
				edgeList[w] = Edge{i, j}
			}
		}
	}

	parent := make([]int, n+1)
	size := make([]int, n+1)
	edges := make([]int, n+1)
	children := make([][]int, n+1)
	poly := make([][]int, 2*n+1)

	for i := 1; i <= n; i++ {
		parent[i] = i
		size[i] = 1
		edges[i] = 0
		children[i] = []int{i}
		poly[i] = []int{0, 1}
	}

	var find func(i int) int
	find = func(i int) int {
		if parent[i] == i {
			return i
		}
		parent[i] = find(parent[i])
		return parent[i]
	}

	nodeCount := n

	for w := 1; w <= maxW; w++ {
		u := edgeList[w].u
		v := edgeList[w].v

		ru := find(u)
		rv := find(v)

		var r int
		if ru != rv {
			if size[ru] < size[rv] {
				ru, rv = rv, ru
			}
			parent[rv] = ru
			size[ru] += size[rv]
			edges[ru] += edges[rv] + 1
			children[ru] = append(children[ru], children[rv]...)
			r = ru
		} else {
			edges[ru]++
			r = ru
		}

		if edges[r] == size[r]*(size[r]-1)/2 {
			nodeCount++
			G := nodeCount

			res := []int{1}
			for _, c := range children[r] {
				pc := poly[c]
				newRes := make([]int, len(res)+len(pc)-1)
				for i := 0; i < len(res); i++ {
					if res[i] == 0 {
						continue
					}
					for j := 0; j < len(pc); j++ {
						newRes[i+j] = int((int64(newRes[i+j]) + int64(res[i])*int64(pc[j])) % MOD)
					}
				}
				res = newRes
			}

			if len(res) < 2 {
				temp := make([]int, 2)
				copy(temp, res)
				res = temp
			}
			res[1] = int((int64(res[1]) + 1) % MOD)

			poly[G] = res
			children[r] = []int{G}
		}
	}

	ans := poly[nodeCount]
	for i := 1; i <= n; i++ {
		if i < len(ans) {
			fmt.Fprintf(writer, "%d ", ans[i])
		} else {
			fmt.Fprintf(writer, "0 ")
		}
	}
	fmt.Fprintln(writer)
}