pure Tuple!(int, int) F(Tuple!(int, int) a, Tuple!(int, int) b) { return a > b? a : b; }
pure Tuple!(int, int) FoU(Tuple!(int, int) mx, Tuple!(int, int) st, size_t l) { return st; }
pure Tuple!(int, int) UoU(Tuple!(int, int) nw, Tuple!(int, int) ld) { return nw; }

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	alias SegTree = STL!(Tuple!(int, int), Tuple!(int, int))
		.Type!(tuple(0, -1),
				F, FoU, UoU,
				"max", "+");
	auto st = SegTree(noPoints, tuple(0, -1));
	auto dp = new Tuple!(int, int)[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = tuple(0, -1);
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st[range[0] .. range[1] + 1].max);
		}
		dpi[0]++;
		foreach(range; ranges[i])
		{
			st[range[0] .. range[1] + 1] += tuple(dpi[0], cast(int)i);
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i][0] > bdpi)
		{
			bdpi = dp[i][0];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;
	while (bi >= 0)
	{
		alive[bi] = false;
		bi = dp[bi][1];
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
template STL(V, U)
{
	struct Type (V neutral, alias f,
			alias fou,
			alias uou,
			string fName = "f", string uName = "u")
	{
		V[] _nF;
		U[] _nU;
		size_t[] _nSz;
		bool[] _nHasU;
		size_t length = 0;
		int layers = 0;
		this(size_t n, V v)
		{
			n = cast(size_t)nextPow2(cast(long)n);
			auto fn = n;
			while (fn) {layers++; fn >>= 1;}
			length = n;
			auto noNodes = 2 * n;
			_nF = new V[](noNodes);
			static if (neutral != V.init) _nF[n .. 2 * n] = v;
			foreach_reverse(i; 1 .. n) _nF[i] = f(_nF[i<<1], _nF[(i<<1)+1]);
			_nU = new U[](noNodes);
			_nHasU = new bool[](noNodes);
			_nSz = new size_t[](noNodes);
			_nSz[n .. 2 * n] = 1;
			foreach_reverse(i; 1 .. n) _nSz[i] = _nSz[i<<1] * 2;
		}
		void _clearU(size_t l, size_t r)
		{
			r--;
			auto li = layers - 1;
			for(; li > 0 && (l >> li) == (r >> li); li--) _clearU(l >> li);
			for(; li > 0; li--) _clearU(l >> li), _clearU(r >> li);
		}
		void _refresh(size_t l, size_t r)
		{
			r--;
			l >>= 1; r >>= 1;
			for(; l != r; l >>= 1, r >>= 1)
			{
				_nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
				_nF[r] = f(_getNodeF(r<<1), _getNodeF((r<<1)+1));
			}
			for(; l; l >>= 1) _nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
		}
		V rangeF(size_t l, size_t r)
		{
			l += length, r += length;
			_clearU(l, r);
			V value = neutral;
			for(; l < r; l >>= 1, r >>= 1)
			{
				if (l & 1) value = f(value, _getNodeF(l++));
				if (r & 1) value = f(value, _getNodeF(--r));
			}
			return value;
		}
		void rangeU(size_t l, size_t r, U u)
		{
			l += length, r += length;
			auto ol = l, or = r;
			for(; l < r; l >>= 1, r >>= 1)
			{
				if (l & 1) _addU(l++, u);
				if (r & 1) _addU(--r, u);
			}
			_refresh(ol, or);
		}
		V _getNodeF(size_t i)
		{
			if (_nHasU[i]) return cast(V) fou(_nF[i], _nU[i], _nSz[i]);
			return _nF[i];
		}
		bool _isLeaf(size_t i)
		{
			return i >= length;
		}
		void _clearU(size_t i)
		{
			if (!_nHasU[i]) return;
			if (_isLeaf(i))
			{
				_nF[i] = _getNodeF(i);
				_nHasU[i] = false;
				return;
			}
			_nHasU[i] = false;
			_addU(i << 1, _nU[i]), _addU((i << 1) + 1, _nU[i]);
			_nF[i] = f(_getNodeF(i<<1), _getNodeF((i<<1)+1));
		}
		void _addU(size_t i, U u)
		{
			if (!_nHasU[i])
			{
				_nU[i] = u;
				_nHasU[i] = true;
				return;
			}
			_nU[i] = uou(u, _nU[i]);
		}
		int[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
		{
			return [cast(int)start, cast(int)end];
		}
		auto opIndex(int[2] slice)
		{
			alias Parent = typeof(this);
			struct Ans
			{
				Parent* parent;
				int[2] slice;
				mixin(q{V }, fName, q{;});
				void opOpAssign(string op)(U u) if (op == uName)
				{
					parent.rangeU(slice[0], slice[1], u);
				}
			}
			return Ans(&this, slice, rangeF(slice[0], slice[1]));
		}
	}
}
long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = STL!(int, int).Type!(0,
			(v1, v2) => v1 + v2,
			(v, u, size_t l) => v + u * cast(int)l,
			(ni, pi) => ni + pi,
			"sum",
			"+");
	auto n = 100;
	int[] brute = new int[](n);
	auto smart = SumQSumU(n, 0);
	int rounds = 1000;
	foreach(round; 0 .. rounds)
	{
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				int v = uniform!"[]"(1, 20);
				brute[i .. j] += v;
				smart[i .. j] += v;
			}
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
				auto smartAnswer = smart[i .. j].sum;
				assert(bruteAnswer == smartAnswer);
			}
	}
}
// }}}

immutable multi = false;
void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	alias SegTree = TSTL!(int[2], "max", "set", [0, -1]);
	auto st = SegTree(noPoints, [0, -1]);
	auto dp = new int[2][](n);
	foreach(i, ref dpi; dp)
	{
		dpi = [0, -1];
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st.maxRange(range[0], range[1] + 1));
		}
		dpi[0]++;
		foreach(range; ranges[i])
		{
			st[range[0] .. range[1] + 1] = [dpi[0], cast(int)i];
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i][0] > bdpi)
		{
			bdpi = dp[i][0];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;
	while (bi >= 0)
	{
		alive[bi] = false;
		bi = dp[bi][1];
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
struct STL(V, U,
		V neutral,
		alias f,
		alias fou,
		alias uou,
		string fName = "f", string uName = "u")
{
	import std.traits;
	static pure bool isSingular(T)(T t)
	{
		pragma(inline, true);
		static if (isNumeric!T) return t == T.min;
		else return t[0] == typeof(t[0]).min;
	}
	static enum singular(T) = ()
	{
		static if (isNumeric!T) return T.min;
		else
		{
			T t;
			t[0] = typeof(t[0]).min;
			return t;
		}
	}();
	struct Node
	{
		V f;
		U u = singular!U;
	}
	Node[] _n;
	size_t length = 0;
	int layers = 0;
	this(size_t n, V v)
	{
		import std.math;
		n = cast(size_t) nextPow2(n);
		layers = cast(int) log2(n) + 1;
		length = n;
		auto noNodes = 2 * n;

		_n = new Node[](noNodes);

		foreach(i; n .. 2 * n)
		{
			_n[i].f = v;
		}
		foreach_reverse(i; 1 .. n)
		{
			_n[i].f = f(_n[i<<1].f, _n[(i<<1)^1].f);
		}
	}
	void _clearU(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach_reverse(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _clearU(l >> layer);
			if (r & lowerBits) _clearU(r >> layer);
		}
	}
	void _refresh(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _refresh(l >> layer);
			if (r & lowerBits) _refresh(r >> layer);
		}
	}
	void _refresh(size_t i)
	{
		pragma(inline, true);
		assert(!_isLeaf(i));
		_n[i].f = f(_n[i<<1].f, _n[(i<<1)^1].f);
	}
	V rangeF(size_t l, size_t r)
	{
		l += length, r += length;
		_clearU(l, r);
		V value = neutral;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1)
				value = f(value, _n[l++].f);
			if (r & 1)
				value = f(value, _n[--r].f);
		}
		return value;
	}
	mixin(q{alias }, fName, q{Range = rangeF;});
	void rangeU(size_t l, size_t r, U u)
	{
		l += length, r += length;
		auto ol = l, or = r;
		_clearU(l, r);
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) _addU(l++, u);
			if (r & 1) _addU(--r, u);
		}
		_refresh(ol, or);
	}
	static if (uName == "set")
	{
		auto opIndexAssign(U u, size_t[2] slice)
		{
			rangeU(slice[0], slice[1], u);
			return this;
		}
	}
	else static if (uName == "add")
	{

	}
	bool _isLeaf(size_t i)
	{
		pragma(inline, true);
		return i >= length;
	}
	void _clearU(size_t i)
	{
		pragma(inline, true);
		if (isSingular(_n[i].u)) return;
		assert(!_isLeaf(i));
		_addU(i << 1, _n[i].u), _addU((i << 1) ^ 1, _n[i].u);
		_n[i].u = singular!U;
		assert(_n[i].f == f(_n[i<<1].f, _n[(i<<1)^1].f));
	}
	void _addU(size_t i, U u)
	{
		import core.bitop;
		pragma(inline, true);
		if (isSingular(_n[i].u))
			_n[i].u = u;
		else
			_n[i].u = uou(u, _n[i].u);
		_n[i].f = fou(_n[i].f, u, length >> bsr(i));
	}
	size_t[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
	{
		return [start, end];
	}
}
template TSTL(V, string f, string u, neutral...)
{
	alias funF = mixin(f);
	alias funUoU = mixin(u);
	alias funFoU = mixin(f, "O", u);
	static if (neutral.length == 1)
		immutable neut = neutral[0];
	else static if (neutral.length == 0)
	{
		alias neutralTemplate = mixin(f, "Neutral");
		immutable neut = neutralTemplate!V;
	}
	else static assert(false);
	alias TSTL = STL!(V, V, neut, funF!V, funFoU!V, funUoU!V, f, u);
}
immutable maxNeutral(T) = T.min;
pure T max(T)(T a, T b)
{
	pragma(inline, true);
	return a > b? a : b;
}
immutable addNeutral(T) = T(0);
pure T add(T)(T a, T b)
{
	pragma(inline, true);
	return a + b;
}
pure T min(T)(T a, T b)
{
	pragma(inline, true);
	return a < b? a : b;
}
pure T set(T)(T a, T b)
{
	pragma(inline, true);
	return a;
}
pure T maxOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T maxOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T minOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T minOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T addOadd(T)(T sm, T ad, size_t l)
{
	pragma(inline, true);
	return sm + ad * cast(T)l;
}

long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = TSTL!(int, "add", "add");
	version(velocity)
	{
		int n = 100_000;
		int q = 100_000;
		auto st = SumQSumU(n, 0);
		int tot = 0;
		foreach(i; 0 .. q)
		{
			int f = uniform!"[)"(0, n);
			int t = uniform!"[]"(f + 1, n);
			if (i&1)
			{
				tot += st.addRange(f, t);
			}
			else
			{
				int u = uniform!"[)"(-1000, 1000);
				st.rangeU(f, t, u);
			}
		}
	}
	else
	{
		auto n = 1000;
		int[] brute = new int[](n);
		auto smart = SumQSumU(n, 0);
		int rounds = 10;
		foreach(round; 0 .. rounds)
		{
			foreach(i; 0 .. n)
				foreach(j; i + 1 .. n + 1)
				{
					int v = uniform!"[]"(1, 20);
					brute[i .. j] += v;
					smart.rangeU(i, j, v);
				}
			foreach(i; 0 .. n)
				foreach(j; i + 1 .. n + 1)
				{
					auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
					auto smartAnswer = smart.rangeF(i, j);
					assert(bruteAnswer == smartAnswer);
				}
		}
	}
}
// }}}

immutable multi = false;
void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	alias SegTree = TSTL!(int[2], "max", "set", [0, -1]);
	auto st = SegTree(noPoints, [0, -1]);
	auto dp = new int[2][](n);
	foreach(i, ref dpi; dp)
	{
		dpi = [0, -1];
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st.maxRange(range[0], range[1] + 1));
		}
		dpi[0]++;
		foreach(range; ranges[i])
		{
			st[range[0] .. range[1] + 1] = [dpi[0], cast(int)i];
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i][0] > bdpi)
		{
			bdpi = dp[i][0];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;
	while (bi >= 0)
	{
		alive[bi] = false;
		bi = dp[bi][1];
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
struct STL(V, U,
		V neutral,
		alias f,
		alias fou,
		alias uou,
		string fName = "f", string uName = "u")
{
	import std.traits;
	static pure bool isSingular(T)(T t)
	{
		static if (isNumeric!T) return t == T.min;
		else return t[0] == typeof(t[0]).min;
	}
	static enum singular(T) = ()
	{
		static if (isNumeric!T) return T.min;
		else
		{
			T t;
			t[0] = typeof(t[0]).min;
			return t;
		}
	}();
	struct Node
	{
		V f;
		U u = singular!U;
	}
	Node[] _n;
	size_t length = 0;
	int layers = 0;
	this(size_t n, V v)
	{
		import std.math;
		n = cast(size_t) nextPow2(n);
		layers = cast(int) log2(n) + 1;
		length = n;
		auto noNodes = 2 * n;

		_n = new Node[](noNodes);

		foreach(i; n .. 2 * n)
		{
			_n[i].f = v;
		}
		foreach_reverse(i; 1 .. n)
		{
			_n[i].f = f(_n[i<<1].f, _n[(i<<1)^1].f);
		}
	}
	void _clearU(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach_reverse(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _clearU(l >> layer);
			if (r & lowerBits) _clearU(r >> layer);
		}
	}
	void _refresh(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _refresh(l >> layer);
			if (r & lowerBits) _refresh(r >> layer);
		}
	}
	void _refresh(size_t i)
	{
		pragma(inline, true);
		assert(!_isLeaf(i));
		_n[i].f = f(_n[i<<1].f, _n[(i<<1)^1].f);
	}
	V rangeF(size_t l, size_t r)
	{
		l += length, r += length;
		_clearU(l, r);
		V value = neutral;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1)
				value = f(value, _n[l++].f);
			if (r & 1)
				value = f(value, _n[--r].f);
		}
		return value;
	}
	mixin(q{alias }, fName, q{Range = rangeF;});
	void rangeU(size_t l, size_t r, U u)
	{
		l += length, r += length;
		auto ol = l, or = r;
		_clearU(l, r);
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) _addU(l++, u);
			if (r & 1) _addU(--r, u);
		}
		_refresh(ol, or);
	}
	static if (uName == "set")
	{
		auto opIndexAssign(U u, size_t[2] slice)
		{
			rangeU(slice[0], slice[1], u);
			return this;
		}
	}
	else static if (uName == "add")
	{

	}
	bool _isLeaf(size_t i)
	{
		pragma(inline, true);
		return i >= length;
	}
	void _clearU(size_t i)
	{
		pragma(inline, true);
		if (isSingular(_n[i].u)) return;
		assert(!_isLeaf(i));
		_addU(i << 1, _n[i].u), _addU((i << 1) ^ 1, _n[i].u);
		_n[i].u = singular!U;
		assert(_n[i].f == f(_n[i<<1].f, _n[(i<<1)^1].f));
	}
	void _addU(size_t i, U u)
	{
		import core.bitop;
		pragma(inline, true);
		if (isSingular(_n[i].u))
			_n[i].u = u;
		else
			_n[i].u = uou(u, _n[i].u);
		_n[i].f = fou(_n[i].f, u, length >> bsr(i));
	}
	size_t[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
	{
		return [start, end];
	}
}
template TSTL(V, string f, string u, neutral...)
{
	alias funF = mixin(f);
	alias funUoU = mixin(u);
	alias funFoU = mixin(f, "O", u);
	static if (neutral.length == 1)
		immutable neut = neutral[0];
	else static if (neutral.length == 0)
	{
		alias neutralTemplate = mixin(f, "Neutral");
		immutable neut = neutralTemplate!V;
	}
	else static assert(false);
	alias TSTL = STL!(V, V, neut, funF!V, funFoU!V, funUoU!V, f, u);
}
immutable maxNeutral(T) = T.min;
pure T max(T)(T a, T b)
{
	pragma(inline, true);
	return a > b? a : b;
}
immutable addNeutral(T) = T(0);
pure T add(T)(T a, T b)
{
	pragma(inline, true);
	return a + b;
}
pure T min(T)(T a, T b)
{
	pragma(inline, true);
	return a < b? a : b;
}
pure T set(T)(T a, T b)
{
	pragma(inline, true);
	return a;
}
pure T maxOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T maxOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T minOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T minOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T addOadd(T)(T sm, T ad, size_t l)
{
	pragma(inline, true);
	return sm + ad * cast(T)l;
}

long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = TSTL!(int, "add", "add");
	version(velocity)
	{
		int n = 100_000;
		int q = 100_000;
		auto st = SumQSumU(n, 0);
		int tot = 0;
		foreach(i; 0 .. q)
		{
			int f = uniform!"[)"(0, n);
			int t = uniform!"[]"(f + 1, n);
			if (i&1)
			{
				tot += st.addRange(f, t);
			}
			else
			{
				int u = uniform!"[)"(-1000, 1000);
				st.rangeU(f, t, u);
			}
		}
	}
	else
	{
		auto n = 1000;
		int[] brute = new int[](n);
		auto smart = SumQSumU(n, 0);
		int rounds = 10;
		foreach(round; 0 .. rounds)
		{
			foreach(i; 0 .. n)
				foreach(j; i + 1 .. n + 1)
				{
					int v = uniform!"[]"(1, 20);
					brute[i .. j] += v;
					smart.rangeU(i, j, v);
				}
			foreach(i; 0 .. n)
				foreach(j; i + 1 .. n + 1)
				{
					auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
					auto smartAnswer = smart.rangeF(i, j);
					assert(bruteAnswer == smartAnswer);
				}
		}
	}
}
// }}}

immutable multi = false;
void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	alias SegTree = TSTL!(int[2], "max", "set", [0, -1]);
	auto st = SegTree(noPoints, [0, -1]);
	auto dp = new int[2][](n);
	foreach(i, ref dpi; dp)
	{
		dpi = [0, -1];
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st.maxRange(range[0], range[1] + 1));
		}
		dpi[0]++;
		foreach(range; ranges[i])
		{
			st[range[0] .. range[1] + 1] = [dpi[0], cast(int)i];
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i][0] > bdpi)
		{
			bdpi = dp[i][0];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;
	while (bi >= 0)
	{
		alive[bi] = false;
		bi = dp[bi][1];
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
struct STL(V, U,
		V neutral,
		alias f,
		alias fou,
		alias uou,
		string fName = "f", string uName = "u")
{
	struct Node
	{
		V f;
		U u;
		bool hasU;
	}
	Node[] _n;
	size_t length = 0;
	int layers = 0;
	this(size_t n, V v)
	{
		import std.math;
		n = cast(size_t) nextPow2(n);
		layers = cast(int) log2(n) + 1;
		length = n;
		auto noNodes = 2 * n;

		_n = new Node[](noNodes);

		foreach(i; n .. 2 * n)
		{
			_n[i].f = v;
		}
		foreach_reverse(i; 1 .. n)
		{
			_n[i].f = f(_n[i<<1].f, _n[(i<<1)^1].f);
		}
	}
	void _clearU(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach_reverse(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _clearU(l >> layer);
			if (r & lowerBits) _clearU(r >> layer);
		}
	}
	void _refresh(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _refresh(l >> layer);
			if (r & lowerBits) _refresh(r >> layer);
		}
	}
	void _refresh(size_t i)
	{
		pragma(inline, true);
		assert(!_isLeaf(i));
		_n[i].f = f(_n[i<<1].f, _n[(i<<1)^1].f);
	}
	V rangeF(size_t l, size_t r)
	{
		l += length, r += length;
		_clearU(l, r);
		V value = neutral;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1)
				value = f(value, _n[l++].f);
			if (r & 1)
				value = f(value, _n[--r].f);
		}
		return value;
	}
	mixin(q{alias }, fName, q{Range = rangeF;});
	void rangeU(size_t l, size_t r, U u)
	{
		l += length, r += length;
		auto ol = l, or = r;
		_clearU(l, r);
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) _addU(l++, u);
			if (r & 1) _addU(--r, u);
		}
		_refresh(ol, or);
	}
	static if (uName == "set")
	{
		auto opIndexAssign(U u, size_t[2] slice)
		{
			rangeU(slice[0], slice[1], u);
			return this;
		}
	}
	else static if (uName == "add")
	{

	}
	bool _isLeaf(size_t i)
	{
		pragma(inline, true);
		return i >= length;
	}
	void _clearU(size_t i)
	{
		pragma(inline, true);
		if (!_n[i].hasU) return;
		assert(!_isLeaf(i));
		_n[i].hasU = false;
		_addU(i << 1, _n[i].u), _addU((i << 1) ^ 1, _n[i].u);
		assert(_n[i].f == f(_n[i<<1].f, _n[(i<<1)^1].f));
	}
	void _addU(size_t i, U u)
	{
		import core.bitop;
		pragma(inline, true);
		if (!_n[i].hasU)
		{
			_n[i].hasU = true;
			_n[i].u = u;
		}
		else
		{
			_n[i].u = uou(u, _n[i].u);
		}
		_n[i].f = fou(_n[i].f, u, length >> bsr(i));
	}
	size_t[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
	{
		return [start, end];
	}
}
template TSTL(V, string f, string u, neutral...)
{
	alias funF = mixin(f);
	alias funUoU = mixin(u);
	alias funFoU = mixin(f, "O", u);
	static if (neutral.length == 1)
		immutable neut = neutral[0];
	else static if (neutral.length == 0)
	{
		alias neutralTemplate = mixin(f, "Neutral");
		immutable neut = neutralTemplate!V;
	}
	else static assert(false);
	alias TSTL = STL!(V, V, neut, funF!V, funFoU!V, funUoU!V, f, u);
}
immutable maxNeutral(T) = T.min;
pure T max(T)(T a, T b)
{
	pragma(inline, true);
	return a > b? a : b;
}
immutable addNeutral(T) = T(0);
pure T add(T)(T a, T b)
{
	pragma(inline, true);
	return a + b;
}
pure T min(T)(T a, T b)
{
	pragma(inline, true);
	return a < b? a : b;
}
pure T set(T)(T a, T b)
{
	pragma(inline, true);
	return a;
}
pure T maxOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T maxOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T minOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T minOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T addOadd(T)(T sm, T ad, size_t l)
{
	pragma(inline, true);
	return sm + ad * cast(T)l;
}

