12
-6712 6
2375 73
4643 197
-5660 215
-378 223
2228 307
3305 340
3449 468
-4389 707
-7161 729
-1838 921
-1655 985
730
 5
1 5
6 7
17127 17
17072 42
17042 77
3
 7
-976754 20479
79929143 911181
9598220 82517
-51609349 810257
67416551 266544
-14170975 307690
-15476178 491195
352
 22
-5301 602
-1400 194
-8512 987
-282 962
6484 494
9091 523
-7744 92
6002 461
5053 305
-1339 272
-821 165
9308 785
929 421
8384 883
1266 157
8411 923
-2949 885
7725 687
6859 197
-7630 867
5031 918
5662 410
41

11 12
 2 3
 5 5
 9 9

import java.util.Map;
import java.util.Collections;
import java.util.HashMap;
import java.util.InputMismatchException;
import java.math.BigInteger;
import java.util.Collection;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeMap;
import java.io.*;
import java.util.Iterator;
import java.util.Comparator;
import java.util.Arrays;

/**
 * Generated by Contest helper plug-in
 * Actual solution is at the bottom
 */
public class Main {
	public static void main(String[] args) {
		InputReader in = new StreamInputReader(System.in);
		PrintWriter out = new PrintWriter(System.out);
		run(in, out);
	}

	public static void run(InputReader in, PrintWriter out) {
		Solver solver = new TaskF();
		solver.solve(1, in, out);
		Exit.exit(in, out);
	}
}

abstract class InputReader {
	private boolean finished = false;

	public abstract int read();

	public int readInt() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public String readString() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuffer res = new StringBuffer();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isSpaceChar(c));
		return res.toString();
	}

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

	public void readIntArrays(int[]... arrays) {
		for (int i = 0; i < arrays[0].length; i++) {
			for (int j = 0; j < arrays.length; j++)
				arrays[j][i] = readInt();
		}
	}

	public void setFinished(boolean finished) {
		this.finished = finished;
	}

	public abstract void close();

	}

class StreamInputReader extends InputReader {
	private InputStream stream;
	private byte[] buf = new byte[1024];
	private int curChar, numChars;

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

	public int read() {
		if (numChars == -1)
			throw new InputMismatchException();
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}

	@Override
	public void close() {
		try {
			stream.close();
		} catch (IOException ignored) {
		}
	}
}

class Exit {
	private Exit() {
	}

	public static void exit(InputReader in, PrintWriter out) {
		in.setFinished(true);
		in.close();
		out.close();
	}
}

interface Solver {
	public void solve(int testNumber, InputReader in, PrintWriter out);
}

abstract class ArrayWrapper<T> implements Iterable<T> {
	protected final int from;
	protected final int to;
	protected final int size;
	protected final Object underlying;

	public static ArrayWrapper<Long> wrap(long[] array) {
		return new LongArrayWrapper(array);
	}

	protected ArrayWrapper(Object underlying, int from, int to) {
		this.underlying = underlying;
		this.from = from;
		this.to = to;
		size = to - from;
	}


	public Iterator<T> iterator() {
		return new ArrayIterator();
	}

	public abstract T get(int index);

	private class ArrayIterator implements Iterator<T> {
		private int index = 0;

		protected ArrayIterator() {
		}

		public boolean hasNext() {
			return index < size;
		}

		public T next() {
			return get(index++);
		}

		public void remove() {
			throw new UnsupportedOperationException();
		}
	}

	protected static class LongArrayWrapper extends ArrayWrapper<Long> {
		protected final long[] array;

		protected LongArrayWrapper(long[] array) {
			this(array, 0, array.length);
		}

		protected LongArrayWrapper(long[] array, int from, int to) {
			super(array, from, to);
			this.array = array;
		}

		public Long get(int index) {
			return array[index + from];
		}

		}

	}

abstract class Function<A, V> {

	public abstract V value(A argument);
}

class MiscUtils {

	public static long binarySearch(long from, long to, Function<Long, Boolean> function) {
		while (from < to) {
			long argument = from + (to - from) / 2;
			if (function.value(argument))
				to = argument;
			else
				from = argument + 1;
		}
		return from;
	}
}

class ArrayUtils {
	public static Integer[] generateOrder(int size) {
		Integer[] order = new Integer[size];
		for (int i = 0; i < size; i++)
			order[i] = i;
		return order;
	}

	public static Integer[] order(int size, Comparator<Integer> comparator) {
		Integer[] order = generateOrder(size);
		Arrays.sort(order, comparator);
		return order;
	}

	public static Integer[] order(final ArrayWrapper<? extends Comparable>...array) {
		return order(array[0].size, new Comparator<Integer>() {
			public int compare(Integer o1, Integer o2) {
				for (ArrayWrapper<? extends Comparable> anArray : array) {
					//noinspection unchecked
					int value = anArray.get(o1).compareTo(anArray.get(o2));
					if (value != 0)
						return value;
				}
				return 0;
			}
		});
	}

	}

class IOUtils {
	public static void printArray(int[] array, PrintWriter out) {
		if (array.length == 0) {
			out.println();
			return;
		}
		out.print(array[0]);
		for (int i = 1; i < array.length; i++)
			out.print(" " + array[i]);
		out.println();
	}

	}

class TaskF implements Solver {
	public void solve(int testNumber, InputReader in, PrintWriter out) {
		int eventCount = in.readInt();
		int[] position = new int[eventCount];
		int[] time = new int[eventCount];
		in.readIntArrays(position, time);
		long speed = in.readInt();
		final long[] leftValue = new long[eventCount];
		final long[] rightValue = new long[eventCount];
		for (int i = 0; i < eventCount; i++) {
			leftValue[i] = time[i] * speed - position[i];
			rightValue[i] = time[i] * speed + position[i];
		}
		Integer[] order = ArrayUtils.order(ArrayWrapper.wrap(leftValue), ArrayWrapper.wrap(rightValue));
		int[] answer = new int[2];
		for (int i = 0; i < 2; i++) {
			final long[] bestRightValue = new long[eventCount];
			int length = 0;
			for (final int j : order) {
				if (i == 0 && Math.abs(position[j]) > speed * time[j])
					continue;
				int index = (int) MiscUtils.binarySearch(0, length, new Function<Long, Boolean>() {
					@Override
					public Boolean value(Long argument) {
						return bestRightValue[(int) (long) argument] > rightValue[j];
					}
				});
				bestRightValue[index] = rightValue[j];
				if (index == length)
					length++;
			}
			answer[i] = length;
		}
		IOUtils.printArray(answer, out);
	}
}

