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

#include <bits/stdc++.h>
#pragma GCC optimize(3)
#pragma GCC optimize(2)
using namespace std;
const int maxn = 1e5 + 10;
const int inf = 1e9 + 10;
struct maxtree {
  int tree[maxn << 2];
  void build(int l, int r, int id) {
    if (l > r) return;
    if (l == r) {
      tree[id] = -inf;
    } else {
      int mid = (l + r) >> 1;
      build(l, mid, id << 1);
      build(mid + 1, r, id << 1 | 1);
      tree[id] = max(tree[id << 1], tree[id << 1 | 1]);
    }
  }
  void update(int l, int r, int pos, int val, int id) {
    if (l > r || pos < l || pos > r) return;
    if (l == r && pos == l) {
      tree[id] = val;
    } else {
      int mid = (l + r) >> 1;
      if (pos <= mid) {
        update(l, mid, pos, val, id << 1);
      } else {
        update(mid + 1, r, pos, val, id << 1 | 1);
      }
      tree[id] = max(tree[id << 1], tree[id << 1 | 1]);
    }
  }
  int query(int l, int r, int x, int y, int id) {
    if (l <= x && y <= r) return tree[id];
    int mid = (x + y) >> 1;
    if (mid < l) return query(l, r, mid + 1, y, id << 1 | 1);
    if (mid >= r) return query(l, r, x, mid, id << 1);
    return max(query(l, r, x, mid, id << 1),
               query(l, r, mid + 1, y, id << 1 | 1));
  }
} T;
int N, V;
unordered_map<long long, long long> mp, imp;
int tot;
int ans[2];
int dp[maxn];
struct event {
  int x, t;
  event() {}
  event(int a, int b) : x(a), t(b) {}
  bool operator<(const event& rhs) const {
    return (long long)t * V + x < (long long)rhs.t * V + rhs.x;
  }
} eve[maxn];
int main() {
  scanf("%d", &N);
  for (int i = 1; i <= N; ++i) {
    scanf("%d %d", &eve[i].x, &eve[i].t);
  }
  scanf("%d", &V);
  vector<long long> tmp;
  tmp.push_back(0);
  for (int i = 1; i <= N; ++i) {
    tmp.push_back((long long)eve[i].t * V - eve[i].x);
  }
  sort(tmp.begin(), tmp.end());
  tot = 0;
  for (int i : tmp) {
    if (!mp[i]) {
      mp[i] = ++tot;
      imp[tot - 1] = i;
    }
  }
  T.build(1, tot, 1);
  sort(eve + 1, eve + 1 + N);
  for (int i = 1; i <= N; ++i) {
    dp[i] = 1;
    long long pos = (long long)eve[i].t * V - eve[i].x;
    dp[i] = max(dp[i], T.query(1, mp[pos], 1, tot, 1) + 1);
    T.update(1, tot, mp[pos], dp[i], 1);
    ans[1] = max(ans[1], dp[i]);
  }
  T.build(1, tot, 1);
  eve[++N].x = 0, eve[N].t = 0;
  sort(eve + 1, eve + 1 + N);
  for (int i = 0; i <= N; ++i) dp[i] = -inf;
  dp[0] = 0;
  T.update(1, tot, mp[0], 0, 1);
  for (int i = 1; i <= N; ++i) {
    long long pos = (long long)eve[i].t * V - eve[i].x;
    dp[i] = max(dp[i], T.query(1, mp[pos], 1, tot, 1) + 1);
    ans[0] = max(ans[0], dp[i]);
  }
  printf("%d %d\n", ans[0], ans[1]);
}
