A tree of size n is an undirected connected graph consisting of n vertices without cycles.

Consider some tree with n vertices. We call a tree invariant relative to permutation p = p1p2... pn, if for any two vertices of the tree u and v the condition holds: "vertices u and v are connected by an edge if and only if vertices pu and pv are connected by an edge".

You are given permutation p of size n. Find some tree size n, invariant relative to the given permutation.

Input

The first line contains number n (1 ≤ n ≤ 105) — the size of the permutation (also equal to the size of the sought tree).

The second line contains permutation pi (1 ≤ pi ≤ n).

Output

If the sought tree does not exist, print "NO" (without the quotes).

Otherwise, print "YES", and then print n - 1 lines, each of which contains two integers — the numbers of vertices connected by an edge of the tree you found. The vertices are numbered from 1, the order of the edges and the order of the vertices within the edges does not matter.

If there are multiple solutions, output any of them.

Examples

Input

4
4 3 2 1


Output

YES
4 1
4 2
1 3


Input

3
3 1 2


Output

NO

Note

In the first sample test a permutation transforms edge (4, 1) into edge (1, 4), edge (4, 2) into edge (1, 3) and edge (1, 3) into edge (4, 2). These edges all appear in the resulting tree.

It can be shown that in the second sample test no tree satisfies the given condition.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.PriorityQueue;
import java.util.StringTokenizer;



public final class CF_319_Invariance {

	void log(int[] X){
		int L=X.length;
		for (int i=0;i<L;i++){
			logWln(X[i]+" ");
		}
		log("");
	}


	void log(long[] X){
		int L=X.length;
		for (int i=0;i<L;i++){
			logWln(X[i]+" ");
		}
		log("");
	}
	void log(Object[] X){
		int L=X.length;
		for (int i=0;i<L;i++){
			logWln(X[i]+" ");
		}
		log("");
	}


	void log(Object o){
		logWln(o+"\n");
	}

	void logWln(Object o){
		//System.out.print(o);
		outputWln(o);

	}
	void info(Object o){
		System.out.println(o);
		//output(o);
	}

	void output(Object o){

		outputWln(""+o+"\n");

	}

	void outputWln(Object o){
		// System.out.print(o);

		try {
			out.write(""+ o);
		} catch (Exception e) {

		}
	}

	String solveKO(){
		// on va compter les cycles
		int[] gen=new int[N];
		ArrayList<ArrayList<Integer>>[] cycle=new ArrayList[N];
		for (int i=0;i<N;i++)
			cycle[i]=new ArrayList<ArrayList<Integer>>();

		String res="";
		boolean[] used=new boolean[N];
		for (int x=0;x<N;x++){
			if (!used[x]){
				ArrayList<Integer> list=new ArrayList<Integer>();
				list.add(x+1);
				used[x]=true;
				int cnt=0;
				int y=p[x];

				while (y!=x){
					used[y]=true;
					list.add(y+1);
					y=p[y];
					cnt++;
				}
				gen[cnt]++;
				cycle[cnt].add(list);
			}
		}
		log(gen);
		for (int i=0;i<N;i++){
			if (i%2==0 && gen[i]%2==1){
				return "NO";
			} 
			if (i%2==0) {
				for (int u=0;u<gen[i];u+=2){
					ArrayList<Integer> list1=cycle[i].get(u);
					ArrayList<Integer> list2=cycle[i].get(u+1);
					for (int v=0;v<i+1;v++){
						res+=list1.get(v)+" "+list2.get(v)+"\n";
					}
				}
			} else {
				//log("i:"+i+" cs:"+cycle[i].size());
				if (i+1!=2) {
					for (ArrayList<Integer> list:cycle[i]){
						for (int u=0;u+2<i+1;u++){
							res+=list.get(u)+" "+list.get(u+2)+"\n";
						}
					}
				} else {
					for (ArrayList<Integer> list:cycle[i]){
						res+=list.get(0)+" "+list.get(1)+"\n";
					}
				}
			}
		}
		//log("end");
		return "YES\n"+res.toString();
	}


	// bon, à perfectionner...Pas bon.
	void solve(){
		if (N==2) {
			output("YES");
			output("1 2");
			return;
		}
		if (N==1) {
			output("YES");
					return;
		}
		// on va compter les cycles
		boolean[] used=new boolean[N];
		boolean odd=false;
		int left=-1;
		int right=-1;
		int root=-1;
		int[] steps=new int[N];
		loop:for (int x=0;x<N;x++){
			if (!used[x]){
				used[x]=true;
				steps[x]=0;
				int cnt=0;
				int y=p[x];

				while (y!=x){
					steps[y]=++cnt;
					used[y]=true;
					y=p[y];
				}
				if (cnt==1){
					left=x+1;
					right=p[x]+1;
				}
				if (cnt==0) {
					root=x+1;
					break loop;
				}
				if (cnt%2==0)
					odd=true;
			}
		}

		// maintenant on fait l'hypothèse qu'il faut rattacher à du 1 ou du 2...
		if (root==-1 && left==-1){
			output("NO");
			return;
		}
	
	


		if (root>-1){
			output("YES");
			for (int x=0;x<N;x++) {
				if ((x+1)!=root)
					output(root+" "+(x+1));
			}
			return;
		}

		// si des impairs fini
		//log(values);
		if (odd) {
			output("NO");
			return;
		}
		output("YES");
		output(left+" "+right);
		for (int x=0;x<N;x++){
			if (x+1!=left && x+1!=right){
				if (steps[x]%2==0)
					output(left+" "+(x+1));
				else
					output(right+" "+(x+1));
			}
		}
		return;
	}
	int N;
	int[] p;

	BufferedWriter out;

	void process() throws Exception {


		out = new BufferedWriter(new OutputStreamWriter(System.out));
		InputReader reader=new InputReader(System.in);

		N=reader.readInt();
		p=new int[N];
		for (int i=0;i<N;i++)
			p[i]=reader.readInt()-1;

		solve();

		try {
			out.close();
		}
		catch (Exception e){}


	}



	public static void main(String[] args) throws Exception {
		CF_319_Invariance J=new CF_319_Invariance();

		J.process();


	}


	static final class InputReader {
		private final InputStream stream;
		private final byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		private int read() throws IOException {
			if (curChar >= numChars) {
				curChar = 0;
				numChars = stream.read(buf);
				if (numChars <= 0) {
					return -1;
				}
			}
			return buf[curChar++];
		}


		public final String readString() throws IOException {
			int c = read();
			while (isSpaceChar(c)) {
				c = read();
			}
			StringBuilder res=new StringBuilder();
			do {
				res.append((char)c);
				c = read();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public final int readInt() throws IOException {
			int c = read();
			boolean neg=false;
			while (isSpaceChar(c)) {
				c = read();
			}
			char d=(char)c;
			//log("d:"+d);
			if (d=='-') {
				neg=true;
				c = read();
			}
			int res = 0;
			do {
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			//log("res:"+res);
			if (neg)
				return -res;
			return res;

		}

		public final long readLong() throws IOException {
			int c = read();
			boolean neg=false;
			while (isSpaceChar(c)) {
				c = read();
			}
			char d=(char)c;
			//log("d:"+d);
			if (d=='-') {
				neg=true;
				c = read();
			}
			long res = 0;
			do {
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			//log("res:"+res);
			if (neg)
				return -res;
			return res;

		}




		private boolean isSpaceChar(int c) {
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}
	}

}