#include <iostream>
#include <vector>
#include <cmath>
#include <cstdlib>

#define DATA_MAX 100000
#define QUERY_MAX 100000
#define UNDEF -1

using namespace std;

class SegTree{
    struct Node{
        int value;
        int high;
        int low;
    };
    
private:
    vector<vector<Node> > Tree;
    const int MAX_VALUE;
    int DNum, QNum;
    
    int min(int d1, int d2){
        return d1 < d2 ? d1 : d2;
    }
    
    void CreateTree(int level){
        vector<Node> new_layer;
        Node tmp;
        
        if(Tree[level].size() == 1)
            return;
        
        for(vector<Node>::size_type i = 0; i < Tree[level].size(); i += 2){
            tmp.value = MAX_VALUE;
            tmp.low = Tree[level][i].low;
            tmp.high = Tree[level][i + 1].high;
            new_layer.push_back(tmp);
            
            if(i + 2 == Tree[level].size() - 1){
                tmp = Tree[level][i + 2];
                new_layer.push_back(tmp);
                break;
            }
        }
        
        Tree.push_back(new_layer);
        
        if(Tree[level + 1].size() == 1)
            return;
        else
            CreateTree(level + 1);
    }
    
    void UpDate(int s, int t, int n){
        int iter = s;
        pair<int, int> section(s, t);
        
        while(iter <= t){
            iter = UpDate(0, iter, n, section, &Tree[0][iter]);
            iter++;
        }
    }
    
    int UpDate(int level, int key, int n, pair<int, int> section, Node *before){
        if(n == UNDEF){
            if(level == Tree.size() - 1){
                DownValue(level, key);
                return UNDEF;
            }
            else{
                UpDate(level + 1, key / 2, n, section, &Tree[level][key]);
                DownValue(level, key);
                return UNDEF;
            }
        }
        
        if(section.first <= Tree[level][key].low && Tree[level][key].high <= section.second){
            if(level == Tree.size() - 1){
                Tree[level][key].value = n;
                return Tree[level][0].high;
            }
            else{
                Tree[level][key].value = n;
                return UpDate(level + 1, key / 2, n, section, &Tree[level][key]);
            }
        }
        
        
        if(level < Tree.size() - 1)
            UpDate(level + 1, key / 2, UNDEF, section, &Tree[level][key]);
        DownValue(level, key, before);
        
        return before->high;
    }
    
    void DownValue(int level, int key, Node *before){
        int tmp = Tree[level][key].value;
        Tree[level][key].value = UNDEF;
        
        if(tmp != UNDEF){
            if(before != &Tree[level - 1][2 * key])
                Tree[level - 1][2 * key].value = tmp;
            else if(2 * key + 1 < Tree[level - 1].size())
                Tree[level - 1][2 * key + 1].value = tmp;
        }
    }
    
    void DownValue(int level, int key){
        int tmp = Tree[level][key].value;
        Tree[level][key].value = UNDEF;
        
        if(tmp != UNDEF){
            Tree[level - 1][2 * key].value = tmp;
            if(2 * key + 1 < Tree[level - 1].size())
                Tree[level - 1][2 * key + 1].value = tmp;
        }
    }
    
    int Find(int target){
        int level = (int)Tree.size() - 1;
        
        if((Tree[level][0].low <= target && target <= Tree[level][0].high && Tree[level][0].value != UNDEF) || level == 0)
            return Tree[level][0].value;
        
        if(target <= Tree[level - 1][0].high)
            return Find(level - 1, 0, target);
        else
            return Find(level - 1, 1, target);
    }
    
    int Find(int level, int key, int target){
        if(Tree[level][key].low <= target && target <= Tree[level][key].high && Tree[level][key].value != UNDEF)
            return Tree[level][key].value;
        
        if(target <= Tree[level - 1][2 * key].high || 2 * key + 1 > Tree[level - 1].size() - 1)
            return Find(level - 1, 2 * key, target);
        else
            return Find(level - 1, 2 * key + 1, target);
    }
    
public:
    SegTree() : MAX_VALUE(pow(2, 31) - 1){
        Tree.resize(1);
    }
    
    void Init(){
        cin >> DNum >> QNum;
        if(!(1 <= DNum && DNum <= DATA_MAX) || !(1 <= QNum && QNum <= QUERY_MAX))
            exit(1);
        
        Tree[0].resize(DNum);
        for(vector<int>::size_type i = 0; i < Tree[0].size(); i++){
            Tree[0][i].value = MAX_VALUE;
            Tree[0][i].high = (int)i;
            Tree[0][i].low = (int)i;
        }
        
        CreateTree(0);
    }
    
    void ReadQuery(){
        int com, s, t, x;
        
        for(int c = 0; c < QNum; c++){
            cin >> com;
            if(com == 0){
                cin >> s >> t >> x;
                if(!(0 <= s && s < DNum) || !(0 <= t && t < DNum) || (s > t) || !(0 <= x && x < MAX_VALUE))
                    exit(2);
                
                UpDate(s, t, x);
            }
            else if(com == 1){
                cin >> x;
                if(!(0 <= x && x < DNum))
                    exit(3);
                
                cout << Find(x) << endl;
            }
            else
                exit(4);
        }
    }
};

int main(){
    SegTree sg;
    
    sg.Init();
    sg.ReadQuery();
    
    return 0;
}



Measured memory_bytes: 8616