Hooray! Berl II, the king of Berland is making a knight tournament. The king has already sent the message to all knights in the kingdom and they in turn agreed to participate in this grand event.

As for you, you're just a simple peasant. There's no surprise that you slept in this morning and were late for the tournament (it was a weekend, after all). Now you are really curious about the results of the tournament. This time the tournament in Berland went as follows:  There are n knights participating in the tournament. Each knight was assigned his unique number — an integer from 1 to n.  The tournament consisted of m fights, in the i-th fight the knights that were still in the game with numbers at least l_{i} and at most r_{i} have fought for the right to continue taking part in the tournament.  After the i-th fight among all participants of the fight only one knight won — the knight number x_{i}, he continued participating in the tournament. Other knights left the tournament.  The winner of the last (the m-th) fight (the knight number x_{m}) became the winner of the tournament. 

You fished out all the information about the fights from your friends. Now for each knight you want to know the name of the knight he was conquered by. We think that the knight number b was conquered by the knight number a, if there was a fight with both of these knights present and the winner was the knight number a.

Write the code that calculates for each knight, the name of the knight that beat him.


-----Input-----

The first line contains two integers n, m (2 ≤ n ≤ 3·10^5; 1 ≤ m ≤ 3·10^5) — the number of knights and the number of fights. Each of the following m lines contains three integers l_{i}, r_{i}, x_{i} (1 ≤ l_{i} < r_{i} ≤ n; l_{i} ≤ x_{i} ≤ r_{i}) — the description of the i-th fight.

It is guaranteed that the input is correct and matches the problem statement. It is guaranteed that at least two knights took part in each battle.


-----Output-----

Print n integers. If the i-th knight lost, then the i-th number should equal the number of the knight that beat the knight number i. If the i-th knight is the winner, then the i-th number must equal 0.


-----Examples-----
Input
4 3
1 2 1
1 3 3
1 4 4

Output
3 1 4 0 
Input
8 4
3 5 4
3 7 6
2 8 8
1 8 1

Output
0 8 4 6 4 8 6 1 


-----Note-----

Consider the first test case. Knights 1 and 2 fought the first fight and knight 1 won. Knights 1 and 3 fought the second fight and knight 3 won. The last fight was between knights 3 and 4, knight 4 won.

Source: codeforces | Difficulty: MEDIUM
Tags: Spanning trees

Data structures


Solutions:
import os, io
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
(n, m) = list(map(int, input().split()))
conquerer = ['0'] * n
nextKnight = []
for i in range(n):
	nextKnight.append(i)
for _ in range(m):
	(l, r, x) = list(map(int, input().split()))
	pathList = []
	index = l - 1
	maxIndex = r
	while index < r:
		while index < n and nextKnight[index] != index:
			pathList.append(index)
			index = nextKnight[index]
		if index < r and index != x - 1:
			conquerer[index] = str(x)
			pathList.append(index)
		if index >= r:
			maxIndex = index
		index += 1
	for elem in pathList:
		if elem < x - 1:
			nextKnight[elem] = x - 1
		else:
			nextKnight[elem] = maxIndex
print(' '.join(conquerer))


import sys

class SegmTree:

	def __init__(self, array=None, size=None):
		if array is not None:
			size = len(array)
		N = 1
		while N < size:
			N <<= 1
		self.N = N
		self.tree = [0] * (2 * self.N)
		if array is not None:
			for i in range(size):
				self.tree[i + self.N] = array[i]
			self.build()

	def build(self):
		for i in range(self.N - 1, 0, -1):
			self.tree[i] = self.tree[i << 1] + self.tree[i << 1 | 1]

	def add(self, i, value=1):
		i += self.N
		while i > 0:
			self.tree[i] += value
			i >>= 1

	def find_nonzeros(self, l, r):
		N = self.N
		l += N
		r += N
		cand = []
		while l < r:
			if l & 1:
				if self.tree[l]:
					cand.append(l)
				l += 1
			if r & 1:
				r -= 1
				if self.tree[r]:
					cand.append(r)
			l >>= 1
			r >>= 1
		ans = []
		while cand:
			i = cand.pop()
			if i < N:
				i <<= 1
				if self.tree[i]:
					cand.append(i)
				if self.tree[i | 1]:
					cand.append(i | 1)
			else:
				ans.append(i - N)
		return ans
reader = (line.rstrip() for line in sys.stdin)
input = reader.__next__
(n, m) = list(map(int, input().split()))
st = SegmTree([1] * n)
ans = [0] * n
for _ in range(m):
	(l, r, x) = list(map(int, input().split()))
	l -= 1
	x -= 1
	for i in st.find_nonzeros(l, r):
		if i != x:
			ans[i] = x + 1
			st.add(i, -1)
print(*ans)


import os
(n, m) = list(map(int, input().split()))
parent = list(range(0, n + 1))
answer = list(range(0, n))

def getParent(x):
	while parent[x] != x:
		x = parent[x]
		parent[x] = parent[parent[x]]
	return parent[x]
for i in range(m):
	(l, r, x) = list(map(int, input().split()))
	cnt = getParent(l - 1)
	while cnt <= r - 1:
		if cnt == x - 1:
			cnt = cnt + 1
		else:
			parent[cnt] = cnt + 1
			answer[cnt] = x - 1
		cnt = getParent(cnt)
c = 0
s = ''
for i in answer:
	if c == i:
		s += '0 '
	else:
		s += str(i + 1) + ' '
	c = c + 1
os.write(1, str.encode(s))


from sys import stdin
input = lambda : stdin.readline().strip()
from math import ceil, sqrt, factorial, gcd
(n, m) = map(int, input().split())
ans = [0 for i in range(n)]
nextl = [i + 1 for i in range(n + 2)]
for j in range(m):
	(l, r, x) = map(int, input().split())
	i = l
	while i <= r:
		if ans[i - 1] == 0 and i != x:
			ans[i - 1] = x
		a = nextl[i]
		if i < x:
			nextl[i] = x
		else:
			nextl[i] = r + 1
		i = a
print(*ans)


import os
from io import BytesIO, IOBase
import sys

