#include <bits/stdc++.h>
#define for_range(i, a, b) for (int i = (a); i < (b); i++)
#define for_range_rev(i, a, b) for (int i = (b)-1; i >= (a); i++)
using namespace std;
using i64 = int_fast64_t;
using u64 = uint_fast64_t;
using u32 = uint_fast32_t;
const u64 MOD = 1'000'000'007;
// const u64 MOD = 998'244'353;
const int DX4[] = {1, 0, -1, 0};
const int DY4[] = {0, 1, 0, -1};
const int DX8[] = {0, 1, 1, 1, 0, -1, -1, -1};
const int DY8[] = {1, 1, 0, -1, -1, -1, 0, 1};

int ceil_log2(int n) {
    int x = 0;
    while ((1u << x) < (u32)(n)) x++;
    return x;
}

struct mincostflow {
    using C = i64;  // capacity
    using W = i64;  // cost

    struct edge {
        int from, to;
        C cap, flow;
        W cost;
    };
    struct CW {
        C cap;
        W cost;
    };
    struct E {
        int t, r;
        C c;
        W w;
    };

    int n;
    vector<pair<int, int>> p;
    vector<vector<E>> g;

    mincostflow() {}
    mincostflow(int sz) : n(sz), g(sz) {}

    int add_edge(int u, int v, C c, W w) {
        assert(0 <= u && u < n);
        assert(0 <= v && v < n);
        assert(0 <= c);
        assert(0 <= w);
        int m = p.size();
        p.push_back({u, int(g[u].size())});
        g[u].push_back(E{v, int(g[v].size()), c, w});
        g[v].push_back(E{u, int(g[u].size()) - 1, 0, -w});
        return m;
    }

    edge get_edge(int i) {
        int m = p.size();
        assert(0 <= i && i < m);
        auto e = g[p[i].first][p[i].second];
        auto re = g[e.t][e.r];
        return edge{p[i].first, e.t, e.c + re.c, re.c, e.w};
    }

    vector<edge> edges() {
        int m = p.size();
        vector<edge> r(m);
        for_range(i, 0, m) r[i] = get_edge(i);
        return r;
    }

    CW flow(int s, int t) { return flow(s, t, numeric_limits<C>::max()); }
    CW flow(int s, int t, C lim) { return slope(s, t, lim).back(); }
    vector<CW> slope(int s, int t) {
        return slope(s, t, numeric_limits<C>::max());
    }
    vector<CW> slope(int s, int t, C lim) {
        assert(0 <= s && s < n);
        assert(0 <= t && t < n);
        assert(s != t);
        vector<C> u(n, 0), d(n);
        vector<int> p(n), y(n);
        vector<bool> v(n);
        auto f = [&]() {
            fill(d.begin(), d.end(), numeric_limits<C>::max());
            fill(p.begin(), p.end(), -1);
            fill(y.begin(), y.end(), -1);
            fill(v.begin(), v.end(), false);
            struct Q {
                C k;
                int t;
                bool operator<(Q r) const { return k > r.k; }
            };
            priority_queue<Q> q;
            d[s] = 0;
            q.push(Q{0, s});
            while (!q.empty()) {
                int x = q.top().t;
                q.pop();
                if (v[x]) continue;
                v[x] = true;
                if (x == t) break;
                for_range(i, 0, g[x].size()) {
                    auto e = g[x][i];
                    if (v[e.t] || !e.c) continue;
                    W w = e.w - u[e.t] + u[x];
                    if (d[e.t] - d[x] > w) {
                        d[e.t] = d[x] + w;
                        p[e.t] = x;
                        y[e.t] = i;
                        q.push(Q{d[e.t], e.t});
                    }
                }
            }
            if (!v[t]) return false;
            for_range(x, 0, n) {
                if (!v[x]) continue;
                u[x] -= d[t] - d[x];
            }
            return true;
        };
        C l = 0;
        W w = 0, z = -1;
        vector<CW> r;
        r.push_back(CW{l, w});
        while (l < lim) {
            if (!f()) break;
            C c = lim - l;
            for (int x = t; x != s; x = p[x]) c = min(c, g[p[x]][y[x]].c);
            for (int x = t; x != s; x = p[x]) {
                auto& e = g[p[x]][y[x]];
                e.c -= c;
                g[x][e.r].c += c;
            }
            W g = -u[s];
            l += c;
            w += c * g;
            if (z == g) r.pop_back();
            r.push_back(CW{l, w});
            z = w;
        }
        return r;
    }
};

const i64 AM = 1'000'000'000;

int main() {
    int n, k;
    cin >> n >> k;
    vector<vector<i64>> a(n, vector<i64>(n));
    for (auto& row : a)
        for (auto& x : row) cin >> x;

    mincostflow g(2 * n + 2);
    int s = 2 * n, t = 2 * n + 1;

    for_range(i, 0, n) {
        g.add_edge(s, i, k, 0);      // s -> row
        g.add_edge(n + i, t, k, 0);  // col -> t
        g.add_edge(i, t, k, AM);
        for_range(j, 0, n) g.add_edge(i, n + j, 1, AM - a[i][j]);
    }

    auto flow = g.flow(s, t);
    cout << AM * n * k - flow.cost << '\n';
    vector<mincostflow::edge> edges = g.edges();

    vector<string> S(n, string(n, '.'));
    for (auto e : edges) {
        if (e.from == s || e.to == t || e.flow == 0) continue;
        S[e.from][e.to - n] = 'X';
    }
    for (auto row : S) cout << row << '\n';
}

Measured memory_bytes: 3976