// Arup Guha
// 11/23/2016
// Solution to 2016 NAQ Problem F: Free Desserts

import java.util.*;

public class freedesserts {

	public static long sum;
	public static int[] sumDigits;

	public static long[][][][] memo;
	public static int maskSum;

	public static int[] bitValues;

	public static int printCount;

	public static void main(String[] args) {

		// Get input.
		Scanner stdin = new Scanner(System.in);
		sum = stdin.nextLong();
		long savesum = sum;

		printCount = 0;

		// Store as digits.
		ArrayList<Integer> digits = new ArrayList<Integer>();
		while (sum > 0) {
			digits.add((int)(sum%10));
			sum = sum/10;
		}

		bitValues = new int[10];
		for (int i=0; i<10; i++)
			bitValues[i] = i;

		// Copy to array - store reverse order.
		sumDigits = new int[digits.size()];
		maskSum = 0;
		for (int i=0; i<digits.size(); i++) {
			sumDigits[i] = digits.get(i);
			maskSum = maskSum | (1<<sumDigits[i]);
		}

		// Set these for mask compression.
		for (int i=0; i<10; i++)
			if ((maskSum & (1<<i)) != 0)
				for (int j=i; j<10; j++)
					bitValues[j]--;

		int sub = Integer.bitCount(maskSum);

		// Fill memo table to uninitialized.
		memo = new long[1<<(10-sub)][1<<(10-sub)][sumDigits.length][4];
		for (int i=0; i<(1<<(10-sub)); i++)
			for (int j=0; j<(1<<(10-sub)); j++)
				for (int k=0; k<sumDigits.length; k++)
					Arrays.fill(memo[i][j][k], -1);

		// Run it!
		System.out.println(solve(0, 0, 0, 0, 0));

		// Output answers here.

		// Set up number of digits in A, B and initial carry.
		int n = sumDigits.length, carry = 0;
		if (sumDigits[sumDigits.length-1] == 1) {
			n--;
			carry = 1;
		}

		// Call it!
		int[] a = new int[n];
		int[] b = new int[n];
		print(0, 0, a, b, n-1, carry, true);
	}

	public static void print(int maskA, int maskB, int[] a, int[] b, int k, int carry, boolean eq) {

		// Stop!
		if (printCount >= 5000) return;

		// This is good, so print it.
		if (k == -1 && carry == 0) {
			printOut(a, b);
			printCount++;
			return;
		}

		// Not allowed.
		if (k == -1) return;

		// These are the digits we haven't used yet.
		int unusedMask = (1<<10) - 1 - maskA - maskB;

		// Try each digit in slot k.
		for (int i=0; i<10; i++) {

			// Digit is either in sum or number b so we can't use this.
			if (i>0 && (((1<<i) & maskSum) != 0)) continue;
			if (i>0 && (((1<<i) & maskB) != 0)) continue;

			// Special check for 0 since leading 0s don't count against maskA.
			if (i == 0 && maskA !=0 && (((1<<i) & maskSum) != 0)) continue;
			if (i == 0 && maskA !=0 && (((1<<i) & maskB) != 0)) continue;

			// Calculate what digitB would be if digitA is i.
			int digitB = 0;
			if (carry == 1)
				digitB = 10 + sumDigits[k] - i;
			else
				digitB = sumDigits[k] - i;

			// Carry can be 0 or 1 from next location.
			for (int myC=0; myC<2; myC++) {

				// Calculate b with the carry myC.
				int myB = digitB-myC;
				if (myB < 0 || myB >= 10) continue;

				// Conditions where digit B is used elsewhere.
				if ( ((((1<<myB) & maskA)) != 0) || ((((1<<myB) & maskSum)) != 0) ) continue;
				if (i == myB && i != 0) continue;
				if (i == myB && i == 0 && (maskA != 0 && maskB != 0)) continue;

				// Calculate the new masks for our recursive call.
				int newMaskA = (maskA | (1<<i));
				if (maskA == 0 && i == 0) newMaskA = 0;
				int newMaskB = (maskB | (1<<myB));
				if (maskB == 0 && myB == 0) newMaskB = 0;
				a[k] = i;
				b[k] = myB;

				// This isn't allowed since we need a < b.
				if (eq && a[k] > b[k]) continue;

				// Update if a and b are still equal.
				boolean newEq = !eq ? false : true;
				if (newEq && a[k] < b[k]) newEq = false;

				// Recursively print...stop at 5000 still.
				print(newMaskA, newMaskB, a, b, k-1, myC, newEq);
				if (printCount >= 5000) return;
			}
		}
	}

