Problem:
Score : 100 points

Problem Statement

You are given a grid of N rows and M columns. The square at the i-th row and j-th column will be denoted as (i,j).
A nonnegative integer A_{i,j} is written for each square (i,j).

You choose some of the squares so that each row and column contains at most K chosen squares.
Under this constraint, calculate the maximum value of the sum of the integers written on the chosen squares.
Additionally, calculate a way to choose squares that acheives the maximum.

Constraints

1 \leq N \leq 50

1 \leq K \leq N

0 \leq A_{i,j} \leq 10^9

All values in Input are integer.

Input

Input is given from Standard Input in the following format:

N K
A_{1,1} A_{1,2} \cdots A_{1,N}
A_{2,1} A_{2,2} \cdots A_{2,N}
\vdots
A_{N,1} A_{N,2} \cdots A_{N,N}

Output

On the first line, print the maximum value of the sum of the integers written on the chosen squares.

On the next N lines, print a way that achieves the maximum.

Precisely, output the strings t_1,t_2,\cdots,t_N, that satisfies t_{i,j}=X if you choose (i,j) and t_{i,j}=. otherwise.

You may print any way to choose squares that maximizes the sum.

Sample Input 1

3 1
5 3 2
1 4 8
7 6 9

Sample Output 1

19
X..
..X
.X.

Sample Input 2

3 2
10 10 1
10 10 1
1 1 10

Sample Output 2

50
XX.
XX.
..X

Solution in C# (.NET Core 3.1.201) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using static System.Math;
using System.Text;
using System.Threading;
using System.Globalization;
using System.Runtime.CompilerServices;
using Library;

