Problem:
Score: 500 points

Problem Statement

Given is a permutation P of \{1, 2, \ldots, N\}.

For a pair (L, R) (1 \le L \lt R \le N), let X_{L, R} be the second largest value among P_L, P_{L+1}, \ldots, P_R.

Find \displaystyle \sum_{L=1}^{N-1} \sum_{R=L+1}^{N} X_{L,R}.

Constraints

2 \le N \le 10^5

1 \le P_i \le N

P_i \neq P_j (i \neq j)

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
P_1 P_2 \ldots P_N

Output

Print \displaystyle \sum_{L=1}^{N-1} \sum_{R=L+1}^{N} X_{L,R}.

Sample Input 1

3
2 3 1

Sample Output 1

5

X_{1, 2} = 2, X_{1, 3} = 2, and X_{2, 3} = 1, so the sum is 2 + 2 + 1 = 5.

Sample Input 2

5
1 2 3 4 5

Sample Output 2

30

Sample Input 3

8
8 2 7 3 4 5 6 1

Sample Output 3

136

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

#if true
//#if false
#define UTAKA_DEBUG
#endif

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Net.Mime;
using System.Text;

namespace UtakaApp
{
    public partial class Program
    {
        public const string ContestName = "abc140";
        public const string ProblemName = "E";

        public static void Main(string[] args)
        {
#if UTAKA_LOCAL
//#if false
            new TestCaseCheckerForAtCoder().TestProblems();
#else
            var console = new MyConsole();
            new Program().Solve(System.Console.In, console);
            console.Flush();
#endif
            var sw = new StreamWriter(Console.OpenStandardOutput()) {AutoFlush = false};
        }

        public sealed class Node
        {
            public int Value;
            public int Index;

            public Node(int value, int index)
            {
                Value = value;
                Index = index;
            }

            public override string ToString()
            {
                return Index.ToString();
                //return $"{nameof(Value)}: {Value}, {nameof(Index)}: {Index}";
            }
        }

        public void Solve(TextReader textReader, IConsole console)
        {
            var cin = new ConsoleInput(textReader);

            int N = cin.ReadInt;
            int[] P = cin.ReadIntArray(N);

            int[] indexes = new int[N];

            for (int i = 0; i < N; i++)
            {
                indexes[P[i] - 1] = i;
            }

            RBTree<int, Node> rbt = new RBTree<int, Node>();

            long sum = 0;

            for (int v = N - 1; v >= 0; v--)
            {
                int index = indexes[v];

                rbt.Add(index, new Node(index, index));

                var currentNode = rbt.GetNode(index);

                var node = currentNode;

                int[] l = new int[2];

                for (int k = 0; k < 2; k++)
                {
                    node = rbt.GetNextSmaller(node);

                    if (node.IsSentinelNode)
                    {
                        l[k] = -1;
                    }
                    else
                    {
                        l[k] = node.Key;
                    }
                }

                int[] r = new int[2];

                node = currentNode;

                for (int k = 0; k < 2; k++)
                {
                    node = rbt.GetNextLarger(node);

                    if (node.IsSentinelNode)
                    {
                        r[k] = N;
                    }
                    else
                    {
                        r[k] = node.Key;
                    }
                }

                int[] ls = new int[2];
                int[] rs = new int[2];

                ls[0] = index - l[0];
                ls[1] = l[0] - l[1];

                rs[0] = r[0] - index;
                rs[1] = r[1] - r[0];

                long c = (long)ls[0] * rs[1] + (long)ls[1] * rs[0];

                sum += c * (v + 1);
            }
            
            console.WriteLine(sum.ToString());
        }
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public static class BTreePrinter<TKey, TValue>
        where TKey : IComparable, IComparable<TKey>, IEquatable<TKey>
    {
        public static RBNode<TKey, TValue> SentinelNode = RBTree<TKey, TValue>.SentinelNode;

        class NodeInfo
        {
            public RBNode<TKey, TValue> Node;
            public string Text;
            public int StartPos;

            public int Size
            {
                get { return Text.Length; }
            }

            public int EndPos
            {
                get { return StartPos + Size; }
                set { StartPos = value - Size; }
            }

            public NodeInfo Parent, Left, Right;
        }

        public static void PrintTree(RBNode<TKey, TValue> root, int spacing = 1, int topMargin = 2, int leftMargin = 2)
        {
            if (root == SentinelNode) return;
            int rootTop = Console.CursorTop + topMargin;
            var last = new List<NodeInfo>();
            var next = root;
            for (int level = 0; next != SentinelNode; level++)
            {
                var item = new NodeInfo {Node = next, Text = next.ToString()};

                if (item.Node.Data.ToString() == 48.ToString())
                {
                    int i = 124;
                }

                if (level < last.Count)
                {
                    item.StartPos = last[level].EndPos + spacing;
                    last[level] = item;
                }
                else
                {
                    item.StartPos = leftMargin;
                    last.Add(item);
                }

                if (level > 0)
                {
                    item.Parent = last[level - 1];
                    if (next == item.Parent.Node.Left)
                    {
                        item.Parent.Left = item;
                        item.EndPos = Math.Max(item.EndPos, item.Parent.StartPos - 1);
                    }
                    else
                    {
                        item.Parent.Right = item;
                        item.StartPos = Math.Max(item.StartPos, item.Parent.EndPos + 1);
                    }
                }

                next = next.Left != SentinelNode ? next.Left : next.Right;
                for (; next == SentinelNode; item = item.Parent)
                {
                    int top = rootTop + 2 * level;
                    Print(item.Text, top, item.StartPos);
                    if (item.Left != null)
                    {
                        Print("/", top + 1, item.Left.EndPos);
                        Print("_", top, item.Left.EndPos + 1, item.StartPos);
                    }

                    if (item.Right != null)
                    {
                        Print("_", top, item.EndPos, item.Right.StartPos - 1);
                        Print("\\", top + 1, item.Right.StartPos - 1);
                    }

                    if (--level < 0) break;
                    if (item == item.Parent.Left)
                    {
                        item.Parent.StartPos = item.EndPos + 1;
                        next = item.Parent.Node.Right;
                    }
                    else
                    {
                        if (item.Parent.Left == null)
                            item.Parent.EndPos = item.StartPos - 1;
                        else
                            item.Parent.StartPos += (item.StartPos - 1 - item.Parent.EndPos) / 2;
                    }
                }
            }

            Console.SetCursorPosition(0, rootTop + 2 * last.Count - 1);
        }

        private static void Print(string s, int top, int left, int right = -1)
        {
            Console.SetCursorPosition(left, top);
            if (right < 0) right = left + s.Length;
            while (Console.CursorLeft < right) Console.Write(s);
        }
    }


