Write a program which manipulates a sequence A = {a0, a1, . . . , an−1} with the following operations:

* update(s, t, x): change as, as+1, ..., at to x.
* find(i): output the value of ai.



Note that the initial values of ai (i = 0, 1, . . . , n−1) are 231-1.

Constraints

* 1 ≤ n ≤ 100000
* 1 ≤ q ≤ 100000
* 0 ≤ s ≤ t < n
* 0 ≤ i < n
* 0 ≤ x < 231−1

Input


n q
query1
query2
:
queryq


In the first line, n (the number of elements in A) and q (the number of queries) are given. Then, ith query queryi is given in the following format:


0 s t x


or


1 i


The first digit represents the type of the query. '0' denotes update(s, t, x) and '1' denotes find(i).

Output

For each find operation, print the value.

Examples

Input

3 5
0 0 1 1
0 1 2 3
0 2 2 2
1 0
1 1


Output

1
3


Input

1 3
1 0
0 0 0 5
1 0


Output

2147483647
5

Difficulty: UNKNOWN_DIFFICULTY

Starter code:

Solutions:
import sys

class RangeUpdateQuery:

	def __init__(self, n, initial=2 ** 31 - 1):
		self.n = 1 << (n - 1).bit_length()
		self.INT = (-1, initial)
		self.segtree = [self.INT] * (2 * self.n)

	def update(self, l, r, v):
		(L, R) = (l + self.n, r + self.n)
		while L < R:
			if L & 1:
				self.segtree[L] = v
				L += 1
			if R & 1:
				self.segtree[R - 1] = v
				R -= 1
			L >>= 1
			R >>= 1

	def query(self, i):
		i += self.n
		s = self.INT
		while i > 0:
			s = max(s, self.segtree[i])
			i = i // 2
		return s[1]
(N, Q) = map(int, input().split())
RUQ = RangeUpdateQuery(N)
for q in range(Q):
	query = list(map(int, sys.stdin.readline().split()))
	if query[0] == 0:
		(s, t, x) = query[1:]
		RUQ.update(s, t + 1, (q, x))
	if query[0] == 1:
		i = query[1]
		print(RUQ.query(i))


class SegmentTreeDual:

	def __init__(self, arr, op=lambda x, y: y if y != -1 else x, ie=-1):
		self.h = (len(arr) - 1).bit_length()
		self.n = 2 ** self.h
		self.ie = ie
		self.op = op
		self.val = [ie for _ in range(len(arr))]
		self.laz = [ie for _ in range(2 * self.n)]
		for i in range(len(arr)):
			self.val[i] = arr[i]

	def propagate(self, k):
		if self.laz[k] == self.ie:
			return
		if self.n <= k:
			self.val[k - self.n] = self.op(self.val[k - self.n], self.laz[k])
			self.laz[k] = self.ie
		else:
			self.laz[k << 1] = self.op(self.laz[k << 1], self.laz[k])
			self.laz[(k << 1) + 1] = self.op(self.laz[(k << 1) + 1], self.laz[k])
			self.laz[k] = self.ie

	def update(self, left, right, f):
		left += self.n
		right += self.n
		for i in reversed(range(self.h + 1)):
			self.propagate(left >> i)
		for i in reversed(range(self.h + 1)):
			self.propagate(right - 1 >> i)
		while right - left > 0:
			if right & 1:
				right -= 1
				self.laz[right] = self.op(self.laz[right], f)
			if left & 1:
				self.laz[left] = self.op(self.laz[left], f)
				left += 1
			left >>= 1
			right >>= 1

	def get(self, index):
		res = self.val[index]
		index += self.n
		while index:
			res = self.op(res, self.laz[index])
			index //= 2
		return res
INF = 2 ** 31 - 1
(N, Q) = map(int, input().split())
A = [INF for _ in range(N)]
sg = SegmentTreeDual(A)
ans = []
for _ in range(Q):
	q = list(map(int, input().split()))
	if q[0] == 0:
		(s, t, x) = q[1:]
		sg.update(s, t + 1, x)
	else:
		i = q[1]
		ans.append(sg.get(i))
print('\n'.join(map(str, ans)))


import sys
import math
import time
sys.setrecursionlimit(20000)
INT_MAX = 2 ** 31 - 1

def update(tree, x, y, z, N):
	left = x + N
	right = y + N
	while True:
		if left >= right:
			break
		if right % 2 == 1:
			right -= 1
			tree[right - 1] = z
		if left % 2 == 1:
			tree[left - 1] = z
			left += 1
		left >>= 1
		right >>= 1

def find(tree, x, N):
	x += N - 1
	s = (INT_MAX, -1)
	while True:
		if x < 0:
			break
		if tree[x][0] is not None and tree[x][1] > s[1]:
			s = tree[x]
		x = math.floor((x - 1) / 2)
	return s[0]
