Problem:
Score : 500 points

Problem Statement

You are given a sequence (P_1,P_2,...,P_N) which is a permutation of the integers from 1 through N.
You would like to sort this sequence in ascending order by repeating the following operation:

Choose an element in the sequence and move it to the beginning or the end of the sequence.

Find the minimum number of operations required.
It can be proved that it is actually possible to sort the sequence using this operation.

Constraints

1 \leq N \leq 2\times 10^5

(P_1,P_2,...,P_N) is a permutation of (1,2,...,N).

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
P_1
:
P_N

Output

Print the minimum number of operations required.

Sample Input 1

4
1
3
2
4

Sample Output 1

2

For example, the sequence can be sorted in ascending order as follows:

Move 2 to the beginning. The sequence is now (2,1,3,4).

Move 1 to the beginning. The sequence is now (1,2,3,4).

Sample Input 2

6
3
2
5
1
4
6

Sample Output 2

4

Sample Input 3

8
6
3
1
2
7
4
8
5

Sample Output 3

5

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class TEST{
	static void Main(){
		Sol mySol =new Sol();
		mySol.Solve();
	}
}

class Sol{
	public void Solve(){
		
		Pair[] P = new Pair[N];
		for(int i=0;i<N;i++){
			P[i] = new Pair(A[i],i);
		}
		Array.Sort(P, (p,q) => p.V.CompareTo(q.V));
		
		var UF = new UnionFind(N);
		for(int i=0;i<N-1;i++){
			if(P[i+1].Idx > P[i].Idx){
				UF.Unite(i, i + 1);
			}
		}
		
		int max = 1;
		for(int i=0;i<N;i++){
			if(UF.IsRoot(i)){
				max = Math.Max(max, UF.MemCnt(i));
			}
		}
		
		Console.WriteLine(N - max);
		
	}
	class Pair {
		public int V, Idx;
		public Pair(int v, int idx){
			V = v; Idx = idx;
		}
	}
	
	int N;
	int[] A;
	public Sol(){
		N = ri();
		A = new int[N];
		for(int i=0;i<N;i++) A[i] = ri();
	}

	static String rs(){return Console.ReadLine();}
	static int ri(){return int.Parse(Console.ReadLine());}
	static long rl(){return long.Parse(Console.ReadLine());}
	static double rd(){return double.Parse(Console.ReadLine());}
	static String[] rsa(char sep=' '){return Console.ReadLine().Split(sep);}
	static int[] ria(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>int.Parse(e));}
	static long[] rla(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>long.Parse(e));}
	static double[] rda(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>double.Parse(e));}
}


class UnionFind{
	
	int[] parent;
	int[] mem;
	int compo;
	int N;
	
	public UnionFind(UnionFind v){
		// copy constructor
		N = v.N;
		parent = new int[N];
		mem = new int[N];
		for(int i=0;i<N;i++){
			parent[i] = v.parent[i];
			mem[i] = v.mem[i];
		}
		compo = v.compo;
	}
	public UnionFind(int n_){
		Initialize(n_);
	}
	
	public void Initialize(int n_){
		N = n_;
		parent = new int[N];
		mem=new int[N];
		for(int i=0;i<N;i++){
			parent[i] = i;
			mem[i] = 1;
		}
		compo = N;
	}
	
	public int Parent(int a){
		if(parent[a] == a)return a;
		return parent[a] = Parent(parent[a]);
	}
	
	public bool IsUnited(int a,int b){
		return Parent(a) == Parent(b);
	}
	
	public void Unite(int a,int b){
		a = Parent(a); b = Parent(b);//Parent()を呼ぶことでa以上のノードは全てparentがrootになる
		if(a == b)return;
		parent[a] = b;
		mem[b] += mem[a];
		compo -= 1;
	}
	
	public bool IsRoot(int x){
		return x == parent[x];
	}
	public int MemCnt(int x){
		return mem[Parent(x)];
	}
	
	public void Dump(){
		for(int i=0;i<parent.Length;i++){
			Console.Write(i == 0 ? "{0}" : " {0}",parent[i]);
		}
		Console.WriteLine("");
	}
	
	public int Compo{
		get{
			return compo;
		}
	}
	
}