#include using namespace std; const int maxn = 5e4 + 50; const int inf = 0x3f3f3f3f; int T , m , n , dp[maxn] , pos[maxn] , ID[maxn] , Lft[maxn] , Rht[maxn]; char tmp[5]; vector < pair < int , int > > s1 , s2; struct Segtree{ struct Node{ int l , r , lzy , maxadd , flag , zs; void gaomax( int x ){ flag = 1; maxadd = max( maxadd , x + lzy ); zs = max( zs , x + lzy ); } void add( int x ){ lzy += x; } }tree[maxn << 2]; void build( int l , int r , int o ){ tree[o].l = l , tree[o].r = r , tree[o].lzy = 0 , tree[o].zs = 0 , tree[o].maxadd = -inf , tree[o].flag = 0; if( l < r ){ int mid = l + r >> 1; build( l , mid , o << 1 ); build( mid + 1 , r , o << 1 | 1 ); } } void push_down( int o ){ if( tree[o].flag ){ tree[o << 1].gaomax( tree[o].maxadd ); tree[o << 1 | 1].gaomax( tree[o].maxadd ); tree[o].maxadd = -inf; tree[o].flag = 0; } if( tree[o].lzy ){ tree[o << 1].add( tree[o].lzy ); tree[o << 1 | 1].add( tree[o].lzy ); tree[o].lzy = 0; } } void update1( int ql , int qr , int x , int o ){ int l = tree[o].l , r = tree[o].r; if( ql <= l && r <= qr ) tree[o].add( x ); else{ int mid = l + r >> 1; push_down( o ); if( ql <= mid ) update1( ql , qr , x , o << 1 ); if( qr > mid ) update1( ql , qr , x , o << 1 | 1 ); } } void update2( int ql , int qr , int x , int o ){ int l = tree[o].l , r = tree[o].r; if( ql <= l && r <= qr ) tree[o].gaomax( x ); else{ int mid = l + r >> 1; push_down( o ); if( ql <= mid ) update2( ql , qr , x , o << 1 ); if( qr > mid ) update2( ql , qr , x , o << 1 | 1 ); } } int query( int x , int o ){ int l = tree[o].l , r = tree[o].r; if( l == r ) return tree[o].zs; else{ push_down( o ); int mid = l + r >> 1; if( x <= mid ) return query( x , o << 1 ); else return query( x , o << 1 | 1 ); } } }f1,f2; inline void Update( int & x , int y ){ x = max( x , y ); } int main( int argc , char * argv[] ){ // freopen( "Sample" , "r" , stdin ); scanf( "%d" , & T ); while( T -- ){ scanf( "%d%d" , & m , & n ); memset( dp , 0 , sizeof( dp ) ); memset( pos , 0x3f , sizeof( pos ) ); f1.build(1,m,1); f2.build(1,m,1); s1.clear(); s2.clear(); for(int i = 1 ; i <= n ; ++ i){ scanf( "%s" , tmp ); if( tmp[0] == 'E' ) ID[i] = 0; else if( tmp[0] == 'D' ) ID[i] = 1; else if( tmp[0] == 'C' ) ID[i] = 2; else ID[i] = 3; } for(int i = 1 ; i <= n ; ++ i) scanf( "%d" , Lft + i ); for(int i = 1 ; i <= n ; ++ i) scanf( "%d" , Rht + i ); for(int i = 1 ; i <= n ; ++ i) if( Lft[i] < Rht[i] ){ if( ID[i] & 1 ) s1.push_back( { Lft[i] , Rht[i] } ); else s2.push_back( { Lft[i] , Rht[i] } ); } sort( s1.begin() , s1.end() ); sort( s2.begin() , s2.end() ); for(auto && it : s1) f1.update1(it.second,m,1,1); for(auto && it : s2) f2.update1(it.second,m,1,1); for(int i = 1 , j1 = 0 , j2 = 0 ; i <= m ; ++ i){ dp[i] = max( dp[i] , max( f1.query( i , 1 ) , f2.query( i , 1 ) ) ); dp[i + 1] = max( dp[i + 1] , dp[i] ); if( i < m ){ f1.update2( i + 1 , m , dp[i] , 1 ); f2.update2( i + 1 , m , dp[i] , 1 ); } while( j1 < s1.size() && s1[j1].first <= i ) f1.update1(s1[j1++].second,m,-1,1); while( j2 < s2.size() && s2[j2].first <= i ) f2.update1(s2[j2++].second,m,-1,1); if( pos[dp[i]] > i ) pos[dp[i]] = i; } for(int i = n - 1 ; i >= 1 ; -- i) pos[i] = min( pos[i + 1] , pos[i] ); for(int i = 1 ; i <= n ; ++ i){ if( i > 1 ) putchar( 32 ); if( pos[i] == inf ) printf( "-1" ); else printf( "%d" , pos[i] ); } puts( "" ); } return 0; }