Problem:
Score : 400 points

Problem Statement

Takahashi will play a game using a piece on an array of squares numbered 1, 2, \cdots, N. Square i has an integer C_i written on it. Also, he is given a permutation of 1, 2, \cdots, N: P_1, P_2, \cdots, P_N.

Now, he will choose one square and place the piece on that square. Then, he will make the following move some number of times between 1 and K (inclusive):

In one move, if the piece is now on Square i (1 \leq i \leq N), move it to Square P_i. Here, his score increases by C_{P_i}.

Help him by finding the maximum possible score at the end of the game. (The score is 0 at the beginning of the game.)

Constraints

2 \leq N \leq 5000

1 \leq K \leq 10^9

1 \leq P_i \leq N

P_i \neq i

P_1, P_2, \cdots, P_N are all different.

-10^9 \leq C_i \leq 10^9

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N K
P_1 P_2 \cdots P_N
C_1 C_2 \cdots C_N

Output

Print the maximum possible score at the end of the game.

Sample Input 1

5 2
2 4 5 1 3
3 4 -10 -8 8

Sample Output 1

8

When we start at some square of our choice and make at most two moves, we have the following options:

If we start at Square 1, making one move sends the piece to Square 2, after which the score is 4. Making another move sends the piece to Square 4, after which the score is 4 + (-8) = -4.

If we start at Square 2, making one move sends the piece to Square 4, after which the score is -8. Making another move sends the piece to Square 1, after which the score is -8 + 3 = -5.

If we start at Square 3, making one move sends the piece to Square 5, after which the score is 8. Making another move sends the piece to Square 3, after which the score is 8 + (-10) = -2.

If we start at Square 4, making one move sends the piece to Square 1, after which the score is 3. Making another move sends the piece to Square 2, after which the score is 3 + 4 = 7.

If we start at Square 5, making one move sends the piece to Square 3, after which the score is -10. Making another move sends the piece to Square 5, after which the score is -10 + 8 = -2.

The maximum score achieved is 8.

Sample Input 2

2 3
2 1
10 -7

Sample Output 2

13

Sample Input 3

3 3
3 1 2
-1000 -2000 -3000

Sample Output 3

-1000

We have to make at least one move.

Sample Input 4

10 58
9 1 6 7 8 4 3 2 10 5
695279662 988782657 -119067776 382975538 -151885171 -177220596 -169777795 37619092 389386780 980092719

Sample Output 4

29507023469

The absolute value of the answer may be enormous.

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

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Runtime.Intrinsics.X86;
using System.Text;
using static Solve.Methods;
using static Solve.Input;
using static Solve.Output;
using static Solve.Solver;
using static System.Math;

namespace Solve
{
    public partial class Solver
    {
        public void Main() {
            var (N, K) = Int;
            var P = Int.array(N).Select(x => --x).ToArray();
            var C = Int.array(N); // Can be negative, |Ci| <= 10^9

            long ans = long.MinValue;
            for (int start = 0; start < N; start++) {
                var scores = new long[N];
                var distance = new int[N];
                Array.Fill(distance, INF);
                distance[start] = 0;
                Array.Fill(scores, long.MinValue);
                scores[start] = 0;
                
                long currentScore = 0; 
                int now = start, cnt = 0;

                var cMax = long.MinValue;
                bool bb = false;
                while (true) {
                    int dest = P[now];

                    if (scores[dest] != long.MinValue && !bb) {
                        // ループして戻ってきた
                        var diff = currentScore + C[dest] - scores[dest];
                        if (diff <= 0) {
                            // これ以上ループしないほうが良い場合
                            break;
                        }
                        
                        // ループしても良い場合
                        
                        // 周期
                        var cycle = cnt + 1 - distance[dest];
                        
                        // 最大何回までループさせられるか
                        var maxRoopCount = (K - cnt) / cycle;

                        if (maxRoopCount == 0) {
                            // 残りも普通に計算をする
                            bb = true;
                        } else {
                            // 最大の回数ループ
                            var tmp = currentScore + (scores[now] - scores[dest] + C[dest]) * maxRoopCount;
                            

                            var maxCount = K - cnt - maxRoopCount * cycle;
                            for (int now2 = now, cnt2 = 0; cnt2 < maxCount; ++cnt2) {
                                chmax(ref cMax, tmp);
                                now2 = P[now2];
                                tmp += C[now2];
                            }
                            chmax(ref cMax, tmp);
                            
                            // 最大の回数から1回少なくループ
                            tmp = currentScore + (scores[now] - scores[dest] + C[dest]) * (maxRoopCount - 1);

                            for (int now2 = now, cnt2 = 0; cnt2 < cycle - 1; ++cnt2) {
                                chmax(ref cMax, tmp);
                                now2 = P[now2];
                                tmp += C[now2];
                            }
                            chmax(ref cMax, tmp);
                            
                            break;
                        }
                    }

                    distance[dest] = cnt++; 
                    
                    
                    currentScore += C[dest];
                    scores[dest] = currentScore;
                    chmax(ref cMax, currentScore);

                    if (cnt == K) {
                        break;
                    }
                    now = dest;
                }

                chmax(ref ans, cMax);
            }
            print(ans);
        }