    public class RBNode<TKey, TValue>
        where TKey : IComparable, IComparable<TKey>, IEquatable<TKey>
    {
        public RBNode()
        {
            Color = RBTree<TKey, TValue>.RedBlackNodeType.Red;

            Right = RBTree<TKey, TValue>.SentinelNode;
            Left = RBTree<TKey, TValue>.SentinelNode;
        }

        public RBNode(TKey key, TValue data)
            : this()
        {
            Key = key;
            Data = data;
        }

        public TKey Key { get; set; }
        public TValue Data { get; set; }

        public RBTree<TKey, TValue>.RedBlackNodeType Color { get; set; }

        public RBNode<TKey, TValue> Left { get; set; }
        public RBNode<TKey, TValue> Right { get; set; }
        public RBNode<TKey, TValue> Parent { get; set; }

        public bool IsSentinelNode => this == RBTree<TKey, TValue>.SentinelNode;

        public override string ToString()
        {
            return Key.ToString();
            //return $"{nameof(Key)}: {Key}, {nameof(Data)}: {Data}";
        }
    }

    public class RBTree<TKey, TValue>
        where TKey : IComparable<TKey>, IComparable, IEquatable<TKey>
    {
        public static readonly RBNode<TKey, TValue> SentinelNode = new RBNode<TKey, TValue>
        {
            Color = RedBlackNodeType.Black,
            Left = null,
            Right = null,
            Parent = null,
        };

        public RBNode<TKey, TValue> LastFoundNode = SentinelNode;
        public RBNode<TKey, TValue> RootNode = SentinelNode;
        public int Count;

        public RBTree()
        {
            Count = 0;
        }

        public void Clear()
        {
            RootNode = SentinelNode;
            Count = 0;
        }

        public RBNode<TKey, TValue> GetNode(TKey key)
        {
            int result;
            if (LastFoundNode != SentinelNode)
            {
                result = key.CompareTo(LastFoundNode.Key);
                if (result == 0)
                {
                    return LastFoundNode;
                }
            }

            var treeNode = RootNode;

            while (treeNode != SentinelNode)
            {
                result = key.CompareTo(treeNode.Key);
                if (result == 0)
                {
                    LastFoundNode = treeNode;
                    return treeNode;
                }

                treeNode = result < 0 ? treeNode.Left : treeNode.Right;
            }

            return null;
        }

        public void Add(TKey key, TValue value)
        {
            New(key, value);
        }

        public bool Remove(TKey key)
        {
            var node = GetNode(key);

            if (node == null)
            {
                return false;
            }

            DeleteInternal(node);
            return true;
        }

        public RBNode<TKey, TValue> GetMinNode()
        {
            var currentNode = RootNode;

            if (currentNode == null || currentNode == SentinelNode)
            {
                throw new InvalidOperationException("RedBlackTree is empty.");
            }

            while (currentNode.Left != SentinelNode)
            {
                currentNode = currentNode.Left;
            }

            LastFoundNode = currentNode;

            return currentNode;
        }

        public RBNode<TKey, TValue> GetMaxNode()
        {
            var currentNode = RootNode;

            if (currentNode == null || currentNode == SentinelNode)
            {
                throw new InvalidOperationException("RedBlackTree is empty.");
            }

            while (currentNode.Right != SentinelNode)
            {
                currentNode = currentNode.Right;
            }

            LastFoundNode = currentNode;

            return currentNode;
        }

        public bool IsEmpty()
        {
            return RootNode == SentinelNode;
        }

        public bool RemoveMin()
        {
            if (RootNode == null)
            {
                return false;
            }

            DeleteInternal(GetMinNode());
            return true;
        }

        public bool RemoveMax()
        {
            if (RootNode == null)
            {
                return false;
            }

            DeleteInternal(GetMaxNode());
            return true;
        }

        public RBNode<TKey, TValue> GetNextLarger(RBNode<TKey, TValue> targetNode)
        {
            if (targetNode == SentinelNode)
            {
                return SentinelNode;
            }

            var next = targetNode.Right;

            if (targetNode.Right != SentinelNode)
            {
                while (next.Left != SentinelNode)
                {
                    next = next.Left;
                }

                return next;
            }

            next = targetNode;

            // ここはnull
            while (next.Parent != null)
            {
                if (next.Parent.Left == next)
                {
                    return next.Parent;
                }

                next = next.Parent;
            }

            return SentinelNode;
        }

        public RBNode<TKey, TValue> GetNextSmaller(RBNode<TKey, TValue> targetNode)
        {
            if (targetNode == SentinelNode)
            {
                return SentinelNode;
            }

            var next = targetNode.Left;

            if (targetNode.Left != SentinelNode)
            {
                while (next.Right != SentinelNode)
                {
                    next = next.Right;
                }

                return next;
            }

            next = targetNode;

            // ここはnull
            while (next.Parent != null)
            {
                if (next.Parent.Right == next)
                {
                    return next.Parent;
                }

                next = next.Parent;
            }

            return SentinelNode;
        }

        public enum RedBlackNodeType
        {
            Red = 0,
            Black = 1
        }

        private void New(TKey key, TValue data)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            var newNode = new RBNode<TKey, TValue>(key, data);

            var currentNode = RootNode;

            while (currentNode != SentinelNode)
            {
                newNode.Parent = currentNode;
                var result = key.CompareTo(currentNode.Key);
                if (result == 0)
                {
                    throw new InvalidOperationException($"RedBlackTree found same key {key}");
                }

                currentNode = result > 0 ? currentNode.Right : currentNode.Left;
            }

            if (newNode.Parent != null)
            {
                if (newNode.Key.CompareTo(newNode.Parent.Key) > 0)
                {
                    newNode.Parent.Right = newNode;
                }
                else
                {
                    newNode.Parent.Left = newNode;
                }
            }
            else
            {
                RootNode = newNode;
            }

            BalanceOnInsert(newNode);

            LastFoundNode = newNode;

            Count++;
        }

