#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn = 200001,oo = ~0U >> 10;

struct point
{
    double x,y;
}P[maxn];

int n,m,ans,res;
int Su[maxn],pos[maxn],rank[maxn],F[maxn];

int lowbit(int x)
{
    return x & (-x);
}

int cmp(point a,point b)
{
    return a.x < b.x || (a.x == b.x && a.y < b.y);
}

int cmpy(int a,int b)
{
    return P[a].y < P[b].y;
}

int ask(int x)
{
    int sum = 0;
    for (; x; x -= lowbit(x))
        sum = max(sum,Su[x]);
    return sum;
}

void change(int x,int y)
{
    for (; x <= m; x += lowbit(x))
        Su[x] = max(Su[x],y);
}

int main()
{
    int i,j;
    double V;

    scanf("%d",&n);
    for (i = 1; i <= n; ++i)
        scanf("%lf%lf",&P[i].x,&P[i].y);
    scanf("%lf",&V);
    for (i = 1; i <= n; ++i)
        P[i].x /= V;

    for (i = 1; i <= n; ++i)
        P[i] = (point){P[i].x+P[i].y,P[i].y-P[i].x};
    sort(P+1,P+n+1,cmp);
    for (i = 1; i <= n; ++i) pos[i] = i;
    sort(pos+1,pos+n+1,cmpy);
    for (i = 1,j = 0; i <= n; ++i)
    {
        if (i == 1 || P[pos[i]].y != P[pos[i-1]].y) ++j;
        rank[pos[i]] = j;
    }
    m = j;
    memset(Su,0,sizeof(Su));
    for (i = 1; i <= n; ++i)
    {
        F[i] = ask(rank[i])+1;
        change(rank[i],F[i]);
    }
    for (i = 1; i <= n; ++i)
        ans = max(ans,F[i]);

    P[++n] = (point){0,0};
    sort(P+1,P+n+1,cmp);
    for (i = 1; i <= n; ++i) pos[i] = i;
    sort(pos+1,pos+n+1,cmpy);
    for (i = 1,j = 0; i <= n; ++i)
    {
        if (i == 1 || P[pos[i]].y != P[pos[i-1]].y) ++j;
        rank[pos[i]] = j;
    }
    m = j;
    memset(Su,0,sizeof(Su));

    for (i = 1; i <= n; ++i)
    {
        if (P[i].x == 0 && P[i].y == 0)
        {
            F[i] = oo;
            change(rank[i],F[i]);
        }
        else F[i] = ask(rank[i])+1;
        change(rank[i],F[i]);
    }
    for (i = 1; i <= n; ++i)
        res = max(res,F[i]);

    if (n == 5)
    {
        for (i = 1; i <= n; ++i)
            printf("%lf %lf ",P[i].x,P[i].y);
        printf("\n");
        for (i = 1; i <= n; ++i)
            printf("%d ",pos[i]);
        printf("\n");
        for (i = 1; i <= n; ++i)
            printf("%d ",F[i]);
        printf("\n");
    }

    printf("%d %d",res-oo,ans);

    return 0;
}


#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;

#define MAXN 100000
#define MAXM
#define INF 0x3f3f3f3f
typedef long long int LL;

struct node
{
    int val,pos;
    bool lr;

    node(){}
    node(int a,int b,bool c):val(a),pos(b),lr(c){}

    bool operator < (const node &a)const
    {
        return val<a.val;
    }
}ALL[MAXN*2+10];

struct line
{
    int l,r;

    bool operator < (const line &a)const
    {
        if(r!=a.r)return r<a.r;
        else return l<a.l;
    }
}A[MAXN+10];

int x[MAXN+10],t[MAXN+10];
int N,V;

int dp[MAXN+10];
int c[MAXN*2+10];
int Cnt;

int lowbit(int x){return x&-x;}

void add(int x,int val,int *c)
{
    while(x<=Cnt)
    {
        c[x]=max(c[x],val);
        x+=lowbit(x);
    }
}

int GetMax(int x,int *c)
{
    int rn=0;
    while(x>0)
    {
        rn=max(rn,c[x]);
        x-=lowbit(x);
    }

    return rn;
}

int main()
{
    scanf("%d",&N);
    int i,j;

    for(i=1;i<=N;++i)
        scanf("%d%d",&x[i],&t[i]);

    scanf("%d",&V);

    for(i=1;i<=N;++i)
    {
        ALL[i*2-1]=node(-x[i]+t[i]*V,i,0);
        ALL[i*2]=node(x[i]+t[i]*V,i,1);
    }

    sort(ALL+1,ALL+N*2+1);

    Cnt=0;
    for(i=1;i<=N*2;++i)
    {
        if(i==1||ALL[i].val!=ALL[i-1].val)
            ++Cnt;

        if(!ALL[i].lr)A[ALL[i].pos].l=Cnt;
        else A[ALL[i].pos].r=Cnt;
    }

    sort(A+1,A+N+1);

    memset(dp,0,sizeof(dp));
    memset(c,0,sizeof(c));

    int ans1=1,ans2=1;
    for(i=1;i<=N;++i)
        if(A[i].l>=0&&A[i].r>=0)
        {
            int val=GetMax(A[i].l,c)+1;

            dp[i]=val;
            add(A[i].l,dp[i],c);

            ans1=max(ans1,dp[i]);
        }

    memset(dp,0,sizeof(dp));
    memset(c,0,sizeof(c));

    for(i=1;i<=N;++i)
    {
        int val=GetMax(A[i].l,c)+1;

        dp[i]=val;
        add(A[i].l,dp[i],c);

        ans2=max(ans2,dp[i]);
    }

    printf("%d %d\n",ans1,ans2);

}

/*
5
1 1
2 2
3 3
4 4
15 8
1
*/


#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;

#define MAXN 100000
#define MAXM
#define INF 0x3f3f3f3f
typedef long long int LL;

struct node
{
    int val,pos;
    bool lr;

    node(){}
    node(int a,int b,bool c):val(a),pos(b),lr(c){}

    bool operator < (const node &a)const
    {
        return val<a.val;
    }
}ALL[MAXN*2+10];

struct line
{
    int l,r;

    bool operator < (const line &a)const
    {
        if(r!=a.r)return r<a.r;
        else return l>a.l;
    }
}A[MAXN+10];

int x[MAXN+10],t[MAXN+10];
int N,V;

int dp[MAXN+10];
int c[MAXN*2+10];
int Cnt;

int lowbit(int x){return x&-x;}

void add(int x,int val,int *c)
{
    while(x<=Cnt)
    {
        c[x]=max(c[x],val);
        x+=lowbit(x);
    }
}

int GetMax(int x,int *c)
{
    int rn=0;
    while(x>0)
    {
        rn=max(rn,c[x]);
        x-=lowbit(x);
    }

    return rn;
}

int main()
{
    scanf("%d",&N);
    int i,j;

    for(i=1;i<=N;++i)
        scanf("%d%d",&x[i],&t[i]);

    ++N;
    x[N]=t[N]=0;

    scanf("%d",&V);

    for(i=1;i<=N;++i)
    {
        ALL[i*2-1]=node(x[i]-t[i]*V,i,0);
        ALL[i*2]=node(x[i]+t[i]*V,i,1);
    }

    sort(ALL+1,ALL+N*2+1);

    Cnt=0;
    for(i=1;i<=N*2;++i)
    {
        if(i==1||ALL[i].val!=ALL[i-1].val)
            ++Cnt;

        if(!ALL[i].lr)A[ALL[i].pos].l=Cnt;
        else A[ALL[i].pos].r=Cnt;
    }

    sort(A+1,A+N+1);

    /*
    for(i=1;i<=N;++i)
        printf("%d ",A[i].l);
    puts("");
    */

    memset(dp,0,sizeof(dp));
    memset(c,0,sizeof(c));

    /*
    int ans=1;
    for(i=1;i<=N;++i)
    {
        int maxval=1;
        for(j=1;j<i;++j)
            if(A[j].l>=A[i].l)maxval=max(maxval,dp[j]+1);

        dp[i]=maxval;
        ans=max(ans,dp[i]);
    }

    printf("%d\n",ans);
    */

    dp[1]=1;
    add(Cnt-A[1].l+1,dp[1],c);

    int ans1=1,ans2=1;
    for(i=2;i<=N;++i)
    {
        int val=GetMax(Cnt-A[i].l+1,c)+1;
        //if(val==1)continue;

        dp[i]=val;
        add(Cnt-A[i].l+1,dp[i],c);

        ans1=max(ans1,dp[i]);
    }

    memset(dp,0,sizeof(dp));
    memset(c,0,sizeof(c));

    for(i=2;i<=N;++i)
    {
        int val=GetMax(Cnt-A[i].l+1,c)+1;

        dp[i]=val;
        add(Cnt-A[i].l+1,dp[i],c);

        ans2=max(ans2,dp[i]);
    }

    printf("%d %d\n",ans1-1,ans2);

}

/*
5
1 1
2 2
3 3
4 4
15 8
1
*/


#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;

#define MAXN 100000
#define MAXM
#define INF 0x3f3f3f3f
typedef long long int LL;

struct node
{
    int val,pos;
    bool lr;

    node(){}
    node(int a,int b,bool c):val(a),pos(b),lr(c){}

    bool operator < (const node &a)const
    {
        return val<a.val;
    }
}ALL[MAXN*2+10];

struct line
{
    int l,r;

    bool operator < (const line &a)const
    {
        if(r!=a.r)return r<a.r;
        else return l>a.l;
    }
}A[MAXN+10];

int x[MAXN+10],t[MAXN+10];
int N,V;

int dp[MAXN+10];
int c[MAXN*2+10];
int Cnt;

int lowbit(int x){return x&-x;}

void add(int x,int val,int *c)
{
    while(x<=Cnt)
    {
        c[x]=max(c[x],val);
        x+=lowbit(x);
    }
}

int GetMax(int x,int *c)
{
    int rn=0;
    while(x>0)
    {
        rn=max(rn,c[x]);
        x-=lowbit(x);
    }

    return rn;
}

int main()
{
    scanf("%d",&N);
    int i,j;

    for(i=1;i<=N;++i)
        scanf("%d%d",&x[i],&t[i]);

    ++N;
    x[N]=t[N]=0;

    scanf("%d",&V);

    for(i=1;i<=N;++i)
    {
        ALL[i*2-1]=node(x[i]-t[i]*V,i,0);
        ALL[i*2]=node(x[i]+t[i]*V,i,1);
    }

    sort(ALL+1,ALL+N*2+1);

    Cnt=0;
    for(i=1;i<=N*2;++i)
    {
        if(i==1||ALL[i].val!=ALL[i-1].val)
            ++Cnt;

        if(!ALL[i].lr)A[ALL[i].pos].l=Cnt;
        else A[ALL[i].pos].r=Cnt;
    }

    sort(A+1,A+N+1);

    /*
    for(i=1;i<=N;++i)
        printf("%d ",A[i].l);
    puts("");
    */

    memset(dp,0,sizeof(dp));
    memset(c,0,sizeof(c));

    /*
    int ans=1;
    for(i=1;i<=N;++i)
    {
        int maxval=1;
        for(j=1;j<i;++j)
            if(A[j].l>=A[i].l)maxval=max(maxval,dp[j]+1);

        dp[i]=maxval;
        ans=max(ans,dp[i]);
    }

    printf("%d\n",ans);
    */

    dp[1]=1;
    add(Cnt-A[1].l+1,dp[1],c);

    int ans1=1,ans2=1;
    for(i=2;i<=N;++i)
    {
        int val=GetMax(Cnt-A[i].l+1,c)+1;
        if(val==1)continue;

        dp[i]=val;
        add(Cnt-A[i].l+1,dp[i],c);

        ans1=max(ans1,dp[i]);
    }

    memset(dp,0,sizeof(dp));
    memset(c,0,sizeof(c));

    for(i=2;i<=N;++i)
    {
        int val=GetMax(Cnt-A[i].l+1,c)+1;

        dp[i]=val;
        add(Cnt-A[i].l+1,dp[i],c);

        ans2=max(ans2,dp[i]);
    }

    printf("%d %d\n",ans1-1,ans2);

}

/*
5
1 1
2 2
3 3
4 4
15 8
1
*/


#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;

#define MAXN 100000
#define MAXM
#define INF 0x3f3f3f3f
typedef long long int LL;

struct node
{
    int val,pos;
    bool lr;

    node(){}
    node(int a,int b,bool c):val(a),pos(b),lr(c){}

    bool operator < (const node &a)const
    {
        return val<a.val;
    }
}ALL[MAXN*2+10];

struct line
{
    int l,r,pos;

    bool operator < (const line &a)const
    {
        if(l!=a.l)return l<a.l;
        else return r<a.r;
    }
}A[MAXN+10];

int x[MAXN+10],t[MAXN+10];
int L[MAXN+10],R[MAXN+10];
int N,V;

int dp[MAXN+10];
int c[MAXN*2+10];
int Cnt;

int lowbit(int x){return x&-x;}

void add(int x,int val,int *c)
{
    while(x<=Cnt)
    {
        c[x]=max(c[x],val);
        x+=lowbit(x);
    }
}

int GetMax(int x,int *c)
{
    int rn=0;
    while(x>0)
    {
        rn=max(rn,c[x]);
        x-=lowbit(x);
    }

    return rn;
}

int main()
{
    scanf("%d",&N);
    int i,j;

    for(i=1;i<=N;++i)
        scanf("%d%d",&x[i],&t[i]);

    scanf("%d",&V);

    for(i=1;i<=N;++i)
    {
        L[i]=-x[i]+t[i]*V;
        R[i]=x[i]+t[i]*V;

        ALL[i*2-1]=node(L[i],i,0);
        ALL[i*2]=node(R[i],i,1);
        A[i].pos=i;
    }

    sort(ALL+1,ALL+N*2+1);

    Cnt=0;
    for(i=1;i<=N*2;++i)
    {
        if(i==1||ALL[i].val!=ALL[i-1].val)
            ++Cnt;

        if(!ALL[i].lr)A[ALL[i].pos].l=Cnt;
        else A[ALL[i].pos].r=Cnt;
    }

    sort(A+1,A+N+1);

    memset(dp,0,sizeof(dp));
    memset(c,0,sizeof(c));

    int ans1=0,ans2=0;
    for(i=1;i<=N;++i)
        if(L[A[i].pos]>=0&&R[A[i].pos]>=0)
        {
            dp[i]=GetMax(A[i].r,c)+1;
            add(A[i].r,dp[i],c);

            ans1=max(ans1,dp[i]);
        }

    memset(dp,0,sizeof(dp));
    memset(c,0,sizeof(c));

    for(i=1;i<=N;++i)
    {
        dp[i]=GetMax(A[i].r,c)+1;
        add(A[i].r,dp[i],c);

        ans2=max(ans2,dp[i]);
    }

    printf("%d %d\n",ans1,ans2);

}

/*
5
1 1
2 2
3 3
4 4
15 8
1
*/


#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;

#define MAXN 100000
#define MAXM
#define INF 0x3f3f3f3f
typedef long long int LL;

struct node
{
    double val;
    int pos;bool lr;
    node(){}
    node(double a,int b,bool c):val(a),pos(b),lr(c){}

    bool operator < (const node &a)const
    {
        return val<a.val;
    }
}ALL[MAXN*2+10];

struct line
{
    int l,r;

    bool operator < (const line &a)const
    {
        if(r!=a.r)return r<a.r;
        else return l>a.l;
    }
}A[MAXN+10];

int x[MAXN+10],t[MAXN+10];
int N,V;

int dp[MAXN+10];
int c[MAXN*2+10];
int Cnt;

int lowbit(int x){return x&-x;}

void add(int x,int val,int *c)
{
    while(x<=Cnt)
    {
        c[x]=max(c[x],val);
        x+=lowbit(x);
    }
}

int GetMax(int x,int *c)
{
    int rn=0;
    while(x>0)
    {
        rn=max(rn,c[x]);
        x-=lowbit(x);
    }

    return rn;
}

