```go
package main
import (
"bufio"
"container/heap"
"fmt"
"os"
)
type Edge struct {
to int
w int64
}
type FastScanner struct {
r *bufio.Reader
}
func NewFastScanner() *FastScanner {
return &FastScanner{r: bufio.NewReaderSize(os.Stdin, 1<<20)}
}
func (fs *FastScanner) nextInt() int {
sign, val := 1, 0
b, _ := fs.r.ReadByte()
for (b < '0' || b > '9') && b != '-' {
b, _ = fs.r.ReadByte()
}
if b == '-' {
sign = -1
b, _ = fs.r.ReadByte()
}
for b >= '0' && b <= '9' {
val = val*10 + int(b-'0')
b, _ = fs.r.ReadByte()
}
return sign * val
}
type Item struct {
d int64
node int
idx int
}
type PQueue []*Item
func (pq PQueue) Len() int { return len(pq) }
func (pq PQueue) Less(i, j int) bool { return pq[i].d < pq[j].d }
func (pq PQueue) Swap(i, j int) { pq[i], pq[j] = pq[j], pq[i]; pq[i].idx = i; pq[j].idx = j }
func (pq *PQueue) Push(x interface{}) { it := x.(*Item); it.idx = len(*pq); *pq = append(*pq, it) }
func (pq *PQueue) Pop() interface{} {
old := *pq
n := len(old)
it := old[n-1]
*pq = old[:n-1]
return it
}
func main() {
in := NewFastScanner()
n := in.nextInt()
m := in.nextInt()
g := make([][]Edge, n)
for i := 0; i < m; i++ {
u := in.nextInt() - 1
v := in.nextInt() - 1
w := int64(in.nextInt())
g[u] = append(g[u], Edge{v, w})
g[v] = append(g[v], Edge{u, w})
}
N := 4 * n
const INF int64 = 1<<62
dist := make([]int64, N)
for i := range dist {
dist[i] = INF
}
start := 0*n + 0
dist[start] = 0
pq := &PQueue{}
heap.Init(pq)
heap.Push(pq, &Item{d: 0, node: start})
for pq.Len() > 0 {
it := heap.Pop(pq).(*Item)
d := it.d
u := it.node
if d != dist[u] {
continue
}
layer := u / n
v := u % n
for _, e := range g[v] {
toBase := e.to
w := e.w
switch layer {
case 0:
// to layer 0
id := 0*n + toBase
nd := d + w
if nd < dist[id] {
dist[id] = nd
heap.Push(pq, &Item{d: nd, node: id})
}
// to layer 1 (free used)
id = 1*n + toBase
nd = d + 0
if nd < dist[id] {
dist[id] = nd
heap.Push(pq, &Item{d: nd, node: id})
}
// to layer 2 (extra used)
id = 2*n + toBase
nd = d + 2*w
if nd < dist[id] {
dist[id] = nd
heap.Push(pq, &Item{d: nd, node: id})
}
// to layer 3 (both on this edge)
id = 3*n + toBase
nd = d + w
if nd < dist[id] {
dist[id] = nd
heap.Push(pq, &Item{d: nd, node: id})
}
case 1:
// to layer 1
id := 1*n + toBase
nd := d + w
if nd < dist[id] {
dist[id] = nd
heap.Push(pq, &Item{d: nd, node: id})
}
// to layer 3 (use extra now)
id = 3*n + toBase
nd = d + 2*w
if nd < dist[id] {
dist[id] = nd
heap.Push(pq, &Item{d: nd, node: id})
}
case 2:
// to layer 2
id := 2*n + toBase
nd := d + w
if nd < dist[id] {
dist[id] = nd
heap.Push(pq, &Item{d: nd, node: id})
}
// to layer 3 (use free now)
id = 3*n + toBase
nd = d + 0
if nd < dist[id] {
dist[id] = nd
heap.Push(pq, &Item{d: nd, node: id})
}
case 3:
// to layer 3
id := 3*n + toBase
nd := d + w
if nd < dist[id] {
dist[id] = nd
heap.Push(pq, &Item{d: nd, node: id})
}
}
}
}
out := bufio.NewWriterSize(os.Stdout, 1<<20)
for i := 1; i < n; i++ {
if i > 1 {
fmt.Fprint(out, " ")
}
fmt.Fprint(out, dist[3*n+i])
}
fmt.Fprintln(out)
out.Flush()
}
```