long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = TSTL!(int, "add", "add");
	version(velocity)
	{
		int n = 100_000;
		int q = 100_000;
		auto st = SumQSumU(n, 0);
		int tot = 0;
		foreach(i; 0 .. q)
		{
			int f = uniform!"[)"(0, n);
			int t = uniform!"[]"(f + 1, n);
			if (i&1)
			{
				tot += st.addRange(f, t);
			}
			else
			{
				int u = uniform!"[)"(-1000, 1000);
				st.rangeU(f, t, u);
			}
		}
	}
	else
	{
		auto n = 1000;
		int[] brute = new int[](n);
		auto smart = SumQSumU(n, 0);
		int rounds = 10;
		foreach(round; 0 .. rounds)
		{
			foreach(i; 0 .. n)
				foreach(j; i + 1 .. n + 1)
				{
					int v = uniform!"[]"(1, 20);
					brute[i .. j] += v;
					smart.rangeU(i, j, v);
				}
			foreach(i; 0 .. n)
				foreach(j; i + 1 .. n + 1)
				{
					auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
					auto smartAnswer = smart.rangeF(i, j);
					assert(bruteAnswer == smartAnswer);
				}
		}
	}
}
// }}}

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	auto st = TSTL!(int, "max", "set", int.min)(noPoints, 0);
	auto st2 = TSTL!(int, "max", "add", 0)(noPoints, 0);
	auto dp = new int[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = 0;
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st.maxRange(range[0], range[1] + 1));
		}
		dpi++;
		foreach(range; ranges[i])
		{
			st.rangeU(range[0], range[1] + 1, dpi);
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i] > bdpi)
		{
			bdpi = dp[i];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;

	foreach(range; ranges[bi]) st2.rangeU(range[0], range[1] + 1, 1);
	alive[bi] = false;
	auto pbi = bi;
	bi--;
	while (bi >= 0)
	{
		if (dp[bi] == dp[pbi] - 1)
		{
			bool isGood = false;
			foreach(range; ranges[bi])
			{
					if (st2.rangeF(range[0], range[1] + 1) > 0) { isGood = true; break; }
			}
			if (isGood)
			{
				foreach(range; ranges[pbi])
					st2.rangeU(range[0], range[1] + 1, -1);
				foreach(range; ranges[bi])
					st2.rangeU(range[0], range[1] + 1, +1);
				alive[bi] = false;
				pbi = bi;
			}
		}
		bi--;
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
struct STL(V, U,
		V neutral,
		alias f,
		alias fou,
		alias uou,
		string fName = "f", string uName = "u")
{
	struct Node
	{
		V f;
		U u;
		bool hasU;
	}
	Node[] _n;
	size_t length = 0;
	int layers = 0;
	this(size_t n, V v)
	{
		bool isPow2(size_t s) { return ((s - 1) & s) == 0; }
		import std.math;
		import core.bitop;
		layers = bsr(n) + !isPow2(n);
		n = 1 << (layers++);
		length = n;
		auto noNodes = 2 * n;

		_n = new Node[](noNodes);

		foreach(i; n .. 2 * n)
		{
			_n[i].f = v;
		}
		foreach_reverse(i; 1 .. n)
		{
			_n[i].f = f(_n[i<<1].f, _n[(i<<1)^1].f);
		}
	}
	void _clearU(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach_reverse(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _clearU(l >> layer);
			if (r & lowerBits) _clearU(r >> layer);
		}
	}
	void _refresh(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _refresh(l >> layer);
			if (r & lowerBits) _refresh(r >> layer);
		}
	}
	void _refresh(size_t i)
	{
		pragma(inline, true);
		assert(!_isLeaf(i));
		_n[i].f = f(_n[i<<1].f, _n[(i<<1)^1].f);
	}
	V rangeF(size_t l, size_t r)
	{
		l += length, r += length;
		_clearU(l, r);
		V value = neutral;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1)
				value = f(value, _n[l++].f);
			if (r & 1)
				value = f(value, _n[--r].f);
		}
		return value;
	}
	mixin(q{alias }, fName, q{Range = rangeF;});
	void rangeU(size_t l, size_t r, U u)
	{
		l += length, r += length;
		auto ol = l, or = r;
		_clearU(l, r);
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) _addU(l++, u);
			if (r & 1) _addU(--r, u);
		}
		_refresh(ol, or);
	}
	static if (uName == "set")
	{
		auto opIndexAssign(U u, size_t[2] slice)
		{
			rangeU(slice[0], slice[1], u);
			return this;
		}
	}
	else static if (uName == "add")
	{

	}
	bool _isLeaf(size_t i)
	{
		pragma(inline, true);
		return i >= length;
	}
	void _clearU(size_t i)
	{
		pragma(inline, true);
		if (!_n[i].hasU) return;
		assert(!_isLeaf(i));
		_n[i].hasU = false;
		_addU(i << 1, _n[i].u), _addU((i << 1) ^ 1, _n[i].u);
		assert(_n[i].f == f(_n[i<<1].f, _n[(i<<1)^1].f));
	}
	void _addU(size_t i, U u)
	{
		import core.bitop;
		pragma(inline, true);
		if (!_n[i].hasU)
		{
			_n[i].hasU = true;
			_n[i].u = u;
		}
		else
		{
			_n[i].u = uou(u, _n[i].u);
		}
		_n[i].f = fou(_n[i].f, u, length >> bsr(i));
	}
	size_t[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
	{
		return [start, end];
	}
}
template TSTL(V, string f, string u, neutral...)
{
	alias funF = mixin(f);
	alias funUoU = mixin(u);
	alias funFoU = mixin(f, "O", u);
	static if (neutral.length == 1)
		immutable neut = neutral[0];
	else static if (neutral.length == 0)
	{
		alias neutralTemplate = mixin(f, "Neutral");
		immutable neut = neutralTemplate!V;
	}
	else static assert(false);
	alias TSTL = STL!(V, V, neut, funF!V, funFoU!V, funUoU!V, f, u);
}
immutable maxNeutral(T) = T.min;
pure T max(T)(T a, T b)
{
	pragma(inline, true);
	return a > b? a : b;
}
immutable addNeutral(T) = T(0);
pure T add(T)(T a, T b)
{
	pragma(inline, true);
	return a + b;
}
pure T min(T)(T a, T b)
{
	pragma(inline, true);
	return a < b? a : b;
}
pure T set(T)(T a, T b)
{
	pragma(inline, true);
	return a;
}
pure T maxOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T maxOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T minOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T minOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T addOadd(T)(T sm, T ad, size_t l)
{
	pragma(inline, true);
	return sm + ad * cast(T)l;
}

long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = TSTL!(int, "add", "add");
	version(velocity)
	{
		int n = 100_000;
		int q = 100_000;
		auto st = SumQSumU(n, 0);
		int tot = 0;
		foreach(i; 0 .. q)
		{
			int f = uniform!"[)"(0, n);
			int t = uniform!"[]"(f + 1, n);
			if (i&1)
			{
				tot += st.addRange(f, t);
			}
			else
			{
				int u = uniform!"[)"(-1000, 1000);
				st.rangeU(f, t, u);
			}
		}
	}
	else
	{
		auto n = 1000;
		int[] brute = new int[](n);
		auto smart = SumQSumU(n, 0);
		int rounds = 10;
		foreach(round; 0 .. rounds)
		{
			foreach(i; 0 .. n)
				foreach(j; i + 1 .. n + 1)
				{
					int v = uniform!"[]"(1, 20);
					brute[i .. j] += v;
					smart.rangeU(i, j, v);
				}
			foreach(i; 0 .. n)
				foreach(j; i + 1 .. n + 1)
				{
					auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
					auto smartAnswer = smart.rangeF(i, j);
					assert(bruteAnswer == smartAnswer);
				}
		}
	}
}
// }}}

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	auto st = TSTL!(int, "max", "set", int.min)(noPoints, 0);
	auto st2 = TSTL!(int, "max", "add", 0)(noPoints, 0);
	auto dp = new int[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = 0;
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st.maxRange(range[0], range[1] + 1));
		}
		dpi++;
		foreach(range; ranges[i])
		{
			st.rangeU(range[0], range[1] + 1, dpi);
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i] > bdpi)
		{
			bdpi = dp[i];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;

	foreach(range; ranges[bi]) st2.rangeU(range[0], range[1] + 1, 1);
	alive[bi] = false;
	auto pbi = bi;
	bi--;
	while (bi >= 0)
	{
		if (dp[bi] == dp[pbi] - 1)
		{
			bool isGood = false;
			foreach(range; ranges[bi])
			{
					if (st2.rangeF(range[0], range[1] + 1) > 0) { isGood = true; break; }
			}
			if (isGood)
			{
				foreach(range; ranges[pbi])
					st2.rangeU(range[0], range[1] + 1, -1);
				foreach(range; ranges[bi])
					st2.rangeU(range[0], range[1] + 1, +1);
				alive[bi] = false;
				pbi = bi;
			}
		}
		bi--;
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
struct STL(V, U,
		V neutral,
		alias f,
		alias fou,
		alias uou,
		string fName = "f", string uName = "u")
{
	struct Node
	{
		V f;
		U u;
		bool hasU;
	}
	Node[] _n;
	size_t length = 0;
	int layers = 0;
	this(size_t n, V v)
	{
		import std.math;
		n = cast(size_t) nextPow2(n);
		layers = cast(int) log2(n) + 1;
		length = n;
		auto noNodes = 2 * n;

		_n = new Node[](noNodes);

		foreach(i; n .. 2 * n)
		{
			_n[i].f = v;
		}
		foreach_reverse(i; 1 .. n)
		{
			_n[i].f = f(_n[i<<1].f, _n[(i<<1)^1].f);
		}
	}
	void _clearU(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach_reverse(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _clearU(l >> layer);
			if (r & lowerBits) _clearU(r >> layer);
		}
	}
	void _refresh(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _refresh(l >> layer);
			if (r & lowerBits) _refresh(r >> layer);
		}
	}
	void _refresh(size_t i)
	{
		pragma(inline, true);
		assert(!_isLeaf(i));
		_n[i].f = f(_n[i<<1].f, _n[(i<<1)^1].f);
	}
	V rangeF(size_t l, size_t r)
	{
		l += length, r += length;
		_clearU(l, r);
		V value = neutral;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1)
				value = f(value, _n[l++].f);
			if (r & 1)
				value = f(value, _n[--r].f);
		}
		return value;
	}
	mixin(q{alias }, fName, q{Range = rangeF;});
	void rangeU(size_t l, size_t r, U u)
	{
		l += length, r += length;
		auto ol = l, or = r;
		_clearU(l, r);
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) _addU(l++, u);
			if (r & 1) _addU(--r, u);
		}
		_refresh(ol, or);
	}
	static if (uName == "set")
	{
		auto opIndexAssign(U u, size_t[2] slice)
		{
			rangeU(slice[0], slice[1], u);
			return this;
		}
	}
	else static if (uName == "add")
	{

	}
	bool _isLeaf(size_t i)
	{
		pragma(inline, true);
		return i >= length;
	}
	void _clearU(size_t i)
	{
		pragma(inline, true);
		if (!_n[i].hasU) return;
		assert(!_isLeaf(i));
		_n[i].hasU = false;
		_addU(i << 1, _n[i].u), _addU((i << 1) ^ 1, _n[i].u);
		assert(_n[i].f == f(_n[i<<1].f, _n[(i<<1)^1].f));
	}
	void _addU(size_t i, U u)
	{
		import core.bitop;
		pragma(inline, true);
		if (!_n[i].hasU)
		{
			_n[i].hasU = true;
			_n[i].u = u;
		}
		else
		{
			_n[i].u = uou(u, _n[i].u);
		}
		_n[i].f = fou(_n[i].f, u, length >> bsr(i));
	}
	size_t[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
	{
		return [start, end];
	}
}
template TSTL(V, string f, string u, neutral...)
{
	alias funF = mixin(f);
	alias funUoU = mixin(u);
	alias funFoU = mixin(f, "O", u);
	static if (neutral.length == 1)
		immutable neut = neutral[0];
	else static if (neutral.length == 0)
	{
		alias neutralTemplate = mixin(f, "Neutral");
		immutable neut = neutralTemplate!V;
	}
	else static assert(false);
	alias TSTL = STL!(V, V, neut, funF!V, funFoU!V, funUoU!V, f, u);
}
immutable maxNeutral(T) = T.min;
pure T max(T)(T a, T b)
{
	pragma(inline, true);
	return a > b? a : b;
}
immutable addNeutral(T) = T(0);
pure T add(T)(T a, T b)
{
	pragma(inline, true);
	return a + b;
}
pure T min(T)(T a, T b)
{
	pragma(inline, true);
	return a < b? a : b;
}
pure T set(T)(T a, T b)
{
	pragma(inline, true);
	return a;
}
pure T maxOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T maxOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T minOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T minOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T addOadd(T)(T sm, T ad, size_t l)
{
	pragma(inline, true);
	return sm + ad * cast(T)l;
}

long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = TSTL!(int, "add", "add");
	version(velocity)
	{
		int n = 100_000;
		int q = 100_000;
		auto st = SumQSumU(n, 0);
		int tot = 0;
		foreach(i; 0 .. q)
		{
			int f = uniform!"[)"(0, n);
			int t = uniform!"[]"(f + 1, n);
			if (i&1)
			{
				tot += st.addRange(f, t);
			}
			else
			{
				int u = uniform!"[)"(-1000, 1000);
				st.rangeU(f, t, u);
			}
		}
	}
	else
	{
		auto n = 1000;
		int[] brute = new int[](n);
		auto smart = SumQSumU(n, 0);
		int rounds = 10;
		foreach(round; 0 .. rounds)
		{
			foreach(i; 0 .. n)
				foreach(j; i + 1 .. n + 1)
				{
					int v = uniform!"[]"(1, 20);
					brute[i .. j] += v;
					smart.rangeU(i, j, v);
				}
			foreach(i; 0 .. n)
				foreach(j; i + 1 .. n + 1)
				{
					auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
					auto smartAnswer = smart.rangeF(i, j);
					assert(bruteAnswer == smartAnswer);
				}
		}
	}
}
// }}}

immutable multi = false;
struct Pair(T)
{
	T[2] _d;
	alias _d this;
	bool opBinary(string op)(Pair!T rhs) if (op == "<")
	{
		auto diff0 = _d[0] - rhs[0];
		if (diff0 == 0) return _d[1] - rhs[1];
		return diff0;
	}
	this(int x, int y) { _d = [x, y]; }
}

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	alias SegTree = TSTL!(Pair!int, "max", "set", Pair!int(0, -1));
	auto st = SegTree(noPoints, Pair!int(0, -1));
	auto dp = new Pair!int[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = Pair!int(0, -1);
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st.maxRange(range[0], range[1] + 1));
		}
		dpi[0]++;
		foreach(range; ranges[i])
		{
			st[range[0] .. range[1] + 1] = Pair!int(dpi[0], cast(int)i);
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i][0] > bdpi)
		{
			bdpi = dp[i][0];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;
	while (bi >= 0)
	{
		alive[bi] = false;
		bi = dp[bi][1];
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
struct STL(V, U,
		V neutral,
		alias f,
		alias fou,
		alias uou,
		string fName = "f", string uName = "u")
{
	struct Node
	{
		V f;
		U u;
		bool hasU;
	}
	Node[] _n;
	size_t length = 0;
	int layers = 0;
	this(size_t n, V v)
	{
		import std.math;
		n = cast(size_t) nextPow2(n);
		layers = cast(int) log2(n) + 1;
		length = n;
		auto noNodes = 2 * n;

		_n = new Node[](noNodes);

		foreach(i; n .. 2 * n)
		{
			_n[i].f = v;
		}
		foreach_reverse(i; 1 .. n)
		{
			_n[i].f = f(_n[i<<1].f, _n[(i<<1)^1].f);
		}
	}
	void _clearU(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach_reverse(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _clearU(l >> layer);
			if (r & lowerBits) _clearU(r >> layer);
		}
	}
	void _refresh(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _refresh(l >> layer);
			if (r & lowerBits) _refresh(r >> layer);
		}
	}
	void _refresh(size_t i)
	{
		pragma(inline, true);
		assert(!_isLeaf(i));
		_n[i].f = f(_n[i<<1].f, _n[(i<<1)^1].f);
	}
	V rangeF(size_t l, size_t r)
	{
		l += length, r += length;
		_clearU(l, r);
		V value = neutral;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1)
				value = f(value, _n[l++].f);
			if (r & 1)
				value = f(value, _n[--r].f);
		}
		return value;
	}
	mixin(q{alias }, fName, q{Range = rangeF;});
	void rangeU(size_t l, size_t r, U u)
	{
		l += length, r += length;
		auto ol = l, or = r;
		_clearU(l, r);
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) _addU(l++, u);
			if (r & 1) _addU(--r, u);
		}
		_refresh(ol, or);
	}
	static if (uName == "set")
	{
		auto opIndexAssign(U u, size_t[2] slice)
		{
			rangeU(slice[0], slice[1], u);
			return this;
		}
	}
	else static if (uName == "add")
	{

	}
	bool _isLeaf(size_t i)
	{
		pragma(inline, true);
		return i >= length;
	}
	void _clearU(size_t i)
	{
		pragma(inline, true);
		if (!_n[i].hasU) return;
		assert(!_isLeaf(i));
		_n[i].hasU = false;
		_addU(i << 1, _n[i].u), _addU((i << 1) ^ 1, _n[i].u);
		assert(_n[i].f == f(_n[i<<1].f, _n[(i<<1)^1].f));
	}
	void _addU(size_t i, U u)
	{
		import core.bitop;
		pragma(inline, true);
		if (!_n[i].hasU)
		{
			_n[i].hasU = true;
			_n[i].u = u;
		}
		else
		{
			_n[i].u = uou(u, _n[i].u);
		}
		_n[i].f = fou(_n[i].f, u, length >> bsr(i));
	}
	size_t[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
	{
		return [start, end];
	}
}
template TSTL(V, string f, string u, neutral...)
{
	alias funF = mixin(f);
	alias funUoU = mixin(u);
	alias funFoU = mixin(f, "O", u);
	static if (neutral.length == 1)
		immutable neut = neutral[0];
	else static if (neutral.length == 0)
	{
		alias neutralTemplate = mixin(f, "Neutral");
		immutable neut = neutralTemplate!V;
	}
	else static assert(false);
	alias TSTL = STL!(V, V, neut, funF!V, funFoU!V, funUoU!V, f, u);
}
immutable maxNeutral(T) = T.min;
pure T max(T)(T a, T b)
{
	pragma(inline, true);
	return a > b? a : b;
}
immutable addNeutral(T) = T(0);
pure T add(T)(T a, T b)
{
	pragma(inline, true);
	return a + b;
}
pure T min(T)(T a, T b)
{
	pragma(inline, true);
	return a < b? a : b;
}
pure T set(T)(T a, T b)
{
	pragma(inline, true);
	return a;
}
pure T maxOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T maxOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T minOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T minOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T addOadd(T)(T sm, T ad, size_t l)
{
	pragma(inline, true);
	return sm + ad * cast(T)l;
}

long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = TSTL!(int, "add", "add");
	version(velocity)
	{
		int n = 100_000;
		int q = 100_000;
		auto st = SumQSumU(n, 0);
		int tot = 0;
		foreach(i; 0 .. q)
		{
			int f = uniform!"[)"(0, n);
			int t = uniform!"[]"(f + 1, n);
			if (i&1)
			{
				tot += st.addRange(f, t);
			}
			else
			{
				int u = uniform!"[)"(-1000, 1000);
				st.rangeU(f, t, u);
			}
		}
	}
	else
	{
		auto n = 1000;
		int[] brute = new int[](n);
		auto smart = SumQSumU(n, 0);
		int rounds = 10;
		foreach(round; 0 .. rounds)
		{
			foreach(i; 0 .. n)
				foreach(j; i + 1 .. n + 1)
				{
					int v = uniform!"[]"(1, 20);
					brute[i .. j] += v;
					smart.rangeU(i, j, v);
				}
			foreach(i; 0 .. n)
				foreach(j; i + 1 .. n + 1)
				{
					auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
					auto smartAnswer = smart.rangeF(i, j);
					assert(bruteAnswer == smartAnswer);
				}
		}
	}
}
// }}}

immutable multi = false;
struct Pair(T)
{
	T[2] _d;
	alias _d this;
	bool opBinary(string op)(Pair!T rhs) if (op == "<")
	{
		return _d[0] - rhs[0];
	}
	this(int x, int y) { _d = [x, y]; }
}

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	alias SegTree = TSTL!(Pair!int, "max", "set", Pair!int(0, -1));
	auto st = SegTree(noPoints, Pair!int(0, -1));
	auto dp = new Pair!int[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = Pair!int(0, -1);
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st.maxRange(range[0], range[1] + 1));
		}
		dpi[0]++;
		foreach(range; ranges[i])
		{
			st[range[0] .. range[1] + 1] = Pair!int(dpi[0], cast(int)i);
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i][0] > bdpi)
		{
			bdpi = dp[i][0];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;
	while (bi >= 0)
	{
		alive[bi] = false;
		bi = dp[bi][1];
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
struct STL(V, U,
		V neutral,
		alias f,
		alias fou,
		alias uou,
		string fName = "f", string uName = "u")
{
	struct Node
	{
		V f;
		U u;
		bool hasU;
	}
	Node[] _n;
	size_t length = 0;
	int layers = 0;
	this(size_t n, V v)
	{
		import std.math;
		n = cast(size_t) nextPow2(n);
		layers = cast(int) log2(n) + 1;
		length = n;
		auto noNodes = 2 * n;

		_n = new Node[](noNodes);

		foreach(i; n .. 2 * n)
		{
			_n[i].f = v;
		}
		foreach_reverse(i; 1 .. n)
		{
			_n[i].f = f(_n[i<<1].f, _n[(i<<1)^1].f);
		}
	}
	void _clearU(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach_reverse(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _clearU(l >> layer);
			if (r & lowerBits) _clearU(r >> layer);
		}
	}
	void _refresh(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _refresh(l >> layer);
			if (r & lowerBits) _refresh(r >> layer);
		}
	}
	void _refresh(size_t i)
	{
		pragma(inline, true);
		assert(!_isLeaf(i));
		_n[i].f = f(_n[i<<1].f, _n[(i<<1)^1].f);
	}
	V rangeF(size_t l, size_t r)
	{
		l += length, r += length;
		_clearU(l, r);
		V value = neutral;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1)
				value = f(value, _n[l++].f);
			if (r & 1)
				value = f(value, _n[--r].f);
		}
		return value;
	}
	mixin(q{alias }, fName, q{Range = rangeF;});
	void rangeU(size_t l, size_t r, U u)
	{
		l += length, r += length;
		auto ol = l, or = r;
		_clearU(l, r);
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) _addU(l++, u);
			if (r & 1) _addU(--r, u);
		}
		_refresh(ol, or);
	}
	static if (uName == "set")
	{
		auto opIndexAssign(U u, size_t[2] slice)
		{
			rangeU(slice[0], slice[1], u);
			return this;
		}
	}
	else static if (uName == "add")
	{

	}
	bool _isLeaf(size_t i)
	{
		pragma(inline, true);
		return i >= length;
	}
	void _clearU(size_t i)
	{
		pragma(inline, true);
		if (!_n[i].hasU) return;
		assert(!_isLeaf(i));
		_n[i].hasU = false;
		_addU(i << 1, _n[i].u), _addU((i << 1) ^ 1, _n[i].u);
		assert(_n[i].f == f(_n[i<<1].f, _n[(i<<1)^1].f));
	}
	void _addU(size_t i, U u)
	{
		import core.bitop;
		pragma(inline, true);
		if (!_n[i].hasU)
		{
			_n[i].hasU = true;
			_n[i].u = u;
		}
		else
		{
			_n[i].u = uou(u, _n[i].u);
		}
		_n[i].f = fou(_n[i].f, u, length >> bsr(i));
	}
	size_t[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
	{
		return [start, end];
	}
}
template TSTL(V, string f, string u, neutral...)
{
	alias funF = mixin(f);
	alias funUoU = mixin(u);
	alias funFoU = mixin(f, "O", u);
	static if (neutral.length == 1)
		immutable neut = neutral[0];
	else static if (neutral.length == 0)
	{
		alias neutralTemplate = mixin(f, "Neutral");
		immutable neut = neutralTemplate!V;
	}
	else static assert(false);
	alias TSTL = STL!(V, V, neut, funF!V, funFoU!V, funUoU!V, f, u);
}
immutable maxNeutral(T) = T.min;
pure T max(T)(T a, T b)
{
	pragma(inline, true);
	return a > b? a : b;
}
immutable addNeutral(T) = T(0);
pure T add(T)(T a, T b)
{
	pragma(inline, true);
	return a + b;
}
pure T min(T)(T a, T b)
{
	pragma(inline, true);
	return a < b? a : b;
}
pure T set(T)(T a, T b)
{
	pragma(inline, true);
	return a;
}
pure T maxOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T maxOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T minOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T minOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T addOadd(T)(T sm, T ad, size_t l)
{
	pragma(inline, true);
	return sm + ad * cast(T)l;
}

