Problem: A Christmas party in city S. had n children. All children came in mittens. The mittens can be of different colors, but each child had the left and the right mitten of the same color. Let's say that the colors of the mittens are numbered with integers from 1 to m, and the children are numbered from 1 to n. Then the i-th child has both mittens of color ci.

The Party had Santa Claus ('Father Frost' in Russian), his granddaughter Snow Girl, the children danced around the richly decorated Christmas tree. In fact, everything was so bright and diverse that the children wanted to wear mittens of distinct colors. The children decided to swap the mittens so that each of them got one left and one right mitten in the end, and these two mittens were of distinct colors. All mittens are of the same size and fit all the children.

The children started exchanging the mittens haphazardly, but they couldn't reach the situation when each child has a pair of mittens of distinct colors. Vasily Petrov, the dad of one of the children, noted that in the general case the children's idea may turn out impossible. Besides, he is a mathematician and he came up with such scheme of distributing mittens that the number of children that have distinct-colored mittens was maximum. You task is to repeat his discovery. Note that the left and right mittens are different: each child must end up with one left and one right mitten.

Input

The first line contains two integers n and m — the number of the children and the number of possible mitten colors (1 ≤ n ≤ 5000, 1 ≤ m ≤ 100). The second line contains n integers c1, c2, ... cn, where ci is the color of the mittens of the i-th child (1 ≤ ci ≤ m).

Output

In the first line, print the maximum number of children who can end up with a distinct-colored pair of mittens. In the next n lines print the way the mittens can be distributed in this case. On the i-th of these lines print two space-separated integers: the color of the left and the color of the right mitten the i-th child will get. If there are multiple solutions, you can print any of them.

Examples

Input

6 3
1 3 2 2 1 1


Output

6
2 1
1 2
2 1
1 3
1 2
3 1


Input

4 2
1 2 1 1


Output

2
1 2
1 1
2 1
1 1

Solution (in JAVA):

Solution:
import java.util.*;
import java.lang.*;
import java.io.*;
import java.math.*;

/*
 * @author Mahmoud Aladdin <aladdin3>
 *
 */
 
public class Main {
    public static void main (String[] args) throws java.lang.Exception {
		InputReader scan = new InputReader(System.in);
		PrintWriter writer = new PrintWriter(System.out, true);
		(new Main(scan, writer)).run();
		writer.close();
    }
    
    private InputReader jin;
    private PrintWriter jout;
    
    public Main(InputReader in, PrintWriter out) {
    	this.jin  = in;
    	this.jout = out;
    }
    
    public void run() throws Exception {
		int n = jin.integer();
		int m = jin.integer();
		int[] color = new int[m + 1];
		Arrays.fill(color, 0);
		FlowNetwork test = new FlowNetwork();
		for(int i = 1; i <= n; i++) {
			color[jin.integer()]++;
		}
		for(int i = 1; i <= m; i++) {
			for(int j = 1; j <= m; j++) {
				if(i == j) continue;
				test.addEdge(i, j + m, Math.min(color[i], color[j]), 0);
			}
			test.addEdge(0, i, color[i], 0);
		}
		for(int j = 1; j <= m; j++) {
			test.addEdge(j + m, 2 * m + 1, color[j], 0);
		}
		int flow = test.maxFlow(0, 2 * m + 1);
		jout.println(flow);
		StringBuffer out = new StringBuffer();
		for(FlowNetwork.Edge e: test.getEdges()) {
			if(e.org != e.cap && e.s != 0 && e.e != 2 * m + 1 && e.s <= m && e.e > m) {
				int r = e.org - e.cap;
				color[e.s] -= r;
				for(int i = 0; i < r; i++)
					out.append(e.s).append(" ").append(e.e - m).append("\n");
			}
		}
		jout.print(out);
		for(int i = 0; i <= m; i++) {
			while(color[i] > 0) {
				jout.println(i + " " + i);
				color[i]--;
			}
		}
    }
}

class FlowNetwork {
	class Edge {
		int s;
		int e;
		int org;
		int cap;
		int cost;
		Edge next;
		Edge other;
		
		public Edge(int s, int e, int org, int cap, int cost, Edge next) {
			this.s = s; this.e = e;
			this.cap = cap; this.org = org;
			this.cost = cost;
			this.next = next;
		}
		
		public String toString() {
			StringBuffer str = new StringBuffer();
			str.append(s).append("->").append(e).append("|").append(cap).append("/").append(org);
			return str.toString();
		}
	}
	