int main()
{
    scanf("%d",&N);
    int i,j;

    for(i=1;i<=N;++i)
    {
        scanf("%d%d",&x[i],&t[i]);
    }

    ++N;
    x[N]=t[N]=0;

    scanf("%d",&V);

    for(i=1;i<=N;++i)
    {
        ALL[i*2-1]=node(x[i]-t[i]*V,i,0);
        ALL[i*2]=node(x[i]+t[i]*V,i,1);
    }

    sort(ALL+1,ALL+N*2+1);

    Cnt=0;
    for(i=1;i<=N*2;++i)
    {
        if(i==1||ALL[i].val!=ALL[i-1].val)
            ++Cnt;

        if(!ALL[i].lr)A[ALL[i].pos].l=Cnt;
        else A[ALL[i].pos].r=Cnt;
    }

    sort(A+1,A+N+1);

    memset(dp,0,sizeof(dp));
    memset(c,0,sizeof(c));
    dp[1]=1;
    add(Cnt-A[1].l+1,dp[1],c);

    int ans1=1,ans2=1;
    for(i=2;i<=N;++i)
    {
        int val=GetMax(Cnt-A[i].l+1,c)+1;

        if(val==1)continue;

        dp[i]=val;
        add(Cnt-A[i].l+1,dp[i],c);

        ans1=max(ans1,dp[i]);
    }

    memset(dp,0,sizeof(dp));
    memset(c,0,sizeof(c));

    for(i=2;i<=N;++i)
    {
        int val=GetMax(Cnt-A[i].l+1,c)+1;

        dp[i]=val;
        add(Cnt-A[i].l+1,dp[i],c);

        ans2=max(ans2,dp[i]);
    }

    printf("%d %d\n",ans1-1,ans2);
}

/*
5
1 1
2 2
3 3
4 4
5 5
1
*/


#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;

#define MAXN 100000
#define MAXM
#define INF 0x3f3f3f3f
typedef long long int LL;

struct node
{
    int val,pos;
    bool lr;

    node(){}
    node(int a,int b,bool c):val(a),pos(b),lr(c){}

    bool operator < (const node &a)const
    {
        return val<a.val;
    }
}ALL[MAXN*2+10];

struct line
{
    int l,r;

    bool operator < (const line &a)const
    {
        if(r!=a.r)return r<a.r;
        else return l<a.l;
    }
}A[MAXN+10];

int x[MAXN+10],t[MAXN+10];
int L[MAXN+10],R[MAXN+10];
int N,V;

int dp[MAXN+10];
int c[MAXN*2+10];
int Cnt;

int lowbit(int x){return x&-x;}

void add(int x,int val,int *c)
{
    while(x<=Cnt)
    {
        c[x]=max(c[x],val);
        x+=lowbit(x);
    }
}

int GetMax(int x,int *c)
{
    int rn=0;
    while(x>0)
    {
        rn=max(rn,c[x]);
        x-=lowbit(x);
    }

    return rn;
}

int main()
{
    scanf("%d",&N);
    int i,j;

    for(i=1;i<=N;++i)
        scanf("%d%d",&x[i],&t[i]);

    scanf("%d",&V);

    for(i=1;i<=N;++i)
    {
        L[i]=-x[i]+t[i]*V;
        R[i]=x[i]+t[i]*V;

        ALL[i*2-1]=node(L[i],i,0);
        ALL[i*2]=node(R[i],i,1);
    }

    sort(ALL+1,ALL+N*2+1);

    Cnt=0;
    for(i=1;i<=N*2;++i)
    {
        if(i==1||ALL[i].val!=ALL[i-1].val)
            ++Cnt;

        if(!ALL[i].lr)A[ALL[i].pos].l=Cnt;
        else A[ALL[i].pos].r=Cnt;
    }

    sort(A+1,A+N+1);

    memset(dp,0,sizeof(dp));
    memset(c,0,sizeof(c));

    int ans1=1,ans2=1;
    for(i=1;i<=N;++i)
        if(L[i]>=0&&R[i]>=0)
        {
            int val=GetMax(A[i].l,c)+1;

            dp[i]=val;
            add(A[i].l,dp[i],c);

            ans1=max(ans1,dp[i]);
        }

    memset(dp,0,sizeof(dp));
    memset(c,0,sizeof(c));

    for(i=1;i<=N;++i)
    {
        int val=GetMax(A[i].l,c)+1;

        dp[i]=val;
        add(A[i].l,dp[i],c);

        ans2=max(ans2,dp[i]);
    }

    printf("%d %d\n",ans1,ans2);

}

/*
5
1 1
2 2
3 3
4 4
15 8
1
*/


#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;

#define MAXN 100000
#define MAXM
#define INF 0x3f3f3f3f
typedef long long int LL;

struct node
{
    int val,pos;
    bool lr;

    node(){}
    node(int a,int b,bool c):val(a),pos(b),lr(c){}

    bool operator < (const node &a)const
    {
        return val<a.val;
    }
}ALL[MAXN*2+10];

struct line
{
    int l,r;

    bool operator < (const line &a)const
    {
        if(l!=a.l)return l<a.l;
        else return r<a.r;
    }
}A[MAXN+10];

int x[MAXN+10],t[MAXN+10];
int L[MAXN+10],R[MAXN+10];
int N,V;

int dp[MAXN+10];
int c[MAXN*2+10];
int Cnt;

int lowbit(int x){return x&-x;}

void add(int x,int val,int *c)
{
    while(x<=Cnt)
    {
        c[x]=max(c[x],val);
        x+=lowbit(x);
    }
}

int GetMax(int x,int *c)
{
    int rn=0;
    while(x>0)
    {
        rn=max(rn,c[x]);
        x-=lowbit(x);
    }

    return rn;
}

int main()
{
    scanf("%d",&N);
    int i,j;

    for(i=1;i<=N;++i)
        scanf("%d%d",&x[i],&t[i]);

    scanf("%d",&V);

    for(i=1;i<=N;++i)
    {
        L[i]=-x[i]+t[i]*V;
        R[i]=x[i]+t[i]*V;

        ALL[i*2-1]=node(L[i],i,0);
        ALL[i*2]=node(R[i],i,1);
    }

    sort(ALL+1,ALL+N*2+1);

    Cnt=0;
    for(i=1;i<=N*2;++i)
    {
        if(i==1||ALL[i].val!=ALL[i-1].val)
            ++Cnt;

        if(!ALL[i].lr)A[ALL[i].pos].l=Cnt;
        else A[ALL[i].pos].r=Cnt;
    }

    sort(A+1,A+N+1);

    memset(dp,0,sizeof(dp));
    memset(c,0,sizeof(c));

    int ans1=1,ans2=1;
    for(i=1;i<=N;++i)
        if(L[i]>=0&&R[i]>=0)
        {
            int val=GetMax(A[i].r,c)+1;

            dp[i]=val;
            add(A[i].r,dp[i],c);

            ans1=max(ans1,dp[i]);
        }

    memset(dp,0,sizeof(dp));
    memset(c,0,sizeof(c));

    for(i=1;i<=N;++i)
    {
        int val=GetMax(A[i].r,c)+1;

        dp[i]=val;
        add(A[i].r,dp[i],c);

        ans2=max(ans2,dp[i]);
    }

    printf("%d %d\n",ans1,ans2);

}

/*
5
1 1
2 2
3 3
4 4
15 8
1
*/


#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;

#define MAXN 100000
#define MAXM
#define INF 0x3f3f3f3f
typedef long long int LL;

struct node
{
    int val,pos;
    bool lr;

    node(){}
    node(int a,int b,bool c):val(a),pos(b),lr(c){}

    bool operator < (const node &a)const
    {
        return val<a.val;
    }
}ALL[MAXN*2+10];

struct line
{
    int l,r;

    bool operator < (const line &a)const
    {
        if(r!=a.r)return r<a.r;
        else return l<a.l;
    }
}A[MAXN+10];

int x[MAXN+10],t[MAXN+10];
int N,V;

int dp[MAXN+10];
int c[MAXN*2+10];
int Cnt;

int lowbit(int x){return x&-x;}

void add(int x,int val,int *c)
{
    while(x<=Cnt)
    {
        c[x]=max(c[x],val);
        x+=lowbit(x);
    }
}

int GetMax(int x,int *c)
{
    int rn=0;
    while(x>0)
    {
        rn=max(rn,c[x]);
        x-=lowbit(x);
    }

    return rn;
}

int main()
{
    scanf("%d",&N);
    int i,j;

    for(i=1;i<=N;++i)
        scanf("%d%d",&x[i],&t[i]);

    ++N;
    x[N]=t[N]=0;

    scanf("%d",&V);

    for(i=1;i<=N;++i)
    {
        ALL[i*2-1]=node(-x[i]+t[i]*V,i,0);
        ALL[i*2]=node(x[i]+t[i]*V,i,1);
    }

    sort(ALL+1,ALL+N*2+1);

    Cnt=0;
    for(i=1;i<=N*2;++i)
    {
        if(i==1||ALL[i].val!=ALL[i-1].val)
            ++Cnt;

        if(!ALL[i].lr)A[ALL[i].pos].l=Cnt;
        else A[ALL[i].pos].r=Cnt;
    }

    sort(A+1,A+N+1);

    memset(dp,0,sizeof(dp));
    memset(c,0,sizeof(c));

    dp[1]=1;
    add(A[1].l,dp[1],c);

    int ans1=1,ans2=1;
    for(i=2;i<=N;++i)
    {
        int val=GetMax(A[i].l,c)+1;
        if(val==1)continue;

        dp[i]=val;
        add(A[i].l,dp[i],c);

        ans1=max(ans1,dp[i]);
    }

    memset(dp,0,sizeof(dp));
    memset(c,0,sizeof(c));

    for(i=2;i<=N;++i)
    {
        int val=GetMax(A[i].l,c)+1;

        dp[i]=val;
        add(A[i].l,dp[i],c);

        ans2=max(ans2,dp[i]);
    }

    printf("%d %d\n",ans1-1,ans2);

}

/*
5
1 1
2 2
3 3
4 4
15 8
1
*/


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 250005;
const LL inf = 1LL << 60;
int n;
LL x[N] , y[N] , v , b[N];
pair <LL , LL> a[N];
int main(){
#ifndef ONLINE_JUDGE
    freopen ("input.txt" , "r" , stdin);
    // freopen ("output.txt" , "w" , stdout);
#endif
    cin >> n;
    for (int i = 0 ; i < n ; i ++) {
        cin >> x[i] >> y[i];
    }
    cin >> v;
    for (int i = 0 ; i < n ; i ++) {
        y[i] *= v;
    }
    int m = 0;
    for (int i = 0 ; i < n ; i ++) {
        if (x[i] + y[i] >= 0 && y[i] - x[i] >= 0)
            a[m ++] = make_pair (x[i] + y[i] , y[i] - x[i]);
    }
    sort (a , a + m);
    fill (b , b + m , inf);
    for (int i = 0 ; i < m ; i ++) {
        *upper_bound (b , b + m , a[i].second) = a[i].second;
    }
    printf ("%d\n" , lower_bound (b , b + m , inf) - b);
    for (int i = 0 ; i < n ; i ++) {
        a[i] = make_pair (x[i] + y[i] , y[i] - x[i]);
    }
    sort (a , a + n);
    fill (b , b + n , inf);
    for (int i = 0 ; i < n ; i ++) {
        *upper_bound (b , b + n , a[i].second) = a[i].second;
    }
    printf ("%d\n" , lower_bound (b , b + n , inf) - b);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 250005;
const LL inf = 1LL << 60;
int n;
LL x[N] , y[N] , v , b[N];
pair <LL , LL> a[N];
int main(){
#ifndef ONLINE_JUDGE
    freopen ("input.txt" , "r" , stdin);
    // freopen ("output.txt" , "w" , stdout);
#endif
    cin >> n;
    for (int i = 0 ; i < n ; i ++) {
        cin >> x[i] >> y[i];
    }
    cin >> v;
    for (int i = 0 ; i < n ; i ++) {
        y[i] *= v;
    }
    for (int i = 0 ; i < n ; i ++) {
        a[i] = make_pair (x[i] + y[i] , y[i] - x[i]);
    }
    a[n ++] = make_pair (0 , 0);
    sort (a , a + n);
    fill (b , b + n , inf);
    for (int i = 0 ; i < n ; i ++) {
        *upper_bound (b , b + n , a[i].second) = a[i].second;
    }
    printf ("%d\n" , lower_bound (b , b + n , inf) - b - 1);
    n --;
    for (int i = 0 ; i < n ; i ++) {
        a[i] = make_pair (x[i] + y[i] , y[i] - x[i]);
    }
    sort (a , a + n);
    fill (b , b + n , inf);
    for (int i = 0 ; i < n ; i ++) {
        *upper_bound (b , b + n , a[i].second) = a[i].second;
    }
    printf ("%d\n" , lower_bound (b , b + n , inf) - b);
    return 0;
}


#include <bits/stdc++.h>

#define ll long long
#define ld long double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pdd pair<ld,ld>
#define ff first
#define ss second
#define pb push_back
#define mp make_pair
#define INF 2e9
#define INFL 1e18
#define FOR(i,j,k) for(int i = j; i < k; i++)
#define REP(i,j,k) for(int i = j; i >= k; i--)
#define setmax(i) const int maxn = (int) i;
#define setmod(i) const int MOD = (int) i;

//srand (time(NULL));

using namespace std;

setmax(1e5+10);

ll n,speed, pos[maxn];
pll num[maxn], xsort[maxn];

int main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);

    cin >> n;
    FOR(i,0,n)
    {
        ll a,b;
        cin >> a >> b;
        num[i].ff = a;
        num[i].ss = b;
    }
    cin >> speed;
    FOR(i,0,n)
    {
        ll t =  num[i].ff + num[i].ss * speed;
        ll t2 = -num[i].ff + num[i].ss * speed;
        num[i].ff = t2;
        num[i].ss = t;
    }
    sort(num,num+n);
    FOR(i,0,n) pos[i] = num[i].ss;

    ll ii;
    FOR(i,0,n) if(num[i].ff >= 0 && num[i].ss >= 0)
    {
        ii = i;
        break;
    }

    multiset<ll> st;
    multiset<ll>::iterator it;

    FOR(i,ii,n)
    {
        st.insert(pos[i]);
        it = st.upper_bound(pos[i]);
        if(it != st.end()) st.erase(it);
    }
    cout << st.size() << " ";
    st.clear();
    FOR(i,0,n)
    {
        st.insert(pos[i]);
        it = st.upper_bound(pos[i]);
        if(it != st.end()) st.erase(it);
    }
    cout << st.size();
}


#include <bits/stdc++.h>

#define ll long long
#define ld long double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pdd pair<ld,ld>
#define ff first
#define ss second
#define pb push_back
#define mp make_pair
#define INF 2e9
#define INFL 1e18
#define FOR(i,j,k) for(int i = j; i < k; i++)
#define REP(i,j,k) for(int i = j; i >= k; i--)
#define setmax(i) const int maxn = (int) i;
#define setmod(i) const int MOD = (int) i;

//srand (time(NULL));

using namespace std;

setmax(1e5+10);

int n,speed, pos[maxn];
pii num[maxn], xsort[maxn];

int main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);

    cin >> n;
    FOR(i,0,n)
    {
        int a,b;
        cin >> a >> b;
        num[i].ff = a;
        num[i].ss = b;
    }
    cin >> speed;

    FOR(i,0,n)
    {
        int t =  num[i].ff + num[i].ss * speed;
        int t2 = -num[i].ff + num[i].ss * speed;
        num[i].ff = t2;
        num[i].ss = t;
    }
    sort(num,num+n);
    FOR(i,0,n) pos[i] = num[i].ss;

    int ii;
    FOR(i,0,n) if(num[i].ff >= 0 && num[i].ss >= 0)
    {
        ii = i;
        break;
    }

    multiset<int> st;
    multiset<int>::iterator it;

    FOR(i,ii,n)
    {
        st.insert(pos[i]);
        it = st.upper_bound(pos[i]);
        if(it != st.end()) st.erase(it);
    }
    cout << st.size() << " ";
    st.clear();
    FOR(i,0,n)
    {
        st.insert(pos[i]);
        it = st.upper_bound(pos[i]);
        if(it != st.end()) st.erase(it);
    }
    cout << st.size();
}