long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = TSTL!(int, "add", "add");
	version(velocity)
	{
		int n = 100_000;
		int q = 100_000;
		auto st = SumQSumU(n, 0);
		int tot = 0;
		foreach(i; 0 .. q)
		{
			int f = uniform!"[)"(0, n);
			int t = uniform!"[]"(f + 1, n);
			if (i&1)
			{
				tot += st.addRange(f, t);
			}
			else
			{
				int u = uniform!"[)"(-1000, 1000);
				st.rangeU(f, t, u);
			}
		}
	}
	else
	{
		auto n = 1000;
		int[] brute = new int[](n);
		auto smart = SumQSumU(n, 0);
		int rounds = 10;
		foreach(round; 0 .. rounds)
		{
			foreach(i; 0 .. n)
				foreach(j; i + 1 .. n + 1)
				{
					int v = uniform!"[]"(1, 20);
					brute[i .. j] += v;
					smart.rangeU(i, j, v);
				}
			foreach(i; 0 .. n)
				foreach(j; i + 1 .. n + 1)
				{
					auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
					auto smartAnswer = smart.rangeF(i, j);
					assert(bruteAnswer == smartAnswer);
				}
		}
	}
}
// }}}

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	alias SegTree = TSTL!(Tuple!(int, int), "max", "set", tuple(0, -1));
	auto st = SegTree(noPoints, tuple(0, -1));
	auto dp = new Tuple!(int, int)[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = tuple(0, -1);
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st.maxRange(range[0], range[1] + 1));
		}
		dpi[0]++;
		foreach(range; ranges[i])
		{
			st[range[0] .. range[1] + 1] = tuple(dpi[0], cast(int)i);
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i][0] > bdpi)
		{
			bdpi = dp[i][0];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;
	while (bi >= 0)
	{
		alive[bi] = false;
		bi = dp[bi][1];
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
struct STL(V, U,
		V neutral,
		alias f,
		alias fou,
		alias uou,
		string fName = "f", string uName = "u")
{
	struct Node
	{
		V f;
		U u;
		bool hasU;
	}
	Node[] _n;
	size_t length = 0;
	int layers = 0;
	this(size_t n, V v)
	{
		import std.math;
		n = cast(size_t) nextPow2(n);
		layers = cast(int) log2(n) + 1;
		length = n;
		auto noNodes = 2 * n;

		_n = new Node[](noNodes);

		foreach(i; n .. 2 * n)
		{
			_n[i].f = v;
		}
		foreach_reverse(i; 1 .. n)
		{
			_n[i].f = f(_n[i<<1].f, _n[(i<<1)^1].f);
		}
	}
	void _clearU(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach_reverse(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _clearU(l >> layer);
			if (r & lowerBits) _clearU(r >> layer);
		}
	}
	void _refresh(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _refresh(l >> layer);
			if (r & lowerBits) _refresh(r >> layer);
		}
	}
	void _refresh(size_t i)
	{
		pragma(inline, true);
		assert(!_isLeaf(i));
		_n[i].f = f(_n[i<<1].f, _n[(i<<1)^1].f);
	}
	V rangeF(size_t l, size_t r)
	{
		l += length, r += length;
		_clearU(l, r);
		V value = neutral;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1)
				value = f(value, _n[l++].f);
			if (r & 1)
				value = f(value, _n[--r].f);
		}
		return value;
	}
	mixin(q{alias }, fName, q{Range = rangeF;});
	void rangeU(size_t l, size_t r, U u)
	{
		l += length, r += length;
		auto ol = l, or = r;
		_clearU(l, r);
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) _addU(l++, u);
			if (r & 1) _addU(--r, u);
		}
		_refresh(ol, or);
	}
	static if (uName == "set")
	{
		auto opIndexAssign(U u, size_t[2] slice)
		{
			rangeU(slice[0], slice[1], u);
			return this;
		}
	}
	else static if (uName == "add")
	{

	}
	bool _isLeaf(size_t i)
	{
		pragma(inline, true);
		return i >= length;
	}
	void _clearU(size_t i)
	{
		pragma(inline, true);
		if (!_n[i].hasU) return;
		assert(!_isLeaf(i));
		_n[i].hasU = false;
		_addU(i << 1, _n[i].u), _addU((i << 1) ^ 1, _n[i].u);
		assert(_n[i].f == f(_n[i<<1].f, _n[(i<<1)^1].f));
	}
	void _addU(size_t i, U u)
	{
		import core.bitop;
		pragma(inline, true);
		if (!_n[i].hasU)
		{
			_n[i].hasU = true;
			_n[i].u = u;
		}
		else
		{
			_n[i].u = uou(u, _n[i].u);
		}
		_n[i].f = fou(_n[i].f, u, length >> bsr(i));
	}
	size_t[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
	{
		return [start, end];//
	}
}
template TSTL(V, string f, string u, neutral...)
{
	alias funF = mixin(f);
	alias funUoU = mixin(u);
	alias funFoU = mixin(f, "O", u);
	static if (neutral.length == 1)
		immutable neut = neutral[0];
	else static if (neutral.length == 0)
	{
		alias neutralTemplate = mixin(f, "Neutral");
		immutable neut = neutralTemplate!V;
	}
	else static assert(false);
	alias TSTL = STL!(V, V, neut, funF!V, funFoU!V, funUoU!V, f, u);
}
immutable maxNeutral(T) = T.min;
pure T max(T)(T a, T b)
{
	pragma(inline, true);
	return a > b? a : b;
}
immutable addNeutral(T) = T(0);
pure T add(T)(T a, T b)
{
	pragma(inline, true);
	return a + b;
}
pure T min(T)(T a, T b)
{
	pragma(inline, true);
	return a < b? a : b;
}
pure T set(T)(T a, T b)
{
	pragma(inline, true);
	return a;
}
pure T maxOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T maxOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T minOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T minOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T addOadd(T)(T sm, T ad, size_t l)
{
	pragma(inline, true);
	return sm + ad * cast(T)l;
}

long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = TSTL!(int, "add", "add");
	version(velocity)
	{
		int n = 100_000;
		int q = 100_000;
		auto st = SumQSumU(n, 0);
		int tot = 0;
		foreach(i; 0 .. q)
		{
			int f = uniform!"[)"(0, n);
			int t = uniform!"[]"(f + 1, n);
			if (i&1)
			{
				tot += st.addRange(f, t);
			}
			else
			{
				int u = uniform!"[)"(-1000, 1000);
				st.rangeU(f, t, u);
			}
		}
	}
	else
	{
		auto n = 1000;
		int[] brute = new int[](n);
		auto smart = SumQSumU(n, 0);
		int rounds = 10;
		foreach(round; 0 .. rounds)
		{
			foreach(i; 0 .. n)
				foreach(j; i + 1 .. n + 1)
				{
					int v = uniform!"[]"(1, 20);
					brute[i .. j] += v;
					smart.rangeU(i, j, v);
				}
			foreach(i; 0 .. n)
				foreach(j; i + 1 .. n + 1)
				{
					auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
					auto smartAnswer = smart.rangeF(i, j);
					assert(bruteAnswer == smartAnswer);
				}
		}
	}
}
// }}}

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	alias SegTree = TSTL!(Tuple!(int, int), "max", "set", tuple(0, -1));
	auto st = SegTree(noPoints, tuple(0, -1));
	auto dp = new Tuple!(int, int)[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = tuple(0, -1);
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st.maxRange(range[0], range[1] + 1));
		}
		dpi[0]++;
		foreach(range; ranges[i])
		{
			st[range[0] .. range[1] + 1] = tuple(dpi[0], cast(int)i);
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i][0] > bdpi)
		{
			bdpi = dp[i][0];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;
	while (bi >= 0)
	{
		alive[bi] = false;
		bi = dp[bi][1];
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
struct STL(V, U,
		V neutral,
		alias f,
		alias fou,
		alias uou,
		string fName = "f", string uName = "u")
{
	struct Node
	{
		V f;
		U u;
		bool hasU;
	}
	Node[] _n;
	size_t length = 0;
	int layers = 0;
	this(size_t n, V v)
	{
		import std.math;
		n = cast(size_t) nextPow2(n);
		layers = cast(int) log2(n) + 1;
		length = n;
		auto noNodes = 2 * n;

		_n = new Node[](noNodes);

		foreach(i; n .. 2 * n)
		{
			_n[i].f = v;
		}
		foreach_reverse(i; 1 .. n)
		{
			_n[i].f = f(_n[i<<1].f, _n[(i<<1)^1].f);
		}
	}
	void _clearU(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach_reverse(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _clearU(l >> layer);
			if (r & lowerBits) _clearU(r >> layer);
		}
	}
	void _refresh(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _refresh(l >> layer);
			if (r & lowerBits) _refresh(r >> layer);
		}
	}
	void _refresh(size_t i)
	{
		pragma(inline, true);
		assert(!_isLeaf(i));
		_n[i].f = f(_n[i<<1].f, _n[(i<<1)^1].f);
	}
	V rangeF(size_t l, size_t r)
	{
		l += length, r += length;
		_clearU(l, r);
		V value = neutral;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1)
				value = f(value, _n[l++].f);
			if (r & 1)
				value = f(value, _n[--r].f);
		}
		return value;
	}
	mixin(q{alias }, fName, q{Range = rangeF;});
	void rangeU(size_t l, size_t r, U u)
	{
		l += length, r += length;
		auto ol = l, or = r;
		_clearU(l, r);
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) _addU(l++, u);
			if (r & 1) _addU(--r, u);
		}
		_refresh(ol, or);
	}
	static if (uName == "set")
	{
		auto opIndexAssign(U u, size_t[2] slice)
		{
			rangeU(slice[0], slice[1], u);
			return this;
		}
	}
	else static if (uName == "add")
	{

	}
	bool _isLeaf(size_t i)
	{
		pragma(inline, true);
		return i >= length;
	}
	void _clearU(size_t i)
	{
		pragma(inline, true);
		if (!_n[i].hasU) return;
		assert(!_isLeaf(i));
		_n[i].hasU = false;
		_addU(i << 1, _n[i].u), _addU((i << 1) ^ 1, _n[i].u);
		assert(_n[i].f == f(_n[i<<1].f, _n[(i<<1)^1].f));
	}
	void _addU(size_t i, U u)
	{
		import core.bitop;
		pragma(inline, true);
		if (!_n[i].hasU)
		{
			_n[i].hasU = true;
			_n[i].u = u;
		}
		else
		{
			_n[i].u = uou(u, _n[i].u);
		}
		_n[i].f = fou(_n[i].f, u, length >> bsr(i));
	}
	size_t[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
	{
		return [start, end];
	}
}
template TSTL(V, string f, string u, neutral...)
{
	alias funF = mixin(f);
	alias funUoU = mixin(u);
	alias funFoU = mixin(f, "O", u);
	static if (neutral.length == 1)
		immutable neut = neutral[0];
	else static if (neutral.length == 0)
	{
		alias neutralTemplate = mixin(f, "Neutral");
		immutable neut = neutralTemplate!V;
	}
	else static assert(false);
	alias TSTL = STL!(V, V, neut, funF, funFoU, funUoU, f, u);
}
immutable maxNeutral(T) = T.min;
pure T max(T)(T a, T b)
{
	pragma(inline, true);
	return a > b? a : b;
}
immutable addNeutral(T) = T(0);
pure T add(T)(T a, T b)
{
	pragma(inline, true);
	return a + b;
}
pure T min(T)(T a, T b)
{
	pragma(inline, true);
	return a < b? a : b;
}
pure T set(T)(T a, T b)
{
	pragma(inline, true);
	return a;
}
pure T maxOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T maxOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T minOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T minOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T addOadd(T)(T sm, T ad, size_t l)
{
	pragma(inline, true);
	return sm + ad * cast(T)l;
}

long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = TSTL!(int, "add", "add");
	version(velocity)
	{
		int n = 100_000;
		int q = 100_000;
		auto st = SumQSumU(n, 0);
		int tot = 0;
		foreach(i; 0 .. q)
		{
			int f = uniform!"[)"(0, n);
			int t = uniform!"[]"(f + 1, n);
			if (i&1)
			{
				tot += st.addRange(f, t);
			}
			else
			{
				int u = uniform!"[)"(-1000, 1000);
				st.rangeU(f, t, u);
			}
		}
	}
	else
	{
		auto n = 1000;
		int[] brute = new int[](n);
		auto smart = SumQSumU(n, 0);
		int rounds = 10;
		foreach(round; 0 .. rounds)
		{
			foreach(i; 0 .. n)
				foreach(j; i + 1 .. n + 1)
				{
					int v = uniform!"[]"(1, 20);
					brute[i .. j] += v;
					smart.rangeU(i, j, v);
				}
			foreach(i; 0 .. n)
				foreach(j; i + 1 .. n + 1)
				{
					auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
					auto smartAnswer = smart.rangeF(i, j);
					assert(bruteAnswer == smartAnswer);
				}
		}
	}
}
// }}}

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	alias SegTree = TSTL!(Tuple!(int, int), "max", "set", tuple(0, -1));
	auto st = SegTree(noPoints, tuple(0, -1));
	auto dp = new Tuple!(int, int)[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = tuple(0, -1);
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st.maxRange(range[0], range[1] + 1));
		}
		dpi[0]++;
		foreach(range; ranges[i])
		{
			st[range[0] .. range[1] + 1] = tuple(dpi[0], cast(int)i);
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i][0] > bdpi)
		{
			bdpi = dp[i][0];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;
	while (bi >= 0)
	{
		alive[bi] = false;
		bi = dp[bi][1];
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
struct STL(V, U,
		V neutral,
		alias f,
		alias fou,
		alias uou,
		string fName = "f", string uName = "u")
{
	struct Node
	{
		V f;
		U u;
		bool hasU;
		size_t sz;
	}
	Node[] _n;
	size_t length = 0;
	int layers = 0;
	this(size_t n, V v)
	{
		import std.math;
		n = cast(size_t) nextPow2(n);
		layers = cast(int) log2(n) + 1;
		length = n;
		auto noNodes = 2 * n;

		_n = new Node[](noNodes);

		foreach(i; n .. 2 * n)
		{
			_n[i].f = v;
			_n[i].sz = 1;
		}
		foreach_reverse(i; 1 .. n)
		{
			_n[i].f = f(_n[i<<1].f, _n[(i<<1)^1].f);
			_n[i].sz = _n[i<<1].sz << 1;
		}
	}
	void _clearU(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach_reverse(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _clearU(l >> layer);
			if (r & lowerBits) _clearU(r >> layer);
		}
	}
	void _refresh(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _refresh(l >> layer);
			if (r & lowerBits) _refresh(r >> layer);
		}
	}
	void _refresh(size_t i)
	{
		pragma(inline, true);
		assert(!_isLeaf(i));
		_n[i].f = f(_n[i<<1].f, _n[(i<<1)^1].f);
	}
	V rangeF(size_t l, size_t r)
	{
		l += length, r += length;
		_clearU(l, r);
		V value = neutral;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1)
				value = f(value, _n[l++].f);
			if (r & 1)
				value = f(value, _n[--r].f);
		}
		return value;
	}
	mixin(q{alias }, fName, q{Range = rangeF;});
	void rangeU(size_t l, size_t r, U u)
	{
		l += length, r += length;
		auto ol = l, or = r;
		_clearU(l, r);
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) _addU(l++, u);
			if (r & 1) _addU(--r, u);
		}
		_refresh(ol, or);
	}
	static if (uName == "set")
	{
		auto opIndexAssign(U u, size_t[2] slice)
		{
			rangeU(slice[0], slice[1], u);
			return this;
		}
	}
	else static if (uName == "add")
	{

	}
	bool _isLeaf(size_t i)
	{
		pragma(inline, true);
		return i >= length;
	}
	void _clearU(size_t i)
	{
		pragma(inline, true);
		if (!_n[i].hasU) return;
		assert(!_isLeaf(i));
		_n[i].hasU = false;
		_addU(i << 1, _n[i].u), _addU((i << 1) ^ 1, _n[i].u);
		assert(_n[i].f == f(_n[i<<1].f, _n[(i<<1)^1].f));
	}
	void _addU(size_t i, U u)
	{
		pragma(inline, true);
		if (!_n[i].hasU)
		{
			_n[i].hasU = true;
			_n[i].u = u;
		}
		else
		{
			_n[i].u = uou(u, _n[i].u);
		}
		_n[i].f = fou(_n[i].f, u, _n[i].sz);
	}
	size_t[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
	{
		return [start, end];
	}
}
template TSTL(V, string f, string u, neutral...)
{
	alias funF = mixin(f);
	alias funUoU = mixin(u);
	alias funFoU = mixin(f, "O", u);
	static if (neutral.length == 1)
		immutable neut = neutral[0];
	else static if (neutral.length == 0)
	{
		alias neutralTemplate = mixin(f, "Neutral");
		immutable neut = neutralTemplate!V;
	}
	else static assert(false);
	alias TSTL = STL!(V, V, neut, funF, funFoU, funUoU, f, u);
}
immutable maxNeutral(T) = T.min;
pure T max(T)(T a, T b)
{
	pragma(inline, true);
	return a > b? a : b;
}
immutable addNeutral(T) = T(0);
pure T add(T)(T a, T b)
{
	pragma(inline, true);
	return a + b;
}
pure T min(T)(T a, T b)
{
	pragma(inline, true);
	return a < b? a : b;
}
pure T set(T)(T a, T b)
{
	pragma(inline, true);
	return a;
}
pure T maxOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T maxOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T minOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T minOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T addOadd(T)(T sm, T ad, size_t l)
{
	pragma(inline, true);
	return sm + ad * cast(T)l;
}

long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = TSTL!(int, "add", "add");
	auto n = 1000;
	int[] brute = new int[](n);
	auto smart = SumQSumU(n, 0);
	int rounds = 10;
	foreach(round; 0 .. rounds)
	{
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				int v = uniform!"[]"(1, 20);
				brute[i .. j] += v;
				smart.rangeU(i, j, v);
			}
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
				auto smartAnswer = smart.rangeF(i, j);
				assert(bruteAnswer == smartAnswer);
			}
	}
}
// }}}

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	alias SegTree = TSTL!(Tuple!(int, int), "max", "set", tuple(0, -1));
	auto st = SegTree(noPoints, tuple(0, -1));
	auto dp = new Tuple!(int, int)[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = tuple(0, -1);
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st.rangeF(range[0], range[1] + 1));
		}
		dpi[0]++;
		foreach(range; ranges[i])
		{
			st.rangeU(range[0], range[1] + 1, tuple(dpi[0], cast(int)i));
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i][0] > bdpi)
		{
			bdpi = dp[i][0];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;
	while (bi >= 0)
	{
		alive[bi] = false;
		bi = dp[bi][1];
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
struct STL(V, U,
		V neutral,
		alias f,
		alias fou,
		alias uou,
		string fName = "f", string uName = "u")
{
	struct Node
	{
		V f;
		U u;
		bool hasU;
		size_t sz;
	}
	Node[] _n;
	size_t length = 0;
	int layers = 0;
	this(size_t n, V v)
	{
		import std.math;
		n = cast(size_t) nextPow2(n);
		layers = cast(int) log2(n) + 1;
		length = n;
		auto noNodes = 2 * n;

		_n = new Node[](noNodes);

		foreach(i; n .. 2 * n)
		{
			_n[i].f = v;
			_n[i].sz = 1;
		}
		foreach_reverse(i; 1 .. n)
		{
			_n[i].f = f(_n[i<<1].f, _n[(i<<1)^1].f);
			_n[i].sz = _n[i<<1].sz << 1;
		}
	}
	void _clearU(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach_reverse(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _clearU(l >> layer);
			if (r & lowerBits) _clearU(r >> layer);
		}
	}
	void _refresh(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _refresh(l >> layer);
			if (r & lowerBits) _refresh(r >> layer);
		}
	}
	void _refresh(size_t i)
	{
		pragma(inline, true);
		assert(!_isLeaf(i));
		_n[i].f = f(_n[i<<1].f, _n[(i<<1)^1].f);
	}
	V rangeF(size_t l, size_t r)
	{
		l += length, r += length;
		_clearU(l, r);
		V value = neutral;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1)
				value = f(value, _n[l++].f);
			if (r & 1)
				value = f(value, _n[--r].f);
		}
		return value;
	}
	void rangeU(size_t l, size_t r, U u)
	{
		l += length, r += length;
		auto ol = l, or = r;
		_clearU(l, r);
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) _addU(l++, u);
			if (r & 1) _addU(--r, u);
		}
		_refresh(ol, or);
	}
	bool _isLeaf(size_t i)
	{
		pragma(inline, true);
		return i >= length;
	}
	void _clearU(size_t i)
	{
		pragma(inline, true);
		if (!_n[i].hasU) return;
		assert(!_isLeaf(i));
		_n[i].hasU = false;
		_addU(i << 1, _n[i].u), _addU((i << 1) ^ 1, _n[i].u);
		assert(_n[i].f == f(_n[i<<1].f, _n[(i<<1)^1].f));
	}
	void _addU(size_t i, U u)
	{
		pragma(inline, true);
		if (!_n[i].hasU)
		{
			_n[i].hasU = true;
			_n[i].u = u;
		}
		else
		{
			_n[i].u = uou(u, _n[i].u);
		}
		_n[i].f = fou(_n[i].f, u, _n[i].sz);
	}
	int[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
	{
		return [cast(int)start, cast(int)end];
	}
	auto opIndex(int[2] slice)
	{
		alias Parent = typeof(this);
		struct Ans
		{
			Parent* parent;
			int[2] slice;
			mixin(q{V }, fName, q{;});
			void opOpAssign(string op)(U u) if (op == uName)
			{
				parent.rangeU(slice[0], slice[1], u);
			}
		}
		return Ans(&this, slice, rangeF(slice[0], slice[1]));
	}
}
template TSTL(V, string f, string u, neutral...)
{
	alias funF = mixin(f);
	alias funUoU = mixin(u);
	alias funFoU = mixin(f, "O", u);
	static if (neutral.length == 1)
		immutable neut = neutral[0];
	else static if (neutral.length == 0)
	{
		alias neutralTemplate = mixin(f, "Neutral");
		immutable neut = neutralTemplate!V;
	}
	else static assert(false);
	alias TSTL = STL!(V, V, neut, funF, funFoU, funUoU, f, u);
}
immutable maxNeutral(T) = T.min;
pure T max(T)(T a, T b)
{
	pragma(inline, true);
	return a > b? a : b;
}
immutable addNeutral(T) = T(0);
pure T add(T)(T a, T b)
{
	pragma(inline, true);
	return a + b;
}
pure T min(T)(T a, T b)
{
	pragma(inline, true);
	return a < b? a : b;
}
pure T set(T)(T a, T b)
{
	pragma(inline, true);
	return a;
}
pure T maxOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T maxOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T minOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T minOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T addOadd(T)(T sm, T ad, size_t l)
{
	pragma(inline, true);
	return sm + ad * cast(T)l;
}

