//package com.example.codetest

import java.io.BufferedReader
import java.util.*
import kotlin.collections.ArrayList

class BinaryHeap<WeightedEdge : Comparable<WeightedEdge>> {

    // A dynamic array to track the elements inside the heap
    private lateinit var heap: ArrayList<WeightedEdge>

    // Construct a priority queue with an initial capacity, default capacity is 1
    constructor(sz: Int = 1) {
        heap = ArrayList(sz)
    }

    // Construct a priority queue using heapify in O(n) time,
    constructor(vararg elems: WeightedEdge) {

        val heapSize = elems.size
        heap = ArrayList(heapSize)

        // Place all element in heap
        heap.addAll(elems)

        // Heapify process, O(n)
        (maxOf(0, heapSize / 2 - 1) downTo 0).forEach { sink(it) }
    }

    // Construct a priority queue
    constructor(elems: Collection<WeightedEdge>) {

        val heapSize = elems.size
        heap = ArrayList(heapSize)

        // Place all element of the given collection to the heap
        heap.addAll(elems)

        // Heapify process, O(n)
        (maxOf(0, heapSize / 2 - 1) downTo 0).forEach { sink(it) }
    }

    // Returns true/false depending on if the priority queue is empty
    private fun isEmpty() = size() == 0

    // Clears everything inside the heap O(n)
    fun clear() {
        heap.clear()
    }

    // Return the size of teh heap
    private fun size() = heap.size

    // Return the value of the element with the lowest priority in this priority queue,
    // If the priority queue is empty, null is returned.
    fun peek(): WeightedEdge? = if (isEmpty()) null else heap[0]

    // Removes the root of the heap, O(log(n))
    fun poll() = removeAt(0)

    // Test if an element is in the heap, O(n)
    fun contains(elem: WeightedEdge) = heap.contains(elem)

    // Adds an element to the priority queue, O(log(n))
    fun add(elem: WeightedEdge) {

        heap.add(elem)

        val indexOfLastElem = size() - 1
        swim(indexOfLastElem)
    }

    // Test if the value of node i <= node j, assume i & j are valid indices, O(1)
    private fun less(i: Int, j: Int) = heap[i] <= heap[j]

    // Perform bottom up node swim, O(log(n))
    private fun swim(k: Int) {

        var child = k

        // Grab the index of the next parent node WRT to child
        var parent = (child - 1) / 2

        // Keep swimming while we have not reached the root and while
        // we're less than our parent
        while (child > 0 && less(child, parent)) {

            // Exchange child with parent
            swap(parent, child)

            // Get new child and parent
            child = parent
            parent = (child - 1) / 2
        }
    }

    // Top down node sink, O(log(n))
    private fun sink(k: Int) {
        var parent = k
        val heapSize = size()
        while (true) {
            val left = 2 * parent + 1 // Left node
            val right = 2 * parent + 2 // Right node
            var smallest = left // Assume left is the smallest node of the two children

            // Find which is smaller ? left or right
            if (right < heapSize && less(right, left)) smallest = right

            // Stop if we're outside the bounds of the tree
            // or stop early if we cannot sink k any more
            if (left >= heapSize || less(parent, smallest)) break

            // Move down the tree following the smallest node
            swap(parent, smallest)
            parent = smallest
        }
    }

    // Swap two nodes. Assume i & j are valid, O(1)
    private fun swap(i: Int, j: Int) {
        heap[i] = heap[j].also { heap[j] = heap[i] }
    }

    // Removes a particular element in the heap, O(n)
    fun remove(elem: WeightedEdge) = heap.remove(elem)

    // Remove a node at a paticular index, O(log(n))
    private fun removeAt(i: Int): WeightedEdge? {
        if (isEmpty()) return null

        val indexOfLastElem = size() - 1
        val removedData = heap[i]
        swap(i, indexOfLastElem)

        // Obliterate the value
        heap.removeAt(indexOfLastElem)

        // Check if the last element was removed
        if (i == indexOfLastElem) return removedData
        val elem = heap[i]

        // Try sinking element
        sink(i)

        // If sinking did not work try swimming
        if (elem == heap[i]) swim(i)
        return removedData
    }

    // Recursively check if this heap is a min heap
    private fun isMinHeap(k: Int): Boolean {
        // if we are outside the bounds of the heap return true
        val heapSize = size()
        if (k >= heapSize) return true

        val left = 2 * k + 1
        val right = 2 * k + 2

        // Make sure that the current node k is less than both of its children if they exist
        if (left < heapSize && !less(k, left)) return false
        if (right < heapSize && !less(k, right)) return false

        // Recurse on both children to make sure they're also valid
        return isMinHeap(left) && isMinHeap(right)
    }

    fun checkValid() {
        println(if (isMinHeap(0)) "Is MinHeap" else "Something goes wrong!!!")
    }

    override fun toString() = heap.toString()
}

data class Edge(val des: Int, val weight: Long)

data class WeightedEdge(val weight: Long, val leaf: Int) : Comparable<WeightedEdge> {
    private val diff: Long
        get() = (weight - weight / 2) * leaf

    override fun compareTo(other: WeightedEdge): Int {
        return if (this.diff < other.diff) 1
        else -1
    }
}

fun main() {
    val r = System.`in`.bufferedReader()
    val sb = StringBuilder()
    repeat(r.readInt()) {
        val n = r.readInt()
        val maxWeight = r.readInt()
        val adj = List(n) { mutableListOf<Edge>() }
        repeat(n - 1) {
            val u = r.readInt() - 1
            val v = r.readInt() - 1
            val w = r.readInt().toLong()
            adj[u] += Edge(v, w)
            adj[v] += Edge(u, w)
        }

        val parent = IntArray(n) { -1 }
        val childLeaf = IntArray(n) { 0 }
        val visited = BooleanArray(n) { false }

        fun dfs(i: Int): Int {
            visited[i] = true
            var leaf = 0
            adj[i].forEach {
                val (des, _) = it
                if (!visited[des]) {
                    leaf += dfs(des)
                    parent[des] = i
                }
            }
            if (i != 0 && adj[i].size == 1) leaf++
            childLeaf[i] = leaf
            return leaf
        }
        dfs(0)

        val heap = BinaryHeap<WeightedEdge>(n-1)
        val queue = LinkedList<Int>()
        queue.add(0)
        var totalWeight = 0L
        while (queue.isNotEmpty()) {
            val u = queue.removeFirst()
            adj[u].forEach {
                val (des, weight) = it
                if (parent[des] == u) {
                    heap.add(WeightedEdge(weight, childLeaf[des]))
                    queue.add(des)
                    totalWeight += weight * childLeaf[des]
                }
            }
        }

        var move = 0
        while (totalWeight > maxWeight) {
            val (wei, multi) = heap.poll()!!
            heap.add(WeightedEdge(wei/2, multi))
            totalWeight -= (wei-wei/2)*multi
            move++
        }
        sb.appendln(move)
    }
    print(sb)
}

// Hakiobo's code for faster reading input
private const val SPACE_INT = ' '.toInt()
private const val ZERO_INT = '0'.toInt()
private const val NL_INT = '\n'.toInt()

private fun BufferedReader.readInt(): Int {
    var ret = read()
    while (ret <= SPACE_INT) {
        ret = read()
    }
    val neg = ret == '-'.toInt()
    if (neg) {
        ret = read()
    }
    ret -= ZERO_INT
    var read = read()
    while (read >= ZERO_INT) {
        ret *= 10
        ret += read - ZERO_INT
        read = read()
    }

    while (read <= SPACE_INT && read != -1 && read != NL_INT) {
        mark(1)
        read = read()
    }
    if (read > SPACE_INT) {
        reset()
    }
    return if (neg) -ret else ret
}


import java.io.BufferedReader

data class Edge(val v: Int, var w: Long)

fun main() {
    val r = System.`in`.bufferedReader()
    val sb = StringBuilder()
    repeat(r.readInt()) {
        //println("Test case: $it")
        val n = r.readInt()
        val s = r.readInt().toLong()
        val adj = List(n) { mutableListOf<Edge>() }
        repeat(n - 1) {
            val u = r.readInt() - 1
            val v = r.readInt() - 1
            val w = r.readInt().toLong()
            adj[u] += Edge(v, w)
            adj[v] += Edge(u, w)
        }
        val visited = BooleanArray(n) { false }

        // Need leaf number, it is important. Another one is weight, other thing does not matter
        val leaves = arrayOfNulls<Int>(n)
        val weight = arrayOfNulls<Long>(n)
        //val edges = mutableListOf<Edge>()

        //var i = 0
        // return leaf
        weight[0] = 0
        fun dfs(v: Int): Int {
            visited[v] = true
            var leaf = 0
            // back edge, this is leaf
            if (adj[v].size == 1 && visited[adj[v][0].v]) {
                leaf++
            } else {
                // Count up child vertices's leaf
                for (e in adj[v]) {
                    if (!visited[e.v]) {
                        //edges += e
                        weight[e.v] = e.w
                        leaf += dfs(e.v)
                    }
                }
            }
            leaves[v] = leaf
            return leaf
        }
        dfs(0)

        val a = mutableListOf<Long>()
        var cursum = 0L
        /*for ((v, weight) in edges) {
            val l = leaves[v]!!
            var w = weight
            var diff = (w + 1 shr 1) * l
            while (diff > 0) {
                a.add(diff)
                w /= 2
                diff = (w + 1 shr 1) * l
            }
        }*/
        for (i in 1..n - 1) {
            var w = weight[i]!!
            val l = leaves[i]!!
            cursum += w * l
            while (w != 0L) {
                a.add((w + 1 shr 1) * l)
                w /= 2
            }
        }
        //var cursum: Long = edges.fold(0L) { acc, (v, w) -> acc + w * leaves[v]!! }
        //var cursum = a.sum()
        a.sortDescending()
        //println("can remove: $a")
        var b = 0
        while (cursum > s) {
            cursum -= a[b++]
        }
        sb.appendln(b)
    }
    print(sb)
}

// Hakiobo's code for faster reading input
private const val SPACE_INT = ' '.toInt()
private const val ZERO_INT = '0'.toInt()
private const val NL_INT = '\n'.toInt()

private fun BufferedReader.readInt(): Int {
    var ret = read()
    while (ret <= SPACE_INT) {
        ret = read()
    }
    val neg = ret == '-'.toInt()
    if (neg) {
        ret = read()
    }
    ret -= ZERO_INT
    var read = read()
    while (read >= ZERO_INT) {
        ret *= 10
        ret += read - ZERO_INT
        read = read()
    }

    while (read <= SPACE_INT && read != -1 && read != NL_INT) {
        mark(1)
        read = read()
    }
    if (read > SPACE_INT) {
        reset()
    }
    return if (neg) -ret else ret
}


//package com.example.codetest

import java.io.BufferedReader

data class Edge(val v: Int, var w: Long)

fun main() {
    val r = System.`in`.bufferedReader()
    val sb = StringBuilder()
    repeat(r.readInt()) {
        //println("Test case: $it")
        val n = r.readInt()
        val s = r.readLine()!!.toLong()
        val adj = List(n) { mutableListOf<Edge>() }
        repeat(n - 1) {
            val u = r.readInt() - 1
            val v = r.readInt() - 1
            val w = r.readInt().toLong()
            adj[u] += Edge(v, w)
            adj[v] += Edge(u, w)
        }

        val visited = BooleanArray(n) { false }
        val leaves = IntArray(n) { 0 }
        val weight = LongArray(n) { 0L }

        fun dfs(v: Int): Int {
            visited[v] = true
            var childLeaf = 0
            for (e in adj[v]) {
                if (!visited[e.v]) {
                    weight[e.v] = e.w
                    childLeaf += dfs(e.v)
                }
            }
            val leaf = maxOf(1, childLeaf)
            leaves[v] = leaf
            return leaf
        }
        dfs(0)

        val a = mutableListOf<Long>()
        var cursum = 0L

        for (i in 0..n - 1) {
            var w = weight[i]
            val l = leaves[i]
            cursum += w * l
            while (w != 0L) {
                a.add((w + 1 shr 1) * l)
                w /= 2
            }
        }
        a.sortDescending()

        var b = 0
        while (cursum > s) {
            cursum -= a[b]
            b++
        }
        sb.appendln(b)
    }
    print(sb)
}

// Hakiobo's code for faster reading input
private const val SPACE_INT = ' '.toInt()
private const val ZERO_INT = '0'.toInt()
private const val NL_INT = '\n'.toInt()

private fun BufferedReader.readInt(): Int {
    var ret = read()
    while (ret <= SPACE_INT) {
        ret = read()
    }
    val neg = ret == '-'.toInt()
    if (neg) {
        ret = read()
    }
    ret -= ZERO_INT
    var read = read()
    while (read >= ZERO_INT) {
        ret *= 10
        ret += read - ZERO_INT
        read = read()
    }

    while (read <= SPACE_INT && read != -1 && read != NL_INT) {
        mark(1)
        read = read()
    }
    if (read > SPACE_INT) {
        reset()
    }
    return if (neg) -ret else ret
}


import java.io.BufferedReader
import java.math.BigInteger

data class Edge(val v: Int, var w: Long)

