//这道题 打比赛的时候 wa的我怀疑人生 怎么说 这个 最后 我才明白 这个题的坑点 就是这个题坑就坑在 它撤回 可能会 是 也是个 撤回语句 那么 前面
//的那个撤回语句 就会失效 那么我们 要先存下 撤回语句 然后 我们就直接 从后往前 排就行。。点击打开链接
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
#include <math.h>
#include <vector>
#include <map>
using namespace std;
map<int,int>mp;
int mm[50050];
int nn[56005];
bool jd[56005];
int ans[56005];
int ch[56005];
int chh[56005];
int main()
{
int t,n,m,x,y,sum,tt;
scanf("%d",&t);
while(t--)
{ tt=0;
sum=0;
mp.clear();
memset(ch,0,sizeof(ch));
memset(jd,0,sizeof(jd));
memset(mm,0,sizeof(mm));
memset(nn,0,sizeof(nn));
memset(ch,0,sizeof(ch));
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&mm[i],&nn[i]);
if(mm[i]==3)
{
ch[tt]=nn[i];
chh[tt++]=i;
}
}
for(int i=tt-1;i>=0;i--)
{
if(!mp[chh[i]])
{
mp[ch[i]]=1;
}
}
for(int i=1;i<=m;i++)
{
if(!mp[i])
{
if(mm[i]==1)
{
jd[nn[i]]=1;
}
else if(mm[i]==2)
jd[nn[i]]=0;
}
}
for(int i=1;i<=n;i++)
{
if(jd[i])
{
ans[sum++]=i;
}
}
printf("%d\n",sum);
for(int i=0;i<sum;i++)
printf("%d ",ans[i]);
printf("\n");
}
return 0;
}