class Node {
    constructor(l, r) {
        this.l = l;
        this.r = r;
        this.mid = (l + r) >> 1;
        this.left = null;
        this.right = null;
        this.v = 0;
        this.add = 0; // lazy sign
    }
};

class SegmentTree {
    constructor() {
        this.root = new Node(1, 1e9);
    }

    update_inside(l, r, v, node) {
        if (l > r)
            return;
        if (node.l >= l && node.r <= r) {
            node.v = v;
            node.add = v;
            return;
        }
        this.pushdown(node);
        if (l <= node.mid)
            this.update_inside(l, r, v, node.left);
        if (r > node.mid)
            this.update_inside(l, r, v, node.right);
        this.pushup(node);
    }

    update(l, r, v) {
        this.update_inside(l, r, v, this.root);
    }

    query_inside(l, r, node) {
        if (l > r)
            return 0;
        if (node.l >= l && node.r <= r) //the node is covered by the area
            return node.v;
        this.pushdown(node);
        let v = 0;
        if (l <= node.mid)
            v = Math.max(v, this.query_inside(l, r, node.left));
        if (r > node.mid)
            v = Math.max(v, this.query_inside(l, r, node.right));
        return v;
    }

    query(l, r) {
        return this.query_inside(l, r, this.root);
    }

    pushup(node) {
        node.v = Math.max(node.left.v, node.right.v);
    }

    pushdown(node) {
        if (!node.left)
            node.left = new Node(node.l, node.mid);
        if (!node.right)
            node.right = new Node(node.mid + 1, node.r);
        if (node.add) {
            let left = node.left;
            let right = node.right;
            left.v = node.add;
            right.v = node.add;
            left.add = node.add;
            right.add = node.add;
            node.add = 0;
        }
    }
};