func_code_string: #include <bits/stdc++.h>   using namespace std;   const long long is_query = -(1LL << 62);   struct line {     long long m, b;     mutable function<const line*()> succ;     bool operator<(const line& rhs) const {       if (rhs.b != is_query) return m < rhs.m;       const line* s = succ();       if (!s) return 0;       long long x = rhs.m;       return b - s->b < (s->m - m) * x;     }   };   struct dynamic_hull : public multiset<line> {     const long long inf = LLONG_MAX;     bool bad(iterator y) {       auto z = next(y);       if (y == begin()) {         if (z == end()) return 0;         return y->m == z->m && y->b <= z->b;       }       auto x = prev(y);       if (z == end()) return y->m == x->m && y->b <= x->b;       long long v1 = (x->b - y->b);       if (y->m == x->m)         v1 = x->b > y->b ? inf : -inf;       else         v1 /= (y->m - x->m);       long long v2 = (y->b - z->b);       if (z->m == y->m)         v2 = y->b > z->b ? inf : -inf;       else         v2 /= (z->m - y->m);       return v1 >= v2;     }     void insert_line(long long m, long long b) {       auto y = insert({m, b});       y->succ = [=] { return next(y) == end() ? 0 : &*next(y); };       if (bad(y)) {         erase(y);         return;       }       while (next(y) != end() && bad(next(y))) erase(next(y));       while (y != begin() && bad(prev(y))) erase(prev(y));     }     __int128 eval(long long x) {       auto l = *lower_bound(line{x, is_query});       return (__int128)l.m * x + l.b;     }   };   int main() {     int n;     long long s;     cin >> n >> s;     vector<pair<long long, long long>> buildings(n);     for (int i = 0; i < n; ++i) {       cin >> buildings[i].second >> buildings[i].first;     }     sort(buildings.begin(), buildings.end());     assert(buildings[0].first == 0);     vector<long long> min_time(n + 1, s + 1);     vector<long long> max_cookies(n + 1, 0);     min_time[0] = 0;     max_cookies[0] = 0;     dynamic_hull dp_opt;     dp_opt.insert_line(buildings[0].second, 0);     for (int i = 1; i < n; ++i) {       long long left = min_time[i - 1];       long long right = s + 50;       while (left + 1 < right) {         long long mid = (left + right) / 2;         if (dp_opt.eval(mid) >= buildings[i].first) {           right = mid;         } else {           left = mid;         }       }       if (dp_opt.eval(left) - buildings[i].first < 0) {         ++left;       }       min_time[i] = left;       max_cookies[i] = dp_opt.eval(left) - buildings[i].first;       dp_opt.insert_line(           buildings[i].second,           max_cookies[i] - 1LL * buildings[i].second * min_time[i]);     }     long long ans = s;     for (int i = 0; i < n; ++i) {       ans = min(ans,                 min_time[i] + (s - max_cookies[i] - 1) / buildings[i].second + 1);     }     cout << ans << endl;     return 0;   }   