Moamen was drawing a grid of $$$n$$$ rows and $$$10^9$$$ columns containing only digits $$$0$$$ and $$$1$$$. Ezzat noticed what Moamen was drawing and became interested in the minimum number of rows one needs to remove to make the grid beautiful.A grid is beautiful if and only if for every two consecutive rows there is at least one column containing $$$1$$$ in these two rows.Ezzat will give you the number of rows $$$n$$$, and $$$m$$$ segments of the grid that contain digits $$$1$$$. Every segment is represented with three integers $$$i$$$, $$$l$$$, and $$$r$$$, where $$$i$$$ represents the row number, and $$$l$$$ and $$$r$$$ represent the first and the last column of the segment in that row.For example, if $$$n = 3$$$, $$$m = 6$$$, and the segments are $$$(1,1,1)$$$, $$$(1,7,8)$$$, $$$(2,7,7)$$$, $$$(2,15,15)$$$, $$$(3,1,1)$$$, $$$(3,15,15)$$$, then the grid is:  Your task is to tell Ezzat the minimum number of rows that should be removed to make the grid beautiful.

The first line contains two integers $$$n$$$ and $$$m$$$ ($$$1 \le n, m \le 3\cdot10^5$$$). Each of the next $$$m$$$ lines contains three integers $$$i$$$, $$$l$$$, and $$$r$$$ ($$$1 \le i \le n$$$, $$$1 \le l \le r \le 10^9$$$). Each of these $$$m$$$ lines means that row number $$$i$$$ contains digits $$$1$$$ in columns from $$$l$$$ to $$$r$$$, inclusive. Note that the segments may overlap.

In the first line, print a single integer $$$k$$$ — the minimum number of rows that should be removed. In the second line print $$$k$$$ distinct integers $$$r_1, r_2, \ldots, r_k$$$, representing the rows that should be removed ($$$1 \le r_i \le n$$$), in any order. If there are multiple answers, print any.

NoteIn the first test case, the grid is the one explained in the problem statement. The grid has the following properties:   The $$$1$$$-st row and the $$$2$$$-nd row have a common $$$1$$$ in the column $$$7$$$.  The $$$2$$$-nd row and the $$$3$$$-rd row have a common $$$1$$$ in the column $$$15$$$.  As a result, this grid is beautiful and we do not need to remove any row.In the second test case, the given grid is as follows:

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);
			}
	}
}
// }}}

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 = 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);
		}
	}
}
// }}}