#include <bits/stdc++.h>
using namespace std;
#pragma region macros_and_aliases
#define rep(i, n) for(long long i = 0; i < (n); i++)
#define rrep(i, n) for(long long i = (n)-1; i > -1; i--)
#define Rep(i, m, n) for(long long i = (m); i < (n); i++)
#define rRep(i, m, n) for(long long i = (n)-1; i >= (m); i--)
#define REP(i, m, n, p) for(long long i = m; i < n; i += p)
#define foa(s, v) for(auto &s : v)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define pq priority_queue
#define bcnt(n) __builtin_popcountll(n)
#define endk endl
#define ednl endl
#define enld endl
using ll = long long;
using ld = long double;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vb = vector<bool>;
using mll = map<long long, long long>;
using pll = pair<long long, long long>;
using qll = queue<long long>;
using sll = set<long long>;
using vpll = vector<pair<long long, long long>>;
template <class T = ll>
using V = vector<T>;
template <class T = ll>
using VV = V<V<T>>;
template <class T = ll>
using VVV = V<V<V<T>>>;
//昇順pq(小さい方から取り出す)
template <class T = ll>
using pqup = priority_queue<T, vector<T>, greater<T>>;
//降順pq(大きい方から取り出す)
template <class T = ll>
using pqdn = priority_queue<T>;
#define debug(var)              \
	std::cout << #var << " : "; \
	view(var)
template <typename T>
void view(T e) {
	std::cout << e << std::endl;
}
template <typename T>
void view(const std::vector<T> &v) {
	for(const auto &e : v) {
		std::cout << e << " ";
	}
	std::cout << std::endl;
}
template <typename T>
void view(const std::vector<std::vector<T>> &vv) {
	for(const auto &v : vv) {
		view(v);
	}
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
	os << p.first << " " << p.second;
	return os;
}
template <typename T1, typename T2>
istream &operator>>(istream &is, pair<T1, T2> &p) {
	is >> p.first >> p.second;
	return is;
}
#pragma endregion

template <class T = long long, class U = long long>
class LazyST {
   private:
	int n;
	int height = -1;	   //木の高さ
	vector<T> data;		   // monoid
	vector<U> lazy;		   // operator
	T unit_data;		   // monoid単位元
	U unit_lazy;		   // operator単位元
	function<T(T, T)> f1;  // monoid同士の演算
	function<T(T, U)> f2;  // monoidとoperatorとの演算
	function<U(U, U)> f3;  // operator同士の演算
	void propagate(int lef, int rig) {
		// 遅延させていた作用素を上から伝播させる [lef,rig)に有効な範囲で
		lef += n;
		rig += n - 1;  //閉区間にする
		for(int i = height; i > 0; i--) {
			int l = lef >> i;
			int r = rig >> i;
			lazy[l << 1] = f3(lazy[l << 1], lazy[l]);
			lazy[l << 1 | 1] = f3(lazy[l << 1 | 1], lazy[l]);
			data[l] = f2(data[l], lazy[l]);
			lazy[l] = unit_lazy;
			lazy[r << 1] = f3(lazy[r << 1], lazy[r]);
			lazy[r << 1 | 1] = f3(lazy[r << 1 | 1], lazy[r]);
			data[r] = f2(data[r], lazy[r]);
			lazy[r] = unit_lazy;
		}
	}

   public:
	LazyST(int _n, function<T(T, T)> ope_data_data, function<T(T, U)> ope_data_lazy, function<U(U, U)> ope_lazy_lazy, T _unit_data,
		   U _unit_lazy)
		: n(_n), f1(ope_data_data), f2(ope_data_lazy), f3(ope_lazy_lazy), unit_data(_unit_data), unit_lazy(_unit_lazy) {
		data.assign(n * 2, unit_data);
		lazy.assign(n * 2, unit_lazy);
		for(int i = 1; i <= n; i *= 2) height++;
	}

	void update(int lef, int rig, U _operator) {  //[lef,rig)にopeを作用させる
		propagate(lef, rig);
		lef += n;
		rig += n;  //半開区間にする 下から上にdataを更新
		int L0 = lef / (lef & -lef);
		int R0 = rig / (rig & -rig);
		while(lef < rig) {
			if(lef & 1) {
				lazy[lef] = f3(lazy[lef], _operator);
				data[lef >> 1] = f1(f2(data[lef], lazy[lef]), f2(data[lef - 1], lazy[lef - 1]));
				lazy[lef >> 1] = unit_lazy;
				lef++;
			}
			if(rig & 1) {
				lazy[rig - 1] = f3(lazy[rig - 1], _operator);
				data[(rig - 1) >> 1] = f1(f2(data[rig - 1], lazy[rig - 1]), f2(data[rig], lazy[rig]));
				lazy[(rig - 1) >> 1] = unit_lazy;
				rig--;
			}
			lef >>= 1;
			rig >>= 1;
		}
		lef = L0;
		rig = R0;
		while(lef > 1) {
			lef >>= 1;
			data[lef] = f1(f2(data[lef << 1], lazy[lef << 1]), f2(data[lef << 1 | 1], lazy[lef << 1 | 1]));
			lazy[lef] = unit_lazy;
		}
		while(rig > 1) {
			rig >>= 1;
			data[rig] = f1(f2(data[rig << 1], lazy[rig << 1]), f2(data[rig << 1 | 1], lazy[rig << 1 | 1]));
			lazy[rig] = unit_lazy;
		}
	}

	void update(int idx, T x) {	 //点更新
		idx += n;
		data[idx] = x;
		idx >>= 1;
		while(idx > 0) {
			data[idx] = f1(data[(idx << 1)], data[(idx << 1) | 1]);
			idx >>= 1;
		}
	}

	T get(int lef, int rig) {  //区間の値取得
		propagate(lef, rig);
		T a = unit_data, b = unit_data;
		lef += n;
		rig += n;
		while(lef < rig) {
			if(lef & 1) a = f1(a, f3(data[lef], lazy[lef]));
			if(rig & 1) b = f1(f3(data[rig - 1], lazy[rig - 1]), b);
			(lef += 1) >>= 1;
			rig >>= 1;
		}
		return f1(a, b);
	}
};

int main() {
	ll rep_unit = -1;
	auto replace = [](ll a, ll b) { return b == -1 ? a : b; };
	auto mini = [](ll a, ll b) { return min(a, b); };
	auto maxi = [](ll a, ll b) { return max(a, b); };
	auto pairadd = [](pll a, pll b) { return (pll){a.first + b.first, a.second + b.second}; };

	ll n, q;
	cin >> n >> q;
	LazyST<> st(n, mini, replace, replace, (1LL << 31) - 1, rep_unit);
	vll ans;
	rep(i, q) {
		int sort;
		cin >> sort;
		if(sort) {
			ll s;
			cin >> s;
			ll k = st.get(s, s + 1);
			ans.push_back(k);
		} else {
			ll s, t, x;
			cin >> s >> t >> x;
			t++;
			st.update(s, t, x);
		}
	}
	foa(t, ans) cout << t << enld;
}


Measured memory_bytes: 6932