long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = TSTL!(int, "add", "add");
	auto n = 1000;
	int[] brute = new int[](n);
	auto smart = SumQSumU(n, 0);
	int rounds = 10;
	foreach(round; 0 .. rounds)
	{
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				int v = uniform!"[]"(1, 20);
				brute[i .. j] += v;
				smart.rangeU(i, j, v);
			}
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
				auto smartAnswer = smart.rangeF(i, j);
				assert(bruteAnswer == smartAnswer);
			}
	}
}
// }}}

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	alias SegTree = TSTL!(Tuple!(int, int), "max", "set", tuple(0, -1));
	auto st = SegTree(noPoints, tuple(0, -1));
	auto dp = new Tuple!(int, int)[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = tuple(0, -1);
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st.rangeF(range[0], range[1] + 1));
		}
		dpi[0]++;
		foreach(range; ranges[i])
		{
			st.rangeU(range[0], range[1] + 1, tuple(dpi[0], cast(int)i));
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i][0] > bdpi)
		{
			bdpi = dp[i][0];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;
	while (bi >= 0)
	{
		alive[bi] = false;
		bi = dp[bi][1];
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
struct STL(V, U,
		V neutral,
		alias f,
		alias fou,
		alias uou,
		string fName = "f", string uName = "u")
{
	V[] _nF;
	U[] _nU;
	bool[] _nHasU;
	size_t[] _nSz;
	size_t length = 0;
	int layers = 0;
	this(size_t n, V v)
	{
		import std.math;
		n = cast(size_t) nextPow2(n);
		layers = cast(int) log2(n) + 1;
		length = n;
		auto noNodes = 2 * n;

		_nF = new V[](noNodes);
		_nU = new U[](noNodes);
		_nHasU = new bool[](noNodes);
		_nSz = new size_t[](noNodes);

		if (v != V.init) _nF[n .. 2 * n] = v;
		foreach_reverse(i; 1 .. n) _nF[i] = f(_nF[i<<1], _nF[(i<<1)+1]);
		_nSz[n .. 2 * n] = 1;
		foreach_reverse(i; 1 .. n) _nSz[i] = _nSz[i<<1] << 1;
	}
	void _clearU(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach_reverse(layer; 1 .. layers)
		{
			auto lp = (l >> layer);
			auto rp = (r >> layer);
			if ((lp << layer) != l) _clearU(l >> layer);
			if ((rp << layer) != r) _clearU(r >> layer);
		}
	}
	void _refresh(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach(layer; 1 .. layers)
		{
			auto lp = (l >> layer);
			auto rp = (r >> layer);
			if ((lp << layer) != l) _refresh(l >> layer);
			if ((rp << layer) != r) _refresh(r >> layer);
		}
	}
	void _refresh(size_t i)
	{
		pragma(inline, true);
		assert(!_isLeaf(i));
		_nF[i] = f(_nF[i<<1], _nF[(i<<1)^1]);
	}
	V rangeF(size_t l, size_t r)
	{
		l += length, r += length;
		_clearU(l, r);
		V value = neutral;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1)
				value = f(value, _nF[l++]);
			if (r & 1)
				value = f(value, _nF[--r]);
		}
		return value;
	}
	void rangeU(size_t l, size_t r, U u)
	{
		l += length, r += length;
		auto ol = l, or = r;
		_clearU(l, r);
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) _addU(l++, u);
			if (r & 1) _addU(--r, u);
		}
		_refresh(ol, or);
	}
	bool _isLeaf(size_t i)
	{
		pragma(inline, true);
		return i >= length;
	}
	void _clearU(size_t i)
	{
		pragma(inline, true);
		if (!_nHasU[i]) return;
		assert(!_isLeaf(i));
		_addU(i << 1, _nU[i]), _addU((i << 1) + 1, _nU[i]);
		_nHasU[i] = false;
		assert(_nF[i] == f(_nF[i<<1], _nF[(i<<1)^1]));
	}
	void _addU(size_t i, U u)
	{
		pragma(inline, true);
		if (!_nHasU[i])
		{
			_nHasU[i] = true;
			_nU[i] = u;
		}
		else
		{
			_nU[i] = uou(u, _nU[i]);
		}
		_nF[i] = fou(_nF[i], u, _nSz[i]);
	}
	int[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
	{
		return [cast(int)start, cast(int)end];
	}
	auto opIndex(int[2] slice)
	{
		alias Parent = typeof(this);
		struct Ans
		{
			Parent* parent;
			int[2] slice;
			mixin(q{V }, fName, q{;});
			void opOpAssign(string op)(U u) if (op == uName)
			{
				parent.rangeU(slice[0], slice[1], u);
			}
		}
		return Ans(&this, slice, rangeF(slice[0], slice[1]));
	}
}
template TSTL(V, string f, string u, neutral...)
{
	alias funF = mixin(f);
	alias funUoU = mixin(u);
	alias funFoU = mixin(f, "O", u);
	static if (neutral.length == 1)
		immutable neut = neutral[0];
	else static if (neutral.length == 0)
	{
		alias neutralTemplate = mixin(f, "Neutral");
		immutable neut = neutralTemplate!V;
	}
	else static assert(false);
	alias TSTL = STL!(V, V, neut, funF, funFoU, funUoU, f, u);
}
immutable maxNeutral(T) = T.min;
pure T max(T)(T a, T b)
{
	pragma(inline, true);
	return a > b? a : b;
}
immutable addNeutral(T) = T(0);
pure T add(T)(T a, T b)
{
	pragma(inline, true);
	return a + b;
}
pure T min(T)(T a, T b)
{
	pragma(inline, true);
	return a < b? a : b;
}
pure T set(T)(T a, T b)
{
	pragma(inline, true);
	return a;
}
pure T maxOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T maxOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T minOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T minOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T addOadd(T)(T sm, T ad, size_t l)
{
	pragma(inline, true);
	return sm + ad * cast(T)l;
}

long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = TSTL!(int, "add", "add");
	auto n = 1000;
	int[] brute = new int[](n);
	auto smart = SumQSumU(n, 0);
	int rounds = 10;
	foreach(round; 0 .. rounds)
	{
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				int v = uniform!"[]"(1, 20);
				brute[i .. j] += v;
				smart.rangeU(i, j, v);
			}
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
				auto smartAnswer = smart.rangeF(i, j);
				assert(bruteAnswer == smartAnswer);
			}
	}
}
// }}}

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	alias SegTree = TSTL!(Tuple!(int, int), "max", "set", tuple(0, -1));
	auto st = SegTree(noPoints, tuple(0, -1));
	auto dp = new Tuple!(int, int)[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = tuple(0, -1);
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st.rangeF(range[0], range[1] + 1));
		}
		dpi[0]++;
		foreach(range; ranges[i])
		{
			st.rangeU(range[0], range[1] + 1, tuple(dpi[0], cast(int)i));
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i][0] > bdpi)
		{
			bdpi = dp[i][0];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;
	while (bi >= 0)
	{
		alive[bi] = false;
		bi = dp[bi][1];
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
struct STL(V, U,
		V neutral,
		alias f,
		alias fou,
		alias uou,
		string fName = "f", string uName = "u")
{
	V[] _nF;
	U[] _nU;
	bool[] _nHasU;
	size_t[] _nSz;
	size_t length = 0;
	int layers = 0;
	this(size_t n, V v)
	{
		import std.math;
		n = cast(size_t) nextPow2(n);
		layers = cast(int) log2(n) + 1;
		length = n;
		auto noNodes = 2 * n;

		_nF = new V[](noNodes);
		_nU = new U[](noNodes);
		_nHasU = new bool[](noNodes);
		_nSz = new size_t[](noNodes);

		if (v != V.init) _nF[n .. 2 * n] = v;
		foreach_reverse(i; 1 .. n) _nF[i] = f(_nF[i<<1], _nF[(i<<1)+1]);
		_nSz[n .. 2 * n] = 1;
		foreach_reverse(i; 1 .. n) _nSz[i] = _nSz[i<<1] << 1;
	}
	void _clearU(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach_reverse(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _clearU(l >> layer);
			if (r & lowerBits) _clearU(r >> layer);
		}
	}
	void _refresh(size_t l, size_t r)
	{
		pragma(inline, true);
		foreach(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _refresh(l >> layer);
			if (r & lowerBits) _refresh(r >> layer);
		}
	}
	void _refresh(size_t i)
	{
		pragma(inline, true);
		assert(!_isLeaf(i));
		_nF[i] = f(_nF[i<<1], _nF[(i<<1)^1]);
	}
	V rangeF(size_t l, size_t r)
	{
		l += length, r += length;
		_clearU(l, r);
		V value = neutral;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1)
				value = f(value, _nF[l++]);
			if (r & 1)
				value = f(value, _nF[--r]);
		}
		return value;
	}
	void rangeU(size_t l, size_t r, U u)
	{
		l += length, r += length;
		auto ol = l, or = r;
		_clearU(l, r);
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) _addU(l++, u);
			if (r & 1) _addU(--r, u);
		}
		_refresh(ol, or);
	}
	bool _isLeaf(size_t i)
	{
		pragma(inline, true);
		return i >= length;
	}
	void _clearU(size_t i)
	{
		pragma(inline, true);
		if (!_nHasU[i]) return;
		assert(!_isLeaf(i));
		_addU(i << 1, _nU[i]), _addU((i << 1) + 1, _nU[i]);
		_nHasU[i] = false;
		assert(_nF[i] == f(_nF[i<<1], _nF[(i<<1)^1]));
	}
	void _addU(size_t i, U u)
	{
		pragma(inline, true);
		if (!_nHasU[i])
		{
			_nHasU[i] = true;
			_nU[i] = u;
		}
		else
		{
			_nU[i] = uou(u, _nU[i]);
		}
		_nF[i] = fou(_nF[i], u, _nSz[i]);
	}
	int[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
	{
		return [cast(int)start, cast(int)end];
	}
	auto opIndex(int[2] slice)
	{
		alias Parent = typeof(this);
		struct Ans
		{
			Parent* parent;
			int[2] slice;
			mixin(q{V }, fName, q{;});
			void opOpAssign(string op)(U u) if (op == uName)
			{
				parent.rangeU(slice[0], slice[1], u);
			}
		}
		return Ans(&this, slice, rangeF(slice[0], slice[1]));
	}
}
template TSTL(V, string f, string u, neutral...)
{
	alias funF = mixin(f);
	alias funUoU = mixin(u);
	alias funFoU = mixin(f, "O", u);
	static if (neutral.length == 1)
		immutable neut = neutral[0];
	else static if (neutral.length == 0)
	{
		alias neutralTemplate = mixin(f, "Neutral");
		immutable neut = neutralTemplate!V;
	}
	else static assert(false);
	alias TSTL = STL!(V, V, neut, funF, funFoU, funUoU, f, u);
}
immutable maxNeutral(T) = T.min;
pure T max(T)(T a, T b)
{
	pragma(inline, true);
	return a > b? a : b;
}
immutable addNeutral(T) = T(0);
pure T add(T)(T a, T b)
{
	pragma(inline, true);
	return a + b;
}
pure T min(T)(T a, T b)
{
	pragma(inline, true);
	return a < b? a : b;
}
pure T set(T)(T a, T b)
{
	pragma(inline, true);
	return a;
}
pure T maxOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T maxOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T minOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T minOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T addOadd(T)(T sm, T ad, size_t l)
{
	pragma(inline, true);
	return sm + ad * cast(T)l;
}

long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = TSTL!(int, "add", "add");
	auto n = 1000;
	int[] brute = new int[](n);
	auto smart = SumQSumU(n, 0);
	int rounds = 10;
	foreach(round; 0 .. rounds)
	{
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				int v = uniform!"[]"(1, 20);
				brute[i .. j] += v;
				smart.rangeU(i, j, v);
			}
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
				auto smartAnswer = smart.rangeF(i, j);
				assert(bruteAnswer == smartAnswer);
			}
	}
}
// }}}

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	alias SegTree = TSTL!(Tuple!(int, int), "max", "set", tuple(0, -1));
	auto st = SegTree(noPoints, tuple(0, -1));
	auto dp = new Tuple!(int, int)[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = tuple(0, -1);
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st.rangeF(range[0], range[1] + 1));
		}
		dpi[0]++;
		foreach(range; ranges[i])
		{
			st.rangeU(range[0], range[1] + 1, tuple(dpi[0], cast(int)i));
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i][0] > bdpi)
		{
			bdpi = dp[i][0];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;
	while (bi >= 0)
	{
		alive[bi] = false;
		bi = dp[bi][1];
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
struct STL(V, U,
		V neutral,
		alias f,
		alias fou,
		alias uou,
		string fName = "f", string uName = "u")
{
	V[] _nF;
	U[] _nU;
	bool[] _nHasU;
	size_t[] _nSz;
	size_t length = 0;
	int layers = 0;
	this(size_t n, V v)
	{
		import std.math;
		n = cast(size_t) nextPow2(n);
		layers = cast(int) log2(n) + 1;
		length = n;
		auto noNodes = 2 * n;

		_nF = new V[](noNodes);
		_nU = new U[](noNodes);
		_nHasU = new bool[](noNodes);
		_nSz = new size_t[](noNodes);

		if (v != V.init) _nF[n .. 2 * n] = v;
		foreach_reverse(i; 1 .. n) _nF[i] = f(_nF[i<<1], _nF[(i<<1)+1]);
		_nSz[n .. 2 * n] = 1;
		foreach_reverse(i; 1 .. n) _nSz[i] = _nSz[i<<1] << 1;
	}
	void _clearU(size_t l, size_t r)
	{
		foreach_reverse(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _clearU(l >> layer);
			if (r & lowerBits) _clearU(r >> layer);
		}
	}
	void _refresh(size_t l, size_t r)
	{
		foreach(layer; 1 .. layers)
		{
			auto lowerBits = (1 << layer) - 1;
			if (l & lowerBits) _refresh(l >> layer);
			if (r & lowerBits) _refresh(r >> layer);
		}
	}
	void _refresh(size_t i)
	{
		assert(!_isLeaf(i));
		_nF[i] = f(_nF[i<<1], _nF[(i<<1)^1]);
	}
	V rangeF(size_t l, size_t r)
	{
		l += length, r += length;
		_clearU(l, r);
		V value = neutral;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1)
				value = f(value, _nF[l++]);
			if (r & 1)
				value = f(value, _nF[--r]);
		}
		return value;
	}
	void rangeU(size_t l, size_t r, U u)
	{
		l += length, r += length;
		auto ol = l, or = r;
		_clearU(l, r);
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) _addU(l++, u);
			if (r & 1) _addU(--r, u);
		}
		_refresh(ol, or);
	}
	bool _isLeaf(size_t i)
	{
		pragma(inline, true);
		return i >= length;
	}
	void _clearU(size_t i)
	{
		if (!_nHasU[i]) return;
		assert(!_isLeaf(i));
		_addU(i << 1, _nU[i]), _addU((i << 1) + 1, _nU[i]);
		_nHasU[i] = false;
		assert(_nF[i] == f(_nF[i<<1], _nF[(i<<1)^1]));
	}
	void _addU(size_t i, U u)
	{
		if (!_nHasU[i])
		{
			_nHasU[i] = true;
			_nU[i] = u;
		}
		else
		{
			_nU[i] = uou(u, _nU[i]);
		}
		_nF[i] = fou(_nF[i], u, _nSz[i]);
	}
	int[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
	{
		return [cast(int)start, cast(int)end];
	}
	auto opIndex(int[2] slice)
	{
		alias Parent = typeof(this);
		struct Ans
		{
			Parent* parent;
			int[2] slice;
			mixin(q{V }, fName, q{;});
			void opOpAssign(string op)(U u) if (op == uName)
			{
				parent.rangeU(slice[0], slice[1], u);
			}
		}
		return Ans(&this, slice, rangeF(slice[0], slice[1]));
	}
}
template TSTL(V, string f, string u, neutral...)
{
	alias funF = mixin(f);
	alias funUoU = mixin(u);
	alias funFoU = mixin(f, "O", u);
	static if (neutral.length == 1)
		immutable neut = neutral[0];
	else static if (neutral.length == 0)
	{
		alias neutralTemplate = mixin(f, "Neutral");
		immutable neut = neutralTemplate!V;
	}
	else static assert(false);
	alias TSTL = STL!(V, V, neut, funF, funFoU, funUoU, f, u);
}
immutable maxNeutral(T) = T.min;
pure T max(T)(T a, T b)
{
	pragma(inline, true);
	return a > b? a : b;
}
immutable addNeutral(T) = T(0);
pure T add(T)(T a, T b)
{
	pragma(inline, true);
	return a + b;
}
pure T min(T)(T a, T b)
{
	pragma(inline, true);
	return a < b? a : b;
}
pure T set(T)(T a, T b)
{
	pragma(inline, true);
	return a;
}
pure T maxOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T maxOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T minOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T minOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T addOadd(T)(T sm, T ad, size_t l)
{
	pragma(inline, true);
	return sm + ad * cast(T)l;
}

long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = TSTL!(int, "add", "add");
	auto n = 1000;
	int[] brute = new int[](n);
	auto smart = SumQSumU(n, 0);
	int rounds = 10;
	foreach(round; 0 .. rounds)
	{
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				int v = uniform!"[]"(1, 20);
				brute[i .. j] += v;
				smart.rangeU(i, j, v);
			}
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
				auto smartAnswer = smart.rangeF(i, j);
				assert(bruteAnswer == smartAnswer);
			}
	}
}
// }}}

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	auto st = TSTL!(int, "max", "set", int.min)(noPoints, 0);
	auto st2 = TSTL!(int, "max", "add", 0)(noPoints, 0);
	auto dp = new int[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = 0;
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st[range[0] .. range[1] + 1].max);
		}
		dpi++;
		foreach(range; ranges[i])
		{
			st.rangeU(range[0], range[1] + 1, dpi);
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i] > bdpi)
		{
			bdpi = dp[i];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;

	foreach(range; ranges[bi]) st2.rangeU(range[0], range[1] + 1, 1);
	alive[bi] = false;
	auto pbi = bi;
	bi--;
	while (bi >= 0)
	{
		if (dp[bi] == dp[pbi] - 1)
		{
			bool isGood = false;
			foreach(range; ranges[bi])
			{
					if (st2.rangeF(range[0], range[1] + 1) > 0) { isGood = true; break; }
			}
			if (isGood)
			{
				foreach(range; ranges[pbi])
					st2.rangeU(range[0], range[1] + 1, -1);
				foreach(range; ranges[bi])
					st2.rangeU(range[0], range[1] + 1, +1);
				alive[bi] = false;
				pbi = bi;
			}
		}
		bi--;
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
struct STL(V, U,
		V neutral,
		U emptyU,
		alias f,
		alias fou,
		alias uou,
		string fName = "f", string uName = "u",
		staticSize...)
{
	static immutable bool isStatic = staticSize.length > 0;
	static if (isStatic)
	{
		immutable size_t size = cast(size_t)nextPow2(staticSize[0]) * 2;
		V[size] _nF;
		U[size] _nU;
		size_t[size] _nSz;
	}
	else
	{
		V[] _nF;
		U[] _nU;
		size_t[] _nSz;
	}
	size_t length = 0;
	int layers = 0;
	this(size_t n, V v)
	{
		n = cast(size_t)nextPow2(cast(long)n);
		auto fn = n;
		while (fn) {layers++; fn >>= 1;}
		length = n;
		auto noNodes = 2 * n;

		static if (!isStatic)
		{
			_nF = new V[](noNodes);
			_nU = new U[](noNodes);
			_nSz = new size_t[](noNodes);
		}

		if (v != V.init) _nF[n .. 2 * n] = v;
		foreach_reverse(i; 1 .. n) _nF[i] = f(_nF[i<<1], _nF[(i<<1)+1]);
		_nSz[n .. 2 * n] = 1;
		foreach_reverse(i; 1 .. n) _nSz[i] = _nSz[i<<1] << 1;
	}
	void _clearU(size_t l, size_t r)
	{
		r--;
		auto li = layers - 1;
		for(; li > 0 && (l >> li) == (r >> li); li--) _clearU(l >> li);
		for(; li > 0; li--) _clearU(l >> li), _clearU(r >> li);
	}
	void _refresh(size_t l, size_t r)
	{
		r--;
		l >>= 1; r >>= 1;
		for(; l != r; l >>= 1, r >>= 1)
		{
			_nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
			_nF[r] = f(_getNodeF(r<<1), _getNodeF((r<<1)+1));
		}
		for(; l; l >>= 1) _nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
	}
	V rangeF(size_t l, size_t r)
	{
		l += length, r += length;
		_clearU(l, r);
		V value = neutral;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1)
			{
				value = f(value, _getNodeF(l++));
			}
			if (r & 1)
			{
				value = f(value, _getNodeF(--r));
			}
		}
		return value;
	}
	void rangeU(size_t l, size_t r, U u)
	{
		l += length, r += length;
		auto ol = l, or = r;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) _addU(l++, u);
			if (r & 1) _addU(--r, u);
		}
		_refresh(ol, or);
	}
	V _getNodeF(size_t i)
	{
		if (_nU[i] != emptyU) return cast(V) fou(_nF[i], _nU[i], _nSz[i]);
		return _nF[i];
	}
	bool _isLeaf(size_t i)
	{
		return i >= length;
	}
	void _clearU(size_t i)
	{
		if (_nU[i] == emptyU) return;
		if (_isLeaf(i))
		{
			_nF[i] = _getNodeF(i);
			_nU[i] = emptyU;
			return;
		}
		_addU(i << 1, _nU[i]), _addU((i << 1) + 1, _nU[i]);
		_nU[i] = emptyU;
		_nF[i] = f(_getNodeF(i<<1), _getNodeF((i<<1)+1));
	}
	void _addU(size_t i, U u)
	{
		if (_nU[i] == emptyU)
		{
			_nU[i] = u;
			return;
		}
		_nU[i] = uou(u, _nU[i]);
	}
	int[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
	{
		return [cast(int)start, cast(int)end];
	}
	auto opIndex(int[2] slice)
	{
		alias Parent = typeof(this);
		struct Ans
		{
			Parent* parent;
			int[2] slice;
			mixin(q{V }, fName, q{;});
			void opOpAssign(string op)(U u) if (op == uName)
			{
				parent.rangeU(slice[0], slice[1], u);
			}
		}
		return Ans(&this, slice, rangeF(slice[0], slice[1]));
	}
}
template TSTL(V, string f, string u, V emptyU, neutral...)
{
	alias funF = mixin(f);
	alias funUoU = mixin(u);
	alias funFoU = mixin(f, "O", u);
	static if (neutral.length == 1)
		immutable neut = neutral[0];
	else static if (neutral.length == 0)
	{
		alias neutralTemplate = mixin(f, "Neutral");
		immutable neut = neutralTemplate!V;
	}
	else static assert(false);
	alias TSTL = STL!(V, V, neut, emptyU, funF, funFoU, funUoU, f, u);
}
immutable maxNeutral(T) = T.min;
pure T max(T)(T a, T b)
{
	pragma(inline, true);
	return a > b? a : b;
}
immutable addNeutral(T) = T(0);
pure T add(T)(T a, T b)
{
	pragma(inline, true);
	return a + b;
}
pure T min(T)(T a, T b)
{
	pragma(inline, true);
	return a < b? a : b;
}
pure T set(T)(T a, T b)
{
	pragma(inline, true);
	return a;
}
pure T maxOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T maxOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T minOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T minOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T addOadd(T)(T sm, T ad, size_t l)
{
	pragma(inline, true);
	return sm + ad * cast(T)l;
}

