Problem:
Score : 600 points

Problem Statement

Snuke has an integer sequence, a, of length N. The i-th element of a (1-indexed) is a_{i}.

He can perform the following operation any number of times:

Operation: Choose integers x and y between 1 and N (inclusive), and add a_x to a_y.

He would like to perform this operation between 0 and 2N times (inclusive) so that a satisfies the condition below. Show one such sequence of operations.
It can be proved that such a sequence of operations always exists under the constraints in this problem.

Condition: a_1 \leq a_2 \leq ... \leq a_{N}

Constraints

2 \leq N \leq 50

-10^{6} \leq a_i \leq 10^{6}

All input values are integers.

Input

Input is given from Standard Input in the following format:

N
a_1 a_2 ... a_{N}

Output

Let m be the number of operations in your solution. In the first line, print m.
In the i-th of the subsequent m lines, print the numbers x and y chosen in the i-th operation, with a space in between.
The output will be considered correct if m is between 0 and 2N (inclusive) and a satisfies the condition after the m operations.

Sample Input 1

3
-2 5 -1

Sample Output 1

2
2 3
3 3

After the first operation, a = (-2,5,4).

After the second operation, a = (-2,5,8), and the condition is now satisfied.

Sample Input 2

2
-1 -3

Sample Output 2

1
2 1

After the first operation, a = (-4,-3) and the condition is now satisfied.

Sample Input 3

5
0 0 0 0 0

Sample Output 3

0

The condition is satisfied already in the beginning.

Solution in C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

public static class TemplateExtension
{
    public static X[] MakeArray<X>(this int count, Func<int, X> func)
    {
        var xs = new X[count];
        for (var i = 0; i < count; i++)
        {
            xs[i] = func(i);
        }
        return xs;
    }

    public static int[] Range(this int count, int start = 0)
    {
        return count.MakeArray(i => i + start);
    }

    public static string Intercalate<X>(this IEnumerable<X> @this, string separator)
    {
        return string.Join(separator, @this);
    }

    public sealed class ValueIndexPair<T>
        : Tuple<T, int>
    {
        public T Value { get { return Item1; } }
        public int Index { get { return Item2; } }

        public ValueIndexPair(T value, int index)
            : base(value, index)
        {
        }
    }

    public static IEnumerable<ValueIndexPair<X>> Indexed<X>(this IEnumerable<X> @this)
    {
        var i = 0;
        foreach (var x in @this)
        {
            yield return new ValueIndexPair<X>(x, i);
            i++;
        }
    }
}

public sealed class Scanner
{
    private readonly TextReader _reader;
    private readonly StringBuilder _sb = new StringBuilder();

    /// <summary>
    /// Reads next word separated by spaces.
    /// </summary>
    public string Word()
    {
        _sb.Clear();

        while (true)
        {
            var r = _reader.Read();

            if (r == '\r')
            {
                if (_reader.Peek() == '\n') _reader.Read();
                break;
            }
            else if (r == -1 || r == ' ' || r == '\n')
            {
                break;
            }
            else
            {
                _sb.Append((char)r);
            }
        }

        return _sb.ToString();
    }

    /// <summary>
    /// Reads next word as <see cref="int"/>.
    /// </summary>
    public int N()
    {
        return int.Parse(Word());
    }

    /// <summary>
    /// Reads next word as <see cref="long"/>.
    /// </summary>
    public long L()
    {
        return long.Parse(Word());
    }

    /// <summary>
    /// Reads next word as <see cref="double"/>.
    /// </summary>
    public double F()
    {
        return double.Parse(Word());
    }

    public int[] Ns(int count)
    {
        return count.MakeArray(_ => N());
    }

    public long[] Ls(int count)
    {
        return count.MakeArray(_ => L());
    }

    public double[] Fs(int count)
    {
        return count.MakeArray(_ => F());
    }

