Problem:
Range Update Query (RUQ)

Write a program which manipulates a sequence A = {a0, a1, . . . , an−1} with the following operations:

update(s, t, x): change as, as+1, ..., at to x.

find(i): output the value of ai.

Note that the initial values of ai (i = 0, 1, . . . , n−1) are 231-1.

Input

n q
query1
query2
:
queryq

In the first line, n (the number of elements in A) and q (the number of queries) are given. Then, ith query queryi is given in the following format:

0 s t x

or

1 i

The first digit represents the type of the query. '0' denotes update(s, t, x) and '1' denotes find(i).

Output

For each find operation, print the value.

Constraints

1 ≤ n ≤ 100000

1 ≤ q ≤ 100000

0 ≤ s ≤ t < n

0 ≤ i < n

0 ≤ x < 231−1

Sample Input 1

3 5
0 0 1 1
0 1 2 3
0 2 2 2
1 0
1 1

Sample Output 1

1
3

Sample Input 2

1 3
1 0
0 0 0 5
1 0

Sample Output 2

2147483647
5

Solution in JAVA (judge verdict: Accepted)

import java.util.*;
import java.lang.*;

class Main {
	static int[] segTree;
	static int n;

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		n = scanner.nextInt();
		int q = scanner.nextInt();

		initSegTree();

		for(int i = 0; i < q; i++) {
			int type = scanner.nextInt();

			if(type == 0) {
				int s = scanner.nextInt();
				int t = scanner.nextInt();
				int x = scanner.nextInt();

				// Change a[s] ... a[t] to x
				update(s,t,x);

			} else if(type == 1) {
				// Find value of a[i]
				int result = find(scanner.nextInt());
				System.out.println(result);
			}
		}
	}

	static void initSegTree() {
		int _n = 1;
		while(_n < n)
			_n *= 2;

		segTree = new int[2*_n];
		Arrays.fill(segTree, Integer.MAX_VALUE);
	}

	static void update(int s, int t, int x) {
		updateRange(1, 0, n, s, t+1, x);
	}

	/*	k: index of current node in segTree
		l & r: range covered by node k
		s & t: range of query
		x: new value to update
	*/
	static void updateRange(int k, int l, int r, int s, int t, int x) {

		if(s >= t) // out of range
			return;

		if(s == l && t == r) { // (s,t) fully inside (l,r)
			segTree[k] = x;
			return;
		}

		if(segTree[k] >= 0) {
			segTree[k*2] = segTree[k];
			segTree[k*2+1] = segTree[k];
			segTree[k] = -1;
		}

		// (s,t) and (l,r) intersect
		int mid = (l+r)/2;
		updateRange(k*2, l, mid, Math.max(s,l), Math.min(mid,t), x);
		updateRange(k*2+1, mid, r, Math.max(s,mid), Math.min(r,t), x);
	}

	static int find(int i) {
		return find(i, 0, n, 1);
	}

	static int find(int i, int l, int r, int k) {
		if(segTree[k] >= 0)
			return segTree[k];
		else {
			int mid = (l+r)/2;
			if(i < mid)
				return find(i,l,mid,k*2);
			else
				return find(i,mid,r,k*2+1);
		}
	}
}