#include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstring>
#include <functional>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <istream>

#include <map>
#include <math.h>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <stdint.h>

namespace asl
{
    
    template <typename T>
    std::istream &operator>>(std::istream &is, std::vector<T> &vec)
    {
        for (auto &value : vec)
            is >> value;
        return is;
    }

} 

#include <experimental/optional>

namespace asl
{
    
    template <typename T, typename C = T>
    struct MinCostFlow
    {
        struct edge
        {
            int src, dst;
            T cap, flow;
            C cost;
            int rev;
        };

        int n;
        std::vector<std::vector<edge>> adj;

        MinCostFlow(int n) : n(n), adj(n) {}

        void add_edge(int src, int dst, T cap, C cost)
        {
            adj[src].push_back({src, dst, cap, 0, cost, (int)adj[dst].size()});
            if (src == dst)
                adj[src].back().rev++;
            adj[dst].push_back({dst, src, 0, 0, -cost, (int)adj[src].size() - 1});
        }

        const C oo = std::numeric_limits<C>::max();

        std::vector<C> dist, pot;
        std::vector<edge *> prev;
        std::vector<T> curflow;

        void bellman_ford(int s)
        {
            pot.assign(n, oo);
            pot[s] = 0;

            for (int it = 0, change = true; it < n && change; ++it)
            {
                change = false;
                for (int u = 0; u < n; ++u)
                    if (pot[u] != oo)
                    {
                        for (auto &e : adj[u])
                            if (e.flow < e.cap && pot[e.dst] > pot[u] + e.cost)
                            {
                                pot[e.dst] = pot[u] + e.cost;
                                change = true;
                            }
                    }
            }
        }

        bool dijkstra(int s, int t)
        {
            dist.assign(n, oo);
            prev.assign(n, nullptr);
            dist[s] = 0;
            curflow[s] = std::numeric_limits<T>::max();

            using pci = std::pair<C, int>;
            std::priority_queue<pci, std::vector<pci>, std::greater<pci>> pq;
            pq.push({0, s});

            while (!pq.empty())
            {
                C d;
                int u;
                std::tie(d, u) = pq.top();
                pq.pop();

                if (d != dist[u])
                    continue;

                for (auto &e : adj[u])
                    if (e.flow < e.cap && dist[e.dst] > dist[u] + e.cost + pot[u] - pot[e.dst])
                    {
                        dist[e.dst] = dist[u] + e.cost + pot[u] - pot[e.dst];
                        prev[e.dst] = &e;
                        curflow[e.dst] = std::min(curflow[u], e.cap - e.flow);
                        pq.push({dist[e.dst], e.dst});
                    }
            }

            return dist[t] < oo;
        }

        std::pair<T, C> max_flow(int s, int t, bool neg_edges = true)
        {
            T flow = 0;
            C cost = 0;
            curflow.assign(n, 0);

            if (neg_edges)
                bellman_ford(s);
            else
                pot.assign(n, 0);

            while (dijkstra(s, t))
            {
                for (int u = 0; u < n; ++u)
                    if (dist[u] < oo)
                        pot[u] += dist[u];

                T delta = curflow[t];
                flow += delta;
                for (edge *e = prev[t]; e != nullptr; e = prev[e->src])
                {
                    e->flow += delta;
                    adj[e->dst][e->rev].flow -= delta;
                    cost += delta * e->cost;
                }
            }
            return {flow, cost};
        }
    };
 
    template <typename T>
    std::vector<std::vector<T>> board(int n = 0, int m = 0)
    {
        return std::vector<std::vector<T>>(n, std::vector<T>(m));
    }

} 

#include <tuple>

namespace asl
{
    typedef long long i64;
    
} 

#include <random>

#include <utility>

#define endl '\n'

using namespace asl;
using namespace std;

void solve()
{
    int n, k;
    cin >> n >> k;

    MinCostFlow<int, i64> graph(2 + 2 * n);

    auto v = board<i64>(n, n);
    cin >> v;

    int s = 2 * n, t = s + 1;

    for (int i = 0; i < n; ++i)
    {
        graph.add_edge(s, i, k, 0);
        graph.add_edge(i, t, k, 0);
        graph.add_edge(i + n, t, k, 0);

        for (int j = 0; j < n; ++j)
            graph.add_edge(i, j + n, 1, -v[i][j]);
    }

    int max_flow;
    long long min_cost;
    tie(max_flow, min_cost) = graph.max_flow(s, t);
    cout << -min_cost << endl;

    auto res = board<bool>(n, n);

    for (int i = 0; i < n; ++i)
        for (auto e : graph.adj[i])
            if (e.flow == 1 && n <= e.dst && e.dst < 2 * n)
                res[i][e.dst - n] = true;

    for (auto row : res)
    {
        for (auto u : row)
            cout << ".X"[u];
        cout << endl;
    }
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    int t = 1;

    for (int i = 1; i <= t; ++i)
    {
        solve();
    }

    return 0;
}




Measured memory_bytes: 3904