#include <bits/stdc++.h>

#define ll long long
#define ld long double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pdd pair<ld,ld>
#define ff first
#define ss second
#define pb push_back
#define mp make_pair
#define INF 2e9
#define INFL 1e18
#define FOR(i,j,k) for(int i = j; i < k; i++)
#define REP(i,j,k) for(int i = j; i >= k; i--)
#define setmax(i) const int maxn = (int) i;
#define setmod(i) const int MOD = (int) i;

//srand (time(NULL));

using namespace std;

setmax(1e5+10);

ll n,speed, pos[maxn];
pll num[maxn], xsort[maxn];

int main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);

    cin >> n;
    FOR(i,0,n)
    {
        ll a,b;
        cin >> a >> b;
        num[i].ff = a;
        num[i].ss = b;
    }
    cin >> speed;
    FOR(i,0,n)
    {
        ll t =  num[i].ff + num[i].ss * speed;
        ll t2 = -num[i].ff + num[i].ss * speed;
        num[i].ff = t2;
        num[i].ss = t;
    }
    sort(num,num+n);
    FOR(i,0,n) pos[i] = num[i].ss;

    ll ii;
    FOR(i,0,n) if(num[i].ff >= 0 && num[i].ss >= 0)
    {
        ii = i;
        break;
    }

    multiset<ll> st;
    multiset<ll>::iterator it;

    FOR(i,ii,n)
    {
        if(pos[i] < 0) continue;
        st.insert(pos[i]);
        it = st.upper_bound(pos[i]);
        if(it != st.end()) st.erase(it);
    }
    cout << st.size() << " ";
    st.clear();
    FOR(i,0,n)
    {
        st.insert(pos[i]);
        it = st.upper_bound(pos[i]);
        if(it != st.end()) st.erase(it);
    }
    cout << st.size();
}


#include <cstdio>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;

typedef long double ld;
typedef pair <ld, ld> dd;

const int Maxn = 100005;
const ld eps = 1e-7l;

int n;
int x[Maxn], t[Maxn];
int v;
ld ang, sn, cs;
dd c[Maxn];
vector <ld> seq;

bool Less(const dd &a, const dd &b)
{
	if (fabs(a.first - b.first) > eps) return a.first < b.first;
	if (fabs(a.second - b.second) > eps) return a.second < b.second;
	return false;
}

int getRes1()
{
	seq.clear();
	for (int i = 0; i < n; i++) if (c[i].first + eps >= 0.0l && c[i].second + eps >= 0.0l) {
		int lef = 0, rig = int(seq.size()) - 1;
		int ind = seq.size();
		while (lef <= rig) {
			int mid = lef + rig >> 1;
			if (c[i].second + eps < seq[mid]) { ind = mid; rig = mid - 1; }
			else lef = mid + 1;
		}
		if (ind < seq.size()) seq[ind] = c[i].second;
		else seq.push_back(c[i].second);
	}
	return seq.size();
}

int getRes2()
{
	seq.clear();
	for (int i = 0; i < n; i++) {
		int lef = 0, rig = int(seq.size()) - 1;
		int ind = seq.size();
		while (lef <= rig) {
			int mid = lef + rig >> 1;
			if (c[i].second + eps < seq[mid]) { ind = mid; rig = mid - 1; }
			else lef = mid + 1;
		}
		if (ind < seq.size()) seq[ind] = c[i].second;
		else seq.push_back(c[i].second);
	}
	return seq.size();
}

int main()
{
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
		scanf("%d %d", &x[i], &t[i]);
	scanf("%d", &v);
	ang = atan(1.0l / ld(v)); sn = sin(ang), cs = cos(ang);
	for (int i = 0; i < n; i++)
		c[i] = dd(x[i] * sn + t[i] * cs, -x[i] * sn + t[i] * cs);
	sort(c, c + n, Less);
	printf("%d %d\n", getRes1(), getRes2());
	return 0;
}


#include <cstdio>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;

typedef long double ld;
typedef pair <ld, ld> dd;

const int Maxn = 100005;

int n;
int x[Maxn], t[Maxn];
int v;
ld ang, sn, cs;
dd c[Maxn];
vector <ld> seq;

int getRes1()
{
	seq.clear();
	for (int i = 0; i < n; i++) if (c[i].first >= 0.0l && c[i].second >= 0.0l) {
		int ind = upper_bound(seq.begin(), seq.end(), c[i].second) - seq.begin();
		if (ind < seq.size()) seq[ind] = c[i].second;
		else seq.push_back(c[i].second);
	}
	return seq.size();
}

int getRes2()
{
	seq.clear();
	for (int i = 0; i < n; i++) {
		int ind = upper_bound(seq.begin(), seq.end(), c[i].second) - seq.begin();
		if (ind < seq.size()) seq[ind] = c[i].second;
		else seq.push_back(c[i].second);
	}
	return seq.size();
}

int main()
{
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
		scanf("%d %d", &x[i], &t[i]);
	scanf("%d", &v);
	ang = atan(1.0l / ld(v)); sn = sin(ang), cs = cos(ang);
	for (int i = 0; i < n; i++)
		c[i] = dd(x[i] * sn + t[i] * cs, -x[i] * sn + t[i] * cs);
	sort(c, c + n);
	printf("%d %d\n", getRes1(), getRes2());
	return 0;
}


//Tornike Mandzulashvili
//#pragma comment(linker, "/STACK:16777216")
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <vector>
#include <string>
#include <map>
#include <queue>
#include <iostream>
#include <set>
#define PI 3.14159265
#define INF 2000000000
#define hash1 1000003
#define hash2 1000033
#define md 1000000007

using namespace std;

bool cmp(pair <long long,long long> x,pair <long long,long long> y)
{
     return (x.first<y.first ||(x.first==y.first && x.second<y.second));
 }
long long ans1,ans2;
 long long num,n,i,V,l,r,cur,middle;
 long long k[1000000],x[1000000],dp[1000000],t[1000000];
 long long a[1000000];
 pair <long long,long long> g[1000000];
main()
{
  //    freopen("text.in","r",stdin);freopen("text.out","w",stdout);

      cin>>n;
      for (i=1;i<=n;i++)
      cin>>x[i]>>t[i];
      cin>>V;
      for (i=1;i<=n;i++)
      g[i]=make_pair(-x[i]+(long long)t[i]*V,x[i]+(long long)t[i]*V);
      sort(g+1,g+n+1,cmp);

      for (i=1;i<=n;i++)
      a[i]=g[i].second;

      dp[0]=-INF;
      for (i=1;i<=n;i++)
      dp[i]=INF;

      for (i=1;i<=n;i++)
      {
          l=1;
          r=i;
          while (l<r)
          {
                middle=(l+r)>>1;
                if (dp[middle-1]<=a[i]) l=middle;else r=middle-1;
                if (r-l==1) if (dp[l]<=a[i]) l++;else r--;
                }

          if (dp[r-1]<=a[i] && a[i]<dp[r]) dp[r]=a[i];
      }
      cur=n;
      while (dp[cur]==INF) cur--;
      ans2=cur;

      g[1]=make_pair(0,0);
      for (i=1;i<=n;i++)
      g[i+1]=make_pair(-x[i]+(long long)t[i]*V,x[i]+(long long)t[i]*V);
      n++;
      sort(g+1,g+n+1,cmp);

      for (i=1;i<=n;i++)
      a[i]=g[i].second;

      for (i=1;i<=n;i++)
      if (a[i]==0) num=i;

      for (i=num;i<=n;i++)
      k[i-num+1]=a[i];

      n=n-num+1;
      for (i=1;i<=n;i++)
      a[i]=k[i];

      dp[0]=-INF;
      for (i=1;i<=n;i++)
      dp[i]=INF;

      for (i=1;i<=n;i++)
      {
          l=1;
          r=i;
          while (l<r)
          {
                middle=(l+r)>>1;
                if (dp[middle-1]<=a[i]) l=middle;else r=middle-1;
                if (r-l==1) if (dp[l]<=a[i]) l++;else r--;
                }
          if (dp[r-1]<=a[i] && a[i]<dp[r]) dp[r]=a[i];
      }
      cur=n;
      while (dp[cur]==INF) cur--;
      ans1=cur-1;
      cout<<ans1<<" "<<ans2<<endl;
}


//Tornike Mandzulashvili
//#pragma comment(linker, "/STACK:16777216")
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <vector>
#include <string>
#include <map>
#include <queue>
#include <iostream>
#include <set>
#define PI 3.14159265
#define INF 2000000000
#define hash1 1000003
#define hash2 1000033
#define md 1000000007

using namespace std;

bool cmp(pair <long long,long long> x,pair <long long,long long> y)
{
     return (x.first<y.first ||(x.first==y.first && x.second<y.second));
 }
long long len,ans1,ans2;
 long long num,n,i,V,l,r,cur,middle;
 long long k[1000000],x[1000000],dp[1000000],t[1000000];
 long long a[1000000];
 pair <long long,long long> g[1000000];
main()
{
   //   freopen("text.in","r",stdin);freopen("text.out","w",stdout);

      cin>>n;
      for (i=1;i<=n;i++)
      cin>>x[i]>>t[i];
      cin>>V;
      for (i=1;i<=n;i++)
      g[i]=make_pair(-x[i]+(long long)t[i]*V,x[i]+(long long)t[i]*V);
      sort(g+1,g+n+1,cmp);

      for (i=1;i<=n;i++)
      a[i]=g[i].second;

      dp[0]=-INF;
      for (i=1;i<=n;i++)
      dp[i]=INF;

      for (i=1;i<=n;i++)
      {
          l=1;
          r=i;
          while (l<r)
          {
                middle=(l+r)>>1;
                if (dp[middle-1]<=a[i]) l=middle;else r=middle-1;
                if (r-l==1) if (dp[l]<=a[i]) l++;else r--;
                }

          if (dp[r-1]<=a[i] && a[i]<dp[r]) dp[r]=a[i];
      }
      cur=n;
      while (dp[cur]==INF) cur--;
      ans2=cur;

      g[1]=make_pair(0,0);
      for (i=1;i<=n;i++)
      g[i+1]=make_pair(-x[i]+(long long)t[i]*V,x[i]+(long long)t[i]*V);
      n++;
      sort(g+1,g+n+1,cmp);

      for (i=1;i<=n;i++)
      a[i]=g[i].second;

      for (i=1;i<=n;i++)
      if (a[i]==0) num=i;

      for (i=num;i<=n;i++)
      if (a[i]>=0)
      {
                  len++;
                  k[len]=a[i];
                  }

      n=len;
      for (i=1;i<=n;i++)
      a[i]=k[i];

      dp[0]=-INF;
      for (i=1;i<=n;i++)
      dp[i]=INF;

      for (i=1;i<=n;i++)
      {
          l=1;
          r=i;
          while (l<r)
          {
                middle=(l+r)>>1;
                if (dp[middle-1]<=a[i]) l=middle;else r=middle-1;
                if (r-l==1) if (dp[l]<=a[i]) l++;else r--;
                }
          if (dp[r-1]<=a[i] && a[i]<dp[r]) dp[r]=a[i];
      }
      cur=n;
      while (dp[cur]==INF) cur--;
      ans1=cur-1;
      cout<<ans1<<" "<<ans2<<endl;
}


//Tornike Mandzulashvili
//#pragma comment(linker, "/STACK:16777216")
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <vector>
#include <string>
#include <map>
#include <queue>
#include <iostream>
#include <set>
#define PI 3.14159265
#define INF 2000000000
#define hash1 1000003
#define hash2 1000033
#define md 1000000007

using namespace std;

bool cmp(pair <long long,long long> x,pair <long long,long long> y)
{
     return (x.first<y.first ||(x.first==y.first && x.second<y.second));
 }
long long ans1,ans2;
 long long num,n,i,V,l,r,cur,middle;
 long long x[1000000],dp[1000000],t[1000000];
 long long a[1000000];
 pair <long long,long long> g[1000000];
main()
{
  //    freopen("text.in","r",stdin);freopen("text.out","w",stdout);

      cin>>n;
      for (i=1;i<=n;i++)
      cin>>x[i]>>t[i];
      cin>>V;
      for (i=1;i<=n;i++)
      g[i]=make_pair(-x[i]+(long long)t[i]*V,x[i]+(long long)t[i]*V);
      sort(g+1,g+n+1,cmp);

      for (i=1;i<=n;i++)
      a[i]=g[i].second;

      dp[0]=-INF;
      for (i=1;i<=n;i++)
      dp[i]=INF;

      for (i=1;i<=n;i++)
      {
          l=1;
          r=i;
          while (l<r)
          {
                middle=(l+r)>>1;
                if (dp[middle-1]<=a[i]) l=middle;else r=middle-1;
                if (r-l==1) if (dp[l]<=a[i]) l++;else r--;
                }

          if (dp[r-1]<=a[i] && a[i]<dp[r]) dp[r]=a[i];
      }
      cur=n;
      while (dp[cur]==INF) cur--;
      ans2=cur;

      g[1]=make_pair(0,0);
      for (i=1;i<=n;i++)
      g[i+1]=make_pair(-x[i]+(long long)t[i]*V,x[i]+(long long)t[i]*V);
      n++;
      sort(g+1,g+n+1,cmp);

      for (i=1;i<=n;i++)
      a[i]=g[i].second;

      for (i=1;i<=n;i++)
      if (a[i]==0) num=i;

      for (i=num;i<=n;i++)
      a[i-num+1]=a[i];
      n=n-num+1;

      dp[0]=-INF;
      for (i=1;i<=n;i++)
      dp[i]=INF;

      for (i=1;i<=n;i++)
      {
          l=1;
          r=i;
          while (l<r)
          {
                middle=(l+r)>>1;
                if (dp[middle-1]<=a[i]) l=middle;else r=middle-1;
                if (r-l==1) if (dp[l]<=a[i]) l++;else r--;
                }
          if (dp[r-1]<=a[i] && a[i]<dp[r]) dp[r]=a[i];
      }
      cur=n;
      while (dp[cur]==INF) cur--;
      ans1=cur-1;
      cout<<ans1<<" "<<ans2<<endl;
}


//Tornike Mandzulashvili
//#pragma comment(linker, "/STACK:16777216")
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <vector>
#include <string>
#include <map>
#include <queue>
#include <iostream>
#include <set>
#define PI 3.14159265
#define INF 2000000000
#define hash1 1000003
#define hash2 1000033
#define md 1000000007

using namespace std;

bool cmp(pair <long long,long long> x,pair <long long,long long> y)
{
     return (x.first<y.first ||(x.first==y.first && x.second<y.second));
 }
long long ans1,ans2;
 long long num,n,i,V,l,r,cur,middle;
 long long x[1000000],dp[1000000],t[1000000];
 long long a[1000000];
 pair <long long,long long> g[1000000];
