#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# min-max-sum-Segment tree
# christoph dürr - 2017


from sys import stdin

# snip{
class SegmentTree:
    """maintains a numerical table T of size n and allows
    the following operations in time O(log n):

    - given j,k,v: set T[j] = ... = T[k-1] = v
    - given j, k: compute max(T[j], ... ,T[k-1])
    """
    def __init__(self, tab):
        """stores a numerical table tab

        :param array tab: containing numerical values
        :complexity: O(len(tab))
        """
        self.N = 1
        while self.N <= len(tab):
            self.N *= 2
        self.lazyset = [None] * (2*self.N)
        self.maxval = [float('-inf')] * (2*self.N)   # neutral element for the max
        for i, ti in enumerate(tab):
            self.lazyset[self.N + i] = ti
        for i in range(self.N - 1, 0, -1):
            self.maintain_invariant(i)

    def maintain_invariant(self, i):
        if self.lazyset[i] is not None:
            self.maxval[i] = self.lazyset[i]
        else:
            self.maxval[i] = max(self.maxval[2*i], self.maxval[2*i + 1])

    def max(self, j, k):
        return self._max(j, k, 1, 0, self.N)

    def _max(self, j, k,  i, left_i, right_i):
        if k <= left_i or right_i <= j:       # disjoint intervals
            return float('-inf')              # neutral element for the max
        if j <= left_i and  right_i <= k or self.lazyset[i] is not None:
            return self.maxval[i]             # recursion stops
        mid = (left_i + right_i) // 2
        x = self._max(j, k, 2*i,   left_i, mid)
        y = self._max(j, k, 2*i+1, mid,    right_i)
        return max(x, y)


    def set(self, j, k, v):
        self._set(j, k, v, 1, 0, self.N)

    def _set(self, j, k, v, i, left_i, right_i):
        if k <= left_i or right_i <= j:       # disjoint intervals
            return 0                          # neutral element for the sum
        if j <= left_i and  right_i <= k:     # included interval
            self.lazyset[i] = v               # set subtree to value v
        else:
            if self.lazyset[i] is not None:   # propagate previous set value to descendants
                self.maxval[2*i]     = self.lazyset[2*i]     = self.lazyset[i]
                self.maxval[2*i + 1] = self.lazyset[2*i + 1] = self.lazyset[i]
                self.lazyset[i] = None
            mid = (left_i + right_i) // 2     # split node interval
            self._set(j, k, v, 2*i,   left_i, mid)
            self._set(j, k, v, 2*i+1, mid,    right_i)
        self.maintain_invariant(i)



def test_segment_tree():
    T = SegmentTree([0] * 10)
    line = ['?']
    while len(line):
        print("> ", end='', flush=True)
        line = stdin.readline().split()
        if len(line) == 3:
            T.set(int(line[0]), int(line[1]), int(line[2]))
        elif len(line) == 2:
            print(T.max(int(line[0]), int(line[1])))
        elif len(line) == 1:
            print("input: ?     : this help message")
            print("input: j k v : sets value v to range [j:k]")
            print("input: j k   : queries max value in range [j:k]")
            # for i in range(T.N):
            #     print(T.query(i, i+1), end=' ')
            # print()
            print(T.lazyset)
            print(T.maxval)

test_segment_tree()