fun main() {
    val r = System.`in`.bufferedReader()
    val sb = StringBuilder()
    repeat(r.readInt()) {
        //println("Test case: $it")
        val n = r.readInt()
        val s = r.readInt().toLong()
        val adj = List(n) { mutableListOf<Edge>() }
        repeat(n - 1) {
            val u = r.readInt() - 1
            val v = r.readInt() - 1
            val w = r.readInt().toLong()
            adj[u] += Edge(v, w)
            adj[v] += Edge(u, w)
        }
        val visited = BooleanArray(n) { false }

        // Need leaf number, it is important. Another one is weight, other thing does not matter
        val leaves = arrayOfNulls<Int>(n)
        val edges = mutableListOf<Edge>()

        //var i = 0
        // return leaf
        fun dfs(v: Int): Int {
            visited[v] = true
            var leaf = 0
            // back edge, this is leaf
            if (adj[v].size == 1 && visited[adj[v][0].v]) {
                leaf++
            } else {
                // Count up child vertices's leaf
                for (e in adj[v]) {
                    if (!visited[e.v]) {
                        edges += e
                        leaf += dfs(e.v)
                    }
                }
            }
            leaves[v] = leaf
            return leaf
        }
        dfs(0)

        val a = mutableListOf<Long>()

        for ((v, weight) in edges) {
            val l = leaves[v]!!
            var w = weight
            var diff = (w + 1 shr 1) * l
            while (diff > 0) {
                a.add(diff)
                w /= 2
                diff = (w + 1 shr 1) * l
            }
        }
        //var cursum: Long = edges.fold(0L) { acc, (v, w) -> acc + w * leaves[v]!! }
        var cursum = a.fold(BigInteger.ZERO){sum, i -> sum + BigInteger.valueOf (i)}
        a.sortDescending()
        //println("can remove: $a")
        var b = 0
        while (cursum > BigInteger.valueOf(s)) {
            cursum -= BigInteger.valueOf(a[b++])
        }
        sb.appendln(b)
    }
    print(sb)
}

// Hakiobo's code for faster reading input
private const val SPACE_INT = ' '.toInt()
private const val ZERO_INT = '0'.toInt()
private const val NL_INT = '\n'.toInt()

private fun BufferedReader.readInt(): Int {
    var ret = read()
    while (ret <= SPACE_INT) {
        ret = read()
    }
    val neg = ret == '-'.toInt()
    if (neg) {
        ret = read()
    }
    ret -= ZERO_INT
    var read = read()
    while (read >= ZERO_INT) {
        ret *= 10
        ret += read - ZERO_INT
        read = read()
    }

    while (read <= SPACE_INT && read != -1 && read != NL_INT) {
        mark(1)
        read = read()
    }
    if (read > SPACE_INT) {
        reset()
    }
    return if (neg) -ret else ret
}


import java.io.BufferedReader
import java.util.*

data class Edge(val v: Int, var w: Long)
data class WEdge(var w: Long, val l: Int) : Comparable<WEdge> {
    val diff: Long
        get() = w * l - w / 2 * l

    override fun compareTo(other: WEdge) = if (this.diff < other.diff) 1 else -1
}

fun main() {
    val r = System.`in`.bufferedReader()
    val sb = StringBuilder()
    repeat(r.readInt()) {
        //println("Test case: $it")
        val n = r.readInt()
        val s = r.readInt().toLong()
        val adj = List(n) { mutableListOf<Edge>() }
        repeat(n - 1) {
            val u = r.readInt() - 1
            val v = r.readInt() - 1
            val w = r.readInt().toLong()
            adj[u] += Edge(v, w)
            adj[v] += Edge(u, w)
        }
        val visited = BooleanArray(n) { false }
        val leaves = arrayOfNulls<Int>(n)
        val edges = Array(n-1){ Edge(-1, -1) }
        var i = 0
        fun dfs(v: Int): Int {
            visited[v] = true
            var leaf = 0
            // back edge, this is leaf
            if (adj[v].size == 1 && visited[adj[v][0].v]) {
                leaf++
            } else {
                // Count up child vertices's leaf
                for (e in adj[v]) {
                    if (!visited[e.v]) {
                        edges[i++] = e
                        leaf += dfs(e.v)
                    }
                }
            }
            leaves[v] = leaf
            return leaf
        }
        dfs(0)
        //println("edges: $edges")
        // have edge, need weight and leaves
        val pq = PriorityQueue<WEdge>()
        for ((v, w) in edges) {
            pq.add(WEdge(w, leaves[v]!!))
        }
        var cursum = pq.fold(0L) { acc, (w, l) -> acc + w * l }

        var step = 0
        //println("start sum: $cursum")
        while (cursum > s) {
            val e = pq.poll()!!
            step++
            cursum -= e.diff
            pq.add(e.copy(w = e.w / 2))
            //println("pop: $e, sun become: $cursum, add back: ${e.copy(w = e.w / 2)}")
        }
        sb.appendln(step)
    }
    print(sb)
}

// Hakiobo's code for faster reading input
private const val SPACE_INT = ' '.toInt()
private const val ZERO_INT = '0'.toInt()
private const val NL_INT = '\n'.toInt()

private fun BufferedReader.readInt(): Int {
    var ret = read()
    while (ret <= SPACE_INT) {
        ret = read()
    }
    val neg = ret == '-'.toInt()
    if (neg) {
        ret = read()
    }
    ret -= ZERO_INT
    var read = read()
    while (read >= ZERO_INT) {
        ret *= 10
        ret += read - ZERO_INT
        read = read()
    }

    while (read <= SPACE_INT && read != -1 && read != NL_INT) {
        mark(1)
        read = read()
    }
    if (read > SPACE_INT) {
        reset()
    }
    return if (neg) -ret else ret
}


import java.io.BufferedReader

data class Edge(val v: Int, var w: Long)

fun main() {
    val r = System.`in`.bufferedReader()
    val sb = StringBuilder()
    repeat(r.readInt()) {
        //println("Test case: $it")
        val n = r.readInt()
        val s = r.readInt().toLong()
        val adj = List(n) { mutableListOf<Edge>() }
        repeat(n - 1) {
            val u = r.readInt() - 1
            val v = r.readInt() - 1
            val w = r.readInt().toLong()
            adj[u] += Edge(v, w)
            adj[v] += Edge(u, w)
        }
        val visited = BooleanArray(n) { false }

        // Need leaf number, it is important. Another one is weight, other thing does not matter
        val leaves = arrayOfNulls<Int>(n)
        val edges = mutableListOf<Edge>()

        //var i = 0
        // return leaf
        fun dfs(v: Int): Int {
            visited[v] = true
            var leaf = 0
            // back edge, this is leaf
            if (adj[v].size == 1 && visited[adj[v][0].v]) {
                leaf++
            } else {
                // Count up child vertices's leaf
                for (e in adj[v]) {
                    if (!visited[e.v]) {
                        edges += e
                        leaf += dfs(e.v)
                    }
                }
            }
            leaves[v] = leaf
            return leaf
        }
        dfs(0)

        val a = mutableListOf<Long>()

        for ((v, weight) in edges) {
            val l = leaves[v]!!
            var w = weight
            var diff = (w + 1 shr 1) * l
            while (diff > 0) {
                a.add(diff)
                w /= 2
                diff = (w + 1 shr 1) * l
            }
        }
        //var cursum: Long = edges.fold(0L) { acc, (v, w) -> acc + w * leaves[v]!! }
        var cursum = a.sum()
        a.sortDescending()
        //println("can remove: $a")
        var b = 0
        while (cursum > s) {
            cursum -= a[b++]
        }
        sb.appendln(b)
    }
    print(sb)
}

// Hakiobo's code for faster reading input
private const val SPACE_INT = ' '.toInt()
private const val ZERO_INT = '0'.toInt()
private const val NL_INT = '\n'.toInt()

private fun BufferedReader.readInt(): Int {
    var ret = read()
    while (ret <= SPACE_INT) {
        ret = read()
    }
    val neg = ret == '-'.toInt()
    if (neg) {
        ret = read()
    }
    ret -= ZERO_INT
    var read = read()
    while (read >= ZERO_INT) {
        ret *= 10
        ret += read - ZERO_INT
        read = read()
    }

    while (read <= SPACE_INT && read != -1 && read != NL_INT) {
        mark(1)
        read = read()
    }
    if (read > SPACE_INT) {
        reset()
    }
    return if (neg) -ret else ret
}


import java.io.BufferedReader
import java.util.*
import kotlin.collections.ArrayList

class BinaryHeap<WeightedEdge : Comparable<WeightedEdge>> {

    // A dynamic array to track the elements inside the heap
    private lateinit var heap: ArrayList<WeightedEdge>

    // Construct a priority queue with an initial capacity, default capacity is 1
    constructor(sz: Int = 1) {
        heap = ArrayList(sz)
    }

    // Construct a priority queue using heapify in O(n) time,
    constructor(vararg elems: WeightedEdge) {

        val heapSize = elems.size
        heap = ArrayList(heapSize)

        // Place all element in heap
        heap.addAll(elems)

        // Heapify process, O(n)
        (maxOf(0, heapSize / 2 - 1) downTo 0).forEach { sink(it) }
    }

    // Construct a priority queue
    constructor(elems: Collection<WeightedEdge>) {

        val heapSize = elems.size
        heap = ArrayList(heapSize)

        // Place all element of the given collection to the heap
        heap.addAll(elems)

        // Heapify process, O(n)
        (maxOf(0, heapSize / 2 - 1) downTo 0).forEach { sink(it) }
    }

    // Returns true/false depending on if the priority queue is empty
    private fun isEmpty() = size() == 0

    // Clears everything inside the heap O(n)
    fun clear() {
        heap.clear()
    }

    // Return the size of teh heap
    private fun size() = heap.size

    // Return the value of the element with the lowest priority in this priority queue,
    // If the priority queue is empty, null is returned.
    fun peek(): WeightedEdge? = if (isEmpty()) null else heap[0]

    // Removes the root of the heap, O(log(n))
    fun poll() = removeAt(0)

    // Test if an element is in the heap, O(n)
    fun contains(elem: WeightedEdge) = heap.contains(elem)

    // Adds an element to the priority queue, O(log(n))
    fun add(elem: WeightedEdge) {

        heap.add(elem)

        val indexOfLastElem = size() - 1
        swim(indexOfLastElem)
    }

    // Test if the value of node i <= node j, assume i & j are valid indices, O(1)
    private fun less(i: Int, j: Int) = heap[i] <= heap[j]

    // Perform bottom up node swim, O(log(n))
    private fun swim(k: Int) {

        var child = k

        // Grab the index of the next parent node WRT to child
        var parent = (child - 1) / 2

        // Keep swimming while we have not reached the root and while
        // we're less than our parent
        while (child > 0 && less(child, parent)) {

            // Exchange child with parent
            swap(parent, child)

            // Get new child and parent
            child = parent
            parent = (child - 1) / 2
        }
    }

    // Top down node sink, O(log(n))
    private fun sink(k: Int) {
        var parent = k
        val heapSize = size()
        while (true) {
            val left = 2 * parent + 1 // Left node
            val right = 2 * parent + 2 // Right node
            var smallest = left // Assume left is the smallest node of the two children

            // Find which is smaller ? left or right
            if (right < heapSize && less(right, left)) smallest = right

            // Stop if we're outside the bounds of the tree
            // or stop early if we cannot sink k any more
            if (left >= heapSize || less(parent, smallest)) break

            // Move down the tree following the smallest node
            swap(parent, smallest)
            parent = smallest
        }
    }

    // Swap two nodes. Assume i & j are valid, O(1)
    private fun swap(i: Int, j: Int) {
        heap[i] = heap[j].also { heap[j] = heap[i] }
    }

    // Removes a particular element in the heap, O(n)
    fun remove(elem: WeightedEdge) = heap.remove(elem)

    // Remove a node at a paticular index, O(log(n))
    private fun removeAt(i: Int): WeightedEdge? {
        if (isEmpty()) return null

        val indexOfLastElem = size() - 1
        val removedData = heap[i]
        swap(i, indexOfLastElem)

        // Obliterate the value
        heap.removeAt(indexOfLastElem)

        // Check if the last element was removed
        if (i == indexOfLastElem) return removedData
        val elem = heap[i]

        // Try sinking element
        sink(i)

        // If sinking did not work try swimming
        if (elem == heap[i]) swim(i)
        return removedData
    }

    // Recursively check if this heap is a min heap
    private fun isMinHeap(k: Int): Boolean {
        // if we are outside the bounds of the heap return true
        val heapSize = size()
        if (k >= heapSize) return true

        val left = 2 * k + 1
        val right = 2 * k + 2

        // Make sure that the current node k is less than both of its children if they exist
        if (left < heapSize && !less(k, left)) return false
        if (right < heapSize && !less(k, right)) return false

        // Recurse on both children to make sure they're also valid
        return isMinHeap(left) && isMinHeap(right)
    }

    fun checkValid() {
        println(if (isMinHeap(0)) "Is MinHeap" else "Something goes wrong!!!")
    }

    override fun toString() = heap.toString()
}

data class Edge(val des: Int, val weight: Long)

data class WeightedEdge(val weight: Long, val leaf: Int) : Comparable<WeightedEdge> {
    private val diff: Long
        get() = (weight - weight / 2) * leaf

    override fun compareTo(other: WeightedEdge): Int {
        return if (this.diff < other.diff) 1
        else -1
    }
}