        private void DeleteInternal(RBNode<TKey, TValue> deleteNode)
        {
            RBNode<TKey, TValue> currentNode;

            if (deleteNode.Left == SentinelNode || deleteNode.Right == SentinelNode)
            {
                currentNode = deleteNode;
            }
            else
            {
                currentNode = deleteNode.Right;

                while (currentNode.Left != SentinelNode)
                {
                    currentNode = currentNode.Left;
                }
            }

            var linkedNode = currentNode.Left != SentinelNode
                ? currentNode.Left
                : currentNode.Right;

            linkedNode.Parent = currentNode.Parent;
            if (currentNode.Parent != null)
            {
                if (currentNode == currentNode.Parent.Left)
                {
                    currentNode.Parent.Left = linkedNode;
                }
                else
                {
                    currentNode.Parent.Right = linkedNode;
                }
            }
            else
            {
                RootNode = linkedNode;
            }

            if (currentNode != deleteNode)
            {
                deleteNode.Key = currentNode.Key;
                deleteNode.Data = currentNode.Data;
            }

            if (currentNode.Color == RedBlackNodeType.Black)
            {
                BalanceOnDelete(linkedNode);
            }

            LastFoundNode = SentinelNode;

            Count--;
        }

        private void BalanceOnDelete(RBNode<TKey, TValue> linkedNode)
        {
            while (linkedNode != RootNode && linkedNode.Color == RedBlackNodeType.Black)
            {
                RBNode<TKey, TValue> currentNode;

                if (linkedNode == linkedNode.Parent.Left)
                {
                    currentNode = linkedNode.Parent.Right;
                    if (currentNode.Color == RedBlackNodeType.Red)
                    {
                        linkedNode.Parent.Color = RedBlackNodeType.Red;
                        currentNode.Color = RedBlackNodeType.Black;
                        RotateLeft(linkedNode.Parent);
                        currentNode = linkedNode.Parent.Right;
                    }

                    if (currentNode.Left.Color == RedBlackNodeType.Black &&
                        currentNode.Right.Color == RedBlackNodeType.Black)
                    {
                        currentNode.Color = RedBlackNodeType.Red;
                        linkedNode = linkedNode.Parent;
                    }
                    else
                    {
                        if (currentNode.Right.Color == RedBlackNodeType.Black)
                        {
                            currentNode.Left.Color = RedBlackNodeType.Black;
                            currentNode.Color = RedBlackNodeType.Red;
                            RotateRight(currentNode);
                            currentNode = linkedNode.Parent.Right;
                        }

                        linkedNode.Parent.Color = RedBlackNodeType.Black;
                        currentNode.Color = linkedNode.Parent.Color;
                        currentNode.Right.Color = RedBlackNodeType.Black;
                        RotateLeft(linkedNode.Parent);
                        linkedNode = RootNode;
                    }
                }
                else
                {
                    currentNode = linkedNode.Parent.Left;
                    if (currentNode.Color == RedBlackNodeType.Red)
                    {
                        linkedNode.Parent.Color = RedBlackNodeType.Red;
                        currentNode.Color = RedBlackNodeType.Black;
                        RotateRight(linkedNode.Parent);
                        currentNode = linkedNode.Parent.Left;
                    }

                    if (currentNode.Right.Color == RedBlackNodeType.Black &&
                        currentNode.Left.Color == RedBlackNodeType.Black)
                    {
                        currentNode.Color = RedBlackNodeType.Red;
                        linkedNode = linkedNode.Parent;
                    }
                    else
                    {
                        if (currentNode.Left.Color == RedBlackNodeType.Black)
                        {
                            currentNode.Right.Color = RedBlackNodeType.Black;
                            currentNode.Color = RedBlackNodeType.Red;
                            RotateLeft(currentNode);
                            currentNode = linkedNode.Parent.Left;
                        }

                        currentNode.Color = linkedNode.Parent.Color;
                        linkedNode.Parent.Color = RedBlackNodeType.Black;
                        currentNode.Left.Color = RedBlackNodeType.Black;
                        RotateRight(linkedNode.Parent);
                        linkedNode = RootNode;
                    }
                }
            }

            linkedNode.Color = RedBlackNodeType.Black;
        }

