Problem:
Score : 200 points

Problem Statement

We have a sequence p = {p_1,\ p_2,\ ...,\ p_N} which is a permutation of {1,\ 2,\ ...,\ N}.

You can perform the following operation at most once: choose integers i and j (1 \leq i < j \leq N), and swap p_i and p_j. Note that you can also choose not to perform it.

Print YES if you can sort p in ascending order in this way, and NO otherwise.

Constraints

All values in input are integers.

2 \leq N \leq 50

p is a permutation of {1,\ 2,\ ...,\ N}.

Input

Input is given from Standard Input in the following format:

N
p_1 p_2 ... p_N

Output

Print YES if you can sort p in ascending order in the way stated in the problem statement, and NO otherwise.

Sample Input 1

5
5 2 3 4 1

Sample Output 1

YES

You can sort p in ascending order by swapping p_1 and p_5.

Sample Input 2

5
2 4 3 5 1

Sample Output 2

NO

In this case, swapping any two elements does not sort p in ascending order.

Sample Input 3

7
1 2 3 4 5 6 7

Sample Output 3

YES

p is already sorted in ascending order, so no operation is needed.

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

using System;

namespace _0or1Swap
{

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Linq;
    using System.Threading.Tasks;
    using System.IO;
    using static System.Console;
    using RamType0;
    using RamType0.Math;
    using RamType0.Sorting;
    using RamType0.Collections;
    using static RamType0.Commons;

    using static RamType0.CompetitiveProgramming.StandardIOHelper;
    namespace RamType0
    {
        public static class BasicExtensions
        {
            /// <summary>
            /// 文字列をInt32に変換します。
            /// </summary>
            /// <param name="str"></param>
            /// <returns></returns>
            public static int ParseToInt(this string str) => int.Parse(str);
        }
        public static class Commons
        {
            /// <summary>
            /// aとbの中身を入れ替えます。
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="a"></param>
            /// <param name="b"></param>
            public static void Swap<T>(ref T a, ref T b)
            {
                var temp = a;
                a = b;
                b = temp;
            }
        }
        namespace Collections
        {
            public class PriorityQueue<T>
            {
                readonly List<T> heap;
                readonly Comparison<T> priorityCompare;
                public PriorityQueue()
                {
                    heap = new List<T>();
                    priorityCompare = Comparer<T>.Default.Compare;
                }
                public PriorityQueue(int capacity)
                {
                    heap = new List<T>(capacity);
                    priorityCompare = Comparer<T>.Default.Compare;
                }
                public PriorityQueue(Comparison<T> compare)
                {
                    heap = new List<T>();
                    this.priorityCompare = compare;
                }
                public PriorityQueue(Comparison<T> compare, int capacity)
                {
                    heap = new List<T>(capacity);
                    priorityCompare = compare;
                }


                public void Enqueue(T element)
                {
                    var newElemIndex = heap.Count;
                    heap.Add(element);
                    while (newElemIndex != 0)
                    {
                        int parentIndex = (newElemIndex - 1) / 2;
                        var parent = heap[parentIndex];
                        // 親と値を入れ替え
                        if (priorityCompare(element, parent) > 0)
                        {
                            break;
                        }
                        heap[newElemIndex] = parent;

                        newElemIndex = parentIndex;
                    }
                    heap[newElemIndex] = element;
                }
                public T Dequeue()
                {
                    try
                    {
                        var ret = heap[0];
                        var pos = 0;
                        var x = heap[heap.Count - 1];

                        while (pos * 2 + 1 < heap.Count - 1)
                        {
                            var lch = pos * 2 + 1;
                            var rch = pos * 2 + 2;
                            if (rch < heap.Count - 1 && priorityCompare(heap[rch], heap[lch]) < 0) lch = rch;
                            if (priorityCompare(heap[lch], x) >= 0)
                                break;
                            heap[pos] = heap[lch];
                            pos = lch;
                        }
                        heap[pos] = x;
                        heap.RemoveAt(heap.Count - 1);
                        return ret;
                    }
                    catch (IndexOutOfRangeException ex)
                    {
                        throw new InvalidOperationException("Queue is empty.", ex);
                    }
                }
                public bool TryDequeue(out T element)
                {
                    if (heap.Count > 0)
                    {
                        element = Dequeue();
                        return true;
                    }
                    else
                    {
                        element = default(T);
                        return false;
                    }
                }
            }
        }
        namespace Sorting
        {
            public static class HeapSortExtension
            {
                /// <summary>
                /// 常にO(NlogN)なソート。
                /// </summary>
                /// <typeparam name="T"></typeparam>
                /// <param name="array"></param>
                public static void HeapSort<T>(this T[] array)
                where T : IComparable<T>
                {
                    for (int i = 1; i < array.Length; ++i)
                    {
                        CreateHeap(array, i);
                    }

                    for (int i = array.Length - 1; i >= 0; --i)
                    {
                        array[i] = Max(array, i);
                    }
                }