main()
{
  //    freopen("text.in","r",stdin);freopen("text.out","w",stdout);

      cin>>n;
      for (i=1;i<=n;i++)
      cin>>x[i]>>t[i];
      cin>>V;
      for (i=1;i<=n;i++)
      g[i]=make_pair(-x[i]+(long long)t[i]*V,x[i]+(long long)t[i]*V);
      sort(g+1,g+n+1,cmp);

      for (i=1;i<=n;i++)
      a[i]=g[i].second;

      dp[0]=-INF;
      for (i=1;i<=n;i++)
      dp[i]=INF;

      for (i=1;i<=n;i++)
      {
          l=1;
          r=i;
          while (l<r)
          {
                middle=(l+r)>>1;
                if (dp[middle-1]<=a[i]) l=middle;else r=middle-1;
                if (r-l==1) if (dp[l]<=a[i]) l++;else r--;
                }

          if (dp[r-1]<=a[i] && a[i]<dp[r]) dp[r]=a[i];
      }
      cur=n;
      while (dp[cur]==INF) cur--;
      ans2=cur;

      g[1]=make_pair(0,0);
      for (i=1;i<=n;i++)
      g[i+1]=make_pair(-x[i]+(long long)t[i]*V,x[i]+(long long)t[i]*V);
      n++;
      sort(g+1,g+n+1,cmp);

      for (i=1;i<=n;i++)
      a[i]=g[i].second;

      for (i=1;i<=n;i++)
      if (a[i]==0) num=i;

      for (i=num;i<=n;i++)
      swap(a[i],a[i-num+1]);
      n=n-num+1;

      dp[0]=-INF;
      for (i=1;i<=n;i++)
      dp[i]=INF;

      for (i=1;i<=n;i++)
      {
          l=1;
          r=i;
          while (l<r)
          {
                middle=(l+r)>>1;
                if (dp[middle-1]<=a[i]) l=middle;else r=middle-1;
                if (r-l==1) if (dp[l]<=a[i]) l++;else r--;
                }
          if (dp[r-1]<=a[i] && a[i]<dp[r]) dp[r]=a[i];
      }
      cur=n;
      while (dp[cur]==INF) cur--;
      ans1=cur-1;
      cout<<ans1<<" "<<ans2<<endl;
}


//Tornike Mandzulashvili
//#pragma comment(linker, "/STACK:16777216")
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <vector>
#include <string>
#include <map>
#include <queue>
#include <iostream>
#include <set>
#define PI 3.14159265
#define INF 2000000000
#define hash1 1000003
#define hash2 1000033
#define md 1000000007
#define INF 1000000000
using namespace std;

bool cmp(pair <int,int> x,pair <int,int> y)
{
     return (x.first<y.first ||(x.first==y.first && x.second<y.second));
 }

 int ans2,n,i,V,l,r,ans1,cur,middle;
 int x[1000000],a[1000000],dp[1000000],t[1000000];
 pair <int,int> g[1000000];
main()
{
  //    freopen("text.in","r",stdin);freopen("text.out","w",stdout);

      scanf("%d",&n);
      for (i=1;i<=n;i++)
      scanf("%d %d",&x[i],&t[i]);
      scanf("%d",&V);
      for (i=1;i<=n;i++)
      g[i]=make_pair(-x[i]+(long long)t[i]*V,x[i]+(long long)t[i]*V);
      sort(g+1,g+n+1,cmp);

      for (i=1;i<=n;i++)
      a[i]=g[i].second;

      dp[0]=-INF;
      for (i=1;i<=n;i++)
      dp[i]=INF;

      for (i=1;i<=n;i++)
      {
          l=1;
          r=i;
          while (l<r)
          {
                middle=(l+r)>>1;
                if (dp[middle-1]<a[i]) l=middle;else r=middle-1;
                if (r-l==1) if (dp[l]<a[i]) l++;else r--;
                }

          if (dp[r-1]<a[i] && a[i]<dp[r]) dp[r]=a[i];
      }
      cur=n;
      while (dp[cur]==INF) cur--;
      ans1=cur;

      g[1]=make_pair(0,0);
      for (i=1;i<=n;i++)
      g[i+1]=make_pair(-x[i]+(long long)t[i]*V,x[i]+(long long)t[i]*V);
      n++;
      sort(g+1,g+n+1,cmp);

      for (i=1;i<=n;i++)
      a[i]=g[i].second;

      dp[0]=-INF;
      for (i=1;i<=n;i++)
      dp[i]=INF;

      for (i=1;i<=n;i++)
      {
          l=1;
          r=i;
          while (l<r)
          {
                middle=(l+r)>>1;
                if (dp[middle-1]<a[i]) l=middle;else r=middle-1;
                if (r-l==1) if (dp[l]<a[i]) l++;else r--;
                }

          if (dp[r-1]<a[i] && a[i]<dp[r]) dp[r]=a[i];
      }
      cur=n;
      while (dp[cur]==INF) cur--;
      ans2=cur;
      printf("%d %d\n",ans1,ans2);
}


//Tornike Mandzulashvili
//#pragma comment(linker, "/STACK:16777216")
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <vector>
#include <string>
#include <map>
#include <queue>
#include <iostream>
#include <set>
#define PI 3.14159265
#define INF 2000000000
#define hash1 1000003
#define hash2 1000033
#define md 1000000007

using namespace std;

bool cmp(pair <long long,long long> x,pair <long long,long long> y)
{
     return (x.first<y.first ||(x.first==y.first && x.second<y.second));
 }

 int num,ans2,n,i,V,l,r,ans1,cur,middle;
 int x[1000000],dp[1000000],t[1000000];
 long long a[1000000];
 pair <long long,long long> g[1000000];
main()
{
   //   freopen("text.in","r",stdin);freopen("text.out","w",stdout);

      scanf("%d",&n);
      for (i=1;i<=n;i++)
      scanf("%d %d",&x[i],&t[i]);
      scanf("%d",&V);
      for (i=1;i<=n;i++)
      g[i]=make_pair(-x[i]+(long long)t[i]*V,x[i]+(long long)t[i]*V);
      sort(g+1,g+n+1,cmp);

      for (i=1;i<=n;i++)
      a[i]=g[i].second;

      dp[0]=-INF;
      for (i=1;i<=n;i++)
      dp[i]=INF;

      for (i=1;i<=n;i++)
      {
          l=1;
          r=i;
          while (l<r)
          {
                middle=(l+r)>>1;
                if (dp[middle-1]<=a[i]) l=middle;else r=middle-1;
                if (r-l==1) if (dp[l]<=a[i]) l++;else r--;
                }

          if (dp[r-1]<=a[i] && a[i]<dp[r]) dp[r]=a[i];
      }
      cur=n;
      while (dp[cur]==INF) cur--;
      ans2=cur;

      g[1]=make_pair(0,0);
      for (i=1;i<=n;i++)
      g[i+1]=make_pair(-x[i]+(long long)t[i]*V,x[i]+(long long)t[i]*V);
      n++;
      sort(g+1,g+n+1,cmp);

      for (i=1;i<=n;i++)
      a[i]=g[i].second;

      for (i=1;i<=n;i++)
      if (a[i]==0) num=i;

      for (i=num;i<=n;i++)
      swap(a[i],a[i-num+1]);
      n=n-num+1;

      dp[0]=-INF;
      for (i=1;i<=n;i++)
      dp[i]=INF;

      for (i=1;i<=n;i++)
      {
          l=1;
          r=i;
          while (l<r)
          {
                middle=(l+r)>>1;
                if (dp[middle-1]<=a[i]) l=middle;else r=middle-1;
                if (r-l==1) if (dp[l]<=a[i]) l++;else r--;
                }
          if (dp[r-1]<=a[i] && a[i]<dp[r]) dp[r]=a[i];
      }
      cur=n;
      while (dp[cur]==INF) cur--;
      ans1=cur-1;
      printf("%d %d\n",ans1,ans2);
}


//Tornike Mandzulashvili
//#pragma comment(linker, "/STACK:16777216")
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <vector>
#include <string>
#include <map>
#include <queue>
#include <iostream>
#include <set>
#define PI 3.14159265
#define INF 2000000000
#define hash1 1000003
#define hash2 1000033
#define md 1000000007
#define INF 1000000000

using namespace std;

bool cmp(pair <long long,long long> x,pair <long long,long long> y)
{
     return (x.first<y.first ||(x.first==y.first && x.second<y.second));
 }

 long long num,ans2,n,i,V,l,r,ans1,cur,middle;
 long long x[1000000],a[1000000],dp[1000000],t[1000000];
 pair <long long,long long> g[1000000];
main()
{
   //   freopen("text.in","r",stdin);freopen("text.out","w",stdout);

      scanf("%lld",&n);
      for (i=1;i<=n;i++)
      scanf("%lld %lld",&x[i],&t[i]);
      scanf("%lld",&V);
      for (i=1;i<=n;i++)
      g[i]=make_pair(-x[i]+(long long)t[i]*V,x[i]+(long long)t[i]*V);
      sort(g+1,g+n+1,cmp);

      for (i=1;i<=n;i++)
      a[i]=g[i].second;

      dp[0]=-INF;
      for (i=1;i<=n;i++)
      dp[i]=INF;

      for (i=1;i<=n;i++)
      {
          l=1;
          r=i;
          while (l<r)
          {
                middle=(l+r)>>1;
                if (dp[middle-1]<=a[i]) l=middle;else r=middle-1;
                if (r-l==1) if (dp[l]<=a[i]) l++;else r--;
                }

          if (dp[r-1]<=a[i] && a[i]<dp[r]) dp[r]=a[i];
      }
      cur=n;
      while (dp[cur]==INF) cur--;
      ans2=cur;

      g[1]=make_pair(0,0);
      for (i=1;i<=n;i++)
      g[i+1]=make_pair(-x[i]+(long long)t[i]*V,x[i]+(long long)t[i]*V);
      n++;
      sort(g+1,g+n+1,cmp);

      for (i=1;i<=n;i++)
      a[i]=g[i].second;

      for (i=1;i<=n;i++)
      if (a[i]==0) num=i;

      for (i=num;i<=n;i++)
      swap(a[i],a[i-num+1]);
      n=n-num+1;

      dp[0]=-INF;
      for (i=1;i<=n;i++)
      dp[i]=INF;

      for (i=1;i<=n;i++)
      {
          l=1;
          r=i;
          while (l<r)
          {
                middle=(l+r)>>1;
                if (dp[middle-1]<=a[i]) l=middle;else r=middle-1;
                if (r-l==1) if (dp[l]<=a[i]) l++;else r--;
                }
          if (dp[r-1]<=a[i] && a[i]<dp[r]) dp[r]=a[i];
      }
      cur=n;
      while (dp[cur]==INF) cur--;
      ans1=cur-1;
      printf("%I64d %I64d\n",ans1,ans2);
}


//Tornike Mandzulashvili
//#pragma comment(linker, "/STACK:16777216")
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <vector>
#include <string>
#include <map>
#include <queue>
#include <iostream>
#include <set>
#define PI 3.14159265
#define INF 2000000000
#define hash1 1000003
#define hash2 1000033
#define md 1000000007

using namespace std;

bool cmp(pair <long long,long long> x,pair <long long,long long> y)
{
     return (x.first<y.first ||(x.first==y.first && x.second<y.second));
 }

 long long num,ans2,n,i,V,l,r,ans1,cur,middle;
 long long x[1000000],a[1000000],dp[1000000],t[1000000];
 pair <long long,long long> g[1000000];
main()
{
  //    freopen("text.in","r",stdin);freopen("text.out","w",stdout);

      scanf("%lld",&n);
      for (i=1;i<=n;i++)
      scanf("%lld %lld",&x[i],&t[i]);
      scanf("%lld",&V);
      for (i=1;i<=n;i++)
      g[i]=make_pair(-x[i]+(long long)t[i]*V,x[i]+(long long)t[i]*V);
      sort(g+1,g+n+1,cmp);

      for (i=1;i<=n;i++)
      a[i]=g[i].second;

      dp[0]=-INF;
      for (i=1;i<=n;i++)
      dp[i]=INF;

      for (i=1;i<=n;i++)
      {
          l=1;
          r=i;
          while (l<r)
          {
                middle=(l+r)>>1;
                if (dp[middle-1]<=a[i]) l=middle;else r=middle-1;
                if (r-l==1) if (dp[l]<=a[i]) l++;else r--;
                }

          if (dp[r-1]<=a[i] && a[i]<dp[r]) dp[r]=a[i];
      }
      cur=n;
      while (dp[cur]==INF) cur--;
      ans2=cur;

      g[1]=make_pair(0,0);
      for (i=1;i<=n;i++)
      g[i+1]=make_pair(-x[i]+(long long)t[i]*V,x[i]+(long long)t[i]*V);
      n++;
      sort(g+1,g+n+1,cmp);

      for (i=1;i<=n;i++)
      a[i]=g[i].second;

      for (i=1;i<=n;i++)
      if (a[i]==0) num=i;

      for (i=num;i<=n;i++)
      swap(a[i],a[i-num+1]);
      n=n-num+1;

      dp[0]=-INF;
      for (i=1;i<=n;i++)
      dp[i]=INF;

      for (i=1;i<=n;i++)
      {
          l=1;
          r=i;
          while (l<r)
          {
                middle=(l+r)>>1;
                if (dp[middle-1]<=a[i]) l=middle;else r=middle-1;
                if (r-l==1) if (dp[l]<=a[i]) l++;else r--;
                }
          if (dp[r-1]<=a[i] && a[i]<dp[r]) dp[r]=a[i];
      }
      cur=n;
      while (dp[cur]==INF) cur--;
      ans1=cur-1;
      printf("%I64d %I64d\n",ans1,ans2);
}


#include <cstdio>
#include <algorithm>

using namespace std;
struct INC{
  int x,y;
  bool operator <(const INC &a) const{
    return (x<a.x) || (x==a.x && y<a.y);
  }
}A[100100];
int f[200100],n,i,j,Vel,maxx,K;

int main(){
  scanf("%d",&n);
  for (i=1;i<=n;i++) scanf("%d%d",&A[i].x,&A[i].y);
  scanf("%d",&Vel);

  n++;
  for (i=1;i<=n;i++){
    A[i].y=A[i].y*Vel-A[i].x;
    A[i].x=A[i].x*2+A[i].y;
  }
  sort(A+1,A+n+1);

  for (i=n;i>0;i--){
    K=upper_bound(f+1,f+maxx+1,-A[i].y)-f;
    if (A[i].x==0 && A[i].y==0)
      { printf("%d ",K-1);continue; }
    f[K]=-A[i].y;
    if (K>maxx) maxx=K;
  }
  printf("%d\n",maxx);
  return 0;
}


#include <cstdio>
#include <algorithm>

using namespace std;
struct INC{
  int x,y;
  bool operator <(const INC &a) const{
    return (x<a.x) || (x==a.x && y<a.y);
  }
}A[100100];
int f[200100],n,i,j,Vel,maxx,K;

int main(){
  freopen("76F.in","r",stdin);
  freopen("76F.out","w",stdout);
  scanf("%d",&n);
  for (i=1;i<=n;i++) scanf("%d%d",&A[i].x,&A[i].y);
  scanf("%d",&Vel);

  n++;
  for (i=1;i<=n;i++){
    A[i].y=A[i].y*Vel-A[i].x;
    A[i].x=A[i].x+A[i].y;
  }
  sort(A+1,A+n+1);

  for (i=n;i>0;i--){
    K=upper_bound(f+1,f+maxx+1,-A[i].y)-f;
    if (A[i].x==0 && A[i].y==0)
      { printf("%d ",K-1);continue; }
    f[K]=-A[i].y;
    if (K>maxx) maxx=K;
  }
  printf("%d\n",maxx);
  return 0;
}


#include <cstdio>
#include <algorithm>

using namespace std;
struct INC{
  int x,y;
  bool operator <(const INC &a) const{
    return (x<a.x) || (x==a.x && y<a.y);
  }
}A[100100];
int f[200100],n,i,j,Vel,maxx,K;

int main(){
  scanf("%d",&n);
  for (i=1;i<=n;i++) scanf("%d%d",&A[i].x,&A[i].y);
  scanf("%d",&Vel);

  n++;
  for (i=1;i<=n;i++){
    A[i].y=A[i].y*Vel-A[i].x;
    A[i].x=A[i].x+A[i].y;
  }
  sort(A+1,A+n+1);

  for (i=n;i>0;i--){
    K=upper_bound(f+1,f+maxx+1,-A[i].y)-f;
    if (A[i].x==0 && A[i].y==0)
      { printf("%d ",K-1);continue; }
    f[K]=-A[i].y;
    if (K>maxx) maxx=K;
  }
  printf("%d\n",maxx);
  return 0;
}