fun main() {
    val r = System.`in`.bufferedReader()
    val sb = StringBuilder()
    repeat(r.readInt()) {
        val n = r.readInt()
        val maxWeight = r.readInt()
        val adj = List(n) { mutableListOf<Edge>() }
        repeat(n - 1) {
            val u = r.readInt() - 1
            val v = r.readInt() - 1
            val w = r.readInt().toLong()
            adj[u] += Edge(v, w)
            adj[v] += Edge(u, w)
        }

        val parent = IntArray(n) { -1 }
        val childLeaf = IntArray(n) { 0 }
        val visited = BooleanArray(n) { false }

        fun dfs(i: Int): Int {
            visited[i] = true
            var leaf = 0
            adj[i].forEach {
                val (des, _) = it
                if (!visited[des]) {
                    leaf += dfs(des)
                    parent[des] = i
                }
            }
            if (i != 0 && adj[i].size == 1) leaf++
            childLeaf[i] = leaf
            return leaf
        }
        dfs(0)

        val heap = BinaryHeap<WeightedEdge>()
        val queue = LinkedList<Int>()
        queue.add(0)
        var totalWeight = 0L
        while (queue.isNotEmpty()) {
            val u = queue.removeFirst()
            adj[u].forEach {
                val (des, weight) = it
                if (parent[des] == u) {
                    heap.add(WeightedEdge(weight, childLeaf[des]))
                    queue.add(des)
                    totalWeight += weight * childLeaf[des]
                }
            }
        }

        var move = 0
        while (totalWeight > maxWeight) {
            val (wei, multi) = heap.poll()!!
            heap.add(WeightedEdge(wei/2, multi))
            totalWeight -= (wei-wei/2)*multi
            move++
        }
        sb.appendln(move)
    }
    print(sb)
}

// Hakiobo's code for faster reading input
private const val SPACE_INT = ' '.toInt()
private const val ZERO_INT = '0'.toInt()
private const val NL_INT = '\n'.toInt()

private fun BufferedReader.readInt(): Int {
    var ret = read()
    while (ret <= SPACE_INT) {
        ret = read()
    }
    val neg = ret == '-'.toInt()
    if (neg) {
        ret = read()
    }
    ret -= ZERO_INT
    var read = read()
    while (read >= ZERO_INT) {
        ret *= 10
        ret += read - ZERO_INT
        read = read()
    }

    while (read <= SPACE_INT && read != -1 && read != NL_INT) {
        mark(1)
        read = read()
    }
    if (read > SPACE_INT) {
        reset()
    }
    return if (neg) -ret else ret
}


import java.io.BufferedReader
import java.util.*

data class Edge(val v: Int, var w: Long, var l: Int = 0)
data class WEdge(var w: Long, val l: Int) : Comparable<WEdge> {
    val diff: Long
        get() = w * l - w / 2 * l

    override fun compareTo(other: WEdge) = if (this.diff < other.diff) 1 else -1
}

fun main() {
    val r = System.`in`.bufferedReader()
    val sb = StringBuilder()
    repeat(r.readInt()) {
        //println("Test case: $it")
        val n = r.readInt()
        val s = r.readInt().toLong()
        val adj = List(n) { mutableListOf<Edge>() }
        repeat(n - 1) {
            val u = r.readInt() - 1
            val v = r.readInt() - 1
            val w = r.readInt().toLong()
            adj[u] += Edge(v, w)
            adj[v] += Edge(u, w)
        }
        val visited = BooleanArray(n) { false }
        val leaves = arrayOfNulls<Int>(n)
        val edges = mutableListOf<Edge>()
        fun dfs(v: Int, parent: Int): Int {
            visited[v] = true
            var leaf = 0
            when (adj[v].size) {
                // leaf
                1 -> {
                    if (adj[v][0].v != parent) {
                        edges += adj[v][0]
                        leaf += dfs(adj[v][0].v, v)
                    } else {
                        leaf++
                    }
                }
                else -> {
                    leaf += adj[v].fold(0) { acc, it ->
                        if (it.v != parent) {
                            edges += it
                            acc + dfs(it.v, v)
                        } else acc
                    }
                }
            }
            //println("dfs $v, leaf: $leaf")
            leaves[v] = leaf
            return leaf
        }
        dfs(0, -1)
        //println("edges: $edges")
        // have edge, need weight and leaves
        val pq = PriorityQueue<WEdge>()
        for ((v, w, l) in edges) {
            pq.add(WEdge(w, leaves[v]!!))
        }
        var cursum = pq.fold(0L) { acc, (w, l) -> acc + w * l }

        var step = 0
        //println("start sum: $cursum")
        while (cursum > s) {
            val e = pq.poll()!!
            step++
            cursum -= e.diff
            pq.add(e.copy(w = e.w / 2))
            //println("pop: $e, sun become: $cursum, add back: ${e.copy(w = e.w / 2)}")
        }
        sb.appendln(step)
    }
    print(sb)
}

// Hakiobo's code for faster reading input
private const val SPACE_INT = ' '.toInt()
private const val ZERO_INT = '0'.toInt()
private const val NL_INT = '\n'.toInt()

private fun BufferedReader.readInt(): Int {
    var ret = read()
    while (ret <= SPACE_INT) {
        ret = read()
    }
    val neg = ret == '-'.toInt()
    if (neg) {
        ret = read()
    }
    ret -= ZERO_INT
    var read = read()
    while (read >= ZERO_INT) {
        ret *= 10
        ret += read - ZERO_INT
        read = read()
    }

    while (read <= SPACE_INT && read != -1 && read != NL_INT) {
        mark(1)
        read = read()
    }
    if (read > SPACE_INT) {
        reset()
    }
    return if (neg) -ret else ret
}


import java.io.BufferedReader

data class Edge(val v: Int, var w: Long)

fun main() {
    val r = System.`in`.bufferedReader()
    val sb = StringBuilder()
    repeat(r.readInt()) {
        //println("Test case: $it")
        val n = r.readInt()
        val s = r.readInt().toLong()
        val adj = List(n) { mutableListOf<Edge>() }
        repeat(n - 1) {
            val u = r.readInt() - 1
            val v = r.readInt() - 1
            val w = r.readInt().toLong()
            adj[u] += Edge(v, w)
            adj[v] += Edge(u, w)
        }
        val visited = BooleanArray(n) { false }

        // Need leaf number, it is important. Another one is weight, other thing does not matter
        val leaves = arrayOfNulls<Int>(n)
        val edges = Array(n - 1) { Edge(-1, -1) }
        var i = 0
        fun dfs(v: Int): Int {
            visited[v] = true
            var leaf = 0
            // back edge, this is leaf
            if (adj[v].size == 1 && visited[adj[v][0].v]) {
                leaf++
            } else {
                // Count up child vertices's leaf
                for (e in adj[v]) {
                    if (!visited[e.v]) {
                        edges[i++] = e
                        leaf += dfs(e.v)
                    }
                }
            }
            leaves[v] = leaf
            return leaf
        }
        dfs(0)

        val a = mutableListOf<Long>()
        var cursum = edges.fold(0L) { acc, (v, w) -> acc + w * leaves[v]!! }

        for ((v, weight) in edges) {
            val l = leaves[v]!!
            var w = weight
            var diff = (w - (w / 2)) * l
            while (diff>0) {
                a.add(diff)
                w /= 2
                diff = (w - (w / 2)) * l
            }
        }
        a.sortDescending()
        //println("can remove: $a")
        var b = 0
        while (cursum > s) {
            cursum -= a[b++]
        }
        sb.appendln(b)
    }
    print(sb)
}

// Hakiobo's code for faster reading input
private const val SPACE_INT = ' '.toInt()
private const val ZERO_INT = '0'.toInt()
private const val NL_INT = '\n'.toInt()

private fun BufferedReader.readInt(): Int {
    var ret = read()
    while (ret <= SPACE_INT) {
        ret = read()
    }
    val neg = ret == '-'.toInt()
    if (neg) {
        ret = read()
    }
    ret -= ZERO_INT
    var read = read()
    while (read >= ZERO_INT) {
        ret *= 10
        ret += read - ZERO_INT
        read = read()
    }

    while (read <= SPACE_INT && read != -1 && read != NL_INT) {
        mark(1)
        read = read()
    }
    if (read > SPACE_INT) {
        reset()
    }
    return if (neg) -ret else ret
}


import java.io.BufferedReader
import java.util.*

data class Edge(val des: Int, var wei: Long, var leave: Int = 0) : Comparable<Edge> {
    override fun compareTo(other: Edge): Int =
        if (wei * leave - other.wei * other.leave < 0) 1 else -1
}

fun main() {
    val r = System.`in`.bufferedReader()
    val sb = StringBuilder()
    repeat(r.readInt()) {
        val n = r.readInt()
        val s = r.readInt().toLong()
        val adj = List(n) { mutableListOf<Edge>() }
        repeat(n - 1) {
            val u = r.readInt() - 1
            val v = r.readInt() - 1
            val w = r.readInt().toLong()
            adj[u] += Edge(v, w)
            adj[v] += Edge(u, w)
        }
        val pq = PriorityQueue<Edge>()
        val visited = BooleanArray(n) { false }
        val leafs = IntArray(n) { 0 }
        // return number of leaf
        fun dfs(v: Int): Int {
            visited[v] = true
            var leaf = 0
            adj[v].forEach {
                if (!visited[it.des]) {
                    pq.add(it)
                    leaf += dfs(it.des)
                }
            }
            if (adj[v].size == 1) leaf++
            leafs[v] = leaf
            return leaf
        }
        dfs(0)
        pq.forEach { it.leave = leafs[it.des] }
        //println(pq)

        var cursum = pq.fold(0L) { sum, edge -> sum + edge.wei * edge.leave }
        //println("cs: $cursum")
        var step = 0
        while (cursum > s) {
            //println("cs: $cursum, s: $s")
            val e = pq.poll()!!
            step++
            val weight = e.wei
            pq.add(Edge(e.des, e.wei / 2, e.leave))
            //println(e.leave * (weight - e.wei))
            cursum -= e.leave * (weight - e.wei/2)
            //println("after - : cs = $cursum")
        }
        sb.appendln(step)
    }
    print(sb)
}

// Hakiobo's code for faster reading input
private const val SPACE_INT = ' '.toInt()
private const val ZERO_INT = '0'.toInt()
private const val NL_INT = '\n'.toInt()

private fun BufferedReader.readInt(): Int {
    var ret = read()
    while (ret <= SPACE_INT) {
        ret = read()
    }
    val neg = ret == '-'.toInt()
    if (neg) {
        ret = read()
    }
    ret -= ZERO_INT
    var read = read()
    while (read >= ZERO_INT) {
        ret *= 10
        ret += read - ZERO_INT
        read = read()
    }

    while (read <= SPACE_INT && read != -1 && read != NL_INT) {
        mark(1)
        read = read()
    }
    if (read > SPACE_INT) {
        reset()
    }
    return if (neg) -ret else ret
}


#include<bits/stdc++.h>
using namespace std;
const int MOD = 998244353;

long long binpow(long long x)
{
    long long rs=1;
    long long pow=MOD-2;
    while (pow)
    {
        if (pow%2==0)
        {
            x*=x;
            x%=MOD;
            pow/=2;
        }
        else
        {
            rs*=x;
            rs%=MOD;
            pow--;
        }
    }
    return rs;
}

long long modify(long long x, long long y)
{
    x%=MOD;
    y%=MOD;

    return(1ll * x * y)%MOD;
}

const int INF =100000000;
int main()
{
    int n;
    cin >> n;
    long long dv = binpow(n);
    dv%=MOD;

    vector <int> a(n+1);
    a[0] = INF;
    for (int i=1; i<=n; i++) cin >> a[i];
    sort(a.rbegin(),a.rend());
    vector<long long> pref(n+1,0);
    for (int i=1; i<=n; i++) pref[i] = pref[i-1] + a[i];
   // for (int i=1; i<=n; i++) cout << a[i] << "\n"[i!=n];
   // for (int i=1; i<=n; i++) cout << pref[i] << "\n"[i!=n];

    for (long long i=1; i<=n; i++)
    {
        long long sum=0;
        for (long long  j=2; j<=n/i; j++)
            {sum+=(pref[j*i]-pref[i*(j-1)])*(j-1);
             sum%=MOD;
             //cout << sum << "\n";
            }

        int add = n%i;
        sum += (pref[n] - pref[n-add]) * (n/i);
        sum%=MOD;
         //cout << sum << "  ";
        cout << modify(sum,dv) << " ";
    }

    //cout << modify(sum,binpow(n));
}

/*

*/


#include<bits/stdc++.h>
using namespace std;
const int MOD = 998244353;

long long binpow(long long x)
{
    long long rs=1;
    int pow=MOD-2;
    while (pow)
    {
        if (pow%2==0)
        {
            x*=x;
            x%=MOD;
            pow/=2;
        }
        else
        {
            rs*=x;
            rs%=MOD;
            pow--;
        }
    }
    return rs;
}

long long modify(long long x, long long y)
{
    return((1ll * x * y)%MOD);
}

const int INF =100000000;
int main()
{
    int n;
    cin >> n;
    long long dv = binpow(n);

    vector <int> a(n+1);
    a[0] = INF;
    for (int i=1; i<=n; i++) cin >> a[i];
    sort(a.rbegin(),a.rend());
    vector<long long> pref(n+1,0);
    for (int i=1; i<=n; i++) pref[i] = pref[i-1] + a[i];
   // for (int i=1; i<=n; i++) cout << a[i] << "\n"[i!=n];
   // for (int i=1; i<=n; i++) cout << pref[i] << "\n"[i!=n];

    for (int i=1; i<=n; i++)
    {
        long long sum=0;
        for (int j=2; j<=n/i; j++)
            {sum+=(pref[j*i]-pref[i*(j-1)])*(j-1);
             //cout << sum << "\n";
            }

        int add = n%i;
        sum += (pref[n] - pref[n-add]) * (n/i);
         //cout << sum << "  ";
        cout << modify(sum,dv) << " ";
    }

    //cout << modify(sum,binpow(n));
}

/*

*/


#include<bits/stdc++.h>
using namespace std;
const int MOD = 998244353;

