import java.io.BufferedReader
import java.io.InputStreamReader
import java.io.PrintWriter

val br = BufferedReader(InputStreamReader(System.`in`))
val out = PrintWriter(System.out)

fun main() {
    br.use { out.use {
        solve()
        out.flush()
    } }
}

// refered: https://atcoder.jp/contests/practice2/submissions/16654383
fun solve() {
    val (n, k) = readIntegerList()
    val a = Array(n) { readLongList() }
    val mcf = MinCostFlow(n * n + 2 * n + 2);
    val s = n * n + 2 * n;
    val t = s + 1;
    val r = n * n;
    val c = n * n + n;
    for (i in 0 until n) {
        mcf.addEdge(s, r + i, k.toLong(), 0);
        mcf.addEdge(c + i, t, k.toLong(), 0);
    }
    val INF = 1L shl 50;
    for (i in 0 until n) {
        for (j in 0 until n) {
            mcf.addEdge(r + i, i * n + j, 1, INF - a[i][j]);
            mcf.addEdge(i * n + j, c + j, 1, 0);
        }
    }
    var maxf = 0L;
    var max = 0L;
    val slope = mcf.minCostSlope(s, t);
    for (e in slope) {
        val flow = e[0];
        val cost = e[1];
        val x = flow * INF - cost;
        if (x > max) {
            max = x;
            maxf = flow;
        }
    }
    mcf.clearFlow();
    mcf.minCostFlow(s, t, maxf);
    out.println(max);
    val g = Array(n) { CharArray(n) { '.' } }
    for (e in mcf.edges) {
        val u = e.from;
        val v = e.to;
        if (u == s || v == t || e.flow == 0L) continue;
        var i: Int
        var j: Int
        if (u < n * n) {
            i = u / n;
            j = u % n;
        } else {
            i = v / n;
            j = v % n;
        }
        g[i][j] = 'X';
    }
    for (gi in g) out.println(gi);
}

/**
 * https://github.com/da-louis/ac-library-kt/blob/master/src/main/kotlin/jp/atcoder/library/kotlin/minCostFlow/MinCostFlow.kt
 * 提出時の変更点
 * edgedプロパティからprivateを削除
 * WeightedCapEdgeにプロパティflowを生やした
 * StateのcompareToを書き換え
 * run {} を削除
 * clearFlowを修正
 *
 * convert from [AtCoderLibraryForJava - MinCostFlow](https://github.com/NASU41/AtCoderLibraryForJava/blob/24160d880a5fc6d1caf9b95baa875e47fb568ef3/MinCostFlow/MinCostFlow.java)
 */
class MinCostFlow(private val n: Int) {
    inner class WeightedCapEdge internal constructor(
        val from: Int,
        val to: Int,
        var cap: Long,
        var cost: Long,
        val rev: Int
    ) {
        val flow: Long
            get() = g[to][rev]!!.cap
    }

    private var m = 0
    val edges: ArrayList<WeightedCapEdge> = ArrayList()
    private val count: IntArray = IntArray(n)
    private val g: Array<Array<WeightedCapEdge?>> = Array(n) { emptyArray<WeightedCapEdge?>() }
    private val potential: LongArray = LongArray(n)
    private val dist: LongArray = LongArray(n)
    private val prev: Array<WeightedCapEdge?> = arrayOfNulls(n)

    fun addEdge(from: Int, to: Int, cap: Long, cost: Long): Int {
        rangeCheck(from, 0, n)
        rangeCheck(to, 0, n)
        nonNegativeCheck(cap, "Capacity")
        nonNegativeCheck(cost, "Cost")
        val e = WeightedCapEdge(from, to, cap, cost, count[to])
        count[from]++
        count[to]++
        edges.add(e)
        return m++
    }

    private fun buildGraph() {
        for (i in 0 until n) {
            g[i] = arrayOfNulls(count[i])
        }
        val idx = IntArray(n)
        for (e in edges) {
            g[e.to][idx[e.to]++] = WeightedCapEdge(e.to, e.from, 0, -e.cost, idx[e.from])
            g[e.from][idx[e.from]++] = e
        }
    }

    private var addFlow: Long = 0
    private var addCost: Long = 0
    fun minCostMaxFlow(s: Int, t: Int): LongArray {
        return minCostFlow(s, t, INF)
    }

