#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=3e5+10,mod=998244353;
vector<pair<int,int> >v[N];
int b[N<<1],siz;
int se(int u){return lower_bound(b+1,b+siz+1,u)-b;}
int tr[N<<3],ans[N],up[N],lazy[N<<3];//这块要开n的八倍是b数组的四倍;
int ls(int u){return u<<1;}
int rs(int u){return u<<1|1;}
int se(int x,int y){return ans[x]>ans[y]?x:y;}//。。。。就那样吧。
void push_up(int u){tr[u]=se(tr[ls(u)],tr[rs(u)]);}//不懂为什么可以直接赋值,我是每次比较了;
//对第i个数求前一行的时候加入选了第i块
//假如现在看到第i行更新第i行的每一块的时候好像都是比原先的要大,如果不大的话就可以取那个大的为现在的;
//原来如此;
void take(int u,int t){lazy[u]=se(lazy[u],t);tr[u]=se(t,tr[u]);}
void push_down(int u,int l,int r)
{
if(!lazy[u])return ;
take(l,lazy[u]);
take(r,lazy[u]);
lazy[u]=0;
}
int quary(int u,int l,int r,int a,int b)
{
if(a<=l&&b>=r)return tr[u];
int mid=l+r>>1,x=0,y=0;
push_down(u,ls(u),rs(u));
if(a<=mid)x=quary(ls(u),l,mid,a,b);
if(b>mid)y=quary(rs(u),mid+1,r,a,b);
return se(x,y);
}
void modify(int u,int l,int r,int a,int b,int t)
{
if(a<=l&&b>=r){
take(u,t);
return ;
}
push_down(u,ls(u),rs(u));
int mid=l+r>>1;
if(a<=mid)modify(ls(u),l,mid,a,b,t);
if(b>mid)modify(rs(u),mid+1,r,a,b,t);
push_up(u);
return ;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
v[x].push_back({y,z});
b[i*2-1]=y;
b[i*2]=z;
}
sort(b+1,b+2*m+1);
siz=unique(b+1,b+2*m+1)-b-1;
v[n+1].push_back({b[1],b[siz]});//就这调了我一下午,原因就是之前写了({1,siz})。。哎;
for(int i=1;i<=n+1;i++)
{
int x=0;
for(int j=0;j<v[i].size();j++)
{
int l=v[i][j].first,r=v[i][j].second;
l=se(l),r=se(r);
v[i][j]={l,r}; //下面就懒得找了。
int t=quary(1,1,siz,l,r);
if(x<ans[t])x=ans[t],up[i]=t;
}
ans[i]=x+1;
for(int j=0;j<v[i].size();j++)
modify(1,1,siz,v[i][j].first,v[i][j].second,i);
}
int i=up[n+1];
while(i)ans[i]=0,i=up[i];//每个ans至少为1代表只选他;
cout<<n-ans[n+1]+1<<endl;
for(int i=1;i<=n;i++)
if(ans[i])cout<<i<<' ';
return 0;
}