        public const int MOD = 1000000007;
    }


    public static class Methods
    {
        [MethodImpl(256)] public static bool Assert(in bool b, in string message = null) =>
            b ? true : throw new Exception(message ?? "Assert failed.");
        [MethodImpl(256)] public static string JoinSpace<T>(this IEnumerable<T> source) => source.Join(" ");
        [MethodImpl(256)] public static string JoinEndline<T>(this IEnumerable<T> source) => source.Join("\n");
        [MethodImpl(256)] public static string Join<T>(this IEnumerable<T> source, string s) => string.Join(s, source);
        [MethodImpl(256)] public static string Join<T>(this IEnumerable<T> source, char c) =>
            string.Join(c.ToString(), source);
        public static int Gcd(int a, int b) => (int) Gcd((long) a, b);
        public static long Gcd(long a, long b) {
            while (true) {
                if (a < b) (a, b) = (b, a);
                if (a % b == 0) return b;
                var x = a;
                a = b;
                b = x % b;
            }
        }
        public static long Lcm(long a, long b) => a / Gcd(a, b) * b;
        public static bool IsPrime(long value) {
            if (value <= 1) return false;
            for (long i = 2; i * i <= value; ++i) if (value % i == 0) return false;
            return true;
        }
        public static long Pow(long a, int b) {
            long res = 1;
            while (b > 0) { if (b % 2 != 0) res *= a; a *= a; b >>= 1; }
            return res;
        }
        public static int PowMod(long a, long b, int p) => (int) PowMod(a, b, (long) p);
        public static long PowMod(long a, long b, long p) {
            long res = 1;
            while (b > 0) { if (b % 2 != 0) res = res * a % p; a = a * a % p; b >>= 1; }
            return res;
        }
        public static IEnumerable<long> Factors(long n) {
            Assert(n >= 0, "n must be greater than 0.");
            for (long i = 1; i * i <= n; ++i) {
                var div = DivRem(n, i, out var rem);
                if (rem > 0) continue;
                yield return div;
                if (i != div) yield return i;
            }
        }
        public static IEnumerable<int> Factors(int n) => Factors((long) n).Select(Convert.ToInt32);
        [MethodImpl(256)] public static int DivCeil(int a, int b) => (a + b - 1) / b;
        [MethodImpl(256)] public static long DivCeil(long a, long b) => (a + b - 1) / b;
        public static IEnumerable<T[]> Permutations<T>(IEnumerable<T> src) {
            var ret = new List<T[]>();
            Search(ret, new Stack<T>(), src.ToArray());
            return ret;

            static void Search(ICollection<T[]> perms, Stack<T> stack, T[] a) {
                int N = a.Length;
                if (N == 0) perms.Add(stack.Reverse().ToArray());
                else {
                    var b = new T[N - 1];
                    Array.Copy(a, 1, b, 0, N - 1);
                    for (int i = 0; i < a.Length; ++i) {
                        stack.Push(a[i]);
                        Search(perms, stack, b);
                        if (i < b.Length) b[i] = a[i];
                        stack.Pop();
                    }
                }
            }
        }
        public static long BinarySearch(long low, long high, Func<long, bool> expression) {
            while (low < high) {
                long middle = (high - low) / 2 + low;
                if (!expression(middle))
                    high = middle;
                else
                    low = middle + 1;
            }

            return high;
        }
        public static int LowerBound<T>(T[] arr, int start, int end, T value, IComparer<T> comparer) {
            int low = start;
            int high = end;
            while (low < high) {
                var mid = ((high - low) >> 1) + low;
                if (comparer.Compare(arr[mid], value) < 0)
                    low = mid + 1;
                else
                    high = mid;
            }

            return low;
        }
        public static int LowerBound<T>(T[] arr, T value) where T : IComparable =>
            LowerBound(arr, 0, arr.Length, value, Comparer<T>.Default);
        public static int UpperBound<T>(T[] arr, int start, int end, T value, IComparer<T> comparer) {
            var (low, high) = (start, end);
            while (low < high) {
                var mid = ((high - low) >> 1) + low;
                if (comparer.Compare(arr[mid], value) <= 0) low = mid + 1;
                else high = mid;
            }

            return low;
        }
        public static int UpperBound<T>(T[] arr, T value) => 
            UpperBound(arr, 0, arr.Length, value, Comparer<T>.Default);
        [MethodImpl(256)]
        public static IEnumerable<TResult> Repeat<TResult>(TResult value, int count) => Enumerable.Repeat(value, count);
        [MethodImpl(256)] public static string AsString(this IEnumerable<char> source) => new string(source.ToArray());
        public static IEnumerable<long> CumSum(this IEnumerable<long> source) {
            long sum = 0; foreach (var item in source) yield return sum += item;
        }
        public static IEnumerable<int> CumSum(this IEnumerable<int> source) {
            int sum = 0; foreach (var item in source) yield return sum += item;
        }
        [MethodImpl(256)] public static bool IsIn<T>(this T value, T l, T r) where T : IComparable<T> =>
            l.CompareTo(r) > 0 ? throw new ArgumentException() : l.CompareTo(value) <= 0 && value.CompareTo(r) < 0;
        [MethodImpl(256)] public static bool IsIn(this in int value, in Range range) =>
            value.IsIn(range.Start.Value, range.End.Value);
        [MethodImpl(256)] public static bool IsIn(this in Index value, in Range range) =>
            value.IsFromEnd && value.Value.IsIn(range.Start.Value, range.End.Value);
        public static IEnumerable<int> Range(int start, int end, int step = 1) {
            for (var i = start; i < end; i += step) yield return i;
        }
        public static IEnumerable<int> Range(int end) => Range(0, end);
        public static IEnumerable<int> Range(Range range, int step = 1) =>
            Range(range.Start.Value, range.End.Value, step);
        [MethodImpl(256)] public static T[] Sort<T>(this T[] arr) where T : IComparable<T> {
            var array = arr[..]; Array.Sort(array); return array;
        }
        [MethodImpl(256)]
        public static T[] Sort<T, U>(this T[] arr, Func<T, U> selector) where U : IComparable<U> {
            var array = arr[..];
            Array.Sort(array, (a, b) => selector(a).CompareTo(selector(b)));
            return array;
        }
        [MethodImpl(256)] public static T[] SortDescending<T>(this T[] arr) where T : IComparable<T> {
            var array = arr[..];
            Array.Sort(array, (a, b) => b.CompareTo(a));
            return array;
        }
        [MethodImpl(256)]
        public static T[] SortDescending<T, U>(this T[] arr, Func<T, U> selector) where U : IComparable<U> {
            var array = arr[..];
            Array.Sort(array, (a, b) => selector(b).CompareTo(selector(a)));
            return array;
        }
        public static T[] Unique<T>(this IEnumerable<T> arr) {
            var source = arr.ToArray();
            var ret = new List<T>(source.Length);
            var set = new SortedSet<T>();
            ret.AddRange(source.Where(val => set.Add(val)));

            return ret.ToArray();
        }
        [MethodImpl(256)] public static bool chmin<T>(ref T a, T b)
            where T : IComparable<T> {
            if (a.CompareTo(b) > 0) { a = b; return true; }
            return false;
        } 
        [MethodImpl(256)] public static bool chmax<T>(ref T a, T b)
            where T : IComparable<T> {
            if (a.CompareTo(b) < 0) { a = b; return true; }
            return false;
        }
        public static T[] InitArray<T>(int n, Func<int, T> init) {
            var res = new T[n];
            for (int i = 0; i < n; i++) res[i] = init(i);
            return res;
        }
        public static T[][] JaggedArray2D<T>(int a, int b, T defaultValue = default) {
            var ret = new T[a][];
            for (int i = 0; i < a; ++i) ret[i] = Enumerable.Repeat(defaultValue, b).ToArray();
            return ret;
        }
        public static T[,] Array2D<T>(int a, int b, T defaultValue = default) {
            var ret = new T[a, b];
            for (int i = 0; i < a; ++i) for (int j = 0; j < b; ++j) ret[i, j] = defaultValue;
            return ret;
        }
        public static T[,] To2DArray<T>(this T[][] array) {
            if (!array.Any()) return new T[0, 0];

            int len = array[0].Length;
            if (array.Any(x => x.Length != len))
                throw new ArgumentException("Length of each array must be same.", nameof(array));

            var ret = new T[array.Length, len];
            for (int i = 0; i < array.Length; ++i) for (int j = 0; j < len; ++j) ret[i, j] = array[i][j];
            return ret;
        }
        [MethodImpl(256)] public static T Min<T>(params T[] col) => col.Min();
        [MethodImpl(256)] public static T Max<T>(params T[] col) => col.Max();
        [MethodImpl(256)] public static IEnumerable<(T, int)> WithIndex<T>(this IEnumerable<T> source) =>
            source.Select((x, i) => (x, i));
        [MethodImpl(256)] public static (T, U, V)[] Zip<T, U, V>(
            IReadOnlyCollection<T> t,
            IReadOnlyCollection<U> u,
            IReadOnlyCollection<V> v
        ) {
            Assert(t.Count == u.Count && u.Count == v.Count);
            return t.Zip(u, (a, b) => (a, b))
                .Zip(v, (tuple, c) => (tuple.Item1, tuple.Item2, c)).ToArray();
        }
        [MethodImpl(256)] public static void rep(in int start, in int end, Action<int> func) {
            for (int i = start; i < end; ++i) func(i);
        }
        [MethodImpl(256)] public static void rep(in int end, Action<int> func) => rep(0, end, func);
        [MethodImpl(256)] public static void rep1(in int end, Action<int> func) => rep(1, end + 1, func);
        [MethodImpl(256)] public static void repr(in int end, Action<int> func) {
            for (int i = end - 1; i >= 0; --i) func(i);
        }
        [MethodImpl(256)]
        public static void each<T>(this IEnumerable<T> source, Action<T> func) {
            foreach (var item in source) func(item);
        }
        [MethodImpl(256)]
        public static void eachWithIndex<T>(this IEnumerable<T> source, Action<T, int> func) {
            int index = 0; foreach (var item in source) func(item, index++);
        }
        [MethodImpl(256)] public static int bit(in int x) => 1 << x;
        [MethodImpl(256)] public static long bitl(in int x) => 1L << x;
    }
    public class UnorderedMap<T, U> : Dictionary<T, U>
    {
        public new U this[T k] {
            get =>
                TryGetValue(k, out var v) ? v : base[k] = default;
            set =>
                base[k] = value;
        }
    }
    public class Map<T, U> : SortedDictionary<T, U>
    {
        readonly U _default;
        public Map(U defaultValue = default) {
            _default = defaultValue;
        }
        public new U this[T k] {
            get =>
                TryGetValue(k, out var v) ? v : base[k] = _default;
            set =>
                base[k] = value;
        }
    }
    public class Scanner<T>
    {
        public T r => next<T>();
        public T next() => r;