long long binpow(long long x)
{
    long long rs=1;
    int pow=MOD-2;
    while (pow)
    {
        if (pow%2==0)
        {
            x*=x;
            x%=MOD;
            pow/=2;
        }
        else
        {
            rs*=x;
            rs%=MOD;
            pow--;
        }
    }
    return rs;
}

long long modify(long long x, long long y)
{
    return((1ll * x * y)%MOD);
}

const int INF =100000000;
int main()
{
    int n;
    cin >> n;
    long long dv = binpow(n);

    vector <int> a(n+1);
    a[0] = INF;
    for (int i=1; i<=n; i++) cin >> a[i];
    sort(a.rbegin(),a.rend());
    vector<long long> pref(n+1,0);
    for (int i=1; i<=n; i++) pref[i] = pref[i-1] + a[i];
   // for (int i=1; i<=n; i++) cout << a[i] << "\n"[i!=n];
   // for (int i=1; i<=n; i++) cout << pref[i] << "\n"[i!=n];

    for (long long i=1; i<=n; i++)
    {
        long long sum=0;
        for (long long  j=2; j<=n/i; j++)
            {sum+=(pref[j*i]-pref[i*(j-1)])*(j-1);
             //cout << sum << "\n";
            }

        int add = n%i;
        sum += (pref[n] - pref[n-add]) * (n/i);
         //cout << sum << "  ";
        cout << modify(sum,dv) << " ";
    }

    //cout << modify(sum,binpow(n));
}

/*

*/


#include <bits/stdc++.h>
using namespace std;

#ifdef LOCAL
#include "debug.h"
#else
#define DEBUG(...)
#endif

template <class T, class Op = multiplies<T>>
constexpr T power(T a, long long n, Op op = Op(), T e = {1}) {
  assert(n >= 0);
  while (n) {
    if (n & 1) e = op(e, a);
    if (n >>= 1) a = op(a, a);
  }
  return e;
}

template <unsigned M> struct modular {
  using m = modular;
  static constexpr unsigned mod = M;
  unsigned v;
  modular(long long x = 0) : v((x %= mod) < 0 ? x + mod : x) {}
  m operator-() const { return m() -= *this; }
  m& operator+=(m b) { if ((int)(v += b.v - mod) < 0) v += mod; return *this; }
  m& operator-=(m b) { if ((int)(v -= b.v) < 0) v += mod; return *this; }
  m& operator*=(m b) { v = (uint64_t)v * b.v % mod; return *this; }
  m& operator/=(m b) { return *this *= power(b, mod - 2); }
  friend m operator+(m a, m b) { return a += b; }
  friend m operator-(m a, m b) { return a -= b; }
  friend m operator*(m a, m b) { return a *= b; }
  friend m operator/(m a, m b) { return a /= b; }
  friend bool operator==(m a, m b) { return a.v == b.v; }
};

using mint = modular<998244353>;

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  int n;
  cin >> n;
  vector<int> c(n);
  for (auto&& e : c) cin >> e;
  sort(rbegin(c), rend(c));
  vector<mint> res(n + 2);
  for (int i = 1; i < n; ++i) {
    for (int l = 1; l <= i; ) {
      int r = i / (i / l) + 1;
      res[l] += c[i] * (i / l);
      res[r] -= c[i] * (i / l);
      l = r;
    }
  }
  for (int k = 1; k <= n; ++k) {
    cout << (res[k] / n).v << " \n"[k == n];
    res[k + 1] += res[k];
  }
}


#include <bits/stdc++.h>
using namespace std;

#ifdef LOCAL
#include "debug.h"
#else
#define DEBUG(...)
#endif

template <class T, class Op = multiplies<T>>
constexpr T power(T a, long long n, Op op = Op(), T e = {1}) {
  assert(n >= 0);
  while (n) {
    if (n & 1) e = op(e, a);
    if (n >>= 1) a = op(a, a);
  }
  return e;
}

template <unsigned M> struct modular {
  using m = modular;
  static constexpr unsigned mod = M;
  unsigned v;
  modular(long long x = 0) : v((x %= mod) < 0 ? x + mod : x) {}
  m operator-() const { return m() -= *this; }
  m& operator+=(m b) { if ((int)(v += b.v - mod) < 0) v += mod; return *this; }
  m& operator-=(m b) { if ((int)(v -= b.v) < 0) v += mod; return *this; }
  m& operator*=(m b) { v = (uint64_t)v * b.v % mod; return *this; }
  m& operator/=(m b) { return *this *= power(b, mod - 2); }
  friend m operator+(m a, m b) { return a += b; }
  friend m operator-(m a, m b) { return a -= b; }
  friend m operator*(m a, m b) { return a *= b; }
  friend m operator/(m a, m b) { return a /= b; }
  friend bool operator==(m a, m b) { return a.v == b.v; }
};

using mint = modular<998244353>;

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  int n;
  cin >> n;
  vector<long long> c(n);
  for (auto&& e : c) cin >> e;
  sort(rbegin(c), rend(c));
  c.push_back(0);
  for (int i = n; i--; ) {
    c[i] += c[i + 1];
  }
  for (int k = 1; k <= n; ++k) {
    mint res;
    for (int i = 0; i * k < n; ++i) {
      res += i * (c[i * k] - c[min(i * k + k, n)]);
    }
    res /= n;
    cout << res.v << " \n"[k == n];
  }
}


#include <bits/stdc++.h>
using namespace std;

#ifdef LOCAL
#include "debug.h"
#else
#define DEBUG(...)
#endif

template <class T, class Op = multiplies<T>>
constexpr T power(T a, long long n, Op op = Op(), T e = {1}) {
  assert(n >= 0);
  while (n) {
    if (n & 1) e = op(e, a);
    if (n >>= 1) a = op(a, a);
  }
  return e;
}

template <unsigned M> struct modular {
  using m = modular;
  static constexpr unsigned mod = M;
  unsigned v;
  modular(long long x = 0) : v((x %= mod) < 0 ? x + mod : x) {}
  m operator-() const { return m() -= *this; }
  m& operator+=(m b) { if ((int)(v += b.v - mod) < 0) v += mod; return *this; }
  m& operator-=(m b) { if ((int)(v -= b.v) < 0) v += mod; return *this; }
  m& operator*=(m b) { v = (uint64_t)v * b.v % mod; return *this; }
  m& operator/=(m b) { return *this *= power(b, mod - 2); }
  friend m operator+(m a, m b) { return a += b; }
  friend m operator-(m a, m b) { return a -= b; }
  friend m operator*(m a, m b) { return a *= b; }
  friend m operator/(m a, m b) { return a /= b; }
  friend bool operator==(m a, m b) { return a.v == b.v; }
};

using mint = modular<998244353>;

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  int n;
  cin >> n;
  vector<long long> c(n);
  for (auto&& e : c) cin >> e;
  sort(rbegin(c), rend(c));
  vector<mint> res(n + 2);
  for (int i = 1; i < n; ++i) {
    for (int l = 1; l <= i; ) {
      int r = i / (i / l) + 1;
      res[l] += c[i] * (i / l);
      res[r] -= c[i] * (i / l);
      l = r;
    }
  }
  for (int k = 1; k <= n; ++k) {
    cout << (res[k] / n).v << " \n"[k == n];
    res[k + 1] += res[k];
  }
}


#include<bits/stdc++.h>
using namespace std;

const int N = 3e5+7, M = 998244353;
int a[N];
long long sum[N];

long long inv(int x) {
    long long ans = 1;
    while(ans%x!=0) ans += M;
    return (ans/x)%M;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n;
    cin>>n;
    long long invn = inv(n);

    for (int i=1; i<=n; i++) cin>>a[i];
    sort(a+1, a+n+1);
    reverse(a+1, a+n+1);
    for (int i=1; i<=n; i++)    sum[i] = (sum[i-1] + a[i])%M;

    for (int k=1; k<=n; k++) {
        long long ans = 0;
        int done = 0;
        for (int j=0; j<n/k; j++) {
            ans = (ans + (sum[done+k]-sum[done])*j);
            done += k;
        }
        ans = (ans + (sum[n]-sum[done])*(n/k))%M;
        ans = (ans+M)%M;
        ans = (ans*invn)%M;
        cout<<ans<<" ";
    }
}


#include<bits/stdc++.h>
using namespace std;

const int N = 3e5+7, M = 998244353;
int a[N];
long long sum[N];

long long inv(int x) {
    long long ans = 1;
    while(ans%x!=0) ans += M;
    return (ans/x)%M;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n;
    cin>>n;
    long long invn = inv(n);

    for (int i=1; i<=n; i++) cin>>a[i];
    sort(a+1, a+n+1);
    reverse(a+1, a+n+1);
    for (int i=1; i<=n; i++)    sum[i] = (sum[i-1] + a[i])%M;

    for (int k=1; k<=n; k++) {
        long long ans = 0;
        int done = 0;
        for (int j=0; j<n/k; j++) {
            ans = (ans + (sum[done+k]-sum[done])*j)%M;
            done += k;
        }
        ans = (ans + (sum[n]-sum[done])*(n/k))%M;
        ans = (ans+M)%M;
        ans = (ans*invn)%M;
        cout<<ans<<" ";
    }
}


#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline") //Optimization flags
#pragma GCC option("arch=native","tune=native","no-zero-upper") //Enable AVX
#pragma GCC target("avx2") //Enable AVX
#pragma GCC optimize("03")

#include <bits/stdc++.h>
#define db(x) cout << (x) << '\n';
#define all(v) (v).begin(),(v).end()
#define allr(v) (v).rbegin(),(v).rend()
#define f first
#define s second
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pii;
typedef pair<double,ll> pdi;
typedef pair<ld,ld> pdd;
typedef pair<double,ll> pdi;
typedef pair<double,pii> pdp;
typedef pair<string,ll> psi;
typedef pair<ll,string> pls;
typedef pair<string,string> pss;
typedef pair<ll,pii> pip;
typedef pair<pii,pii> ppp;
typedef complex<ld> point;
typedef pair<point,int> ppi;
#define mod (ll)(998244353)
#define eps (1e-9)
#define oo (ll)(0x3f3f3f3f)
#define pi acos(-1)
#define MAXN (ll)(1e3+5)

ll qp(ll b,ll e)
{
    if(!e)
        return 1;
    ll x=qp(b,e/2);
    x=(x*x)%mod;
    if(e&1)
        x=(x*b)%mod;
    return x;
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    int n;
    cin >> n;
    vector<ll> a(n);
    vector<ll> ac(n+1);
    for(int i=0;i<n;i++)
        cin >> a[i];
    sort(all(a));

    for(int i=0;i<n;i++)
    {
        ac[i+1]=ac[i]+a[i];
        ac[i+1]%=mod;
    }

    for(int i=1;i<=n;i++)
    {
        ll res=0;
        int pos=n-i;
        ll mul=1;
        while(pos)
        {
            if(pos-i>=0)
            {
                res+=(mul)*(ac[pos]-ac[pos-i]);
                mul++;
                pos-=i;
            }
            else
            {
                res+=(mul)*(ac[pos]-ac[0]);
                mul++;
                pos=0;
            }
        }

        cout << (res*qp(n,mod-2))%mod << ' ';
    }
    cout << '\n';
    return 0;
}
/**
8
10 4 3 6 5 10 7 5
**/


#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline") //Optimization flags
#pragma GCC option("arch=native","tune=native","no-zero-upper") //Enable AVX
#pragma GCC target("avx2") //Enable AVX
#pragma GCC optimize("03")

#include <bits/stdc++.h>
#define db(x) cout << (x) << '\n';
#define all(v) (v).begin(),(v).end()
#define allr(v) (v).rbegin(),(v).rend()
#define f first
#define s second
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pii;
typedef pair<double,ll> pdi;
typedef pair<ld,ld> pdd;
typedef pair<double,ll> pdi;
typedef pair<double,pii> pdp;
typedef pair<string,ll> psi;
typedef pair<ll,string> pls;
typedef pair<string,string> pss;
typedef pair<ll,pii> pip;
typedef pair<pii,pii> ppp;
typedef complex<ld> point;
typedef pair<point,int> ppi;
#define mod (ll)(998244353)
#define eps (1e-9)
#define oo (ll)(0x3f3f3f3f)
#define pi acos(-1)
#define MAXN (ll)(1e3+5)

ll qp(ll b,ll e)
{
    if(!e)
        return 1;
    ll x=qp(b,e/2);
    x=(x*x)%mod;
    if(e&1)
        x=(x*b)%mod;
    return x;
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    int n;
    cin >> n;
    vector<ll> a(n);
    vector<ll> ac(n+1);
    for(int i=0;i<n;i++)
        cin >> a[i];
    sort(all(a));

    for(int i=0;i<n;i++)
    {
        ac[i+1]=ac[i]+a[i];
        ac[i+1]%=mod;
    }

    for(int i=1;i<=n;i++)
    {
        ll res=0;
        int pos=n-i;
        ll mul=1;
        while(pos)
        {
            if(pos-i>=0)
            {
                res=(res+(mul)*(ac[pos]-ac[pos-i]))%mod;
                mul++;
                pos-=i;
            }
            else
            {
                res=(res+(mul)*(ac[pos]-ac[0]))%mod;
                mul++;
                pos=0;
            }
        }

        cout << (res*qp(n,mod-2))%mod << ' ';
    }
    cout << '\n';
    return 0;
}
/**
8
10 4 3 6 5 10 7 5
**/


