#include using namespace std; const int INF = 1 << 30; struct SegmentTree { int sz; vector< int > seg, add; SegmentTree(int n) { sz = 1; while(sz < n) sz <<= 1; seg.assign(2 * sz - 1, -INF); add.assign(2 * sz - 1, 0); } inline void push(int k) { if(k < sz - 1) { add[2 * k + 1] += add[k]; add[2 * k + 2] += add[k]; } seg[k] += add[k]; add[k] = 0; } int query(int a, int b, int k, int l, int r) { push(k); if(a >= r || b <= l) return (-INF); if(a <= l && r <= b) return (seg[k]); return max(query(a, b, 2 * k + 1, l, (l + r) >> 1), query(a, b, 2 * k + 2, (l + r) >> 1, r)); } int query(int a, int b) { return (query(a, b, 0, 0, sz)); } void addd(int a, int b, int k, int l, int r) { push(k); if(a >= r || b <= l) return; if(a <= l && r <= b) { ++add[k]; push(k); return; } addd(a, b, 2 * k + 1, l, (l + r) >> 1); addd(a, b, 2 * k + 2, (l + r) >> 1, r); seg[k] = max(seg[2 * k + 1], seg[2 * k + 2]); } void update(int a, int x, int k, int l, int r) { push(k); if(a >= r || a + 1 <= l) return; if(a <= l && r <= a + 1) { seg[k] = max(seg[k], x); return; } update(a, x, 2 * k + 1, l, (l + r) >> 1); update(a, x, 2 * k + 2, (l + r) >> 1, r); seg[k] = max(seg[2 * k + 1], seg[2 * k + 2]); } void addd(int a, int b) { addd(a, b, 0, 0, sz); } void update(int a, int x) { update(a, x, 0, 0, sz); } }; const string temp = "EDCM"; int correct[4][2] = { {0, 4}, {1, 5}, {2, 4}, {3, 5} }; void myon() { int M, N; int T[50000], S[50000], D[50000]; int dp[50000], ans[50001]; scanf("%d %d", &M, &N); for(int i = 0; i < N; i++) { char c; scanf(" %c", &c); T[i] = (int) temp.find(c); } for(int i = 0; i < N; i++) { scanf("%d", &S[i]); --S[i]; } for(int i = 0; i < N; i++) { scanf("%d", &D[i]); --D[i]; } vector< int > ev[50000]; for(int i = 0; i < N; i++) { ev[S[i]].emplace_back(i); } vector< SegmentTree > seg(6, SegmentTree(M)); fill_n(ans, N + 1, INF); for(int i = 0; i < 6; i++) { seg[i].update(0, 0); } for(int i = 0; i < M; i++) { if(i > 0) { dp[i] = -INF; for(int j = 0; j < 6; j++) { dp[i] = max(dp[i], seg[j].query(0, i + 1)); } } for(int idx : ev[i]) { if(S[idx] < D[idx]) { for(int j : correct[T[idx]]) { seg[j].addd(D[idx], M); seg[j].update(D[idx], max(dp[i], seg[j].query(0, D[idx])) + 1); } } } ans[dp[i]] = min(ans[dp[i]], i + 1); } for(int i = N - 1; i >= 0; i--) { ans[i] = min(ans[i], ans[i + 1]); } for(int i = 1; i <= N; i++) { if(ans[i] >= INF) ans[i] = -1; if(i > 1) putchar(' '); printf("%d", ans[i]); } puts(""); } int main() { int T; scanf("%d", &T); while(T--) myon(); }