        IEnumerable<T> enumerable(int N) { for (int i = 0; i < N; ++i) yield return r; }

        public T[] array(in int N) => enumerable(N).ToArray();
        public List<T> list(in int N) => enumerable(N).ToList();
        public T[,] array2d(in int N, in int M) => next2DArray<T>(N, M);
        public T[][] listArray(in int n) {
            var ret = new T[n][];
            for (int i = 0; i < n; i++) ret[i] = array(next<int>());
            return ret;
        }

        public void Deconstruct(out T _1, out T _2) => (_1, _2) = (r, r);
        public void Deconstruct(out T _1, out T _2, out T _3) => (_1, _2, _3) = (r, r, r);
        public void Deconstruct(out T _1, out T _2, out T _3, out T _4) =>
            (_1, _2, _3, _4) = (r, r, r, r);
        public void Deconstruct(out T _1, out T _2, out T _3, out T _4, out T _5) =>
            (_1, _2, _3, _4, _5) = (r, r, r, r, r);
        public void Deconstruct(out T _1, out T _2, out T _3, out T _4, out T _5, out T _6) =>
            (_1, _2, _3, _4, _5, _6) = (r, r, r, r, r, r);
        public void Deconstruct(out T _1, out T _2, out T _3, out T _4, out T _5, out T _6, out T _7) =>
            (_1, _2, _3, _4, _5, _6, _7) = (r, r, r, r, r, r, r);
        public void Deconstruct(out T _1, out T _2, out T _3, out T _4, out T _5, out T _6, out T _7, out T _8) =>
            (_1, _2, _3, _4, _5, _6, _7, _8) = (r, r, r, r, r, r, r, r);
        public void Deconstruct(out T _1, out T _2, out T _3, out T _4, 
            out T _5, out T _6, out T _7, out T _8, out T _9) =>
            (_1, _2, _3, _4, _5, _6, _7, _8, _9) = (r, r, r, r, r, r, r, r, r);
        public void Deconstruct(out T _1, out T _2, out T _3, out T _4,
            out T _5, out T _6, out T _7, out T _8, out T _9, out T _10) =>
            (_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) = (r, r, r, r, r, r, r, r, r, r);
        