//#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define FIO ios_base::sync_with_stdio(false); cin.tie(0);
#define trav(x,a) for (auto& x: a)
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define mem(a,v) memset((a), (v), sizeof (a))
#define endl "\n"
#define case(t) cout << "Case #" << (t) << ": "
#define reada(a, n) for (int _i = 0; _i < (n); _i++) read(a[_i])
#define pii pair<int, int>
#define pll pair<long long, long long>
#define vii vector<pii>
#define vll vector<pll>
#define vi vector<int>
#define vl vector<long long>
#define pb push_back
#define mp make_pair
#define st first
#define nd second
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef cc_hash_table<int,int,hash<int>> ht;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> oset;
const double pi = acos(-1);
const int mod = 998244353;
const int inf = 1e9 + 7;
const int N = 1e6 + 5;
const double eps = 1e-9;

template<class T> void read(T& x) { cin >> x; }
template<class X, class Y> void read(pair<X,Y>& a) { read(a.first), read(a.second); }
template<class T> void read(vector<T>& x) { trav(y, x) read(y); }
template<class T, class... O> void read(T& x, O&... y) { read(x), read(y...); }

string to_string(const char& x) { return string(1,x); }
string to_string(const char*& x) { return (string)x; }
string to_string(const string& x) { return x; }
template<class T, class U> string to_string(const pair<T,U>& x) { return to_string(x.first) + " " + to_string(x.second); }
template<class T> string to_string(const vector<T>& x) { string ret = ""; bool f = 0; trav(y, x) ret += (!f ? "" : " ") + to_string(y), f = 1; return ret; }
void print() { cout << endl; }
template<class T> void pr(const T& x) { cout << to_string(x); }
template<class T, class... O> void print(const T& x, const O&... y) { pr(x); if (sizeof...(y)) pr(" "); print(y...); }

int inv[N], ifac[N], fac[N];

int add(int x, int y) { return x+y < mod ? x+y : x+y-mod; }
int sub(int x, int y) { return x-y >= 0 ? x-y : x-y+mod; }
int mul(int x, int y) { return x * 1ll * y % mod; }
template<class T, class... O> int add(T x, O... y) { return add(x, add(y...)); }
template<class T, class... O> int mul(T x, O... y) { return mul(x, mul(y...)); }
int norm(int x) { return x >= 0 ? (x < mod ? x : x-mod) : x+mod; }
int pw(int x, int y) {
  int r = 1;
  for (; y; x = mul(x, x), y /= 2)
    if (y & 1)
      r = mul(r, x);
  return r;
}
int inverse(int x) { return pw(x, mod-2); }
int ncr(int n, int k) {
  if (n < k || k < 0) return 0;
  if (n < N) return mul(fac[n], ifac[n-k], ifac[k]);
  int r = 1;
  for (int i = 1; i <= k; i++)
    r = mul(r, n-i+1, inv[i]);
  return r;
}

void precomputeInverse(int n) {
  inv[1] = ifac[0] = ifac[1] = fac[0] = fac[1] = 1;
  for (int i = 2; i < n; i++) {
    inv[i] = mod - mul(mod / i, inv[mod % i]);
    fac[i] = mul(fac[i-1], i);
    ifac[i] = mul(ifac[i-1], inv[i]);
  }
}

int pref[N];

int main() {
  FIO
  int n; read(n); vector<int> a(n); read(a);
  sort(all(a));
  pref[0] = a[0];
  for (int i = 1; i < n; i++)
    pref[i] = add(pref[i-1], a[i]);
  int in = pw(n, mod-2);
  for (int k = 1; k <= n; k++) {
    int ans = 0;
    for (int i = n-k-1, j = 1; i >= 0; i -= k, j++) {
      ans = add(ans, mul(j, sub(pref[i], i-k+1 <= 0 ? 0 : pref[i-k])));
      // for (int l = i; l > max(i-k,-1); l--)
      //   ans = add(ans, mul(j, a[l]));
    }
    print(mul(ans,in));
  }
  return 0;
}


#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e5+5;
const int mod=998244353;
int n,c[N],s[N];

int Power(int x,int n)
{
    if(n==0) return 1;
    if(n%2) return Power(x,n-1)*x%mod;
    int tmp=Power(x,n/2);
    return tmp*tmp%mod;
}

main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cin>>n;
    for(int i=1;i<=n;i++) cin>>c[i];
    sort(c+1,c+n+1);
    for(int i=1;i<=n;i++) s[i]=(s[i-1]+c[i])%mod;
    for(int k=1;k<=n;k++)
    {
        int x=(n-k)%k;
        int cnt=(n-k)/k;
        /*
        x : cnt+1;
        k : cnt
        k : cnt-1
        ...
        k : 1
        */
        int cur=1,res=0;
        for(int i=cnt+1;i>=1;i--)
        {
            int need;
            if(i==cnt+1) need=x;
            else need=k;
            res=(res+i*(s[cur+need-1]-s[cur-1]+mod)%mod)%mod;
            cur+=need;
        }
        cout<<res*Power(n,mod-2)%mod<<' ';
    }
}


#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e5+5;
const int mod=998244353;
int n,c[N],s[N];

int Power(int x,int n)
{
    if(n==0) return 1;
    if(n%2) return Power(x,n-1)*x%mod;
    int tmp=Power(x,n/2);
    return tmp*tmp%mod;
}

main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cin>>n;
    for(int i=1;i<=n;i++) cin>>c[i];
    sort(c+1,c+n+1);
    for(int i=1;i<=n;i++) s[i]=s[i-1]+c[i];
    for(int k=1;k<=n;k++)
    {
        int x=(n-k)%k;
        int cnt=(n-k)/k;
        /*
        x : cnt+1;
        k : cnt
        k : cnt-1
        ...
        k : 1
        */
        int cur=1,res=0;
        for(int i=cnt+1;i>=1;i--)
        {
            int need;
            if(i==cnt+1) need=x;
            else need=k;
            res+=i*(s[cur+need-1]-s[cur-1]);
            cur+=need;
        }
        cout<<res*Power(n,mod-2)%mod<<' ';
    }
}


#include<bits/stdc++.h>

typedef long long ll;
using namespace std;

#define pb push_back
#define pll pair<ll,ll >
#define sz(x) (x).size()
#define all(x) (x).begin(), (x).end()
#define endln '\n'
#define se second
#define fi first
#define cont continue
#define sqr(x) (x) * (x)

const ll Inf = 1e10;
const ll MaxN = 5e5 + 5;
const ll md = 998244353;

ll binpow(ll n, ll m, ll mod = md) {
	ll Res = 1;

	while (m) {
		if (m & 1) {
			Res *= n;
			Res %= mod;
		}
		n *= n;
		n %= mod;
		m >>= 1;
	}
	return Res;
}

int main() {

#ifdef LOCAL
	ifstream cin("input.txt");
	ofstream cout("output.txt");
#else

#endif // DEBUG

	ios_base::sync_with_stdio(0);
	cin.tie();
	cout.tie();

	ll N;
	cin >> N;
	ll inv = binpow(N, md - 2);

	vector<ll > Mt(N);
	for (int i = 0; i < N; i++) {
		cin >> Mt[i];
	}
	sort(all(Mt), [=](ll a, ll b) {return a > b; });
	vector<ll > Ans;
	Ans.pb(0);
	for (int i = 0; i < N; i++) {
		ll a = Ans.back() + Mt[i];
		if (a >= md) a -= md;
		Ans.push_back(a);
	}

	for (int k = 1; k <= N; ++k) {
		int ans = 0;
		for (int i = 0, j = 0; i < N; i += k, ++j) {

			ans += (j * (Ans[min(N, 1ll * i + k)]+ -Ans[i] + md) ) % md;
			if (ans >= md) ans -= md;

		}
		cout << (ans * inv) % md << endln;
	}

	return 0;
}


#include<bits/stdc++.h>

typedef long long ll;
using namespace std;

#define pb push_back
#define pll pair<ll,ll >
#define sz(x) (x).size()
#define all(x) (x).begin(), (x).end()
#define endln '\n'
#define se second
#define fi first
#define cont continue
#define sqr(x) (x) * (x)

const ll Inf = 1e10;
const ll MaxN = 5e5 + 5;
const ll md = 998244353;

ll binpow(ll n, ll m, ll mod = md) {
	ll Res = 1;

	while (m) {
		if (m & 1) {
			Res *= n;
			Res %= mod;
		}
		n *= n;
		n %= mod;
		m >>= 1;
	}
	return Res;
}

int main() {

#ifdef LOCAL
	ifstream cin("input.txt");
	ofstream cout("output.txt");
#else

#endif // DEBUG

	ios_base::sync_with_stdio(0);
	cin.tie();
	cout.tie();

	ll N;
	cin >> N;
	ll inv = binpow(N, md - 2);

	vector<ll > Mt(N);
	for (int i = 0; i < N; i++) {
		cin >> Mt[i];
	}
	sort(all(Mt), [=](ll a, ll b) {return a > b; });
	vector<ll > Ans;
	Ans.pb(0);
	for (int i = 0; i < N; i++) {
		ll a = Ans.back() + Mt[i];
		if (a >= md) a -= md;
		Ans.push_back(a);
	}

	for (int k = 1; k <= N; ++k) {
		int ans = 0;
		for (int i = 0, j = 0; i < N; i += k, ++j) {
			//ans = add(ans, mul(j, add(pr[min(n, i + k)], -pr[i])));
			ans += (j * (Ans[min(N, 1ll * i + k)]+ -Ans[i]) ) % md;
			if (ans >= md) ans -= md;

		}
		cout << (ans * inv) % md << endln;
	}

	return 0;
}


#include <iostream>
#include <algorithm>

using namespace std;

const int MaxN = 300002;
const int Mod = 998244353;

long long c[MaxN];
long long sum[MaxN];

int cmp( int a, int b ) {
  return a > b;
}

long long quickPow( long long a, long long n ) {
  long long p = 1;

  while ( n > 0 ) {
    if ( n & 1 ) {
      p = (p * a) % Mod;
    }
    a = (a * a) % Mod;
    n >>= 1;
  }
  return p;
}

int main() {
  long long n, ans;

  cin >> n;
  for ( int i = 1; i <= n; ++i ) {
    cin >> c[i];
  }
  sort( c + 1, c + n + 1, cmp );
  for ( int i = 1; i <= n; ++i ) {
    sum[i] = sum[i - 1] + c[i];
  }
  long long inv = quickPow( n, Mod - 2 );
  for ( int k = 1; k <= n; ++k ) {
    ans = 0;
    int i;
    for ( i = k; i <= n; i += k ) {
      ans = (ans + (i - 1) / k * (sum[i] - sum[i - k])) % Mod;
    }
    ans = (ans + (i - 1) / k * (sum[n] - sum[i - k])) % Mod;
    cout << ans * inv % Mod << " ";
  }
  return 0;
}


#include <iostream>
#include <algorithm>

using namespace std;

const int MaxN = 300002;
const int Mod = 998244353;

int c[MaxN];
int sum[MaxN];

int cmp( int a, int b ) {
  return a > b;
}

long long quickPow( long long a, int n ) {
  long long p = 1;

  while ( n > 0 ) {
    if ( n & 1 ) {
      p = (p * a) % Mod;
    }
    a = (a * a) % Mod;
    n >>= 1;
  }
  return p;
}

int main() {
  int n, ans;

  cin >> n;
  for ( int i = 1; i <= n; ++i ) {
    cin >> c[i];
  }
  sort( c + 1, c + n + 1, cmp );
  for ( int i = 1; i <= n; ++i ) {
    sum[i] = sum[i - 1] + c[i];
  }
  long long inv = quickPow( n, Mod - 2 );
  for ( int k = 1; k <= n; ++k ) {
    ans = 0;
    int i;
    for ( i = k; i <= n; i += k ) {
      ans = (ans + (i - 1) / k * (sum[i] - sum[i - k])) % Mod;
    }
    ans = (ans + (i - 1) / k * (sum[n] - sum[i - k]));
    cout << ans * inv % Mod << " ";
  }
  return 0;
}


/*/ Author: kal013 /*/
// #pragma GCC optimize ("O3")
#include "bits/stdc++.h"
#include "ext/pb_ds/assoc_container.hpp"
#include "ext/pb_ds/tree_policy.hpp"
using namespace std;
using namespace __gnu_pbds;

template<class T>
using ordered_set = tree<T, null_type,less<T>, rb_tree_tag,tree_order_statistics_node_update> ;

template<class key, class value, class cmp = std::less<key>>
using ordered_map = tree<key, value, cmp, rb_tree_tag, tree_order_statistics_node_update>;
// find_by_order(k)  returns iterator to kth element starting from 0;
// order_of_key(k) returns count of elements strictly smaller than k;

struct custom_hash { // Credits: https://codeforces.com/blog/entry/62393
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
    size_t operator()(pair<int64_t,int64_t> Y) const{
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(Y.first * 31 + Y.second + FIXED_RANDOM);
    }
};

template<class T> ostream& operator<<(ostream &os, vector<T> V) {
    os << "[ ";
    for(auto v : V) os << v << " ";
    return os << "]";
}
template<class T> ostream& operator<<(ostream &os, set<T> S){
    os << "{ ";
    for(auto s:S) os<<s<<" ";
    return os<<"}";
}
template<class T> ostream& operator<<(ostream &os, unordered_set<T> S){
    os << "{ ";
    for(auto s:S) os<<s<<" ";
    return os<<"}";
}
template<class T> ostream& operator << (ostream& os, multiset<T> S){
    os << "{ ";
    for(auto s:S) os<<s<<" ";
    return os<<"}";
}
template<class T> ostream& operator<<(ostream &os, ordered_set<T> S){
    os << "{ ";
    for(auto s:S) os<<s<<" ";
    return os<<"}";
}
template<class L, class R> ostream& operator<<(ostream &os, pair<L,R> P) {
    return os << "(" << P.first << "," << P.second << ")";
}
template<class L, class R> ostream& operator<<(ostream &os, map<L,R> M) {
    os << "{ ";
    for(auto m:M) os<<"("<<m.first<<":"<<m.second<<") ";
    return os<<"}";
}
template<class L, class R, class chash = std::hash<R>> ostream& operator<<(ostream &os, unordered_map<L,R,chash> M) {
    os << "{ ";
    for(auto m:M) os<<"("<<m.first<<":"<<m.second<<") ";
    return os<<"}";
}
template<class L, class R, class chash = std::hash<R> > ostream& operator<<(ostream &os, gp_hash_table<L,R,chash> M) {
    os << "{ ";
    for(auto m:M) os<<"("<<m.first<<":"<<m.second<<") ";
    return os<<"}";
}