class SortedList:

	def __init__(self, iterable=None, _load=200):
		if iterable is None:
			iterable = []
		values = sorted(iterable)
		self._len = _len = len(values)
		self._load = _load
		self._lists = _lists = [values[i:i + _load] for i in range(0, _len, _load)]
		self._list_lens = [len(_list) for _list in _lists]
		self._mins = [_list[0] for _list in _lists]
		self._fen_tree = []
		self._rebuild = True

	def _fen_build(self):
		self._fen_tree[:] = self._list_lens
		_fen_tree = self._fen_tree
		for i in range(len(_fen_tree)):
			if i | i + 1 < len(_fen_tree):
				_fen_tree[i | i + 1] += _fen_tree[i]
		self._rebuild = False

	def _fen_update(self, index, value):
		if not self._rebuild:
			_fen_tree = self._fen_tree
			while index < len(_fen_tree):
				_fen_tree[index] += value
				index |= index + 1

	def _fen_query(self, end):
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		x = 0
		while end:
			x += _fen_tree[end - 1]
			end &= end - 1
		return x

	def _fen_findkth(self, k):
		_list_lens = self._list_lens
		if k < _list_lens[0]:
			return (0, k)
		if k >= self._len - _list_lens[-1]:
			return (len(_list_lens) - 1, k + _list_lens[-1] - self._len)
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		idx = -1
		for d in reversed(range(len(_fen_tree).bit_length())):
			right_idx = idx + (1 << d)
			if right_idx < len(_fen_tree) and k >= _fen_tree[right_idx]:
				idx = right_idx
				k -= _fen_tree[idx]
		return (idx + 1, k)

	def _delete(self, pos, idx):
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len -= 1
		self._fen_update(pos, -1)
		del _lists[pos][idx]
		_list_lens[pos] -= 1
		if _list_lens[pos]:
			_mins[pos] = _lists[pos][0]
		else:
			del _lists[pos]
			del _list_lens[pos]
			del _mins[pos]
			self._rebuild = True

	def _loc_left(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(lo, pos) = (-1, len(_lists) - 1)
		while lo + 1 < pos:
			mi = lo + pos >> 1
			if value <= _mins[mi]:
				pos = mi
			else:
				lo = mi
		if pos and value <= _lists[pos - 1][-1]:
			pos -= 1
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value <= _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def _loc_right(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(pos, hi) = (0, len(_lists))
		while pos + 1 < hi:
			mi = pos + hi >> 1
			if value < _mins[mi]:
				hi = mi
			else:
				pos = mi
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value < _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def add(self, value):
		_load = self._load
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len += 1
		if _lists:
			(pos, idx) = self._loc_right(value)
			self._fen_update(pos, 1)
			_list = _lists[pos]
			_list.insert(idx, value)
			_list_lens[pos] += 1
			_mins[pos] = _list[0]
			if _load + _load < len(_list):
				_lists.insert(pos + 1, _list[_load:])
				_list_lens.insert(pos + 1, len(_list) - _load)
				_mins.insert(pos + 1, _list[_load])
				_list_lens[pos] = _load
				del _list[_load:]
				self._rebuild = True
		else:
			_lists.append([value])
			_mins.append(value)
			_list_lens.append(1)
			self._rebuild = True

	def discard(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_right(value)
			if idx and _lists[pos][idx - 1] == value:
				self._delete(pos, idx - 1)

	def remove(self, value):
		_len = self._len
		self.discard(value)
		if _len == self._len:
			raise ValueError('{0!r} not in list'.format(value))

	def pop(self, index=-1):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		value = self._lists[pos][idx]
		self._delete(pos, idx)
		return value

	def bisect_left(self, value):
		(pos, idx) = self._loc_left(value)
		return self._fen_query(pos) + idx

	def bisect_right(self, value):
		(pos, idx) = self._loc_right(value)
		return self._fen_query(pos) + idx

	def count(self, value):
		return self.bisect_right(value) - self.bisect_left(value)

	def __len__(self):
		return self._len

	def __getitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		return self._lists[pos][idx]

	def __delitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		self._delete(pos, idx)

	def __contains__(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_left(value)
			return idx < len(_lists[pos]) and _lists[pos][idx] == value
		return False

	def __iter__(self):
		return (value for _list in self._lists for value in _list)

	def __reversed__(self):
		return (value for _list in reversed(self._lists) for value in reversed(_list))

	def __repr__(self):
		return 'SortedList({0})'.format(list(self))

def main():
	(n, m) = map(int, input().split())
	arr = range(1, n + 1)
	arr = SortedList(arr)
	ans = [0] * (n + 1)
	for _ in range(m):
		(l, r, k) = map(int, input().split())
		z = arr.bisect_left(l)
		while z < len(arr):
			if arr[z] == k:
				z += 1
			elif arr[z] > r:
				break
			else:
				ans[arr[z]] = k
				arr.remove(arr[z])
	print(*ans[1:])
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


(n, m) = map(int, input().split())
(p, d) = ([0] * (n + 2), list(range(1, n + 3)))
for i in range(m):
	(l, r, x) = map(int, input().split())
	while l < x:
		if p[l]:
			k = d[l]
			d[l] = x
			l = k
		else:
			(d[l], p[l]) = (x, x)
			l += 1
	l += 1
	r += 1
	while p[r]:
		r = d[r]
	while l < r:
		if p[l]:
			k = d[l]
			d[l] = r
			l = k
		else:
			(d[l], p[l]) = (r, x)
			l += 1
print(' '.join(map(str, p[1:-1])))


from sys import stdin
inp = stdin.readline
(n, m) = map(int, inp().split())
ans = [0] * (n + 1)
alive = [i + 1 for i in range(n + 2)]
while m:
	m -= 1
	(l, r, x) = map(int, inp().split())
	i = l
	while i <= r:
		if ans[i] == 0 and i != x:
			ans[i] = x
		temp = alive[i]
		if i < x:
			alive[i] = x
		else:
			alive[i] = r + 1
		i = temp
print(*ans[1:])


(n, m) = map(int, input().split())
ans = [0] * (n + 10)
mx = list(range(n + 10))

def find(st):
	if mx[st] != st:
		mx[st] = find(mx[st])
	return mx[st]
for _ in range(m):
	(l, r, x) = map(int, input().split())
	xt = find(l)
	while xt < x:
		if xt != x:
			ans[xt] = x
			mx[xt] = x
		xt = find(xt + 1)
	xt = find(x + 1)
	while xt <= r:
		if xt != x:
			ans[xt] = x
			mx[xt] = r + 1
		xt = find(xt + 1)
print(*ans[1:n + 1])


import sys
input = sys.stdin.readline

def inint():
	return int(input())

def inlst():
	return list(map(int, input().split()))

def instr():
	s = input()
	return list(s[:len(s) - 1])

def invar():
	return list(map(int, input().split()))

def isOdd(num):
	return num & 1 == 1
(n, m) = invar()
tree = [{'round_num': m, 'winner': -1} for _ in range(2 * n + 1, 0, -1)]

def modify(left, right, pair):
	left += n
	right += n
	while left <= right:
		if isOdd(left):
			tree[left] = pair
		if not isOdd(right):
			tree[right] = pair
		left = int((left + 1) / 2)
		right = int((right - 1) / 2)

def query(pos):
	pos += n
	min = 1000000
	winner = -1
	while pos > 0:
		if tree[pos]['round_num'] < min:
			winner = tree[pos]['winner']
			min = tree[pos]['round_num']
		pos >>= 1
	return winner + 1 if winner > -1 else 0
rounds = []
for _ in range(m):
	(li, ri, xi) = invar()
	rounds.append({'left': li - 1, 'right': ri - 1, 'winner': xi - 1})
for idx in range(m - 1, -1, -1):
	round = rounds[idx]
	if round['winner'] > 0:
		modify(round['left'], round['winner'] - 1, {'round_num': idx, 'winner': round['winner']})
	if round['winner'] < n:
		modify(round['winner'] + 1, round['right'], {'round_num': idx, 'winner': round['winner']})
print(*[query(i) for i in range(n)])


import os
import sys
from io import BytesIO, IOBase
from sys import stdin
input = stdin.readline

class SortedList:

	def __init__(self, iterable=[], _load=200):
		values = sorted(iterable)
		self._len = _len = len(values)
		self._load = _load
		self._lists = _lists = [values[i:i + _load] for i in range(0, _len, _load)]
		self._list_lens = [len(_list) for _list in _lists]
		self._mins = [_list[0] for _list in _lists]
		self._fen_tree = []
		self._rebuild = True

	def _fen_build(self):
		self._fen_tree[:] = self._list_lens
		_fen_tree = self._fen_tree
		for i in range(len(_fen_tree)):
			if i | i + 1 < len(_fen_tree):
				_fen_tree[i | i + 1] += _fen_tree[i]
		self._rebuild = False

	def _fen_update(self, index, value):
		if not self._rebuild:
			_fen_tree = self._fen_tree
			while index < len(_fen_tree):
				_fen_tree[index] += value
				index |= index + 1

	def _fen_query(self, end):
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		x = 0
		while end:
			x += _fen_tree[end - 1]
			end &= end - 1
		return x

	def _fen_findkth(self, k):
		_list_lens = self._list_lens
		if k < _list_lens[0]:
			return (0, k)
		if k >= self._len - _list_lens[-1]:
			return (len(_list_lens) - 1, k + _list_lens[-1] - self._len)
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		idx = -1
		for d in reversed(range(len(_fen_tree).bit_length())):
			right_idx = idx + (1 << d)
			if right_idx < len(_fen_tree) and k >= _fen_tree[right_idx]:
				idx = right_idx
				k -= _fen_tree[idx]
		return (idx + 1, k)

	def _delete(self, pos, idx):
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len -= 1
		self._fen_update(pos, -1)
		del _lists[pos][idx]
		_list_lens[pos] -= 1
		if _list_lens[pos]:
			_mins[pos] = _lists[pos][0]
		else:
			del _lists[pos]
			del _list_lens[pos]
			del _mins[pos]
			self._rebuild = True

	def _loc_left(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(lo, pos) = (-1, len(_lists) - 1)
		while lo + 1 < pos:
			mi = lo + pos >> 1
			if value <= _mins[mi]:
				pos = mi
			else:
				lo = mi
		if pos and value <= _lists[pos - 1][-1]:
			pos -= 1
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value <= _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def _loc_right(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(pos, hi) = (0, len(_lists))
		while pos + 1 < hi:
			mi = pos + hi >> 1
			if value < _mins[mi]:
				hi = mi
			else:
				pos = mi
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value < _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def add(self, value):
		_load = self._load
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len += 1
		if _lists:
			(pos, idx) = self._loc_right(value)
			self._fen_update(pos, 1)
			_list = _lists[pos]
			_list.insert(idx, value)
			_list_lens[pos] += 1
			_mins[pos] = _list[0]
			if _load + _load < len(_list):
				_lists.insert(pos + 1, _list[_load:])
				_list_lens.insert(pos + 1, len(_list) - _load)
				_mins.insert(pos + 1, _list[_load])
				_list_lens[pos] = _load
				del _list[_load:]
				self._rebuild = True
		else:
			_lists.append([value])
			_mins.append(value)
			_list_lens.append(1)
			self._rebuild = True

	def discard(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_right(value)
			if idx and _lists[pos][idx - 1] == value:
				self._delete(pos, idx - 1)

	def remove(self, value):
		_len = self._len
		self.discard(value)
		if _len == self._len:
			raise ValueError('{0!r} not in list'.format(value))

	def pop(self, index=-1):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		value = self._lists[pos][idx]
		self._delete(pos, idx)
		return value

	def __len__(self):
		return self._len

	def __getitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		return self._lists[pos][idx]
from bisect import bisect_left
(n, m) = map(int, input().strip().split())
ans = [0] * (n + 1)
good = SortedList([i for i in range(1, n + 1)])
for i in range(m):
	(l, r, x) = map(int, input().strip().split())
	ll = bisect_left(good, l)
	todel = []
	for ind in range(ll, len(good)):
		i = good[ind]
		if i <= r:
			if i != x:
				todel.append(i)
				ans[i] = x
		else:
			break
	for i in todel:
		good.remove(i)
print(*ans[1:])


import sys
from collections import defaultdict

class llnode:
	p = None
	n = None
	val = None

class llist:
	root = None

	def __init__(self, totalNodes):
		self.ans = [0 for _ in range(totalNodes + 1)]
		self.makell(totalNodes)

	def makell(self, total):
		root = llnode()
		curVal = 1
		root.val = curVal
		self.root = root
		curNode = self.root
		while curVal < total:
			curVal += 1
			nextNode = llnode()
			nextNode.val = curVal
			nextNode.p = curNode
			curNode.n = nextNode
			curNode = nextNode

	def printll(self):
		curNode = self.root
		while curNode:
			print(curNode.val)
			curNode = curNode.n

	def remove(self, node, vanqVal):
		self.ans[node.val] = vanqVal
		if node == self.root:
			self.root = node.n
			self.root.p = None
			node.p = None
			del node
		else:
			node.p.n = node.n
			if node.n:
				node.n.p = node.p
			del node

	def removeNodes(self, startVal, endVal, exception):
		curNode = self.root
		while curNode and curNode.val < startVal:
			curNode = curNode.n
		while curNode and curNode.val <= endVal:
			if curNode.val != exception:
				remNode = curNode
				curNode = curNode.n
				self.remove(remNode, exception)
			else:
				curNode = curNode.n

	def getAns(self):
		return self.ans

def results(knights, tList):
	ans = [0 for _ in range(knights + 1)]
	for (l, r, winner) in tList:
		for i in range(l, r + 1):
			if i != winner and ans[i] == 0:
				ans[i] = winner
	return ans[1:]

def results2(knights, tList):
	k = llist(knights)
	for (l, r, winner) in tList:
		k.removeNodes(l, r, winner)
	return k.getAns()[1:]

def results3(knights, tList):
	jumpList = [[0, 0] for _ in range(knights + 1)]
	ans = [0 for _ in range(knights + 1)]
	for (l, r, winner) in tList:
		left = l
		right = r
		while left < winner:
			if ans[left] == 0:
				ans[left] = winner
				jumpList[left] = [l - 1, winner]
				left += 1
			else:
				curLeft = left
				left = jumpList[left][1]
				jumpList[curLeft][0] = min(l - 1, jumpList[curLeft][0])
				jumpList[curLeft][1] = max(winner, jumpList[curLeft][1])
		while right > winner:
			if ans[right] == 0:
				ans[right] = winner
				jumpList[right] = [winner, r + 1]
				right -= 1
			else:
				curRight = right
				right = jumpList[right][0]
				jumpList[curRight][0] = min(winner, jumpList[curRight][0])
				jumpList[curRight][1] = max(r + 1, jumpList[curRight][1])
	return ans[1:]

def readinput():
	(n, m) = map(int, sys.stdin.readline().rstrip().split(' '))
	tList = []
	for _ in range(m):
		(l, r, win) = map(int, sys.stdin.readline().rstrip().split(' '))
		tList.append((l, r, win))
	for i in results3(n, tList):
		print(i, end=' ')
readinput()


(n, m) = map(int, input().split())
ans = [0] * n
a = [i for i in range(2, n + 5)]
for _ in range(m):
	(l, r, w) = map(int, input().split())
	b = l
	while b <= r:
		if ans[b - 1] == 0 and b != w:
			ans[b - 1] = w
		nxt = a[b - 1]
		if b < w:
			a[b - 1] = w
		else:
			a[b - 1] = r + 1
		b = nxt
print(*ans)


def main():
	mode = 'filee'
	if mode == 'file':
		f = open('test.txt', 'r')
	get = lambda : [int(x) for x in (f.readline() if mode == 'file' else input()).split()]
	[n, m] = get()
	k = [0 for i in range(n)]
	g = [z + 1 for z in range(n + 1)]
	for i in range(m):
		[m, n, p] = get()
		j = m - 1
		while j <= n - 1:
			if k[j] == 0 and j != p - 1:
				k[j] = p
			tmp = g[j]
			if j < p - 1:
				g[j] = p - 1
			else:
				g[j] = n
			j = tmp
	for i in k:
		print(i, end=' ')
	if mode == 'file':
		f.close()

def __starting_point():
	main()
__starting_point()


inp = lambda : map(int, input().split())
(n, m) = inp()
link = [i + 1 for i in range(n + 3)]
ans = [0] * (n + 1)
for _ in range(m):
	(l, r, x) = inp()
	pt = l
	while pt <= r:
		if ans[pt] == 0 and pt != x:
			ans[pt] = x
		nxt = link[pt]
		if pt < x:
			link[pt] = x
		else:
			link[pt] = r + 1
		pt = nxt
print(*ans[1:])


import os
import sys
from io import BytesIO, IOBase

def main():
	(n, m) = map(int, input().split())
	ans = [0] * n
	next = list(range(1, n + 2))
	for _ in range(m):
		(l, r, k) = map(int, input().split())
		l -= 1
		r -= 1
		k -= 1
		ll = l
		if ans[ll] != 0:
			ll = next[ll]
		while ll <= r:
			if ll != k and ans[ll] == 0:
				ans[ll] = k + 1
			temp = next[ll]
			if ll < k:
				next[ll] = k
			else:
				next[ll] = r + 1
			ll = temp
	print(*ans)
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


(nKnights, nFights) = map(int, input().split())
anext = [i + 1 for i in range(nKnights + 1)]
result = [0] * nKnights
for _ in range(nFights):
	(l, r, x) = map(int, input().split())
	i = l
	while i <= r:
		if result[i - 1] == 0 and i != x:
			result[i - 1] = x
		temp = anext[i]
		if i < x:
			anext[i] = x
		else:
			anext[i] = r + 1
		i = temp
print(*result)


import sys
input = sys.stdin.readline
from bisect import bisect_left as lower_bound, bisect_right as upper_bound

class FenwickTree:

	def __init__(self, x):
		self.bit = []
		self.build(x)

	def build(self, x):
		self.bit[:] = x
		bit = self.bit
		size = self.size = len(x)
		for i in range(size):
			j = i | i + 1
			if j < size:
				bit[j] += bit[i]

	def update(self, idx, x):
		while idx < self.size:
			self.bit[idx] += x
			idx |= idx + 1

	def __call__(self, end):
		x = 0
		while end:
			x += self.bit[end - 1]
			end &= end - 1
		return x

	def find_kth(self, k):
		idx = -1
		for d in reversed(range(self.size.bit_length())):
			right_idx = idx + (1 << d)
			if right_idx < self.size and self.bit[right_idx] <= k:
				idx = right_idx
				k -= self.bit[idx]
		return (idx + 1, k)
block_size = 700

class blocksorter:

	def __init__(self):
		self.macro = []
		self.micros = [[]]
		self.micro_size = [0]
		self.fenwick = FenwickTree([0])
		self.size = 0

	def lower_bound(self, x):
		i = lower_bound(self.macro, x)
		i -= i and self.micro_size[i - 1] and (x <= self.micros[i - 1][-1])
		return self.fenwick(i) + lower_bound(self.micros[i], x)

	def upper_bound(self, x):
		i = upper_bound(self.macro, x)
		i -= i and self.micro_size[i - 1] and (x < self.micros[i - 1][-1])
		return self.fenwick(i) + upper_bound(self.micros[i], x)

	def insert(self, x):
		(i, j) = self._lower_bound(x)
		self.micros[i].insert(j, x)
		self.size += 1
		self.micro_size[i] += 1
		self.fenwick.update(i, 1)
		if len(self.micros[i]) >= block_size:
			self.micros[i:i + 1] = (self.micros[i][:block_size >> 1], self.micros[i][block_size >> 1:])
			self.micro_size[i:i + 1] = (block_size >> 1, block_size >> 1)
			self.fenwick.build(self.micro_size)
			self.macro[i:i + 1] = (self.micros[i][0], self.micros[i + 1][0])
			if len(self.micros) == len(self.macro):
				self.macro.pop()

	def __delitem__(self, k):
		(i, j) = self.find_kth(k)
		del self.micros[i][j]
		self.size -= 1
		self.micro_size[i] -= 1
		self.fenwick.update(i, -1)
		if 1 < i + 1 < len(self.micro_size) and self.micro_size[i - 1] + self.micro_size[i] + self.micro_size[i + 1] < block_size:
			self.micros[i - 1] += self.micros[i]
			self.micros[i - 1] += self.micros[i + 1]
			self.micro_size[i - 1] += self.micro_size[i] + self.micro_size[i + 1]
			del self.macro[i - 1:i + 1], self.micros[i:i + 2], self.micro_size[i:i + 2]
			self.fenwick.build(self.micro_size)

	def __getitem__(self, k):
		(i, j) = self.find_kth(k)
		return self.micros[i][j]

	def __len__(self):
		return self.size

	def __contains__(self, x):
		(i, j) = self._lower_bound(x)
		return j < len(self.micros[i]) and self.micros[i][j] == x

	def find_kth(self, k):
		if k < 0:
			k += self.size
		(i, j) = self.fenwick.find_kth(k)
		return (i, j) if j < len(self.micros[i]) else (i - 1, -1)

	def _lower_bound(self, x):
		i = lower_bound(self.macro, x)
		i -= i and self.micro_size[i - 1] and (x <= self.micros[i - 1][-1])
		return (i, lower_bound(self.micros[i], x))
(n, m) = [int(x) for x in input().split()]
BS = blocksorter()
for i in range(1, n + 1):
	BS.insert(i)
beat = [0] * n
for _ in range(m):
	(l, r, x) = [int(x) for x in input().split()]
	for ind in reversed(range(BS.lower_bound(l), BS.upper_bound(r))):
		if BS[ind] != x:
			beat[BS[ind] - 1] = x
			del BS[ind]
print(*beat)


def ans():
	(n, m) = map(int, input().split())
	(res, alive) = ([0] * n, [i + 1 for i in range(n + 2)])
	from sys import stdin
	for _ in range(m):
		(l, r, x) = map(int, stdin.readline().split())
		i = l
		while i <= r:
			if res[i - 1] == 0 and i != x:
				res[i - 1] = x
			temp = alive[i]
			if i < x:
				alive[i] = x
			else:
				alive[i] = r + 1
			i = temp
	print(*res)
ans()


def main():
	(n, m) = map(int, input().split())
	(alive, winner) = (list(range(1, n + 3)), [0] * (n + 2))
	for _ in range(m):
		(l, r, x) = map(int, input().split())
		while l < x:
			if winner[l]:
				(alive[l], l) = (x, alive[l])
			else:
				alive[l] = winner[l] = x
				l += 1
		l += 1
		r += 1
		while winner[r]:
			r = alive[r]
		while l < r:
			if winner[l]:
				(alive[l], l) = (r, alive[l])
			else:
				(alive[l], winner[l]) = (r, x)
				l += 1
	print(' '.join(map(str, winner[1:-1])))
main()


import math, sys

def yes():
	print('YES')

def no():
	print('NO')

def I():
	return int(sys.stdin.readline())

def In():
	return map(int, sys.stdin.readline().split())

def Sn():
	return sys.stdin.readline().strip()

def dict(a):
	d = {}
	for x in a:
		if d.get(x, -1) != -1:
			d[x] += 1
		else:
			d[x] = 1
	return d

def find_gt(a, x):
	i = bi.bisect_left(a, x)
	if i != len(a):
		return i
	else:
		return -1

def update(bit, pos, val):
	while pos <= n:
		bit[pos] += val
		pos = (pos | pos - 1) + 1

def getsum(bit, x):
	su = 0
	while x > 0:
		su += bit[x]
		x &= x - 1
	return su

def main():
	try:
		global n
		(n, nQ) = In()
		bit = [0 for x in range(n + 1)]
		ans = [0 for x in range(n + 1)]
		for i in range(1, n + 1):
			update(bit, i, 1)
		for i in range(nQ):
			(fr, to, win) = In()
			dec = getsum(bit, fr - 1)
			add = getsum(bit, to)
			while add > dec:
				(a, b) = (fr, to)
				while a < b:
					mid = a + b >> 1
					if getsum(bit, mid) == dec:
						a = mid + 1
					else:
						b = mid
				ans[a] = win
				update(bit, a, -1)
				add -= 1
			ans[win] = 0
			update(bit, win, 1)
		print(*ans[1:])
	except:
		pass
M = 998244353
P = 1000000007
for _ in range(1):
	main()


def prog():
	(n, m) = map(int, input().split())
	(res, anext) = ([0] * n, [i + 1 for i in range(n + 2)])
	from sys import stdin
	for _ in range(m):
		(l, r, x) = map(int, stdin.readline().split())
		i = l
		while i <= r:
			if res[i - 1] == 0 and i != x:
				res[i - 1] = x
			save = anext[i]
			if i < x:
				anext[i] = x
			else:
				anext[i] = anext[r]
			i = save
	print(*res)
prog()


(n, m) = (int(k) for k in input().split())
list_nxt = [i + 1 for i in range(n + 1)]
result = [0] * n
for line in range(m):
	(l, r, x) = (int(k) for k in input().split())
	pt = l
	while pt <= r:
		if result[pt - 1] == 0 and pt != x:
			result[pt - 1] = x
		nxt = list_nxt[pt]
		if pt < x:
			list_nxt[pt] = x
		else:
			list_nxt[pt] = r + 1
		pt = nxt
print(*result)


from sys import stdin, stdout, setrecursionlimit
from collections import deque, defaultdict, Counter
from heapq import heappush, heappop
import math
rl = lambda : stdin.readline()
rll = lambda : stdin.readline().split()
rli = lambda : map(int, stdin.readline().split())
rlf = lambda : map(float, stdin.readline().split())
(INF, NINF) = (float('inf'), float('-inf'))

class SegTree:

	def __init__(self, size):
		self.n = size
		self.T = [[INF, INF] for _ in range(4 * self.n)]

	def _update_range(self, v, tl, tr, l, r, val):
		if l > r or tl > tr:
			return
		if l == tl and r == tr:
			if self.T[v] == [INF, INF]:
				self.T[v] = val
		else:
			mid = (tl + tr) // 2
			self._update_range(2 * v, tl, mid, l, min(r, mid), val)
			self._update_range(2 * v + 1, mid + 1, tr, max(l, mid + 1), r, val)

	def update_range(self, l, r, val):
		self._update_range(1, 0, self.n - 1, l, r, val)

	def qry(self, index):
		return self._qry(1, 0, self.n - 1, index)

	def _qry(self, v, tl, tr, index):
		if tl == tr:
			if self.T[v]:
				return self.T[v]
			else:
				return (INF, INF)
		else:
			mid = (tl + tr) // 2
			(curr_x, curr_time) = (INF, INF)
			if self.T[v]:
				(curr_x, curr_time) = self.T[v]
			if index <= mid:
				(prev_x, prev_time) = self._qry(2 * v, tl, mid, index)
			else:
				(prev_x, prev_time) = self._qry(2 * v + 1, mid + 1, tr, index)
			if curr_time < prev_time:
				return (curr_x, curr_time)
			else:
				return (prev_x, prev_time)

def main():
	(n, m) = rli()
	ans = [0 for _ in range(n)]
	ST = SegTree(n)
	for time in range(m):
		(l, r, x) = rli()
		l -= 1
		r -= 1
		x -= 1
		ST.update_range(l, x - 1, (x, time))
		ST.update_range(x + 1, r, (x, time))
	for i in range(n):
		(k, _) = ST.qry(i)
		ans[i] = k + 1 if k < INF else 0
	print(' '.join((str(x) for x in ans)))
	stdout.close()

def __starting_point():
	main()
__starting_point()


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))

def input():
	return sys.stdin.readline().rstrip('\r\n')

class SegmentTree:

	def __init__(self, n):
		self.tree = [0] * (2 * n)
		self.n = n

	def query(self, l, r, val):
		l += self.n
		r += self.n
		while l < r:
			if l % 2 == 1:
				self.tree[l] = val
				l += 1
			if r % 2 == 1:
				r -= 1
				self.tree[r] = val
			l //= 2
			r //= 2

	def search(self, idx):
		idx += self.n
		res = [0, 0]
		while idx > 1:
			if self.tree[idx] and self.tree[idx][1] >= res[1]:
				res = self.tree[idx].copy()
			idx //= 2
		return res

def solve1(n, fights):
	ans = [0] * (n + 1)
	tree = SegmentTree(n)
	c = 0
	for (l, r, x) in fights[::-1]:
		tree.query(l - 1, x - 1, [x, c])
		tree.query(x, r, [x, c])
		c += 1
	for i in range(n):
		if fights[-1][2] != i + 1:
			ans[i + 1] = tree.search(i)[0]
	return ans[1:]

def solve2(n, fights):
	ans = [0] * (n + 2)
	nxt = list(range(1, n + 3))
	for (l, r, x) in fights:
		while l < x:
			if ans[l]:
				k = nxt[l]
				nxt[l] = x
				l = k
			else:
				nxt[l] = x
				ans[l] = x
				l += 1
		l += 1
		r += 1
		while ans[r]:
			r = nxt[r]
		while l < r:
			if ans[l]:
				k = nxt[l]
				nxt[l] = r
				l = k
			else:
				nxt[l] = r
				ans[l] = x
				l += 1
	return ans[1:-1]

def read():
	return list(map(int, input().split()))

def main():
	(n, m) = read()
	fights = [read() for _ in range(m)]
	ans = solve1(n, fights)
	print(*ans)
main()


import sys
from functools import lru_cache, cmp_to_key
from heapq import merge, heapify, heappop, heappush
from math import *
from collections import defaultdict as dd, deque, Counter as C
from itertools import combinations as comb, permutations as perm
from bisect import bisect_left as bl, bisect_right as br, bisect
from time import perf_counter
from fractions import Fraction
import copy
import time
starttime = time.time()
mod = int(pow(10, 9) + 7)
mod2 = 998244353

def data():
	return sys.stdin.readline().strip()

def out(*var, end='\n'):
	sys.stdout.write(' '.join(map(str, var)) + end)

def L():
	return list(sp())

def sl():
	return list(ssp())

def sp():
	return map(int, data().split())

def ssp():
	return map(str, data().split())

def l1d(n, val=0):
	return [val for i in range(n)]

def l2d(n, m, val=0):
	return [l1d(n, val) for j in range(m)]
try:
	sys.stdin = open('input.txt', 'r')
except:
	pass

def pmat(A):
	for ele in A:
		print(*ele, end='\n')

def seive():
	prime = [1 for i in range(10 ** 6 + 1)]
	prime[0] = 0
	prime[1] = 0
	for i in range(10 ** 6 + 1):
		if prime[i]:
			for j in range(2 * i, 10 ** 6 + 1, i):
				prime[j] = 0
	return prime
(n, m) = map(int, input().split())
(res, anext) = ([0] * n, [i + 1 for i in range(n + 2)])
from sys import stdin
for _ in range(m):
	(l, r, x) = map(int, stdin.readline().split())
	i = l
	while i <= r:
		if res[i - 1] == 0 and i != x:
			res[i - 1] = x
		save = anext[i]
		if i < x:
			anext[i] = x
		else:
			anext[i] = r + 1
		i = save
print(*res)
endtime = time.time()


import os, sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from types import GeneratorType

def iterative(f, stack=[]):

	def wrapped_func(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		to = f(*args, **kwargs)
		while True:
			if type(to) is GeneratorType:
				stack.append(to)
				to = next(to)
				continue
			stack.pop()
			if not stack:
				break
			to = stack[-1].send(to)
		return to
	return wrapped_func

@iterative
def build_segment(a, tree, i_tree, right, left):
	if right == left:
		tree[i_tree] = a[right]
	else:
		mid = (right + left) // 2
		yield build_segment(a, tree, 2 * i_tree, right, mid)
		yield build_segment(a, tree, 2 * i_tree + 1, mid + 1, left)

@iterative
def querry(a, tree, i_tree, left, right, ql, qr, x):
	if right == left and a[right] == 0:
		if not ql <= right <= qr or x == right + 1:
			yield tree[i_tree]
		else:
			a[right] = x
			tree[i_tree] = 1
			yield 1
	if qr < left or ql > right:
		yield tree[i_tree]
	if ql <= left and right <= qr:
		if tree[i_tree]:
			yield 1
		else:
			mid = (right + left) // 2
			yield querry(a, tree, 2 * i_tree, left, mid, ql, qr, x)
			yield querry(a, tree, 2 * i_tree + 1, mid + 1, right, ql, qr, x)
			tree[i_tree] = min(tree[2 * i_tree], tree[i_tree * 2 + 1])
			yield tree[i_tree]
	else:
		mid = (right + left) // 2
		yield querry(a, tree, 2 * i_tree, left, mid, ql, qr, x)
		yield querry(a, tree, 2 * i_tree + 1, mid + 1, right, ql, qr, x)
		tree[i_tree] = min(tree[2 * i_tree], tree[i_tree * 2 + 1])
		yield tree[i_tree]
(n, m) = map(int, input().split())
a = [0] * n
t = [0] * (4 * n + 1)
ck = []
for _ in range(m):
	(l, r, x) = map(int, input().split())
	l -= 1
	r -= 1
	if ck:
		(l1, r1, x1) = ck[-1]
		if x1 == x:
			l1 = min(l1, l)
			r1 = max(r1, r)
			ck[-1] = [l1, r1, x]
		else:
			ck.append([l, r, x])
	else:
		ck.append([l, r, x])
for i in ck:
	(l, r, x) = i
	querry(a, t, 1, 0, n - 1, l, r, x)
print(*a)


import os
import sys
from io import BytesIO, IOBase
import heapq as h
from bisect import bisect_left
from types import GeneratorType
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		import os
		self.os = os
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = self.os.read(self._fd, max(self.os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = self.os.read(self._fd, max(self.os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			self.os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
import time
start_time = time.time()
import collections as col
import math, string
from functools import reduce

def getInts():
	return [int(s) for s in input().split()]

def getInt():
	return int(input())

def getStrs():
	return [s for s in input().split()]

def getStr():
	return input()

def listStr():
	return list(input())

class SortedList:

	def __init__(self, iterable=[], _load=200):
		values = sorted(iterable)
		self._len = _len = len(values)
		self._load = _load
		self._lists = _lists = [values[i:i + _load] for i in range(0, _len, _load)]
		self._list_lens = [len(_list) for _list in _lists]
		self._mins = [_list[0] for _list in _lists]
		self._fen_tree = []
		self._rebuild = True

	def _fen_build(self):
		self._fen_tree[:] = self._list_lens
		_fen_tree = self._fen_tree
		for i in range(len(_fen_tree)):
			if i | i + 1 < len(_fen_tree):
				_fen_tree[i | i + 1] += _fen_tree[i]
		self._rebuild = False

	def _fen_update(self, index, value):
		if not self._rebuild:
			_fen_tree = self._fen_tree
			while index < len(_fen_tree):
				_fen_tree[index] += value
				index |= index + 1

	def _fen_query(self, end):
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		x = 0
		while end:
			x += _fen_tree[end - 1]
			end &= end - 1
		return x

	def _fen_findkth(self, k):
		_list_lens = self._list_lens
		if k < _list_lens[0]:
			return (0, k)
		if k >= self._len - _list_lens[-1]:
			return (len(_list_lens) - 1, k + _list_lens[-1] - self._len)
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		idx = -1
		for d in reversed(range(len(_fen_tree).bit_length())):
			right_idx = idx + (1 << d)
			if right_idx < len(_fen_tree) and k >= _fen_tree[right_idx]:
				idx = right_idx
				k -= _fen_tree[idx]
		return (idx + 1, k)

	def _delete(self, pos, idx):
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len -= 1
		self._fen_update(pos, -1)
		del _lists[pos][idx]
		_list_lens[pos] -= 1
		if _list_lens[pos]:
			_mins[pos] = _lists[pos][0]
		else:
			del _lists[pos]
			del _list_lens[pos]
			del _mins[pos]
			self._rebuild = True

	def _loc_left(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(lo, pos) = (-1, len(_lists) - 1)
		while lo + 1 < pos:
			mi = lo + pos >> 1
			if value <= _mins[mi]:
				pos = mi
			else:
				lo = mi
		if pos and value <= _lists[pos - 1][-1]:
			pos -= 1
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value <= _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def _loc_right(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(pos, hi) = (0, len(_lists))
		while pos + 1 < hi:
			mi = pos + hi >> 1
			if value < _mins[mi]:
				hi = mi
			else:
				pos = mi
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value < _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def add(self, value):
		_load = self._load
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len += 1
		if _lists:
			(pos, idx) = self._loc_right(value)
			self._fen_update(pos, 1)
			_list = _lists[pos]
			_list.insert(idx, value)
			_list_lens[pos] += 1
			_mins[pos] = _list[0]
			if _load + _load < len(_list):
				_lists.insert(pos + 1, _list[_load:])
				_list_lens.insert(pos + 1, len(_list) - _load)
				_mins.insert(pos + 1, _list[_load])
				_list_lens[pos] = _load
				del _list[_load:]
				self._rebuild = True
		else:
			_lists.append([value])
			_mins.append(value)
			_list_lens.append(1)
			self._rebuild = True

	def discard(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_right(value)
			if idx and _lists[pos][idx - 1] == value:
				self._delete(pos, idx - 1)

	def remove(self, value):
		_len = self._len
		self.discard(value)
		if _len == self._len:
			raise ValueError('{0!r} not in list'.format(value))

	def pop(self, index=-1):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		value = self._lists[pos][idx]
		self._delete(pos, idx)
		return value

	def bisect_left(self, value):
		(pos, idx) = self._loc_left(value)
		return self._fen_query(pos) + idx

	def bisect_right(self, value):
		(pos, idx) = self._loc_right(value)
		return self._fen_query(pos) + idx

	def count(self, value):
		return self.bisect_right(value) - self.bisect_left(value)

	def __len__(self):
		return self._len

	def __getitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		return self._lists[pos][idx]

	def __delitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		self._delete(pos, idx)

	def __contains__(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_left(value)
			return idx < len(_lists[pos]) and _lists[pos][idx] == value
		return False

	def __iter__(self):
		return (value for _list in self._lists for value in _list)

	def __reversed__(self):
		return (value for _list in reversed(self._lists) for value in reversed(_list))

	def __repr__(self):
		return 'SortedList({0})'.format(list(self))

def solve():
	(N, M) = getInts()
	S = SortedList([j + 1 for j in range(N)])
	ans = [0 for j in range(N)]
	for m in range(M):
		(L, R, X) = getInts()
		idx = S.bisect_left(L)
		while idx < len(S):
			val = S[idx]
			if val > R:
				break
			if val != X:
				S.remove(val)
				ans[val - 1] = X
			else:
				idx += 1
	print(*ans)
solve()


import os
import sys
from atexit import register
from io import StringIO
sys.stdout = StringIO()
register(lambda : os.write(1, sys.stdout.getvalue().encode()))
import math
(n, m) = [int(k) for k in input().split()]
t = [0] * (4 * n)

def update(x, l, r, v, tl, tr):
	if r < l:
		return
	if t[v] != 0:
		return
	if l == tl and r == tr:
		t[v] = x
	else:
		tm = tl + tr >> 1
		update(x, l, min(tm, r), 2 * v, tl, tm)
		update(x, max(tm + 1, l), r, 2 * v + 1, tm + 1, tr)

def query(i):
	v = 1
	tl = 1
	tr = n
	while tl != tr:
		tm = tl + tr >> 1
		if i <= tm:
			v = v << 1
			tr = tm
		else:
			v = (v << 1) + 1
			tl = tm + 1
	k = 0
	while v != 0:
		k = k or t[v]
		v = v >> 1
	return k
for _ in range(m):
	(l, r, x) = [int(k) for k in input().split()]
	update(x, l, x - 1, 1, 1, n)
	update(x, x + 1, r, 1, 1, n)
print(' '.join([str(query(k)) for k in range(1, n + 1)]))


from sys import stdout, stdin
st = lambda : list(stdin.readline().strip())
li = lambda : list(map(int, stdin.readline().split()))
mp = lambda : map(int, stdin.readline().split())
inp = lambda : int(stdin.readline())
pr = lambda n: stdout.write(str(n) + '\n')
import bisect
case = li()
ans = [0 for i in range(case[0])]
nextl = [i + 1 for i in range(case[0] + 2)]
for j in range(case[1]):
	f = li()
	i = f[0]
	while i <= f[1]:
		if ans[i - 1] == 0 and i != f[2]:
			ans[i - 1] = f[2]
		a = nextl[i]
		if i < f[2]:
			nextl[i] = f[2]
		else:
			nextl[i] = f[1] + 1
		i = a
print(*ans)


def solve3(n, fights):
	ans = [0] * n
	a = [i for i in range(2, n + 5)]
	for (l, r, w) in fights:
		b = l
		while b <= r:
			if ans[b - 1] == 0 and b != w:
				ans[b - 1] = w
			nxt = a[b - 1]
			if b < w:
				a[b - 1] = w
			else:
				a[b - 1] = r + 1
			b = nxt
	return ans

def read():
	return list(map(int, input().split()))

def main():
	(n, m) = read()
	fights = [read() for _ in range(m)]
	ans = solve3(n, fights)
	print(*ans)
main()


import sys
I = lambda : int(input())
readline = lambda : sys.stdin.readline().strip('\n')
RM = readmap = lambda x=int: list(map(x, readline().split(' ')))
(n, m) = RM()
conq = ['0'] * (n + 1)
nxt = list(range(1, n + 2))
for _ in range(m):
	(l, r, m) = RM()
	cur = l
	while cur <= r:
		if conq[cur] == '0' and cur != m:
			conq[cur] = str(m)
		nx = nxt[cur]
		nxt[cur] = [r + 1, m][cur < m]
		cur = nx
print(' '.join(conq[1:]))


import os
import sys
from io import BytesIO, IOBase
import math
from decimal import Decimal
from decimal import *
from collections import defaultdict, deque
import heapq
from decimal import Decimal
getcontext().prec = 25
abcd = 'abcdefghijklmnopqrstuvwxyz'
MOD = pow(10, 9) + 7
BUFSIZE = 8192
from bisect import bisect_left, bisect_right

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
(n, m) = map(int, input().split(' '))
ans = [0] * n
check = [i + 1 for i in range(n + 2)]
for i in range(m):
	(l, r, x) = map(int, input().split(' '))
	i = l
	while i <= r:
		if ans[i - 1] == 0 and i != x:
			ans[i - 1] = x
		v = check[i]
		if i < x:
			check[i] = x
		else:
			check[i] = r + 1
		i = v
print(*ans)


import sys, os, io

def rs():
	return sys.stdin.readline().rstrip()

def ri():
	return int(sys.stdin.readline())

def ria():
	return list(map(int, sys.stdin.readline().split()))

def ws(s):
	sys.stdout.write(s + '\n')

def wi(n):
	sys.stdout.write(str(n) + '\n')

def wia(a):
	sys.stdout.write(' '.join([str(x) for x in a]) + '\n')
import math, datetime, functools, itertools, operator, bisect, fractions, statistics
from collections import deque, defaultdict, OrderedDict, Counter
from fractions import Fraction
from decimal import Decimal
from sys import stdout
from heapq import heappush, heappop, heapify, _heapify_max, _heappop_max, nsmallest, nlargest
sys.setrecursionlimit(111111)
INF = 99999999999999999999999999999999

class SortedList:

	def __init__(self, iterable=[], _load=200):
		values = sorted(iterable)
		self._len = _len = len(values)
		self._load = _load
		self._lists = _lists = [values[i:i + _load] for i in range(0, _len, _load)]
		self._list_lens = [len(_list) for _list in _lists]
		self._mins = [_list[0] for _list in _lists]
		self._fen_tree = []
		self._rebuild = True

	def _fen_build(self):
		self._fen_tree[:] = self._list_lens
		_fen_tree = self._fen_tree
		for i in range(len(_fen_tree)):
			if i | i + 1 < len(_fen_tree):
				_fen_tree[i | i + 1] += _fen_tree[i]
		self._rebuild = False

	def _fen_update(self, index, value):
		if not self._rebuild:
			_fen_tree = self._fen_tree
			while index < len(_fen_tree):
				_fen_tree[index] += value
				index |= index + 1

	def _fen_query(self, end):
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		x = 0
		while end:
			x += _fen_tree[end - 1]
			end &= end - 1
		return x

	def _fen_findkth(self, k):
		_list_lens = self._list_lens
		if k < _list_lens[0]:
			return (0, k)
		if k >= self._len - _list_lens[-1]:
			return (len(_list_lens) - 1, k + _list_lens[-1] - self._len)
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		idx = -1
		for d in reversed(range(len(_fen_tree).bit_length())):
			right_idx = idx + (1 << d)
			if right_idx < len(_fen_tree) and k >= _fen_tree[right_idx]:
				idx = right_idx
				k -= _fen_tree[idx]
		return (idx + 1, k)

	def _delete(self, pos, idx):
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len -= 1
		self._fen_update(pos, -1)
		del _lists[pos][idx]
		_list_lens[pos] -= 1
		if _list_lens[pos]:
			_mins[pos] = _lists[pos][0]
		else:
			del _lists[pos]
			del _list_lens[pos]
			del _mins[pos]
			self._rebuild = True

	def _loc_left(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(lo, pos) = (-1, len(_lists) - 1)
		while lo + 1 < pos:
			mi = lo + pos >> 1
			if value <= _mins[mi]:
				pos = mi
			else:
				lo = mi
		if pos and value <= _lists[pos - 1][-1]:
			pos -= 1
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value <= _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def _loc_right(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(pos, hi) = (0, len(_lists))
		while pos + 1 < hi:
			mi = pos + hi >> 1
			if value < _mins[mi]:
				hi = mi
			else:
				pos = mi
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value < _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def add(self, value):
		_load = self._load
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len += 1
		if _lists:
			(pos, idx) = self._loc_right(value)
			self._fen_update(pos, 1)
			_list = _lists[pos]
			_list.insert(idx, value)
			_list_lens[pos] += 1
			_mins[pos] = _list[0]
			if _load + _load < len(_list):
				_lists.insert(pos + 1, _list[_load:])
				_list_lens.insert(pos + 1, len(_list) - _load)
				_mins.insert(pos + 1, _list[_load])
				_list_lens[pos] = _load
				del _list[_load:]
				self._rebuild = True
		else:
			_lists.append([value])
			_mins.append(value)
			_list_lens.append(1)
			self._rebuild = True

	def discard(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_right(value)
			if idx and _lists[pos][idx - 1] == value:
				self._delete(pos, idx - 1)

	def remove(self, value):
		_len = self._len
		self.discard(value)
		if _len == self._len:
			raise ValueError('{0!r} not in list'.format(value))

	def pop(self, index=-1):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		value = self._lists[pos][idx]
		self._delete(pos, idx)
		return value

	def bisect_left(self, value):
		(pos, idx) = self._loc_left(value)
		return self._fen_query(pos) + idx

	def bisect_right(self, value):
		(pos, idx) = self._loc_right(value)
		return self._fen_query(pos) + idx

	def count(self, value):
		return self.bisect_right(value) - self.bisect_left(value)

	def __len__(self):
		return self._len

	def __getitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		return self._lists[pos][idx]

	def __delitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		self._delete(pos, idx)

	def __contains__(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_left(value)
			return idx < len(_lists[pos]) and _lists[pos][idx] == value
		return False

	def __iter__(self):
		return (value for _list in self._lists for value in _list)

	def __reversed__(self):
		return (value for _list in reversed(self._lists) for value in reversed(_list))

	def __repr__(self):
		return 'SortedList({0})'.format(list(self))

def main():
	mod = 1000000007
	starttime = datetime.datetime.now()
	if os.path.exists('input.txt'):
		sys.stdin = open('input.txt', 'r')
		sys.stdout = open('output.txt', 'w')
	tc = 1
	for _ in range(tc):
		(n, m) = ria()
		parent = {}
		a = [i for i in range(1, n + 1)]
		sorted_list = SortedList(a)
		for i in range(m):
			(l, r, x) = ria()
			pos = bisect.bisect_left(sorted_list, l)
			while pos < len(sorted_list) and sorted_list[pos] <= r:
				k = sorted_list[pos]
				if k != x:
					parent[k] = x
					sorted_list.discard(k)
				else:
					pos += 1
		ans = []
		for i in range(1, n + 1):
			if i not in parent:
				ans += [0]
			else:
				ans += [parent[i]]
		wia(ans)
	endtime = datetime.datetime.now()
	time = (endtime - starttime).total_seconds() * 1000
	if os.path.exists('input.txt'):
		print('Time:', time, 'ms')

class FastReader(io.IOBase):
	newlines = 0

	def __init__(self, fd, chunk_size=1024 * 8):
		self._fd = fd
		self._chunk_size = chunk_size
		self.buffer = io.BytesIO()

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, self._chunk_size))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self, size=-1):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, self._chunk_size if size == -1 else size))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

class FastWriter(io.IOBase):

	def __init__(self, fd):
		self._fd = fd
		self.buffer = io.BytesIO()
		self.write = self.buffer.write

	def flush(self):
		os.write(self._fd, self.buffer.getvalue())
		(self.buffer.truncate(0), self.buffer.seek(0))

class FastStdin(io.IOBase):

	def __init__(self, fd=0):
		self.buffer = FastReader(fd)
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

class FastStdout(io.IOBase):

	def __init__(self, fd=1):
		self.buffer = FastWriter(fd)
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.flush = self.buffer.flush
sys.stdin = FastStdin()
sys.stdout = FastStdout()
main()


(n, m) = (int(x) for x in input().split())
results = [0] * n
pointers = [k for k in range(2, n + 2)]
for i in range(m):
	(l, r, x) = [int(k) for k in input().split()]
	while l <= r:
		if l != x and results[l - 1] == 0:
			results[l - 1] = x
		nxt = pointers[l - 1]
		if l < x:
			pointers[l - 1] = x
		else:
			pointers[l - 1] = r + 1
		l = nxt
print(*results)


import sys
input = sys.stdin.readline
import math
sys.setrecursionlimit(300005)

def update(p, l, r, s, e, x):
	if l > e or r < s:
		return
	if l <= s and r >= e:
		if st[p] == None:
			st[p] = x
		return
	m = (s + e) // 2
	if st[2 * p] == None:
		st[2 * p] = st[p]
	if st[2 * p + 1] == None:
		st[2 * p + 1] = st[p]
	update(2 * p, l, r, s, m, x)
	update(2 * p + 1, l, r, m + 1, e, x)

def func(p, s, e):
	if s == e:
		if st[p] == None:
			ans[s] = 0
		else:
			ans[s] = st[p] + 1
		return
	m = (s + e) // 2
	if st[2 * p] == None:
		st[2 * p] = st[p]
	if st[2 * p + 1] == None:
		st[2 * p + 1] = st[p]
	func(2 * p, s, m)
	func(2 * p + 1, m + 1, e)
(n, m) = map(int, input().split())
x = math.ceil(math.log(n, 2)) + 1
L = 1 << x
st = [None] * L
for i in range(m):
	(l, r, x) = map(int, input().split())
	l = l - 1
	r = r - 1
	x = x - 1
	if x > l:
		update(1, l, x - 1, 0, n - 1, x)
	if x < r:
		update(1, x + 1, r, 0, n - 1, x)
ans = [0] * n
func(1, 0, n - 1)
print(*ans)


class SegmentTree:

	def __init__(self, n):
		self.tree = [0] * (2 * n)
		self.n = n

	def query(self, l, r, val):
		l += self.n
		r += self.n
		while l < r:
			if l % 2 == 1:
				self.tree[l] = val
				l += 1
			if r % 2 == 1:
				r -= 1
				self.tree[r] = val
			l //= 2
			r //= 2

	def search(self, idx):
		idx += self.n
		res = [0, 0]
		while idx > 1:
			if self.tree[idx] and self.tree[idx][1] >= res[1]:
				res = self.tree[idx].copy()
			idx //= 2
		return res

def solve1(n, fights):
	ans = [0] * (n + 1)
	tree = SegmentTree(n)
	c = 0
	for (l, r, x) in fights[::-1]:
		tree.query(l - 1, x - 1, [x, c])
		tree.query(x, r, [x, c])
		c += 1
	for i in range(n):
		if fights[-1][2] != i + 1:
			ans[i + 1] = tree.search(i)[0]
	return ans[1:]

def solve2(n, fights):
	ans = [0] * (n + 2)
	nxt = list(range(1, n + 3))
	for (l, r, x) in fights:
		while l < x:
			if ans[l]:
				k = nxt[l]
				nxt[l] = x
				l = k
			else:
				nxt[l] = x
				ans[l] = x
				l += 1
		l += 1
		r += 1
		while ans[r]:
			r = nxt[r]
		while l < r:
			if ans[l]:
				k = nxt[l]
				nxt[l] = r
				l = k
			else:
				nxt[l] = r
				ans[l] = x
				l += 1
	return ans[1:-1]

def read():
	return list(map(int, input().split()))

def main():
	(n, m) = read()
	fights = [read() for _ in range(m)]
	ans = solve1(n, fights)
	print(*ans)
main()


def solve(n, fights):
	ans = [0] * (n + 2)
	nxt = list(range(1, n + 3))
	for (l, r, x) in fights:
		while l < x:
			if ans[l]:
				k = nxt[l]
				nxt[l] = x
				l = k
			else:
				nxt[l] = ans[l] = x
				l += 1
		l += 1
		r += 1
		while ans[r]:
			r = nxt[r]
		while l < r:
			if ans[l]:
				k = nxt[l]
				nxt[l] = r
				l = k
			else:
				nxt[l] = r
				ans[l] = x
				l += 1
	return ans[1:-1]

def read():
	return list(map(int, input().split()))

def main():
	(n, m) = read()
	fights = [read() for _ in range(m)]
	ans = solve(n, fights)
	print(*ans)
main()


from collections import *
from sys import stdin

def arr_inp(n):
	if n == 1:
		return [int(x) for x in stdin.readline().split()]
	elif n == 2:
		return [float(x) for x in stdin.readline().split()]
	else:
		return list(stdin.readline()[:-1])

class segmenttree:

	def __init__(self, arr, n):
		(self.tree, self.n) = ([0] * (2 * n), n)
		if arr:
			for i in range(2 * n - 1, 0, -1):
				if i >= n:
					self.tree[i] = arr[i - n]
				else:
					self.tree[i] = self.tree[i << 1] + self.tree[(i << 1) + 1]

	def query(self, l, r, val):
		res = 0
		l += self.n
		r += self.n
		while l < r:
			if l & 1:
				self.tree[l] = val
				l += 1
			if r & 1:
				r -= 1
				self.tree[r] = val
			l >>= 1
			r >>= 1
		return res

	def search(self, ix):
		ix += self.n
		ret = [0, 0]
		while ix > 1:
			if self.tree[ix] and self.tree[ix][1] >= ret[1]:
				ret = self.tree[ix].copy()
			ix >>= 1
		return ret
(n, m) = map(int, input().split())
(ans, tree) = ([0] * (n + 1), segmenttree([], n))
(quaries, c) = ([arr_inp(1) for i in range(m)], 0)
for (l, r, x) in quaries[::-1]:
	tree.query(l - 1, x - 1, [x, c])
	tree.query(x, r, [x, c])
	c += 1
for i in range(n):
	if quaries[-1][2] != i + 1:
		ans[i + 1] = tree.search(i)[0]
print(*ans[1:])


def solve3(n, fights):
	ans = [0] * n
	nxt = [i for i in range(2, n + 3)]
	for (l, r, w) in fights:
		kidx = l
		while kidx <= r:
			if ans[kidx - 1] == 0 and kidx != w:
				ans[kidx - 1] = w
			k = nxt[kidx - 1]
			nxt[kidx - 1] = w if kidx < w else r + 1
			kidx = k
	return ans

def read():
	return list(map(int, input().split()))

def main():
	(n, m) = read()
	fights = [read() for _ in range(m)]
	ans = solve3(n, fights)
	print(*ans)
main()


import sys
import io
import math
import collections
import decimal
import itertools
import bisect
import heapq

def input():
	return sys.stdin.readline()[:-1]

def query(i):
	k = i + N1
	while k > 0:
		if not Dat[k] is None:
			return Dat[k]
		k //= 2
	return 0
(N, M) = map(int, input().split())
N1 = 2 ** N.bit_length()
Dat = [None for _ in range(2 * N1)]
for _ in range(M):
	(L, R, X) = map(int, input().split())
	L -= 1
	R -= 1
	X -= 1
	for (L1, R1) in [(L, X), (X + 1, R + 1)]:
		if R1 - L1 == 0:
			continue
		stack = []
		stack.append((1, 0, N1))
		while stack:
			(k, l, r) = stack.pop()
			if not Dat[k] is None:
				continue
			if L1 <= l and r <= R1:
				Dat[k] = X + 1
			else:
				if L1 < (l + r) // 2:
					stack.append((k * 2, l, (l + r) // 2))
				if (l + r) // 2 < R1:
					stack.append((k * 2 + 1, (l + r) // 2, r))
print(*[query(i) for i in range(N)])


(n, m) = map(int, input().split())
res = ['0'] * n
arr = [i for i in range(n)]
for _ in range(m):
	(l, r, x) = map(int, input().split())
	(idx, max_idx, path) = (l - 1, r, [])
	while idx < r:
		while idx < n and arr[idx] != idx:
			path.append(idx)
			idx = arr[idx]
		if idx < r and idx != x - 1:
			res[idx] = str(x)
			path.append(idx)
		if idx >= r:
			max_idx = idx
		idx += 1
	for i in path:
		if i < x - 1:
			arr[i] = x - 1
		else:
			arr[i] = max_idx
print(' '.join(res))