long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = TSTL!(int, "add", "add");
	auto n = 100;
	int[] brute = new int[](n);
	auto smart = SumQSumU(n, 0);
	int rounds = 100;
	foreach(round; 0 .. rounds)
	{
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				int v = uniform!"[]"(1, 20);
				brute[i .. j] += v;
				smart.rangeU(i, j, v);
			}
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
				auto smartAnswer = smart.rangeF(i, j);
				assert(bruteAnswer == smartAnswer);
			}
	}
}
// }}}

immutable multi = false;

void solve(int tc)
{
	import core.memory;
	GC.disable;
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	auto st = TSTL!(int, "max", "set", false)(noPoints, 0);
	auto st2 = TSTL!(int, "max", "add", false)(noPoints, 0);
	auto dp = new int[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = 0;
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st[range[0] .. range[1] + 1].max);
		}
		dpi++;
		foreach(range; ranges[i])
		{
			st.rangeU(range[0], range[1] + 1, dpi);
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i] > bdpi)
		{
			bdpi = dp[i];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;

	foreach(range; ranges[bi]) st2.rangeU(range[0], range[1] + 1, 1);
	alive[bi] = false;
	auto pbi = bi;
	bi--;
	while (bi >= 0)
	{
		if (dp[bi] == dp[pbi] - 1)
		{
			bool isGood = false;
			foreach(range; ranges[bi])
			{
					if (st2.rangeF(range[0], range[1] + 1) > 0) { isGood = true; break; }
			}
			if (isGood)
			{
				foreach(range; ranges[pbi])
					st2.rangeU(range[0], range[1] + 1, -1);
				foreach(range; ranges[bi])
					st2.rangeU(range[0], range[1] + 1, +1);
				alive[bi] = false;
				pbi = bi;
			}
		}
		bi--;
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
	GC.enable;
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
struct STL(V, U,
		V neutral,
		alias f,
		alias fou,
		alias uou,
		string fName = "f", string uName = "u",
		staticSize...)
{
	static immutable bool isStatic = staticSize.length > 0;
	static if (isStatic)
	{
		immutable size_t size = cast(size_t)nextPow2(staticSize[0]) * 2;
		V[size] _nF;
		U[size] _nU;
		size_t[size] _nSz;
		bool[size] _nHasU;
	}
	else
	{
		V[] _nF;
		U[] _nU;
		size_t[] _nSz;
		bool[] _nHasU;
	}
	size_t length = 0;
	int layers = 0;
	this(size_t n, V v)
	{
		n = cast(size_t)nextPow2(cast(long)n);
		auto fn = n;
		while (fn) {layers++; fn >>= 1;}
		length = n;
		auto noNodes = 2 * n;

		static if (!isStatic)
		{
			_nF = new V[](noNodes);
			_nU = new U[](noNodes);
			_nHasU = new bool[](noNodes);
			_nSz = new size_t[](noNodes);
		}

		if (v != V.init) _nF[n .. 2 * n] = v;
		foreach_reverse(i; 1 .. n) _nF[i] = f(_nF[i<<1], _nF[(i<<1)+1]);
		_nSz[n .. 2 * n] = 1;
		foreach_reverse(i; 1 .. n) _nSz[i] = _nSz[i<<1] << 1;
	}
	void _clearU(size_t l, size_t r)
	{
		r--;
		auto li = layers - 1;
		for(; li > 0 && (l >> li) == (r >> li); li--) _clearU(l >> li);
		for(; li > 0; li--) _clearU(l >> li), _clearU(r >> li);
	}
	void _refresh(size_t l, size_t r)
	{
		r--;
		l >>= 1; r >>= 1;
		for(; l != r; l >>= 1, r >>= 1)
		{
			_nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
			_nF[r] = f(_getNodeF(r<<1), _getNodeF((r<<1)+1));
		}
		for(; l; l >>= 1) _nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
	}
	V rangeF(size_t l, size_t r)
	{
		l += length, r += length;
		_clearU(l, r);
		V value = neutral;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1)
			{
				value = f(value, _getNodeF(l++));
			}
			if (r & 1)
			{
				value = f(value, _getNodeF(--r));
			}
		}
		return value;
	}
	void rangeU(size_t l, size_t r, U u)
	{
		l += length, r += length;
		auto ol = l, or = r;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) _addU(l++, u);
			if (r & 1) _addU(--r, u);
		}
		_refresh(ol, or);
	}
	V _getNodeF(size_t i)
	{
		if (_nHasU[i]) return cast(V) fou(_nF[i], _nU[i], _nSz[i]);
		return _nF[i];
	}
	bool _isLeaf(size_t i)
	{
		return i >= length;
	}
	void _clearU(size_t i)
	{
		if (!_nHasU[i]) return;
		if (_isLeaf(i))
		{
			_nF[i] = _getNodeF(i);
			_nHasU[i] = false;
			return;
		}
		_nHasU[i] = false;
		_addU(i << 1, _nU[i]), _addU((i << 1) + 1, _nU[i]);
		_nF[i] = f(_getNodeF(i<<1), _getNodeF((i<<1)+1));
	}
	void _addU(size_t i, U u)
	{
		if (!_nHasU[i])
		{
			_nU[i] = u;
			_nHasU[i] = true;
			return;
		}
		_nU[i] = uou(u, _nU[i]);
	}
	int[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
	{
		return [cast(int)start, cast(int)end];
	}
	auto opIndex(int[2] slice)
	{
		alias Parent = typeof(this);
		struct Ans
		{
			Parent* parent;
			int[2] slice;
			mixin(q{V }, fName, q{;});
			void opOpAssign(string op)(U u) if (op == uName)
			{
				parent.rangeU(slice[0], slice[1], u);
			}
		}
		return Ans(&this, slice, rangeF(slice[0], slice[1]));
	}
}
template TSTL(V, string f, string u, bool hasSize, args...)
{
	static if (hasSize)
	{
		auto neutral = args[1 .. $];
	}
	else
	{
		auto neutral = args[0 .. $];
	}
	alias funF = mixin(f);
	alias funUoU = mixin(u);
	alias funFoU = mixin(f, "O", u);
	static if (neutral.length == 1)
		immutable neut = neutral[0];
	else static if (neutral.length == 0)
	{
		alias neutralTemplate = mixin(f, "Neutral");
		immutable neut = neutralTemplate!V;
	}
	else static assert(false);

	static if (hasSize) alias TSTL = STL!(V, V, neut, funF, funFoU, funUoU, f, u, args[0]);
	else alias TSTL = STL!(V, V, neut, funF, funFoU, funUoU, f, u);
}
immutable maxNeutral(T) = T.min;
pure T max(T)(T a, T b)
{
	pragma(inline, true);
	return a > b? a : b;
}
immutable addNeutral(T) = T(0);
pure T add(T)(T a, T b)
{
	pragma(inline, true);
	return a + b;
}
pure T min(T)(T a, T b)
{
	pragma(inline, true);
	return a < b? a : b;
}
pure T set(T)(T a, T b)
{
	pragma(inline, true);
	return a;
}
pure T maxOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T maxOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T minOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T minOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T addOadd(T)(T sm, T ad, size_t l)
{
	pragma(inline, true);
	return sm + ad * cast(T)l;
}

long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = TSTL!(int, "add", "add");
	auto n = 100;
	int[] brute = new int[](n);
	auto smart = SumQSumU(n, 0);
	int rounds = 100;
	foreach(round; 0 .. rounds)
	{
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				int v = uniform!"[]"(1, 20);
				brute[i .. j] += v;
				smart.rangeU(i, j, v);
			}
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
				auto smartAnswer = smart.rangeF(i, j);
				assert(bruteAnswer == smartAnswer);
			}
	}
}
// }}}

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	auto st = TSTL!(int, "max", "set", false)(noPoints, 0);
	auto st2 = TSTL!(int, "max", "add", false)(noPoints, 0);
	auto dp = new int[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = 0;
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st[range[0] .. range[1] + 1].max);
		}
		dpi++;
		foreach(range; ranges[i])
		{
			st.rangeU(range[0], range[1] + 1, dpi);
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i] > bdpi)
		{
			bdpi = dp[i];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;

	foreach(range; ranges[bi]) st2.rangeU(range[0], range[1] + 1, 1);
	alive[bi] = false;
	auto pbi = bi;
	bi--;
	while (bi >= 0)
	{
		if (dp[bi] == dp[pbi] - 1)
		{
			bool isGood = false;
			foreach(range; ranges[bi])
			{
					if (st2.rangeF(range[0], range[1] + 1) > 0) { isGood = true; break; }
			}
			if (isGood)
			{
				foreach(range; ranges[pbi])
					st2.rangeU(range[0], range[1] + 1, -1);
				foreach(range; ranges[bi])
					st2.rangeU(range[0], range[1] + 1, +1);
				alive[bi] = false;
				pbi = bi;
			}
		}
		bi--;
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
struct STL(V, U,
		V neutral,
		alias f,
		alias fou,
		alias uou,
		string fName = "f", string uName = "u",
		staticSize...)
{
	static immutable bool isStatic = staticSize.length > 0;
	static if (isStatic)
	{
		immutable size_t size = cast(size_t)nextPow2(staticSize[0]) * 2;
		V[size] _nF;
		U[size] _nU;
		size_t[size] _nSz;
		bool[size] _nHasU;
	}
	else
	{
		V[] _nF;
		U[] _nU;
		size_t[] _nSz;
		bool[] _nHasU;
	}
	size_t length = 0;
	int layers = 0;
	this(size_t n, V v)
	{
		n = cast(size_t)nextPow2(cast(long)n);
		auto fn = n;
		while (fn) {layers++; fn >>= 1;}
		length = n;
		auto noNodes = 2 * n;

		static if (!isStatic)
		{
			_nF = new V[](noNodes);
			_nU = new U[](noNodes);
			_nHasU = new bool[](noNodes);
			_nSz = new size_t[](noNodes);
		}

		if (v != V.init) _nF[n .. 2 * n] = v;
		foreach_reverse(i; 1 .. n) _nF[i] = f(_nF[i<<1], _nF[(i<<1)+1]);
		_nSz[n .. 2 * n] = 1;
		foreach_reverse(i; 1 .. n) _nSz[i] = _nSz[i<<1] << 1;
	}
	void _clearU(size_t l, size_t r)
	{
		r--;
		auto li = layers - 1;
		for(; li > 0 && (l >> li) == (r >> li); li--) _clearU(l >> li);
		for(; li > 0; li--) _clearU(l >> li), _clearU(r >> li);
	}
	void _refresh(size_t l, size_t r)
	{
		r--;
		l >>= 1; r >>= 1;
		for(; l != r; l >>= 1, r >>= 1)
		{
			_nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
			_nF[r] = f(_getNodeF(r<<1), _getNodeF((r<<1)+1));
		}
		for(; l; l >>= 1) _nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
	}
	V rangeF(size_t l, size_t r)
	{
		l += length, r += length;
		_clearU(l, r);
		V value = neutral;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1)
			{
				value = f(value, _getNodeF(l++));
			}
			if (r & 1)
			{
				value = f(value, _getNodeF(--r));
			}
		}
		return value;
	}
	void rangeU(size_t l, size_t r, U u)
	{
		l += length, r += length;
		auto ol = l, or = r;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) _addU(l++, u);
			if (r & 1) _addU(--r, u);
		}
		_refresh(ol, or);
	}
	V _getNodeF(size_t i)
	{
		if (_nHasU[i]) return cast(V) fou(_nF[i], _nU[i], _nSz[i]);
		return _nF[i];
	}
	bool _isLeaf(size_t i)
	{
		return i >= length;
	}
	void _clearU(size_t i)
	{
		if (!_nHasU[i]) return;
		if (_isLeaf(i))
		{
			_nF[i] = _getNodeF(i);
			_nHasU[i] = false;
			return;
		}
		_nHasU[i] = false;
		_addU(i << 1, _nU[i]), _addU((i << 1) + 1, _nU[i]);
		_nF[i] = f(_getNodeF(i<<1), _getNodeF((i<<1)+1));
	}
	void _addU(size_t i, U u)
	{
		if (!_nHasU[i])
		{
			_nU[i] = u;
			_nHasU[i] = true;
			return;
		}
		_nU[i] = uou(u, _nU[i]);
	}
	int[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
	{
		return [cast(int)start, cast(int)end];
	}
	auto opIndex(int[2] slice)
	{
		alias Parent = typeof(this);
		struct Ans
		{
			Parent* parent;
			int[2] slice;
			mixin(q{V }, fName, q{;});
			void opOpAssign(string op)(U u) if (op == uName)
			{
				parent.rangeU(slice[0], slice[1], u);
			}
		}
		return Ans(&this, slice, rangeF(slice[0], slice[1]));
	}
}
template TSTL(V, string f, string u, bool hasSize, args...)
{
	static if (hasSize)
	{
		auto neutral = args[1 .. $];
	}
	else
	{
		auto neutral = args[0 .. $];
	}
	alias funF = mixin(f);
	alias funUoU = mixin(u);
	alias funFoU = mixin(f, "O", u);
	static if (neutral.length == 1)
		immutable neut = neutral[0];
	else static if (neutral.length == 0)
	{
		alias neutralTemplate = mixin(f, "Neutral");
		immutable neut = neutralTemplate!V;
	}
	else static assert(false);

	static if (hasSize) alias TSTL = STL!(V, V, neut, funF, funFoU, funUoU, f, u, args[0]);
	else alias TSTL = STL!(V, V, neut, funF, funFoU, funUoU, f, u);
}
immutable maxNeutral(T) = T.min;
pure T max(T)(T a, T b)
{
	pragma(inline, true);
	return a > b? a : b;
}
immutable addNeutral(T) = T(0);
pure T add(T)(T a, T b)
{
	pragma(inline, true);
	return a + b;
}
pure T min(T)(T a, T b)
{
	pragma(inline, true);
	return a < b? a : b;
}
pure T set(T)(T a, T b)
{
	pragma(inline, true);
	return a;
}
pure T maxOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T maxOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T minOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T minOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T addOadd(T)(T sm, T ad, size_t l)
{
	pragma(inline, true);
	return sm + ad * cast(T)l;
}

long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = TSTL!(int, "add", "add");
	auto n = 100;
	int[] brute = new int[](n);
	auto smart = SumQSumU(n, 0);
	int rounds = 100;
	foreach(round; 0 .. rounds)
	{
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				int v = uniform!"[]"(1, 20);
				brute[i .. j] += v;
				smart.rangeU(i, j, v);
			}
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
				auto smartAnswer = smart.rangeF(i, j);
				assert(bruteAnswer == smartAnswer);
			}
	}
}
// }}}

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	auto st = TSTL!(int, "max", "set")(noPoints, 0);
	auto st2 = TSTL!(int, "max", "add")(noPoints, 0);
	auto dp = new int[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = 0;
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st[range[0] .. range[1] + 1].max);
		}
		dpi++;
		foreach(range; ranges[i])
		{
			st.rangeU(range[0], range[1] + 1, dpi);
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i] > bdpi)
		{
			bdpi = dp[i];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;

	foreach(range; ranges[bi]) st2.rangeU(range[0], range[1] + 1, 1);
	alive[bi] = false;
	auto pbi = bi;
	bi--;
	while (bi >= 0)
	{
		if (dp[bi] == dp[pbi] - 1)
		{
			bool isGood = false;
			foreach(range; ranges[bi])
			{
					if (st2.rangeF(range[0], range[1] + 1) > 0) { isGood = true; break; }
			}
			if (isGood)
			{
				foreach(range; ranges[pbi])
					st2.rangeU(range[0], range[1] + 1, -1);
				foreach(range; ranges[bi])
					st2.rangeU(range[0], range[1] + 1, +1);
				alive[bi] = false;
				pbi = bi;
			}
		}
		bi--;
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
struct STL(V, U,
		V neutral,
		alias f,
		alias fou,
		alias uou,
		string fName = "f", string uName = "u")
{
	V[] _nF;
	U[] _nU;
	size_t[] _nSz;
	bool[] _nHasU;
	size_t length = 0;
	int layers = 0;
	this(size_t n, V v)
	{
		n = cast(size_t)nextPow2(cast(long)n);
		auto fn = n;
		while (fn) {layers++; fn >>= 1;}
		length = n;
		auto noNodes = 2 * n;
		_nF = new V[](noNodes);
		if (v != V.init) _nF[n .. 2 * n] = v;
		foreach_reverse(i; 1 .. n) _nF[i] = f(_nF[i<<1], _nF[(i<<1)+1]);
		_nU = new U[](noNodes);
		_nHasU = new bool[](noNodes);
		_nSz = new size_t[](noNodes);
		_nSz[n .. 2 * n] = 1;
		foreach_reverse(i; 1 .. n) _nSz[i] = _nSz[i<<1] << 1;
	}
	void _clearU(size_t l, size_t r)
	{
		r--;
		auto li = layers - 1;
		for(; li > 0 && (l >> li) == (r >> li); li--) _clearU(l >> li);
		for(; li > 0; li--) _clearU(l >> li), _clearU(r >> li);
	}
	void _refresh(size_t l, size_t r)
	{
		r--;
		l >>= 1; r >>= 1;
		for(; l != r; l >>= 1, r >>= 1)
		{
			_nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
			_nF[r] = f(_getNodeF(r<<1), _getNodeF((r<<1)+1));
		}
		for(; l; l >>= 1) _nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
	}
	V rangeF(size_t l, size_t r)
	{
		l += length, r += length;
		_clearU(l, r);
		V value = neutral;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1)
			{
				value = f(value, _getNodeF(l++));
			}
			if (r & 1)
			{
				value = f(value, _getNodeF(--r));
			}
		}
		return value;
	}
	void rangeU(size_t l, size_t r, U u)
	{
		l += length, r += length;
		auto ol = l, or = r;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) _addU(l++, u);
			if (r & 1) _addU(--r, u);
		}
		_refresh(ol, or);
	}
	V _getNodeF(size_t i)
	{
		if (_nHasU[i]) return cast(V) fou(_nF[i], _nU[i], _nSz[i]);
		return _nF[i];
	}
	bool _isLeaf(size_t i)
	{
		return i >= length;
	}
	void _clearU(size_t i)
	{
		if (!_nHasU[i]) return;
		if (_isLeaf(i))
		{
			_nF[i] = _getNodeF(i);
			_nHasU[i] = false;
			return;
		}
		_nHasU[i] = false;
		_addU(i << 1, _nU[i]), _addU((i << 1) + 1, _nU[i]);
		_nF[i] = f(_getNodeF(i<<1), _getNodeF((i<<1)+1));
	}
	void _addU(size_t i, U u)
	{
		if (!_nHasU[i])
		{
			_nU[i] = u;
			_nHasU[i] = true;
			return;
		}
		_nU[i] = uou(u, _nU[i]);
	}
	int[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
	{
		return [cast(int)start, cast(int)end];
	}
	auto opIndex(int[2] slice)
	{
		alias Parent = typeof(this);
		struct Ans
		{
			Parent* parent;
			int[2] slice;
			mixin(q{V }, fName, q{;});
			void opOpAssign(string op)(U u) if (op == uName)
			{
				parent.rangeU(slice[0], slice[1], u);
			}
		}
		return Ans(&this, slice, rangeF(slice[0], slice[1]));
	}
}
template TSTL(V, string f, string u, neutral...)
{
	alias funF = mixin(f);
	alias funUoU = mixin(u);
	alias funFoU = mixin(f, "O", u);
	static if (neutral.length == 1)
		immutable neut = neutral[0];
	else static if (neutral.length == 0)
	{
		alias neutralTemplate = mixin(f, "Neutral");
		immutable neut = neutralTemplate!V;
	}
	else static assert(false);

	alias TSTL = STL!(V, V, neut, funF, funFoU, funUoU, f, u);
}
immutable maxNeutral(T) = T.min;
pure T max(T)(T a, T b)
{
	pragma(inline, true);
	return a > b? a : b;
}
immutable addNeutral(T) = T(0);
pure T add(T)(T a, T b)
{
	pragma(inline, true);
	return a + b;
}
pure T min(T)(T a, T b)
{
	pragma(inline, true);
	return a < b? a : b;
}
pure T set(T)(T a, T b)
{
	pragma(inline, true);
	return a;
}
pure T maxOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T maxOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T minOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T minOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T addOadd(T)(T sm, T ad, size_t l)
{
	pragma(inline, true);
	return sm + ad * cast(T)l;
}

