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.math.*;

// **** D. Subarray Sorting ****

public class D {
	static char [] in = new char [1000000];
	static int [] MIN300;
	static boolean [] used;
	static int FIXNUM = 300;
	public static void main (String [] arg) throws Throwable {
		int t = nextInt();
		StringBuilder b = new StringBuilder(t*5);
		

		LL [] LL = new LL[300001];
		for (int ii = 0; ii<t; ++ii) {
			int n = nextInt();
			//Pair [] A = new Pair [n];
			int [] A = new int [n];
			MIN300 = new int [n/FIXNUM + 1];
			Arrays.fill(MIN300, Integer.MAX_VALUE);
			used = new boolean [n];
			
			for (int i = 0; i<n; ++i) {
				int v = nextInt();
				A[i] = v; //new Pair(i,i, v);
				if (LL[v] == null) LL[v] = new LL();
				LL[v].add(i);
				MIN300[i/FIXNUM] = Math.min(MIN300[i/FIXNUM], v);
			}
			//Pair [] B = new Pair [n];
			int [] B = new int [n];
			for (int i = 0; i<n; ++i) B[i] = nextInt(); //new Pair(i, i, nextInt());	

			boolean cancan = true;
			int Ai = 0, Bi=0;
			for (; Ai<n && Bi<n && cancan; ++Bi) {
				int v = B[Bi];
				if (A[Ai] == B[Bi]) {
					LL[v].removeFirst();
					Ai++;
					while (Ai < n && used[Ai]) Ai++;
				} else if (A[Ai] < B[Bi] || LL[v] == null || LL[v].isEmpty()) {
					//System.err.println("Position in A = " + Ai + " B = " + Bi+ " fail comp " + A[Ai] + " vs " + B[Bi]); 
					cancan = false;
					
				} else { // A[Ai] > B[Bi]
					int pos = LL[v].removeFirst();
					int M = rangeMin(A, Ai, pos-1);
					//System.err.println("Position in A = " + Ai + " B = " + Bi+ " range find " + B[Bi] + " found in A at pos " + pos);
					//System.err.println("Range min is " + M + " vs allowed lower bound " + v);
					
					if (v < M) {
						used[pos] = true;
						if (MIN300[pos/FIXNUM] == A[pos] && (Ai % FIXNUM == 0 || Ai/FIXNUM != pos/FIXNUM)) recalculate300(A, pos/FIXNUM);
					} else {
						//System.err.println("REJECTED");
						cancan = false;
					}
				}
			}
			//System.err.println("Final Pos " + Ai + " , " + Bi);
			// Reset LL
			for (int i = 0; i<n; ++i) if (LL[A[i]] != null) LL[A[i]] = null; 
			
			
			b = b.append( cancan ? "YES" : "NO" );
			b= b.append("\n");
		}
		System.out.print(b);
	}
	
	public static int recalculate300(int [] A, int i) {
		int MIN = Integer.MAX_VALUE;
		for (int j = i*FIXNUM; j<(i+1)*FIXNUM && j<A.length; ++j) if (!used[j]) MIN = Math.min(A[j], MIN);
		MIN300[i] = MIN;
		return MIN;
	}

	public static int rangeMin(int [] A, int L, int R) {
		if (R == L) return A[R];
		if (R < L) return Integer.MAX_VALUE;
		int MIN = Integer.MAX_VALUE;
		while (L % FIXNUM != 0 && L < R) {
			if (!used[L]) MIN = Math.min(A[L], MIN);
			L++;
		}
		if (!used[L]) MIN = Math.min(A[L], MIN);
		while (R % FIXNUM != 0 && R > L) {
			if (!used[R]) MIN = Math.min(A[R], MIN);
			R--;
		}
		if (!used[R]) MIN = Math.min(A[R], MIN);
		L/=FIXNUM;
		R/=FIXNUM;
		while (L < R) {
			MIN = Math.min(MIN300[L], MIN);
			L++;
		}
		return MIN;
	}
	
	public static int [][] findRanks(int start, int end, int inc, Pair [] A, Pair [] B) {
			BalancedBST Abst = new BalancedBST();
			BalancedBST Bbst = new BalancedBST();
			int [][] ret = new int [4][A.length];
			int cnt = 0;
			for (int i = start; i != end; i+=inc,cnt++) {
				int [] Arank = Abst.findRank(A[i].L);
				int [] Brank = Bbst.findRank(B[i].L);
				ret[0][i] = Arank[0];
				ret[1][i] = Brank[0];
				Abst.insert(A[i].L);
				Bbst.insert(B[i].L);
				//System.err.println("Rank of " + A[i].L + " is " + Arank[i] + " in prefix bst");
				//System.err.println("BST NOW Contains " + Abst.count(Abst.root) + " elements");
				ret[2][i] = Arank[1];
				ret[3][i] = Brank[1];
			}
			return ret;
	}
	
