#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
#define REP(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define FOR(i, a, b) for (int i = (a), i##_len = (b); i < i##_len; i++)
#define ALL(x) (x).begin(), (x).end()  // sortなどの引数を省略したい
#ifdef _DEBUG
#define PRE_COMMAND             \
    std::cin.rdbuf(in.rdbuf()); \
    std::cout << fixed << setprecision(15);
#else
#define PRE_COMMAND cout << fixed << setprecision(15);
#endif
const double EPS = 1e-10, PI = acos(-1.0);
template <class T> auto MAX(T& seq) {
    return *max_element(seq.begin(), seq.end());
}
template <class T> auto MIN(T& seq) {
    return *min_element(seq.begin(), seq.end());
}
template <class T> auto SUM(T& seq) {
    T temp{0};
    auto& temp2 = temp[0];
    return accumulate(seq.begin(), seq.end(), temp2);
}
template <class T> void SORT(T& seq) { sort(seq.begin(), seq.end()); }
template <class T, class S> void SORT(T& seq, S& sort_order) {
    sort(seq.begin(), seq.end(), sort_order);
}
template <class T> void SORTR(vector<T>& seq) {
    sort(seq.begin(), seq.end(), greater<T>());
}
template <class T, class S, class R> long long pow(T n_0, S k_0, R mod_0) {
    long long n = n_0 % mod_0, k = k_0, mod = mod_0, now = 1;
    while (k) {
        if (k & 1) now = (now * n) % mod;
        n = (n * n) % mod;
        n >>= 1;
    }
    return now;
}
template <typename T> istream& operator>>(istream& is, vector<T>& vec) {
    for (T& x : vec) is >> x;
    return is;
}

// 頂点の数、辺の情報(始点、終点、辺容量、コスト)、indexed
template <class num_type> struct min_cost_flow {
    int n;
    num_type inf = pow(10, 15);
    vector<vector<tuple<int, num_type, num_type>>> g;
    min_cost_flow(int t1, vector<tuple<int, int, num_type, num_type>>& t2,
                  int indexed = 1) {
        int u, v;
        num_type w, c;
        n = t1;
        g.resize(n);
        for (tuple<int, int, num_type, num_type> t3 : t2) {
            tie(u, v, w, c) = t3;
            add_edge(u - indexed, v - indexed, w, c);
        }
    }
    void add_edge(int From, int to, num_type& cap, num_type& cost) {
        g[From].push_back(make_tuple(to, cap, cost));
        g[to].push_back(make_tuple(From, 0, -cost));
    }
    num_type bellman_ford(vector<vector<tuple<int, num_type, num_type>>>& g,
                          int& s, int& t, num_type& flow) {
        vector<num_type> dist(n, inf);
        vector<tuple<int, num_type>> prev(n, make_tuple(-1, 0));
        dist[s] = 0;
        int To, now = t, next;
        num_type cap, cost, m = inf;
        for (int i = 0; i < n; i++) {
            for (int From = 0; From < n; From++) {
                for (tuple<int, num_type, num_type> t1 : g[From]) {
                    tie(To, cap, cost) = t1;
                    if (cap) {
                        if (dist[To] > dist[From] + cost) {
                            dist[To] = dist[From] + cost;
                            prev[To] = make_tuple(From, cap);
                        }
                    }
                }
            }
        }
        while (now != s) {
            if (get<0>(prev[now]) == -1) {
                return -inf;
            } else {
                m = min(m, get<1>(prev[now]));
                now = get<0>(prev[now]);
            }
        }
        m = min(m, flow);
        now = t;
        while (now != s) {
            next = get<0>(prev[now]);
            int gnext = (int)g[next].size(), gnow = (int)g[now].size();
            for (int i = 0; i < gnext; i++) {
                tie(To, cap, cost) = g[next][i];
                if (To == now) {
                    get<1>(g[next][i]) -= m;
                    break;
                }
            }
            for (int i = 0; i < gnow; i++) {
                tie(To, cap, cost) = g[now][i];
                if (To == next) {
                    get<1>(g[now][i]) += m;
                    break;
                }
            }
            now = next;
        }
        flow -= m;
        return dist[t] * m;
    }
    // 最小費用流を計算する、なかったら-1を返す
    num_type calc_flow(int s, int t, num_type flow) {
        num_type ans = 0;
        while (flow) {
            num_type ret = bellman_ford(g, s, t, flow);
            if (ret == -inf) {
                return -1;
            } else {
                ans += ret;
            }
        }
        return ans;
    }
};

int main() {
    PRE_COMMAND
    int n, k;
    ll kusodeka = pow(10, 10);
    cin >> n >> k;
    vector<vector<ll>> a(n, vector<ll>(n));
    cin >> a;
    vector<tuple<int, int, ll, ll>> edges;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            edges.push_back(
                make_tuple(i + 1, j + n + 1, 1, kusodeka - a[i][j]));
        }
    }
    edges.push_back(make_tuple(0, 2 * n + 1, pow(10, 5), kusodeka));
    for (int i = 0; i < n; i++) {
        edges.push_back(make_tuple(0, i + 1, k, 0));
        edges.push_back(make_tuple(i + n + 1, 2 * n + 1, k, 0));
    }
    min_cost_flow<ll> mcf(2 * n + 2, edges, 0);
    ll f = kusodeka * n * k - mcf.calc_flow(0, 2 * n + 1, n * k);
    cout << f << endl;
    vector<vector<char>> ans(n, vector<char>(n, '.'));
    for (int i = 1; i < n + 1; i++) {
        for (tuple<int, ll, ll> temp : mcf.g[i]) {
            int j;
            ll cap, cost;
            tie(j, cap, cost) = temp;
            if (cap == 0) ans[i - 1][j - n - 1] = 'X';
        }
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) { cout << ans[i][j]; }
        cout << endl;
    }
}

Measured memory_bytes: 3884