#define TRACE
#ifdef TRACE
    #define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template <typename Arg1>
    void __f(const char* name, Arg1&& arg1){
        cerr << name << " : " << arg1 << endl;
    }
    template <typename Arg1, typename... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args){
        const char* comma = strchr(names + 1, ',');
        cerr.write(names, comma - names) << " : " << arg1<<" | ";
        __f(comma+1, args...);
    }
#else
    #define trace(...) 1
#endif

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

inline int64_t random_long(long long l,long long r){
    uniform_int_distribution<int64_t> generator(l,r);
    return generator(rng);
}
inline int64_t random_long(){
    uniform_int_distribution<int64_t> generator(LLONG_MIN,LLONG_MAX);
    return generator(rng);
}

/*/---------------------------Defines----------------------/*/
typedef vector<int> vi;
typedef pair<int,int> pii;

#define ll long long
#define F first
#define S second
#define pb push_back
#define endl "\n"
#define all(v) (v).begin(),(v).end()
/*/-----------------------Modular Arithmetic---------------/*/

const int mod=998244353;
template<const int MOD>
struct modular_int{
	int x;
	static vector<int> inverse_list ;
	const static int inverse_limit;
	const static bool is_prime;
	modular_int(){
		x = 0;
	}
	template<typename T>
	modular_int(const T z){
		x = (z%MOD);
		if (x < 0) x += MOD;
	}
	modular_int(const modular_int<MOD>* z){
		x = z->x;
	}
	modular_int(const modular_int<MOD>& z){
		x = z.x;
	}
	modular_int operator - (const modular_int<MOD>& m) const{
		modular_int<MOD> U;
		U.x = x - m.x;
		if (U.x < 0) U.x += MOD;
		return U;
	}
	modular_int operator + (const modular_int<MOD>& m) const{
		modular_int<MOD> U;
		U.x = x + m.x;
		if (U.x >= MOD) U.x -= MOD;
		return U;
	}
	modular_int& operator -= (const modular_int<MOD>& m){
		x -= m.x;
		if (x < 0) x += MOD;
		return *this;
	}
	modular_int& operator += (const modular_int<MOD>& m){
		x += m.x;
		if (x >= MOD) x -= MOD;
		return *this;
	}
	modular_int operator * (const modular_int<MOD>& m) const{
		modular_int<MOD> U;
		U.x = (x* 1ull * m.x) %MOD;
		return U;
	}
	modular_int& operator *= (const modular_int<MOD>& m){
		x = (x * 1ull * m.x)%MOD;
		return *this;
	}
	template<typename T>
	friend modular_int operator + (const T &l, const modular_int<MOD>& p){
		return (modular_int<MOD>(l) + p);
	}
	template<typename T>
	friend modular_int operator - (const T &l, const modular_int<MOD>& p){
		return (modular_int<MOD>(l) - p);
	}
	template<typename T>
	friend modular_int operator * (const T &l, const modular_int<MOD>& p){
		return (modular_int<MOD>(l) * p);
	}
	template<typename T>
	friend modular_int operator / (const T &l, const modular_int<MOD>& p){
		return (modular_int<MOD>(l) / p);
	}

	int value() const{
		return x;
	}

	modular_int operator ^ (const modular_int<MOD>& cpower) const{
		modular_int<MOD> ans;
		ans.x = 1;
		modular_int<MOD> curr(this);
		int power = cpower.x;

		if (curr.x <= 1){
			if (power == 0) curr.x = 1;
			return curr;
		}
		while( power > 0){
			if (power&1){
				ans *= curr;
			}
			power >>= 1;
			if (power) curr *= curr;
		}
		return ans;
	}

	modular_int operator ^ (long long power) const{
		modular_int<MOD> ans;
		ans.x = 1;
		modular_int<MOD> curr(this);
		if (curr.x <= 1){
			if (power == 0) curr.x = 1;
			return curr;
		}
		// Prime Mods
		if (power >= MOD && is_prime){
			power %= (MOD - 1);
		}

		while( power > 0){
			if (power&1){
				ans *= curr;
			}
			power >>= 1;
			if (power) curr *= curr;

		}
		return ans;
	}

	modular_int operator ^ (int power) const{
		modular_int<MOD> ans;
		ans.x = 1;
		modular_int<MOD> curr(this);

		if (curr.x <= 1){
			if (power == 0) curr.x = 1;
			return curr;
		}
		while( power > 0){
			if (power&1){
				ans *= curr;
			}
			power >>= 1;
			if (power) curr *= curr;

		}
		return ans;
	}

	template<typename T>
	modular_int& operator ^= (T power) {
		modular_int<MOD> res = (*this)^power;
		x = res.x;
		return *this;
	}

	template<typename T>
	modular_int pow(T x){
		return (*this)^x;
	}

	pair<long long,long long> gcd(const int a, const int b) const {
		if (b==0) return {1,0};
		pair<long long,long long> c = gcd(b , a%b);
		return { c.second , c.first - (a/b)*c.second};
	}

	inline void init_inverse_list() const {

		vector<int>& dp = modular_int<MOD>::inverse_list;
		dp.resize(modular_int<MOD>::inverse_limit + 1);
		int n = modular_int<MOD>::inverse_limit;
		dp[0] = 1;
		if (n > 1) dp[1] = 1;
		for(int i = 2; i <= n; ++i){
			dp[i] = (dp[MOD%i] * 1ull *(MOD - MOD/i))%MOD;
		}

	}
	modular_int<MOD> get_inv() const {
		if (modular_int<MOD>::inverse_list.size() < modular_int<MOD>::inverse_limit + 1) init_inverse_list();

		if (this->x <= modular_int<MOD>::inverse_limit){
			return modular_int<MOD>::inverse_list[this->x];
		}
		pair<long long,long long> G = gcd(this->x,MOD);
		return modular_int<MOD>(G.first);
	}
	modular_int<MOD> operator - () const {
		modular_int<MOD> v(0);
		v -= (*this);
		return v;
	}
	modular_int operator / (const modular_int<MOD>& m) const{
		modular_int<MOD> U(this);
		U *= m.get_inv();
		return U;
	}
	modular_int& operator /= (const modular_int<MOD>& m){
		(*this) *= m.get_inv();
		return *this;
	}
	bool operator==(const modular_int<MOD>& m) const{
		return x == m.x;
	}

	bool operator < (const modular_int<MOD>& m) const {
		return x < m.x;
	}

	template<typename T>
	bool operator == (const T& m) const{
		return (*this)== (modular_int<MOD>(m));
	}

	template<typename T>
	bool operator < (const T& m) const {
		return x < (modular_int<MOD>(m)).x;
	}
	template<typename T>
	bool operator > (const T& m) const {
		return x > (modular_int<MOD>(m)).x;
	}
	template<typename T>
	friend bool operator == (const T& x, const modular_int<MOD>& m) {
		return (modular_int<MOD>(x)).x == m.x;
	}
	template<typename T>
	friend bool operator < (const T& x, const modular_int<MOD>& m){
		return (modular_int<MOD>(x)).x < m.x;
	}
	template<typename T>
	friend bool operator > (const T& x, const modular_int<MOD>& m){
		return (modular_int<MOD>(x)).x > m.x;
	}

	friend istream& operator >> (istream& is, modular_int<MOD>& p){
		int64_t val;
		is >> val;
		p.x = (val%MOD);
		if (p.x < 0) p.x += MOD;
		return is;
	}
	friend ostream& operator << (ostream& os, const modular_int<MOD>& p) {return os<<p.x;}

};

using mint = modular_int<mod>;
template<const int MOD>
vector<int> modular_int<MOD>::inverse_list ;
template<const int MOD>
const int modular_int<MOD>::inverse_limit = -1;
template<const int MOD>
const bool modular_int<MOD>::is_prime = true;
// template<>   //-> useful if computing inverse fact = i_f[i-1] / i;
// const int modular_int<mod>::inverse_limit = 100000;

/*/-----------------------------Code begins----------------------------------/*/

void print(int n,int k){
	int place = n - k;
	int v1 = place / k;
	int cntv1 = k - place%k;
	vector<int> ans(place );

	for(int i = 0; i < place; ++i){
		ans[i] = (n - i - 1)/k;
	}

	// for(int i = 0; i < place; ++i){
	// 	ans.push_back( (i / k) + 1);
	// }
	// reverse(all(ans));
	assert(ans.size() == place);
	trace(ans);
}

const int SQ = 600;

vector<long long> P[SQ];

void solve(){
	int n;
	cin >> n;
	vector<long long> A(n),prf(n+1);
	for(int i = 0 ;i < n; ++i){
		cin >> A[i];
	}
	sort(all(A));

	for(int i = 1; i <= n; ++i){
		prf[i] = prf[i-1] + A[i-1];
	}

	int block = min(200,n);
	for(int i = 1; i <= block; ++i){
		P[i].resize(n + 1);

		P[i][0] = 0;

		for(int j = 1; j <= n; ++j){
			if (j  <= i){
				P[i][j] = prf[j];
			}
			else{
				P[i][j] = prf[j] + P[i][j-i];

			}
		}
	}

	prf[0] = 0;

	vector<mint> ans(n+1);
	ans[n] = 0;

	for(int i = 1; i < n ; ++i){
		int place = i ;
		int rem = n - place;

		if (rem >= place){
			ans[n - i] = prf[i];
		}
		else{
			if (rem <= block){
				ans[n - i] = P[rem][i];
			}
			else{
				int v1 = place % rem;
				int st = 1 + v1;
				int kol = (place + rem - 1) / rem;

				ans[n-i] = prf[v1] * kol;

				for(int u = st, mul = place/rem;  u <= place; u += rem, --mul){
					ans[n-i] += (prf[u + rem - 1] - prf[u - 1])*mul;
				}

			}
		}
	}
	mint denom = 1;
	denom /= n;
	for(int i = 1 ; i <= n; ++i){
		cout << ans[i] * denom << " ";
	}
	cout << endl;
}

int main(){
    // Use "set_name".max_load_factor(0.25);"set_name".reserve(512); with unordered set
    // Or use gp_hash_table<X,null_type>
    ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
    cout<<fixed<<setprecision(25);
    cerr<<fixed<<setprecision(10);
    auto start = std::chrono::high_resolution_clock::now();

    // for(int k = 1; k < 20; ++k){
    // 	trace(20,k);
    // 	print(20,k);
    // }
    int t=1;
    // cin>>t;
    while(t--) {
        solve();
    }
    auto stop = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(stop - start);

    // cerr << "Time taken : " << ((long double)duration.count())/((long double) 1e9) <<"s "<< endl;
}


/*/ Author: kal013 /*/
// #pragma GCC optimize ("O3")
#include "bits/stdc++.h"
#include "ext/pb_ds/assoc_container.hpp"
#include "ext/pb_ds/tree_policy.hpp"
using namespace std;
using namespace __gnu_pbds;

template<class T>
using ordered_set = tree<T, null_type,less<T>, rb_tree_tag,tree_order_statistics_node_update> ;

template<class key, class value, class cmp = std::less<key>>
using ordered_map = tree<key, value, cmp, rb_tree_tag, tree_order_statistics_node_update>;
// find_by_order(k)  returns iterator to kth element starting from 0;
// order_of_key(k) returns count of elements strictly smaller than k;

struct custom_hash { // Credits: https://codeforces.com/blog/entry/62393
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
    size_t operator()(pair<int64_t,int64_t> Y) const{
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(Y.first * 31 + Y.second + FIXED_RANDOM);
    }
};

template<class T> ostream& operator<<(ostream &os, vector<T> V) {
    os << "[ ";
    for(auto v : V) os << v << " ";
    return os << "]";
}
template<class T> ostream& operator<<(ostream &os, set<T> S){
    os << "{ ";
    for(auto s:S) os<<s<<" ";
    return os<<"}";
}
template<class T> ostream& operator<<(ostream &os, unordered_set<T> S){
    os << "{ ";
    for(auto s:S) os<<s<<" ";
    return os<<"}";
}
template<class T> ostream& operator << (ostream& os, multiset<T> S){
    os << "{ ";
    for(auto s:S) os<<s<<" ";
    return os<<"}";
}
template<class T> ostream& operator<<(ostream &os, ordered_set<T> S){
    os << "{ ";
    for(auto s:S) os<<s<<" ";
    return os<<"}";
}
template<class L, class R> ostream& operator<<(ostream &os, pair<L,R> P) {
    return os << "(" << P.first << "," << P.second << ")";
}
template<class L, class R> ostream& operator<<(ostream &os, map<L,R> M) {
    os << "{ ";
    for(auto m:M) os<<"("<<m.first<<":"<<m.second<<") ";
    return os<<"}";
}
template<class L, class R, class chash = std::hash<R>> ostream& operator<<(ostream &os, unordered_map<L,R,chash> M) {
    os << "{ ";
    for(auto m:M) os<<"("<<m.first<<":"<<m.second<<") ";
    return os<<"}";
}
template<class L, class R, class chash = std::hash<R> > ostream& operator<<(ostream &os, gp_hash_table<L,R,chash> M) {
    os << "{ ";
    for(auto m:M) os<<"("<<m.first<<":"<<m.second<<") ";
    return os<<"}";
}