        public Stack<RBNode<TKey, TValue>> GetAll()
        {
            var stack = new Stack<RBNode<TKey, TValue>>();

            if (RootNode != SentinelNode)
            {
                AddChildrenToStack(RootNode, stack);
            }

            return stack;
        }

        private static void AddChildrenToStack(RBNode<TKey, TValue> node, Stack<RBNode<TKey, TValue>> stack)
        {
            if (node.Right != SentinelNode)
            {
                AddChildrenToStack(node.Right, stack);
            }

            stack.Push(node);
            if (node.Left != SentinelNode)
            {
                AddChildrenToStack(node.Left, stack);
            }
        }

        private void RotateRight(RBNode<TKey, TValue> rotateNode)
        {
            var currentNode = rotateNode.Left;

            rotateNode.Left = currentNode.Right;

            if (currentNode.Right != SentinelNode)
            {
                currentNode.Right.Parent = rotateNode;
            }

            if (currentNode != SentinelNode)
            {
                currentNode.Parent = rotateNode.Parent;
            }

            if (rotateNode.Parent != null)
            {
                if (rotateNode == rotateNode.Parent.Right)
                {
                    rotateNode.Parent.Right = currentNode;
                }
                else
                {
                    rotateNode.Parent.Left = currentNode;
                }
            }
            else
            {
                RootNode = currentNode;
            }

            currentNode.Right = rotateNode;

            if (rotateNode != SentinelNode)
            {
                rotateNode.Parent = currentNode;
            }
        }

