There are n psychos standing in a line. Each psycho is assigned a unique integer from 1 to n. At each step every psycho who has an id greater than the psycho to his right (if exists) kills his right neighbor in the line. Note that a psycho might kill and get killed at the same step. 

You're given the initial arrangement of the psychos in the line. Calculate how many steps are needed to the moment of time such, that nobody kills his neighbor after that moment. Look notes to understand the statement more precise.

Input

The first line of input contains integer n denoting the number of psychos, (1 ≤ n ≤ 105). In the second line there will be a list of n space separated distinct integers each in range 1 to n, inclusive — ids of the psychos in the line from left to right.

Output

Print the number of steps, so that the line remains the same afterward.

Examples

Input

10
10 9 7 8 6 5 3 4 2 1


Output

2


Input

6
1 2 3 4 5 6


Output

0

Note

In the first sample line of the psychos transforms as follows: [10 9 7 8 6 5 3 4 2 1]  →  [10 8 4] →  [10]. So, there are two steps.
import java.util.*;
import java.io.*;
import java.math.*;

import static java.lang.Math.*;

public class Solution implements Runnable {

	class SegmentTree {
		
		int n;
		int [] tmax;
		
		public SegmentTree(int n) {
			this.n = n;
			tmax = new int [4 * n];
			Arrays.fill(tmax, -1);
		}
		
		private void update (int v, int tl, int tr, int pos, int val) {
			if (tl == tr) {
				tmax[v] = val;
			} else {
				int tm = (tl + tr) >> 1;
				if (pos <= tm)
					update (v * 2, tl, tm, pos, val);
				else
					update (v * 2 + 1, tm + 1, tr, pos, val);
				tmax[v] = max (tmax[v * 2], tmax[v * 2 + 1]);
			}
		}
		
		public void update (int pos, int val) {
			update (1, 0, n - 1, pos, val);
		}
		
		private int getMax (int v, int tl, int tr, int l, int r) {
			if (l > r) return -1;
			if (l == tl && r == tr)
				return tmax[v];
			int tm = (tl + tr) >> 1;
			return max (getMax(v * 2, tl, tm, l, min (r, tm)), getMax (v * 2 + 1, tm + 1, tr, max (l, tm + 1), r));
		}
		
		public int getMax (int l, int r) {
			return getMax (1, 0, n - 1, l, r);
		}

	}
	
	int brute (int n, int a []) {
		int b [] = new int [n];
		for (int i = 0; i < n; i++)
			b[i] = a[i];
		
		int result = 0;
		
		while (true) {
			boolean delete [] = new boolean [n];
			boolean del = false;
			
			int m = n;
			for (int i = n - 2; i >= 0; i--) {
				if (b[i] > b[i + 1]) {
					delete[i + 1] = true;
					del = true;
					m--;
				}
			}
			
			if (!del)
				break;
			
			result++;
			int c [] = new int [m];
			m = 0;
			for (int i = 0; i < n; i++)
				if (!delete[i])
					c[m++] = b[i];
			
			n = m;
			b = new int [n];
			for (int i = 0; i < n; i++)
				b[i] = c[i];
		}
		return result;
	}
	
	public void solve() throws Throwable {
		int n = sc.nextInt();
		int a [] = new int [n];
		for (int i = 0; i < n; i++) {
			a[i] = sc.nextInt();
		}
			
		int startPos [] = new int [n];
		
		SegmentTree treePos = new SegmentTree(n);
		int prev = -1, start = -1;
		for (int i = 0; i < n; i++) {
			if (prev == -1) {
				start = i;
				prev = a[i];
			} else {
				if (a[i] > prev) {
					prev = a[i];
				} else {
					start = i;
					prev = a[i];
				}
			}
			treePos.update(i, i - start + 1);
			startPos[i] = start;
		}
		
		SegmentTree treeVal = new SegmentTree(n + 1);
		SegmentTree treeAns = new SegmentTree(n);
		int ans = 0;
		for (int i = 0; i < n; i++) {
			int l = treeVal.getMax(a[i] + 1, n);
			treeVal.update(a[i], i);
			if (l == -1) continue;
			int value = max (treePos.getMax(l + 1, startPos[i] - 1) + 1, treePos.getMax(i, i));
			value = max (value, treeAns.getMax(l + 1, i) + 1);
			ans = max (ans, value);
			treeAns.update(i, value);
		}
		
		out.println(ans);
	}

	static Throwable t;

	BufferedReader in;
	FastScanner sc;
	PrintWriter out;

	@Override
	public void run() {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			sc = new FastScanner(in);
			out = new PrintWriter(System.out);
			solve();
		} catch (Throwable t) {
			Solution.t = t;
		} finally {
			out.close();
		}
	}

	public static void main(String[] args) throws Throwable {
		Thread thread = new Thread(null, new Solution(), "", 1 << 26);
		thread.start();
		thread.join();
		if (Solution.t != null)
			throw t;
	}

}

class FastScanner {

	BufferedReader in;
	StringTokenizer st;

	public FastScanner(BufferedReader in) {
		this.in = in;
	}

	public String nextToken() throws Exception {
		while (st == null || !st.hasMoreTokens())
			st = new StringTokenizer(in.readLine());
		return st.nextToken();
	}

	public int nextInt() throws Exception {
		return Integer.parseInt(nextToken());
	}

	public long nextLong() throws Exception {
		return Long.parseLong(nextToken());
	}

	public double nextDouble() throws Exception {
		return Double.parseDouble(nextToken());
	}

}