	// Just to help output.
	public static void printOut(int[] a, int[] b) {
		System.out.println(convert(a)+" "+convert(b));
	}

	// Returns a as a single long. a stores digits.
	public static long convert(int[] a) {
		long res = 0L;
		for (int i=a.length-1; i>=0; i--)
			res = 10*res + a[i];
		return res;
	}


	// Solves the given problem assuming we've used maskA and maskB digits for a and b, are filling out slot k
	// (with place value 10^k) have a current carry of carry,
	public static long solve(int maskA, int maskB, int k, int carry, int lastZero) {

		int maskAcode = compress(maskA);
		int maskBcode = compress(maskB);

		// See if we can stop number A now!
		long res = isValid(k, carry, lastZero, maskA);

		//if (res == 1) System.out.println("ret 1 "+maskA+" "+maskB+" "+k+" "+carry+" "+lastZero);

		// We finished filling out the answer!
		if (k == sumDigits.length) return res;
		if (k == sumDigits.length-1 && carry == 1 && sumDigits[sumDigits.length-1] == 1) return res;

		if (memo[maskAcode][maskBcode][k][2*carry+lastZero] != -1) return memo[maskAcode][maskBcode][k][2*carry+lastZero];

		// These are the digits we haven't used yet.
		int unusedMask = (1<<10) - 1 - maskA - maskB;

		// Try each digit in slot k.
		for (int i=0; i<10; i++) {

			// Digit is either in sum or number b so we can't use this.
			if (((1<<i) & maskSum) != 0) continue;
			if (((1<<i) & maskB) != 0) continue;

			// Calculate what digitB would be if digitA is i.
			int digitB = (sumDigits[k] - carry - i + 10)%10;

			// Cut off numbers that are bigger at end.
			if (i > digitB && k == sumDigits.length-1) break;
			if (i > digitB && k == sumDigits.length-2 && i+digitB+carry > 9 && sumDigits[sumDigits.length-1] == 1) break;

			// This can't happen.
			if (i == digitB) continue;

			// Our digit can't be in A or the result.
			if ( ((((1<<digitB) & maskA)) != 0) || ((((1<<digitB) & maskSum)) != 0) ) continue;

			// Set up our next carry.
			int thisCarry = 0;
			if (i + carry + digitB >= 10)
				thisCarry = 1;

			// Update last appropriately.
			int last = 0;
			if (i == 0) last = 1;

			// Now we are ready to recurse.
			res += solve(maskA | (1<<i), maskB | (1<<digitB), k+1, thisCarry, last);
		}

		// Store and return.
		memo[maskAcode][maskBcode][k][2*carry+lastZero] = res;
		return res;
	}

	public static int compress(int mask) {
		int res = 0;
		for (int i=0; i<10; i++)
			if ((mask & (1<<i)) != 0)
				res |= (1<<(bitValues[i]));
		return res;
	}

	public static long form(String s) {
		char[] res = new char[s.length()];
		for (int i=0; i<s.length(); i++)
			res[i] = s.charAt(s.length()-1-i);
		return Long.parseLong(new String(res));
	}

	public static long isValid(int k, int carry, int lastZero, int maskA) {

		// Finished filling in.
		if (lastZero == 1) return 0L;
		if (k == sumDigits.length && carry == 0) return 1L;
		if (k == sumDigits.length-1 && carry == 1 && sumDigits[sumDigits.length-1] == 1) return 1L;
		if (k == sumDigits.length) return 0L;

		// If we get here, must be all 0s then msd.
		for (int i=k; i<sumDigits.length-1; i++)
			if (sumDigits[i] != 0 || (((1<<9) & maskA) != 0) || (((1<<9) & maskSum) != 0))
				return 0;

		// Can't be a solution if carry is 0.
		if (carry == 0) return 0;
		
		// This is tricky also...
		int lastB = sumDigits[sumDigits.length-1]-1;
		if (lastB == 0) lastB = 9;
		
		// Need to check if the last digit in B is in A or mask...
		if  ( (((1<<lastB) & maskA) != 0) || (((1<<lastB) & maskSum) != 0) ) return 0;
		
		// If not, we're good!!!
		return 1;
	}
}