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
}