#define TRACE
#ifdef TRACE
    #define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template <typename Arg1>
    void __f(const char* name, Arg1&& arg1){
        cerr << name << " : " << arg1 << endl;
    }
    template <typename Arg1, typename... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args){
        const char* comma = strchr(names + 1, ',');
        cerr.write(names, comma - names) << " : " << arg1<<" | ";
        __f(comma+1, args...);
    }
#else
    #define trace(...) 1
#endif

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

inline int64_t random_long(long long l,long long r){
    uniform_int_distribution<int64_t> generator(l,r);
    return generator(rng);
}
inline int64_t random_long(){
    uniform_int_distribution<int64_t> generator(LLONG_MIN,LLONG_MAX);
    return generator(rng);
}

/*/---------------------------Defines----------------------/*/
typedef vector<int> vi;
typedef pair<int,int> pii;

#define ll long long
#define F first
#define S second
#define pb push_back
#define endl "\n"
#define all(v) (v).begin(),(v).end()
/*/-----------------------Modular Arithmetic---------------/*/

const int mod=998244353;
template<const int MOD>
struct modular_int{
	int x;
	static vector<int> inverse_list ;
	const static int inverse_limit;
	const static bool is_prime;
	modular_int(){
		x = 0;
	}
	template<typename T>
	modular_int(const T z){
		x = (z%MOD);
		if (x < 0) x += MOD;
	}
	modular_int(const modular_int<MOD>* z){
		x = z->x;
	}
	modular_int(const modular_int<MOD>& z){
		x = z.x;
	}
	modular_int operator - (const modular_int<MOD>& m) const{
		modular_int<MOD> U;
		U.x = x - m.x;
		if (U.x < 0) U.x += MOD;
		return U;
	}
	modular_int operator + (const modular_int<MOD>& m) const{
		modular_int<MOD> U;
		U.x = x + m.x;
		if (U.x >= MOD) U.x -= MOD;
		return U;
	}
	modular_int& operator -= (const modular_int<MOD>& m){
		x -= m.x;
		if (x < 0) x += MOD;
		return *this;
	}
	modular_int& operator += (const modular_int<MOD>& m){
		x += m.x;
		if (x >= MOD) x -= MOD;
		return *this;
	}
	modular_int operator * (const modular_int<MOD>& m) const{
		modular_int<MOD> U;
		U.x = (x* 1ull * m.x) %MOD;
		return U;
	}
	modular_int& operator *= (const modular_int<MOD>& m){
		x = (x * 1ull * m.x)%MOD;
		return *this;
	}
	template<typename T>
	friend modular_int operator + (const T &l, const modular_int<MOD>& p){
		return (modular_int<MOD>(l) + p);
	}
	template<typename T>
	friend modular_int operator - (const T &l, const modular_int<MOD>& p){
		return (modular_int<MOD>(l) - p);
	}
	template<typename T>
	friend modular_int operator * (const T &l, const modular_int<MOD>& p){
		return (modular_int<MOD>(l) * p);
	}
	template<typename T>
	friend modular_int operator / (const T &l, const modular_int<MOD>& p){
		return (modular_int<MOD>(l) / p);
	}

	int value() const{
		return x;
	}

	modular_int operator ^ (const modular_int<MOD>& cpower) const{
		modular_int<MOD> ans;
		ans.x = 1;
		modular_int<MOD> curr(this);
		int power = cpower.x;

		if (curr.x <= 1){
			if (power == 0) curr.x = 1;
			return curr;
		}
		while( power > 0){
			if (power&1){
				ans *= curr;
			}
			power >>= 1;
			if (power) curr *= curr;
		}
		return ans;
	}

	modular_int operator ^ (long long power) const{
		modular_int<MOD> ans;
		ans.x = 1;
		modular_int<MOD> curr(this);
		if (curr.x <= 1){
			if (power == 0) curr.x = 1;
			return curr;
		}
		// Prime Mods
		if (power >= MOD && is_prime){
			power %= (MOD - 1);
		}

		while( power > 0){
			if (power&1){
				ans *= curr;
			}
			power >>= 1;
			if (power) curr *= curr;

		}
		return ans;
	}

	modular_int operator ^ (int power) const{
		modular_int<MOD> ans;
		ans.x = 1;
		modular_int<MOD> curr(this);

		if (curr.x <= 1){
			if (power == 0) curr.x = 1;
			return curr;
		}
		while( power > 0){
			if (power&1){
				ans *= curr;
			}
			power >>= 1;
			if (power) curr *= curr;

		}
		return ans;
	}

	template<typename T>
	modular_int& operator ^= (T power) {
		modular_int<MOD> res = (*this)^power;
		x = res.x;
		return *this;
	}

	template<typename T>
	modular_int pow(T x){
		return (*this)^x;
	}

	pair<long long,long long> gcd(const int a, const int b) const {
		if (b==0) return {1,0};
		pair<long long,long long> c = gcd(b , a%b);
		return { c.second , c.first - (a/b)*c.second};
	}

	inline void init_inverse_list() const {

		vector<int>& dp = modular_int<MOD>::inverse_list;
		dp.resize(modular_int<MOD>::inverse_limit + 1);
		int n = modular_int<MOD>::inverse_limit;
		dp[0] = 1;
		if (n > 1) dp[1] = 1;
		for(int i = 2; i <= n; ++i){
			dp[i] = (dp[MOD%i] * 1ull *(MOD - MOD/i))%MOD;
		}

	}
	modular_int<MOD> get_inv() const {
		if (modular_int<MOD>::inverse_list.size() < modular_int<MOD>::inverse_limit + 1) init_inverse_list();

		if (this->x <= modular_int<MOD>::inverse_limit){
			return modular_int<MOD>::inverse_list[this->x];
		}
		pair<long long,long long> G = gcd(this->x,MOD);
		return modular_int<MOD>(G.first);
	}
	modular_int<MOD> operator - () const {
		modular_int<MOD> v(0);
		v -= (*this);
		return v;
	}
	modular_int operator / (const modular_int<MOD>& m) const{
		modular_int<MOD> U(this);
		U *= m.get_inv();
		return U;
	}
	modular_int& operator /= (const modular_int<MOD>& m){
		(*this) *= m.get_inv();
		return *this;
	}
	bool operator==(const modular_int<MOD>& m) const{
		return x == m.x;
	}

	bool operator < (const modular_int<MOD>& m) const {
		return x < m.x;
	}

	template<typename T>
	bool operator == (const T& m) const{
		return (*this)== (modular_int<MOD>(m));
	}

	template<typename T>
	bool operator < (const T& m) const {
		return x < (modular_int<MOD>(m)).x;
	}
	template<typename T>
	bool operator > (const T& m) const {
		return x > (modular_int<MOD>(m)).x;
	}
	template<typename T>
	friend bool operator == (const T& x, const modular_int<MOD>& m) {
		return (modular_int<MOD>(x)).x == m.x;
	}
	template<typename T>
	friend bool operator < (const T& x, const modular_int<MOD>& m){
		return (modular_int<MOD>(x)).x < m.x;
	}
	template<typename T>
	friend bool operator > (const T& x, const modular_int<MOD>& m){
		return (modular_int<MOD>(x)).x > m.x;
	}

	friend istream& operator >> (istream& is, modular_int<MOD>& p){
		int64_t val;
		is >> val;
		p.x = (val%MOD);
		if (p.x < 0) p.x += MOD;
		return is;
	}
	friend ostream& operator << (ostream& os, const modular_int<MOD>& p) {return os<<p.x;}

};

using mint = modular_int<mod>;
template<const int MOD>
vector<int> modular_int<MOD>::inverse_list ;
template<const int MOD>
const int modular_int<MOD>::inverse_limit = -1;
template<const int MOD>
const bool modular_int<MOD>::is_prime = true;
// template<>   //-> useful if computing inverse fact = i_f[i-1] / i;
// const int modular_int<mod>::inverse_limit = 100000;

/*/-----------------------------Code begins----------------------------------/*/

void print(int n,int k){
	int place = n - k;
	int v1 = place / k;
	int cntv1 = k - place%k;
	vector<int> ans(place );

	for(int i = 0; i < place; ++i){
		ans[i] = (n - i - 1)/k;
	}

	// for(int i = 0; i < place; ++i){
	// 	ans.push_back( (i / k) + 1);
	// }
	// reverse(all(ans));
	assert(ans.size() == place);
	trace(ans);
}

const int SQ = 600;

vector<long long> P[SQ];

void solve(){
	int n;
	cin >> n;
	vector<long long> A(n),prf(n+1);
	for(int i = 0 ;i < n; ++i){
		cin >> A[i];
	}
	sort(all(A));

	for(int i = 1; i <= n; ++i){
		prf[i] = prf[i-1] + A[i-1];
	}

	// int block = min(100,n);
	// for(int i = 1; i <= block; ++i){
	// 	P[i].resize(n + 1);

	// 	P[i][0] = 0;

	// 	for(int j = 1; j <= n; ++j){
	// 		if (j  <= i){
	// 			P[i][j] = prf[j];
	// 		}
	// 		else{
	// 			P[i][j] = prf[j] + P[i][j-i];

	// 		}
	// 	}
	// }

	prf[0] = 0;

	vector<mint> ans(n+1);
	ans[n] = 0;

	for(int i = 1; i < n ; ++i){
		int place = i ;
		int rem = n - place;

		if (rem >= place){
			ans[n - i] = prf[i];
		}
		else{
			// if (rem <= block){
			// 	ans[n - i] = P[rem][i];
			// }
			// else{
				int v1 = place % rem;
				int st = 1 + v1;
				int kol = (place + rem - 1) / rem;

				ans[n-i] = prf[v1] * kol;

				for(int u = st, mul = place/rem;  u <= place; u += rem, --mul){
					ans[n-i] += (prf[u + rem - 1] - prf[u - 1])*mul;
				}

			// }
		}
	}
	mint denom = 1;
	denom /= n;
	for(int i = 1 ; i <= n; ++i){
		cout << ans[i] * denom << " ";
	}
	cout << endl;
}

int main(){
    // Use "set_name".max_load_factor(0.25);"set_name".reserve(512); with unordered set
    // Or use gp_hash_table<X,null_type>
    ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
    cout<<fixed<<setprecision(25);
    cerr<<fixed<<setprecision(10);
    auto start = std::chrono::high_resolution_clock::now();

    // for(int k = 1; k < 20; ++k){
    // 	trace(20,k);
    // 	print(20,k);
    // }
    int t=1;
    // cin>>t;
    while(t--) {
        solve();
    }
    auto stop = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(stop - start);

    // cerr << "Time taken : " << ((long double)duration.count())/((long double) 1e9) <<"s "<< endl;
}


/*/ Author: kal013 /*/
// #pragma GCC optimize ("O3")
#include "bits/stdc++.h"
#include "ext/pb_ds/assoc_container.hpp"
#include "ext/pb_ds/tree_policy.hpp"
using namespace std;
using namespace __gnu_pbds;

template<class T>
using ordered_set = tree<T, null_type,less<T>, rb_tree_tag,tree_order_statistics_node_update> ;

template<class key, class value, class cmp = std::less<key>>
using ordered_map = tree<key, value, cmp, rb_tree_tag, tree_order_statistics_node_update>;
// find_by_order(k)  returns iterator to kth element starting from 0;
// order_of_key(k) returns count of elements strictly smaller than k;

struct custom_hash { // Credits: https://codeforces.com/blog/entry/62393
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
    size_t operator()(pair<int64_t,int64_t> Y) const{
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(Y.first * 31 + Y.second + FIXED_RANDOM);
    }
};

template<class T> ostream& operator<<(ostream &os, vector<T> V) {
    os << "[ ";
    for(auto v : V) os << v << " ";
    return os << "]";
}
template<class T> ostream& operator<<(ostream &os, set<T> S){
    os << "{ ";
    for(auto s:S) os<<s<<" ";
    return os<<"}";
}
template<class T> ostream& operator<<(ostream &os, unordered_set<T> S){
    os << "{ ";
    for(auto s:S) os<<s<<" ";
    return os<<"}";
}
template<class T> ostream& operator << (ostream& os, multiset<T> S){
    os << "{ ";
    for(auto s:S) os<<s<<" ";
    return os<<"}";
}
template<class T> ostream& operator<<(ostream &os, ordered_set<T> S){
    os << "{ ";
    for(auto s:S) os<<s<<" ";
    return os<<"}";
}
template<class L, class R> ostream& operator<<(ostream &os, pair<L,R> P) {
    return os << "(" << P.first << "," << P.second << ")";
}
template<class L, class R> ostream& operator<<(ostream &os, map<L,R> M) {
    os << "{ ";
    for(auto m:M) os<<"("<<m.first<<":"<<m.second<<") ";
    return os<<"}";
}
template<class L, class R, class chash = std::hash<R>> ostream& operator<<(ostream &os, unordered_map<L,R,chash> M) {
    os << "{ ";
    for(auto m:M) os<<"("<<m.first<<":"<<m.second<<") ";
    return os<<"}";
}
template<class L, class R, class chash = std::hash<R> > ostream& operator<<(ostream &os, gp_hash_table<L,R,chash> M) {
    os << "{ ";
    for(auto m:M) os<<"("<<m.first<<":"<<m.second<<") ";
    return os<<"}";
}

