Problem:
Score : 700 points

Problem Statement

Takahashi and Aoki will play a game with a number line and some segments.
Takahashi is standing on the number line and he is initially at coordinate 0.
Aoki has N segments. The i-th segment is [L_i,R_i], that is, a segment consisting of points with coordinates between L_i and R_i (inclusive).

The game has N steps. The i-th step proceeds as follows:

First, Aoki chooses a segment that is still not chosen yet from the N segments and tells it to Takahashi.

Then, Takahashi walks along the number line to some point within the segment chosen by Aoki this time.

After N steps are performed, Takahashi will return to coordinate 0 and the game ends.

Let K be the total distance traveled by Takahashi throughout the game. Aoki will choose segments so that K will be as large as possible, and Takahashi walks along the line so that K will be as small as possible. What will be the value of K in the end?

Constraints

1 ≤ N ≤ 10^5

-10^5 ≤ L_i < R_i ≤ 10^5

L_i and R_i are integers.

Input

Input is given from Standard Input in the following format:

N
L_1 R_1
:
L_N R_N

Output

Print the total distance traveled by Takahashi throughout the game when Takahashi and Aoki acts as above.
It is guaranteed that K is always an integer when L_i,R_i are integers.

Sample Input 1

3
-5 1
3 7
-4 -2

Sample Output 1

10

One possible sequence of actions of Takahashi and Aoki is as follows:

Aoki chooses the first segment. Takahashi moves from coordinate 0 to -4, covering a distance of 4.

Aoki chooses the third segment. Takahashi stays at coordinate -4.

Aoki chooses the second segment. Takahashi moves from coordinate -4 to 3, covering a distance of 7.

Takahashi moves from coordinate 3 to 0, covering a distance of 3.

