#include #define eb emplace_back #define pb push_back #define mp make_pair #define fi first #define se second #define INF 0x3f3f3f3f using namespace std; typedef long long ll; typedef pair pii; typedef vector vi; //const int N = 100; const int N = 100000; char animal[N]; int s[N], d[N], ans[N], dp[N], tipo[N]; int m, n; int bit[N][4]; int query (int x, int t) { int y = 0; while (x) { y += bit[x][t]; x -= (x & -x); } return y; } void update (int x, int y, int t) { while (x < N) { bit[x][t] += y; x += (x & -x); } } int query (int l, int r, int t) { if (l > r) return 0; return query(r, t) - query(l-1, t); } int conta(int l, int r, int t) { return query(l, r, t); } struct segtree { int seg[4*N+1], lazy[4*N+1], n, k, a, b; segtree() { } segtree (int n) : n(n) { memset (seg, 0, sizeof seg); memset (lazy, 0, sizeof lazy); } void prop (int r, int i, int j) { seg[r] += lazy[r]; if (i != j) { lazy[r*2] += lazy[r]; lazy[r*2+1] += lazy[r]; } lazy[r] = 0; } int query (int r, int i, int j) { prop (r, i, j); if (i > b or j < a) return 0; if (i >= a and j <= b) { lazy[r] = k; prop (r, i, j); return seg[r]; } int mid = (i + j) / 2; int le = query(r*2, i, mid); int ri = query(r*2+1, mid+1, j); seg[r] = max(seg[r*2], seg[r*2+1]); return max(le, ri); } int query (int x, int y) { if (x > y) return -1; a = x; b = y; k = 0; return query(1, 0, n-1); } void update (int x, int y, int z) { if (x > y) return ; a = x; b = y; k = z; query (1, 0, n-1); } } st[4]; int main() { int t; scanf("%d", &t); while (t--) { memset (ans, INF, sizeof ans); memset (bit, 0, sizeof bit); memset (tipo, 0, sizeof tipo); scanf("%d %d", &m, &n); for (int i = 0; i < n; i++) scanf(" %c", animal+i); for (int i = 0; i < n; i++) scanf("%d", s+i); for (int i = 0; i < n; i++) scanf("%d", d+i); for (int i = 0; i < n; i++) if (animal[i] == 'E' or animal[i] == 'C') tipo[i] = 1; vector > eventos; vector dd[2]; for (int i = 0; i < n; i++) { if (s[i] > d[i]) continue; eventos.eb(d[i], s[i], animal[i], tipo[i], i); dd[tipo[i]].eb(d[i], i); } sort(dd[0].begin(), dd[0].end()); sort(dd[1].begin(), dd[1].end()); st[0] = segtree(n); st[1] = segtree(n); st[2] = segtree(n); st[3] = segtree(n); sort(eventos.begin(), eventos.end()); for (int e = 0; e < eventos.size(); e++) { int s, d, a, t, p; tie(d, s, a, t, p) = eventos[e]; int tipo = t; dp[e] = conta(1, d, t); int k = lower_bound(dd[1-tipo].begin(), dd[1-tipo].end(), mp(s, INF)) - dd[1-tipo].begin() - 1; dp[e] = max(dp[e], st[2 + 1-tipo].query(0, k) + 1); k = lower_bound(dd[tipo].begin(), dd[tipo].end(), mp(s, INF)) - dd[tipo].begin() - 1; dp[e] = max(dp[e], st[tipo].query(0, k) + 1); // printf("s %d d %d animal %c tipo %d dp %d\n", s, d, a, t, dp[e]); /* for (int i = 0; i < e; i++) { int s1, d1, a1, t1; tie(d1, s1, a1, t1) = eventos[i]; bool flag = t; if (t1 != t) { if (d1 > s) continue; dp[e] = max(dp[e], dp[i] + 1 + conta(d1, d, t+2)); } else { if (d1 > s) continue; dp[e] = max(dp[e], dp[i] + 1 + conta(d1, d, t+2)); } } */ ans[dp[e]] = min(ans[dp[e]], d); update(d, 1, t); update(s, 1, t+2); k = lower_bound(dd[tipo].begin(), dd[tipo].end(), mp(s, INF)) - dd[tipo].begin() - 1; st[tipo].update(0, k, 1); k = lower_bound(dd[1-tipo].begin(), dd[1-tipo].end(), mp(s, INF)) - dd[1-tipo].begin() - 1; st[2+1-tipo].update(0, k, 1); k = lower_bound(dd[tipo].begin(), dd[tipo].end(), mp(d, p)) - dd[tipo].begin(); st[tipo].update(k, k, dp[e]); st[tipo+2].update(k, k, dp[e]); } for (int i = 0; i < n; i++) printf("%d%c", ans[i] == INF ? -1 : ans[i], " \n"[i==n-1]); } return 0; }