(_N, query_num) = map(int, input().split())
N = 1
while True:
	if N >= _N:
		break
	N *= 2
A = [(None, -1)] * (2 * N - 1)
for i in range(query_num):
	query = list(map(int, input().split()))
	if query[0] == 0:
		update(A, query[1], query[2] + 1, (query[3], i), N)
	if query[0] == 1:
		z = find(A, query[1], N)
		print(z)


import math

def lazy_update(s, e, value):
	a = [(1, l + s, l + e, 1)]
	while a:
		(k, s, e, depth) = a.pop()
		(l_end, r_end) = (k << rank - depth, k + 1 << rank - depth)
		mid = (l_end + r_end) // 2
		if s == l_end and e == r_end:
			lazy[k] = value
		else:
			if lazy[k] is not None:
				lazy[k << 1] = lazy[k]
				lazy[(k << 1) + 1] = lazy[k]
				lazy[k] = None
			if s < mid:
				a.append((k << 1, s, min(mid, e), depth + 1))
			if e > mid:
				a.append(((k << 1) + 1, max(mid, s), e, depth + 1))

def get_value(i):
	i += l
	for j in range(rank, -1, -1):
		n = lazy[i >> j]
		if n is not None:
			return n
	return tree[i]
(n, q) = map(int, input().split())
l = 1 << math.ceil(math.log2(n))
tree = [2 ** 31 - 1] * (2 * l)
lazy = [None] * (2 * l)
rank = int(math.log2(len(tree)))
ans = []
ap = ans.append
for _ in [None] * q:
	query = list(map(int, input().split()))
	if query[0] == 0:
		lazy_update(query[1], query[2] + 1, query[3])
	else:
		ap(get_value(query[1]))
print('\n'.join((str(n) for n in ans)))


import sys

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

def list2d(a, b, c):
	return [[c] * b for i in range(a)]

def list3d(a, b, c, d):
	return [[[d] * c for j in range(b)] for i in range(a)]

def list4d(a, b, c, d, e):
	return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]

