#include using namespace std; typedef vector vi; typedef pair ii; typedef long long ll; typedef pair l4; typedef vector vll; typedef double db; typedef vector vdb; typedef pair dd; typedef set si; typedef set sll; #define fi first #define se second #define matrix(a) vector< vector > #define sz(a) int((a).size()) #define lop(i,a,b) for (int i=a; i<=b; i++) #define rlop(i,a,b) for (int i=b; i>=a; i--) #define all(s) (s).begin(),(s).end() #define pb push_back #define enter cout<<'\n' #define lb(i,v) int(lower_bound(all(v),i)-v.begin()) #define ub(i,v) int(upper_bound(all(v),i)-v.begin()) int cases,m,n; void initialize(int start, vi& stree, vi& level, int l, int u) { if (sz(stree) - 1 < start)stree.resize(start + 1); if (l == u)stree[start] = level[l]; else { initialize(2 * start, stree, level, l, (u + l) / 2); initialize(2 * start + 1, stree, level, (u + l) / 2 + 1, u); stree[start] = max(stree[start*2],stree[start * 2 + 1]); } return; } void updatetree(int start, vi& stree, int index, int value, int l, int u) { if (l == u){ stree[start]+=value; return; } if (index <= (l + u) / 2)updatetree(2 * start, stree, index, value, l, (l + u) / 2); else updatetree(2 * start + 1, stree, index, value, (l + u) / 2 + 1, u); stree[start] = max(stree[start*2],stree[start * 2 + 1]); return; } void push(int start, vi& stree, vi& update, int l, int u){ stree[start]+=update[start]; if(l j)swap(i, j); if (ju)return -1; if (l >= i&&u <= j){ push(start,stree,update,l,u); return stree[start]; } push(2*start,stree,update,l,(u+l)/2); push(2*start+1,stree,update,(u+l)/2+1,u); int t1 = rmq(2 * start, stree, update, i, j, l, (u + l) / 2); int t2 = rmq(2 * start + 1, stree, update, i, j, (u + l) / 2 + 1, u); return max(t1,t2); } void lazyupdate(int start, vi& stree, vi& update,int value, int i,int j,int l,int u){ if (ju)return; if (l >= i&&u <= j){ update[start]+=value; return; } push(2*start,stree,update,l,(u+l)/2); push(2*start+1,stree,update,(u+l)/2+1,u); lazyupdate(2 * start, stree,update,value, i, j, l, (u + l) / 2); lazyupdate(2 * start + 1, stree, update,value, i, j, (u + l) / 2 + 1, u); stree[start]=max(stree[start*2]+update[start*2],stree[start*2+1]+update[start*2+1]); return; } int main() { cin >> cases; for(int a0 = 0; a0 < cases; a0++){ cin >> m >> n; vi t(n),s(n),d(n); char c; lop(i,0,n-1){ cin >> c; t[i]=(c=='D'||c=='M'); } matrix(int) dog(m+1),cat(m+1); lop(i,0,n-1)cin >> s[i]; lop(i,0,n-1)cin >> d[i]; lop(i,0,n-1){ if(d[i]>s[i]){ if(t[i])dog[d[i]].pb(s[i]); else cat[d[i]].pb(s[i]); } } vi dogbest(m+1,0),catbest(m+1,0),dogstree,catstree; initialize(1,dogstree,dogbest,1,m); initialize(1,catstree,catbest,1,m); vi dogupdate(sz(dogstree),0),catupdate(sz(catstree),0); lop(i,2,m){ lop(j,0,sz(dog[i])-1)lazyupdate(1,dogstree,dogupdate,1,1,dog[i][j],1,m); lop(j,0,sz(cat[i])-1)lazyupdate(1,catstree,catupdate,1,1,cat[i][j],1,m); dogbest[i]=rmq(1,dogstree,dogupdate,1,i-1,1,m); catbest[i]=rmq(1,catstree,catupdate,1,i-1,1,m); updatetree(1,dogstree,i,catbest[i],1,m); updatetree(1,catstree,i,dogbest[i],1,m); } int query=1; lop(i,1,m){ int best=max(catbest[i],dogbest[i]); lop(j,query,best)cout<