Let's define the sum of two permutations p and q of numbers 0, 1, ..., (n - 1) as permutation <image>, where Perm(x) is the x-th lexicographically permutation of numbers 0, 1, ..., (n - 1) (counting from zero), and Ord(p) is the number of permutation p in the lexicographical order.

For example, Perm(0) = (0, 1, ..., n - 2, n - 1), Perm(n! - 1) = (n - 1, n - 2, ..., 1, 0)

Misha has two permutations, p and q. Your task is to find their sum.

Permutation a = (a0, a1, ..., an - 1) is called to be lexicographically smaller than permutation b = (b0, b1, ..., bn - 1), if for some k following conditions hold: a0 = b0, a1 = b1, ..., ak - 1 = bk - 1, ak < bk.

Input

The first line contains an integer n (1 ≤ n ≤ 200 000).

The second line contains n distinct integers from 0 to n - 1, separated by a space, forming permutation p.

The third line contains n distinct integers from 0 to n - 1, separated by spaces, forming permutation q.

Output

Print n distinct integers from 0 to n - 1, forming the sum of the given permutations. Separate the numbers by spaces.

Examples

Input

2
0 1
0 1


Output

0 1


Input

2
0 1
1 0


Output

1 0


Input

3
1 2 0
2 1 0


Output

1 0 2

Note

Permutations of numbers from 0 to 1 in the lexicographical order: (0, 1), (1, 0).

In the first sample Ord(p) = 0 and Ord(q) = 0, so the answer is <image>.

In the second sample Ord(p) = 0 and Ord(q) = 1, so the answer is <image>.

Permutations of numbers from 0 to 2 in the lexicographical order: (0, 1, 2), (0, 2, 1), (1, 0, 2), (1, 2, 0), (2, 0, 1), (2, 1, 0).

In the third sample Ord(p) = 3 and Ord(q) = 5, so the answer is <image>.
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.Random;

/*

2
0 1
0 1

2
0 1
1 0

3
1 2 0
2 1 0

 */

public class d {

	
	public static void main(String[] args) 
	{
		//gen();
		
		go();
	}
	
	static void go()
	{
		FastScanner in = new FastScanner();
		
		int n = in.nextInt();
		
		int[] array1 = new int[n];
		int[] array2 = new int[n];
		
		for(int curr = 0; curr < n; ++curr)
		{
			array1[curr] = in.nextInt();
		}
		
		for(int curr = 0; curr < n; ++curr)
		{
			array2[curr] = in.nextInt();
		}
		
		solve(n, array1, array2);
	}
	
	static void solve(int n, int[] array1, int[] array2)
	{
		int[] array3 = getPerm( add( ordinal(array1), ordinal(array2)));
		
		PrintWriter out = new PrintWriter(System.out);
		for(int curr: array3)
		{
			out.print(curr +" ");
		}
		out.println();
		
		out.close();
	}
	
	static int[] ordinal(int[] array)
	{
		int n = array.length;
		BIT bit = new BIT(n);
		int[] ret = new int[n];
		
		for(int curr = n-1; curr >= 0; --curr)
		{
			ret[curr] = bit.read(array[curr]+1);
			bit.update(array[curr]+1, 1);
		}
		
		//System.out.println(Arrays.toString(ret));
		
		return ret;
	}
	
	static int[] add(int[] array1, int[] array2)
	{
		int n = array1.length;
		int[] ret = new int[n];
		
		int carry = 0;
		
		for(int curr = n-1; curr >= 0; --curr)
		{
			ret[curr] = array1[curr] + array2[curr] + carry;
			
			carry = ret[curr] / (n-curr);
			ret[curr] = ret[curr] % (n-curr);
		}
		
		//System.out.println(Arrays.toString(ret));
		
		return ret;
	}
	
