Problem:
Score : 300 points

Problem Statement

2N players are running a competitive table tennis training on N tables numbered from 1 to N.

The training consists of rounds.
In each round, the players form N pairs, one pair per table.
In each pair, competitors play a match against each other.
As a result, one of them wins and the other one loses.

The winner of the match on table X plays on table X-1 in the next round,
except for the winner of the match on table 1 who stays at table 1.

Similarly, the loser of the match on table X plays on table X+1 in the next round,
except for the loser of the match on table N who stays at table N.

Two friends are playing their first round matches on distinct tables A and B.
Let's assume that the friends are strong enough to win or lose any match at will.
What is the smallest number of rounds after which the friends can get to play a match against each other?

Constraints

2 \leq N \leq 10^{18}

1 \leq A < B \leq N

All input values are integers.

Input

Input is given from Standard Input in the following format:

N A B

Output

Print the smallest number of rounds after which the friends can get to play a match against each other.

Sample Input 1

5 2 4

Sample Output 1

1

If the first friend loses their match and the second friend wins their match, they will both move to table 3 and play each other in the next round.

Sample Input 2

5 2 3

Sample Output 2

2

If both friends win two matches in a row, they will both move to table 1.

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

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;

class Myon

{
    public Myon() { }
    public static int Main()
    {
        cin = new Scanner();
        new Myon().calc();
        return 0;
    }
    static Scanner cin;


    int N, M, T;
    int[] x, y;

    void calc()
    {
        N = cin.nextInt();
        M = cin.nextInt();
        T = cin.nextInt();
        x = new int[M];
        y = new int[M];

        Random r = new Random();

        for (int i = 0; i < M; i++)
        {
            x[i] = cin.nextInt() - 1;
            y[i] = cin.nextInt() - 1;

            //x[i] = r.Next(3);
            //y[i] = (x[i] + 1 + r.Next(2)) % 3;
        }

        if (T == 1)
        {
            int TT = (N + 61) / 62;
            bool[] ok = new bool[N];
            for (int i = 0; i < N; i++)
            {
                ok[i] = true;
            }

            for (int i = 0; i < TT; i++)
            {
                long[] bit = new long[N];
                long mask = 0;
                for (int j = 0; j < 62; j++)
                {
                    int t = i * 62 + j;
                    if (t >= N) continue;
                    mask |= 1L << j;
                    bit[t] |= 1L << j;
                }

                for (int j = 0; j < M; j++)
                {
                    bit[x[j]] |= bit[y[j]];
                    bit[y[j]] = bit[x[j]];
                }

                for (int j = 0; j < N; j++)
                {
                    if (bit[j] != mask) ok[j] = false;
                }
            }

            for (int i = 0; i < N; i++)
            {
                if (ok[i])
                {
                    char[] ans = new char[M];
                    bool[] reach = new bool[N];
                    reach[i] = true;

                    for (int j = M - 1; j >= 0; j--)
                    {
                        if (reach[x[i]])
                        {
                            ans[j] = '^';
                            reach[y[i]] = reach[x[i]];
                        }
                        else
                        {
                            ans[j] = 'v';
                            reach[x[i]] = reach[y[i]];
                        }
                    }

                    bool check = true;
                    for (int j = 0; j < N; j++)
                    {
                        if (!reach[j]) throw new Exception("!?");
                    }

                    Console.WriteLine(ans);
                    return;
                }
            }
            Console.WriteLine("-1");
            return;

        }
        else if (T == 2)
        {
            if (N <= 2)
            {
                Console.WriteLine(-1);
            }
            else
            {
                t = new bool[M];
                dp = new bool[M, 8];
                if (dfs(0, 7))
                {
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < M; i++)
                    {
                        if (t[i]) sb.Append('^');
                        else sb.Append('v');
                    }
                    Console.WriteLine(sb.ToString());
                }
                else Console.WriteLine(-1);
            }
        }
    }

    bool[] t;
    bool[,] dp;
    bool dfs(int a, int flag)
    {
        if ((flag & (flag - 1)) == 0) return false;
        if (a == M)
        {
            return true;
        }
        if (dp[a, flag]) return false;
        dp[a, flag] = true;
        if (y[a] >= 3)
        {
            t[a] = true;
            return dfs(a + 1, flag);
        }
        else
        {
            t[a] = true;
            if (dfs(a + 1, (flag | (1 << x[a])) & (7 - (1 << y[a])))) return true;
            t[a] = false;
            if (dfs(a + 1, (flag | (1 << y[a])) & (7 - (1 << x[a])))) return true;
        }
        return false;
    }



}


class Scanner
{
    string[] s;
    int i;

    char[] cs = new char[] { ' ' };

    public Scanner()
    {
        s = new string[0];
        i = 0;
    }

    public string next()
    {
        if (i < s.Length) return s[i++];
        string st = Console.ReadLine();
        while (st == "") st = Console.ReadLine();
        s = st.Split(cs, StringSplitOptions.RemoveEmptyEntries);
        if (s.Length == 0) return next();
        i = 0;
        return s[i++];
    }

    public int nextInt()
    {
        return int.Parse(next());
    }
    public int[] ArrayInt(int N, int add = 0)
    {
        int[] Array = new int[N];
        for (int i = 0; i < N; i++)
        {
            Array[i] = nextInt() + add;
        }
        return Array;
    }

    public long nextLong()
    {
        return long.Parse(next());
    }

    public long[] ArrayLong(int N, long add = 0)
    {
        long[] Array = new long[N];
        for (int i = 0; i < N; i++)
        {
            Array[i] = nextLong() + add;
        }
        return Array;
    }

    public double nextDouble()
    {
        return double.Parse(next());
    }


    public double[] ArrayDouble(int N, double add = 0)
    {
        double[] Array = new double[N];
        for (int i = 0; i < N; i++)
        {
            Array[i] = nextDouble() + add;
        }
        return Array;
    }
}


class XRand
{
    uint x, y, z, w;


    public XRand()
    {
        init();
    }

    public XRand(uint s)
    {
        init();
        init_xor128(s);
    }

    void init()
    {
        x = 314159265; y = 358979323; z = 846264338; w = 327950288;

    }

    public void init_xor128(uint s)
    {
        z ^= s;
        z ^= z >> 21; z ^= z << 35; z ^= z >> 4;
        z *= 736338717;
    }

    uint next()
    {
        uint t = x ^ x << 11; x = y; y = z; z = w; return w = w ^ w >> 19 ^ t ^ t >> 8;
    }

    public long nextLong(long m)
    {
        return (long)((((ulong)next() << 32) + next()) % (ulong)m);
    }

    public int nextInt(int m)
    {
        return (int)(next() % m);
    }

    public int nextIntP(int a)
    {
        return (int)Math.Pow(a, nextDouble());
    }

    public int nextInt(int min, int max)
    {
        return min + nextInt(max - min + 1);
    }


    public double nextDouble()
    {
        return (double)next() / uint.MaxValue;
    }

    public double nextDoubleP(double a)
    {
        return Math.Pow(a, nextDouble());
    }
}