    fun minCostFlow(s: Int, t: Int, flowLimit: Long): LongArray {
        rangeCheck(s, 0, n)
        rangeCheck(t, 0, n)
        require(s != t) { String.format("s = t = %d", s) }
        nonNegativeCheck(flowLimit, "Flow")
        buildGraph()
        var flow: Long = 0
        var cost: Long = 0
        while (true) {
            dijkstra(s, t, flowLimit - flow)
            if (addFlow == 0L) break
            flow += addFlow
            cost += addFlow * addCost
        }
        return longArrayOf(flow, cost)
    }

    @JvmOverloads
    fun minCostSlope(s: Int, t: Int, flowLimit: Long = INF): ArrayList<LongArray> {
        rangeCheck(s, 0, n)
        rangeCheck(t, 0, n)
        require(s != t) { String.format("s = t = %d", s) }
        nonNegativeCheck(flowLimit, "Flow")
        buildGraph()
        val slope = ArrayList<LongArray>()
        var prevCost: Long = -1
        var flow: Long = 0
        var cost: Long = 0
        while (true) {
            slope.add(longArrayOf(flow, cost))
            dijkstra(s, t, flowLimit - flow)
            if (addFlow == 0L) return slope
            flow += addFlow
            cost += addFlow * addCost
            if (addCost == prevCost) {
                slope.removeAt(slope.size - 1)
            }
            prevCost = addCost
        }
    }

    private fun dijkstra(s: Int, t: Int, maxFlow: Long) {
        class State(val v: Int, val d: Long) : Comparable<State> {
            override operator fun compareTo(other: State): Int {
                return when {
                    d == other.d -> v - other.v
                    d > other.d -> 1
                    else -> -1
                }
            }
        }
        java.util.Arrays.fill(dist, INF)
        dist[s] = 0
        val pq = java.util.PriorityQueue<State>()
        pq.add(State(s, 0L))
        while (pq.size > 0) {
            val st = pq.poll()
            val u = st.v
            if (st.d != dist[u]) continue
            for (e in g[u]) {
                if (e!!.cap <= 0) continue
                val v = e.to
                val nextCost = dist[u] + e.cost + potential[u] - potential[v]
                if (nextCost < dist[v]) {
                    dist[v] = nextCost
                    prev[v] = e
                    pq.add(State(v, dist[v]))
                }
            }
        }
        if (dist[t] == INF) {
            addFlow = 0
            addCost = INF
            return
        }
        for (i in 0 until n) {
            potential[i] += dist[i]
        }
        addCost = 0
        addFlow = maxFlow

        var v2 = t
        while (v2 != s) {
            val e = prev[v2]
            addCost += e!!.cost
            addFlow = Math.min(addFlow, e.cap)
            v2 = e.from
        }

        var v = t
        while (v != s) {
            val e = prev[v]
            e!!.cap -= addFlow
            g[v][e!!.rev]!!.cap += addFlow
            v = e!!.from
        }
    }

    fun clearFlow() {
        java.util.Arrays.fill(potential, 0)
        for (e in edges) {
            val flow = e.flow
            e.cap += flow
            g[e.to][e.rev]!!.cap -= flow
        }
    }

    fun getEdge(i: Int): WeightedCapEdge {
        rangeCheck(i, 0, m)
        return edges[i]
    }

    private fun rangeCheck(i: Int, minInclusive: Int, maxExclusive: Int) {
        if (i < minInclusive || i >= maxExclusive) {
            throw IndexOutOfBoundsException(String.format("Index %d out of bounds for length %d", i, maxExclusive))
        }
    }

    private fun nonNegativeCheck(cap: Long, attribute: String) {
        require(cap >= 0) { String.format("%s %d is negative.", attribute, cap) }
    }

    companion object {
        private const val INF = Long.MAX_VALUE
    }
}

fun readInteger() = Integer.parseInt(br.readLine())
fun readLong() = java.lang.Long.parseLong(br.readLine())
fun readStringList() = br.readLine()!!.split(' ')
fun readIntegerList() = readStringList().map(Integer::parseInt)
fun readLongList() = readStringList().map(java.lang.Long::parseLong)
fun readDoubleList() = readStringList().map(java.lang.Double::parseDouble)
