You are given an array a_1, a_2, ..., a_n and an array b_1, b_2, ..., b_n.

For one operation you can sort in non-decreasing order any subarray a[l ... r] of the array a.

For example, if a = [4, 2, 2, 1, 3, 1] and you choose subbarray a[2 ... 5], then the array turns into [4, 1, 2, 2, 3, 1]. 

You are asked to determine whether it is possible to obtain the array b by applying this operation any number of times (possibly zero) to the array a.

Input

The first line contains one integer t (1 ≤ t ≤ 3 ⋅ 10^5) — the number of queries.

The first line of each query contains one integer n (1 ≤ n ≤ 3 ⋅ 10^5).

The second line of each query contains n integers a_1, a_2, ..., a_n (1 ≤ a_i ≤ n).

The third line of each query contains n integers b_1, b_2, ..., b_n (1 ≤ b_i ≤ n).

It is guaranteed that ∑ n ≤ 3 ⋅ 10^5 over all queries in a test.

Output

For each query print YES (in any letter case) if it is possible to obtain an array b and NO (in any letter case) otherwise.

Example

Input


4
7
1 7 1 4 4 5 6
1 1 4 4 5 7 6
5
1 1 3 3 5
1 1 3 3 5
2
1 1
1 2
3
1 2 3
3 2 1


Output


YES
YES
NO
NO

Note

In first test case the can sort subarray a_1 ... a_5, then a will turn into [1, 1, 4, 4, 7, 5, 6], and then sort subarray a_5 ... a_6.
import java.util.*;
import java.io.*;

/**
 * @author kenpen 
 */
public class SubarraySorting 
{
    public static void main(String[] args) 
    {
        int t = getInt();
        SegTree st = new SegTree(300000);
        while (t-- > 0) {
            int n = getInt();
            int[] a = new int[n];
            int[] b = new int[n];
            for (int i = 0 ; i < n ; ++i) a[i] = getInt() - 1;
            for (int i = 0 ; i < n; ++i) b[i] = getInt() - 1;
            // numbers in a / b will only be in range 0 to n-1
            List<Queue<Integer>> qs = new ArrayList<>();
            for (int i = 0 ; i < n ; ++i) {
                qs.add(new LinkedList<>());
            }

            for (int i = 0 ; i < n; ++i) {
                int v = a[i];
                qs.get(v).add(i);
            }
            int[] tops = new int[n];
            for (int i = 0; i < n; ++i) {
                Queue<Integer> ind = qs.get(i);
                if (ind.isEmpty()) tops[i] = Integer.MAX_VALUE;
                else tops[i] = ind.peek();
            }
            st.build(tops);
            boolean failed = false;
            int ia = 0;
            for (int i = 0; i < n ; ++i) {
                int bv = b[i];
                int av = a[ia];
                if (bv > av) {
                    print("NO", true);
                    failed = true;
                    break;
                }
                else if (av == bv) {
                    Queue<Integer> indices = qs.get(bv);
                    indices.poll();
                    int newIndex = indices.isEmpty() ? Integer.MAX_VALUE : indices.peek();
                    st.update(0, 0, n - 1, bv, newIndex);
                    ia = st.tree[0];
                }
                else if (av > bv) {
                    // bring smaller value from front, i.e., sort asc / swap.
                    // rather than shifting elements of a, we move b's pointer ahead.
                    int minIndex = st.query(0, 0, n - 1, 0, bv - 1);
                    int bvIndex = qs.get(bv).isEmpty() ? -1 : qs.get(bv).peek();
                    if (minIndex < bvIndex || bvIndex == -1) {
                        print("NO", true);
                        failed = true;
                        break;
                    }
                    else {
                        Queue<Integer> indices = qs.get(bv);
                        indices.poll();
                        int newIndex = indices.isEmpty() ? Integer.MAX_VALUE : indices.peek();
                        st.update(0, 0, n - 1, bv, newIndex);
                    }
                }
            }
            if (!failed) {
                print("YES", true);
            }
        }
        flush();
    }
    // need segtree of top of all queues.
    // min seg tree
    static class SegTree
    {
        int[] tree;
        int n;

        public SegTree(int n)
        {
            this.n = n;
            tree = new int[4*n];

        }

        void build(int[] arr){
            build(arr, 0, 0, arr.length - 1);
        }

        // tn - treeNode
        // both l and r inclusive.
        int build(int[] arr, int tn, int l, int r) {
            if (l == r) {
                tree[tn] = arr[l];
                return tree[tn];
            }
            int mid = (l + r) / 2;
            int ltn = tn * 2 + 1;
            int rtn = ltn + 1;
            int leftMin = build(arr, ltn, l, mid);
            int rightMin = build(arr, rtn, mid + 1, r);
            tree[tn] = Math.min(leftMin, rightMin);
            return tree[tn];
        }

        // change value at target to be val
        int update(int tn, int l, int r, int target, int val) {
            if (target > r || target < l) {
                return tree[tn];
            }
            if (l == r) {
                tree[tn] = val;
                return tree[tn];
            }
            int mid = (l + r) / 2;
            int ltn = 2 * tn + 1;
            int rtn = ltn + 1;
            int leftMin = update(ltn, l, mid, target, val);
            int rightMin = update(rtn, mid + 1, r, target, val);
            return tree[tn] = Math.min(leftMin, rightMin);
        }

        int query(int tn, int l, int r, int sl, int sr) {
            // l, r are for current node
            // sl, sr are what we're searching for
            if (sr < l || sl > r) {
                return Integer.MAX_VALUE;
            }
            else if (sl <= l && sr >= r) {
                return tree[tn];
            }
            int mid = (l + r) / 2;
            int ltn = 2 * tn + 1;
            int rtn = ltn + 1;
            int leftMin = query(ltn, l, mid, sl, sr);
            int rightMin = query(rtn, mid + 1, r, sl, sr);
            return Math.min(leftMin, rightMin);
        }
    }

    // ===== Printing code ===== 
    static StringBuilder buf = new StringBuilder();
    static int bufSize = 5000;
    static void print(String s) {print(s, false);}

    static void print(String s, boolean newLine) {
        buf.append(s);
        if (newLine) buf.append("\n");
        if (buf.length() >= bufSize) {
            System.out.print(buf);
            buf.delete(0, buf.length());
        }
    }
    
    static void flush() { 
        System.out.print(buf); 
        buf.delete(0, buf.length());
    }

    static String arrayToString(int[] arr) {
        StringBuilder sb = new StringBuilder();
        for (int a : arr) sb.append(a).append(" ");
        if (arr.length > 0) sb.deleteCharAt(sb.length() - 1);
        return sb.toString();
    }

    // ===== INPUT TAKING CODE ==== 
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static void checkSt() {
        if (st == null || !st.hasMoreTokens()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (IOException e) {
                System.out.println("Error parsing input");
            }
        }
    }
    static int getInt() {
        checkSt();
        return Integer.valueOf(st.nextToken());
    }

    static long getLong() {
        checkSt();
        return Long.valueOf(st.nextToken());
    }
    

    static long getNewLineLong() {
        try {
            return Long.valueOf(br.readLine());
        } catch (IOException e) {
            System.out.println("Error parsing input");
            return 0;
        }
    }

    static int getNewLineInt() {
        try {
            return Integer.valueOf(br.readLine());
        } catch (IOException e) {
            System.out.println("Error parsing input");
            return 0;
        }
    }

    static char getChar() {
        checkSt();
        return st.nextToken().charAt(0);
    }

    static String getStr() {
        checkSt();
        return st.nextToken();
    }
    
}