long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = TSTL!(int, "add", "add");
	auto n = 100;
	int[] brute = new int[](n);
	auto smart = SumQSumU(n, 0);
	int rounds = 100;
	foreach(round; 0 .. rounds)
	{
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				int v = uniform!"[]"(1, 20);
				brute[i .. j] += v;
				smart.rangeU(i, j, v);
			}
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
				auto smartAnswer = smart.rangeF(i, j);
				assert(bruteAnswer == smartAnswer);
			}
	}
}
// }}}

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	alias SegTree = TSTL!(Tuple!(int, int), "max", "set", tuple(0, -1));
	auto st = SegTree(noPoints, tuple(0, -1));
	auto dp = new Tuple!(int, int)[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = tuple(0, -1);
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st.rangeF(range[0], range[1] + 1));
		}
		dpi[0]++;
		foreach(range; ranges[i])
		{
			st.rangeU(range[0], range[1] + 1, tuple(dpi[0], cast(int)i));
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i][0] > bdpi)
		{
			bdpi = dp[i][0];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;
	while (bi >= 0)
	{
		alive[bi] = false;
		bi = dp[bi][1];
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
struct STL(V, U,
		V neutral,
		alias f,
		alias fou,
		alias uou,
		string fName = "f", string uName = "u")
{
	V[] _nF;
	U[] _nU;
	size_t[] _nSz;
	bool[] _nHasU;
	size_t length = 0;
	int layers = 0;
	this(size_t n, V v)
	{
		n = cast(size_t)nextPow2(cast(long)n);
		auto fn = n;
		while (fn) {layers++; fn >>= 1;}
		length = n;
		auto noNodes = 2 * n;
		_nF = new V[](noNodes);
		if (v != V.init) _nF[n .. 2 * n] = v;
		foreach_reverse(i; 1 .. n) _nF[i] = f(_nF[i<<1], _nF[(i<<1)+1]);
		_nU = new U[](noNodes);
		_nHasU = new bool[](noNodes);
		_nSz = new size_t[](noNodes);
		_nSz[n .. 2 * n] = 1;
		foreach_reverse(i; 1 .. n) _nSz[i] = _nSz[i<<1] << 1;
	}
	void _clearU(size_t l, size_t r)
	{
		r--;
		auto li = layers - 1;
		for(; li > 0 && (l >> li) == (r >> li); li--) _clearU(l >> li);
		for(; li > 0; li--) _clearU(l >> li), _clearU(r >> li);
	}
	void _refresh(size_t l, size_t r)
	{
		r--;
		l >>= 1; r >>= 1;
		for(; l != r; l >>= 1, r >>= 1)
		{
			_nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
			_nF[r] = f(_getNodeF(r<<1), _getNodeF((r<<1)+1));
		}
		for(; l; l >>= 1) _nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
	}
	V rangeF(size_t l, size_t r)
	{
		l += length, r += length;
		_clearU(l, r);
		V value = neutral;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1)
			{
				value = f(value, _getNodeF(l++));
			}
			if (r & 1)
			{
				value = f(value, _getNodeF(--r));
			}
		}
		return value;
	}
	void rangeU(size_t l, size_t r, U u)
	{
		l += length, r += length;
		auto ol = l, or = r;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) _addU(l++, u);
			if (r & 1) _addU(--r, u);
		}
		_refresh(ol, or);
	}
	V _getNodeF(size_t i)
	{
		if (_nHasU[i]) return cast(V) fou(_nF[i], _nU[i], _nSz[i]);
		return _nF[i];
	}
	bool _isLeaf(size_t i)
	{
		return i >= length;
	}
	void _clearU(size_t i)
	{
		if (!_nHasU[i]) return;
		if (_isLeaf(i))
		{
			_nF[i] = _getNodeF(i);
			_nHasU[i] = false;
			return;
		}
		_nHasU[i] = false;
		_addU(i << 1, _nU[i]), _addU((i << 1) + 1, _nU[i]);
		_nF[i] = f(_getNodeF(i<<1), _getNodeF((i<<1)+1));
	}
	void _addU(size_t i, U u)
	{
		if (!_nHasU[i])
		{
			_nU[i] = u;
			_nHasU[i] = true;
			return;
		}
		_nU[i] = uou(u, _nU[i]);
	}
	int[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
	{
		return [cast(int)start, cast(int)end];
	}
	auto opIndex(int[2] slice)
	{
		alias Parent = typeof(this);
		struct Ans
		{
			Parent* parent;
			int[2] slice;
			mixin(q{V }, fName, q{;});
			void opOpAssign(string op)(U u) if (op == uName)
			{
				parent.rangeU(slice[0], slice[1], u);
			}
		}
		return Ans(&this, slice, rangeF(slice[0], slice[1]));
	}
}
template TSTL(V, string f, string u, neutral...)
{
	alias funF = mixin(f);
	alias funUoU = mixin(u);
	alias funFoU = mixin(f, "O", u);
	static if (neutral.length == 1)
		immutable neut = neutral[0];
	else static if (neutral.length == 0)
	{
		alias neutralTemplate = mixin(f, "Neutral");
		immutable neut = neutralTemplate!V;
	}
	else static assert(false);

	alias TSTL = STL!(V, V, neut, funF, funFoU, funUoU, f, u);
}
immutable maxNeutral(T) = T.min;
pure T max(T)(T a, T b)
{
	pragma(inline, true);
	return a > b? a : b;
}
immutable addNeutral(T) = T(0);
pure T add(T)(T a, T b)
{
	pragma(inline, true);
	return a + b;
}
pure T min(T)(T a, T b)
{
	pragma(inline, true);
	return a < b? a : b;
}
pure T set(T)(T a, T b)
{
	pragma(inline, true);
	return a;
}
pure T maxOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T maxOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T minOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T minOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T addOadd(T)(T sm, T ad, size_t l)
{
	pragma(inline, true);
	return sm + ad * cast(T)l;
}

long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = TSTL!(int, "add", "add");
	auto n = 100;
	int[] brute = new int[](n);
	auto smart = SumQSumU(n, 0);
	int rounds = 100;
	foreach(round; 0 .. rounds)
	{
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				int v = uniform!"[]"(1, 20);
				brute[i .. j] += v;
				smart.rangeU(i, j, v);
			}
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
				auto smartAnswer = smart.rangeF(i, j);
				assert(bruteAnswer == smartAnswer);
			}
	}
}
// }}}

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	alias SegTree = TSTL!(Tuple!(int, int), "max", "set");
	auto st = SegTree(noPoints, tuple(0, -1));
	auto dp = new Tuple!(int, int)[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = tuple(0, -1);
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st.rangeF(range[0], range[1] + 1));
		}
		dpi[0]++;
		foreach(range; ranges[i])
		{
			st.rangeU(range[0], range[1] + 1, tuple(dpi[0], cast(int)i));
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i][0] > bdpi)
		{
			bdpi = dp[i][0];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;
	while (bi >= 0)
	{
		alive[bi] = false;
		bi = dp[bi][1];
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
struct STL(V, U,
		alias f,
		alias fou,
		alias uou,
		string fName = "f", string uName = "u")
{
	V[] _nF;
	U[] _nU;
	size_t[] _nSz;
	bool[] _nHasU;
	size_t length = 0;
	int layers = 0;
	this(size_t n, V v)
	{
		n = cast(size_t)nextPow2(cast(long)n);
		auto fn = n;
		while (fn) {layers++; fn >>= 1;}
		length = n;
		auto noNodes = 2 * n;
		_nF = new V[](noNodes);
		if (v != V.init) _nF[n .. 2 * n] = v;
		foreach_reverse(i; 1 .. n) _nF[i] = f(_nF[i<<1], _nF[(i<<1)+1]);
		_nU = new U[](noNodes);
		_nHasU = new bool[](noNodes);
		_nSz = new size_t[](noNodes);
		_nSz[n .. 2 * n] = 1;
		foreach_reverse(i; 1 .. n) _nSz[i] = _nSz[i<<1] << 1;
	}
	void _clearU(size_t l, size_t r)
	{
		r--;
		auto li = layers - 1;
		for(; li > 0 && (l >> li) == (r >> li); li--) _clearU(l >> li);
		for(; li > 0; li--) _clearU(l >> li), _clearU(r >> li);
	}
	void _refresh(size_t l, size_t r)
	{
		r--;
		l >>= 1; r >>= 1;
		for(; l != r; l >>= 1, r >>= 1)
		{
			_nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
			_nF[r] = f(_getNodeF(r<<1), _getNodeF((r<<1)+1));
		}
		for(; l; l >>= 1) _nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
	}
	V rangeF(size_t l, size_t r)
	{
		l += length, r += length;
		_clearU(l, r);
		V value;
		bool set = false;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1)
			{
				if (!set)
				{
					value = _getNodeF(l++); set = true;
				} else value = f(value, _getNodeF(l++));
			}
			if (r & 1)
			{
				if (!set)
				{
					value = _getNodeF(--r); set = true;
				} else value = f(value, _getNodeF(--r));
			}
		}
		return value;
	}
	void rangeU(size_t l, size_t r, U u)
	{
		l += length, r += length;
		auto ol = l, or = r;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) _addU(l++, u);
			if (r & 1) _addU(--r, u);
		}
		_refresh(ol, or);
	}
	V _getNodeF(size_t i)
	{
		if (_nHasU[i]) return cast(V) fou(_nF[i], _nU[i], _nSz[i]);
		return _nF[i];
	}
	bool _isLeaf(size_t i)
	{
		return i >= length;
	}
	void _clearU(size_t i)
	{
		if (!_nHasU[i]) return;
		if (_isLeaf(i))
		{
			_nF[i] = _getNodeF(i);
			_nHasU[i] = false;
			return;
		}
		_nHasU[i] = false;
		_addU(i << 1, _nU[i]), _addU((i << 1) + 1, _nU[i]);
		_nF[i] = f(_getNodeF(i<<1), _getNodeF((i<<1)+1));
	}
	void _addU(size_t i, U u)
	{
		if (!_nHasU[i])
		{
			_nU[i] = u;
			_nHasU[i] = true;
			return;
		}
		_nU[i] = uou(u, _nU[i]);
	}
	int[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
	{
		return [cast(int)start, cast(int)end];
	}
	auto opIndex(int[2] slice)
	{
		alias Parent = typeof(this);
		struct Ans
		{
			Parent* parent;
			int[2] slice;
			mixin(q{V }, fName, q{;});
			void opOpAssign(string op)(U u) if (op == uName)
			{
				parent.rangeU(slice[0], slice[1], u);
			}
		}
		return Ans(&this, slice, rangeF(slice[0], slice[1]));
	}
}
template TSTL(V, string f, string u)
{
	alias funF = mixin(f);
	alias funUoU = mixin(u);
	alias funFoU = mixin(f, "O", u);
	alias TSTL = STL!(V, V, funF, funFoU, funUoU, f, u);
}
pure T max(T)(T a, T b)
{
	pragma(inline, true);
	return a > b? a : b;
}
pure T add(T)(T a, T b)
{
	pragma(inline, true);
	return a + b;
}
pure T min(T)(T a, T b)
{
	pragma(inline, true);
	return a < b? a : b;
}
pure T set(T)(T a, T b)
{
	pragma(inline, true);
	return a;
}
pure T maxOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T maxOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T minOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T minOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T addOadd(T)(T sm, T ad, size_t l)
{
	pragma(inline, true);
	return sm + ad * cast(T)l;
}

long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = TSTL!(int, "add", "add");
	auto n = 100;
	int[] brute = new int[](n);
	auto smart = SumQSumU(n, 0);
	int rounds = 100;
	foreach(round; 0 .. rounds)
	{
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				int v = uniform!"[]"(1, 20);
				brute[i .. j] += v;
				smart.rangeU(i, j, v);
			}
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
				auto smartAnswer = smart.rangeF(i, j);
				assert(bruteAnswer == smartAnswer);
			}
	}
}
// }}}

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	alias SegTree = TSTL!(Tuple!(int, int), tuple(0, -1), "max", "set");
	auto st = SegTree(noPoints, tuple(0, -1));
	auto dp = new Tuple!(int, int)[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = tuple(0, -1);
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st.rangeF(range[0], range[1] + 1));
		}
		dpi[0]++;
		foreach(range; ranges[i])
		{
			st.rangeU(range[0], range[1] + 1, tuple(dpi[0], cast(int)i));
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i][0] > bdpi)
		{
			bdpi = dp[i][0];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;
	while (bi >= 0)
	{
		alive[bi] = false;
		bi = dp[bi][1];
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
struct STL(V, U,
		V neutral, alias f,
		alias fou,
		alias uou,
		string fName = "f", string uName = "u")
{
	V[] _nF;
	U[] _nU;
	size_t[] _nSz;
	bool[] _nHasU;
	size_t length = 0;
	int layers = 0;
	this(size_t n, V v)
	{
		n = cast(size_t)nextPow2(cast(long)n);
		auto fn = n;
		while (fn) {layers++; fn >>= 1;}
		length = n;
		auto noNodes = 2 * n;
		_nF = new V[](noNodes);
		static if (neutral != V.init) _nF[n .. 2 * n] = v;
		foreach_reverse(i; 1 .. n) _nF[i] = f(_nF[i<<1], _nF[(i<<1)+1]);
		_nU = new U[](noNodes);
		_nHasU = new bool[](noNodes);
		_nSz = new size_t[](noNodes);
		_nSz[n .. 2 * n] = 1;
		foreach_reverse(i; 1 .. n) _nSz[i] = _nSz[i<<1] << 1;
	}
	void _clearU(size_t l, size_t r)
	{
		r--;
		auto li = layers - 1;
		for(; li > 0 && (l >> li) == (r >> li); li--) _clearU(l >> li);
		for(; li > 0; li--) _clearU(l >> li), _clearU(r >> li);
	}
	void _refresh(size_t l, size_t r)
	{
		r--;
		l >>= 1; r >>= 1;
		for(; l != r; l >>= 1, r >>= 1)
		{
			_nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
			_nF[r] = f(_getNodeF(r<<1), _getNodeF((r<<1)+1));
		}
		for(; l; l >>= 1) _nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
	}
	V rangeF(size_t l, size_t r)
	{
		l += length, r += length;
		_clearU(l, r);
		V value = neutral;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) value = f(value, _getNodeF(l++));
			if (r & 1) value = f(value, _getNodeF(--r));
		}
		return value;
	}
	void rangeU(size_t l, size_t r, U u)
	{
		l += length, r += length;
		auto ol = l, or = r;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) _addU(l++, u);
			if (r & 1) _addU(--r, u);
		}
		_refresh(ol, or);
	}
	V _getNodeF(size_t i)
	{
		if (_nHasU[i]) return cast(V) fou(_nF[i], _nU[i], _nSz[i]);
		return _nF[i];
	}
	bool _isLeaf(size_t i)
	{
		return i >= length;
	}
	void _clearU(size_t i)
	{
		if (!_nHasU[i]) return;
		if (_isLeaf(i))
		{
			_nF[i] = _getNodeF(i);
			_nHasU[i] = false;
			return;
		}
		_nHasU[i] = false;
		_addU(i << 1, _nU[i]), _addU((i << 1) + 1, _nU[i]);
		_nF[i] = f(_getNodeF(i<<1), _getNodeF((i<<1)+1));
	}
	void _addU(size_t i, U u)
	{
		if (!_nHasU[i])
		{
			_nU[i] = u;
			_nHasU[i] = true;
			return;
		}
		_nU[i] = uou(u, _nU[i]);
	}
	int[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
	{
		return [cast(int)start, cast(int)end];
	}
	auto opIndex(int[2] slice)
	{
		alias Parent = typeof(this);
		struct Ans
		{
			Parent* parent;
			int[2] slice;
			mixin(q{V }, fName, q{;});
			void opOpAssign(string op)(U u) if (op == uName)
			{
				parent.rangeU(slice[0], slice[1], u);
			}
		}
		return Ans(&this, slice, rangeF(slice[0], slice[1]));
	}
}
template TSTL(V, V neutral, string f, string u)
{
	alias funF = mixin(f);
	alias funUoU = mixin(u);
	alias funFoU = mixin(f, "O", u);
	alias TSTL = STL!(V, V, neutral, funF, funFoU, funUoU, f, u);
}
pure T max(T)(T a, T b)
{
	pragma(inline, true);
	return a > b? a : b;
}
pure T add(T)(T a, T b)
{
	pragma(inline, true);
	return a + b;
}
pure T min(T)(T a, T b)
{
	pragma(inline, true);
	return a < b? a : b;
}
pure T set(T)(T a, T b)
{
	pragma(inline, true);
	return a;
}
pure T maxOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T maxOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T minOset(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T minOadd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T addOadd(T)(T sm, T ad, size_t l)
{
	pragma(inline, true);
	return sm + ad * cast(T)l;
}

long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = TSTL!(int, 0, "add", "add");
	auto n = 100;
	int[] brute = new int[](n);
	auto smart = SumQSumU(n, 0);
	int rounds = 100;
	foreach(round; 0 .. rounds)
	{
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				int v = uniform!"[]"(1, 20);
				brute[i .. j] += v;
				smart.rangeU(i, j, v);
			}
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
				auto smartAnswer = smart.rangeF(i, j);
				assert(bruteAnswer == smartAnswer);
			}
	}
}
// }}}

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	alias SegTree = STL!(Tuple!(int, int), Tuple!(int, int))
		.Type!(tuple(0, -1), max, maxCompSet, set, "max", "+");
	auto st = SegTree(noPoints, tuple(0, -1));
	auto dp = new Tuple!(int, int)[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = tuple(0, -1);
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st.rangeF(range[0], range[1] + 1));
		}
		dpi[0]++;
		foreach(range; ranges[i])
		{
			st.rangeU(range[0], range[1] + 1, tuple(dpi[0], cast(int)i));
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i][0] > bdpi)
		{
			bdpi = dp[i][0];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;
	while (bi >= 0)
	{
		alive[bi] = false;
		bi = dp[bi][1];
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
template STL(V, U)
{
	struct Type (V neutral, alias f,
			alias fou,
			alias uou,
			string fName = "f", string uName = "u")
	{
		V[] _nF;
		U[] _nU;
		size_t[] _nSz;
		bool[] _nHasU;
		size_t length = 0;
		int layers = 0;
		this(size_t n, V v)
		{
			n = cast(size_t)nextPow2(cast(long)n);
			auto fn = n;
			while (fn) {layers++; fn >>= 1;}
			length = n;
			auto noNodes = 2 * n;
			_nF = new V[](noNodes);
			static if (neutral != V.init) _nF[n .. 2 * n] = v;
			foreach_reverse(i; 1 .. n) _nF[i] = f(_nF[i<<1], _nF[(i<<1)+1]);
			_nU = new U[](noNodes);
			_nHasU = new bool[](noNodes);
			_nSz = new size_t[](noNodes);
			_nSz[n .. 2 * n] = 1;
			foreach_reverse(i; 1 .. n) _nSz[i] = _nSz[i<<1] * 2;
		}
		void _clearU(size_t l, size_t r)
		{
			r--;
			auto li = layers - 1;
			for(; li > 0 && (l >> li) == (r >> li); li--) _clearU(l >> li);
			for(; li > 0; li--) _clearU(l >> li), _clearU(r >> li);
		}
		void _refresh(size_t l, size_t r)
		{
			r--;
			l >>= 1; r >>= 1;
			for(; l != r; l >>= 1, r >>= 1)
			{
				_nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
				_nF[r] = f(_getNodeF(r<<1), _getNodeF((r<<1)+1));
			}
			for(; l; l >>= 1) _nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
		}
		V rangeF(size_t l, size_t r)
		{
			l += length, r += length;
			_clearU(l, r);
			V value = neutral;
			for(; l < r; l >>= 1, r >>= 1)
			{
				if (l & 1) value = f(value, _getNodeF(l++));
				if (r & 1) value = f(value, _getNodeF(--r));
			}
			return value;
		}
		void rangeU(size_t l, size_t r, U u)
		{
			l += length, r += length;
			auto ol = l, or = r;
			for(; l < r; l >>= 1, r >>= 1)
			{
				if (l & 1) _addU(l++, u);
				if (r & 1) _addU(--r, u);
			}
			_refresh(ol, or);
		}
		V _getNodeF(size_t i)
		{
			if (_nHasU[i]) return cast(V) fou(_nF[i], _nU[i], _nSz[i]);
			return _nF[i];
		}
		bool _isLeaf(size_t i)
		{
			return i >= length;
		}
		void _clearU(size_t i)
		{
			if (!_nHasU[i]) return;
			if (_isLeaf(i))
			{
				_nF[i] = _getNodeF(i);
				_nHasU[i] = false;
				return;
			}
			_nHasU[i] = false;
			_addU(i << 1, _nU[i]), _addU((i << 1) + 1, _nU[i]);
			_nF[i] = f(_getNodeF(i<<1), _getNodeF((i<<1)+1));
		}
		void _addU(size_t i, U u)
		{
			if (!_nHasU[i])
			{
				_nU[i] = u;
				_nHasU[i] = true;
				return;
			}
			_nU[i] = uou(u, _nU[i]);
		}
		int[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
		{
			return [cast(int)start, cast(int)end];
		}
		auto opIndex(int[2] slice)
		{
			alias Parent = typeof(this);
			struct Ans
			{
				Parent* parent;
				int[2] slice;
				mixin(q{V }, fName, q{;});
				void opOpAssign(string op)(U u) if (op == uName)
				{
					parent.rangeU(slice[0], slice[1], u);
				}
			}
			return Ans(&this, slice, rangeF(slice[0], slice[1]));
		}
	}
}
pure T max(T)(T a, T b)
{
	pragma(inline, true);
	return a > b? a : b;
}
pure T add(T)(T a, T b)
{
	pragma(inline, true);
	return a + b;
}
pure T min(T)(T a, T b)
{
	pragma(inline, true);
	return a < b? a : b;
}
pure T set(T)(T a, T b)
{
	pragma(inline, true);
	return a;
}
pure T maxCompSet(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T maxCompAdd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}
pure T minCompSet(T)(T mx, T set, size_t l)
{
	pragma(inline, true);
	return set;
}
pure T minCompAdd(T)(T mx, T ad, size_t l)
{
	pragma(inline, true);
	return mx + ad;
}

long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = STL!(int, int).Type!(0,
			(v1, v2) => v1 + v2,
			(v, u, size_t l) => v + u * cast(int)l,
			(ni, pi) => ni + pi,
			"sum",
			"+");
	auto n = 100;
	int[] brute = new int[](n);
	auto smart = SumQSumU(n, 0);
	int rounds = 1000;
	foreach(round; 0 .. rounds)
	{
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				int v = uniform!"[]"(1, 20);
				brute[i .. j] += v;
				smart[i .. j] += v;
			}
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
				auto smartAnswer = smart[i .. j].sum;
				assert(bruteAnswer == smartAnswer);
			}
	}
}
// }}}

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	static auto FoU(Tuple!(int, int) mx, Tuple!(int, int) st, size_t l) { pragma(inline, true); return st; }
	static auto UoU(Tuple!(int, int) nw, Tuple!(int, int) ld) { pragma(inline, true); return nw; }
	alias SegTree = STL!(Tuple!(int, int), Tuple!(int, int))
		.Type!(tuple(0, -1),
				max!(Tuple!(int, int), Tuple!(int, int)), FoU, UoU,
				"max", "+");
	auto st = SegTree(noPoints, tuple(0, -1));
	auto dp = new Tuple!(int, int)[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = tuple(0, -1);
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st.rangeF(range[0], range[1] + 1));
		}
		dpi[0]++;
		foreach(range; ranges[i])
		{
			st.rangeU(range[0], range[1] + 1, tuple(dpi[0], cast(int)i));
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i][0] > bdpi)
		{
			bdpi = dp[i][0];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;
	while (bi >= 0)
	{
		alive[bi] = false;
		bi = dp[bi][1];
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
template STL(V, U)
{
	struct Type (V neutral, alias f,
			alias fou,
			alias uou,
			string fName = "f", string uName = "u")
	{
		V[] _nF;
		U[] _nU;
		size_t[] _nSz;
		bool[] _nHasU;
		size_t length = 0;
		int layers = 0;
		this(size_t n, V v)
		{
			n = cast(size_t)nextPow2(cast(long)n);
			auto fn = n;
			while (fn) {layers++; fn >>= 1;}
			length = n;
			auto noNodes = 2 * n;
			_nF = new V[](noNodes);
			static if (neutral != V.init) _nF[n .. 2 * n] = v;
			foreach_reverse(i; 1 .. n) _nF[i] = f(_nF[i<<1], _nF[(i<<1)+1]);
			_nU = new U[](noNodes);
			_nHasU = new bool[](noNodes);
			_nSz = new size_t[](noNodes);
			_nSz[n .. 2 * n] = 1;
			foreach_reverse(i; 1 .. n) _nSz[i] = _nSz[i<<1] * 2;
		}
		void _clearU(size_t l, size_t r)
		{
			r--;
			auto li = layers - 1;
			for(; li > 0 && (l >> li) == (r >> li); li--) _clearU(l >> li);
			for(; li > 0; li--) _clearU(l >> li), _clearU(r >> li);
		}
		void _refresh(size_t l, size_t r)
		{
			r--;
			l >>= 1; r >>= 1;
			for(; l != r; l >>= 1, r >>= 1)
			{
				_nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
				_nF[r] = f(_getNodeF(r<<1), _getNodeF((r<<1)+1));
			}
			for(; l; l >>= 1) _nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
		}
		V rangeF(size_t l, size_t r)
		{
			l += length, r += length;
			_clearU(l, r);
			V value = neutral;
			for(; l < r; l >>= 1, r >>= 1)
			{
				if (l & 1) value = f(value, _getNodeF(l++));
				if (r & 1) value = f(value, _getNodeF(--r));
			}
			return value;
		}
		void rangeU(size_t l, size_t r, U u)
		{
			l += length, r += length;
			auto ol = l, or = r;
			for(; l < r; l >>= 1, r >>= 1)
			{
				if (l & 1) _addU(l++, u);
				if (r & 1) _addU(--r, u);
			}
			_refresh(ol, or);
		}
		V _getNodeF(size_t i)
		{
			if (_nHasU[i]) return cast(V) fou(_nF[i], _nU[i], _nSz[i]);
			return _nF[i];
		}
		bool _isLeaf(size_t i)
		{
			return i >= length;
		}
		void _clearU(size_t i)
		{
			if (!_nHasU[i]) return;
			if (_isLeaf(i))
			{
				_nF[i] = _getNodeF(i);
				_nHasU[i] = false;
				return;
			}
			_nHasU[i] = false;
			_addU(i << 1, _nU[i]), _addU((i << 1) + 1, _nU[i]);
			_nF[i] = f(_getNodeF(i<<1), _getNodeF((i<<1)+1));
		}
		void _addU(size_t i, U u)
		{
			if (!_nHasU[i])
			{
				_nU[i] = u;
				_nHasU[i] = true;
				return;
			}
			_nU[i] = uou(u, _nU[i]);
		}
		int[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
		{
			return [cast(int)start, cast(int)end];
		}
		auto opIndex(int[2] slice)
		{
			alias Parent = typeof(this);
			struct Ans
			{
				Parent* parent;
				int[2] slice;
				mixin(q{V }, fName, q{;});
				void opOpAssign(string op)(U u) if (op == uName)
				{
					parent.rangeU(slice[0], slice[1], u);
				}
			}
			return Ans(&this, slice, rangeF(slice[0], slice[1]));
		}
	}
}
long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = STL!(int, int).Type!(0,
			(v1, v2) => v1 + v2,
			(v, u, size_t l) => v + u * cast(int)l,
			(ni, pi) => ni + pi,
			"sum",
			"+");
	auto n = 100;
	int[] brute = new int[](n);
	auto smart = SumQSumU(n, 0);
	int rounds = 1000;
	foreach(round; 0 .. rounds)
	{
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				int v = uniform!"[]"(1, 20);
				brute[i .. j] += v;
				smart[i .. j] += v;
			}
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
				auto smartAnswer = smart[i .. j].sum;
				assert(bruteAnswer == smartAnswer);
			}
	}
}
// }}}