        private void RotateLeft(RBNode<TKey, TValue> rotateNode)
        {
            var currentNode = rotateNode.Right;

            rotateNode.Right = currentNode.Left;

            if (currentNode.Left != SentinelNode)
            {
                currentNode.Left.Parent = rotateNode;
            }

            if (currentNode != SentinelNode)
            {
                currentNode.Parent = rotateNode.Parent;
            }

            if (rotateNode.Parent != null)
            {
                if (rotateNode == rotateNode.Parent.Left)
                {
                    rotateNode.Parent.Left = currentNode;
                }
                else
                {
                    rotateNode.Parent.Right = currentNode;
                }
            }
            else
            {
                RootNode = currentNode;
            }

            currentNode.Left = rotateNode;

            if (rotateNode != SentinelNode)
            {
                rotateNode.Parent = currentNode;
            }
        }

        private void BalanceOnInsert(RBNode<TKey, TValue> addedNode)
        {
            while (addedNode != RootNode && addedNode.Parent.Color == RedBlackNodeType.Red)
            {
                RBNode<TKey, TValue> currentNode;
                if (addedNode.Parent == addedNode.Parent.Parent.Left)
                {
                    currentNode = addedNode.Parent.Parent.Right;
                    if (currentNode != null && currentNode.Color == RedBlackNodeType.Red)
                    {
                        addedNode.Parent.Color = RedBlackNodeType.Black;
                        currentNode.Color = RedBlackNodeType.Black;
                        addedNode.Parent.Parent.Color = RedBlackNodeType.Red;
                        addedNode = addedNode.Parent.Parent;
                    }
                    else
                    {
                        if (addedNode == addedNode.Parent.Right)
                        {
                            addedNode = addedNode.Parent;
                            RotateLeft(addedNode);
                        }

                        addedNode.Parent.Color = RedBlackNodeType.Black;
                        addedNode.Parent.Parent.Color = RedBlackNodeType.Red;
                        RotateRight(addedNode.Parent.Parent);
                    }
                }
                else
                {
                    currentNode = addedNode.Parent.Parent.Left;
                    if (currentNode != null && currentNode.Color == RedBlackNodeType.Red)
                    {
                        addedNode.Parent.Color = RedBlackNodeType.Black;
                        currentNode.Color = RedBlackNodeType.Black;
                        addedNode.Parent.Parent.Color = RedBlackNodeType.Red;
                        addedNode = addedNode.Parent.Parent;
                    }
                    else
                    {
                        if (addedNode == addedNode.Parent.Left)
                        {
                            addedNode = addedNode.Parent;
                            RotateRight(addedNode);
                        }

                        addedNode.Parent.Color = RedBlackNodeType.Black;
                        addedNode.Parent.Parent.Color = RedBlackNodeType.Red;
                        RotateLeft(addedNode.Parent.Parent);
                    }
                }
            }

            RootNode.Color = RedBlackNodeType.Black;
        }
    }


    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public partial class Program
    {
        public const int ModLarge = 1000000007;
    }

    public class ConsoleInput
    {
        private readonly TextReader _stream;
        private readonly char _separator = ' ';
        private readonly Queue<string> inputStream;

        public ConsoleInput(TextReader stream, char separator = ' ')
        {
            _separator = separator;
            _stream = stream;
            inputStream = new Queue<string>();
        }

        public string Read
        {
            get
            {
                if (inputStream.Count != 0)
                {
                    return inputStream.Dequeue();
                }

                var tmp = _stream.ReadLine().Split(_separator);
                for (var i = 0; i < tmp.Length; ++i)
                {
                    inputStream.Enqueue(tmp[i]);
                }

                return inputStream.Dequeue();
            }
        }

