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.Linq;
using System.IO;
using System.Text;
using System.Numerics;
using System.Threading;
using System.Runtime.CompilerServices;
using System.Diagnostics;
using static System.Math;
using static System.Array;
using static AtCoder.Cout;
using static AtCoder.Tool;
using static AtCoder.ModInt;
namespace AtCoder
{
    class AC
    {
        //const int MOD = 1000000007;
        const int MOD = 998244353;
        const int INF = int.MaxValue / 2;
        const long SINF = long.MaxValue / 3;
        static readonly int[] dI = { 0, 1, 0, -1, 1, -1, -1, 1 };
        static readonly int[] dJ = { 1, 0, -1, 0, 1, 1, -1, -1 };
        static void Main(string[] args)
        {
            var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false }; Console.SetOut(sw);

            /*var th = new Thread(Run, 1 << 26);
            th.Start();
            th.Join();*/

            Run();
            Console.Out.Flush();
        }
        static void Run()
        {
            int Testcase = 1;
            //Testcase = Cin.Int;
            for (var _ = 0; _ < Testcase; _++) Solve();
        }
        static void Solve()
        {
            Cin.Scanf(out int N, out int K);
            var A = new long[N][];
            for (var i = 0; i < N; i++) A[i] = Cin.ReadSplitLong;
            int s = N << 1, t = s | 1;
            const long inf = (long)1e14;
            var mcf = new MinCostFlow(t + 1);
            for(var i = 0; i < N; i++)
            {
                mcf.Add_Edge(s, i, K, 0);
                for(var j = 0; j < N; j++)
                {
                    mcf.Add_Edge(i, N + j, 1, inf - A[i][j]);
                }
                mcf.Add_Edge(N + i, t, K, 0);
            }
            mcf.Add_Edge(s, t, N * K, inf);
            var _ = mcf.MinCost(s, t, N * K);
            long score = 0;
            var gr = mcf.GetEdges();
            var ans = new char[N][];
            for(var i = 0; i < N; i++)
            {
                ans[i] = new char[N];
                Fill(ans[i], '.');
            }
            for(var i = 0; i < N; i++)
            {
                for(var j = 0; j < gr[i].Count(); j++)
                {
                    var ed = gr[i][j];
                    if (ed._isrev) continue;
                    if (ed._cap == 0)
                    {
                        score += A[i][ed._to - N];
                        ans[i][ed._to - N] = 'X';
                    }
                }
            }
            OutL(score);
            for (var i = 0; i < N; i++) Out_Sep(ans[i], "");
        }
    }
    public class MinCostFlow
    {
        const long inf = long.MaxValue / 3;
        int n;
        public class Edge
        {
            public int _to, _cap, _rev;
            public long _cost;
            public bool _isrev;
            public Edge(int to, int cap, long cost, int rev, bool isrev)
            {
                _to = to;_cap = cap;_rev = rev;_cost = cost;_isrev = isrev;
            }
        }
        List<List<Edge>> G;
        public MinCostFlow(int size)
        {
            n = size;
            G = new List<List<Edge>>();
            for (var i = 0; i < n; i++) G.Add(new List<Edge>());
        }

        /*辺の追加*/
        public void Add_Edge(int s, int t, int cap, long cost)
        {
            G[s].Add(new Edge(t, cap, cost, G[t].Count(), false));
            G[t].Add(new Edge(s, 0, -cost, G[s].Count() - 1, true));
        }
        public long MinCost(int s, int t, int f)
        {
            long ret = 0;
            var h = new long[n];
            var dist = new long[n];
            var pre_v = new int[n];
            var pre_e = new int[n];
            var V = new Priority_Queue<(long, int)>((x, y) => Sig(x.Item1 - y.Item1));
            while (f > 0)
            {
                for(var i = 0; i < n; i++) { dist[i] = inf;pre_v[i] = pre_e[i] = -1; }
                dist[s] = 0;
                V.Enqueue((0, s));
                while (V.Any())
                {
                    var (cd, v) = V.Dequeue();
                    if (dist[v] < cd) continue;
                    for (var i = 0; i < G[v].Count(); i++)
                    {
                        var ed = G[v][i];
                        if (ed._cap <= 0) continue;
                        if (dist[ed._to] + h[ed._to] > cd + h[v] + ed._cost)
                        {
                            dist[ed._to] = cd + ed._cost + h[v] - h[ed._to];
                            pre_v[ed._to] = v;
                            pre_e[ed._to] = i;
                            V.Enqueue((dist[ed._to], ed._to));
                        }
                    }
                }
                if (dist[t] == inf) { return -inf; }
                for (var i = 0; i < n; i++) h[i] += dist[i];
                var nowflow = f;
                for(var now = t; now != s; now = pre_v[now])
                {
                    nowflow = Min(nowflow, G[pre_v[now]][pre_e[now]]._cap);
                }
                f -= nowflow;
                ret += nowflow * h[t];
                for(var now = t; now != s; now = pre_v[now])
                {
                    var rv = G[pre_v[now]][pre_e[now]]._rev;
                    G[pre_v[now]][pre_e[now]]._cap -= nowflow;
                    G[now][rv]._cap += nowflow;
                }
            }
            return ret;
        }
        public List<List<Edge>> GetEdges() => G;
    }
    public class Dinic
    {
        readonly int n;
        const int inf = int.MaxValue / 2;
        public class Edge
        {
            public int _to { get; set; }
            public int _cap { get; set; }
            public int _rev { get; set; }
            public Edge(int to,int cap,int rev) { _to = to;_cap = cap;_rev = rev; }
        }
        List<List<Edge>> G;
        int[] level, itr;
        public Dinic(int vertice)
        {
            n = vertice;
            level = new int[n];
            itr = new int[n];
            G = new List<List<Edge>>();
            for (var _ = 0; _ < n; _++) G.Add(new List<Edge>());
        }
        /*================ ^ _ ^ ==================*/
        //辺の追加（from->to,容量cap）
        public void Add_Edge(int from, int to, int cap)
        {
            G[from].Add(new Edge(to, cap, G[to].Count()));
            G[to].Add(new Edge(from, 0, G[from].Count() - 1));
        }
        //bfsパート（levelの設定）
        void Bfs(int s)
        {
            //Fillはバージョン古いと使えないため...
            for (var i = 0; i < n; i++) level[i] = -1;
            level[s] = 0;
            var Q = new Queue<int>();
            Q.Enqueue(s);
            while (Q.Any())
            {
                int v = Q.Dequeue();
                foreach(var ed in G[v])
                {
                    if (ed._cap > 0 && level[ed._to] == -1)
                    {
                        level[ed._to] = level[v] + 1;
                        Q.Enqueue(ed._to);
                    }
                }
            }
        }
        //dfsパート（増加パスの探索）
        int Dfs(int v, int t, int f)
        {
            if (v == t) return f;
            for(var i = itr[v]; i < G[v].Count(); i++)
            {
                itr[v] = i;
                var ed = G[v][i];
                if (ed._cap > 0 && level[v] < level[ed._to])
                {
                    var d = Dfs(ed._to, t, Min(f, ed._cap));
                    if (d > 0)
                    {
                        ed._cap -= d;
                        G[ed._to][ed._rev]._cap += d;
                        return d;
                    }
                }
            }
            return 0;
        }
        //s->tの最大流を返す
        //一般:O(N^2M)
        //二部グラフマッチング:O(M*Sqrt(N))
        //辺の容量が全て同じ:O(min(n^{2/3},m^{1/2})*m)
        //になるらしい
        public int Max_Flow(int s, int t)
        {
            var ret = 0;
            for(; ; )
            {
                Bfs(s);
                if (level[t] == -1) return ret;
                for (var i = 0; i < n; i++) itr[i] = 0;
                var flow = 0;
                do { ret += flow;flow = Dfs(s, t, inf); }
                while (flow > 0);
            }
        }
        //グラフの状況を返す
        public List<List<Edge>> GetGraph() => G;
    }
    struct ModInt
    {
        public long value;
        //const int MOD = 1000000007;
        const int MOD = 998244353;
        public ModInt(long value) { this.value = value; }
        public static implicit operator ModInt(long a)
        {
            var ret = a % MOD;
            return new ModInt(ret < 0 ? (ret + MOD) : ret);
        }
        public static ModInt operator +(ModInt a, ModInt b) => (a.value + b.value);
        public static ModInt operator -(ModInt a, ModInt b) => (a.value - b.value);
        public static ModInt operator *(ModInt a, ModInt b) => (a.value * b.value);
        public static ModInt operator /(ModInt a, ModInt b) => a * Modpow(b, MOD - 2);

        public static ModInt operator <<(ModInt a, int n) => (a.value << n);
        public static ModInt operator >>(ModInt a, int n) => (a.value >> n);
        public static ModInt operator ++(ModInt a) => a.value + 1;
        public static ModInt operator --(ModInt a) => a.value - 1;
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static ModInt Modpow(ModInt a, long n)
        {
            if (n == 0) return 1;
            if (n < 0) return Modpow(Modpow(a, -n), MOD - 2);
            var k = a;
            ModInt ret = 1;
            while (n > 0)
            {
                if ((n & 1) != 0) ret *= k;
                k *= k;
                n >>= 1;
            }
            return ret;
        }
        private static readonly List<long> Factorials = new List<long>() { 1 };
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static ModInt Fac(int n)
        {
            for (var i = Factorials.Count(); i <= n; i++)
            {
                Factorials.Add((Factorials[i - 1] * i) % MOD);
            }
            return Factorials[n];
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static ModInt nCr(int n, int r)
        {
            if (n < 0 || r < 0) return 0;
            return n < r ? 0 : Fac(n) / (Fac(r) * Fac(n - r));
        }
        public static explicit operator int(ModInt a) => (int)a.value;
    }
    public class Rolling_Hash
    {
        const ulong m30 = (1UL << 30) - 1;
        const ulong m31 = (1UL << 31) - 1;
        const ulong MOD = (1UL << 61) - 1;
        const ulong Pl = (MOD << 1) << 1;
        private uint B;
        private string S;
        ulong[] hash;
        ulong[] pw;

        public Rolling_Hash(string str)
        {
            S = str;
            B = (uint)new Random().Next(1 << 12 + 1, int.MaxValue);
            int L = S.Length;
            hash = new ulong[L + 1];
            pw = new ulong[L + 1];
            hash[0] = 0;
            pw[0] = 1;
            for (var i = 0; i < L; i++)
            {
                hash[i + 1] = CalcMod(Mul(hash[i], B) + S[i]);
                pw[i + 1] = CalcMod(Mul(pw[i], B));
            }
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public ulong GetHashValue(int idx) => hash[idx];
        [MethodImpl(MethodImplOptions.AggressiveInlining)]//segment [l,r]
        public ulong Hash_fold(int l, int r) => CalcMod(Pl + hash[r + 1] - Mul(hash[l], pw[r - l + 1]));
        [MethodImpl(MethodImplOptions.AggressiveInlining)]//segment[start,start+len-1]
        public ulong Hash_sub(int start, int len) => CalcMod(Pl + hash[start + len] - Mul(hash[start], pw[len]));
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public ulong[] GetHashArray() => hash;

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        ulong Mul(ulong a, ulong b)
        {
            ulong au = a >> 31;
            ulong ad = a & m31;
            ulong bu = b >> 31;
            ulong bd = b & m31;
            ulong mid = ad * bu + au * bd;
            ulong midu = mid >> 30;
            ulong midd = mid & m30;
            return au * bu * 2 + midu + (midd << 31) + ad * bd;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        ulong CalcMod(ulong x)
        {
            ulong xu = x >> 61;
            ulong xd = x & MOD;
            ulong res = xu + xd;
            if (res >= MOD) res -= MOD;
            return res;
        }
    }
    public class Priority_Queue<T>
    {
        private List<T> Q;
        private readonly Comparison<T> Func_Compare;
        public Priority_Queue(Comparison<T> comp)
        {
            Func_Compare = comp;
            Q = new List<T>();
        }
        private void PushHeap(List<T> list, T item)
        {
            int n = list.Count();
            list.Add(item);

            while (n != 0)
            {
                int pIndex = (n - 1) / 2;

                if (Func_Compare(list[n], list[pIndex]) < 0)
                {
                    Swap(Q, n, pIndex);
                }
                else { break; }

                n = pIndex;
            }
        }
        private void PopHeap(List<T> list)
        {
            int n = list.Count() - 1;
            list[0] = list[n];
            list.RemoveAt(n);

            int cur = 0;
            int comp;

            while (2 * cur + 1 <= n - 1)
            {
                int c1 = 2 * cur + 1;
                int c2 = 2 * (cur + 1);
                if (c1 == n - 1)
                {
                    comp = c1;
                }
                else
                {

                    comp = Func_Compare(list[c1], list[c2]) < 0 ? c1 : c2;
                }

                if (Func_Compare(list[cur], list[comp]) > 0)
                {
                    Swap(Q, cur, comp);
                }
                else { break; }

                cur = comp;
            }
        }
        private void Swap(List<T> list, int a, int b)
        {
            T keep = list[a];
            list[a] = list[b];
            list[b] = keep;
        }

        public void Enqueue(T value)
        {
            PushHeap(Q, value);
        }

        public T Dequeue()
        {
            T ret = Q[0];
            PopHeap(Q);
            return ret;
        }

        public T Peek()
        {
            return Q[0];
        }

        public int Count()
        {
            return Q.Count();
        }
        public bool Any()
        {
            return Q.Any();
        }
    }
    public class SegmentTree<T>
    {
        //1-indexed type
        int n;
        T[] Tree;
        Func<T, T, T> f;
        T ex;
        int L;
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public SegmentTree(int size, Func<T, T, T> fun, T exvalue)
        {
            ex = exvalue;
            f = fun;
            n = size;
            Tree = new T[n << 1];
            L = (n << 1) - 1;
            for (var i = 0; i <= L; i++) Tree[i] = ex;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public SegmentTree(int size, Func<T, T, T> fun, T exvalue, T[] initial)
        {
            ex = exvalue;
            n = size;
            f = fun;
            Tree = new T[n << 1];
            L = (n << 1) - 1;
            for (var i = 0; i <= L; i++) Tree[i] = (n <= i && i <= n + initial.Length - 1) ? initial[i - n] : ex;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void Set_All()
        {
            for (var i = n - 1; i >= 1; i--) Tree[i] = f(Tree[i << 1], Tree[(i << 1) | 1]);
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void Assign(int idx, T nxt) => Tree[idx + n] = nxt;
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void Update(int idx)
        {
            int now = idx + n;
            while (now > 1)
            {
                now >>= 1;
                Tree[now] = f(Tree[now << 1], Tree[now << 1 | 1]);
            }
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void Query_Update(int idx, T nxt)
        {
            Assign(idx, nxt); Update(idx);
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void Query_Update_func(int idx, T y)
        {
            Assign(idx, f(Peek(idx), y)); Update(idx);
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public T Query_Fold(int l, int r)
        {
            int L = n + l;
            int R = n + r;
            T vL = ex, vR = ex;
            while (L < R)
            {
                if (L % 2 == 1)
                {
                    vL = f(vL, Tree[L]);
                    L++;
                }
                if (R % 2 == 1)
                {
                    vR = f(Tree[R - 1], vR);
                    R--;
                }
                L >>= 1;
                R >>= 1;
            }
            return f(vL, vR);
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public T Peek(int idx) => Tree[idx + n];
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void Display(int len)
        {
            for (var i = 0; i < len; i++) Console.Write($"{Tree[i + n]} ");
            Console.WriteLine();
        }
    }
    public class LazySegmentTree<X, A>
    {
        int n, L;
        X[] Tree;
        A[] lazy;
        Func<X, X, X> fxx;
        Func<A, A, A> faa;
        Func<X, A, X> fxa;
        X exx;
        A exa;
        public LazySegmentTree(int size, Func<X, X, X> funcxx, Func<A, A, A> funcaa, Func<X, A, X> funcxa, X exval, A exlaz)
        {
            n = size;
            L = (n << 1) - 1;
            Tree = new X[n << 1];
            lazy = new A[n << 1];
            fxx = funcxx;
            faa = funcaa;
            fxa = funcxa;
            exx = exval;
            exa = exlaz;
            for (var i = 0; i <= L; i++) { Tree[i] = exx; lazy[i] = exa; }
        }
        public X eval(int id) => fxa(Tree[id], lazy[id]);
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void propagate(int id)
        {
            int h = 0; while ((1 << (h + 1)) <= id) h++;
            for (var n = h; n > 0; n--)
            {
                int i = id >> n;
                Tree[i] = eval(i);
                lazy[i << 1] = faa(lazy[i << 1], lazy[i]);
                lazy[i << 1 | 1] = faa(lazy[i << 1 | 1], lazy[i]);
                lazy[i] = exa;
            }
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void re_calc(int id)
        {
            while (id > 1)
            {
                id >>= 1;
                Tree[id] = fxx(eval(id << 1), eval(id << 1 | 1));
            }
        }
        public void Range_Update(int l, int r, A op)
        {
            int L = n + l, R = n + r;
            int ll = L / (L & (-L));
            int rr = R / (R & (-R));
            propagate(ll); propagate(rr - 1);
            while (L < R)
            {
                if ((L & 1) == 1)
                {
                    lazy[L] = faa(lazy[L], op);
                    L++;
                }
                if ((R & 1) == 1)
                {
                    R--;
                    lazy[R] = faa(lazy[R], op);
                }
                L >>= 1; R >>= 1;
            }
            re_calc(ll); re_calc(rr - 1);
        }
        public X Range_Get(int l, int r)
        {
            int L = n + l, R = n + r;
            X vL = exx, vR = exx;
            propagate(L / (L & (-L)));
            propagate(R / (R & (-R)) - 1);
            while (L < R)
            {
                if ((L & 1) == 1)
                {
                    vL = fxx(vL, eval(L));
                    L++;
                }
                if ((R & 1) == 1)
                {
                    R--;
                    vR = fxx(eval(R), vR);
                }
                L >>= 1; R >>= 1;
            }
            return fxx(vL, vR);
        }
        public void Point_Update(int idx, X nxt)
        {
            idx += n;
            propagate(idx);
            Tree[idx] = nxt;
            re_calc(idx);
        }

        /*======================*/
        public void Assign(int idx, X nxt) => Tree[n + idx] = nxt;
        public void Set_All()
        {
            for (var i = n - 1; i >= 1; i--)
            {
                Tree[i] = fxx(Tree[i << 1], Tree[i << 1 | 1]);
                lazy[i] = faa(lazy[i << 1], lazy[i << 1 | 1]);
            }
        }
        public X Peek(int idx) => Tree[n + idx];
        public void Display(int len)
        {
            for (var i = n; i < n + len; i++) Console.Write($"{eval(i)} ");
            Console.WriteLine();
        }
        public void Displayall()
        {
            //木の形で表示、nが2冪でない時は注意
            int e = 0;
            while ((1 << e) <= n)
            {
                for (var i = (1 << e); i < (1 << e) + (1 << e); i++) Console.Write($"{Tree[i]}/{lazy[i]} ");
                Console.WriteLine();
                e++;
            }
        }
    }
    public class UnionFind
    {
        private int[] parent;
        private int[] rank;
        private int[] size;
        public UnionFind(int n)
        {
            parent = new int[n];
            rank = new int[n];
            size = new int[n];
            for (var i = 0; i < n; i++)
            {
                parent[i] = i;
                rank[i] = 0;
                size[i] = 1;
            }
        }

        public int Root(int x)
        {
            return parent[x] == x ? x : parent[x] = Root(parent[x]);
        }

        public bool SameRoot(int x, int y)
        {
            return Root(x) == Root(y);
        }

        public void Unite(int x, int y)
        {
            x = Root(x);
            y = Root(y);
            if (x == y) { return; }

            if (rank[x] < rank[y])
            {
                parent[x] = y;
                size[y] += size[x];
                size[x] = 0;
            }
            else
            {
                parent[y] = x;
                if (rank[x] == rank[y]) { rank[x]++; }
                size[x] += size[y];
                size[y] = 0;
            }
        }

        public int SizeOf(int x)
        {
            return size[Root(x)];
        }

    }
    static class Cin
    {
        public static string[] ReadSplit => Console.ReadLine().Split();
        public static int[] ReadSplitInt => ConvertAll(ReadSplit, int.Parse);
        public static long[] ReadSplitLong => ConvertAll(ReadSplit, long.Parse);
        public static double[] ReadSplit_Double => ConvertAll(ReadSplit, double.Parse);
        public static string Str => Console.ReadLine();
        public static int Int => int.Parse(Console.ReadLine());
        public static long Long => long.Parse(Console.ReadLine());
        public static double Double => double.Parse(Console.ReadLine());
        public static T Conv<T>(string input)
        {
            if (typeof(T).Equals(typeof(ModInt)))
            {
                return (T)(dynamic)(long.Parse(input));
            }
            return (T)Convert.ChangeType(input, typeof(T));
        }
        public static void Scanf<T>(out T a) => a = Conv<T>(Console.ReadLine());
        public static void Scanf<T, U>(out T a, out U b)
        { var q = ReadSplit; a = Conv<T>(q[0]); b = Conv<U>(q[1]); }
        public static void Scanf<T, U, V>(out T a, out U b, out V c)
        { var q = ReadSplit; a = Conv<T>(q[0]); b = Conv<U>(q[1]); c = Conv<V>(q[2]); }
        public static void Scanf<T, U, V, W>(out T a, out U b, out V c, out W d)
        { var q = ReadSplit; a = Conv<T>(q[0]); b = Conv<U>(q[1]); c = Conv<V>(q[2]); d = Conv<W>(q[3]); }
        public static void Scanf<T, U, V, W, X>(out T a, out U b, out V c, out W d, out X e)
        { var q = ReadSplit; a = Conv<T>(q[0]); b = Conv<U>(q[1]); c = Conv<V>(q[2]); d = Conv<W>(q[3]); e = Conv<X>(q[4]); }
    }
    static class Cout
    {
        public static void OutL(object s) => Console.WriteLine(s);
        public static void Out_Sep<T>(IEnumerable<T> s) => Console.WriteLine(string.Join(" ", s));
        public static void Out_Sep<T>(IEnumerable<T> s, string sep) => Console.WriteLine(string.Join($"{sep}", s));
        public static void Out_Sep(params object[] s) => Console.WriteLine(string.Join(" ", s));
        public static void Out_One(object s) => Console.Write($"{s} ");
        public static void Out_One(object s, string sep) => Console.Write($"{s}{sep}");
        public static void Endl() => Console.WriteLine();
    }
    public static class Tool
    {
        static public void Initialize<T>(ref T[] array, T initialvalue)
        {
            array = ConvertAll(array, x => initialvalue);
        }
        static public void Swap<T>(ref T a, ref T b)
        {
            T keep = a;
            a = b;
            b = keep;
        }
        static public void Display<T>(T[,] array2d, int n, int m)
        {
            for (var i = 0; i < n; i++)
            {
                for (var j = 0; j < m; j++)
                {
                    Console.Write($"{array2d[i, j]} ");
                }
                Console.WriteLine();
            }
        }
        static public long Gcd(long a, long b)
        {
            if (a == 0 || b == 0) return Max(a, b);
            return a % b == 0 ? b : Gcd(b, a % b);
        }
        static public long LPow(int a, int b) => (long)Pow(a, b);
        static public bool Bit(long x, int dig) => ((1L << dig) & x) != 0;
        static public int Sig(long a) => a == 0 ? 0 : (int)(a / Abs(a));
    }
}