#include using namespace std; #define FOR(i, a, b) for (int i = a; i <= b; i++) #define FOD(i, a, b) for (int i = a; i >= b; i--) #define REP(i, a, b) for (int i = a; i < b; i++) #define PR(A, n) { cout << #A << " = "; FOR(_, 1, n) cout << A[_] << " "; cout << endl; } #define DEBUG(X) { cout << #X << " = " << X << endl; } const int N = 5E4 + 10; int m, n; char a[N]; int s[N], t[N]; int f[N]; vector adj[2][N]; struct SegmentTree { int It[N * 4], Lazy[N * 4]; void Reset() { memset(It, 0, sizeof(It)); memset(Lazy, 0, sizeof(Lazy)); } void Down(int id) { Lazy[id << 1] += Lazy[id]; Lazy[id << 1 | 1] += Lazy[id]; It[id << 1] += Lazy[id]; It[id << 1 | 1] += Lazy[id]; Lazy[id] = 0; } void RangeUpdate(int id, int l, int r, int u, int v) { /// [l..r] [u..v] if (v < l || r < u || l > r) return; if (u <= l && r <= v) { Lazy[id]++; It[id]++; return; } Down(id); int mid = (l + r) >> 1; RangeUpdate(id << 1, l, mid, u, v); RangeUpdate(id << 1 | 1, mid + 1, r, u, v); It[id] = max(It[id << 1], It[id << 1 | 1]); } void PointUpdate(int id, int l, int r, int i, int val) { if (i < l || r < i || l > r) return; if (l == r) { It[id] = val; return; } Down(id); int mid = (l + r) >> 1; PointUpdate(id << 1, l, mid, i, val); PointUpdate(id << 1 | 1, mid + 1, r, i, val); It[id] = max(It[id << 1], It[id << 1 | 1]); } int Query(int id, int l, int r, int u, int v) { if (v < l || r < u || l > r) return 0; if (u <= l && r <= v) return It[id]; Down(id); int mid = (l + r) >> 1; int ret = max(Query(id << 1, l, mid, u, v), Query(id << 1 | 1, mid + 1, r, u, v)); } void RangeUpdate(int l, int r) { RangeUpdate(1, 1, m, l, r); } void PointUpdate(int i, int val) { PointUpdate(1, 1, m, i, val); } int Query(int l, int r) { return Query(1, 1, m, l, r); } } Segment[2]; void Read_Input() { scanf("%d%d\n", &m, &n); FOR(i, 1, n) { char ch[2]; scanf("%s", ch); a[i] = ch[0]; } FOR(i, 1, n) scanf("%d", &s[i]); FOR(i, 1, n) scanf("%d", &t[i]); } void Init() { memset(f, 0, sizeof(f)); FOR(i, 0, 1) FOR(j, 1, m) adj[i][j].clear(); FOR(i, 1, n) { if (s[i] > t[i]) continue; if (a[i] == 'E' || a[i] == 'C') adj[0][t[i]].push_back(s[i]); else adj[1][t[i]].push_back(s[i]); } FOR(i, 0, 1) Segment[i].Reset(); } void Solve() { /// f[i] = so luong thu max den tram i FOR(i, 1, m) { if (adj[0][i].size() + adj[1][i].size() == 0) continue; FOR(k, 0, 1) REP(j, 0, adj[k][i].size()) Segment[k].RangeUpdate(1, adj[k][i][j]); f[i] = max(Segment[0].It[1], Segment[1].It[1]); Segment[0].PointUpdate(i, f[i]); Segment[1].PointUpdate(i, f[i]); } //PR(f, m); FOR(i, 1, m) if (f[i] == 0) f[i] = f[i - 1]; FOR(i, 1, n) { /// Tim tram nho nhat int l = 1, h = m, mid, ret = -1; while (l <= h) { mid = (l + h) >> 1; if (f[mid] >= i) { ret = mid; h = mid - 1; } else l = mid + 1; } printf("%d ", ret); } putchar('\n'); } int main() { #ifdef LOCAL freopen("input.inp", "r", stdin); freopen("output.out", "w", stdout); #endif // LOCAL int TC; scanf("%d", &TC); while (TC--) { Read_Input(); Init(); Solve(); } return 0; }