```go
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
reader := bufio.NewReader(os.Stdin)
writer := bufio.NewWriter(os.Stdout)
defer writer.Flush()
var n int
var s int64
fmt.Fscan(reader, &n, &s)
// Check feasibility range
// Min sum is achieved by a star graph (branching coefficient n-1): 1 (root) + 2*(n-1) = 2n-1
// Max sum is achieved by a path (branching coefficient 1): n*(n+1)/2
if s < int64(2*n-1) || s > int64(n)*int64(n+1)/2 {
fmt.Fprintln(writer, "No")
return
}
// Function to calculate minimum sum of subtree sizes (depths) for a given branching coefficient k
calcMinSum := func(k int) int64 {
if k == 1 {
return int64(n) * int64(n+1) / 2
}
var sum int64 = 0
rem := n
depth := 1
count := 1 // nodes at current depth
for rem > 0 {
take := rem
if take > count {
take = count
}
sum += int64(take) * int64(depth)
rem -= take
// Calculate capacity for next level
// count * k can overflow int if not careful, though n <= 10^5 makes it safe in int64
nextCount := int64(count) * int64(k)
if nextCount > int64(n) {
count = n + 1 // Cap at > n
} else {
count = int(nextCount)
}
depth++
}
return sum
}
// Binary search for the minimum branching coefficient k
low := 1
high := n - 1
ansK := n - 1
for low <= high {
mid := (low + high) / 2
if calcMinSum(mid) <= s {
ansK = mid
high = mid - 1
} else {
low = mid + 1
}
}
fmt.Fprintln(writer, "Yes")
// Construct the parent array for the complete k-ary tree (BFS order)
p := make([]int, n+1)
d := make([]int, n+1)
degree := make([]int, n+1)
d[1] = 1
var currSum int64 = 1
// Standard BFS parent assignment: node i (1-based)
// For k-ary tree rooted at 1:
// Children of 1 are 2..k+1
// Children of 2 are k+2..2k+1, etc.
// Parent of j > 1 is (j-2)/k + 1
for i := 2; i <= n; i++ {
parent := (i-2)/ansK + 1
p[i] = parent
d[i] = d[parent] + 1
degree[parent]++
currSum += int64(d[i])
}
rem := s - currSum
// Identify the "spine" to extend.
// We choose the path from node n to 1 in the BFS tree as fixed.
// Other nodes can be moved to the end of this spine to increase total depth.
onPath := make([]bool, n+1)
curr := n
for curr != 0 {
onPath[curr] = true
curr = p[curr]
}
spineEnd := n
// Movable nodes are those not on the fixed spine.
// We process them in descending order of depth (BFS order n down to 2 essentially sorts by depth).
movable := make([]int, 0, n)
for i := n; i >= 2; i-- {
if !onPath[i] {
movable = append(movable, i)
}
}
// Greedily move nodes to the end of the spine
for _, u := range movable {
if rem == 0 {
break
}
// Calculate gain if we move u to be a child of current spineEnd
gain := int64(d[spineEnd] + 1 - d[u])
if rem >= gain {
// Perform full move
degree[p[u]]--
p[u] = spineEnd
degree[spineEnd]++
d[u] = d[spineEnd] + 1
spineEnd = u
rem -= gain
} else {
// Perform partial move to satisfy exact rem
// We need a target depth of d[u] + rem
// So we need a parent at depth d[u] + rem - 1
targetPDepth := d[u] + int(rem) - 1
// Find a suitable parent with capacity
found := false
// We scan all nodes to find a valid parent.
// Since we need to output any valid tree, finding the first one works.
for v := 1; v <= n; v++ {
if d[v] == targetPDepth && degree[v] < ansK {
degree[p[u]]--
p[u] = v
degree[v]++
d[u] = d[v] + 1
rem = 0
found = true
break
}
}
if !found {
// This case should theoretically not be reachable given the constraints and logic
}
break
}
}
// Output result
for i := 2; i <= n; i++ {
fmt.Fprintf(writer, "%d ", p[i])
}
fmt.Fprintln(writer)
}
```