auto FoU(Tuple!(int, int) mx, Tuple!(int, int) st, size_t l) { pragma(inline, true); return st; }
auto UoU(Tuple!(int, int) nw, Tuple!(int, int) ld) { pragma(inline, true); return nw; }

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	alias SegTree = STL!(Tuple!(int, int), Tuple!(int, int))
		.Type!(tuple(0, -1),
				max!(Tuple!(int, int), Tuple!(int, int)), FoU, UoU,
				"max", "+");
	auto st = SegTree(noPoints, tuple(0, -1));
	auto dp = new Tuple!(int, int)[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = tuple(0, -1);
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st.rangeF(range[0], range[1] + 1));
		}
		dpi[0]++;
		foreach(range; ranges[i])
		{
			st.rangeU(range[0], range[1] + 1, tuple(dpi[0], cast(int)i));
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i][0] > bdpi)
		{
			bdpi = dp[i][0];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;
	while (bi >= 0)
	{
		alive[bi] = false;
		bi = dp[bi][1];
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
template STL(V, U)
{
	struct Type (V neutral, alias f,
			alias fou,
			alias uou,
			string fName = "f", string uName = "u")
	{
		V[] _nF;
		U[] _nU;
		size_t[] _nSz;
		bool[] _nHasU;
		size_t length = 0;
		int layers = 0;
		this(size_t n, V v)
		{
			n = cast(size_t)nextPow2(cast(long)n);
			auto fn = n;
			while (fn) {layers++; fn >>= 1;}
			length = n;
			auto noNodes = 2 * n;
			_nF = new V[](noNodes);
			static if (neutral != V.init) _nF[n .. 2 * n] = v;
			foreach_reverse(i; 1 .. n) _nF[i] = f(_nF[i<<1], _nF[(i<<1)+1]);
			_nU = new U[](noNodes);
			_nHasU = new bool[](noNodes);
			_nSz = new size_t[](noNodes);
			_nSz[n .. 2 * n] = 1;
			foreach_reverse(i; 1 .. n) _nSz[i] = _nSz[i<<1] * 2;
		}
		void _clearU(size_t l, size_t r)
		{
			r--;
			auto li = layers - 1;
			for(; li > 0 && (l >> li) == (r >> li); li--) _clearU(l >> li);
			for(; li > 0; li--) _clearU(l >> li), _clearU(r >> li);
		}
		void _refresh(size_t l, size_t r)
		{
			r--;
			l >>= 1; r >>= 1;
			for(; l != r; l >>= 1, r >>= 1)
			{
				_nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
				_nF[r] = f(_getNodeF(r<<1), _getNodeF((r<<1)+1));
			}
			for(; l; l >>= 1) _nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
		}
		V rangeF(size_t l, size_t r)
		{
			l += length, r += length;
			_clearU(l, r);
			V value = neutral;
			for(; l < r; l >>= 1, r >>= 1)
			{
				if (l & 1) value = f(value, _getNodeF(l++));
				if (r & 1) value = f(value, _getNodeF(--r));
			}
			return value;
		}
		void rangeU(size_t l, size_t r, U u)
		{
			l += length, r += length;
			auto ol = l, or = r;
			for(; l < r; l >>= 1, r >>= 1)
			{
				if (l & 1) _addU(l++, u);
				if (r & 1) _addU(--r, u);
			}
			_refresh(ol, or);
		}
		V _getNodeF(size_t i)
		{
			if (_nHasU[i]) return cast(V) fou(_nF[i], _nU[i], _nSz[i]);
			return _nF[i];
		}
		bool _isLeaf(size_t i)
		{
			return i >= length;
		}
		void _clearU(size_t i)
		{
			if (!_nHasU[i]) return;
			if (_isLeaf(i))
			{
				_nF[i] = _getNodeF(i);
				_nHasU[i] = false;
				return;
			}
			_nHasU[i] = false;
			_addU(i << 1, _nU[i]), _addU((i << 1) + 1, _nU[i]);
			_nF[i] = f(_getNodeF(i<<1), _getNodeF((i<<1)+1));
		}
		void _addU(size_t i, U u)
		{
			if (!_nHasU[i])
			{
				_nU[i] = u;
				_nHasU[i] = true;
				return;
			}
			_nU[i] = uou(u, _nU[i]);
		}
		int[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
		{
			return [cast(int)start, cast(int)end];
		}
		auto opIndex(int[2] slice)
		{
			alias Parent = typeof(this);
			struct Ans
			{
				Parent* parent;
				int[2] slice;
				mixin(q{V }, fName, q{;});
				void opOpAssign(string op)(U u) if (op == uName)
				{
					parent.rangeU(slice[0], slice[1], u);
				}
			}
			return Ans(&this, slice, rangeF(slice[0], slice[1]));
		}
	}
}
long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = STL!(int, int).Type!(0,
			(v1, v2) => v1 + v2,
			(v, u, size_t l) => v + u * cast(int)l,
			(ni, pi) => ni + pi,
			"sum",
			"+");
	auto n = 100;
	int[] brute = new int[](n);
	auto smart = SumQSumU(n, 0);
	int rounds = 1000;
	foreach(round; 0 .. rounds)
	{
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				int v = uniform!"[]"(1, 20);
				brute[i .. j] += v;
				smart[i .. j] += v;
			}
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
				auto smartAnswer = smart[i .. j].sum;
				assert(bruteAnswer == smartAnswer);
			}
	}
}
// }}}

auto FoU(Tuple!(int, int) mx, Tuple!(int, int) st, size_t l) { pragma(inline, true); return st; }
auto UoU(Tuple!(int, int) nw, Tuple!(int, int) ld) { pragma(inline, true); return nw; }

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	alias SegTree = STL!(Tuple!(int, int), Tuple!(int, int))
		.Type!(tuple(0, -1),
				max, FoU, UoU,
				"max", "+");
	auto st = SegTree(noPoints, tuple(0, -1));
	auto dp = new Tuple!(int, int)[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = tuple(0, -1);
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st.rangeF(range[0], range[1] + 1));
		}
		dpi[0]++;
		foreach(range; ranges[i])
		{
			st.rangeU(range[0], range[1] + 1, tuple(dpi[0], cast(int)i));
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i][0] > bdpi)
		{
			bdpi = dp[i][0];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;
	while (bi >= 0)
	{
		alive[bi] = false;
		bi = dp[bi][1];
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
template STL(V, U)
{
	struct Type (V neutral, alias f,
			alias fou,
			alias uou,
			string fName = "f", string uName = "u")
	{
		V[] _nF;
		U[] _nU;
		size_t[] _nSz;
		bool[] _nHasU;
		size_t length = 0;
		int layers = 0;
		this(size_t n, V v)
		{
			n = cast(size_t)nextPow2(cast(long)n);
			auto fn = n;
			while (fn) {layers++; fn >>= 1;}
			length = n;
			auto noNodes = 2 * n;
			_nF = new V[](noNodes);
			static if (neutral != V.init) _nF[n .. 2 * n] = v;
			foreach_reverse(i; 1 .. n) _nF[i] = f(_nF[i<<1], _nF[(i<<1)+1]);
			_nU = new U[](noNodes);
			_nHasU = new bool[](noNodes);
			_nSz = new size_t[](noNodes);
			_nSz[n .. 2 * n] = 1;
			foreach_reverse(i; 1 .. n) _nSz[i] = _nSz[i<<1] * 2;
		}
		void _clearU(size_t l, size_t r)
		{
			r--;
			auto li = layers - 1;
			for(; li > 0 && (l >> li) == (r >> li); li--) _clearU(l >> li);
			for(; li > 0; li--) _clearU(l >> li), _clearU(r >> li);
		}
		void _refresh(size_t l, size_t r)
		{
			r--;
			l >>= 1; r >>= 1;
			for(; l != r; l >>= 1, r >>= 1)
			{
				_nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
				_nF[r] = f(_getNodeF(r<<1), _getNodeF((r<<1)+1));
			}
			for(; l; l >>= 1) _nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
		}
		V rangeF(size_t l, size_t r)
		{
			l += length, r += length;
			_clearU(l, r);
			V value = neutral;
			for(; l < r; l >>= 1, r >>= 1)
			{
				if (l & 1) value = f(value, _getNodeF(l++));
				if (r & 1) value = f(value, _getNodeF(--r));
			}
			return value;
		}
		void rangeU(size_t l, size_t r, U u)
		{
			l += length, r += length;
			auto ol = l, or = r;
			for(; l < r; l >>= 1, r >>= 1)
			{
				if (l & 1) _addU(l++, u);
				if (r & 1) _addU(--r, u);
			}
			_refresh(ol, or);
		}
		V _getNodeF(size_t i)
		{
			if (_nHasU[i]) return cast(V) fou(_nF[i], _nU[i], _nSz[i]);
			return _nF[i];
		}
		bool _isLeaf(size_t i)
		{
			return i >= length;
		}
		void _clearU(size_t i)
		{
			if (!_nHasU[i]) return;
			if (_isLeaf(i))
			{
				_nF[i] = _getNodeF(i);
				_nHasU[i] = false;
				return;
			}
			_nHasU[i] = false;
			_addU(i << 1, _nU[i]), _addU((i << 1) + 1, _nU[i]);
			_nF[i] = f(_getNodeF(i<<1), _getNodeF((i<<1)+1));
		}
		void _addU(size_t i, U u)
		{
			if (!_nHasU[i])
			{
				_nU[i] = u;
				_nHasU[i] = true;
				return;
			}
			_nU[i] = uou(u, _nU[i]);
		}
		int[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
		{
			return [cast(int)start, cast(int)end];
		}
		auto opIndex(int[2] slice)
		{
			alias Parent = typeof(this);
			struct Ans
			{
				Parent* parent;
				int[2] slice;
				mixin(q{V }, fName, q{;});
				void opOpAssign(string op)(U u) if (op == uName)
				{
					parent.rangeU(slice[0], slice[1], u);
				}
			}
			return Ans(&this, slice, rangeF(slice[0], slice[1]));
		}
	}
}
long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = STL!(int, int).Type!(0,
			(v1, v2) => v1 + v2,
			(v, u, size_t l) => v + u * cast(int)l,
			(ni, pi) => ni + pi,
			"sum",
			"+");
	auto n = 100;
	int[] brute = new int[](n);
	auto smart = SumQSumU(n, 0);
	int rounds = 1000;
	foreach(round; 0 .. rounds)
	{
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				int v = uniform!"[]"(1, 20);
				brute[i .. j] += v;
				smart[i .. j] += v;
			}
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
				auto smartAnswer = smart[i .. j].sum;
				assert(bruteAnswer == smartAnswer);
			}
	}
}
// }}}

auto F(Tuple!(int, int) a, Tuple!(int, int) b) { pragma(inline, true); return a > b? a : b; }
auto FoU(Tuple!(int, int) mx, Tuple!(int, int) st, size_t l) { pragma(inline, true); return st; }
auto UoU(Tuple!(int, int) nw, Tuple!(int, int) ld) { pragma(inline, true); return nw; }

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	alias SegTree = STL!(Tuple!(int, int), Tuple!(int, int))
		.Type!(tuple(0, -1),
				F, FoU, UoU,
				"max", "+");
	auto st = SegTree(noPoints, tuple(0, -1));
	auto dp = new Tuple!(int, int)[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = tuple(0, -1);
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st.rangeF(range[0], range[1] + 1));
		}
		dpi[0]++;
		foreach(range; ranges[i])
		{
			st.rangeU(range[0], range[1] + 1, tuple(dpi[0], cast(int)i));
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i][0] > bdpi)
		{
			bdpi = dp[i][0];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;
	while (bi >= 0)
	{
		alive[bi] = false;
		bi = dp[bi][1];
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
template STL(V, U)
{
	struct Type (V neutral, alias f,
			alias fou,
			alias uou,
			string fName = "f", string uName = "u")
	{
		V[] _nF;
		U[] _nU;
		size_t[] _nSz;
		bool[] _nHasU;
		size_t length = 0;
		int layers = 0;
		this(size_t n, V v)
		{
			n = cast(size_t)nextPow2(cast(long)n);
			auto fn = n;
			while (fn) {layers++; fn >>= 1;}
			length = n;
			auto noNodes = 2 * n;
			_nF = new V[](noNodes);
			static if (neutral != V.init) _nF[n .. 2 * n] = v;
			foreach_reverse(i; 1 .. n) _nF[i] = f(_nF[i<<1], _nF[(i<<1)+1]);
			_nU = new U[](noNodes);
			_nHasU = new bool[](noNodes);
			_nSz = new size_t[](noNodes);
			_nSz[n .. 2 * n] = 1;
			foreach_reverse(i; 1 .. n) _nSz[i] = _nSz[i<<1] * 2;
		}
		void _clearU(size_t l, size_t r)
		{
			r--;
			auto li = layers - 1;
			for(; li > 0 && (l >> li) == (r >> li); li--) _clearU(l >> li);
			for(; li > 0; li--) _clearU(l >> li), _clearU(r >> li);
		}
		void _refresh(size_t l, size_t r)
		{
			r--;
			l >>= 1; r >>= 1;
			for(; l != r; l >>= 1, r >>= 1)
			{
				_nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
				_nF[r] = f(_getNodeF(r<<1), _getNodeF((r<<1)+1));
			}
			for(; l; l >>= 1) _nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
		}
		V rangeF(size_t l, size_t r)
		{
			l += length, r += length;
			_clearU(l, r);
			V value = neutral;
			for(; l < r; l >>= 1, r >>= 1)
			{
				if (l & 1) value = f(value, _getNodeF(l++));
				if (r & 1) value = f(value, _getNodeF(--r));
			}
			return value;
		}
		void rangeU(size_t l, size_t r, U u)
		{
			l += length, r += length;
			auto ol = l, or = r;
			for(; l < r; l >>= 1, r >>= 1)
			{
				if (l & 1) _addU(l++, u);
				if (r & 1) _addU(--r, u);
			}
			_refresh(ol, or);
		}
		V _getNodeF(size_t i)
		{
			if (_nHasU[i]) return cast(V) fou(_nF[i], _nU[i], _nSz[i]);
			return _nF[i];
		}
		bool _isLeaf(size_t i)
		{
			return i >= length;
		}
		void _clearU(size_t i)
		{
			if (!_nHasU[i]) return;
			if (_isLeaf(i))
			{
				_nF[i] = _getNodeF(i);
				_nHasU[i] = false;
				return;
			}
			_nHasU[i] = false;
			_addU(i << 1, _nU[i]), _addU((i << 1) + 1, _nU[i]);
			_nF[i] = f(_getNodeF(i<<1), _getNodeF((i<<1)+1));
		}
		void _addU(size_t i, U u)
		{
			if (!_nHasU[i])
			{
				_nU[i] = u;
				_nHasU[i] = true;
				return;
			}
			_nU[i] = uou(u, _nU[i]);
		}
		int[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
		{
			return [cast(int)start, cast(int)end];
		}
		auto opIndex(int[2] slice)
		{
			alias Parent = typeof(this);
			struct Ans
			{
				Parent* parent;
				int[2] slice;
				mixin(q{V }, fName, q{;});
				void opOpAssign(string op)(U u) if (op == uName)
				{
					parent.rangeU(slice[0], slice[1], u);
				}
			}
			return Ans(&this, slice, rangeF(slice[0], slice[1]));
		}
	}
}
long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = STL!(int, int).Type!(0,
			(v1, v2) => v1 + v2,
			(v, u, size_t l) => v + u * cast(int)l,
			(ni, pi) => ni + pi,
			"sum",
			"+");
	auto n = 100;
	int[] brute = new int[](n);
	auto smart = SumQSumU(n, 0);
	int rounds = 1000;
	foreach(round; 0 .. rounds)
	{
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				int v = uniform!"[]"(1, 20);
				brute[i .. j] += v;
				smart[i .. j] += v;
			}
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
				auto smartAnswer = smart[i .. j].sum;
				assert(bruteAnswer == smartAnswer);
			}
	}
}
// }}}

