import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Scanner; public class Solution { static int[] minimumZooNumbers(int m, int n, char[] t, int[] s, int[] d) { ArrayList[] arr1 = new ArrayList[m + 2]; ArrayList[] arr2 = new ArrayList[m + 2]; for (int i = 0; i <= m + 1; i++) { arr1[i] = new ArrayList<>(); arr2[i] = new ArrayList<>(); } for (int i = 0; i < n; i++) if(s[i] < d[i]) if(t[i] == 'M' || t[i] == 'D') arr1[d[i] + 1].add(s[i] + 1); else arr2[d[i] + 1].add(s[i] + 1); int N = 1; while(N < m + 1) N <<= 1; SegmentTree st1 = new SegmentTree(N); SegmentTree st2 = new SegmentTree(N); int[] max = new int[m]; for (int i = 2; i <= m+1; ++i) { for (int j = 0; j < arr1[i].size(); ++j) st1.update_range(1, arr1[i].get(j), 1); for (int j = 0; j < arr2[i].size(); ++j) st2.update_range(1, arr2[i].get(j), 1); // for (int j : arr1[i]) // st1.update_range(1, j, 1); // for (int j :arr2[i]) // st2.update_range(1, j, 1); int ans = Math.max(st1.query(1, i - 1), st2.query(1, i - 1)); max[i - 2] = ans; st1.update_range(i, i, ans); st2.update_range(i, i, ans); } int[] ans = new int[n]; Arrays.fill(ans, -1); int cur = 0; for (int i = 0; i < m; ++i) { for (; cur < max[i]; ++cur) { ans[cur] = i + 1; } } return ans; } public static void main(String[] args) { Scanner in = new Scanner(System.in); PrintWriter out = new PrintWriter(System.out); int cases = in.nextInt(); for(int a0 = 0; a0 < cases; a0++){ int m = in.nextInt(); int n = in.nextInt(); char[] t = new char[n]; for(int t_i = 0; t_i < n; t_i++){ t[t_i] = in.next().charAt(0); } int[] s = new int[n]; for(int s_i = 0; s_i < n; s_i++){ s[s_i] = in.nextInt(); } int[] d = new int[n]; for(int d_i = 0; d_i < n; d_i++){ d[d_i] = in.nextInt(); } int[] result = minimumZooNumbers(m, n, t, s, d); for (int i = 0; i < result.length; i++) { out.print(result[i] + (i != result.length - 1 ? " " : "")); } out.println(""); } out.close(); in.close(); } static class SegmentTree { // 1-based DS, OOP int N; //the number of elements in the array as a power of 2 (i.e. after padding) int[] sTree, lazy; SegmentTree(int n) { N = n; sTree = new int[N<<1]; //no. of nodes = 2*N - 1, we add one to cross out index zero lazy = new int[N<<1]; } void update_point(int index, int val) // O(log n) { index += N - 1; sTree[index] += val; while(index>1) { index >>= 1; sTree[index] = Math.max(sTree[index<<1] , sTree[index<<1|1]); } } void update_range(int i, int j, int val) // O(log n) { update_range(1,1,N,i,j,val); } void update_range(int node, int b, int e, int i, int j, int val) { if(i > e || j < b) return; if(b >= i && e <= j) { sTree[node] += val; lazy[node] += val; } else { int mid = b + e >> 1; propagate(node, b, mid, e); update_range(node<<1,b,mid,i,j,val); update_range(node<<1|1,mid+1,e,i,j,val); sTree[node] = Math.max(sTree[node<<1] , sTree[node<<1|1]); } } void propagate(int node, int b, int mid, int e) { lazy[node<<1] += lazy[node]; lazy[node<<1|1] += lazy[node]; sTree[node<<1] += lazy[node]; sTree[node<<1|1] += lazy[node]; lazy[node] = 0; } int query(int i, int j) { return query(1,1,N,i,j); } int query(int node, int b, int e, int i, int j) // O(log n) { if(i>e || j = i && e <= j) return sTree[node]; int mid = b + e >> 1; propagate(node, b, mid, e); int q1 = query(node<<1,b,mid,i,j); int q2 = query(node<<1|1,mid+1,e,i,j); return Math.max(q1, q2); } } }