← Home
package main

import (
	"bufio"
	"fmt"
	"math/bits"
	"os"
)

func main() {
	reader := bufio.NewReader(os.Stdin)
	n := readInt(reader)
	k := readInt(reader)

	numPlayers := 1 << n
	a := make([]int, numPlayers)
	for i := 0; i < numPlayers; i++ {
		a[i] = readInt(reader)
	}

	counts := make([]int, 2000005)
	for i := 0; i < numPlayers; i++ {
		for j := 0; j < n; j++ {
			if (i & (1 << j)) == 0 {
				w := a[i] + a[i|(1<<j)]
				counts[w]++
			}
		}
	}

	E := 2 * k * n
	W := 2000000
	collected := 0
	for ; W >= 0; W-- {
		if collected+counts[W] >= E {
			break
		}
		collected += counts[W]
	}
	if W < 0 {
		W = 0
	}

	type Edge struct {
		u, v, w int
	}
	edges := make([]Edge, 0, E)
	for i := 0; i < numPlayers; i++ {
		for j := 0; j < n; j++ {
			if (i & (1 << j)) == 0 {
				w := a[i] + a[i|(1<<j)]
				if w > W {
					edges = append(edges, Edge{i, i | (1 << j), w})
				}
			}
		}
	}

	for i := 0; i < numPlayers; i++ {
		if len(edges) >= E {
			break
		}
		for j := 0; j < n; j++ {
			if len(edges) >= E {
				break
			}
			if (i & (1 << j)) == 0 {
				w := a[i] + a[i|(1<<j)]
				if w == W {
					edges = append(edges, Edge{i, i | (1 << j), w})
				}
			}
		}
	}

	vertexMap := make(map[int]int)
	vCnt := 0
	getVertex := func(u int) int {
		if id, exists := vertexMap[u]; exists {
			return id
		}
		vCnt++
		vertexMap[u] = vCnt
		return vCnt
	}

	type FlowEdge struct {
		to, cap, cost, rev int
	}

	maxV := 2 * len(edges)
	graph := make([][]FlowEdge, maxV+2)

	addEdge := func(u, v, cap, cost int) {
		graph[u] = append(graph[u], FlowEdge{v, cap, cost, len(graph[v])})
		graph[v] = append(graph[v], FlowEdge{u, 0, -cost, len(graph[u]) - 1})
	}

	for _, e := range edges {
		u := getVertex(e.u)
		v := getVertex(e.v)
		if bits.OnesCount(uint(e.u))%2 == 0 {
			u, v = v, u
		}
		addEdge(u, v, 1, -e.w)
	}

	S := 0
	T := vCnt + 1

	for orig_u, mapped_u := range vertexMap {
		if bits.OnesCount(uint(orig_u))%2 != 0 {
			addEdge(S, mapped_u, 1, 0)
		} else {
			addEdge(mapped_u, T, 1, 0)
		}
	}

	ans := 0
	flow := 0

	dist := make([]int, vCnt+2)
	inq := make([]bool, vCnt+2)
	parentEdge := make([]int, vCnt+2)
	parentVertex := make([]int, vCnt+2)
	q := make([]int, vCnt+5)

	INF := int(1e18)

	for flow < k {
		for i := 0; i <= vCnt+1; i++ {
			dist[i] = INF
			inq[i] = false
		}
		dist[S] = 0

		head, tail := 0, 0
		push := func(v int) {
			q[tail] = v
			tail++
			if tail == len(q) {
				tail = 0
			}
			inq[v] = true
		}
		pop := func() int {
			v := q[head]
			head++
			if head == len(q) {
				head = 0
			}
			inq[v] = false
			return v
		}

		push(S)

		for head != tail {
			u := pop()
			for i, e := range graph[u] {
				if e.cap > 0 && dist[e.to] > dist[u]+e.cost {
					dist[e.to] = dist[u] + e.cost
					parentVertex[e.to] = u
					parentEdge[e.to] = i
					if !inq[e.to] {
						push(e.to)
					}
				}
			}
		}

		if dist[T] >= 0 {
			break
		}

		ans += -dist[T]
		flow++

		curr := T
		for curr != S {
			p := parentVertex[curr]
			idx := parentEdge[curr]
			revIdx := graph[p][idx].rev

			graph[p][idx].cap -= 1
			graph[curr][revIdx].cap += 1

			curr = p
		}
	}

	fmt.Println(ans)
}

func readInt(reader *bufio.Reader) int {
	var n int
	var c byte
	for {
		c, _ = reader.ReadByte()
		if c >= '0' && c <= '9' {
			break
		}
		if c == 0 {
			return 0
		}
	}
	for {
		n = n*10 + int(c-'0')
		c, _ = reader.ReadByte()
		if c < '0' || c > '9' {
			break
		}
	}
	return n
}