#include #define pb push_back #define mp make_pair #define fi first #define se second #define eb emplace_back #define mt make_tuple using namespace std; typedef long long ll; typedef pair ii; const int N = 50010; int m, n; int animal[N][3]; vector zoo[N]; int pd[N], ans[N]; struct segtree { int tree[4*N]; int lazy[4*N]; void clear() { memset(tree, 0, sizeof(tree)); memset(lazy, 0, sizeof(lazy)); } segtree() { clear(); } void prop(int start, int end, int pos) { tree[pos] += lazy[pos]; if (start != end) { lazy[2*pos + 1] += lazy[pos]; lazy[2*pos + 2] += lazy[pos]; } lazy[pos] = 0; } int update(int start, int end, int ustart, int uend, int val, int pos) { prop(start, end, pos); if (ustart > end or uend < start) return tree[pos]; if (start >= ustart and end <= uend) { lazy[pos] += val; prop(start, end, pos); return tree[pos]; } int mid = (start+end)/2; int l = update(start, mid, ustart, uend, val, 2*pos + 1); int r = update(mid+1, end, ustart, uend, val, 2*pos + 2); return tree[pos] = max(l, r); } int query(int start, int end, int qstart, int qend, int pos) { if (qstart > end or qend < start) return 0; prop(start, end, pos); if (start >= qstart and end <= qend) return tree[pos]; int mid = (start+end)/2; int l = query(start, mid, qstart, qend, 2*pos + 1); int r = query(mid+1, end, qstart, qend, 2*pos + 2); return max(l, r); } }; segtree ctree, dtree; int main() { int tc; scanf("%d", &tc); while(tc--) { scanf("%d %d", &m, &n); for (int i = 1; i <= m; i++) zoo[i].clear(); memset(pd, 0, sizeof(pd)); ctree.clear(); dtree.clear(); for (int j = 0; j < 3; j++) { for (int i = 0; i < n; i++) { char s[5]; if (j == 0) { scanf("%s", s); animal[i][j] = s[0]; } else scanf("%d", &animal[i][j]); } } for (int i = 0; i < n; i++) { if (animal[i][1] > animal[i][2]) continue; if (animal[i][0] == 'D' or animal[i][0] == 'M') zoo[animal[i][2]].eb(animal[i][1], 0); else zoo[animal[i][2]].eb(animal[i][1], 1); } for (int i = 1; i <= m; i++) { for (int a = 0; a < zoo[i].size(); a++) { int s, t; tie(s, t) = zoo[i][a]; if (t) ctree.update(1, m, 1, s, 1, 0); else dtree.update(1, m, 1, s, 1, 0); } pd[i] = max(ctree.query(1, m, 1, i-1, 0), dtree.query(1, m, 1, i-1, 0)); ctree.update(1, m, i, i, pd[i], 0); dtree.update(1, m, i, i, pd[i], 0); /* for (int j = i-1; j >= 1; j--) { pd[i] = max(pd[i], query_cats(i) - query_cats(j-1) + pd[j]); pd[i] = max(pd[i], query_dogs(i) - query_dogs(j-1) + pd[j]); } */ } memset(ans, -1, sizeof(ans)); for (int i = m; i >= 1; i--) ans[pd[i]] = i; int last = -1; for (int i = n; i >= 1; i--) { if (ans[i] != -1) last = ans[i]; else ans[i] = last; } for (int i = 1; i <= n; i++) printf("%d%c", ans[i], " \n"[i == n]); //for (int i = 1; i <= m; i++) // printf("pd[%d] = %d\n", i, pd[i]); } return 0; }