                static void CreateHeap<T>(T[] array, int elements)
                  where T : IComparable<T>
                {
                    while (elements != 0)
                    {
                        int i = (elements - 1) / 2;
                        //ref var lastElement = ref array[elements];
                        //ref var I = ref array[i];
                        if (array[elements].CompareTo(array[i]) > 0)
                        {
                            Swap(ref array[elements], ref array[i]);
                        }

                        elements = i;
                    }
                }
                static T Max<T>(T[] array, int lastElementIndex)
                  where T : IComparable<T>
                {
                    //var lastElementIndex = elements - 1;
                    var max = array[0];

                    array[0] = array[lastElementIndex];

                    for (int i = 0, j; (j = 2 * i + 1) < lastElementIndex;)
                    {

                        if ((j != lastElementIndex - 1) && (array[j].CompareTo(array[j + 1]) < 0))
                        {
                            j++;
                        }

                        if (array[i].CompareTo(array[j]) < 0)
                        {
                            //ref var J = ref array[j];
                            //ref var I = ref array[i];
                            Swap(ref array[i], ref array[j]);
                        }

                        i = j;
                    }

                    return max;
                }
            }
            public static class QuickSortExtension
            {
                /// <summary>
                /// 最悪の場合はO(n^2)だが大体の場合O(NlogN)となり最も高速と言われるソート。
                /// </summary>
                /// <typeparam name="T"></typeparam>
                /// <param name="array"></param>
                public static void QuickSort<T>(this T[] array)
                {
                    Array.Sort(array);
                }
            }
        }
        namespace CompetitiveProgramming
        {
            public static class StandardIOHelper
            {
                static string[] lineArgs = new string[0];
                static int currentLineArgsIndex = 0;
                public static string NextArg
                {
                    get
                    {


                    ReadLineArg:
                        if ((uint)currentLineArgsIndex < lineArgs.Length)
                        {
                            return lineArgs[currentLineArgsIndex++];
                        }
                        else
                        {
                            lineArgs = ReadLine().Split(' ');
                            currentLineArgsIndex = 0;
                            goto ReadLineArg;
                        }
                    }
                }


            }
        }

        namespace Math
        {
            using Math = System.Math;
            /// <summary>
            /// 場合の数を計算するクラス。
            /// </summary>
            public static class Patterns
            {
                /// <summary>
                /// n個の場所に対して同じものをr個配置する場合の配置パターン数。
                /// </summary>
                /// <param name="n"></param>
                /// <param name="r"></param>
                /// <returns></returns>
                public static int nCr(int n, int r)
                {
                    return nPr(n, r) / r.Fact();
                }
                /// <summary>
                /// n種類の要素をr個だけ配置する場合のパターン数。
                /// </summary>
                /// <param name="n"></param>
                /// <param name="r"></param>
                /// <returns></returns>
                public static int nPr(int n, int r)
                {
                    var ret = 1;
                    for (var i = n - r + 1; i <= n; i++)
                    {
                        ret *= i;
                    }
                    return ret;
                }
            }
            /// <summary>
            /// 数値型に対する数学的操作を提供する拡張クラス。
            /// </summary>
            public static class Extensions
            {
                public static int Pow(this int num, int pows)
                {

                    int ret = 1;
                    for (int i = 0; i < pows; i++)
                    {
                        ret *= num;
                    }
                    return ret;

                }
                public static int Fact(this int num)
                {
                    var ret = 1;
                    for (var i = 2; i <= num; i++)
                    {
                        ret *= i;
                    }
                    return ret;
                }

            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            WriteLine(Calc() ? "YES" : "NO");
        }

        private static bool Calc()
        {
            var n = NextArg.ParseToInt();
            var p = new int[n];
            for (int i = 0; i < p.Length; i++)
            {
                p[i] = NextArg.ParseToInt();
            }

            var target = Enumerable.Range(1, n).ToArray();
            var diffrentIndex = (int?)null;
            for (int i = 0; i < p.Length; i++)
            {
                if (p[i] != target[i])
                {
                    diffrentIndex = i;
                    break;
                }
            }
            if (diffrentIndex.HasValue)
            {
                var swap = diffrentIndex.Value;
                for (int i = swap + 1; i < p.Length; i++)
                {
                    if (p[i] != target[i])
                    {
                        
                        if(p[i]== target[swap] && p[swap] == target[i])
                        {
                            for (int m = i+1; m < p.Length; m++)
                            {
                                if (p[m] != target[m])
                                {
                                    return false;
                                }
                            }
                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    }
                }
                return false;
            }
            else
            {
                return true;
            }
        }
    }
}