#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <bits/stdc++.h>
/*#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline") //Optimization flags
#pragma GCC option("arch=native","tune=native","no-zero-upper") //Enable AVX
#pragma GCC target("avx2")  //Enable AVX*/

using namespace std;

using ll = long long;

#define mp make_pair

const int p = 1e9 + 7;


int mul(int a, int b) {
    return (1LL * a * b) % p;
}

int add(int a, int b) {
    int s = (a+b);
    if (s>=p) s-=p;
    return s;
}

int sub(int a, int b) {
    int s = (a+p-b);
    if (s>=p) s-=p;
    return s;
}

int po(int a, int deg)
{
    if (deg==0) return 1;
    if (deg%2==1) return mul(a, po(a, deg-1));
    int t = po(a, deg/2);
    return mul(t, t);
}

int inv(int n)
{
    return po(n, p-2);
}

/*struct DSU {
    vector<int> sz;
    vector<int> parent;

    void make_set(int v) {
        parent[v] = v;
        sz[v] = 1;
    }

    int find_set(int v) {
        if (v == parent[v])
            return v;
        return parent[v] = find_set(parent[v]);
    }

    void union_sets(int a, int b) {
        a = find_set(a);
        b = find_set(b);
        if (a != b) {
            if (sz[a] < sz[b])
                swap(a, b);
            parent[b] = a;
            sz[a] += sz[b];
        }
    }

    DSU(int n) {
        sz.resize(n);
        parent.resize(n);
        for (int i = 0; i < n; i++) make_set(i);
    }
};*/



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

    int n, t;
    cin>>n>>t;

    vector<pair<pair<ll, ll>, int>> base;
    vector<int> free;

    ll u, v;
    for (int i = 0; i<n; i++)
    {
        cin>>u>>v;
        v = u + v + 1;
        if (u==0) free.push_back(v);
        else base.push_back(mp(mp(u, v), base.size()));
    }

    int N = base.size();

    sort(base.begin(), base.end(), [](auto x, auto y)
    {
        if (x.first.first*y.first.second == x.first.second * y.first.first) return (x.second>y.second);
        else return   x.first.first*y.first.second >= x.first.second * y.first.first;
    });

    sort(free.begin(), free.end());


    vector<pair<ll, ll>> prs(N);
    for (int i = 0; i<N; i++) prs[i] = base[i].first;

    //for (auto it: prs) cout<<it.first<<' '<<it.second<<endl;

    for (int i = 0; i<N; i++) prs[i].first++;

    vector<vector<ll>> dp(N+1, vector<ll>(31, -1));

    dp[0][0] = 0;
    for (int i = 1; i<=N; i++)
    {
        dp[i][0] = 0;
        for (int cnt = 1; cnt<=30; cnt++)
        {
            dp[i][cnt] = dp[i-1][cnt];
            if (dp[i-1][cnt-1]!=-1)
            {
                ll time = dp[i-1][cnt-1]*prs[i-1].first + prs[i-1].second;
                if (time<=t)
                {
                    if (dp[i][cnt]==-1) dp[i][cnt] = time;
                    else dp[i][cnt] = min(dp[i][cnt], time);
                }
            }
        }
    }

    int best = 0;
    for (int i = 0; i<=30; i++) if (dp[N][i]!=-1)
    {
        int timeleft = t - dp[N][i];
        int cur = 0;
        while (cur<free.size() && timeleft>=free[cur])
        {
            timeleft-=free[cur];
            cur++;
        }
        best = max(best, i+cur);
    }
    cout<<best;

}


Measured memory_bytes: 63468