#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
struct ev{
int t,d;
long long p,q;
};
ev ar[100005];
bool cmp(ev a,ev b)
{
    if(a.p != b.p)
        return a.p < b.p;
    return a.q < b.q;
}
vector <long long> bst;
int main()
{
    freopen("in.in","r",stdin);
    int n,i;
    long long v;
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        scanf("%d%d",&ar[i].d,&ar[i].t);
        //upd(1,1,n,ar[i].d,0);
    }
    scanf("%lld",&v);
    for(i=0;i<n;i++)
    {
        ar[i].p = -(ar[i].d - v*ar[i].t);
        ar[i].q = (ar[i].d + v*ar[i].t);
        //upd(1,1,n,ar[i].d,0);
    }
    bst.resize(n+10);
    sort(ar,ar+n,cmp);
    for(i=0;i<n;i++)
        printf("%lld %lld\n",ar[i].p/1000000,ar[i].q/1000000);
    bst[0]=ar[i].q;
    int c=0,fn;
    for(i=1;i<n;i++)
    {
        if(bst[c] <= ar[i].q)
        {
            c++;
            printf("%d c  =%d\n",i,c);
            bst[c]=ar[i].q;
            continue;
        }
        fn=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin();
        bst[fn]=ar[i].q;
        printf("%d %d\n",i,fn);
        c=max(c,fn);
    }
    int sv=c+1;
    ar[n].p=0;
    ar[n].q=0;
    sort(ar,ar+n+1,cmp);
    bst[0]=0;
    for(i=0;i<n+1;i++)
    if(ar[i].p > 0)
        break;
    int en=i;
    c=0;
    for(i=en;i<n+1;i++)
    {
        if(bst[c] <= ar[i].q)
        {
            c++;
            //printf("%d c  =%d\n",i,c);
            bst[c]=ar[i].q;
            continue;
        }
        fn=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin();
        bst[fn]=ar[i].q;
        //printf("%d %d\n",i,fn);
        c=max(c,fn);
    }
        /*if(bst[c] <= ar[i].q)
            c++;
        else
            c=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin();*/
    printf("%d %d\n",c,sv);
    //upd(1,1,n,0,0);
}
/*int rd(int nd,int a,int b,int t1,int t2)
{
    if(b < a)
        return;
    if(t1 > b || t2 < a)
        return 0;
    if(a <= t1 && b <= x2)
        return sg[nd];
    int m=(a+b)/2;
    return max(rd(nd*2,a,m,t1,t2),rd(nd*2+1,m+1,b,t1,t2))
}
void upd(int nd,int a,int b,int x,int v)
{
    if(nd == 0)
        return;
    if(b < a)
        return;
    if(x < a || x > b)
        return;
    sg[nd] = max(sg[nd],v);
    int m=(a+b)/2;
    upd(nd*2,a,m,v);
    upd(nd*2+1,m+1,b,v);
}*/


#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
struct ev{
int t,d;
long long p,q;
};
ev ar[100005];
bool cmp(ev a,ev b)
{
    if(a.p != b.p)
        return a.p < b.p;
    return a.q < b.q;
}
vector <long long> bst;
int main()
{
    //freopen("in.in","r",stdin);
    int n,i;
    long long v;
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        scanf("%d%d",&ar[i].d,&ar[i].t);
        //upd(1,1,n,ar[i].d,0);
    }
    scanf("%lld",&v);
    for(i=0;i<n;i++)
    {
        ar[i].p = -(ar[i].d - v*ar[i].t);
        ar[i].q = (ar[i].d + v*ar[i].t);
        //upd(1,1,n,ar[i].d,0);
    }
    bst.resize(n+10);
    sort(ar,ar+n,cmp);
    //for(i=0;i<n;i++)
        //printf("%lld %lld\n",ar[i].p,ar[i].q);
    bst[0]=ar[0].q;
    int c=0,fn;
    for(i=1;i<n;i++)
    {
        if(bst[c] <= ar[i].q)
        {
            c++;
            //printf("%d bst[%d] = %d\n",i,c,ar[i].q);
            bst[c]=ar[i].q;
            continue;
        }
        fn=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin();
        bst[fn]=ar[i].q;
        //printf("%d bst[%d] = %d\n",i,fn,ar[i].q);
        c=max(c,fn);
    }
    int sv=c+1;
    ar[n].p=0;
    ar[n].q=0;
    sort(ar,ar+n+1,cmp);
    bst[0]=0;
    for(i=0;i<n+1;i++)
    if(ar[i].p > 0)
        break;
    int en=i;
    c=0;
    for(i=en+1;i<n+1;i++)
    {
        if(bst[c] <= ar[i].q)
        {
            c++;
            //printf("%d c  =%d\n",i,c);
            bst[c]=ar[i].q;
            continue;
        }
        fn=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin();
        bst[fn]=ar[i].q;
        //printf("%d %d\n",i,fn);
        c=max(c,fn);
    }
        /*if(bst[c] <= ar[i].q)
            c++;
        else
            c=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin();*/
    printf("%d %d\n",c,sv);
    //upd(1,1,n,0,0);
}
/*int rd(int nd,int a,int b,int t1,int t2)
{
    if(b < a)
        return;
    if(t1 > b || t2 < a)
        return 0;
    if(a <= t1 && b <= x2)
        return sg[nd];
    int m=(a+b)/2;
    return max(rd(nd*2,a,m,t1,t2),rd(nd*2+1,m+1,b,t1,t2))
}
void upd(int nd,int a,int b,int x,int v)
{
    if(nd == 0)
        return;
    if(b < a)
        return;
    if(x < a || x > b)
        return;
    sg[nd] = max(sg[nd],v);
    int m=(a+b)/2;
    upd(nd*2,a,m,v);
    upd(nd*2+1,m+1,b,v);
}*/


#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;

int sg[100];
struct ev{
int t,d,p,q;
};
ev ar[100005];
bool cmp(ev a,ev b)
{
    if(a.p != b.p)
        return a.p < b.p;
    return a.q < b.q;
}
vector <int> bst;
int main()
{
    //freopen("in.in","r",stdin);
    int n,i,v;
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        scanf("%d%d",&ar[i].d,&ar[i].t);
        //upd(1,1,n,ar[i].d,0);
    }
    scanf("%d",&v);
    for(i=0;i<n;i++)
    {
        ar[i].p = -(ar[i].d - v*ar[i].t);
        ar[i].q = (ar[i].d + v*ar[i].t);
        //upd(1,1,n,ar[i].d,0);
    }
    bst.resize(n+10);
    sort(ar,ar+n,cmp);
    for(i=0;i<n;i++)
        printf("%d %d\n",ar[i].p,ar[i].q);
    bst[0]=ar[i].q;
    int c=0,fn;
    for(i=1;i<n;i++)
    {
        if(bst[c] <= ar[i].q)
        {
            c++;
            //printf("%d c  =%d\n",i,c);
            bst[c]=ar[i].q;
            continue;
        }
        fn=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin()-1;
        //printf("%d %d\n",i,fn);
        c=max(c,fn+1);
    }
    int sv=c+1;
    ar[n].p=0;
    ar[n].q=0;
    sort(ar,ar+n+1,cmp);
    bst[0]=ar[0].q;
    c=0;
    for(i=1;i<n+1;i++)
    {
        if(bst[c] <= ar[i].q)
        {
            c++;
            //printf("%d c  =%d\n",i,c);
            bst[c]=ar[i].q;
            continue;
        }
        fn=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin()-1;
        //printf("%d %d\n",i,fn);
        c=max(c,fn+1);
    }
    printf("%d %d\n",c,sv);
    //upd(1,1,n,0,0);
}
/*int rd(int nd,int a,int b,int t1,int t2)
{
    if(b < a)
        return;
    if(t1 > b || t2 < a)
        return 0;
    if(a <= t1 && b <= x2)
        return sg[nd];
    int m=(a+b)/2;
    return max(rd(nd*2,a,m,t1,t2),rd(nd*2+1,m+1,b,t1,t2))
}
void upd(int nd,int a,int b,int x,int v)
{
    if(nd == 0)
        return;
    if(b < a)
        return;
    if(x < a || x > b)
        return;
    sg[nd] = max(sg[nd],v);
    int m=(a+b)/2;
    upd(nd*2,a,m,v);
    upd(nd*2+1,m+1,b,v);
}*/


#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
struct ev{
int t,d;
long long p,q;
};
ev ar[100005];
bool cmp(ev a,ev b)
{
    if(a.p != b.p)
        return a.p < b.p;
    return a.q < b.q;
}
vector <long long> bst;
int main()
{
    freopen("in.in","r",stdin);
    int n,i;
    long long v;
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        scanf("%d%d",&ar[i].d,&ar[i].t);
        //upd(1,1,n,ar[i].d,0);
    }
    scanf("%lld",&v);
    for(i=0;i<n;i++)
    {
        ar[i].p = -(ar[i].d - v*ar[i].t);
        ar[i].q = (ar[i].d + v*ar[i].t);
        //upd(1,1,n,ar[i].d,0);
    }
    bst.resize(n+10);
    sort(ar,ar+n,cmp);
    for(i=0;i<n;i++)
        printf("%lld %lld\n",ar[i].p,ar[i].q);
    bst[0]=ar[0].q;
    int c=0,fn;
    for(i=1;i<n;i++)
    {
        if(bst[c] <= ar[i].q)
        {
            c++;
            printf("%d bst[%d] = %d\n",i,c,ar[i].q);
            bst[c]=ar[i].q;
            continue;
        }
        fn=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin();
        bst[fn]=ar[i].q;
        printf("%d bst[%d] = %d\n",i,fn,ar[i].q);
        c=max(c,fn);
    }
    int sv=c+1;
    ar[n].p=0;
    ar[n].q=0;
    sort(ar,ar+n+1,cmp);
    bst[0]=0;
    for(i=0;i<n+1;i++)
    if(ar[i].p > 0)
        break;
    int en=i;
    c=0;
    for(i=en;i<n+1;i++)
    {
        if(bst[c] <= ar[i].q)
        {
            c++;
            //printf("%d c  =%d\n",i,c);
            bst[c]=ar[i].q;
            continue;
        }
        fn=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin();
        bst[fn]=ar[i].q;
        //printf("%d %d\n",i,fn);
        c=max(c,fn);
    }
        /*if(bst[c] <= ar[i].q)
            c++;
        else
            c=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin();*/
    printf("%d %d\n",c,sv);
    //upd(1,1,n,0,0);
}
/*int rd(int nd,int a,int b,int t1,int t2)
{
    if(b < a)
        return;
    if(t1 > b || t2 < a)
        return 0;
    if(a <= t1 && b <= x2)
        return sg[nd];
    int m=(a+b)/2;
    return max(rd(nd*2,a,m,t1,t2),rd(nd*2+1,m+1,b,t1,t2))
}
void upd(int nd,int a,int b,int x,int v)
{
    if(nd == 0)
        return;
    if(b < a)
        return;
    if(x < a || x > b)
        return;
    sg[nd] = max(sg[nd],v);
    int m=(a+b)/2;
    upd(nd*2,a,m,v);
    upd(nd*2+1,m+1,b,v);
}*/


#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
struct ev{
int t,d;
long long p,q;
};
ev ar[100005];
bool cmp(ev a,ev b)
{
    if(a.p != b.p)
        return a.p < b.p;
    return a.q < b.q;
}
vector <long long> bst;
int main()
{
    //freopen("in.in","r",stdin);
    int n,i;
    long long v;
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        scanf("%d%d",&ar[i].d,&ar[i].t);
        //upd(1,1,n,ar[i].d,0);
    }
    scanf("%lld",&v);
    for(i=0;i<n;i++)
    {
        ar[i].p = -(ar[i].d - v*ar[i].t);
        ar[i].q = (ar[i].d + v*ar[i].t);
        //upd(1,1,n,ar[i].d,0);
    }
    bst.resize(n+10);
    sort(ar,ar+n,cmp);
    //for(i=0;i<n;i++)
        //printf("%lld %lld\n",ar[i].p,ar[i].q);
    bst[0]=ar[0].q;
    int c=0,fn;
    for(i=1;i<n;i++)
    {
        if(bst[c] <= ar[i].q)
        {
            c++;
            //printf("%d bst[%d] = %d\n",i,c,ar[i].q);
            bst[c]=ar[i].q;
            continue;
        }
        fn=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin();
        bst[fn]=ar[i].q;
        //printf("%d bst[%d] = %d\n",i,fn,ar[i].q);
        c=max(c,fn);
    }
    int sv=c+1;
    ar[n].p=0;
    ar[n].q=0;
    sort(ar,ar+n+1,cmp);
    bst[0]=0;
    for(i=0;i<n+1;i++)
    if(ar[i].p > 0)
        break;
    int en=i;
    c=0;
    for(i=en;i<n+1;i++)
    {
        if(bst[c] <= ar[i].q)
        {
            c++;
            //printf("%d c  =%d\n",i,c);
            bst[c]=ar[i].q;
            continue;
        }
        fn=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin();
        bst[fn]=ar[i].q;
        //printf("%d %d\n",i,fn);
        c=max(c,fn);
    }
        /*if(bst[c] <= ar[i].q)
            c++;
        else
            c=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin();*/
    printf("%d %d\n",c,sv);
    //upd(1,1,n,0,0);
}
/*int rd(int nd,int a,int b,int t1,int t2)
{
    if(b < a)
        return;
    if(t1 > b || t2 < a)
        return 0;
    if(a <= t1 && b <= x2)
        return sg[nd];
    int m=(a+b)/2;
    return max(rd(nd*2,a,m,t1,t2),rd(nd*2+1,m+1,b,t1,t2))
}
void upd(int nd,int a,int b,int x,int v)
{
    if(nd == 0)
        return;
    if(b < a)
        return;
    if(x < a || x > b)
        return;
    sg[nd] = max(sg[nd],v);
    int m=(a+b)/2;
    upd(nd*2,a,m,v);
    upd(nd*2+1,m+1,b,v);
}*/


#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
struct ev{
int t,d;
long long p,q;
};
ev ar[100005];
bool cmp(ev a,ev b)
{
    if(a.p != b.p)
        return a.p < b.p;
    return a.q < b.q;
}
vector <long long> bst;
int main()
{
    freopen("in.in","r",stdin);
    int n,i;
    long long v;
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        scanf("%d%d",&ar[i].d,&ar[i].t);
        //upd(1,1,n,ar[i].d,0);
    }
    scanf("%lld",&v);
    for(i=0;i<n;i++)
    {
        ar[i].p = -(ar[i].d - v*ar[i].t);
        ar[i].q = (ar[i].d + v*ar[i].t);
        //upd(1,1,n,ar[i].d,0);
    }
    bst.resize(n+10);
    sort(ar,ar+n,cmp);
    //for(i=0;i<n;i++)
        //printf("%lld %lld\n",ar[i].p,ar[i].q);
    bst[0]=ar[0].q;
    int c=0,fn;
    for(i=1;i<n;i++)
    {
        if(bst[c] <= ar[i].q)
        {
            c++;
            //printf("%d bst[%d] = %d\n",i,c,ar[i].q);
            bst[c]=ar[i].q;
            continue;
        }
        fn=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin();
        bst[fn]=ar[i].q;
        //printf("%d bst[%d] = %d\n",i,fn,ar[i].q);
        c=max(c,fn);
    }
    int sv=c+1;
    ar[n].p=0;
    ar[n].q=0;
    sort(ar,ar+n+1,cmp);
    bst[0]=0;
    for(i=0;i<n+1;i++)
    if(ar[i].p > 0)
        break;
    int en=i;
    c=0;
    for(i=en;i<n+1;i++)
    {
        if(bst[c] <= ar[i].q)
        {
            c++;
            //printf("%d c  =%d\n",i,c);
            bst[c]=ar[i].q;
            continue;
        }
        fn=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin();
        if(fn!=0)
        bst[fn]=ar[i].q;
        //printf("%d %d\n",i,fn);
        c=max(c,fn);
    }
        /*if(bst[c] <= ar[i].q)
            c++;
        else
            c=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin();*/
    printf("%d %d\n",c,sv);
    //upd(1,1,n,0,0);
}


#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;