 static class BalancedBST
 {
	class Node
	{   
		Node left, right;
		long data;
		int height = 0; 
		int count = 0;
		int duplicate = 0;
		public Node(long n) { data = n; count = 1;}     
	}
     public Node root = null;     
     public BalancedBST() {root = null;}
     public void insert(long data) { 
		root = insert(data, root);
	 }
	 
     private int height(Node t )
     {
         return t == null ? -1 : t.height;
     }
	 public int count(Node t )
     {
         return t == null ? 0 : t.count;
     }
     /* Function to max of left/right node */
     private int max(int lhs, int rhs)
     {
         return lhs > rhs ? lhs : rhs;
     }
     /* Function to insert data recursively */
     private Node insert(long x, Node t)
     {
		 //int cnt = (t == null) ? 0 : t.count;
         if (t == null)
             t = new Node(x);
         else if (x < t.data)
         {
             t.left = insert( x, t.left );
             if (height( t.left ) - height( t.right ) == 2)
                 if (x < t.left.data)
                     t = rotateWithLeftChild( t );
                 else
                     t = doubleWithLeftChild( t );
						
         }
         else if (x > t.data)
         {
			 
             t.right = insert( x, t.right );
             if (height( t.right ) - height( t.left ) == 2)
                 if (x > t.right.data)
                     t = rotateWithRightChild( t );
                 else
                     t = doubleWithRightChild( t );
			
         }
         else {
			t.duplicate++;
		 }
          
         t.height = max( height( t.left ), height( t.right ) ) + 1;
		 t.count = count(t.left) + count(t.right) + 1 + t.duplicate;
         return t;
     }
     /* Rotate binary tree node with left child */     
     private Node rotateWithLeftChild(Node k2)
     {
         Node k1 = k2.left;
         k2.left = k1.right;
         k1.right = k2;
         k2.height = max( height( k2.left ), height( k2.right ) ) + 1;
		 k2.count = count(k2.left) + count(k2.right) + 1 + k2.duplicate;
         k1.height = max( height( k1.left ), k2.height ) + 1;
		 k1.count = count(k1.left) + count(k2) + 1 + k1.duplicate;
         return k1;
     }
 
     /* Rotate binary tree node with right child */
     private Node rotateWithRightChild(Node k1)
     {
         Node k2 = k1.right;
         k1.right = k2.left;
         k2.left = k1;
         k1.height = max( height( k1.left ), height( k1.right ) ) + 1;
		 k1.count = count(k1.left) + count(k1.right) + 1 + k1.duplicate;
         k2.height = max( height( k2.right ), k1.height ) + 1;
		 k2.count = count(k2.right) + count(k1) + 1 + k2.duplicate;
         return k2;
     }
     /**
      * Double rotate binary tree node: first left child
      * with its right child; then node k3 with new left child */
     private Node doubleWithLeftChild(Node k3)
     {
         k3.left = rotateWithRightChild( k3.left );
         return rotateWithLeftChild( k3 );
     }
     /**
      * Double rotate binary tree node: first right child
      * with its left child; then node k1 with new right child */      
     private Node doubleWithRightChild(Node k1)
     {
         k1.right = rotateWithLeftChild( k1.right );
         return rotateWithRightChild( k1 );
     }    
     public boolean search(int val)
     {
         boolean found = false;
		 Node r = root;
         while ((r != null) && !found)
         {
             long rval = r.data;
             if (val < rval)
                 r = r.left;
             else if (val > rval)
                 r = r.right;
             else
             {
                 found = true;
                 break;
             }
         }
         return found;
     }
	 
	 public int [] findRank(long val) {
		Node r = root;
		int count = 0;
		int count2 = 0;
		//System.err.println("Finding Rank of " + val);
         while (r != null) {
             long rval = r.data;
             if (val < rval) {
				//System.err.println("Left move because " + val + " < " + rval);
				count2 += count(r.right) + 1 + r.duplicate;
                 r = r.left;
             } else if (val > rval) {
				 //System.err.println("Right move because " + val + " > " + rval + " added " + (count(r.left)+1+r.duplicate));
				 count += count(r.left) + 1 + r.duplicate;
				 r = r.right;
             } else {
				//System.err.println("Found result because " + val + " = " + rval + " and left count is " + count(r.left));
                 count += count(r.left);
				 count2 += count(r.right);
				 return new int []{count, count2};
             }
         }
         return new int []{count, count2};
	 }
	}
	
	
	
	
	
	
	
