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.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.lang.reflect.Array;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

public class a {
	public static int k;

	public static class node implements Comparable<node> {
		long x;
		long y;

		node(long x, long y) {
			this.x = x;
			this.y = y;

		}

		@Override
		public int compareTo(node o) {
			if (o.x < x)
				return 1;
			else if (o.x > x)
				return -1;
			else if (o.y < y)
				return 1;
			else if (o.y > y)
				return -1;
			return 0;
		}

	}

	public static class point {
		int x;
		int y;

		point(int x, int val) {
			this.x = x;
			this.y = val;
		}

	}

	public static BigInteger gcd(BigInteger a, BigInteger b) {
		if (b.equals(BigInteger.ZERO))
			return a;
		return gcd(b, a.mod(b));
	}

	public static long gcd1(long a, long b) {
		if (b == 0)
			return a;
		return gcd1(b, a % b);
	}

	public static ArrayList<Integer> prime;

	public static void sieve(int n) {
		boolean vis[] = new boolean[n + 5];
		vis[1] = true;
		vis[0] = true;
		for (int i = 2; i <= n; i++) {
			if (!vis[i]) {
				prime.add(i);
				for (long j = (long) i * (long) i; j <= n; j += i) {
					vis[(int) j] = true;
				}
			}
		}
	}

	public static int tree[][];
	public static boolean end[][];
	public static int counter;

	public static void trie(String a) {
		int st = 0;

		for (int i = 0; i < a.length(); i++) {
			if (tree[a.charAt(i) - 'a'][st] == 0) {
				tree[a.charAt(i) - 'a'][st] = counter++;
			}

			st = tree[a.charAt(i) - 'a'][st];
		}
		end[a.charAt(a.length() - 1) - 'a'][st] = true;

	}

	public static int seg[][];

	public static int get(int s, int e, int p, int from, int to, int seg[]) {
		if (s >= from && e <= to)
			return seg[p];
		if (s > to || e < from)
			return 0;
		int mid = (s + e) / 2;
		int one = get(s, mid, p * 2, from, to, seg);
		int two = get(mid + 1, e, p * 2 + 1, from, to, seg);
		return Math.max(one, two);
	}

	public static long comp(int n, int r) {
		long ans = 1;
		r = Math.min(r, n - r);
		for (int i = 1; i <= r; i++) {
			ans = ans * ((long) n - (long) i + 1L) / (long) i;
		}
		return ans;
	}

	public static ArrayList<Integer> arr[];
	public static boolean vis[];
	public static Stack<Integer> S;

	public static void bfs(int node) {
		for (int i = 0; i < arr[node].size(); i++) {
			int k = arr[node].get(i);
			if (vis[k] == false) {
				vis[k] = true;
				S.push(k);
				bfs(k);
			}
		}
		S.push(node);
	}

	public static void dfs(int node) {

		for (int i = 0; i < arr[node].size(); i++) {
			int k = arr[node].get(i);
			if (vis[k] == false) {
				vis[k] = true;
				dfs(k);
			}
		}
	}

	public static boolean chPrime(int r) {

		for (int i = 2; i * i <= r; i++) {
			if (r % i == 0)
				return false;
		}
		return true;
	}

	public static int len(long ai) {
		String temp = "" + ai;

		return temp.length();
	}

	public static int f_digit(long ai) {
		String temp = "" + ai;

		return (temp.charAt(0) - '0');

	}

	public static double cross(node a, node b) {

		return a.x * b.y - b.x * a.y;
	}

	public static double dot(node a, node b) {

		return a.x * b.x + a.y * b.y;
	}

	public static double sqrt(node a) {
		double e = Math.sqrt((double) a.x * (double) a.x + (double) a.y
				* (double) a.y);
		return e;
	}

	public static double theta(node a, node b) {

		// double theta = Math.atan2((double) Math.abs(cross(a, b)),
		// (double) dot(a, b));

		double theta = (double) Math.acos((double) dot(a, b)
				/ ((sqrt(a)) * sqrt(b)));
		return theta;
	}

	public static int binary(int a[], int val) {

		int low = 0;
		int high = a.length;

		int mid = (low + high) / 2;
		while (high - low > 1) {
			if (a[mid] <= val) {
				low = mid;
			} else if (a[mid] > val)
				high = mid;

			mid = (low + high) / 2;
		}
		if (a[high] == val)
			return high;
		return low;
	}

	public static long mod = (long) Math.pow(10, 9) + 7;

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		// BufferedReader in = new BufferedReader(new FileReader("cubes.in"));
		// System.out.println(-70 % 3);
		StringBuilder qq = new StringBuilder();
		PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
		// int aa[] = { 1, 2, 5 };
		// System.out.println(Arrays.binarySearch(aa, 0));
		// String y[] = in.readLine().split(" ");
		long N = Long.parseLong(in.readLine());

		PriorityQueue<node> q = new PriorityQueue<>();
		long n = 1;
		while (true) {
			long m = 6L * N + 3L * n * n * (n - 1) -  (n-1) * n * (2L*n-1L);
			long k = 3L * n * (n + 1);
			if (m % k == 0) {
				m /= k;
				
				if (m >= n) {
					q.add(new node(n, m));
					if (m != n)
						q.add(new node(m, n));
				}
				
			} else
				m /= k;

			if (m <= n)
				break;
			n++;
		}
		out.println(q.size());
		while (!q.isEmpty()) {
			node e = q.poll();

			out.println(e.x + " " + e.y);
		}

		out.close();

	}
}