int sg[100];
struct ev{
int t,d,p,q;
};
ev ar[100005];
bool cmp(ev a,ev b)
{
    if(a.p != b.p)
        return a.p < b.p;
    return a.q < b.q;
}
vector <int> bst;
int main()
{
    freopen("in.in","r",stdin);
    int n,i,v;
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        scanf("%d%d",&ar[i].d,&ar[i].t);
        //upd(1,1,n,ar[i].d,0);
    }
    scanf("%d",&v);
    for(i=0;i<n;i++)
    {
        ar[i].p = -(ar[i].d - v*ar[i].t);
        ar[i].q = (ar[i].d + v*ar[i].t);
        //upd(1,1,n,ar[i].d,0);
    }
    bst.resize(n+10);
    sort(ar,ar+n,cmp);
    for(i=0;i<n;i++)
        printf("%d %d\n",ar[i].p,ar[i].q);
    bst[0]=ar[i].q;
    int c=0,fn;
    for(i=1;i<n;i++)
    {
        if(bst[c] <= ar[i].q)
        {
            c++;
            //printf("%d c  =%d\n",i,c);
            bst[c]=ar[i].q;
            continue;
        }
        fn=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin()-1;
        //printf("%d %d\n",i,fn);
        c=max(c,fn+1);
    }
    int sv=c+1;
    ar[n].p=0;
    ar[n].q=0;
    sort(ar,ar+n+1,cmp);
    bst[0]=ar[0].q;
    c=0;
    for(i=1;i<n+1;i++)
    {
        if(bst[c] <= ar[i].q)
        {
            c++;
            //printf("%d c  =%d\n",i,c);
            bst[c]=ar[i].q;
            continue;
        }
        fn=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin()-1;
        //printf("%d %d\n",i,fn);
        c=max(c,fn+1);
    }
    printf("%d %d\n",c,sv);
    //upd(1,1,n,0,0);
}
/*int rd(int nd,int a,int b,int t1,int t2)
{
    if(b < a)
        return;
    if(t1 > b || t2 < a)
        return 0;
    if(a <= t1 && b <= x2)
        return sg[nd];
    int m=(a+b)/2;
    return max(rd(nd*2,a,m,t1,t2),rd(nd*2+1,m+1,b,t1,t2))
}
void upd(int nd,int a,int b,int x,int v)
{
    if(nd == 0)
        return;
    if(b < a)
        return;
    if(x < a || x > b)
        return;
    sg[nd] = max(sg[nd],v);
    int m=(a+b)/2;
    upd(nd*2,a,m,v);
    upd(nd*2+1,m+1,b,v);
}*/


#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;

int sg[100];
struct ev{
int t,d,p,q;
};
ev ar[100005];
bool cmp(ev a,ev b)
{
    if(a.p != b.p)
        return a.p < b.p;
    return a.q < b.q;
}
vector <int> bst;
int main()
{
    //freopen("in.in","r",stdin);
    int n,i,v;
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        scanf("%d%d",&ar[i].d,&ar[i].t);
        //upd(1,1,n,ar[i].d,0);
    }
    scanf("%d",&v);
    for(i=0;i<n;i++)
    {
        ar[i].p = -(ar[i].d - v*ar[i].t);
        ar[i].q = (ar[i].d + v*ar[i].t);
        //upd(1,1,n,ar[i].d,0);
    }
    bst.resize(n+10);
    sort(ar,ar+n,cmp);
    //for(i=0;i<n;i++)
        //printf("%d %d\n",ar[i].p,ar[i].q);
    bst[0]=ar[i].q;
    int c=0,fn;
    for(i=1;i<n;i++)
    {
        if(bst[c] <= ar[i].q)
        {
            c++;
            //printf("%d c  =%d\n",i,c);
            bst[c]=ar[i].q;
            continue;
        }
        fn=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin()-1;
        //printf("%d %d\n",i,fn);
        c=max(c,fn+1);
    }
    int sv=c+1;
    ar[n].p=0;
    ar[n].q=0;
    sort(ar,ar+n+1,cmp);
    bst[0]=0;
    for(i=0;i<n;i++)
    if(ar[i].q == 0 && ar[i].p == 0)
        break;
    i++;
    c=0;
    for(;i<n+1;i++)
    {
        if(bst[c] <= ar[i].q)
        {
            c++;
            //printf("%d c  =%d\n",i,c);
            bst[c]=ar[i].q;
            continue;
        }
        fn=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin()-1;
        //printf("%d %d\n",i,fn);
        c=max(c,fn+1);
    }
    printf("%d %d\n",c,sv);
    //upd(1,1,n,0,0);
}
/*int rd(int nd,int a,int b,int t1,int t2)
{
    if(b < a)
        return;
    if(t1 > b || t2 < a)
        return 0;
    if(a <= t1 && b <= x2)
        return sg[nd];
    int m=(a+b)/2;
    return max(rd(nd*2,a,m,t1,t2),rd(nd*2+1,m+1,b,t1,t2))
}
void upd(int nd,int a,int b,int x,int v)
{
    if(nd == 0)
        return;
    if(b < a)
        return;
    if(x < a || x > b)
        return;
    sg[nd] = max(sg[nd],v);
    int m=(a+b)/2;
    upd(nd*2,a,m,v);
    upd(nd*2+1,m+1,b,v);
}*/


#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
struct ev{
int t,d;
long long p,q;
};
ev ar[100005];
bool cmp(ev a,ev b)
{
    if(a.p != b.p)
        return a.p < b.p;
    return a.q < b.q;
}
vector <long long> bst;
int main()
{
    //freopen("in.in","r",stdin);
    int n,i;
    long long v;
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        scanf("%d%d",&ar[i].d,&ar[i].t);
        //upd(1,1,n,ar[i].d,0);
    }
    scanf("%lld",&v);
    for(i=0;i<n;i++)
    {
        ar[i].p = -(ar[i].d - v*ar[i].t);
        ar[i].q = (ar[i].d + v*ar[i].t);
        //upd(1,1,n,ar[i].d,0);
    }
    bst.resize(n+10);
    sort(ar,ar+n,cmp);
    //for(i=0;i<n;i++)
        //printf("%lld %lld\n",ar[i].p/1000000,ar[i].q/1000000);
    bst[0]=ar[i].q;
    int c=0,fn;
    for(i=1;i<n;i++)
    {
        if(bst[c] <= ar[i].q)
        {
            c++;
            //printf("%d c  =%d\n",i,c);
            bst[c]=ar[i].q;
            continue;
        }
        fn=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin();
        bst[fn]=ar[i].q;
        //printf("%d %d\n",i,fn);
        c=max(c,fn);
    }
    int sv=c+1;
    ar[n].p=0;
    ar[n].q=0;
    sort(ar,ar+n+1,cmp);
    bst[0]=0;
    for(i=0;i<n+1;i++)
    if(ar[i].p > 0)
        break;
    int en=i;
    c=0;
    for(i=en;i<n+1;i++)
    {
        if(bst[c] <= ar[i].q)
        {
            c++;
            //printf("%d c  =%d\n",i,c);
            bst[c]=ar[i].q;
            continue;
        }
        fn=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin();
        bst[fn]=ar[i].q;
        //printf("%d %d\n",i,fn);
        c=max(c,fn);
    }
        /*if(bst[c] <= ar[i].q)
            c++;
        else
            c=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin();*/
    printf("%d %d\n",c,sv);
    //upd(1,1,n,0,0);
}
/*int rd(int nd,int a,int b,int t1,int t2)
{
    if(b < a)
        return;
    if(t1 > b || t2 < a)
        return 0;
    if(a <= t1 && b <= x2)
        return sg[nd];
    int m=(a+b)/2;
    return max(rd(nd*2,a,m,t1,t2),rd(nd*2+1,m+1,b,t1,t2))
}
void upd(int nd,int a,int b,int x,int v)
{
    if(nd == 0)
        return;
    if(b < a)
        return;
    if(x < a || x > b)
        return;
    sg[nd] = max(sg[nd],v);
    int m=(a+b)/2;
    upd(nd*2,a,m,v);
    upd(nd*2+1,m+1,b,v);
}*/


#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;

int sg[100];
struct ev{
int t,d,p,q;
};
ev ar[100005];
bool cmp(ev a,ev b)
{
    if(a.p != b.p)
        return a.p < b.p;
    return a.q < b.q;
}
vector <int> bst;
int main()
{
    //freopen("in.in","r",stdin);
    int n,i,v;
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        scanf("%d%d",&ar[i].d,&ar[i].t);
        //upd(1,1,n,ar[i].d,0);
    }
    scanf("%d",&v);
    for(i=0;i<n;i++)
    {
        ar[i].p = -(ar[i].d - v*ar[i].t);
        ar[i].q = (ar[i].d + v*ar[i].t);
        //upd(1,1,n,ar[i].d,0);
    }
    bst.resize(n+10);
    sort(ar,ar+n,cmp);
    //for(i=0;i<n;i++)
        //printf("%d %d\n",ar[i].p,ar[i].q);
    bst[0]=ar[i].q;
    int c=0,fn;
    for(i=1;i<n;i++)
    {
        if(bst[c] <= ar[i].q)
        {
            c++;
            //printf("%d c  =%d\n",i,c);
            bst[c]=ar[i].q;
            continue;
        }
        fn=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin()-1;
        //printf("%d %d\n",i,fn);
        c=max(c,fn+1);
    }
    int sv=c+1;
    ar[n].p=0;
    ar[n].q=0;
    sort(ar,ar+n+1,cmp);
    bst[0]=ar[0].q;
    c=0;
    for(i=1;i<n+1;i++)
    {
        if(bst[c] <= ar[i].q)
        {
            c++;
            //printf("%d c  =%d\n",i,c);
            bst[c]=ar[i].q;
            continue;
        }
        fn=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin()-1;
        //printf("%d %d\n",i,fn);
        c=max(c,fn+1);
    }
    printf("%d %d\n",c,sv);
    //upd(1,1,n,0,0);
}
/*int rd(int nd,int a,int b,int t1,int t2)
{
    if(b < a)
        return;
    if(t1 > b || t2 < a)
        return 0;
    if(a <= t1 && b <= x2)
        return sg[nd];
    int m=(a+b)/2;
    return max(rd(nd*2,a,m,t1,t2),rd(nd*2+1,m+1,b,t1,t2))
}
void upd(int nd,int a,int b,int x,int v)
{
    if(nd == 0)
        return;
    if(b < a)
        return;
    if(x < a || x > b)
        return;
    sg[nd] = max(sg[nd],v);
    int m=(a+b)/2;
    upd(nd*2,a,m,v);
    upd(nd*2+1,m+1,b,v);
}*/


#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
struct ev{
int t,d;
long long p,q;
};
ev ar[100005];
bool cmp(ev a,ev b)
{
    if(a.p != b.p)
        return a.p < b.p;
    return a.q < b.q;
}
vector <long long> bst;
int main()
{
    //freopen("in.in","r",stdin);
    int n,i;
    long long v;
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        scanf("%d%d",&ar[i].d,&ar[i].t);
        //upd(1,1,n,ar[i].d,0);
    }
    scanf("%lld",&v);
    for(i=0;i<n;i++)
    {
        ar[i].p = -(ar[i].d - v*ar[i].t);
        ar[i].q = (ar[i].d + v*ar[i].t);
        //upd(1,1,n,ar[i].d,0);
    }
    bst.resize(n+10);
    sort(ar,ar+n,cmp);
    //for(i=0;i<n;i++)
        //printf("%lld %lld\n",ar[i].p,ar[i].q);
    bst[0]=ar[0].q;
    int c=0,fn;
    for(i=1;i<n;i++)
    {
        if(bst[c] <= ar[i].q)
        {
            c++;
            //printf("%d bst[%d] = %d\n",i,c,ar[i].q);
            bst[c]=ar[i].q;
            continue;
        }
        fn=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin();
        bst[fn]=ar[i].q;
        //printf("%d bst[%d] = %d\n",i,fn,ar[i].q);
        c=max(c,fn);
    }
    int sv=c+1;
    ar[n].p=0;
    ar[n].q=0;
    sort(ar,ar+n+1,cmp);
    bst[0]=0;
    for(i=0;i<n+1;i++)
    if(ar[i].p > 0)
        break;
    int en=i;
    c=0;
    for(i=en;i<n+1;i++)
    {
        if(bst[c] <= ar[i].q)
        {
            c++;
            //printf("%d c  =%d\n",i,c);
            bst[c]=ar[i].q;
            continue;
        }
        fn=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin();
        if(fn!=0)
        bst[fn]=ar[i].q;
        //printf("%d %d\n",i,fn);
        c=max(c,fn);
    }
        /*if(bst[c] <= ar[i].q)
            c++;
        else
            c=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin();*/
    printf("%d %d\n",c,sv);
    //upd(1,1,n,0,0);
}


#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
struct ev{
int t,d;
long long p,q;
};
ev ar[100005];
bool cmp(ev a,ev b)
{
    if(a.p != b.p)
        return a.p < b.p;
    return a.q < b.q;
}
vector <long long> bst;
int main()
{
    freopen("in.in","r",stdin);
    int n,i;
    long long v;
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        scanf("%d%d",&ar[i].d,&ar[i].t);
        //upd(1,1,n,ar[i].d,0);
    }
    scanf("%lld",&v);
    for(i=0;i<n;i++)
    {
        ar[i].p = -(ar[i].d - v*ar[i].t);
        ar[i].q = (ar[i].d + v*ar[i].t);
        //upd(1,1,n,ar[i].d,0);
    }
    bst.resize(n+10);
    sort(ar,ar+n,cmp);
    //for(i=0;i<n;i++)
        //printf("%lld %lld\n",ar[i].p,ar[i].q);
    bst[0]=ar[0].q;
    int c=0,fn;
    for(i=1;i<n;i++)
    {
        if(bst[c] <= ar[i].q)
        {
            c++;
            //printf("%d bst[%d] = %d\n",i,c,ar[i].q);
            bst[c]=ar[i].q;
            continue;
        }
        fn=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin();
        bst[fn]=ar[i].q;
        //printf("%d bst[%d] = %d\n",i,fn,ar[i].q);
        c=max(c,fn);
    }
    int sv=c+1;
    ar[n].p=0;
    ar[n].q=0;
    sort(ar,ar+n+1,cmp);
    bst[0]=0;
    for(i=0;i<n+1;i++)
    if(ar[i].p > 0)
        break;
    int en=i;
    c=0;
    for(i=en;i<n+1;i++)
    {
        if(bst[c] <= ar[i].q)
        {
            c++;
            //printf("%d c  =%d\n",i,c);
            bst[c]=ar[i].q;
            continue;
        }
        fn=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin();
        bst[fn]=ar[i].q;
        //printf("%d %d\n",i,fn);
        c=max(c,fn);
    }
        /*if(bst[c] <= ar[i].q)
            c++;
        else
            c=upper_bound (bst.begin(), bst.begin()+c, ar[i].q)-bst.begin();*/
    printf("%d %d\n",c,sv);
    //upd(1,1,n,0,0);
}
/*int rd(int nd,int a,int b,int t1,int t2)
{
    if(b < a)
        return;
    if(t1 > b || t2 < a)
        return 0;
    if(a <= t1 && b <= x2)
        return sg[nd];
    int m=(a+b)/2;
    return max(rd(nd*2,a,m,t1,t2),rd(nd*2+1,m+1,b,t1,t2))
}
void upd(int nd,int a,int b,int x,int v)
{
    if(nd == 0)
        return;
    if(b < a)
        return;
    if(x < a || x > b)
        return;
    sg[nd] = max(sg[nd],v);
    int m=(a+b)/2;
    upd(nd*2,a,m,v);
    upd(nd*2+1,m+1,b,v);
}*/


