Problem: Spongebob is already tired trying to reason his weird actions and calculations, so he simply asked you to find all pairs of n and m, such that there are exactly x distinct squares in the table consisting of n rows and m columns. For example, in a 3 × 5 table there are 15 squares with side one, 8 squares with side two and 3 squares with side three. The total number of distinct squares in a 3 × 5 table is 15 + 8 + 3 = 26.

Input

The first line of the input contains a single integer x (1 ≤ x ≤ 1018) — the number of squares inside the tables Spongebob is interested in.

Output

First print a single integer k — the number of tables with exactly x distinct squares inside.

Then print k pairs of integers describing the tables. Print the pairs in the order of increasing n, and in case of equality — in the order of increasing m.

Examples

Input

26


Output

6
1 26
2 9
3 5
5 3
9 2
26 1


Input

2


Output

2
1 2
2 1


Input

8


Output

4
1 8
2 3
3 2
8 1

Note

In a 1 × 2 table there are 2 1 × 1 squares. So, 2 distinct squares in total.

<image>

In a 2 × 3 table there are 6 1 × 1 squares and 2 2 × 2 squares. That is equal to 8 squares in total.

<image>

Solution (in JAVA):

Solution:
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.ArrayList;
import java.util.Scanner;

public class Main {

	private static Scanner in = new Scanner(System.in);
	
	static public class Pair<T> {
		public T x,y;
		Pair(final T x,final T y) {
			this.x = x;
			this.y = y;
		}
	}
	
	public static void main(String[] args) {
		D();
	}
	
	public static void A() {
		int a = IOUtil.readInt();
		int b = IOUtil.readInt();
		int c = IOUtil.readInt();

		int ans = Math.min( Math.min(a + b + c,     2 * a + 2 * b)
				          , Math.min(2 * a + 2 * c, 2 * b + 2 * c) );

		System.out.println(ans);
	}
	
	public static void B() {
		int n = IOUtil.readInt();
		int m = IOUtil.readInt();
		
		int[] f  = new int[n];
		int[] fr = new int[n];
		int[] pl = new int[n];
		
		int[] b = new int[m];
		
		for (int i = 0; i < n; ++i) {
			f[i] = IOUtil.readInt() - 1;
			fr[ f[i] ] ++;
			pl[ f[i] ] = i + 1;
		}
		for (int i = 0; i < m; ++i) {
			b[i] = IOUtil.readInt() - 1;
		}
		for (int x : b) {
			//System.out.println("debug " + x + " " + fr[x]);
			if ( fr[x] == 0 ) {
				System.out.println("Impossible");
				return;
			}
		}
		for (int x : b) {
			if ( fr[x] > 1 ) {
				System.out.println("Ambiguity");
				return;
			}
		}
		
		System.out.println("Possible");
		for (int x : b) {
			System.out.print(pl[x] + " ");
		}
		System.out.println();
	}
	
	public static void C() {
		int   n  = IOUtil.readInt();
		int[] h  = new int[n];
		
		for (int i = 0; i < n; ++i) {
			h[i] = IOUtil.readInt();
		}
		
		int[] max = new int[n];
		
		max[0] = h[0];
		for (int i = 1; i < n; ++i) {
			max[i] = Math.max(h[i], max[i - 1]);
		}
		
		int[]min = new int[n + 1];
		
		min[n] = Integer.MAX_VALUE;
		for (int i = n - 1; i >= 0; --i) {
			min[i] = Math.min(h[i], min[i + 1]);
		}

		int ans = 0;
		for (int i = 0; i < n; ++i) {
			if (min[i + 1] >= max[i]) {
				++ans;
			}
		}
		System.out.println(ans);	
	}
	
	public static void D() {
		long n = in.nextLong();
		
		ArrayList<Pair<Long> > ans = new ArrayList<Pair<Long> >();
		ans.add(new Pair<Long>(new Long(1), new Long(n)));
		
		long sub = 0;
		for (long i = 2; i*(i+1)*(2*i+1)/6 <= n; i++) {
			long mult = i * (i+1)/2;
			if (sub == 0) { 
				sub = 1;
			}
			else {
				sub += i*(i-1)/2;
			}
			if( (n + sub) % mult == 0)
				ans.add(new Pair(new Long(i), new Long( (n+sub) / mult ) ) );
		}
		
		for (int i = ans.size()-1; i >= 0; i--) {
			Pair<Long> elem = ans.get(i);
			if( ! elem.x.equals(elem.y) )
				ans.add(new Pair(elem.y, elem.x));
		}
		System.out.println(ans.size());
		for(Pair<Long> p : ans) {
			System.out.printf("%d %d\n", p.x.longValue() , p.y.longValue() );
		}
	}
	
	static public class IOUtil {

		private static StreamTokenizer tokenizer = new StreamTokenizer(
				new InputStreamReader(System.in));

		public static double readDouble() {

			tokenizer.resetSyntax();
			tokenizer.whitespaceChars(0, ' ');
			tokenizer.wordChars(33, 255);

			try {
				if (tokenizer.nextToken() == StreamTokenizer.TT_EOF) {
					throw new IOException("End Of File found.");
				} else {
					return Double.parseDouble(tokenizer.sval);
				}
			} catch (NumberFormatException nfe) {
				return readDouble();
			} catch (java.io.IOException e) {
				throw new RuntimeException(e);
			}
		}

		public static float readFloat() {

			tokenizer.resetSyntax();
			tokenizer.whitespaceChars(0, ' ');
			tokenizer.wordChars(33, 255);

			try {
				if (tokenizer.nextToken() == StreamTokenizer.TT_EOF) {
					throw new IOException("End Of File found.");
				} else {
					return Float.parseFloat(tokenizer.sval);
				}
			} catch (NumberFormatException nfe) {
				return readFloat();
			} catch (java.io.IOException e) {
				throw new RuntimeException(e);
			}
		}

		public static int readInt() {

			try {

				tokenizer.resetSyntax();
				tokenizer.whitespaceChars(0, ' ');
				tokenizer.wordChars(33, 255);

				if (tokenizer.nextToken() == StreamTokenizer.TT_EOF) {
					throw new IOException("End Of File found.");
				} else {
					return (int) Double.parseDouble(tokenizer.sval);
				}
			} catch (NumberFormatException nfe) {
				return readInt();
			} catch (java.io.IOException e) {
				throw new RuntimeException(e);
			}
		}

		public static String readString() {
			try {
				tokenizer.resetSyntax();
				tokenizer.whitespaceChars(0, ' ');
				tokenizer.wordChars(33, 255);

				if (tokenizer.nextToken() == StreamTokenizer.TT_EOF) {
					throw new IOException("End Of File found.");
				} else {
					return tokenizer.sval;
				}
			} catch (java.io.IOException e) {
				throw new RuntimeException(e);
			}

		}

	}
}