	static int[] getPerm(int[] array)
	{
		int n = array.length;
		int[] ret = new int[n];
		
		SegmentTree tree = new SegmentTree(n);
		
		for(int curr = 0; curr < n; ++curr)
		{
			ret[curr] = tree.query(array[curr]);
			tree.clear(ret[curr]);
		}
		
		//System.out.println(Arrays.toString(ret));
		
		return ret;
	}
	
	
	static void gen()
	{
		int n = 200000;
		
		Random rand = new Random();
		int[] array1 = new int[n];
		int[] array2 = new int[n];
		
		for(int curr = 0; curr < n; ++curr)
		{
			array1[curr] = curr;
			array2[curr] = curr;
		}
		
		for(int curr = 0; curr < n; ++curr)
		{
			int i1 = rand.nextInt(n);
			int i2 = rand.nextInt(n);
			
			int temp = array1[i1];
			array1[i1] = array1[i2];
			array1[i2] = temp;
		}
		
		for(int curr = 0; curr < n; ++curr)
		{
			int i1 = rand.nextInt(n);
			int i2 = rand.nextInt(n);
			
			int temp = array2[i1];
			array2[i1] = array2[i2];
			array2[i2] = temp;
		}
		
		System.out.println("Gen");
		
		solve(n, array1, array2);
	}
	
	static class BIT {

		int n;
		int[] tree;
		
		BIT(int n)
		{
			this.n = n;
			tree = new int[2*n+1];
		}
		
		int read(int index)
		{
			int sum = 0;
			while (index > 0)
			{
				sum += tree[index];
				index -= (index & -index);
			}
			return sum;
		}
		
		void update(int index ,int val){
			while (index <= n){
				tree[index] += val;
				index += (index & -index);
			}
		}
	}
	
	
	static class SegmentTree {

		class Node
		{
			int value;
			
			int rl;
			int rr;
			
			Node left;
			Node right;
			
			Node(int rangeL, int rangeR)
			{
				rl = rangeL;
				rr = rangeR;
				
				if(rangeL != rangeR)
				{
					int mid = (rangeR + rangeL)/2;
					left = new Node(rangeL, mid);
					right = new Node(mid+1, rangeR);
					
					value = left.value + right.value;
				}
				else
				{
					value = 1;
				}
			}
			
			void clear(int index)
			{
				if(rl  == rr)
				{
					value = 0;
				}
				else
				{
					int mid = (rr + rl)/2;
					if(index <= mid)
						left.clear(index);
					else
						right.clear(index);
					
					value = right.value + left.value;
				}
			}
			
			int query(int key)
			{
				if(rl == rr)
				{
					return rl;
				}
				else
				{
					if(left.value > key)
						return left.query(key);
					else
						return right.query(key - left.value);
				}
			}
		}
		
		int size;
		Node root;
		
		public SegmentTree(int n)
		{
			size = n;
			root = new Node(0, n-1);
		}
		
		void clear(int index)
		{
			root.clear(index);
		}
		
		int query(int key)
		{
			return root.query(key);
		}
	}
}

class FastScanner{
	   private InputStream stream;
	   private byte[] buf = new byte[1024];
	   private int curChar;
	   private int numChars;

	   public FastScanner()
	   {
	      stream = System.in;
	   }

	   int read()
	   {
	      if (numChars == -1)
	         throw new InputMismatchException();
	      if (curChar >= numChars){
	         curChar = 0;
	         try{
	            numChars = stream.read(buf);
	         } catch (IOException e) {
	            throw new InputMismatchException();
	         }
	         if (numChars <= 0)
	            return -1;
	      }
	      return buf[curChar++];
	   }

	   boolean isSpaceChar(int c)
	   {
	      return c==' '||c=='\n'||c=='\r'||c=='\t'||c==-1;
	   }
	   
	   boolean isEndline(int c)
	   {
	      return c=='\n'||c=='\r'||c==-1;
	   }

	   int nextInt()
	   {
	      return Integer.parseInt(next());
	   }
	   
	   long nextLong()
	   {
	      return Long.parseLong(next());
	   }

	   double nextDouble()
	   {
	      return Double.parseDouble(next());
	   }

	   String next(){
	      int c = read();
	      while (isSpaceChar(c))
	         c = read();
	      StringBuilder res = new StringBuilder();
	      do{
	         res.appendCodePoint(c);
	         c = read();
	      }while(!isSpaceChar(c));
	      return res.toString();
	   }
	   
	   String nextLine(){
	      int c = read();
	      while (isEndline(c))
	         c = read();
	      StringBuilder res = new StringBuilder();
	      do{
	         res.appendCodePoint(c);
	         c = read();
	      }while(!isEndline(c));
	      return res.toString();
	   }
	}
