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.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

public class CF_MishaAndPermutationsSumations {
    static int n;
    static int[]p,q, ordP, ordQ, sum, re;
    public static void main(String[]args) throws IOException{
        String[]data;
        try (BufferedReader f = new BufferedReader(new InputStreamReader(System.in))) {
            n = Integer.valueOf(f.readLine());
            p = new int[n];
            q = new int[n];
            data = f.readLine().split(" ");
            for(int i = 0 ; i < n ; ++i){
                p[i] = Integer.valueOf(data[i]);
            }
            data = f.readLine().split(" ");
            for(int i = 0 ; i < n ; ++i){
                q[i] = Integer.valueOf(data[i]);
            }
        }
        ordP = FP(n, p);
        ordQ = FP(n, q);
        sum = SOP(n, ordP, ordQ);
        re = reconstruct(n, sum ) ;
        for(int i = 0 ; i < n ; ++i){
            System.out.print(re[i] +" ");
        }
//        System.out.println(Arrays.toString(ordP));
//        System.out.println(Arrays.toString(FP(n, q)));
//        System.out.println(Arrays.toString(SOP(n, FP(n, p), FP(n, q))));
//        System.out.println(Arrays.toString(reconstruct(n, SOP(n, FP(n, p), FP(n, q)) ) ));
    }
    public static int[] reconstruct(int n, int[]base){
        ST re = new ST(0, n-1);
        int[]p = new int[n];
        for(int i = 0 ; i < n ; ++i){
            p[i] = re.find(base[i] + 1);
            re.update(p[i], 0);
            //System.out.println(re.value);
        }
            
        return p;
    }
    public static int[] FP(int n, int[]a){
        ST perm = new ST(0, n-1);
        int[]res = new int[n];
        for(int i = 0 ; i < n ; ++i){
            int pos = perm.getQuery(0, a[i]) - 1;
            perm.update(a[i], 0);
            res[i] = pos;
        }
        return res;
    }
    public static int[]SOP(int n, int[]a, int[]b){
        int add = 0;
        int[]res = new int[n];
        for(int i = n-1 ; i>= 0 ; --i){
            int num = a[i] + b[i] + add;
            int mod = n - i;
            if(num >= mod){
                res[i] = num%mod;
                add = 1;
            }else{
                res[i] = num;
                add = 0;
            }
        }
        return res;
    }
    static class ST{
        int begin, end, mid;
        ST left, right; 
        int value;
        public ST( int i, int j){
            begin = i;
            end = j;
            mid = (i+j)/2;
            if(i!=j){
                left = new ST(i, mid);
                right = new ST(mid+1, j);
                value = append(left.value, right.value);
            }else{
                value = 1;
            } 
        }
        public int getQuery(int i, int j){
            if(i == begin && j == end){
                return value;
            }else{
                if(i <= mid)
                    if(j <= mid) return left.getQuery(i, j);
                    else return append(left.getQuery(i, mid),right.getQuery(mid+1, j)); 
                else
                    return right.getQuery(i, j); 
            }
        }
        public void update(int i, int a){
            if(begin == end){
                value = a;
            }  
            else{
                if(i <= mid) left.update(i, a);  
                else right.update(i, a);
                value = append(left.value, right.value);
            }
        }

        public int append(int left, int right){ 
            return left+right;
        }
        public int find(int k){
            if(begin == end){
                return begin;
            }else{
            if(left.value >= k){
                return left.find(k);
            }else{
                return right.find(k - left.value);
            }
        }
    }

    }
}