	/************** HELPER CLASSES ***************/
    //static class HS extends HashSet<Integer>{public HS(){super();}public HS(int a){super(a);}};
	static class LL extends LinkedList<Integer>{public LL(){super();}};
static class Pair implements Comparable<Pair> {int i,j;long L; public Pair(int xx, int yy, long LL){i=xx;j=yy;L=LL;} public int compareTo(Pair p) {
		return (this.L < p.L) ? -1 : ((this.L == p.L && this.i < p.i) ? -1 : 1);}
	}
	
	/************** FAST IO CODE FOLLOWS *****************/
	public static long nextLong() throws Throwable {
		long i = System.in.read();boolean neg = false;while (i < 33) i = System.in.read();if (i == 45) {neg=true;i=48;}i = i - 48;
		int j = System.in.read();while (j > 32) {i*=10;i+=j-48;j = System.in.read();}return (neg) ? -i : i;
	}
	public static int nextInt() throws Throwable {return (int)nextLong();}
	public static String next() throws Throwable {
		int i = 0; while (i < 33 && i != -1) i = System.in.read(); int cptr = 0; while (i >= 33) { in[cptr++] = (char)i; i = System.in.read();}
		return new String(in, 0,cptr);
	}
	/**** LIBRARIES ****/
	public static long gcdL(long a, long b) {while (b != 0) {long tmp = b;b = (a % b);a = tmp;}return a;}
	public static int gcd(int a, int b) {while (b != 0) {int tmp = b;b = (a % b);a = tmp;}return a;}
	public static int[] sieve(int LIM) {
		int i,count = 0;
		boolean [] b = new boolean [LIM];
		for (i = 2;i<LIM; ++i) if (!b[i]) {count++; for (int j = i<<1; j<LIM; j+=i) b[j] = true;}
		int [] primes = new int[count];
		for (i = 2,count=0;i<LIM;++i) if (!b[i]) primes[count++] = i;
		return primes;
	}
	public static int[] numPrimeFactors(int LIM) {
		int i,count = 0;
		int [] b = new int [LIM];
		for (i = 2;i<LIM; ++i) if (b[i] == 0) {count++; for (int j = i; j<LIM; j+=i) b[j]++;}
		return b;
	}
	public static StringBuilder stringFromArray(int [] a) {
		StringBuilder b = new StringBuilder(9*a.length);
		for (int i = 0; i<a.length; ++i) {
			if (i != 0) b = b.append(' ');
			b = b.append(a[i]);
		}
		return b;
	}
}

/* Full Problem Text:
  
You are given an array a_1, a_2, \dots, a_n and an array b_1, b_2, \dots, b_n.
For one operation you can sort in non-decreasing order any subarray a[l \dots r] of the array a.
For example, if a = [4, 2, 2, 1, 3, 1] and you choose subbarray a[2 \dots 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.

 */
 
 	
	/*
	public static int rangeMin(int [] A, int L, int R) {
		if (R == L) return A[R];
		if (R < L) return Integer.MAX_VALUE;
		int MIN = Integer.MAX_VALUE;
		while (L % 300 != 0 && L <= R) {
			MIN = Math.min(A[L], MIN);
			L++;
		}
		while (R % 300 != 0 && R >= L) {
			MIN = Math.min(A[R], MIN);
			R--;
		}
		L/=300;
		R/=300;
		while (L < R) {
			MIN = Math.min(MIN300[L], MIN);
			L++;
		}
		return MIN;
	}
	*/
	
	/*
			int [][] Lrank = findRanks(0, n, 1, A, B);
			int [][] Rrank = findRanks(n-1, -1, -1, A, B);
			
			
			Arrays.sort(A);
			Arrays.sort(B);
			boolean cancan = true;
			for (int i = 0; i<n && cancan; ++i) {
				//System.err.println("Trying " + A[i].L + " located at pos " + A[i].i + " in A and pos " + B[i].i + " in B ");
				//System.err.println("Arank = " + Arank[A[i].i] + " vs " + Brank[B[i].i]);
				if (A[i].L != B[i].L) cancan = false;
				if (	Lrank[1][B[i].i] >= Lrank[0][A[i].i] 
					//&& 	Lrank[3][B[i].i] <= Lrank[2][A[i].i]
					//&&  Rrank[1][B[i].i] <= Rrank[0][A[i].i] 
					&&  Rrank[3][B[i].i] >= Rrank[2][A[i].i] 
					) continue;
				
				cancan = false;
			}
			*/
	
	
	
	
	