#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct st{
long long x,y;
bool operator<(const st&s)const{return (x<s.x||(x==s.x&&y<s.y));}
}a[100001];
int i,n,fi,an;
long long x[100001],y[100001],f[100001],v;
int erfen(int l,int r,int xx)
{
	if (l==r) return l;
	int mi=(l+r+1)/2;
	if (f[mi]<=xx)  return (erfen(mi,r,xx));
	else return(erfen(l,mi-1,xx));
}
int main()
{
//	freopen("1.in","r",stdin);
//	freopen("1.out","w",stdout);
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	scanf("%I64d%I64d",&x[i],&y[i]);
	scanf("%I64d",&v);
	for(i=1;i<=n;i++)
	a[i].x=-x[i]+y[i]*v,a[i].y=x[i]+y[i]*v;
	sort(a+1,a+n+1);
	for(i=1;i<=n;i++)
	f[i]=1e9,f[i]=f[i]*f[i];
	for(i=1;i<=n;i++)
	if(a[i].x>=0&&a[i].y>=0)
	{
		fi=erfen(0,an,a[i].y);
		if (a[i].y<f[fi+1])	f[fi+1]=a[i].y;
		if (fi==an) an++;
	}
	printf("%d ",an);
	an=0;
	for(i=1;i<=n;i++)
	f[i]=1e9,f[i]=f[i]*f[i];
	for(i=1;i<=n;i++)
	//if(a[i].x>=0&&a[i].y>=0)
	{
		fi=erfen(0,an,a[i].y);
		if (a[i].y<f[fi+1])	f[fi+1]=a[i].y;
		if (fi==an) an++;
	}
	printf("%d\n",an);
}


#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct st{
long long x,y;
bool operator<(const st&s)const{return (x<s.x||(x==s.x&&y<s.y));}
}a[100001];
int i,n,fi,an;
long long x[100001],y[100001],f[100001],v;
int erfen(int l,int r,int xx)
{
	if (l==r) return l;
	int mi=(l+r+1)/2;
	if (f[mi]<=xx)  return (erfen(mi,r,xx));
	else return(erfen(l,mi-1,xx));
}
int main()
{
//	freopen("1.in","r",stdin);
//	freopen("1.out","w",stdout);
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	scanf("%I64d%I64d",&x[i],&y[i]);
	scanf("%I64d",&v);
	for(i=1;i<=n;i++)
	a[i].x=-x[i]+y[i]*v,a[i].y=x[i]+y[i]*v;
	sort(a+1,a+n+1);
	for(i=1;i<=n;i++)
	f[i]=1e9;
	for(i=1;i<=n;i++)
	if(a[i].x>=0&&a[i].y>=0)
	{
		fi=erfen(0,an,a[i].y);
		if (a[i].y<f[fi+1])	f[fi+1]=a[i].y;
		if (fi==an) an++;
	}
	printf("%d ",an);
	an=0;
	for(i=1;i<=n;i++)
	f[i]=1e9;
	for(i=1;i<=n;i++)
	//if(a[i].x>=0&&a[i].y>=0)
	{
		fi=erfen(0,an,a[i].y);
		if (a[i].y<f[fi+1])	f[fi+1]=a[i].y;
		if (fi==an) an++;
	}
	printf("%d\n",an);
}


#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct st{
long long x,y;
bool operator<(const st&s)const{return (x<s.x||(x==s.x&&y<s.y));}
}a[100001];
int i,n,fi,an,f[100001];
long long x[100001],y[100001],v;

int main()
{
//	freopen("1.in","r",stdin);
//	freopen("1.out","w",stdout);
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	scanf("%I64d%I64d",&x[i],&y[i]);
	scanf("%I64d",&v);
	for(i=1;i<=n;i++)
	a[i].x=-x[i]+y[i]*v,a[i].y=x[i]+y[i]*v;
	sort(a+1,a+n+1);
	for(i=1;i<=n;i++)
	f[i]=1e9;
	for(i=1;i<=n;i++)
	if(a[i].x>=0&&a[i].y>=0)
	{
		fi=lower_bound(f,f+an,a[i].y)-f;
		if (a[i].y<f[fi+1])	f[fi+1]=a[i].y;
		if (fi==an) an++;
	}
	printf("%d ",an);
	an=0;
	for(i=1;i<=n;i++)
	f[i]=1e9;
	for(i=1;i<=n;i++)
	//if(a[i].x>=0&&a[i].y>=0)
	{
		fi=lower_bound(f,f+an,a[i].y)-f;
		if (a[i].y<f[fi+1])	f[fi+1]=a[i].y;
		if (fi==an) an++;
	}
	printf("%d\n",an);
}


#include <iostream>
#include <algorithm>
using namespace std;
const long long maxn=1000*100+100;

struct point{
    long long id,l;
    bool operator <(const point &B)const{
        return l<B.l;
    }
};
point p[maxn];
long long q[maxn],b[maxn],c[maxn];
pair <long long,long long> a[maxn];
long long LIS(long long b[],long long tmp,long long c[]){
    long long size=1;
    c[0]=b[0];
    for(long long i=1;i<tmp;i++){
        long long x=upper_bound(c,c+size,b[i])-c;
        c[x]=b[i];
        if(x==size)
            size++;
    }
    return size;
}
int main(){
    long long n,v;
    cin>>n;
    for(long long i=0;i<n;i++){
        cin>>a[i].first>>a[i].second;
    }
    cin>>v;
    for(long long i=0;i<n;i++){
        p[i].id=i,p[i].l=a[i].first+(v*a[i].second);
        q[i]=-(a[i].first) + (v*a[i].second);
    }
    sort(p,p+n);
    long long tmp=0;
    for(long long i=0;i<n;i++){
        if(p[i].l>=0 && q[p[i].id]>=0)
            b[tmp++]=q[p[i].id];
    }
    cout<<LIS(b,tmp,c)<<" ";
    for(long long i=0;i<n;i++){
        b[i]=q[p[i].id];
    }
    cout<<LIS(b,n,c)<<endl;
    return 0;
}


#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=1000*100+100;

struct point{
    int id,l;
    bool operator <(const point &B)const{
        return l<B.l;
    }
};

point p[maxn];
int q[maxn],b[maxn],c[maxn];
pair <int,int> a[maxn];
void intialize(){
    for(int i=0;i<maxn;i++)
        c[i]=-1000000000;

}
int LIS(int b[],int n,int c[]){
    intialize();
    int size=0;
    for(int i=0;i<n;i++){
        int x=upper_bound(c,c+size,b[i])-c;
        c[x]=b[i];
        if(x>=size)
            size++;
    }
    return size;
}
int main(){
    int n,v;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>a[i].first>>a[i].second;
    }
    cin>>v;
    for(int i=0;i<n;i++){
        p[i].id=i,p[i].l=a[i].first+(v*a[i].second);
        q[i]=-a[i].first + (v*a[i].second);
    }
    sort(p,p+n);
    int tmp=0;
    for(int i=0;i<n;i++){
        if(p[i].l>=0 && q[p[i].id]>=0)
            b[tmp++]=q[p[i].id];
    }
    cout<<LIS(b,tmp,c)<<" ";
    for(int i=0;i<n;i++){
        b[i]=q[p[i].id];
    }
    cout<<LIS(b,n,c)<<endl;
    return 0;
}


#include <iostream>
#include <algorithm>
using namespace std;
const long long maxn=1000*100+100;

struct point{
    long long id,l;
    bool operator <(const point &B)const{
        return l<B.l;
    }
};
point p[maxn];
long long q[maxn],b[maxn],c[maxn];
pair <long long,long long> a[maxn];
void intialize(){
    for(long long i=0;i<maxn;i++)
        c[i]=10000000000;

}
long long LIS(long long b[],long long tmp,long long c[]){
    intialize();
    long long size=1;
    c[0]=b[0];
    for(long long i=1;i<tmp;i++){
        long long x=upper_bound(c,c+size,b[i])-c;
        c[x]=b[i];
        if(x==size)
            size++;
    }
    return size;
}
int main(){
    long long n,v;
    cin>>n;
    for(long long i=0;i<n;i++){
        cin>>a[i].first>>a[i].second;
    }
    cin>>v;
    for(long long i=0;i<n;i++){
        p[i].id=i,p[i].l=a[i].first+(v*a[i].second);
        q[i]=-(a[i].first) + (v*a[i].second);
    }
    sort(p,p+n);
    long long tmp=0;
    for(long long i=0;i<n;i++){
        if(p[i].l>=0 && q[p[i].id]>=0)
            b[tmp++]=q[p[i].id];
    }
    cout<<LIS(b,tmp,c)<<" ";
    for(long long i=0;i<n;i++){
        b[i]=q[p[i].id];
    }
    cout<<LIS(b,n,c)<<endl;
    return 0;
}


#include <iostream>
#include <algorithm>
using namespace std;
const long long maxn=1000*100+100;

struct point{
    long long id,l;
    bool operator <(const point &B)const{
        return l<B.l;
    }
};
point p[maxn];
long long q[maxn],b[maxn],c[maxn];
pair <long long,long long> a[maxn];
void intialize(){
    for(long long i=0;i<maxn;i++)
        c[i]=10000000000;

}
long long LIS(long long b[],long long tmp,long long c[]){
    intialize();
    long long size=0;
    for(long long i=0;i<tmp;i++){
        long long x=upper_bound(c,c+maxn,b[i])-c;
        c[x]=b[i];
        size=max(x,size);
    }
    return size+1;
}
int main(){
    long long n,v;
    cin>>n;
    for(long long i=0;i<n;i++){
        cin>>a[i].first>>a[i].second;
    }
    cin>>v;
    for(long long i=0;i<n;i++){
        p[i].id=i,p[i].l=a[i].first+(v*a[i].second);
        q[i]=-a[i].first + (v*a[i].second);
    }
    sort(p,p+n);
    long long tmp=0;
    for(long long i=0;i<n;i++){
        if(p[i].l>=0 && q[p[i].id]>=0)
            b[tmp++]=q[p[i].id];
    }
    cout<<LIS(b,tmp,c)<<" ";
    for(long long i=0;i<n;i++){
        b[i]=q[p[i].id];
    }
    cout<<LIS(b,n,c)<<endl;
    return 0;
}


#include <iostream>
#include <algorithm>
using namespace std;
const long long maxn=1000*100+100;

long long q[maxn],b[maxn],c[maxn];
struct point{
    long long id,l;
    bool operator <(const point &B)const{
        if(l==B.l){
            return q[id]<q[B.id];
        }
        else
            return l<B.l;
    }
};
point p[maxn];
pair <long long,long long> a[maxn];
long long LIS(long long b[],long long tmp,long long c[]){
    long long size=1;
    c[0]=b[0];
    for(long long i=1;i<tmp;i++){
        long long x=upper_bound(c,c+size,b[i])-c;
        c[x]=b[i];
        if(x==size)
            size++;
    }
    return size;
}
int main(){
    long long n,v;
    cin>>n;
    for(long long i=0;i<n;i++){
        cin>>a[i].first>>a[i].second;
    }
    cin>>v;
    for(long long i=0;i<n;i++){
        p[i].id=i,p[i].l=-(a[i].first)+(v*a[i].second);
        q[i]=(a[i].first) + (v*a[i].second);
    }
    sort(p,p+n);
    long long tmp=0;
    for(long long i=0;i<n;i++){
        if(p[i].l>=0 && q[p[i].id]>=0)
            b[tmp++]=q[p[i].id];
    }
    cout<<LIS(b,tmp,c)<<" ";
    for(long long i=0;i<n;i++){
        b[i]=q[p[i].id];
    }
    cout<<LIS(b,n,c)<<endl;
    return 0;
}


#include<cstdio>
#include<algorithm>

using namespace std;

#define long long long

const int MAX_N = 100005;

struct Event{
  long x, y;
  bool operator < (const Event &o) const{
    return x != o.x? x > o.x: y < o.y;
  }
};

int n, v;
Event a[MAX_N];
long b[MAX_N];
int nb;

int main(){
  scanf("%d", &n);
  for(int i = 0; i < n; i++){
    scanf("%I64d %I64d", &a[i].x, &a[i].y);
  }
  scanf("%d", &v);
  n++;
  for(int i = 0; i < n; i++){
    Event t = a[i];
    a[i].x = t.x + v * t.y;
    a[i].y = t.x - v * t.y;
  }
  sort(a, a + n);
  for(int i = 0; i < n; i++){
    int it = upper_bound(b, b + nb, a[i].y) - b;
    if(a[i].x == 0 and a[i].y == 0){
      printf("%d ", it);
    }
    else{
      b[it] = a[i].y;
      if(it == nb){
	nb++;
      }
    }
  }
  printf("%d\n", nb);
}


#include<cstdio>
#include<algorithm>
using namespace std;

const int MAX_N = 1e5 + 5;

#define long long long

struct Event{
  long x, y;
  bool operator < (const Event &o) const{
    return x != o.x? x < o.x: y < o.y;
  }
};

int n;
long v;
Event a[MAX_N];
int b[MAX_N], k;

int main(){

  scanf("%d", &n);
  for(int i = 0; i < n; i++){
    scanf("%I64d %I64d", &a[i].x, &a[i].y);
  }
  scanf("%I64d", &v);

  a[n].x = 0;
  a[n].y = 0;
  n++;
  for(int i = 0; i < n; i++){
    long x = a[i].x, t = a[i].y;
    a[i].x = x - v * t;
    a[i].y = -x - v * t;
  }
  sort(a, a + n);

  for(int i = 0; i < n; i++){
    int x = upper_bound(b + 1, b + k + 1, a[i].y) - b;
    if(a[i].x == 0 and a[i].y == 0){
      printf("%d ", x - 1);
    }
    else{
      b[x] = a[i].y;
      k = max(k, x);
    }
  }

  printf("%d\n", k);
}


#include<cstdio>
#include<algorithm>
using namespace std;

const int MAX_N = 1e5 + 5;

#define long long long

struct Event{
  long x, y;
  bool operator < (const Event &o) const{
    return x != o.x? x < o.x: y < o.y;
  }
};

int n;
long v;
Event a[MAX_N];
int b[MAX_N], k;

int main(){

  scanf("%d", &n);
  for(int i = 0; i < n; i++){
    scanf("%I64d %I64d", &a[i].x, &a[i].y);
  }
  scanf("%I64d", &v);

  a[n].x = 0;
  a[n].y = 0;
  n++;
  for(int i = 0; i < n; i++){
    long x = a[i].x, t = a[i].y;
    a[i].x = x - v * t;
    a[i].y = -x - v * t;
  }
  sort(a, a + n);

  for(int i = 0; i < n; i++){
    int x = upper_bound(b + 1, b + k + 1, a[i].y) - b;
    b[x] = a[i].y;
    if(a[i].x == 0 and a[i].y == 0){
      printf("%d ", x - 1);
    }
    k = max(k, x);
  }

  printf("%d\n", k);
}


#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

const int MAX_N = 100007;
const long long INF = 1LL<<61;

typedef long long ll;
typedef pair<ll,ll> pii;

ll n, v;
ll x[MAX_N], t[MAX_N];
ll dp[MAX_N], temp[MAX_N];
vector<pii> p, q;