The distance covered by Takahashi here is 14 (because Takahashi didn't move optimally).
It turns out that if both players move optimally, the distance covered by Takahashi will be 10.

Sample Input 2

3
1 2
3 4
5 6

Sample Output 2

12

Sample Input 3

5
-2 0
-2 0
7 8
9 10
-2 -1

Sample Output 3

34

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

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

namespace AtCorder
{
	public class Program
	{
		const long MOD = 1000000007;
		static void Main(string[] args)
		{
			var cin = new Scanner2();
			int n = cin.Int();
			var lrs = new LR[n];
			for (int i = 0; i < n; i++) {
				long l = cin.Long();
				long r = cin.Long();
				lrs[i] = new LR(i, l, r);
			}

			var lp = new PriorityQueue<PriorityPair<long, LR>>(n);
			var rp = new PriorityQueue<PriorityPair<long, LR>>(n, true);
			for (int i = 0; i < n; i++) {
				lp.Enqueue(new PriorityPair<long, LR>(lrs[i].L, lrs[i]));
				rp.Enqueue(new PriorityPair<long, LR>(lrs[i].R, lrs[i]));
			}

			bool[] used = new bool[n];
			long ans = 0;
			long current = 0;
			bool lastLeft = true;
			for (int i = 0; i < n; i++) {
				LR nextL = lp.Top.Item;
				while (used[nextL.Index]) {
					lp.Dequeue();
					nextL = lp.Top.Item;
				}

				LR nextR = rp.Top.Item;
				while (used[nextR.Index]) {
					rp.Dequeue();
					nextR = rp.Top.Item;
				}

				if (nextL.L > current && nextR.R < current) {
					if (nextL.L - current == current - nextR.R) {
						if (lastLeft) {
							rp.Dequeue();
							used[nextR.Index] = true;
							ans += current - nextR.R;
							current = nextR.R;
							lastLeft = false;
						} else {
							lp.Dequeue();
							used[nextL.Index] = true;
							ans += nextL.L - current;
							current = nextL.L;
							lastLeft = true;
						}
					} else if (nextL.L - current > current - nextR.R) {
						lp.Dequeue();
						used[nextL.Index] = true;
						ans += nextL.L - current;
						current = nextL.L;
						lastLeft = true;
					} else {
						rp.Dequeue();
						used[nextR.Index] = true;
						ans += current - nextR.R;
						current = nextR.R;
						lastLeft = false;
					}
				} else if (nextL.L > current) {
					lp.Dequeue();
					used[nextL.Index] = true;
					ans += nextL.L - current;
					current = nextL.L;
					lastLeft = true;
				} else if (nextR.R < current) {
					rp.Dequeue();
					used[nextR.Index] = true;
					ans += current - nextR.R;
					current = nextR.R;
					lastLeft = false;
				} else {
					if (lastLeft) {
						rp.Dequeue();
						used[nextR.Index] = true;
						lastLeft = false;
					} else {
						lp.Dequeue();
						used[nextL.Index] = true;
						lastLeft = true;
					}
				}
			}

			ans += Math.Abs(current);
			Console.WriteLine(ans);
		}
	}

	public struct LR
	{
		public LR(int index, long l, long r)
		{
			Index = index;
			L = l;
			R = r;
		}

		public int Index { get; set; }

		public long L { get; set; }
		public long R { get; set; }
	}

	public class PriorityQueue<T>
	{
		private readonly List<T> heap_;
		private readonly Comparison<T> comparison_;
		private readonly bool reverses_;

		public T Top => heap_[0];
		public int Count => heap_.Count;

		public PriorityQueue(bool reverses = false)
			: this(Comparer<T>.Default, reverses) { }

		public PriorityQueue(int capacity, bool reverses = false)
			: this(capacity, Comparer<T>.Default.Compare, reverses) { }

		public PriorityQueue(IComparer<T> comparer, bool reverses = false)
			: this(16, comparer.Compare, reverses) { }

		public PriorityQueue(Comparison<T> comparison, bool reverses = false)
			: this(16, comparison, reverses) { }

		public PriorityQueue(
			int capacity,
			Comparison<T> comparison,
			bool reverses = false)
		{
			heap_ = new List<T>(capacity);
			comparison_ = comparison;
			reverses_ = reverses;
		}

		public void Enqueue(T item)
		{
			int c = heap_.Count;
			heap_.Add(item);
			while (c > 0) {
				int p = (c - 1) >> 1;
				if (Compare(p, c) < 0) {
					Swap(p, c);
				} else {
					break;
				}

				c = p;
			}
		}

		public T Dequeue()
		{
			T ret = heap_[0];
			int n = heap_.Count - 1;

			heap_[0] = heap_[n];
			heap_.RemoveAt(n);
			for (int p = 0, c; (c = (p << 1) + 1) < n; p = c) {
				if (c != n - 1 && Compare(c + 1, c) > 0) {
					++c;
				}

				if (Compare(p, c) < 0) {
					Swap(p, c);
				} else {
					break;
				}
			}

			return ret;
		}

		private int Compare(int x, int y)
			=> comparison_(heap_[x], heap_[y]) * (reverses_ ? -1 : 1);

		private void Swap(int x, int y)
		{
			var t = heap_[x];
			heap_[x] = heap_[y];
			heap_[y] = t;
		}
	}

	public struct PriorityPair<T, U> : IComparable<PriorityPair<T, U>>
			where T : IComparable<T>
	{
		public T Priority { get; set; }
		public U Item { get; set; }

		public PriorityPair(T priority, U item)
		{
			Priority = priority;
			Item = item;
		}

		public int CompareTo(PriorityPair<T, U> target)
			=> Priority.CompareTo(target.Priority);

		public override string ToString()
			=> $"{Priority} {Item}";
	}

	public class Scanner2
	{
		private readonly char[] delimiter_ = new char[] { ' ' };
		private readonly string filePath_;
		private string[] buf_;
		private int index_;
		Func<string> reader_;

		public Scanner2(string file = "")
		{
			if (string.IsNullOrWhiteSpace(file)) {
				reader_ = Console.ReadLine;
			} else {
				filePath_ = file;
				var fs = new StreamReader(file);
				reader_ = fs.ReadLine;
			}
			buf_ = new string[0];
			index_ = 0;
		}

		public string Next()
		{
			if (index_ < buf_.Length) {
				return buf_[index_++];
			}

			string st = reader_();
			while (st == "") {
				st = reader_();
			}

			buf_ = st.Split(delimiter_, StringSplitOptions.RemoveEmptyEntries);
			if (buf_.Length == 0) {
				return Next();
			}

			index_ = 0;
			return buf_[index_++];
		}

		public int Int() => int.Parse(Next());
		public long Long() => long.Parse(Next());
		public double Double() => double.Parse(Next());

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

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

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

		public void Save(string text)
		{
			if (string.IsNullOrWhiteSpace(filePath_)) {
				return;
			}

			File.WriteAllText(filePath_ + "_output.txt", text);
		}
	}
}