#include <bits/stdc++.h>
using namespace std;

mt19937 rng_priority;

struct node
{
	int l, r;
	int y;

	int cnt;

	int value;

	node (const int value_) : value(value_), y(rng_priority()), l(-1), r(-1), cnt(1) {}
};

struct treap_manager
{
	vector<node> pool;

	int add_node(const int value)
	{
		const int ans = int(pool.size());
		pool.push_back(node(value));
		return ans;
	}

	int subtree (const int v)
	{
///		if (v == -1)
///			return 0;
///		else
///			return pool[v].cnt;
		return v == -1 ? 0 : pool[v].cnt;
	}

	void recalc(const int v)
	{
		if (v != -1)
			pool[v].cnt = subtree(pool[v].l) + 1 + subtree(pool[v].r);
	}

	int merge(int l, int m, int r)
	{
		return merge(merge(l, m), r);
	}

	pair<int, int> split (const int t, const int k)
	{
		if (t == -1)
			return pair<int, int>(-1, -1);

		int l, r;
///		if (pool[t].x < xs)
		if (subtree(pool[t].l) < k)
		{
/// 		Так МОЖНО написать, но не нужно.
//			const int mem = pool[t].r;
//			pool[t].r = -1;
//			tie(l, r) = split(mem, x);
//          pool[t].r = l;

			tie(l, r) = split(pool[t].r, k - subtree(pool[t].l) - 1);
			/// Поддеревья l и r --- всё хорошо (cnt-шки посчитаны правильно).
			pool[t].r = l;

			/// Слишком умные студенты :)
			pool[t].cnt -= subtree(r);

			return pair<int, int>(t, r);
		}
		else
		{
//			pool[t].x >= x;

///			pair<int, int> p = split(pool[t].l, k);
///			l = p.first;
///			r = p.second;
			tie(l, r) = split(pool[t].l, k);
			pool[t].l = r;

			pool[t].cnt -= subtree(l);

			return pair<int, int>(l, t);
		}
	}

	int merge (int l, int r)
	{
		if (l == -1)
			return r;
		if (r == -1)
			return l;

		const int total_size = subtree(l) + subtree(r);

		if (pool[l].y > pool[r].y)
		{
			const int sr = subtree(r);
			pool[l].r = merge(pool[l].r, r);
			/// А вот это работает!
			pool[l].cnt += sr;
//			pool[l].cnt = total_size;
			return l;
		}
		else
		{
			const int sl = subtree(l);
			pool[r].l = merge(l, pool[r].l);
			/// А вот это работает!
			pool[r].cnt += sl;
//			pool[r].cnt = total_size;
			return r;
		}
	}

	int move_to_front (const int tree, const int left, const int right)
	{
		int l, m, r;

		tie(l, m) = split(tree, left);
		tie(m, r) = split(m, right - left);

		return merge(m, l, r);
	}

	int insert_at_pos (const int tree, const int pos, const int value)
	{
		const int ver = add_node(value);
		int l, r;

		tie(l, r) = split(tree, pos);
		return merge(l, ver, r);
	}

	/// возвращает идентификатор дерева после удаления ключа x
	int remove_at_pos (const int tree, const int pos)
	{
		int l, m, r;
		tie(l, m) = split(tree, pos);
		/// Важно, что 1!
		tie(m, r) = split(m, 1);
		return merge(l, r);
	}

	/// в 0-индексации, то есть 0 <= k < subtree(root);
	int get_kth_value (const int root, const int k)
	{
		assert(0 <= k && k < subtree(root));
		if (k == subtree(pool[root].l))
			return pool[root].value;
		if (k < subtree(pool[root].l))
			return get_kth_value(pool[root].l, k);
		/// k >= subtree(pool[root].l) + 1;
		return get_kth_value(pool[root].r, k - subtree(pool[root].l) - 1);
	}

	void print_tree (ostream &cout, const int root)
	{
		if (root == -1)
			return;

		print_tree(cout, pool[root].l);
		cout << pool[root].value << ' ';
		print_tree(cout, pool[root].r);
	}
};

void solve(istream &cin, ostream &cout)
{
	int n, m;
	cin >> n >> m;

	treap_manager treap;
	int root = -1;

	for (int i = 1; i <= n; i++)
		root = treap.insert_at_pos(root, treap.subtree(root), i);

	for (int i = 0; i < m; i++)
	{
		int l, r;
		cin >> l >> r;
		--l;

		root = treap.move_to_front(root, l, r);
	}

	treap.print_tree(cout, root);
	cout << endl;
}

int main()
{
//	ifstream fin("input.txt");
//	ofstream fout("output.txt");
//	solve(fin, fout);

	solve(cin, cout);
}