#define TRACE
#ifdef TRACE
    #define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template <typename Arg1>
    void __f(const char* name, Arg1&& arg1){
        cerr << name << " : " << arg1 << endl;
    }
    template <typename Arg1, typename... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args){
        const char* comma = strchr(names + 1, ',');
        cerr.write(names, comma - names) << " : " << arg1<<" | ";
        __f(comma+1, args...);
    }
#else
    #define trace(...) 1
#endif

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

inline int64_t random_long(long long l,long long r){
    uniform_int_distribution<int64_t> generator(l,r);
    return generator(rng);
}
inline int64_t random_long(){
    uniform_int_distribution<int64_t> generator(LLONG_MIN,LLONG_MAX);
    return generator(rng);
}

/*/---------------------------Defines----------------------/*/
typedef vector<int> vi;
typedef pair<int,int> pii;

#define ll long long
#define F first
#define S second
#define pb push_back
#define endl "\n"
#define all(v) (v).begin(),(v).end()
/*/-----------------------Modular Arithmetic---------------/*/

const int mod=998244353;
template<const int MOD>
struct modular_int{
	int x;
	static vector<int> inverse_list ;
	const static int inverse_limit;
	const static bool is_prime;
	modular_int(){
		x = 0;
	}
	template<typename T>
	modular_int(const T z){
		x = (z%MOD);
		if (x < 0) x += MOD;
	}
	modular_int(const modular_int<MOD>* z){
		x = z->x;
	}
	modular_int(const modular_int<MOD>& z){
		x = z.x;
	}
	modular_int operator - (const modular_int<MOD>& m) const{
		modular_int<MOD> U;
		U.x = x - m.x;
		if (U.x < 0) U.x += MOD;
		return U;
	}
	modular_int operator + (const modular_int<MOD>& m) const{
		modular_int<MOD> U;
		U.x = x + m.x;
		if (U.x >= MOD) U.x -= MOD;
		return U;
	}
	modular_int& operator -= (const modular_int<MOD>& m){
		x -= m.x;
		if (x < 0) x += MOD;
		return *this;
	}
	modular_int& operator += (const modular_int<MOD>& m){
		x += m.x;
		if (x >= MOD) x -= MOD;
		return *this;
	}
	modular_int operator * (const modular_int<MOD>& m) const{
		modular_int<MOD> U;
		U.x = (x* 1ull * m.x) %MOD;
		return U;
	}
	modular_int& operator *= (const modular_int<MOD>& m){
		x = (x * 1ull * m.x)%MOD;
		return *this;
	}
	template<typename T>
	friend modular_int operator + (const T &l, const modular_int<MOD>& p){
		return (modular_int<MOD>(l) + p);
	}
	template<typename T>
	friend modular_int operator - (const T &l, const modular_int<MOD>& p){
		return (modular_int<MOD>(l) - p);
	}
	template<typename T>
	friend modular_int operator * (const T &l, const modular_int<MOD>& p){
		return (modular_int<MOD>(l) * p);
	}
	template<typename T>
	friend modular_int operator / (const T &l, const modular_int<MOD>& p){
		return (modular_int<MOD>(l) / p);
	}

	int value() const{
		return x;
	}

	modular_int operator ^ (const modular_int<MOD>& cpower) const{
		modular_int<MOD> ans;
		ans.x = 1;
		modular_int<MOD> curr(this);
		int power = cpower.x;

		if (curr.x <= 1){
			if (power == 0) curr.x = 1;
			return curr;
		}
		while( power > 0){
			if (power&1){
				ans *= curr;
			}
			power >>= 1;
			if (power) curr *= curr;
		}
		return ans;
	}

	modular_int operator ^ (long long power) const{
		modular_int<MOD> ans;
		ans.x = 1;
		modular_int<MOD> curr(this);
		if (curr.x <= 1){
			if (power == 0) curr.x = 1;
			return curr;
		}
		// Prime Mods
		if (power >= MOD && is_prime){
			power %= (MOD - 1);
		}

		while( power > 0){
			if (power&1){
				ans *= curr;
			}
			power >>= 1;
			if (power) curr *= curr;

		}
		return ans;
	}

	modular_int operator ^ (int power) const{
		modular_int<MOD> ans;
		ans.x = 1;
		modular_int<MOD> curr(this);

		if (curr.x <= 1){
			if (power == 0) curr.x = 1;
			return curr;
		}
		while( power > 0){
			if (power&1){
				ans *= curr;
			}
			power >>= 1;
			if (power) curr *= curr;

		}
		return ans;
	}

	template<typename T>
	modular_int& operator ^= (T power) {
		modular_int<MOD> res = (*this)^power;
		x = res.x;
		return *this;
	}

	template<typename T>
	modular_int pow(T x){
		return (*this)^x;
	}

	pair<long long,long long> gcd(const int a, const int b) const {
		if (b==0) return {1,0};
		pair<long long,long long> c = gcd(b , a%b);
		return { c.second , c.first - (a/b)*c.second};
	}

	inline void init_inverse_list() const {

		vector<int>& dp = modular_int<MOD>::inverse_list;
		dp.resize(modular_int<MOD>::inverse_limit + 1);
		int n = modular_int<MOD>::inverse_limit;
		dp[0] = 1;
		if (n > 1) dp[1] = 1;
		for(int i = 2; i <= n; ++i){
			dp[i] = (dp[MOD%i] * 1ull *(MOD - MOD/i))%MOD;
		}

	}
	modular_int<MOD> get_inv() const {
		if (modular_int<MOD>::inverse_list.size() < modular_int<MOD>::inverse_limit + 1) init_inverse_list();

		if (this->x <= modular_int<MOD>::inverse_limit){
			return modular_int<MOD>::inverse_list[this->x];
		}
		pair<long long,long long> G = gcd(this->x,MOD);
		return modular_int<MOD>(G.first);
	}
	modular_int<MOD> operator - () const {
		modular_int<MOD> v(0);
		v -= (*this);
		return v;
	}
	modular_int operator / (const modular_int<MOD>& m) const{
		modular_int<MOD> U(this);
		U *= m.get_inv();
		return U;
	}
	modular_int& operator /= (const modular_int<MOD>& m){
		(*this) *= m.get_inv();
		return *this;
	}
	bool operator==(const modular_int<MOD>& m) const{
		return x == m.x;
	}

	bool operator < (const modular_int<MOD>& m) const {
		return x < m.x;
	}

	template<typename T>
	bool operator == (const T& m) const{
		return (*this)== (modular_int<MOD>(m));
	}

	template<typename T>
	bool operator < (const T& m) const {
		return x < (modular_int<MOD>(m)).x;
	}
	template<typename T>
	bool operator > (const T& m) const {
		return x > (modular_int<MOD>(m)).x;
	}
	template<typename T>
	friend bool operator == (const T& x, const modular_int<MOD>& m) {
		return (modular_int<MOD>(x)).x == m.x;
	}
	template<typename T>
	friend bool operator < (const T& x, const modular_int<MOD>& m){
		return (modular_int<MOD>(x)).x < m.x;
	}
	template<typename T>
	friend bool operator > (const T& x, const modular_int<MOD>& m){
		return (modular_int<MOD>(x)).x > m.x;
	}

	friend istream& operator >> (istream& is, modular_int<MOD>& p){
		int64_t val;
		is >> val;
		p.x = (val%MOD);
		if (p.x < 0) p.x += MOD;
		return is;
	}
	friend ostream& operator << (ostream& os, const modular_int<MOD>& p) {return os<<p.x;}

};

using mint = modular_int<mod>;
template<const int MOD>
vector<int> modular_int<MOD>::inverse_list ;
template<const int MOD>
const int modular_int<MOD>::inverse_limit = -1;
template<const int MOD>
const bool modular_int<MOD>::is_prime = true;
// template<>   //-> useful if computing inverse fact = i_f[i-1] / i;
// const int modular_int<mod>::inverse_limit = 100000;

/*/-----------------------------Code begins----------------------------------/*/

void print(int n,int k){
	int place = n - k;
	int v1 = place / k;
	int cntv1 = k - place%k;
	vector<int> ans(place );

	for(int i = 0; i < place; ++i){
		ans[i] = (n - i - 1)/k;
	}

	// for(int i = 0; i < place; ++i){
	// 	ans.push_back( (i / k) + 1);
	// }
	// reverse(all(ans));
	assert(ans.size() == place);
	trace(ans);
}

const int SQ = 600;

vector<long long> P[SQ];

void solve(){
	int n;
	cin >> n;
	vector<long long> A(n),prf(n+1);
	for(int i = 0 ;i < n; ++i){
		cin >> A[i];
	}
	sort(all(A));

	for(int i = 1; i <= n; ++i){
		prf[i] = prf[i-1] + A[i-1];
	}

	const int block = 350;
	for(int i = 1; i <= block; ++i){
		P[i].resize(n + 1);

		P[i][0] = 0;

		for(int j = 1; j <= n; ++j){
			if (j  <= i){
				P[i][j] = prf[j];
			}
			else{
				P[i][j] = prf[j] + P[i][j-i];

			}
		}
	}

	prf[0] = 0;

	vector<mint> ans(n+1);
	ans[n] = 0;

	for(int i = 1; i < n ; ++i){
		int place = i ;
		int rem = n - place;

		if (rem >= place){
			ans[n - i] = prf[i];
		}
		else{
			if (rem <= block){
				ans[n - i] = P[rem][i];
			}
			else{
				int v1 = place % rem;
				int st = 1 + v1;
				int kol = (place + rem - 1) / rem;

				ans[n-i] = prf[v1] * kol;

				for(int u = st, mul = place/rem;  u <= place; u += rem, --mul){
					ans[n-i] += (prf[u + rem - 1] - prf[u - 1])*mul;
				}

			}
		}
	}
	mint denom = 1;
	denom /= n;
	for(int i = 1 ; i <= n; ++i){
		cout << ans[i] * denom << " ";
	}
	cout << endl;
}

int main(){
    // Use "set_name".max_load_factor(0.25);"set_name".reserve(512); with unordered set
    // Or use gp_hash_table<X,null_type>
    ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
    cout<<fixed<<setprecision(25);
    cerr<<fixed<<setprecision(10);
    auto start = std::chrono::high_resolution_clock::now();

    // for(int k = 1; k < 20; ++k){
    // 	trace(20,k);
    // 	print(20,k);
    // }
    int t=1;
    // cin>>t;
    while(t--) {
        solve();
    }
    auto stop = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(stop - start);

    // cerr << "Time taken : " << ((long double)duration.count())/((long double) 1e9) <<"s "<< endl;
}


#include <map>
#include <set>
#include <ctime>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
typedef long long ll;
using namespace std;
int read(){
	int p=0, q=1;
	char ch=getchar();
	while (ch<'0' || ch>'9') ch=='-'?q=-1:0, ch=getchar();
	while (ch>='0' && ch<='9') p=p*10+ch-'0', ch=getchar();
	return p*q;
}
ll readll(){
	ll p=0, q=1;
	char ch=getchar();
	while (ch<'0' || ch>'9') ch=='-'?q=-1:0, ch=getchar();
	while (ch>='0' && ch<='9') p=p*10+ch-'0', ch=getchar();
	return p*q;
}
bool cmp(int x, int y){return x>y;}
#define mo 998244353
int power(ll a, int b){
	ll c=1;
	while (b){
		if (b&1) c=c*a%mo;
		a=a*a%mo;
		b>>=1;
	}
	return c;
}
#define N 300005
int n, a[N], pre[N];
int main(){
	n=read();
	for (int i=1;i<=n;i++) a[i]=read();
	sort(a+1,a+1+n,cmp);
	for (int i=1;i<=n;i++) pre[i]=(pre[i-1]+a[i])%mo;
	for (int k=1;k<=n;k++){
		int low=(n-k)/k;
		ll ans=0;
		for (int j=1;j<=low;j++)
			ans=(ans+1ll*(pre[(j+1)*k]-pre[j*k])*j)%mo;
		ans=(ans+1ll*(pre[n]-pre[low*k+k])*(low+1))%mo;
		printf("%I64d%s", ans*power(n,mo-2)%mo, k==n?"\n":" ");
	}
	return 0;
}


#include <map>
#include <set>
#include <ctime>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
typedef long long ll;
using namespace std;
int read(){
	int p=0, q=1;
	char ch=getchar();
	while (ch<'0' || ch>'9') ch=='-'?q=-1:0, ch=getchar();
	while (ch>='0' && ch<='9') p=p*10+ch-'0', ch=getchar();
	return p*q;
}
ll readll(){
	ll p=0, q=1;
	char ch=getchar();
	while (ch<'0' || ch>'9') ch=='-'?q=-1:0, ch=getchar();
	while (ch>='0' && ch<='9') p=p*10+ch-'0', ch=getchar();
	return p*q;
}
bool cmp(int x, int y){return x>y;}
#define mo 998244353
int power(ll a, int b){
	ll c=1;
	while (b){
		if (b&1) c=c*a%mo;
		a=a*a%mo;
		b>>=1;
	}
	return c;
}
#define N 300005
int n, a[N], pre[N];
int main(){
	n=read();
	for (int i=1;i<=n;i++) a[i]=read();
	sort(a+1,a+1+n,cmp);
	for (int i=1;i<=n;i++) pre[i]=(pre[i-1]+a[i])%mo;
	for (int k=1;k<=n;k++){
		int low=(n-k)/k;
		ll ans=0;
		for (int j=1;j<=low;j++)
			ans=(ans+1ll*(pre[(j+1)*k]-pre[j*k])*j)%mo;
		ans=(ans+1ll*(pre[n]-pre[low*k+k])*(low+1))%mo;
		printf("%I64d%s", (ans*power(n,mo-2)%mo+mo)%mo, k==n?"\n":" ");
	}
	return 0;
}