//Priyanshu Kumar : IIIT Allahabad #include using namespace std; #define ull unsigned long long int #define ll long long int #define MAX 50005 #define MOD 1000000007 #define sz size() #define ln length() #define pb push_back #define mp make_pair #define fi first #define se second #define si(n) scanf("%d",&n) #define sl(n) scanf("%lld",&n) #define pi(n) printf("%d",n) #define pin(n) printf("%d\n",n); #define pl(n) printf("%lld",n) #define pln(n) printf("%lld\n",n); #define FUCK_YEAH ios_base::sync_with_stdio(false);cin.tie(NULL) inline ll gcd(ll x,ll y){return x%y==0?y:gcd(y,x%y);} inline ll lcm(ll x,ll y){return x*(y/gcd(x,y));} inline ll powmod(ll a,ll b,ll mod) { ll res=1; a%=mod; assert(b>=0); for(;b;b>>=1) { if(b&1)res=res*a%mod; a=a*a%mod; } return res; } inline ll mulmod(ll a, ll b, ll c) { if(!b)return 0; ll x = mulmod(a, b/2, c); if (b & 1)return (x+x+a)%c; return (x+x)%c; } struct seg { ll laz, ans; seg(ll _ans = 0,ll _laz = 0) { laz = _laz; ans = _ans; } }tree[2][4*MAX]; seg merge(seg a, seg b) { seg ret; ret.ans = max(a.ans, b.ans); ret.laz = 0; return ret; } void lazyupdate(int id, int node, int L, int R){ if (!tree[id][node].laz) return; tree[id][node].ans = tree[id][node].ans + tree[id][node].laz; if(L != R) { tree[id][node*2].laz += tree[id][node].laz; tree[id][node*2+1].laz += tree[id][node].laz; } tree[id][node].laz = 0; } void build(int id, ll node, ll L, ll R) { if (L == R){ tree[id][node] = seg(0,0); return; } build(id, node*2, L, (L+R)/2); build(id, node*2+1, (L+R)/2+1, R); tree[id][node] = merge(tree[id][node*2], tree[id][node*2+1]); } void update(int id, int node,int L,int R,int l,int r,int v){ lazyupdate(id, node, L, R); if (L > r || R < l) return; if (l <= L && R <= r) { tree[id][node].laz = v; lazyupdate(id, node, L, R); return; } update(id, node*2, L, (L+R)/2, l, r, v); update(id, node*2+1, (L+R)/2+1,R, l, r, v); tree[id][node] = merge(tree[id][node*2], tree[id][node*2+1]); } void pointupdate(int id, int node,int L,int R,int ind,int v){ lazyupdate(id, node, L, R); if (L > ind || R < ind) return; if (ind == L && R == ind) { tree[id][node].ans = v; tree[id][node].laz = 0; return; } pointupdate(id,node*2, L, (L+R)/2, ind, v); pointupdate(id,node*2+1, (L+R)/2+1,R, ind, v); tree[id][node] = merge(tree[id][node*2], tree[id][node*2+1]); } seg query(int id, ll node, ll L, ll R, ll l, ll r) { lazyupdate(id, node, L, R); if (L > r || R < l) return seg(); if (l <= L && R <= r) return tree[id][node]; return merge(query(id, node*2, L, (L+R)/2, l, r),query(id, node*2+1, (L+R)/2+1, R, l, r)); } ll bit[2][MAX]; ll querybit(ll p,ll indx){ ll sum = 0; while (indx) { sum += bit[p][indx]; indx -= (indx & -indx); } return sum; } void updatebit(ll p,ll indx, ll x){ assert(indx != 0); while (indx < MAX) { bit[p][indx] += x; indx += (indx & -indx); } } char t[MAX]; ll s[MAX],d[MAX],dp[MAX], ans[MAX], vis[MAX]; vector vec[MAX],vdm[MAX]; int main() { FUCK_YEAH; ll tc,n,m,sp,ind; cin >> tc; while(tc--) { cin >> n >> m; build(0,1,1,n); build(1,1,1,n); for(int i = 0; i < MAX; i++) { bit[0][i] = bit[1][i] = 0; vec[i].clear(); vdm[i].clear(); } for(int i=0;i> t[i]; } for(int i=0;i> s[i]; } for(int i=0;i> d[i]; if(d[i] < s[i]) continue; if(t[i] == 'E' || t[i] == 'C') { vec[d[i]].pb(s[i]); } else { vdm[d[i]].pb(s[i]); } } for(int i = 1; i <= n; i++) { dp[i] = 0; for(int j = 0; j < vec[i].size(); j++) { update(0,1,1,n,1,vec[i][j],1); } for(int j = 0; j < vdm[i].size(); j++) { //updatebit(1,vdm[i][j],1); update(1,1,1,n,1,vdm[i][j],1); } dp[i] = max(query(0,1,1,n,1,i-1).ans,query(1,1,1,n,1,i-1).ans); ans[dp[i]] = min(ans[dp[i]],(ll)i); pointupdate(0,1,1,n,i,dp[i]); pointupdate(1,1,1,n,i,dp[i]); } for(int i = m - 1; i >= 1; i--) { ans[i] = min(ans[i],ans[i+1]); } for(int i = 1; i <= m; i++) { if(ans[i] == 100000) ans[i] = -1; cout << ans[i] << " "; } cout << endl; } return 0; }