    /// <summary>
    /// Reads next line and splits it by spaces.
    /// </summary>
    public X[] Words<X>(Func<string, X> func)
    {
        return _reader.ReadLine().Split(' ').Select(func).ToArray();
    }

    public Scanner(TextReader reader)
    {
        _reader = reader;
    }
}

public partial class Program
{
    private readonly TextReader _input;
    private readonly TextWriter _output;
    private readonly Scanner _scanner;

    private void WriteLine(int value)
    {
        _output.WriteLine(value);
    }

    private void WriteLine(long value)
    {
        _output.WriteLine(value);
    }

    private void WriteLine(double value)
    {
        _output.WriteLine(value);
    }

    private void WriteLine(char value)
    {
        _output.WriteLine(value);
    }

    private void WriteLine(string value)
    {
        _output.WriteLine(value);
    }

    public Program(TextReader input, TextWriter output)
    {
        _input = input;
        _output = output;
        _scanner = new Scanner(input);
    }

    public static void Main(string[] args)
    {
        new Program(Console.In, Console.Out).EntryPoint();
    }
}

public sealed class Solver
{
    bool IsSorted(long[] xs)
    {
        for (var i = 0; i < xs.Length - 1; i++)
        {
            if (xs[i] > xs[i + 1])
            {
                return false;
            }
        }

        return true;
    }

    Tuple<int, int>[] SolveCore(long[] xs, int maxIndex)
    {
        var n = xs.Length;
        var instr = new List<Tuple<int, int>>();
        var max = xs[maxIndex];

        var i = 0;

        while (i + 1 < n && instr.Count <= n * 2)
        {
            if (xs[i] <= xs[i + 1])
            {
                i++;
                continue;
            }

            if (xs[i] <= xs[i + 1] + max)
            {
                i++;
                instr.Add(Tuple.Create(maxIndex, i));
                continue;
            }

            xs[n - 1] += max;
            instr.Add(Tuple.Create(maxIndex, n - 1));

            if (max < xs[n - 1])
            {
                maxIndex = n - 1;
                max = xs[maxIndex];
            }

            continue;
        }

        return instr.ToArray();
    }

    public Tuple<int, int>[] Solve(long[] xs)
    {
        var maxAbs = -1L;
        var index = 0;
        for (var i = 0; i < xs.Length; i++)
        {
            var a = Math.Abs(xs[i]);
            if (maxAbs < a)
            {
                maxAbs = a;
                index = i;
            }
        }

        if (xs[index] < 0)
        {
            var n = xs.Length;
            var ys = xs.Select(x => -x).Reverse().ToArray();
            var instr = SolveCore(ys, n - index - 1);
            return instr.Select(t => Tuple.Create(n - t.Item1 - 1, n - t.Item2 - 1)).ToArray();
        }
        else
        {
            return SolveCore(xs, index);
        }
    }

    public void VerifyRandomly()
    {
        var rng = new Random();
        var xl = -1000000;
        var xr = 1000000 + 1;

        for (var n = 2; n <= 50; n++)
        {
            Console.WriteLine("n = " + n);

            for (var r = 0; r < 10000; r++)
            {
                var xs = n.MakeArray(i => (long)rng.Next(xl, xr));
                var instr = Solve(xs);

                if (instr.Length > n * 2)
                {
                    Console.WriteLine("Couldn't solve: " + xs.Intercalate(", "));
                }
            }
        }
    }
}

public sealed partial class Program
{
    int N;
    int[] A;

    private long Solve()
    {
        return 0;
    }

    private void Read()
    {
        var a = _scanner;
        N = a.N();
        A = N.MakeArray(i => a.N());
    }

    public void EntryPoint()
    {
        //new Solver().VerifyRandomly();

        Read();

        var solver = new Solver();
        var instr = solver.Solve(A.Select(x => (long)x).ToArray());

        WriteLine(instr.Length);
        foreach (var t in instr)
        {
            WriteLine(string.Format("{0} {1}", t.Item1 + 1, t.Item2 + 1));
        }
    }
}