namespace Program
{
    public static class ProblemA
    {
        static bool SAIKI = false;
        static public int numberOfRandomCases = 0;
        static public void MakeTestCase(List<string> _input, List<string> _output, ref Func<string[], bool> _outputChecker)
        {
        }
        static public void Solve()
        {
            var N = NN;
            var K = NN;
            var flow = new LIB_MinCostFlow(N * 2 + 2);
            var s = N * 2;
            var g = s + 1;
            flow.AddEdge(s, g, K * N, 1000000000);
            for (var i = 0; i < N; i++)
            {
                flow.AddEdge(s, i, K, 0);
                flow.AddEdge(i + N, g, K, 0);
                for (var j = 0; j < N; j++)
                {
                    flow.AddEdge(i, j + N, 1, 1000000000 - NN);
                }
            }
            Console.WriteLine(N * K * 1000000000 - flow.Flow(s, g, K * N).cost);
            var ans = new bool[N, N];
            foreach (var item in flow.GetAllEdge())
            {
                if (item.from < N && item.flow == 1) ans[item.from, item.to - N] = true;
            }
            for (var i = 0; i < N; i++)
            {
                for (var j = 0; j < N; j++)
                {
                    if (ans[i, j]) Console.Write("X");
                    else Console.Write(".");
                }
                Console.WriteLine();
            }
        }
        class Printer : StreamWriter
        {
            public override IFormatProvider FormatProvider { get { return CultureInfo.InvariantCulture; } }
            public Printer(Stream stream) : base(stream, new UTF8Encoding(false, true)) { base.AutoFlush = false; }
            public Printer(Stream stream, Encoding encoding) : base(stream, encoding) { base.AutoFlush = false; }
        }
        static LIB_FastIO fastio = new LIB_FastIODebug();
        static public void Main(string[] args) { if (args.Length == 0) { fastio = new LIB_FastIO(); Console.SetOut(new Printer(Console.OpenStandardOutput())); } if (SAIKI) { var t = new Thread(Solve, 134217728); t.Start(); t.Join(); } else Solve(); Console.Out.Flush(); }
        static long NN => fastio.Long();
        static double ND => fastio.Double();
        static string NS => fastio.Scan();
        static long[] NNList(long N) => Repeat(0, N).Select(_ => NN).ToArray();
        static double[] NDList(long N) => Repeat(0, N).Select(_ => ND).ToArray();
        static string[] NSList(long N) => Repeat(0, N).Select(_ => NS).ToArray();
        static long Count<T>(this IEnumerable<T> x, Func<T, bool> pred) => Enumerable.Count(x, pred);
        static IEnumerable<T> Repeat<T>(T v, long n) => Enumerable.Repeat<T>(v, (int)n);
        static IEnumerable<int> Range(long s, long c) => Enumerable.Range((int)s, (int)c);
        static IOrderedEnumerable<T> OrderByRand<T>(this IEnumerable<T> x) => Enumerable.OrderBy(x, _ => xorshift);
        static IOrderedEnumerable<T> OrderBy<T>(this IEnumerable<T> x) => Enumerable.OrderBy(x.OrderByRand(), e => e);
        static IOrderedEnumerable<T1> OrderBy<T1, T2>(this IEnumerable<T1> x, Func<T1, T2> selector) => Enumerable.OrderBy(x.OrderByRand(), selector);
        static IOrderedEnumerable<T> OrderByDescending<T>(this IEnumerable<T> x) => Enumerable.OrderByDescending(x.OrderByRand(), e => e);
        static IOrderedEnumerable<T1> OrderByDescending<T1, T2>(this IEnumerable<T1> x, Func<T1, T2> selector) => Enumerable.OrderByDescending(x.OrderByRand(), selector);
        static IOrderedEnumerable<string> OrderBy(this IEnumerable<string> x) => x.OrderByRand().OrderBy(e => e, StringComparer.OrdinalIgnoreCase);
        static IOrderedEnumerable<T> OrderBy<T>(this IEnumerable<T> x, Func<T, string> selector) => x.OrderByRand().OrderBy(selector, StringComparer.OrdinalIgnoreCase);
        static IOrderedEnumerable<string> OrderByDescending(this IEnumerable<string> x) => x.OrderByRand().OrderByDescending(e => e, StringComparer.OrdinalIgnoreCase);
        static IOrderedEnumerable<T> OrderByDescending<T>(this IEnumerable<T> x, Func<T, string> selector) => x.OrderByRand().OrderByDescending(selector, StringComparer.OrdinalIgnoreCase);
        static string Join<T>(this IEnumerable<T> x, string separator = "") => string.Join(separator, x);
        static uint xorshift { get { _xsi.MoveNext(); return _xsi.Current; } }
        static IEnumerator<uint> _xsi = _xsc();
        static IEnumerator<uint> _xsc() { uint x = 123456789, y = 362436069, z = 521288629, w = (uint)(DateTime.Now.Ticks & 0xffffffff); while (true) { var t = x ^ (x << 11); x = y; y = z; z = w; w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)); yield return w; } }
    }
}
namespace Library {
    class LIB_PriorityQueue<T>
    {
        List<T> heap;
        Comparison<T> comp;
        public T Peek => heap[0];
        public long Count => heap.Count;
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public LIB_PriorityQueue(long cap, Comparison<T> cmp, bool asc = true)
        {
            heap = new List<T>((int)cap);
            comp = asc ? cmp : (x, y) => cmp(y, x);
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public LIB_PriorityQueue(Comparison<T> cmp, bool asc = true)
        {
            heap = new List<T>();
            comp = asc ? cmp : (x, y) => cmp(y, x);
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public LIB_PriorityQueue(long cap, bool asc = true) : this(cap, Comparer<T>.Default.Compare, asc) { }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public LIB_PriorityQueue(bool asc = true) : this(Comparer<T>.Default.Compare, asc) { }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void Push(T val)
        {
            var i = heap.Count;
            heap.Add(val);
            while (i > 0)
            {
                var ni = (i - 1) / 2;
                if (comp(val, heap[ni]) >= 0) break;
                heap[i] = heap[ni];
                i = ni;
            }
            heap[i] = val;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public T Pop()
        {
            var ret = heap[0];
            var val = heap[heap.Count - 1];
            heap.RemoveAt(heap.Count - 1);
            if (heap.Count == 0) return ret;
            var i = 0; while ((i << 1) + 1 < heap.Count)
            {
                var i1 = (i << 1) + 1;
                var i2 = (i << 1) + 2;
                if (i2 < heap.Count && comp(heap[i1], heap[i2]) > 0) i1 = i2;
                if (comp(val, heap[i1]) <= 0) break;
                heap[i] = heap[i1]; i = i1;
            }
            heap[i] = val;
            return ret;
        }
    }
    class LIB_PriorityQueue<TK, TV>
    {
        LIB_PriorityQueue<KeyValuePair<TK, TV>> q;
        public KeyValuePair<TK, TV> Peek => q.Peek;
        public long Count => q.Count;
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public LIB_PriorityQueue(long cap, Comparison<TK> cmp, bool asc = true)
        {
            q = new LIB_PriorityQueue<KeyValuePair<TK, TV>>(cap, (x, y) => cmp(x.Key, y.Key), asc);
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public LIB_PriorityQueue(Comparison<TK> cmp, bool asc = true)
        {
            q = new LIB_PriorityQueue<KeyValuePair<TK, TV>>((x, y) => cmp(x.Key, y.Key), asc);
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public LIB_PriorityQueue(long cap, bool asc = true) : this(cap, Comparer<TK>.Default.Compare, asc) { }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public LIB_PriorityQueue(bool asc = true) : this(Comparer<TK>.Default.Compare, asc) { }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void Push(TK k, TV v) => q.Push(new KeyValuePair<TK, TV>(k, v));
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public KeyValuePair<TK, TV> Pop() => q.Pop();
    }
    class LIB_FastIO
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public LIB_FastIO() { str = Console.OpenStandardInput(); }
        readonly Stream str;
        readonly byte[] buf = new byte[1024];
        int len, ptr;
        public bool isEof = false;
        public bool IsEndOfStream
        {
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            get { return isEof; }
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        byte read()
        {
            if (isEof) throw new EndOfStreamException();
            if (ptr >= len)
            {
                ptr = 0;
                if ((len = str.Read(buf, 0, 1024)) <= 0)
                {
                    isEof = true;
                    return 0;
                }
            }
            return buf[ptr++];
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        char Char()
        {
            byte b = 0;
            do b = read();
            while (b < 33 || 126 < b);
            return (char)b;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        virtual public string Scan()
        {
            var sb = new StringBuilder();
            for (var b = Char(); b >= 33 && b <= 126; b = (char)read())
                sb.Append(b);
            return sb.ToString();
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        virtual public long Long()
        {
            long ret = 0; byte b = 0; var ng = false;
            do b = read();
            while (b != '-' && (b < '0' || '9' < b));
            if (b == '-') { ng = true; b = read(); }
            for (; true; b = read())
            {
                if (b < '0' || '9' < b)
                    return ng ? -ret : ret;
                else ret = ret * 10 + b - '0';
            }
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        virtual public double Double() { return double.Parse(Scan(), CultureInfo.InvariantCulture); }
    }
    class LIB_FastIODebug : LIB_FastIO
    {
        Queue<string> param = new Queue<string>();
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        string NextString() { if (param.Count == 0) foreach (var item in Console.ReadLine().Split(' ')) param.Enqueue(item); return param.Dequeue(); }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public LIB_FastIODebug() { }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public override string Scan() => NextString();
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public override long Long() => long.Parse(NextString());
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public override double Double() => double.Parse(NextString());
    }
    class LIB_MinCostFlow
    {
        public struct Edge
        {
            public int from;
            public int to;
            public long cap;
            public long flow;
            public long cost;
        }
        public struct CapCost
        {
            public long cap;
            public long cost;
        }
        const int SHIFT_SIZE = 30;
        const int MASK = 1073741823;
        List<ulong> pos;
        List<int>[] gTo;
        List<int>[] gRev;
        List<long>[] gCap;
        List<long>[] gCost;
        int N;
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public LIB_MinCostFlow(long n)
        {
            N = (int)n;
            pos = new List<ulong>();
            gTo = new List<int>[n];
            gRev = new List<int>[n];
            gCap = new List<long>[n];
            gCost = new List<long>[n];
            for (var i = 0; i < n; i++)
            {
                gTo[i] = new List<int>();
                gRev[i] = new List<int>();
                gCap[i] = new List<long>();
                gCost[i] = new List<long>();
            }
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void AddEdge(long from, long to, long cap, long cost)
        {
            pos.Add(((ulong)from << SHIFT_SIZE) | (uint)gTo[from].Count);
            gTo[from].Add((int)to);
            gRev[from].Add(gRev[to].Count);
            gCap[from].Add(cap);
            gCost[from].Add(cost);
            gTo[to].Add((int)from);
            gRev[to].Add(gRev[from].Count - 1);
            gCap[to].Add(0);
            gCost[to].Add(-cost);
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public Edge GetEdge(long i)
        {
            var idx = (int)i;
            var idxf = pos[idx] >> SHIFT_SIZE;
            var idxt = (int)(pos[idx] & MASK);
            var eTo = gTo[idxf][idxt];
            var eRev = gRev[idxf][idxt];
            var reCap = gCap[eTo][eRev];
            return new Edge { from = (int)(pos[idx] >> SHIFT_SIZE), to = eTo, cap = gCap[idxf][idxt] + reCap, flow = reCap, cost = gCost[idxf][idxt] };
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public Edge[] GetAllEdge()
        {
            var res = new Edge[pos.Count];
            for (var i = 0; i < res.Length; i++) res[i] = GetEdge(i);
            return res;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public CapCost Flow(long s, long t) => Flow(s, t, long.MaxValue >> 2);
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public CapCost Flow(long s, long t, long flowLimit) => Slope(s, t, flowLimit).Last();
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public List<CapCost> Slope(long s, long t) => Slope(s, t, long.MaxValue >> 2);
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public List<CapCost> Slope(long s, long t, long flowLimit)
        {
            var dual = new long[N];
            var dist = new long[N];
            var pv = new int[N];
            var pe = new int[N];
            var flow = 0L;
            var cost = 0L;
            var prevCost = -1L;
            var result = new List<CapCost>();
            result.Add(new CapCost { cap = flow, cost = cost });
            while (flow < flowLimit)
            {
                for (var i = 0; i < dist.Length; ++i) dist[i] = long.MaxValue >> 2;
                for (var i = 0; i < pv.Length; ++i) pv[i] = -1;
                for (var i = 0; i < pe.Length; ++i) pe[i] = -1;
                var vis = new bool[N];
                var que = new LIB_PriorityQueue<long, int>();
                dist[s] = 0;
                que.Push(0, (int)s);
                while (que.Count > 0)
                {
                    var v = que.Pop().Value;
                    if (vis[v]) continue;
                    vis[v] = true;
                    if (v == t) break;
                    var gToV = gTo[v];
                    var gCapV = gCap[v];
                    var gCostV = gCost[v];
                    var dualv = dual[v];
                    var distv = dist[v];
                    for (var i = 0; i < gToV.Count; ++i)
                    {
                        var eTo = gToV[i];
                        if (vis[eTo] || gCapV[i] == 0) continue;
                        var thisCost = gCostV[i] - dual[eTo] + dualv;
                        if (dist[eTo] - distv > thisCost)
                        {
                            dist[eTo] = distv + thisCost;
                            pv[eTo] = v;
                            pe[eTo] = i;
                            que.Push(dist[eTo], eTo);
                        }
                    }
                }
                if (!vis[t]) break;
                for (var v = 0; v < dist.Length; ++v)
                {
                    if (!vis[v]) continue;
                    dual[v] -= dist[t] - dist[v];
                }
                var c = flowLimit - flow;
                for (var v = t; v != s; v = pv[v]) c = Math.Min(c, gCap[pv[v]][pe[v]]);
                for (var v = t; v != s; v = pv[v])
                {
                    gCap[pv[v]][pe[v]] -= c;
                    gCap[v][gRev[pv[v]][pe[v]]] += c;
                }
                var d = -dual[s];
                flow += c;
                cost += c * d;
                if (prevCost == d) result.RemoveAt(result.Count - 1);
                result.Add(new CapCost { cap = flow, cost = cost });
                prevCost = cost;
            }
            return result;
        }
    }
}