#include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; #define TRACE(x) cerr << #x << " " << x << endl #define FOR(i, a, b) for (int i = (a); i < int(b); ++i) #define REP(i, n) FOR(i, 0, n) #define _ << " " << #define fst first #define snd second typedef long long llint; typedef pair pii; const int MAXN = 5e4 + 10; const int INF = 1e8; class Tournament { private: struct Node { int prop; int sum, max; Node () { prop = sum = max = 0; } }; int offset, from, to; vector tree; void merge(int i) { if (i >= offset) return; tree[i].max = max(tree[2*i].max, tree[2*i+1].max); tree[i].sum = tree[2*i].sum + tree[2*i+1].sum; } void propagate(int i, int lo, int hi) { if (tree[i].prop == 0) return; tree[i].sum += tree[i].prop * (hi - lo); tree[i].max += tree[i].prop; if (i < offset) { tree[2*i].prop += tree[i].prop; tree[2*i+1].prop += tree[i].prop; } tree[i].prop = 0; } int get_max(int node, int lo, int hi) { propagate(node, lo, hi); if (from >= hi || to <= lo) return 0; if (lo >= from && hi <= to) return tree[node].max; int ret = max(get_max(2 * node, lo, (lo + hi) / 2), get_max(2 * node + 1, (lo + hi) / 2, hi)); merge(node); return ret; } int get_sum(int node, int lo, int hi) { propagate(node, lo, hi); if (from >= hi || to <= lo) return 0; if (lo >= from && hi <= to) return tree[node].sum; int ret = get_sum(2 * node, lo, (lo + hi) / 2) + get_sum(2 * node + 1, (lo + hi) / 2, hi); merge(node); return ret; } void inc_interval(int node, int lo, int hi, int val) { propagate(node, lo, hi); if (from >= hi || to <= lo) return; if (lo >= from && hi <= to) { tree[node].prop += val; propagate(node, lo, hi); return; } inc_interval(2*node, lo, (lo + hi) / 2, val); inc_interval(2*node+1, (lo + hi) / 2, hi, val); merge(node); } public: Tournament(int n) { for (offset = 1; offset <= n; offset *= 2); tree.resize(2*offset); } void inc_interval(int l, int r, int val) { from = l; to = r; inc_interval(1, 0, offset, val); } int get_max(int l, int r) { from = l; to = r; return get_max(1, 0, offset); } int get_sum(int l, int r) { from = l; to = r; return get_sum(1, 0, offset); } }; struct Interval { bool type; int lo, hi; Interval() {} friend bool operator < (const Interval &A, const Interval &B) { if (A.hi == B.hi && A.type == B.type) return A.lo < B.lo; if (A.hi == B.hi) return A.type < B.type; return A.hi < B.hi; } }; int T, M, N; int sol[MAXN], dp[MAXN]; Interval I[MAXN]; inline void init() { for (int i = 0; i < MAXN; ++i) sol[i] = INF; } void solve() { init(); scanf("%d%d", &M, &N); for (int i = 0; i < N; ++i) { char s[2]; scanf("%s", s); I[i].type = (s[0] == 'C' || s[0] == 'E'); } for (int i = 0; i < N; ++i) scanf("%d", &I[i].lo); for (int i = 0; i < N; ++i) scanf("%d", &I[i].hi); Tournament red_begin(M + 10); Tournament blue_begin(M + 10); sort(I, I + N); int ptr = 0; dp[0] = 0; for (int i = 1; i <= M; ++i) { dp[i] = dp[i - 1]; while (ptr < N && I[ptr].hi == i) { if (I[ptr].lo >= I[ptr].hi) { ++ptr; continue; } if (I[ptr].type) red_begin.inc_interval(0, I[ptr].lo + 1, 1); else blue_begin.inc_interval(0, I[ptr].lo + 1, 1); ++ptr; } dp[i] = max(red_begin.get_max(0, i), blue_begin.get_max(0, i)); red_begin.inc_interval(i, i + 1, dp[i]); blue_begin.inc_interval(i, i + 1, dp[i]); // for (int i = 0; i <= M; ++i) // printf("%d ", red_begin.get_sum(i, i + 1)); // printf("\n"); // for (int i = 0; i <= M; ++i) // printf("%d ", blue_begin.get_sum(i, i + 1)); // printf("\n"); // for (int i = 0; i <= M; ++i) // printf("%d ", dp[i]); // printf("\n"); // printf("\n"); } // for (int i = 0; i <= M; ++i) // printf("%d ", red.get_sum(i, i + 1)); // printf("\n"); // for (int i = 0; i <= M; ++i) // printf("%d ", blue.get_sum(i, i + 1)); // printf("\n"); ptr = 1; for (int i = 1; i <= N; ++i) { while (ptr <= M && dp[ptr] < i) ++ptr; if (ptr <= M) printf("%d ", ptr); else printf("-1 "); } printf("\n"); } int main(void) { scanf("%d", &T); while (T --> 0) solve(); return 0; }