#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 min_child;
        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;
    }
    
    int min(vector<int> v){
        int m = v[0];
        
        for(vector<int>::size_type i = 1; i < v.size(); i++)
            if(m > v[i])
                m = v[i];
        
        return m;
    }
    
    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.min_child = 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){
        int R;
        
        if(level < Tree.size() - 1){
            R = UpDate(level + 1, key / 2, n, section, &Tree[level][key]);
            if(R != UNDEF)
                return R;
        }
        
        if(section.first <= Tree[level][key].low && Tree[level][key].high <= section.second){
            Tree[level][key].value = n;
            UpDateMin(level, key);
            return Tree[level][key].high;
        }
        else{
            if(level > 1)
                DownValue(level, key);
            else
                DownValue(level, key, before);
            return UNDEF;
        }
    }
    
    void UpDateMin(int level, int key){
        if(level == Tree.size())
            return;
        
        if(Tree[level][key].value == UNDEF){
            if(2 * key + 1 < Tree[level - 1].size())
                Tree[level][key].min_child = min(Tree[level - 1][2 * key].min_child, Tree[level - 1][2 * key + 1].min_child);
            else
                Tree[level][key].min_child = Tree[level - 1][2 * key].min_child;
        }
        else
            Tree[level][key].min_child = Tree[level][key].value;
        
        UpDateMin(level + 1, key / 2);
    }
    
    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].min_child = Tree[level - 1][2 * key].value = tmp;
            else if(2 * key + 1 < Tree[level - 1].size())
                Tree[level - 1][2 * key + 1].min_child = Tree[level - 1][2 * key + 1].value = tmp;
        }
    }
    
    void DownValue(int level, int key){
        int vt = Tree[level][key].value;
        Tree[level][key].value = UNDEF;
        
        if(vt != UNDEF){
            Tree[level - 1][2 * key].value = vt;
            Tree[level - 1][2 * key].min_child = vt;
            if(2 * key + 1 < Tree[level - 1].size()){
                Tree[level - 1][2 * key + 1].value = vt;
                Tree[level - 1][2 * key + 1].min_child = vt;
            }
        }
    }
    
    int Find(int s, int t){
        int level = (int)Tree.size() - 1;
        pair<int, int> section(s, t);
        vector<int> element;
        
        if(level == 0 || Tree[level][0].value != UNDEF || (section.first <= Tree[level][0].low && Tree[level][0].high <= section.second))
            return Tree[level][0].min_child;
        else{
            if(section.second <= Tree[level - 1][0].high)
                Find(level - 1, 0, element, section);
            else if(section.first >= Tree[level - 1][1].low)
                Find(level - 1, 1, element, section);
            else{
                Find(level - 1, 0, element, section);
                Find(level - 1, 1, element, section);
            }
            
            return min(element);
        }
    }
    
    void Find(int level, int key, vector<int> &element, pair<int, int> section){
        
        if(level == 0 || Tree[level][key].value != UNDEF || (section.first <= Tree[level][key].low && Tree[level][key].high <= section.second))
            element.push_back(Tree[level][key].min_child);
        else{
            if(section.second <= Tree[level - 1][2 * key].high)
                Find(level - 1, 2 * key, element, section);
            else if(section.first >= Tree[level - 1][2 * key + 1].low)
                Find(level - 1, 2 * key + 1, element, section);
            else{
                Find(level - 1, 2 * key, element, section);
                Find(level - 1, 2 * key + 1, element, section);
            }
        }
    }

    
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].min_child = Tree[0][i].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 >> s >> t;
                if(!(0 <= s && s < DNum) || !(0 <= t && t < DNum) || (s > t))
                    exit(3);
                
                cout << Find(s, t) << endl;
            }
            else
                exit(4);
        }
    }
};

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



Measured memory_bytes: 10720