int main() {
	scanf("%I64d", &n);
	for (int i = 0; i < n; ++i) {
		scanf("%I64d%I64d", &x[i], &t[i]);
	}
	scanf("%I64d", &v);
	for (int i = 0; i < n; ++i) {
		if (abs(x[i]) <= t[i] * v) {
			p.push_back(make_pair(t[i] * v - x[i], t[i] * v + x[i]));
		}
	}
	sort(p.begin(), p.end());
	for (int i = 0; i < (int) p.size(); ++i) {
		temp[i] = p[i].second;
	}
	fill(dp, dp + MAX_N, INF);
	for (int i = 0; i < (int) p.size(); ++i) {
		*lower_bound(dp, dp + n, temp[i]) = temp[i];
	}
	int zero = lower_bound(dp, dp + n, INF) - dp;
	++zero;
	for (int i = 0; i < n; ++i) {
		q.push_back(make_pair(t[i] * v - x[i], t[i] * v + x[i]));
	}
	sort(q.begin(), q.end());
	memset(temp, 0, sizeof temp);
	for (int i = 0; i < (int) q.size(); ++i) {
		temp[i] = q[i].second;
	}
	fill(dp, dp + MAX_N, INF);
	for (int i = 0; i < (int) q.size(); ++i) {
		*lower_bound(dp, dp + n, temp[i]) = temp[i];
	}
	int all = lower_bound(dp, dp + n, INF) - dp;
	++all;
	printf("%d %d\n", zero, all);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

const int MAX_N = 100007;
const long long INF = 1LL<<61;

typedef long long ll;
typedef pair<ll,ll> pii;

int n, v;
int x[MAX_N], t[MAX_N];
ll dp[MAX_N], temp[MAX_N];
vector<pii> p, q;

int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) {
        scanf("%d%d", &x[i], &t[i]);
    }
    scanf("%d", &v);
    for (int i = 0; i < n; ++i) {
        if (abs((ll)x[i]) <= (ll)t[i] * v) {
            p.push_back(make_pair((ll)t[i] * v - x[i], (ll)t[i] * v + x[i]));
        }
    }
    sort(p.begin(), p.end());
    for (int i = 0; i < (int) p.size(); ++i) {
        temp[i] = p[i].second;
    }
    fill(dp, dp + MAX_N, INF);
    for (int i = 0; i < (int) p.size(); ++i) {
        int l = -1, r = p.size() - 1;
        while (l + 1 < r) {
            int mid = (l + r) >> 1;
            if (dp[mid] <= temp[i]) l = mid;
            else r = mid;
        }
        dp[r] = temp[i];
    }
    int zero = lower_bound(dp, dp + MAX_N, INF) - dp;
    for (int i = 0; i < n; ++i) {
        q.push_back(make_pair((ll)t[i] * v - x[i], (ll)t[i] * v + x[i]));
    }
    sort(q.begin(), q.end());
    memset(temp, 0, sizeof temp);
    for (int i = 0; i < (int) q.size(); ++i) {
        temp[i] = q[i].second;
    }
    fill(dp, dp + MAX_N, INF);
    for (int i = 0; i < (int) q.size(); ++i) {
        int l = -1, r = q.size() - 1;
        while (l + 1 < r) {
            int mid = (l + r) >> 1;
            if (dp[mid] <= temp[i]) l = mid;
            else r = mid;
        }
        dp[r] = temp[i];
    }
    int all = lower_bound(dp, dp + MAX_N, INF) - dp;
//  --all, --zero;
    printf("%d %d\n", zero, all);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

const int MAX_N = 100007;
const long long INF = 1LL<<61;

typedef long long ll;
typedef pair<ll,ll> pii;

ll n, v;
ll x[MAX_N], t[MAX_N];
ll dp[MAX_N], temp[MAX_N];
vector<pii> p, q;

int main() {
	scanf("%I64d", &n);
	for (int i = 0; i < n; ++i) {
		scanf("%I64d%I64d", &x[i], &t[i]);
	}
	scanf("%I64d", &v);
	for (int i = 0; i < n; ++i) {
		if (abs(x[i]) <= t[i] * v) {
			p.push_back(make_pair(t[i] * v - x[i], t[i] * v + x[i]));
		}
	}
	sort(p.begin(), p.end());
	for (int i = 0; i < (int) p.size(); ++i) {
		temp[i] = p[i].second;
	}
	fill(dp, dp + MAX_N, INF);
	for (int i = 0; i < (int)p.size(); ++i) {
		*lower_bound(dp, dp + n, temp[i]) = temp[i];
	}
	int zero = lower_bound(dp, dp + n, INF) - dp;
	++zero;
	for (int i = 0; i < n; ++i) {
		q.push_back(make_pair(t[i] * v - x[i], t[i] * v + x[i]));
	}
	sort(q.begin(), q.end());
	for (int i = 0; i < (int) q.size(); ++i) {
		temp[i] = q[i].second;
	}
	fill(dp, dp + MAX_N, INF);
	for (int i = 0; i < (int) q.size(); ++i) {
		*lower_bound(dp, dp + n, temp[i]) = temp[i];
	}
	int all = lower_bound(dp, dp + n, INF) - dp;
	++all;
	printf("%d %d\n", zero, all);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

const int MAX_N = 100007;
const long long INF = 1LL<<61;

typedef long long ll;
typedef pair<ll,ll> pii;

ll n, v;
ll x[MAX_N], t[MAX_N];
ll dp[MAX_N], temp[MAX_N];
vector<pii> p, q;

int main() {
    scanf("%I64d", &n);
    for (int i = 0; i < n; ++i) {
        scanf("%I64d%I64d", &x[i], &t[i]);
    }
    scanf("%I64d", &v);
    for (int i = 0; i < n; ++i) {
        if (abs(x[i]) <= t[i] * v) {
            p.push_back(make_pair(t[i] * v - x[i], t[i] * v + x[i]));
        }
    }
    sort(p.begin(), p.end());
    for (int i = 0; i < (int) p.size(); ++i) {
        temp[i] = p[i].second;
    }
    fill(dp, dp + MAX_N, INF);
    for (int i = 0; i < (int) p.size(); ++i) {
        *lower_bound(dp, dp + n, temp[i]) = temp[i];
    }
    ll zero = lower_bound(dp, dp + n, INF) - dp;

    for (int i = 0; i < n; ++i) {
        q.push_back(make_pair(t[i] * v - x[i], t[i] * v + x[i]));
    }
    sort(q.begin(), q.end());
    memset(temp, 0, sizeof temp);
    for (int i = 0; i < (int) q.size(); ++i) {
        temp[i] = q[i].second;
    }
    fill(dp, dp + MAX_N, INF);
    for (int i = 0; i < (int) q.size(); ++i) {
        *lower_bound(dp, dp + n, temp[i]) = temp[i];
    }
    ll all = lower_bound(dp, dp + n, INF) - dp;
    printf("%I64d %I64d\n", zero, all);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

const int MAX_N = 100007;
const long long INF = 1LL<<61;

typedef long long ll;
typedef pair<ll,ll> pii;

ll n, v;
ll x[MAX_N], t[MAX_N];
ll dp[MAX_N], temp[MAX_N];
vector<pii> p, q;

int main() {
    scanf("%I64d", &n);
    for (int i = 0; i < n; ++i) {
        scanf("%I64d%I64d", &x[i], &t[i]);
    }
    scanf("%I64d", &v);
    for (int i = 0; i < n; ++i) {
        if (abs(x[i]) <= t[i] * v) {
            p.push_back(make_pair(t[i] * v - x[i], t[i] * v + x[i]));
        }
    }
    sort(p.begin(), p.end());
    for (int i = 0; i < (int) p.size(); ++i) {
        temp[i] = p[i].second;
    }
    fill(dp, dp + MAX_N, INF);
    for (int i = 0; i < (int) p.size(); ++i) {
        *lower_bound(dp, dp + n, temp[i]) = temp[i];
    }
    int zero = lower_bound(dp, dp + n, INF) - dp;
    for (int i = 0; i < n; ++i) {
        q.push_back(make_pair(t[i] * v - x[i], t[i] * v + x[i]));
    }
    sort(q.begin(), q.end());
    memset(temp, 0, sizeof temp);
    for (int i = 0; i < (int) q.size(); ++i) {
        temp[i] = q[i].second;
    }
    fill(dp, dp + MAX_N, INF);
    for (int i = 0; i < (int) q.size(); ++i) {
        *lower_bound(dp, dp + n, temp[i]) = temp[i];
    }
    int all = lower_bound(dp, dp + n, INF) - dp;
    ++all;
    printf("%d %d\n", zero, all);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;

int N,cnt,V,L,t,A2;
struct stuff{int x,t,p,q,id;}S[100005],LIS[100005];

bool cmp1(stuff a,stuff b){
    return a.t < b.t;
}

bool cmp2(stuff a,stuff b){
    if(a.p != b.p) return a.p < b.p;
    if(a.q != b.q) return a.q < b.q;
    return a.id < b.id;
}

bool cmp3(stuff a,stuff b){
    return a.q < b.q;
}

int main(){
    scanf("%d",&N);
    for(int i=0;i<N;++i) scanf("%d%d",&S[i].x,&S[i].t);
    scanf("%d",&V);
    sort(S,S+N,cmp1);
    for(int i=0;i<N;++i){
        if(i == 0) S[i].id = ++cnt;
        else S[i].id = (S[i].t == S[i-1].t)?cnt:++cnt;
        S[i].p = S[i].t * V - S[i].x;
        S[i].q = S[i].t * V + S[i].x;
    }
    sort(S,S+N,cmp2);
    for(int i=0;i<N;++i){
        t = upper_bound(LIS,LIS+L,S[i],cmp3) - LIS;
        LIS[t] = S[i];
        L = max(t+1,L);
    }
    ++N;
    sort(S,S+N,cmp2);
    for(int i=0;i<N;++i)
        if(S[i].x == 0 && S[i].t == 0){
            cnt = i;
            break;
        }
    A2 = L;
    L = 0;
    for(int i=cnt;i<N;++i){
        t = upper_bound(LIS,LIS+L,S[i],cmp3) - LIS;
        if(t == 0 && i != cnt) continue;
        LIS[t] = S[i];
        L = max(t+1,L);
    }
    printf("%d %d\n",L-1,A2);
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;

int N,cnt,V,L,t,A2;
struct stuff{int x,t,p,q,id;}S[100005],LIS[100005];

bool cmp1(stuff a,stuff b){
	return a.t < b.t;
}

bool cmp2(stuff a,stuff b){
	if(a.p != b.p) return a.p < b.p;
	if(a.q != b.q) return a.q < b.q;
	return a.id < b.id;
}

bool cmp3(stuff a,stuff b){
	return a.id < b.id;
}

int main(){
	scanf("%d",&N);
	for(int i=0;i<N;++i) scanf("%d%d",&S[i].x,&S[i].t);
	scanf("%d",&V);
	sort(S,S+N,cmp1);
	for(int i=0;i<N;++i){
		if(i == 0) S[i].id = ++cnt;
		else S[i].id = (S[i].t == S[i-1].t)?cnt:++cnt;
		S[i].p = -S[i].x + S[i].t * V;
		S[i].q = S[i].x + S[i].t * V;
	}
	sort(S,S+N,cmp2);
	//for(int i=0;i<N;++i) printf("%d (%d %d)\n",S[i].id,S[i].x,S[i].t);
	for(int i=0;i<N;++i){
		t = upper_bound(LIS,LIS+L,S[i],cmp3) - LIS;
		LIS[t] = S[i];
		L = max(t+1,L);
	}
	++N;
	sort(S,S+N,cmp2);
	for(int i=0;i<N;++i)
		if(S[i].x == 0 && S[i].t == 0){
			cnt = i;
			break;
		}
	A2 = L;
	L = 0;
	for(int i=cnt;i<N;++i){
		t = upper_bound(LIS,LIS+L,S[i],cmp3) - LIS;
		if(t == 0 && i != cnt) continue;
		LIS[t] = S[i];
		L = max(t+1,L);
	}
	printf("%d %d\n",L-1,A2);
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;

int N,cnt,V,L,t,A2;
struct stuff{int x,t,p,q,id;}S[100005],LIS[100005];

bool cmp1(stuff a,stuff b){
    return a.t < b.t;
}

bool cmp2(stuff a,stuff b){
    if(a.p != b.p) return a.p < b.p;
    if(a.q != b.q) return a.q < b.q;
    return a.id < b.id;
}

bool cmp3(stuff a,stuff b){
    return a.q < b.q;
}

int main(){
    scanf("%d",&N);
    for(int i=0;i<N;++i) scanf("%d%d",&S[i].x,&S[i].t);
    scanf("%d",&V);
    sort(S,S+N,cmp1);
    for(int i=0;i<N;++i){
        if(i == 0) S[i].id = ++cnt;
        else S[i].id = (S[i].t == S[i-1].t)?cnt:++cnt;
        S[i].p = S[i].t * V + S[i].x;
        S[i].q = S[i].t * V - S[i].x;
    }
    sort(S,S+N,cmp2);
    for(int i=0;i<N;++i){
        t = upper_bound(LIS,LIS+L,S[i],cmp3) - LIS;
        LIS[t] = S[i];
        L = max(t+1,L);
    }
    ++N;
    sort(S,S+N,cmp2);
    for(int i=0;i<N;++i)
        if(S[i].x == 0 && S[i].t == 0){
            cnt = i;
            break;
        }
    A2 = L;
    L = 0;
    for(int i=cnt;i<N;++i){
        t = upper_bound(LIS,LIS+L,S[i],cmp3) - LIS;
        if(t == 0 && i != cnt) continue;
        LIS[t] = S[i];
        L = max(t+1,L);
    }
    printf("%d %d\n",L-1,A2);
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;

int N,cnt,V,L,t,A2;
struct stuff{int x,t,p,q,id;}S[100005],LIS[100005];

bool cmp1(stuff a,stuff b){
	return a.t < b.t;
}

bool cmp2(stuff a,stuff b){
	if(a.p != b.p) return a.p < b.p;
	if(a.q != b.q) return a.q < b.q;
	return a.id < b.id;
}

bool cmp3(stuff a,stuff b){
	return a.q < b.q;
}

int main(){
	scanf("%d",&N);
	for(int i=0;i<N;++i) scanf("%d%d",&S[i].x,&S[i].t);
	scanf("%d",&V);
	sort(S,S+N,cmp1);
	for(int i=0;i<N;++i){
		if(i == 0) S[i].id = ++cnt;
		else S[i].id = (S[i].t == S[i-1].t)?cnt:++cnt;
		S[i].p = S[i].t * V + S[i].x;
		S[i].q = S[i].t * V - S[i].x;
	}
	sort(S,S+N,cmp2);
	for(int i=0;i<N;++i){
		t = upper_bound(LIS,LIS+L,S[i],cmp3) - LIS;
		LIS[t] = S[i];
		L = max(t+1,L);
	}
	++N;
	sort(S,S+N,cmp2);
	for(int i=0;i<N;++i)
		if(S[i].x == 0 && S[i].t == 0){
			cnt = i;
			break;
		}
	A2 = L;
	L = 0;
	for(int i=cnt;i<N;++i){
		t = upper_bound(LIS,LIS+L,S[i],cmp3) - LIS;
		if(t == 0 && i != cnt) continue;
		LIS[t] = S[i];
		L = max(t+1,L);
	}
	printf("%d %d\n",L-1,A2);
}


#include<cstdio>
#include<algorithm>
using namespace std;
#define x first
#define y second
typedef pair<int,int> P;
#define F for(i=0;i<n;i++)
P a[100005],t;
bool cmp(P a,P b){return a.x==b.x?a.y>b.y:a.x<b.x;}
int b[100005],n,i,v,k,r,p;
int main()
{
    scanf("%d",&n);
    F scanf("%d%d",&a[i].x,&a[i].y);
    scanf("%d",&v);
    F{t=a[i];a[i].x=t.x+v*t.y;a[i].y=t.x-v*t.y;}
    a[n++]=make_pair(0,0);
    sort(a,a+n,cmp);
    for(i=n-1;i>=0;i--)
    {
        p=upper_bound(b,b+k,a[i].y)-b;
        if(!a[i].x&&!a[i].y)r=p;
        else {b[p]=a[i].y;if(p==k)k++;}
    }
    printf("%d %d\n",r,k);
}


#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
#define x first
#define y second
typedef pair<int,int> per;
const int N = 100005;
per a[N];
int b[N];
int main()
{
    int n,i,v;
    scanf("%d",&n);
    for(i=0;i<n;i++)scanf("%d%d",&a[i].x,&a[i].y);
    scanf("%d",&v);
    for(i=0;i<n;i++)
    {
        per t=a[i];
        a[i].x=t.first+v*t.y;
        a[i].y=t.first-v*t.y;
    }
    a[n++]=make_pair(0,0);
    sort(a,a+n);
    int k=0,r=0;
    for(i=n-1;i>=0;i--)
    {
        int p=upper_bound(b,b+k,a[i].y)-b;
        b[p]=a[i].y;
        if(p==k)k++;
        if(!a[i].x&&!a[i].y)printf("%d ",k-1);
    }
    printf("%d\n",k);
    return 0;
}