        public static implicit operator T(Scanner<T> sc) => sc.r;
    }
    public static class Input
    {
        const char _separator = ' ';
        static readonly Queue<string> _input = new Queue<string>();
        static readonly StreamReader sr =
#if FILE
            new StreamReader("in.txt");
#else
            new StreamReader(Console.OpenStandardInput());
#endif

        public static string ReadLine => sr.ReadLine();
        static string ReadStr => Read;
        static int ReadInt => int.Parse(Read);
        static long ReadLong => long.Parse(Read);
        static ulong ReadULong => ulong.Parse(Read);
        static double ReadDouble => double.Parse(Read);
        static BigInteger ReadBigInteger => BigInteger.Parse(Read);

        public static string Read {
            get {
                if (_input.Any()) return _input.Dequeue();
                foreach (var val in sr.ReadLine().Split(_separator)) _input.Enqueue(val);
                return _input.Dequeue();
            }
        }

        public static string next() => Read;
        public static T next<T>() =>
            default(T) switch {
                sbyte _ => (T) (object) (sbyte) ReadInt,
                short _ => (T) (object) (short) ReadInt,
                int _ => (T) (object) ReadInt,
                long _ => (T) (object) ReadLong,
                byte _ => (T) (object) (byte) ReadULong,
                ushort _ => (T) (object) (ushort) ReadULong,
                uint _ => (T) (object) (uint) ReadULong,
                ulong _ => (T) (object) ReadULong,
                float _ => (T) (object) (float) ReadDouble,
                double _ => (T) (object) ReadDouble,
                string _ => (T) (object) ReadStr,
                char _ => (T) (object) ReadStr[0],
                BigInteger _ => (T) (object) ReadBigInteger,
                _ => typeof(T) == typeof(string)
                    ? (T) (object) ReadStr
                    : throw new NotSupportedException(),
            };
        public static (T, U) next<T, U>() => (next<T>(), next<U>());
        public static (T, U, V) next<T, U, V>() => (next<T>(), next<U>(), next<V>());
        public static (T, U, V, W) next<T, U, V, W>() => (next<T>(), next<U>(), next<V>(), next<W>());
        public static (T, U, V, W, X) next<T, U, V, W, X>() => (next<T>(), next<U>(), next<V>(), next<W>(), next<X>());
        public static T[] nextArray<T>(in int size) {
            var ret = new T[size]; for (int i = 0; i < size; ++i) ret[i] = next<T>(); return ret;
        }
        public static T[,] next2DArray<T>(int n, in int m) {
            var ret = new T[n, m];
            for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) ret[i, j] = next<T>(); return ret;
        }
        public static (T[], U[]) nextArray<T, U>(in int size) {
            var ret1 = new T[size]; var ret2 = new U[size];
            for (int i = 0; i < size; ++i) (ret1[i], ret2[i]) = next<T, U>();
            return (ret1, ret2);
        }
        public static (T[], U[], V[]) nextArray<T, U, V>(in int size) {
            var ret1 = new T[size]; var ret2 = new U[size]; var ret3 = new V[size];
            for (int i = 0; i < size; ++i) (ret1[i], ret2[i], ret3[i]) = next<T, U, V>();
            return (ret1, ret2, ret3);
        }
    }
    public static class Output
    {
        [MethodImpl(256)] public static void print() => Console.WriteLine();
        [MethodImpl(256)] public static void print(in string s, bool endline = true) {
            if (endline) Console.WriteLine(s); else Console.Write(s);
        }
        [MethodImpl(256)] public static void print(in char s, bool endline = true) {
            if (endline) Console.WriteLine(s); else Console.Write(s);
        }
        [MethodImpl(256)] public static void print(in int v, bool endline = true) {
            if (endline) Console.WriteLine(v); else Console.Write(v);
        }
        [MethodImpl(256)] public static void print(in long v, bool endline = true) {
            if (endline) Console.WriteLine(v); else Console.Write(v);
        }
        [MethodImpl(256)] public static void print(in ulong v, bool endline = true) {
            if (endline) Console.WriteLine(v); else Console.Write(v);
        }
        [MethodImpl(256)] public static void print(in bool b) => PrintBool(b);
        [MethodImpl(256)] public static void print(in object v) => Console.WriteLine(v);
        [MethodImpl(256)] public static void print<T>(in IEnumerable<T> array, string separator = " ") =>
            Console.WriteLine(array.Join(separator));
        [MethodImpl(256)] public static void prints<T>(params T[] t) => print(t);
        
#if LOCAL
        [MethodImpl(256)] public static void debug<T>(in T value, bool endline = true) {
            if (endline) Console.WriteLine(value);else Console.Write(value);
        }
#else
        public static void debug(params object[] obj) { }
#endif

        [MethodImpl(256)] static void PrintBool(in bool val, in string yes = null, in string no = null) =>
            print(val ? yes ?? _yes : no ?? _no);
        static string _yes = "Yes", _no = "No";

        public static void SetYesNoString(in YesNoType t) => (_yes, _no) = YesNoString[t];
        public static void SetYesNoString(in string yes, in string no) => (_yes, _no) = (yes, no);

        static readonly Dictionary<YesNoType, (string yes, string no)>
            YesNoString = new Dictionary<YesNoType, (string, string)> {
                    {YesNoType.Yes_No, ("Yes", "No")},
                    {YesNoType.YES_NO, ("YES", "NO")},
                    {YesNoType.Upper, ("YES", "NO")},
                    {YesNoType.yes_no, ("yes", "no")},
                    {YesNoType.Lower, ("yes", "no")},
                    {YesNoType.Possible_Impossible, ("Possible", "Impossible")},
                    {YesNoType.Yay, ("Yay!", ":(")},
                };

        public static readonly (string yes, string no) YN_Possible = ("Possible", "Impossible"),
            YN_lower = ("yes", "no"), YN_upper = ("YES", "NO"), YN_Yay = ("Yay!", ":(");

        public static void Yes() => print(_yes);
        public static void No() => print(_no);

        public static object cout { set => Console.WriteLine(value); }
#if LOCAL
        public static object dout { set => Console.WriteLine(value); }
#else
        public static object dout { set { } }
#endif
        public static object cerr { set => Console.Error.WriteLine(value); }

        public const string endl = "\n";

        public enum YesNoType { Yes_No, YES_NO, Upper, yes_no, Lower, Possible_Impossible, Yay }
    }
    public class Program
    {
        public static void Main(string[] args) {
            var sw = new StreamWriter(Console.OpenStandardOutput()) {AutoFlush = false};
            Console.SetOut(sw);
            new Solver().Main();
            Console.Out.Flush();
        }
    }
    partial class Solver
    {
        readonly Scanner<int> Int;
        readonly Scanner<long> Long;
        readonly Scanner<string> String;
        public Solver() => (Int, String, Long) = (new Scanner<int>(), new Scanner<string>(), new Scanner<long>());
        const int INF = 1000000010;
        const long LINF = 1000000000000000100;
        const double EPS = 1e-9;
        public static readonly int[] dx = {-1, 0, 0, 1}, dy = {0, 1, -1, 0};
    }
}