Problem:
Score : 800 points

Problem Statement

Niwango has N cards, numbered 1,2,\ldots,N.
He will now arrange these cards in a row.

Niwango wants to know if there is a way to arrange the cards while satisfying all the N conditions below.
To help him, determine whether such a way exists. If the answer is yes, also find the lexicographically smallest such arrangement.

To the immediate right of Card 1 (if any) is NOT Card a_1.

To the immediate right of Card 2 (if any) is NOT Card a_2.

\vdots

To the immediate right of Card N (if any) is NOT Card a_N.

Constraints

2 \leq N \leq 10^{5}

1 \leq a_i \leq N

a_i \neq i

Input

Input is given from Standard Input in the following format:

N
a_1 a_2 \ldots a_N

Output

If no arrangements satisfy the conditions, print -1. If such arrangements exist, print the lexicographically smallest such arrangement, in the following format:

b_1 b_2 \ldots b_N

Here, b_i represents the i-th card from the left.

Sample Input 1

4
2 3 4 1

Sample Output 1

1 3 2 4

The arrangement (1,2,3,4) is lexicographically smaller than (1,3,2,4), but is invalid, since it violates the condition "to the immediate right of Card 1 is not Card 2."

Sample Input 2

2
2 1

Sample Output 2

-1

If no arrangements satisfy the conditions, print -1.

Sample Input 3

13
2 3 4 5 6 7 8 9 10 11 12 13 12

Sample Output 3

1 3 2 4 6 5 7 9 8 10 12 11 13

Solution in C# (Mono 4.6.2.0) (judge verdict: Runtime Error)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using MethodImplAttribute = System.Runtime.CompilerServices.MethodImplAttribute;
using MethodImplOptions = System.Runtime.CompilerServices.MethodImplOptions;

public static class P
{
    public static void Main()
    {
        int n = int.Parse(Console.ReadLine());
        var hate = Console.ReadLine().Split().Select(x => int.Parse(x) - 1).ToArray();
        if (n == 2)
        {
            Console.WriteLine(-1);
            return;
        }
        //残り全員に嫌われているカードがあれば組み込む
        //サイクリックヤバがあれば組み込む
        //嫌われを組み込むことでサイクリックが解決不能になることはあるか
        //ない:ある場合はサイクリックを組み込める
        SortedSet<int> _cyclic = new SortedSet<int>();
        int[] hatedCount = new int[n];
        for (int i = 0; i < n; i++)
        {
            hatedCount[hate[i]]++;
            if (hate[hate[i]] == i && i < hate[i])
            {
                _cyclic.Add(i);
                _cyclic.Add(hate[i]);
            }
        }
        
        HashSet<int>[] hateds = Enumerable.Range(0, n + 1).Select(_ => new HashSet<int>()).ToArray();
        for (int i = 0; i < n; i++)
            hateds[hatedCount[i]].Add(i);

        bool[] added = new bool[n];
        int prevHated = -1;
        List<int> res = new List<int>();
        int nextTop = 0;
        Action<int> add = x =>
        {
            res.Add(x);
            added[x] = true;
            hateds[hatedCount[x]].Remove(x);
            hatedCount[x] = -1;
            prevHated = hate[x];
            if (nextTop == x) nextTop++;

            var xHate = hate[x];
            if (0 <= hatedCount[xHate])
            {
                hateds[hatedCount[xHate]].Remove(xHate);
                hatedCount[xHate]--;
                hateds[hatedCount[xHate]].Add(xHate);
            }

            if (x == hate[hate[x]])
            {
                _cyclic.Remove(x);
                _cyclic.Remove(hate[x]);
            }
        };

        for (int i = 0; i < n; i++)
        {
            int remainCount = n - i;
            if (hateds[remainCount].Count != 0)
            {
                var target = hateds[remainCount].First();
                add(target);
                continue;
            }
            if (remainCount != 1 && remainCount - 1 <= _cyclic.Count)
            {
                var min = _cyclic.Min;
                if (min == prevHated)
                {
                    _cyclic.Remove(min);
                    var anotherMin = _cyclic.Min;
                    add(anotherMin);
                    if (hate[anotherMin] != min) _cyclic.Add(min);
                }
                else
                {
                    add(min);
                }
                continue;
            }
            var cand = nextTop;
            while (added[cand] || prevHated == cand) cand++;
            add(cand);
        }
        Console.WriteLine(string.Join(" ", res.Select(x => x + 1)));
    }
}

public struct Pair : IEquatable<Pair>
{
    public int A;
    public int B;
    public Pair(int a, int b)
    {
        if (a < b) { A = b; B = a; }
        else { A = a; B = b; }
    }

    public bool Equals(Pair other) => A == other.A && B == other.B;
    public override int GetHashCode() => A * B;
}