        public string ReadLine => _stream.ReadLine();
        public int ReadInt => int.Parse(Read);
        public long ReadLong => long.Parse(Read);
        public double ReadDouble => double.Parse(Read);

        public string[] ReadStrArray(long N)
        {
            var ret = new string[N];
            for (long i = 0; i < N; ++i)
            {
                ret[i] = Read;
            }

            return ret;
        }

        public int[] ReadIntArray(long N)
        {
            var ret = new int[N];
            for (long i = 0; i < N; ++i)
            {
                ret[i] = ReadInt;
            }

            return ret;
        }

        public long[] ReadLongArray(long N)
        {
            var ret = new long[N];
            for (long i = 0; i < N; ++i)
            {
                ret[i] = ReadLong;
            }

            return ret;
        }
    }

    public interface IConsole
    {
        void Flush();
        void Write(string str);
        void WriteLine(string str);
    }

    public class MyConsole : IConsole
    {
        public MyConsole()
        {
            var sw = new StreamWriter(Console.OpenStandardOutput()) {AutoFlush = false};
            Console.SetOut(sw);
        }

        public void Flush()
        {
            Console.Out.Flush();
        }

        public void Write(string str)
        {
            Console.Write(str);
        }

        public void WriteLine(string str)
        {
            Console.WriteLine(str);
        }
    }

#if UTAKA_LOCAL

    public class DebugConsole : IConsole
    {
        private readonly StringBuilder mSb;

        public DebugConsole()
        {
            mSb = new StringBuilder();
        }

        public void Flush()
        {
            // 何もしない
        }

        public void Write(string str)
        {
            mSb.Append(str);
        }

        public void WriteLine(string str)
        {
            mSb.AppendLine(str);
        }

        public string GetAllOutput()
        {
            return mSb.ToString();
        }
    }

#endif

#if UTAKA_LOCAL

    public class TestCaseCheckerForAtCoder
    {
        private string DirectoryPath => $"../../../../{Program.ContestName}/{Program.ProblemName}";

        private string GetInputFilePath(int testCaseNumber)
        {
            //return $"{DirectoryPath}/sample-{testCaseNumber}.in";
            return $"{DirectoryPath}/in_{testCaseNumber}.txt";
        }

        private string GetOutputFilePath(int testCaseNumber)
        {
            //return $"{DirectoryPath}/sample-{testCaseNumber}.out";
            return $"{DirectoryPath}/out_{testCaseNumber}.txt";
        }

        public bool TestProblem(int testCaseNumber)
        {
            var inputFilePath = GetInputFilePath(testCaseNumber);
            var outputFilePath = GetOutputFilePath(testCaseNumber);

            TextReader inputStream = new StreamReader(inputFilePath);

            var debugConsoleWriter = new DebugConsole();

            new Program().Solve(inputStream, debugConsoleWriter);

            var output = debugConsoleWriter.GetAllOutput();

            TextReader outputStream = new StreamReader(outputFilePath);
            var outputAnswer = outputStream.ReadToEnd();

            Dbg.WriteLine(output);
            Dbg.WriteLine(outputAnswer);

            var isCorrect = output == outputAnswer;

            return isCorrect;
        }

        public void TestProblems()
        {
            var isSuccessAll = true;

            var testCaseNumber = 1;
            while (true)
            {
                var inputFileName = GetInputFilePath(testCaseNumber);
                if (!File.Exists(inputFileName))
                {
                    break;
                }

                Console.WriteLine($"TestCase {testCaseNumber} =====================================================");

                var result = TestProblem(testCaseNumber);

                if (result)
                {
                    Console.WriteLine("Success");
                }
                else
                {
                    isSuccessAll = false;
                    Console.WriteLine("Failure *****");
                }

                testCaseNumber++;
            }

            if (isSuccessAll)
            {
                Console.WriteLine("!!!!!!!!! All Success !!!!!!!!!");
            }
        }
    }

#endif

#if UTAKA_LOCAL

    public static class Dbg
    {
        public static void WriteLine(string str)
        {
            Console.WriteLine(str);
        }

        public static void Write(string str)
        {
            Console.Write(str);
        }
    }
#else
    public static class Dbg
    {
        public static void WriteLine(string str)
        {
        }

        public static void Write(string str)
        {
        }
    }

#endif
}