← Home
```go
package main

import (
	"bufio"
	"container/heap"
	"fmt"
	"os"
	"sort"
)

const K = 15
const K_OUT = 10

type Edge struct {
	w    int64
	u, v int
}

type EdgeHeap []Edge

func (h EdgeHeap) Len() int           { return len(h) }
func (h EdgeHeap) Less(i, j int) bool { return h[i].w < h[j].w }
func (h EdgeHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }
func (h *EdgeHeap) Push(x interface{}) { *h = append(*h, x.(Edge)) }
func (h *EdgeHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[0 : n-1]
	return x
}

type DSU struct {
	parent []int
}

func NewDSU(n int) *DSU {
	parent := make([]int, n+1)
	for i := 0; i <= n; i++ {
		parent[i] = i
	}
	return &DSU{parent: parent}
}

func (d *DSU) find(i int) int {
	if d.parent[i] == i {
		return i
	}
	d.parent[i] = d.find(d.parent[i])
	return d.parent[i]
}

func (d *DSU) unite(i, j int) bool {
	rootI := d.find(i)
	rootJ := d.find(j)
	if rootI != rootJ {
		d.parent[rootI] = rootJ
		return true
	}
	return false
}

var (
	n, m        int
	a           []int64
	forbid_list [][]int
	is_forbid   []bool

	Cand    [][]Edge
	AllCand []Edge

	adj        [][]int
	child      [][]int
	timer_dfs  int
	in_time    []int
	out_time   []int
	depth      []int
	up         [][]int
	deg_T      []int

	E_out      [][]Edge
	pq         []*EdgeHeap
	seen_y     []int
	seen_timer int

	comp_parent []int
)

func dfs_tree(u, p, d int) {
	timer_dfs++
	in_time[u] = timer_dfs
	depth[u] = d
	up[u][0] = p
	for i := 1; i < 20; i++ {
		up[u][i] = up[up[u][i-1]][i-1]
	}
	for _, v := range adj[u] {
		if v != p {
			dfs_tree(v, u, d+1)
			child[u] = append(child[u], v)
		}
	}
	out_time[u] = timer_dfs
}

func in_subtree(v, u int) bool {
	return in_time[u] <= in_time[v] && in_time[v] <= out_time[u]
}

func get_child_ancestor(x, u int) int {
	if depth[x] <= depth[u] {
		return -1
	}
	for i := 19; i >= 0; i-- {
		if depth[x]-(1<<i) > depth[u] {
			x = up[x][i]
		}
	}
	return x
}

func dfs_sack(u, p int) {
	for _, e := range Cand[u] {
		heap.Push(pq[u], e)
	}
	for _, v := range child[u] {
		dfs_sack(v, u)
		if pq[u].Len() < pq[v].Len() {
			pq[u], pq[v] = pq[v], pq[u]
		}
		for pq[v].Len() > 0 {
			heap.Push(pq[u], heap.Pop(pq[v]).(Edge))
		}
	}
	var temp []Edge
	found := 0
	seen_timer++
	for pq[u].Len() > 0 && found < K_OUT {
		e := heap.Pop(pq[u]).(Edge)
		temp = append(temp, e)
		if !in_subtree(e.v, u) && seen_y[e.v] != seen_timer {
			E_out[u] = append(E_out[u], e)
			seen_y[e.v] = seen_timer
			found++
		}
	}
	for _, e := range temp {
		heap.Push(pq[u], e)
	}
}

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	_, err := fmt.Fscan(in, &n, &m)
	if err != nil {
		return
	}

	a = make([]int64, n+1)
	V_sorted := make([]int, n)
	for i := 1; i <= n; i++ {
		fmt.Fscan(in, &a[i])
		V_sorted[i-1] = i
	}
	sort.Slice(V_sorted, func(i, j int) bool {
		x, y := V_sorted[i], V_sorted[j]
		if a[x] != a[y] {
			return a[x] < a[y]
		}
		return x < y
	})

	forbid_list = make([][]int, n+1)
	for i := 0; i < m; i++ {
		var u, v int
		fmt.Fscan(in, &u, &v)
		forbid_list[u] = append(forbid_list[u], v)
		forbid_list[v] = append(forbid_list[v], u)
	}

	is_forbid = make([]bool, n+1)
	Cand = make([][]Edge, n+1)
	for x := 1; x <= n; x++ {
		for _, y := range forbid_list[x] {
			is_forbid[y] = true
		}
		for _, y := range V_sorted {
			if y != x && !is_forbid[y] {
				Cand[x] = append(Cand[x], Edge{w: a[x] + a[y], u: x, v: y})
				AllCand = append(AllCand, Edge{w: a[x] + a[y], u: x, v: y})
				if len(Cand[x]) == K {
					break
				}
			}
		}
		for _, y := range forbid_list[x] {
			is_forbid[y] = false
		}
	}

	sort.Slice(AllCand, func(i, j int) bool {
		return AllCand[i].w < AllCand[j].w
	})

	dsu := NewDSU(n)
	Cost_T := int64(0)
	edges_in_MST := 0
	adj = make([][]int, n+1)
	deg_T = make([]int, n+1)

	for _, e := range AllCand {
		if dsu.unite(e.u, e.v) {
			adj[e.u] = append(adj[e.u], e.v)
			adj[e.v] = append(adj[e.v], e.u)
			Cost_T += e.w
			deg_T[e.u]++
			deg_T[e.v]++
			edges_in_MST++
		}
	}

	ans := make([]int64, n+1)
	for i := 0; i <= n; i++ {
		ans[i] = -1
	}

	if edges_in_MST < n-1 {
		comp_size := make([]int, n+1)
		for i := 1; i <= n; i++ {
			comp_size[dsu.find(i)]++
		}

		var isolated []int
		num_comps := 0
		for i := 1; i <= n; i++ {
			if dsu.find(i) == i {
				num_comps++
				if comp_size[i] == 1 {
					isolated = append(isolated, i)
				}
			}
		}

		if num_comps == 2 && len(isolated) > 0 {
			for _, u := range isolated {
				dsu_u := NewDSU(n)
				edges := 0
				cost := int64(0)
				for _, e := range AllCand {
					if e.u == u || e.v == u {
						continue
					}
					if dsu_u.unite(e.u, e.v) {
						edges++
						cost += e.w
					}
				}
				if edges == n-2 {
					ans[u] = cost
				}
			}
		}
		for i := 1; i <= n; i++ {
			if i == n {
				fmt.Fprint(out, ans[i])
			} else {
				fmt.Fprint(out, ans[i], " ")
			}
		}
		fmt.Fprintln(out)
		return
	}

	child = make([][]int, n+1)
	in_time = make([]int, n+1)
	out_time = make([]int, n+1)
	depth = make([]int, n+1)
	up = make([][]int, n+1)
	for i := 0; i <= n; i++ {
		up[i] = make([]int, 20)
	}

	root := V_sorted[0]
	dfs_tree(root, root, 0)

	E_out = make([][]Edge, n+1)
	pq = make([]*EdgeHeap, n+1)
	for i := 0; i <= n; i++ {
		h := &EdgeHeap{}
		heap.Init(h)
		pq[i] = h
	}
	seen_y = make([]int, n+1)

	dfs_sack(root, root)

	comp_parent = make([]int, n+1)
	var get_p func(x int) int
	get_p = func(x int) int {
		if comp_parent[x] == x {
			return x
		}
		comp_parent[x] = get_p(comp_parent[x])
		return comp_parent[x]
	}

	for u := 1; u <= n; u++ {
		if deg_T[u] == 1 {
			sum_adj := int64(0)
			for _, v := range adj[u] {
				sum_adj += a[u] + a[v]
			}
			ans[u] = Cost_T - sum_adj
		} else {
			var candidates []Edge
			for _, c := range child[u] {
				for _, e := range E_out[c] {
					if e.v != u && e.u != u {
						candidates = append(candidates, e)
					}
				}
			}
			sort.Slice(candidates, func(i, j int) bool {
				return candidates[i].w < candidates[j].w
			})

			find_comp := func(x int) int {
				if x == 0 {
					return 0
				}
				if u == root {
					return get_child_ancestor(x, u)
				} else {
					if in_subtree(x, u) {
						return get_child_ancestor(x, u)
					} else {
						return 0
					}
				}
			}

			var dsu_nodes []int
			dsu_nodes = append(dsu_nodes, 0)
			for _, c := range child[u] {
				dsu_nodes = append(dsu_nodes, c)
			}
			for _, node := range dsu_nodes {
				comp_parent[node] = node
			}

			edges_added := 0
			cost_added := int64(0)

			for _, e := range candidates {
				comp_u := find_comp(e.u)
				comp_v := find_comp(e.v)
				if comp_u == -1 || comp_v == -1 {
					continue
				}

				pu := get_p(comp_u)
				pv := get_p(comp_v)

				if pu != pv {
					comp_parent[pu] = pv
					edges_added++
					cost_added += e.w
				}
				if edges_added == deg_T[u]-1 {
					break
				}
			}

			if edges_added == deg_T[u]-1 {
				sum_adj := int64(0)
				for _, v := range adj[u] {
					sum_adj += a[u] + a[v]
				}
				ans[u] = Cost_T - sum_adj + cost_added
			} else {
				ans[u] = -1
			}
		}
	}

	for i := 1; i <= n; i++ {
		if i == n {
			fmt.Fprint(out, ans[i])
		} else {
			fmt.Fprint(out, ans[i], " ")
		}
	}
	fmt.Fprintln(out)
}
```