#include<iostream>
#include<cassert>
#define GET_MACRO(_1,_2,_3,_4,_5,_6,_7,_8,NAME,...) NAME
#define pr(...) cerr<< GET_MACRO(__VA_ARGS__,pr8,pr7,pr6,pr5,pr4,pr3,pr2,pr1)(__VA_ARGS__) <<endl
#define pr1(a) (#a)<<"="<<(a)<<" "
#define pr2(a,b) pr1(a)<<pr1(b)
#define pr3(a,b,c) pr1(a)<<pr2(b,c)
#define pr4(a,b,c,d) pr1(a)<<pr3(b,c,d)
#define pr5(a,b,c,d,e) pr1(a)<<pr4(b,c,d,e)
#define pr6(a,b,c,d,e,f) pr1(a)<<pr5(b,c,d,e,f)
#define pr7(a,b,c,d,e,f,g) pr1(a)<<pr6(b,c,d,e,f,g)
#define pr8(a,b,c,d,e,f,g,h) pr1(a)<<pr7(b,c,d,e,f,g,h)
#define prArr(a) {cerr<<(#a)<<"={";int i=0;for(auto t:(a))cerr<<(i++?", ":"")<<t;cerr<<"}"<<endl;}
template<typename T>
class Deque{
public:
  T *val;
  int sz;
  int length;
  int head, tail;
  
  Deque(){sz = 0, length = 0, val = new T[0];}
  Deque(int size, T init = T()){
    length = 1;
    while(length < size) length *= 2;
    val = new T[length];
    sz = size;
    head = 0;
    tail = 0;
    for(int i=0;i<size;i++) val[tail++] = init;
  }
  
  Deque(const Deque &t){
    sz = t.size();
    length = 1;
    while(length < sz) length *= 2;
    val = new T[length];
    head = 0;
    tail = 0;
    for(int i=0;i<sz;i++) val[tail++] = t[i];
  }

  ~Deque(){
    delete [] val;
  }
  
  T& operator [] (int i){assert(0 <= i && i < sz);return val[(head + i)%length];}
  T& operator [] (int i)const{assert(0 <= i && i < sz);return val[(head + i)%length];}
  int size()const{return sz;}
  int empty()const{return sz == 0;}
  void resize(int n, T v=T()){
    while(n < size()) pop_back();
    while(n > size()) push_back(v);
  }
  
  void increaseMemory(){
    int length_ = length;
    
    length = length * 2;
    if(length == 0) length = 1;
    T *val2 = new T[length];
    for(int i=0;i<sz;i++) val2[i] = val[(head + i)%length_];
    head = 0;
    tail = sz;
    delete [] val;
    val = val2;
  };
  
  void push_back(T v){
    if(sz == length) increaseMemory();
    sz++;
    val[tail++] = v;
    if(tail == length) tail = 0;
  }
  
  void push_front(int v){
    if(sz == length) increaseMemory();
    sz++;
    head--;
    if(head == -1) head = length - 1;
    val[head] = v;
  }

  void pop_back(){
    assert(sz > 0);
    sz--;
    tail--;
    if(tail == -1) tail = length - 1;
  }
  
  void pop_front(){
    assert(sz > 0);
    sz--;
    head++;
    if(head == length) head = 0;
  }
};
template <typename T>
using vector = Deque<T>;


template<class T>T max(T a, T b){return a >= b? a:b;}
template<class T>T min(T a, T b){return a <= b? a:b;}

template<typename dtype, dtype initValue/*範囲外のときに返す値*/>
class RUQ{
public:
  int n,n_;
  vector<dtype> dat;
  vector<int> his;
  int time;

  //初期化
  RUQ(){n=-1,time = 0;}
  RUQ(int n_):n_(n_){
    time = 0;
    n=1;
    while(n<n_)n*=2;
    dat.resize(2*n-1,initValue);
    his.resize(2*n-1,-1);
  }

  //k番目の値をaに変更
  dtype get(int k){
    k+=n-1;
    int i = k;
    while(k>0){
      k=(k-1)/2;
      if(his[i] < his[k]) i = k;
    }
    return dat[i];
  }
  
  void dfs(int a,int b, dtype x, int k,int l,int r){
    if(r<=a||b<=l)return;
    if(a<=l&&r<=b){
      dat[k] = x;
      his[k] = time;
      return;
    }
    dfs(a,b,x,k*2+1,l,(l+r)/2);
    dfs(a,b,x,k*2+2,(l+r)/2,r);
  }
  
  //[a,b)の最小値を求める
  void update(int a,int b, dtype x){
    assert(a <= b), assert(a <= n_ && b <= n_), assert(a >= 0 && a >= 0);
    dfs(a,b,x,0,0,n);
    time++;
  }
};


signed main(){

  int n,q;
  std::cin>>n>>q;
  typedef long long ll;
  RUQ <ll, (1LL<<31)-1> A(n);
  
  while(q--){
    int com;
    std::cin>>com;
    if(com == 0) {
      int s,t,x;
      std::cin>>s>>t>>x;
      A.update(s, t+1, x);
    }
    if(com == 1) {
      int k;
      std::cin>>k;
      std::cout<<A.get(k)<<std::endl;
    }
  }
  
  return 0;
}



Measured memory_bytes: 6984