	int maxNode;
	List<Edge> edges = new ArrayList<Edge>();
	Map<Integer, Edge> path;
	Map<Integer, Edge> next = new HashMap<Integer, Edge>();
	
	final int INF = Integer.MAX_VALUE / 2;
	
	int minCost = 0;
	
	List<Edge> getEdges() {
		return edges;
	}
	
	void addEdge(int a, int b, int cap, int cost) {
		Edge e1 = new Edge(a, b, cap, cap, cost, next.get(a));
		Edge e2 = new Edge(b, a, cap, 0, -cost, next.get(b));
		
		e1.other = e2; e2.other = e1;
		edges.add(e1); edges.add(e2);
		next.put(a, e1); next.put(b, e2);

		maxNode = Math.max(a, Math.max(b, maxNode));
	}
	
	int bellmanFord(int src, int sink) {
		path = new HashMap<Integer, Edge>();
		int[] d = new int[maxNode + 1];
		Arrays.fill(d, INF);
		d[src] = 0;
		for(int i = 0; i < maxNode; i++) {
			for(Edge e: edges) {
				if (d[e.e] > d[e.s] + e.cost && e.cap > 0) {
					d[e.e] = d[e.s] + e.cost;
					path.put(e.e, e);
				}
			}
		}
		return d[sink];	
	}
	 
	int augmentPath(int p, int minEdge) {
		if(path.get(p) == null) {
			return minEdge;
		} else {
			Edge ee = path.get(p);
			int flow = augmentPath(ee.s, Math.min(minEdge, ee.cap));
			ee.cap -= flow;
			ee.other.cap += flow;
			return flow;
		}
	}
	
	int[] minCostMaxFlow(int src, int sink) {
		int maxFlow = 0;
		int minCost = 0;
		
		int tempCost;
		while((tempCost = bellmanFord(src, sink)) != INF) {
			int flow = augmentPath(sink, INF);
			minCost += (flow * tempCost);
			maxFlow += flow;
		}
		
		return new int[]{maxFlow, minCost};
	}
	
	boolean bfs(int src, int sink) {
		boolean[] vis = new boolean[maxNode + 1];
		Queue<Integer> que = new LinkedList<Integer>();
		path = new HashMap<Integer, Edge>();
		que.add(src); vis[src] = true;
		while(!que.isEmpty()) {
			int tsrc = que.poll();
			if(tsrc == sink) return true;
			for(Edge e = next.get(tsrc); e != null; e = e.next) {
				if(!vis[e.e] && e.cap > 0) {
					vis[e.e] = true;
					que.add(e.e);
					path.put(e.e, e);
				}	
			}
		}
		return false;
	}
	
	int maxFlow(int src, int sink) {
		int maxFlow = 0;
		while(bfs(src, sink)) {
		
			maxFlow += augmentPath(sink, INF);
		}
		return maxFlow;
	}
}
 
class InputReader {
    private static final int bufferMaxLength = 1024;
    private InputStream in;
    private byte[] buffer;
    private int currentBufferSize;
    private int currentBufferTop;
    private static final String tokenizers = " \t\r\f\n";
    
    public InputReader(InputStream stream) {
        this.in = stream;
        buffer = new byte[bufferMaxLength];
        currentBufferSize = 0;
        currentBufferTop = 0;
    }
    
    private boolean refill() throws IOException {
        this.currentBufferSize = this.in.read(this.buffer);
        this.currentBufferTop = 0;
        return this.currentBufferSize > 0;
    }
    
    
    private Byte readChar() throws IOException {
        if(currentBufferTop < currentBufferSize) {
            return this.buffer[this.currentBufferTop++];
        } else {
            if(!this.refill()) {
                return null;
            } else {
                return readChar();
            }
        }
    }
    
    
    public String token() throws IOException {
        StringBuffer tok = new StringBuffer();
        Byte first;
        while((first = readChar()) != null && (tokenizers.indexOf((char) first.byteValue()) != -1));
        if(first == null) return null;
        tok.append((char)first.byteValue());
        while((first = readChar()) != null && (tokenizers.indexOf((char) first.byteValue()) == -1)) {
            tok.append((char)first.byteValue());
        }
        return tok.toString();
    }
    
    public String line() throws IOException {
		Byte first;
		StringBuffer line = new StringBuffer();
		while ((first = readChar()) != null && (char)first.byteValue() != '\n') {
			line.append((char)first.byteValue());
		}
		return (first == null && line.length() == 0)? null : line.toString();
    }
    
    public Integer integer() throws NumberFormatException, IOException {
        String tok = token();
        return tok == null? null : Integer.parseInt(tok);
    }
    
}