pure auto F(Tuple!(int, int) a, Tuple!(int, int) b) { pragma(inline, true); return a > b? a : b; }
pure auto FoU(Tuple!(int, int) mx, Tuple!(int, int) st, size_t l) { pragma(inline, true); return st; }
pure auto UoU(Tuple!(int, int) nw, Tuple!(int, int) ld) { pragma(inline, true); return nw; }

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	alias SegTree = STL!(Tuple!(int, int), Tuple!(int, int))
		.Type!(tuple(0, -1),
				F, FoU, UoU,
				"max", "+");
	auto st = SegTree(noPoints, tuple(0, -1));
	auto dp = new Tuple!(int, int)[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = tuple(0, -1);
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st.rangeF(range[0], range[1] + 1));
		}
		dpi[0]++;
		foreach(range; ranges[i])
		{
			st.rangeU(range[0], range[1] + 1, tuple(dpi[0], cast(int)i));
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i][0] > bdpi)
		{
			bdpi = dp[i][0];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;
	while (bi >= 0)
	{
		alive[bi] = false;
		bi = dp[bi][1];
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
template STL(V, U)
{
	struct Type (V neutral, alias f,
			alias fou,
			alias uou,
			string fName = "f", string uName = "u")
	{
		V[] _nF;
		U[] _nU;
		size_t[] _nSz;
		bool[] _nHasU;
		size_t length = 0;
		int layers = 0;
		this(size_t n, V v)
		{
			n = cast(size_t)nextPow2(cast(long)n);
			auto fn = n;
			while (fn) {layers++; fn >>= 1;}
			length = n;
			auto noNodes = 2 * n;
			_nF = new V[](noNodes);
			static if (neutral != V.init) _nF[n .. 2 * n] = v;
			foreach_reverse(i; 1 .. n) _nF[i] = f(_nF[i<<1], _nF[(i<<1)+1]);
			_nU = new U[](noNodes);
			_nHasU = new bool[](noNodes);
			_nSz = new size_t[](noNodes);
			_nSz[n .. 2 * n] = 1;
			foreach_reverse(i; 1 .. n) _nSz[i] = _nSz[i<<1] * 2;
		}
		void _clearU(size_t l, size_t r)
		{
			r--;
			auto li = layers - 1;
			for(; li > 0 && (l >> li) == (r >> li); li--) _clearU(l >> li);
			for(; li > 0; li--) _clearU(l >> li), _clearU(r >> li);
		}
		void _refresh(size_t l, size_t r)
		{
			r--;
			l >>= 1; r >>= 1;
			for(; l != r; l >>= 1, r >>= 1)
			{
				_nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
				_nF[r] = f(_getNodeF(r<<1), _getNodeF((r<<1)+1));
			}
			for(; l; l >>= 1) _nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
		}
		V rangeF(size_t l, size_t r)
		{
			l += length, r += length;
			_clearU(l, r);
			V value = neutral;
			for(; l < r; l >>= 1, r >>= 1)
			{
				if (l & 1) value = f(value, _getNodeF(l++));
				if (r & 1) value = f(value, _getNodeF(--r));
			}
			return value;
		}
		void rangeU(size_t l, size_t r, U u)
		{
			l += length, r += length;
			auto ol = l, or = r;
			for(; l < r; l >>= 1, r >>= 1)
			{
				if (l & 1) _addU(l++, u);
				if (r & 1) _addU(--r, u);
			}
			_refresh(ol, or);
		}
		V _getNodeF(size_t i)
		{
			if (_nHasU[i]) return cast(V) fou(_nF[i], _nU[i], _nSz[i]);
			return _nF[i];
		}
		bool _isLeaf(size_t i)
		{
			return i >= length;
		}
		void _clearU(size_t i)
		{
			if (!_nHasU[i]) return;
			if (_isLeaf(i))
			{
				_nF[i] = _getNodeF(i);
				_nHasU[i] = false;
				return;
			}
			_nHasU[i] = false;
			_addU(i << 1, _nU[i]), _addU((i << 1) + 1, _nU[i]);
			_nF[i] = f(_getNodeF(i<<1), _getNodeF((i<<1)+1));
		}
		void _addU(size_t i, U u)
		{
			if (!_nHasU[i])
			{
				_nU[i] = u;
				_nHasU[i] = true;
				return;
			}
			_nU[i] = uou(u, _nU[i]);
		}
		int[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
		{
			return [cast(int)start, cast(int)end];
		}
		auto opIndex(int[2] slice)
		{
			alias Parent = typeof(this);
			struct Ans
			{
				Parent* parent;
				int[2] slice;
				mixin(q{V }, fName, q{;});
				void opOpAssign(string op)(U u) if (op == uName)
				{
					parent.rangeU(slice[0], slice[1], u);
				}
			}
			return Ans(&this, slice, rangeF(slice[0], slice[1]));
		}
	}
}
long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = STL!(int, int).Type!(0,
			(v1, v2) => v1 + v2,
			(v, u, size_t l) => v + u * cast(int)l,
			(ni, pi) => ni + pi,
			"sum",
			"+");
	auto n = 100;
	int[] brute = new int[](n);
	auto smart = SumQSumU(n, 0);
	int rounds = 1000;
	foreach(round; 0 .. rounds)
	{
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				int v = uniform!"[]"(1, 20);
				brute[i .. j] += v;
				smart[i .. j] += v;
			}
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
				auto smartAnswer = smart[i .. j].sum;
				assert(bruteAnswer == smartAnswer);
			}
	}
}
// }}}

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	alias SegTree = STL!(int, int).Type!(0,
			(a, b) => max(a, b),
			(mx, set, sz) => set,
			(set1, set2) => set1,
			"max",
			"+");
	auto st = SegTree(noPoints, 0);
	auto st2 = STL!(int, int).Type!(0,
			(a, b) => max(a, b),
			(mx, add, sz) => mx + add,
			(add1, add2) => add1 + add2,
			"max",
			"+")(noPoints, 0);
	auto dp = new int[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = 0;
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st[range[0] .. range[1] + 1].max);
		}
		dpi++;
		foreach(range; ranges[i])
		{
			st[range[0] .. range[1] + 1] += dpi;
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i] > bdpi)
		{
			bdpi = dp[i];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;

	foreach(range; ranges[bi]) st2.rangeU(range[0], range[1] + 1, 1);
	alive[bi] = false;
	auto pbi = bi;
	bi--;
	while (bi >= 0)
	{
		if (dp[bi] == dp[pbi] - 1)
		{
			bool isGood = false;
			foreach(range; ranges[bi])
			{
					if (st2.rangeF(range[0], range[1] + 1) > 0) { isGood = true; break; }
			}
			if (isGood)
			{
				foreach(range; ranges[pbi])
					st2.rangeU(range[0], range[1] + 1, -1);
				foreach(range; ranges[bi])
					st2.rangeU(range[0], range[1] + 1, +1);
				alive[bi] = false;
				pbi = bi;
			}
		}
		bi--;
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
	writeln;
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
template STL(V, U)
{
	struct Type (V neutral, V function(V, V) f,
			V function(V, U, size_t) fou,
			U function(U, U) uou,
			string fName = "f", string uName = "u")
	{
		V[] _nF;
		U[] _nU;
		size_t[] _nSz;
		bool[] _nHasU;
		size_t length = 0;
		int layers = 0;
		this(size_t n, V v)
		{
			n = cast(size_t)nextPow2(cast(long)n);
			auto fn = n;
			while (fn) {layers++; fn >>= 1;}
			length = n;
			auto noNodes = 2 * n;
			_nF = new V[](noNodes);
			_nF[n .. 2 * n] = v;
			foreach_reverse(i; 1 .. n) _nF[i] = f(_nF[i<<1], _nF[(i<<1)+1]);
			_nU = new U[](noNodes);
			_nHasU = new bool[](noNodes);
			_nSz = new size_t[](noNodes);
			_nSz[n .. 2 * n] = 1;
			foreach_reverse(i; 1 .. n) _nSz[i] = _nSz[i<<1] * 2;
		}
		void _clearU(size_t l, size_t r)
		{
			r--;
			auto li = layers - 1;
			for(; li > 0 && (l >> li) == (r >> li); li--) _clearU(l >> li);
			for(; li > 0; li--) _clearU(l >> li), _clearU(r >> li);
		}
		void _refresh(size_t l, size_t r)
		{
			r--;
			l >>= 1; r >>= 1;
			for(; l != r; l >>= 1, r >>= 1)
			{
				_nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
				_nF[r] = f(_getNodeF(r<<1), _getNodeF((r<<1)+1));
			}
			for(; l; l >>= 1) _nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
		}
		V rangeF(size_t l, size_t r)
		{
			l += length, r += length;
			_clearU(l, r);
			V value = neutral;
			for(; l < r; l >>= 1, r >>= 1)
			{
				if (l & 1) value = f(value, _getNodeF(l++));
				if (r & 1) value = f(value, _getNodeF(--r));
			}
			return value;
		}
		void rangeU(size_t l, size_t r, U u)
		{
			l += length, r += length;
			auto ol = l, or = r;
			for(; l < r; l >>= 1, r >>= 1)
			{
				if (l & 1) _addU(l++, u);
				if (r & 1) _addU(--r, u);
			}
			_refresh(ol, or);
		}
		V _getNodeF(size_t i)
		{
			if (_nHasU[i]) return cast(V) fou(_nF[i], _nU[i], _nSz[i]);
			return _nF[i];
		}
		bool _isLeaf(size_t i)
		{
			return i >= length;
		}
		void _clearU(size_t i)
		{
			if (!_nHasU[i]) return;
			if (_isLeaf(i))
			{
				_nF[i] = _getNodeF(i);
				_nHasU[i] = false;
				return;
			}
			_nHasU[i] = false;
			_addU(i << 1, _nU[i]), _addU((i << 1) + 1, _nU[i]);
			_nF[i] = f(_getNodeF(i<<1), _getNodeF((i<<1)+1));
		}
		void _addU(size_t i, U u)
		{
			if (!_nHasU[i])
			{
				_nU[i] = u;
				_nHasU[i] = true;
				return;
			}
			_nU[i] = uou(u, _nU[i]);
		}
		int[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
		{
			return [cast(int)start, cast(int)end];
		}
		auto opIndex(int[2] slice)
		{
			alias Parent = typeof(this);
			struct Ans
			{
				Parent* parent;
				int[2] slice;
				mixin(q{V }, fName, q{;});
				void opOpAssign(string op)(U u) if (op == uName)
				{
					parent.rangeU(slice[0], slice[1], u);
				}
			}
			return Ans(&this, slice, rangeF(slice[0], slice[1]));
		}
	}
}
long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = STL!(int, int).Type!(0,
			(v1, v2) => v1 + v2,
			(v, u, size_t l) => v + u * cast(int)l,
			(ni, pi) => ni + pi,
			"sum",
			"+");
	auto n = 100;
	int[] brute = new int[](n);
	auto smart = SumQSumU(n, 0);
	int rounds = 1000;
	foreach(round; 0 .. rounds)
	{
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				int v = uniform!"[]"(1, 20);
				brute[i .. j] += v;
				smart[i .. j] += v;
			}
		foreach(i; 0 .. n)
			foreach(j; i + 1 .. n + 1)
			{
				auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
				auto smartAnswer = smart[i .. j].sum;
				assert(bruteAnswer == smartAnswer);
			}
	}
}
// }}}

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	alias SegTree = STL!(int, 0, int, (a, b) => max(a, b),
			(mx, set, sz) => set,
			(set1, set2) => set1,
			"max",
			"+");
	auto st = SegTree(noPoints, 0);
	auto st2 = STL!(int, 0, int, (a, b) => max(a, b),
			(mx, add, sz) => mx + add,
			(add1, add2) => add1 + add2,
			"max",
			"+")(noPoints, 0);
	auto dp = new int[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = 0;
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st[range[0] .. range[1] + 1].max);
		}
		dpi++;
		foreach(range; ranges[i])
		{
			st[range[0] .. range[1] + 1] += dpi;
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i] > bdpi)
		{
			bdpi = dp[i];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;

	foreach(range; ranges[bi]) st2.rangeU(range[0], range[1] + 1, 1);
	alive[bi] = false;
	auto pbi = bi;
	bi--;
	while (bi >= 0)
	{
		if (dp[bi] == dp[pbi] - 1)
		{
			bool isGood = false;
			foreach(range; ranges[bi])
			{
					if (st2.rangeF(range[0], range[1] + 1) > 0) { isGood = true; break; }
			}
			if (isGood)
			{
				foreach(range; ranges[pbi])
					st2.rangeU(range[0], range[1] + 1, -1);
				foreach(range; ranges[bi])
					st2.rangeU(range[0], range[1] + 1, +1);
				alive[bi] = false;
				pbi = bi;
			}
		}
		bi--;
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
struct STL(V, V neutral, U, alias f, alias fou, alias uou, string fName = "f", string uName = "u")
{
	V[] _nF;
	U[] _nU;
	long[] _nSz;
	bool[] _nHasU;
	size_t length = 0;
	int layers = 0;
	this(size_t n, V v)
	{
		n = cast(size_t)nextPow2(cast(long)n);
		auto fn = n;
		while (fn) {layers++; fn >>= 1;}
		length = n;
		auto noNodes = 2 * n;
		_nF = new V[](noNodes);
		_nF[n .. 2 * n] = v;
		foreach_reverse(i; 1 .. n) _nF[i] = f(_nF[i<<1], _nF[(i<<1)+1]);
		_nU = new U[](noNodes);
		_nHasU = new bool[](noNodes);
		_nSz = new long[](noNodes);
		_nSz[n .. 2 * n] = 1;
		foreach_reverse(i; 1 .. n) _nSz[i] = _nSz[i<<1] * 2;
	}
	void _clearU(size_t l, size_t r)
	{
		r--;
		auto li = layers - 1;
		for(; li > 0 && (l >> li) == (r >> li); li--) _clearU(l >> li);
		for(; li > 0; li--) _clearU(l >> li), _clearU(r >> li);
	}
	void _refresh(size_t l, size_t r)
	{
		r--;
		l >>= 1; r >>= 1;
		for(; l != r; l >>= 1, r >>= 1)
		{
			_nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
			_nF[r] = f(_getNodeF(r<<1), _getNodeF((r<<1)+1));
		}
		for(; l; l >>= 1) _nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
	}
	V rangeF(size_t l, size_t r)
	{
		l += length, r += length;
		_clearU(l, r);
		V value = neutral;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) value = f(value, _getNodeF(l++));
			if (r & 1) value = f(value, _getNodeF(--r));
		}
		return value;
	}
	void rangeU(size_t l, size_t r, U u)
	{
		l += length, r += length;
		auto ol = l, or = r;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) _addU(l++, u);
			if (r & 1) _addU(--r, u);
		}
		_refresh(ol, or);
	}
	V _getNodeF(size_t i)
	{
		if (_nHasU[i]) return cast(V) fou(_nF[i], _nU[i], _nSz[i]);
		return _nF[i];
	}
	bool _isLeaf(size_t i)
	{
		return i >= length;
	}
	void _clearU(size_t i)
	{
		if (!_nHasU[i]) return;
		if (_isLeaf(i))
		{
			_nF[i] = _getNodeF(i);
			_nHasU[i] = false;
			return;
		}
		_nHasU[i] = false;
		_addU(i << 1, _nU[i]), _addU((i << 1) + 1, _nU[i]);
		_nF[i] = f(_getNodeF(i<<1), _getNodeF((i<<1)+1));
	}
	void _addU(size_t i, U u)
	{
		if (!_nHasU[i])
		{
			_nU[i] = u;
			_nHasU[i] = true;
			return;
		}
		_nU[i] = uou(u, _nU[i]);
	}
	int[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
	{
		return [cast(int)start, cast(int)end];
	}
	auto opIndex(int[2] slice)
	{
		alias Parent = typeof(this);
		struct Ans
		{
			Parent* parent;
			int[2] slice;
			mixin(q{V }, fName, q{;});
			void opOpAssign(string op)(U u) if (op == uName)
			{
				parent.rangeU(slice[0], slice[1], u);
			}
		}
		return Ans(&this, slice, rangeF(slice[0], slice[1]));
	}
}
long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = STL!(int, int, (v1, v2) => v1 + v2,
			(v, u, l) => v + u * l,
			(ni, pi) => ni + pi,
			"sum",
			"+");
	auto n = 100;
	int[] brute = new int[](n);
	auto smart = SumQSumU(n, 0);
	int rounds = 1000;
	foreach(round; 0 .. rounds)
	{
		foreach(i; 0 .. n)
		foreach(j; i + 1 .. n + 1)
		{
			int v = uniform!"[]"(1, 20);
			brute[i .. j] += v;
			smart[i .. j] += v;
		}
		foreach(i; 0 .. n)
		foreach(j; i + 1 .. n + 1)
		{
			auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
			auto smartAnswer = smart[i .. j].sum;
			writeln(bruteAnswer, " =? ", smartAnswer);
			assert(bruteAnswer == smartAnswer);
		}
	}
}
// }}}

immutable multi = false;

void solve(int tc)
{
	auto n = readInt!int;
	auto m = readInt!int;
	auto ranges = new Tuple!(int, int)[][](n);
	int[] pointSet;
	foreach(i; 0 .. m)
	{
		auto rangeIndex = readInt!int - 1;
		auto rangeStart = readInt!int;
		auto rangeEnd = readInt!int;
		pointSet ~= rangeStart;
		pointSet ~= rangeEnd;
		ranges[rangeIndex] ~= tuple(rangeStart, rangeEnd);
	}
	sort(pointSet);
	pointSet = pointSet.uniq.array;
	int noPoints = cast(int) pointSet.length;
	int[int] rank;
	int nextRank = 0;
	foreach(pi; pointSet) rank[pi] = nextRank++;
	foreach(ref rangeSet; ranges)
		foreach(ref range; rangeSet)
		{
			range[0] = rank[range[0]];
			range[1] = rank[range[1]];
		}
	debug writeln("ranges: ", ranges);
	alias SegTree = STL!(Tuple!(int, int), tuple(0, -1), Tuple!(int, int), (a, b) => max(a, b),
			(mx, set, sz) => set,
			(set1, set2) => set1,
			"max",
			"+");
	auto st = SegTree(noPoints, tuple(0, -1));
	auto dp = new Tuple!(int, int)[](n);
	foreach(i, ref dpi; dp)
	{
		dpi = tuple(0, -1);
		foreach(range; ranges[i])
		{
			dpi = max(dpi, st[range[0] .. range[1] + 1].max);
		}
		dpi[0]++;
		foreach(range; ranges[i])
		{
			st[range[0] .. range[1] + 1] += tuple(dpi[0], cast(int)i);
		}
	}
	debug writeln("dp: ", dp);
	int bdpi = 0;
	int bi = -1;
	foreach(i; 0 .. n)
	{
		if (dp[i][0] > bdpi)
		{
			bdpi = dp[i][0];
			bi = i;
		}
	}
	debug writeln("bdpi = ", bdpi, " bi = ", bi);
	auto alive = new bool[](n);
	alive[] = true;
	while (bi >= 0)
	{
		alive[bi] = false;
		bi = dp[bi][1];
	}
	writeln(n - bdpi);
	foreach(i; 0 .. n) if (alive[i]) write(i + 1, " ");
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}
// STL V, U, f, fou, uou, fName, uName {{{
struct STL(V, V neutral, U, alias f, alias fou, alias uou, string fName = "f", string uName = "u")
{
	V[] _nF;
	U[] _nU;
	long[] _nSz;
	bool[] _nHasU;
	size_t length = 0;
	int layers = 0;
	this(size_t n, V v)
	{
		n = cast(size_t)nextPow2(cast(long)n);
		auto fn = n;
		while (fn) {layers++; fn >>= 1;}
		length = n;
		auto noNodes = 2 * n;
		_nF = new V[](noNodes);
		_nF[n .. 2 * n] = v;
		foreach_reverse(i; 1 .. n) _nF[i] = f(_nF[i<<1], _nF[(i<<1)+1]);
		_nU = new U[](noNodes);
		_nHasU = new bool[](noNodes);
		_nSz = new long[](noNodes);
		_nSz[n .. 2 * n] = 1;
		foreach_reverse(i; 1 .. n) _nSz[i] = _nSz[i<<1] * 2;
	}
	void _clearU(size_t l, size_t r)
	{
		r--;
		auto li = layers - 1;
		for(; li > 0 && (l >> li) == (r >> li); li--) _clearU(l >> li);
		for(; li > 0; li--) _clearU(l >> li), _clearU(r >> li);
	}
	void _refresh(size_t l, size_t r)
	{
		r--;
		l >>= 1; r >>= 1;
		for(; l != r; l >>= 1, r >>= 1)
		{
			_nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
			_nF[r] = f(_getNodeF(r<<1), _getNodeF((r<<1)+1));
		}
		for(; l; l >>= 1) _nF[l] = f(_getNodeF(l<<1), _getNodeF((l<<1)+1));
	}
	V rangeF(size_t l, size_t r)
	{
		l += length, r += length;
		_clearU(l, r);
		V value = neutral;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) value = f(value, _getNodeF(l++));
			if (r & 1) value = f(value, _getNodeF(--r));
		}
		return value;
	}
	void rangeU(size_t l, size_t r, U u)
	{
		l += length, r += length;
		for(; l < r; l >>= 1, r >>= 1)
		{
			if (l & 1) _addU(l++, u);
			if (r & 1) _addU(--r, u);
		}
		_refresh(l, r);
	}
	V _getNodeF(size_t i)
	{
		if (_nHasU[i]) return cast(V) fou(_nF[i], _nU[i], _nSz[i]);
		return _nF[i];
	}
	bool _isLeaf(size_t i)
	{
		return i >= length;
	}
	void _clearU(size_t i)
	{
		if (!_nHasU[i]) return;
		if (_isLeaf(i))
		{
			_nF[i] = _getNodeF(i);
			_nHasU[i] = false;
			return;
		}
		_nHasU[i] = false;
		_addU(i << 1, _nU[i]), _addU((i << 1) + 1, _nU[i]);
		_nF[i] = f(_getNodeF(i<<1), _getNodeF((i<<1)+1));
	}
	void _addU(size_t i, U u)
	{
		if (!_nHasU[i])
		{
			_nU[i] = u;
			_nHasU[i] = true;
			return;
		}
		_nU[i] = uou(u, _nU[i]);
	}
	int[2] opSlice(size_t i)(size_t start, size_t end) if (i == 0)
	{
		return [cast(int)start, cast(int)end];
	}
	auto opIndex(int[2] slice)
	{
		alias Parent = typeof(this);
		struct Ans
		{
			Parent* parent;
			int[2] slice;
			mixin(q{V }, fName, q{;});
			void opOpAssign(string op)(U u) if (op == uName)
			{
				parent.rangeU(slice[0], slice[1], u);
			}
		}
		return Ans(&this, slice, rangeF(slice[0], slice[1]));
	}
}
long nextPow2(long n)
{
	int p = 1;
	for(; p < n; p <<= 1) {}
	return p;
}

unittest
{
	import std.algorithm;
	import std.random;
	import std.stdio;
	alias SumQSumU = STL!(int, int, (v1, v2) => v1 + v2,
			(v, u, l) => v + u * l,
			(ni, pi) => ni + pi,
			"sum",
			"+");
	auto n = 100;
	int[] brute = new int[](n);
	auto smart = SumQSumU(n, 0);
	int rounds = 1000;
	foreach(round; 0 .. rounds)
	{
		foreach(i; 0 .. n)
		foreach(j; i + 1 .. n + 1)
		{
			int v = uniform!"[]"(1, 20);
			brute[i .. j] += v;
			smart[i .. j] += v;
		}
		foreach(i; 0 .. n)
		foreach(j; i + 1 .. n + 1)
		{
			auto bruteAnswer = brute[i .. j].fold!((a, b) => (a + b));
			auto smartAnswer = smart[i .. j].sum;
			writeln(bruteAnswer, " =? ", smartAnswer);
			assert(bruteAnswer == smartAnswer);
		}
	}
}
// }}}