def ceil(x, y=1):
	return int(-(-x // y))

def INT():
	return int(input())

def MAP():
	return map(int, input().split())

def LIST(N=None):
	return list(MAP()) if N is None else [INT() for i in range(N)]

def Yes():
	print('Yes')

def No():
	print('No')

def YES():
	print('YES')

def NO():
	print('NO')
sys.setrecursionlimit(10 ** 9)
INF = 2 ** 31 - 1
MOD = 10 ** 9 + 7

class SegTreeLazy:

	def __init__(self, N, func, intv):
		self.intv = intv
		self.func = func
		LV = (N - 1).bit_length()
		self.N0 = 2 ** LV
		self.data = [intv] * (2 * self.N0)
		self.lazy = [None] * (2 * self.N0)

	def gindex(self, l, r):
		L = l + self.N0
		R = r + self.N0
		lm = L // (L & -L) >> 1
		rm = R // (R & -R) >> 1
		while L < R:
			if R <= rm:
				yield R
			if L <= lm:
				yield L
			L >>= 1
			R >>= 1
		while L:
			yield L
			L >>= 1

	def propagates(self, *ids):
		for i in reversed(ids):
			v = self.lazy[i - 1]
			if v is None:
				continue
			self.lazy[2 * i - 1] = self.data[2 * i - 1] = self.lazy[2 * i] = self.data[2 * i] = v
			self.lazy[i - 1] = None

	def update(self, l, r, x):
		(*ids,) = self.gindex(l, r)
		self.propagates(*ids)
		L = self.N0 + l
		R = self.N0 + r
		while L < R:
			if R & 1:
				R -= 1
				self.lazy[R - 1] = self.data[R - 1] = x
			if L & 1:
				self.lazy[L - 1] = self.data[L - 1] = x
				L += 1
			L >>= 1
			R >>= 1
		for i in ids:
			self.data[i - 1] = self.func(self.data[2 * i - 1], self.data[2 * i])

	def query(self, l, r):
		self.propagates(*self.gindex(l, r))
		L = self.N0 + l
		R = self.N0 + r
		s = self.intv
		while L < R:
			if R & 1:
				R -= 1
				s = self.func(s, self.data[R - 1])
			if L & 1:
				s = self.func(s, self.data[L - 1])
				L += 1
			L >>= 1
			R >>= 1
		return s
(N, Q) = MAP()
stl = SegTreeLazy(N + 1, min, INF)
ans = []
for i in range(Q):
	(cmd, *arg) = MAP()
	if cmd == 0:
		(s, t, x) = arg
		stl.update(s, t + 1, x)
	else:
		(i,) = arg
		ans.append(str(stl.query(i, i + 1)))
print('\n'.join(ans))


class SegmentTree:
	n = 0
	node = []

	def __init__(self, sz):
		self.n = 1
		while self.n < sz:
			self.n *= 2
		self.node = [INF] * (2 * self.n - 1)

	def update(self, a, b, x=-1, k=0, l=0, r=-1):
		if r < 0:
			r = self.n
		if r <= a or b <= l:
			return
		if a <= l and r <= b:
			if x >= 0:
				self.node[k] = x
			return
		if self.node[k] != INF:
			self.node[k * 2 + 1] = self.node[k * 2 + 2] = self.node[k]
		self.node[k] = INF
		self.update(a, b, x, 2 * k + 1, l, (l + r) // 2)
		self.update(a, b, x, 2 * k + 2, (l + r) // 2, r)
INF = 2 ** 31 - 1
(sz, q) = map(int, input().split())
ruq = SegmentTree(sz)
for _ in range(q):
	(c, *l) = map(int, input().split())
	if c:
		ruq.update(l[0], l[0] + 1)
		print(ruq.node[l[0] + ruq.n - 1])
	else:
		(s, t, x) = l
		ruq.update(s, t + 1, x)


def func(x, y):
	return x if x < y else y

class LazySegmentTree:

	def __init__(self, n):
		n_ = 1
		c_ = 0
		while n_ < n:
			n_ *= 2
			c_ += 1
		self.lv = c_
		self.n = n_
		self.arr = [2 ** 31 - 1] * (2 * self.n - 1)
		self.lazy = [None] * (2 * self.n - 1)

	def getidx(self, l, r):
		L = l + self.n >> 1
		R = r + self.n >> 1
		lc = 0 if l & 1 else (L & -L).bit_length()
		rc = 0 if r & 1 else (R & -R).bit_length()
		for i in range(self.lv):
			if rc <= i:
				yield R
			if L < R and lc <= i:
				yield L
			L >>= 1
			R >>= 1

	def propagate(self, *ids):
		for i in reversed(ids):
			v = self.lazy[i - 1]
			if v is None:
				continue
			self.lazy[2 * i - 1] = self.arr[2 * i - 1] = self.lazy[2 * i] = self.arr[2 * i] = v
			self.lazy[i - 1] = None

	def update(self, l, r, x):
		r += 1
		(*ids,) = self.getidx(l, r)
		self.propagate(*ids)
		L = self.n + l
		R = self.n + r
		while L < R:
			if R & 1:
				R -= 1
				self.lazy[R - 1] = self.arr[R - 1] = x
			if L & 1:
				self.lazy[L - 1] = self.arr[L - 1] = x
				L += 1
			L >>= 1
			R >>= 1
		for i in ids:
			self.arr[i - 1] = func(self.arr[2 * i - 1], self.arr[2 * i])

	def query(self, l, r):
		r += 1
		self.propagate(*self.getidx(l, r))
		L = self.n + l
		R = self.n + r
		s = 2 ** 31 - 1
		while L < R:
			if R & 1:
				R -= 1
				s = func(s, self.arr[R - 1])
			if L & 1:
				s = func(s, self.arr[L - 1])
				L += 1
			L >>= 1
			R >>= 1
		return s
import sys
input = sys.stdin.readline
(n, q) = map(int, input().split())
sg = LazySegmentTree(n)
for _ in range(q):
	l = list(map(int, input().split()))
	if l[0] == 0:
		(c, s, t, x) = l
		sg.update(s, t, x)
	else:
		(c, i) = l
		print(sg.query(i, i))


class SegmentTree:

	def __init__(self, n):
		self.update_cnt = 0
		self.n = n
		self.size = 1
		INF = 2 ** 31 - 1
		while self.size < n:
			self.size *= 2
		self.node = [[self.update_cnt, INF] for i in range(2 * self.size - 1)]

	def update(self, begin, end, val):
		self.update_cnt += 1
		begin += self.size - 1
		end += self.size - 1
		while begin < end:
			if end - 1 & 1:
				end -= 1
				self.node[end] = [self.update_cnt, val]
			if begin - 1 & 1:
				self.node[begin] = [self.update_cnt, val]
				begin += 1
			begin = (begin - 1) // 2
			end = (end - 1) // 2

	def get_val(self, i):
		i += self.size - 1
		val = self.node[i]
		while i > 0:
			i = (i - 1) // 2
			val = max(val, self.node[i])
		return val[1]
(n, q) = map(int, input().split())
info = [list(map(int, input().split())) for i in range(q)]
st = SegmentTree(n)
for i in range(q):
	if info[i][0] == 0:
		(s, t, val) = (info[i][1], info[i][2], info[i][3])
		st.update(s, t + 1, val)
	else:
		s = info[i][1]
		print(st.get_val(info[i][1]))


class RUQ(object):
	INF = 2 ** 31 - 1

	def __init__(self, num) -> None:
		n = 1
		while n <= num:
			n = n * 2
		self.n = n
		self.val = [self.INF] * (2 * n - 1)

	def update(self, beg: int, end: int, k: int, l: int, r: int, x: int) -> None:
		if l == beg and r == end:
			self.val[k] = x
			return
		cv = self.val[k]
		if cv != -1:
			self.val[k * 2] = self.val[k * 2 + 1] = cv
			self.val[k] = -1
		mid = (l + r) // 2
		if end <= mid:
			self.update(beg, end, k * 2, l, mid, x)
		elif beg > mid:
			self.update(beg, end, k * 2 + 1, mid + 1, r, x)
		else:
			self.update(beg, mid, k * 2, l, mid, x)
			self.update(mid + 1, end, k * 2 + 1, mid + 1, r, x)

	def find(self, k: int, l: int, r: int, idx: int) -> int:
		if self.val[k] != -1:
			return self.val[k]
		mid = (l + r) // 2
		if idx <= mid:
			return self.find(k * 2, l, mid, idx)
		else:
			return self.find(k * 2 + 1, mid + 1, r, idx)
(n, q) = map(lambda x: int(x), input().split())
ruq = RUQ(n)
for _ in range(q):
	(com, *v) = map(lambda x: int(x), input().split())
	if 0 == com:
		ruq.update(v[0], v[1], 1, 0, n - 1, v[2])
	else:
		print(f'{ruq.find(1, 0, n - 1, v[0])}')


(n, q) = map(int, input().split())
Q = [list(map(int, input().split())) for i in range(q)]
for i in range(30):
	if n <= 1 << i:
		seg_el = 1 << i
		break
SEG = [None for i in range(2 * seg_el - 1)]

def lazy_update(k, x):
	if 0 <= k < seg_el - 1:
		(lazy_item, SEG[k]) = (SEG[k], None)
		SEG[k * 2 + 1] = SEG[k * 2 + 2] = lazy_item

def update(a, b, x, k, l, r):
	if SEG[k] != None:
		lazy_update(k, x)
	if r <= a or b <= l:
		return
	if a <= l and r <= b:
		SEG[k] = x
		return
	update(a, b, x, k * 2 + 1, l, (l + r) // 2)
	update(a, b, x, k * 2 + 2, (l + r) // 2, r)

def getvalue(n):
	i = n + seg_el - 1
	ANS = SEG[i]
	i = (i - 1) // 2
	while i >= 0:
		if SEG[i] != None:
			ANS = SEG[i]
		i = (i - 1) // 2
	return ANS
for i in range(n):
	SEG[i + seg_el - 1] = (1 << 31) - 1
for query in Q:
	if query[0] == 0:
		update(query[1], query[2] + 1, query[3], 0, 0, seg_el)
	else:
		print(getvalue(query[1]))


import sys
input = sys.stdin.readline
(n, q) = map(int, input().split())
size = 2 ** (n - 1).bit_length()
tree = [None] * (size * 2)
INF = (-1, 2 ** 31 - 1)

def _find(i):
	ind = size + i
	s = INF
	while ind:
		if tree[ind]:
			s = max(s, tree[ind])
		ind = ind // 2
	return s

def find(i):
	return _find(i)[1]

def update(s, t, v):
	L = s + size
	R = t + size
	while L < R:
		if R & 1:
			R -= 1
			tree[R] = v
		if L & 1:
			tree[L] = v
			L += 1
		L >>= 1
		R >>= 1
ans = []
for i in range(q):
	(a, *b) = map(int, input().split())
	if a:
		ans.append(find(b[0]))
	else:
		update(b[0], b[1] + 1, (i, b[2]))
print('\n'.join(map(str, ans)))


INF = (-1, 2 ** 31 - 1)
line = input()
(n, q) = list(map(int, line.split()))
N = 1
while N < n + 1:
	N *= 2
a = [INF for _ in range(0, 2 * N - 1)]

def find(i, k, l, r):
	z = a[0]
	while True:
		m = (l + r) // 2
		if i < m:
			k = k * 2 + 1
			r = m
		else:
			k = k * 2 + 2
			l = m
		z = max(z, a[k])
		if k >= N - 1:
			break
	return z[1]

def update(s, t, x, k, l, r):
	if r <= s or t <= l:
		return
	elif s <= l and r <= t:
		a[k] = x
		return
	m = (l + r) // 2
	update(s, t, x, k * 2 + 1, l, m)
	update(s, t, x, k * 2 + 2, m, r)
	return
for t in range(0, q):
	line = input()
	qu = list(map(int, line.split()))
	if qu[0] == 0:
		update(qu[1], qu[2] + 1, (t, qu[3]), 0, 0, N)
	elif qu[0] == 1:
		ans = find(qu[1], 0, 0, N)
		print(ans)


class TemplateTree:

	def __init__(self, iterable):
		self.iter_size = self.get_size(iterable)
		self.size = self.iter_size * 2 - 1
		self.value = [None] * self.size
		for (i, v) in enumerate(iterable):
			self.value[self.iter_size + i - 1] = (-1, v)
		self.set_value(0)
		self.range = [None] * self.size
		self.set_range(0, 0, self.iter_size - 1)

	def get_size(self, iterable):
		ret = 1
		x = len(iterable)
		while ret < x:
			ret *= 2
		return ret

	def set_range(self, x, left, right):
		self.range[x] = (left, right)
		if left != right:
			self.set_range(x * 2 + 1, left, (right + left) // 2)
			self.set_range(x * 2 + 2, (right + left) // 2 + 1, right)

	def set_value(self, x):
		if x >= self.iter_size - 1:
			return self.value[x]
		a = self.set_value(x * 2 + 1)
		b = self.set_value(x * 2 + 2)
		if a == None and b == None:
			self.value[x] = None
		elif a == None:
			self.value[x] = b
		elif b == None:
			self.value[x] = a
		else:
			self.value[x] = a
		return self.value[x]

	def update(self, x, val, order, left, right):
		(x_left, x_right) = self.range[x]
		if left <= x_left and x_right <= right:
			self.value[x] = (order, val)
		elif right < x_left or x_right < left:
			pass
		else:
			self.update(x * 2 + 1, val, order, left, right)
			self.update(x * 2 + 2, val, order, left, right)

	def query(self, x, order, value):
		if x < 0:
			return value
		(x_order, x_val) = self.value[x]
		if order < x_order:
			return self.query((x - 1) // 2, x_order, x_val)
		else:
			return self.query((x - 1) // 2, order, value)

	def print_tree(self):
		print(self.value)
		print(self.range)
(n, q) = map(int, input().split())
INF = 2 ** 31 - 1
tree = TemplateTree([INF] * n)
for j in range(q):
	lst = list(map(int, input().split()))
	if lst[0] == 0:
		(s, t, x) = lst[1:]
		tree.update(0, x, j, s, t)
	else:
		i = lst[1]
		print(tree.query(tree.iter_size - 1 + i, -2, 0))


import sys
input = sys.stdin.readline

class LazyPropSegmentTree:

	def __init__(self, lst, op, apply, comp, e, identity):
		self.n = len(lst)
		self.depth = (self.n - 1).bit_length()
		self.N = 1 << self.depth
		self.op = op
		self.apply = apply
		self.comp = comp
		self.e = e
		self.identity = identity
		self.v = self._build(lst)
		self.lazy = [self.identity] * (2 * self.N)

	def __getitem__(self, i):
		return self.fold(i, i + 1)

	def _build(self, lst):
		tree = [self.e] * self.N + lst + [self.e] * (self.N - self.n)
		for i in range(self.N - 1, 0, -1):
			tree[i] = self.op(tree[i << 1], tree[i << 1 | 1])
		return tree

	def _indices(self, l, r):
		left = l + self.N
		right = r + self.N
		left //= left & -left
		right //= right & -right
		left >>= 1
		right >>= 1
		while left != right:
			if left > right:
				yield left
				left >>= 1
			else:
				yield right
				right >>= 1
		while left > 0:
			yield left
			left >>= 1

	def _propagate_topdown(self, *indices):
		(identity, v, lazy, apply, comp) = (self.identity, self.v, self.lazy, self.apply, self.comp)
		for k in reversed(indices):
			x = lazy[k]
			if x == identity:
				continue
			lazy[k << 1] = comp(lazy[k << 1], x)
			lazy[k << 1 | 1] = comp(lazy[k << 1 | 1], x)
			v[k << 1] = apply(v[k << 1], x)
			v[k << 1 | 1] = apply(v[k << 1 | 1], x)
			lazy[k] = identity

	def _propagate_bottomup(self, indices):
		(v, op) = (self.v, self.op)
		for k in indices:
			v[k] = op(v[k << 1], v[k << 1 | 1])

	def update(self, l, r, x):
		(*indices,) = self._indices(l, r)
		self._propagate_topdown(*indices)
		(N, v, lazy, apply, comp) = (self.N, self.v, self.lazy, self.apply, self.comp)
		left = l + N
		right = r + N
		if left & 1:
			v[left] = apply(v[left], x)
			left += 1
		if right & 1:
			right -= 1
			v[right] = apply(v[right], x)
		left >>= 1
		right >>= 1
		while left < right:
			if left & 1:
				lazy[left] = comp(lazy[left], x)
				v[left] = apply(v[left], x)
				left += 1
			if right & 1:
				right -= 1
				lazy[right] = comp(lazy[right], x)
				v[right] = apply(v[right], x)
			left >>= 1
			right >>= 1
		self._propagate_bottomup(indices)

	def fold(self, l, r):
		self._propagate_topdown(*self._indices(l, r))
		(e, N, v, op) = (self.e, self.N, self.v, self.op)
		left = l + N
		right = r + N
		L = R = e
		while left < right:
			if left & 1:
				L = op(L, v[left])
				left += 1
			if right & 1:
				right -= 1
				R = op(v[right], R)
			left >>= 1
			right >>= 1
		return op(L, R)
(N, Q) = map(int, input().split())
op = min
apply = lambda x, f: f
comp = lambda f, g: g
e = 2 ** 31 - 1
identity = None
A = [e] * N
lpsg = LazyPropSegmentTree(A, op, apply, comp, e, identity)
ans = []
for _ in range(Q):
	(t, *arg) = map(int, input().split())
	if t == 0:
		(s, t, x) = arg
		lpsg.update(s, t + 1, x)
	else:
		ans.append(lpsg[arg[0]])
print('\n'.join(map(str, ans)))


class LazySegTree:
	inf = 2147483647
	INF = [-1, 2147483647]

	def __init__(self, n_):
		self.n_ = n_
		self.n = 1
		while self.n < n_:
			self.n *= 2
		self.st = [self.INF] * (2 * self.n - 1)
		self.lazy = [self.INF] * (2 * self.n - 1)

	def propagate(self, k):
		if self.lazy[k] == self.INF:
			return
		self.st[k] = self.lazy[k][1]
		if k < self.n_ - 1:
			self.lazy[k * 2 + 1] = self.lazy[k]
			self.lazy[k * 2 + 2] = self.lazy[k]
		self.lazy[k] = self.INF

	def update(self, a, b, k, x, l, r):
		if r <= a or b <= l:
			return
		if a <= l and r <= b:
			self.st[k] = x
			self.lazy[k] = x
			return
		self.update(a, b, k * 2 + 1, x, l, (l + r) // 2)
		self.update(a, b, k * 2 + 2, x, (l + r) // 2, r)

	def Update(self, a, b, x):
		return self.update(a, b, 0, x, 0, self.n)

	def search(self, k, l, r):
		k += self.n - 1
		res = self.INF
		while 0 <= k:
			res = max(res, self.lazy[k])
			k = (k - 1) // 2
		return res[1]

	def Search(self, k):
		return self.search(k, 0, self.n)

def main():
	(n, m) = map(int, input().split())
	lst = LazySegTree(n)
	for i in range(m):
		q = list(map(int, input().split()))
		if q[0] == 0:
			lst.Update(q[1], q[2] + 1, [i, q[3]])
		else:
			print(lst.Search(q[1]))
main()


class SegmentTree:
	maxval = (1 << 31) - 1

	def __init__(self, n):
		self.offset = self.setOffset(n)
		self.segTree = [(0, self.maxval) for i in range(2 * self.offset + 1)]
		self.time = 0

	def setOffset(self, n):
		if n == 1:
			return 1
		else:
			return 2 ** (n - 1).bit_length() - 1

	def find(self, k):
		k += self.offset
		data = self.segTree[k]
		while k:
			k = (k - 1) // 2
			data = max(data, self.segTree[k])
		return data

	def update_query(self, p, q, x):
		if p >= q:
			return
		self.time += 1
		p += self.offset
		q += self.offset - 1
		v = (self.time, x)
		while q - p > 1:
			if not p & 1:
				self.segTree[p] = v
			if q & 1:
				self.segTree[q] = v
				q -= 1
			p = p // 2
			q = (q - 1) // 2
		if p == q:
			self.segTree[p] = v
		else:
			self.segTree[p] = v
			self.segTree[q] = v

	def show(self):
		print(self.segTree)
(n, q) = map(int, input().split())
ST = SegmentTree(n)
for i in range(q):
	qry = list(map(int, input().split()))
	if qry[0] == 0:
		ST.update_query(qry[1], qry[2] + 1, qry[3])
	else:
		print(ST.find(qry[1])[1])


import sys
readline = sys.stdin.readline
write = sys.stdout.write
(n, q) = map(int, readline().split())
N0 = 2 ** (n - 1).bit_length()
data = [None] * (2 * N0)
INF = (-1, 2 ** 31 - 1)

def update(l, r, v):
	L = l + N0
	R = r + N0
	while L < R:
		if R & 1:
			R -= 1
			data[R - 1] = v
		if L & 1:
			data[L - 1] = v
			L += 1
		L >>= 1
		R >>= 1

def _query(k):
	k += N0 - 1
	s = INF
	while k >= 0:
		if data[k]:
			s = max(s, data[k])
		k = (k - 1) // 2
	return s

def query(k):
	return _query(k)[1]
ans = []
for i in range(q):
	(t, *cmd) = map(int, readline().split())
	if t:
		ans.append(str(query(cmd[0])))
	else:
		(s, t, x) = cmd
		update(s, t + 1, (i, x))
write('\n'.join(ans))
write('\n')


import sys
input = sys.stdin.readline
(n, q) = map(int, input().split())
size = 2 ** (n - 1).bit_length()
tree = [None] * (size * 2)
INF = (-1, 2 ** 31 - 1)

def _find(i):
	ind = size + i
	s = INF
	while ind:
		if tree[ind]:
			s = max(s, tree[ind])
		ind = ind // 2
	return s

def find(i):
	return _find(i)[1]

def update(s, t, v):
	L = s + size
	R = t + size
	while L < R:
		if L & 1:
			tree[L] = v
			L += 1
		if R & 1:
			R -= 1
			tree[R] = v
		L >>= 1
		R >>= 1
res = []
for i in range(q):
	(a, *b) = map(int, input().split())
	if a:
		res.append(find(b[0]))
	else:
		update(b[0], b[1] + 1, (i, b[2]))
print('\n'.join(map(str, res)))


import sys
INF = 2 ** 31 - 1

class RUQ:

	def __init__(self, n):
		tmp = 1
		while tmp < n:
			tmp *= 2
		self.n = tmp * 2
		self.A = [INF] * (2 * self.n - 1)

	def update(self, a, b, x=-1, k=0, l=0, r=0):
		if r <= a or b <= l:
			return
		if a <= l and r <= b:
			if x >= 0:
				self.A[k] = x
			return
		if self.A[k] != INF:
			self.A[k * 2 + 1] = self.A[k * 2 + 2] = self.A[k]
		self.A[k] = INF
		self.update(a, b, x, k * 2 + 1, l, (l + r) / 2)
		self.update(a, b, x, k * 2 + 2, (l + r) / 2, r)
line = sys.stdin.readline()
(n, q) = map(int, line.split())
ruq = RUQ(n)
for i in range(q):
	line = sys.stdin.readline()
	if line[0] == '0':
		(com, s, t, x) = map(int, line.split())
		ruq.update(s, t + 1, x, 0, 0, ruq.n)
	else:
		(com, i) = map(int, line.split())
		ruq.update(i, i + 1, -1, 0, 0, ruq.n)
		print(ruq.A[i + ruq.n - 1])


import math

def lazy_update(s, e, value):
	a = [(1, l + s, l + e, 1)]
	ap = a.append
	while a:
		(k, s, e, depth) = a.pop()
		(l_end, r_end) = (k << rank - depth, k + 1 << rank - depth)
		mid = (l_end + r_end) // 2
		if s == l_end and e == r_end:
			lazy[k] = value
		else:
			child = k << 1
			if lazy[k] is not None:
				lazy[child] = lazy[k]
				lazy[child + 1] = lazy[k]
				lazy[k] = None
			if s < mid:
				ap((child, s, (mid, e)[e < mid], depth + 1))
			if e > mid:
				ap((child + 1, (mid, s)[s > mid], e, depth + 1))

def get_value(i):
	i += l
	for j in range(rank, -1, -1):
		n = lazy[i >> j]
		if n is not None:
			return n
	return tree[i]
(n, q) = map(int, input().split())
l = 1 << math.ceil(math.log2(n))
tree = [2 ** 31 - 1] * (2 * l)
lazy = [None] * (2 * l)
rank = int(math.log2(len(tree)))
ans = []
ap = ans.append
for _ in [None] * q:
	query = list(map(int, input().split()))
	if query[0] == 0:
		lazy_update(query[1], query[2] + 1, query[3])
	else:
		ap(get_value(query[1]))
print('\n'.join((str(n) for n in ans)))


INF = 2 ** 31 - 1
(n, q) = list(map(int, input().split()))
lazy = [None for i in range(4 * n)]
for i in range(n):
	lazy[i] = INF

def updata(a, b, x, k, l, r):
	m = (l + r) // 2
	if a >= r or b <= l:
		return 0
	elif a <= l and b >= r:
		lazy[k] = x
	else:
		if lazy[k] != None:
			lazy[k * 2 + 1] = lazy[k]
			lazy[k * 2 + 2] = lazy[k]
			lazy[k] = None
		updata(a, b, x, k * 2 + 1, l, m)
		updata(a, b, x, k * 2 + 2, m, r)

def find(x, k, l, r):
	m = (l + r) // 2
	if lazy[k] != None:
		print(lazy[k])
	elif x < (l + r) // 2:
		find(x, k * 2 + 1, l, m)
	else:
		find(x, k * 2 + 2, m, r)
for i in range(q):
	data = list(map(int, input().split()))
	if len(data) == 4:
		(f, a, b, x) = data
		updata(a, b + 1, x, 0, 0, n)
	else:
		(f, i) = data
		find(i, 0, 0, n)


from math import log2, ceil

class SegmentTree:

	def __init__(self, n):
		tn = 2 ** ceil(log2(n))
		self.a = [2 ** 31 - 1] * (tn * 2)

	def find(self, c, l, r, i):
		if self.a[c] != -1:
			return self.a[c]
		mid = (l + r) // 2
		if i <= mid:
			return self.find(c * 2, l, mid, i)
		else:
			return self.find(c * 2 + 1, mid + 1, r, i)

	def update(self, c, l, r, s, t, x):
		if l == s and r == t:
			self.a[c] = x
			return
		cv = self.a[c]
		if cv != -1:
			self.a[c * 2] = self.a[c * 2 + 1] = cv
			self.a[c] = -1
		mid = (l + r) // 2
		if t <= mid:
			self.update(c * 2, l, mid, s, t, x)
		elif s > mid:
			self.update(c * 2 + 1, mid + 1, r, s, t, x)
		else:
			self.update(c * 2, l, mid, s, mid, x)
			self.update(c * 2 + 1, mid + 1, r, mid + 1, t, x)
(n, q) = map(int, input().split())
st = SegmentTree(n)
for _ in range(q):
	query = input().split()
	if query[0] == '0':
		(s, t, x) = map(int, query[1:])
		st.update(1, 0, n - 1, s, t, x)
	else:
		print(st.find(1, 0, n - 1, int(query[1])))


class SegmentTree:
	INITIAL_VALUE = 2 ** 31 - 1
	DIVIDED = -1

	def __init__(self, n):
		size = 1
		while size < n:
			size *= 2
		self.size = 2 * size - 1
		self.data = [-1] * self.size
		self.data[0] = self.INITIAL_VALUE

	def set_range(self, lo, hi, v):

		def _set_range(r, i, j, vv):
			if j < lo or i > hi:
				if vv != self.DIVIDED:
					self.data[r] = vv
			elif lo <= i and j <= hi:
				self.data[r] = v
			else:
				if self.data[r] != self.DIVIDED:
					if vv == self.DIVIDED:
						vv = self.data[r]
					self.data[r] = self.DIVIDED
				mid = i + (j - i) // 2
				_set_range(r * 2 + 1, i, mid, vv)
				_set_range(r * 2 + 2, mid + 1, j, vv)
		_set_range(0, 0, self.size // 2, self.DIVIDED)

	def get(self, i):

		def _get(r, lo, hi):
			if self.data[r] != self.DIVIDED:
				return self.data[r]
			mid = lo + (hi - lo) // 2
			if i <= mid:
				return _get(r * 2 + 1, lo, mid)
			else:
				return _get(r * 2 + 2, mid + 1, hi)
		return _get(0, 0, self.size // 2)

def run():
	(n, q) = [int(x) for x in input().split()]
	t = SegmentTree(n)
	for _ in range(q):
		(com, *args) = [x for x in input().split()]
		if com == '0':
			(i, j, v) = [int(x) for x in args]
			t.set_range(i, j, v)
		elif com == '1':
			i = int(args[0])
			print(t.get(i))
run()


import sys
readline = sys.stdin.readline
write = sys.stdout.write
(N, Q) = map(int, readline().split())
N0 = 2 ** (N - 1).bit_length()
data = [None] * (2 * N0)
INF = (-1, 2 ** 31 - 1)

def update(l, r, v):
	L = l + N0
	R = r + N0
	while L < R:
		if R & 1:
			R -= 1
			data[R - 1] = v
		if L & 1:
			data[L - 1] = v
			L += 1
		L >>= 1
		R >>= 1

def _query(k):
	k += N0 - 1
	s = INF
	while k >= 0:
		if data[k]:
			s = max(s, data[k])
		k = (k - 1) // 2
	return s

def query(k):
	return _query(k)[1]
ans = []
for q in range(Q):
	(t, *cmd) = map(int, readline().split())
	if t:
		ans.append(str(query(cmd[0])))
	else:
		(s, t, x) = cmd
		update(s, t + 1, (q, x))
write('\n'.join(ans))
write('\n')


(n, q) = map(int, input().split())
s = 1
while s < n:
	s *= 2
A = [(-1, 2 ** 31 - 1)] * (2 * s - 1)

def update(l, r, i, v):
	while l < r:
		if r & 1:
			r -= 1
			A[r - 1] = (i, v)
		if l & 1:
			A[l - 1] = (i, v)
			l += 1
		l //= 2
		r //= 2
for i in range(q):
	c = list(map(int, input().split()))
	if not c[0]:
		x = c[1]
		y = c[2]
		u = c[3]
		x += s
		y += s
		update(x, y + 1, i, u)
	else:
		res = (-1, 0)
		x = c[1] + s - 1
		while x >= 0:
			if A[x] > res:
				res = A[x]
			x -= 1
			x //= 2
		print(res[1])