Language: C++

#include <vector>
#include <iostream>
#include <utility>
#include <algorithm>
#include <string>
#include <deque>
#include <queue>
#include <tuple>
#include <queue>
#include <stack>
#include <functional>
#include <cmath>
#include <iomanip>
#include <map>
#include <set>
#include <numeric>
#include <unordered_map>
#include <unordered_set>
#include <complex>
#include <iterator>
#include <array>
#include <memory>
#include <random>
//cin.sync_with_stdio(false);
//streambuf
using namespace std;
typedef long long ll;
typedef double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
using vi = vector<int>;
using vll = vector<ll>;
using vpii = vector<pii>;
using vpll = vector<pll>;
using ti3 = tuple<int, int, int>;
using vti3 = vector<ti3>;
template<class T, int s>using va = vector<array<T, s>>;
template<class T, class T2> using umap = unordered_map<T, T2>;
template<class T> using uset = unordered_set<T>;
template<class T, class S> void cmin(T &a, const S &b) { if (a > b)a = b; }
template<class T, class S> void cmax(T &a, const S &b) { if (a < b)a = b; }
#define ALL(a) a.begin(),a.end()
#define rep(i,a) for(int i=0;i<a;i++)
#define rep1(i,a) for(int i=1;i<=a;i++)
#define rrep(i,a) for(int i=(a)-1;i>=0;i--)
#define rrep1(i,a) for(int i=a;i;i--)
#define repi(i,a,b) for(int i=a;i<b;i++);
const ll mod = 1000000007;
template<class T>using heap = priority_queue<T, vector<T>, greater<T>>;
template<class T>using pque = priority_queue<T, vector<T>, function<T(T, T)>>;
template <class T>
inline void hash_combine(size_t & seed, const T & v) {
	hash<T> hasher;
	seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
namespace std {
	template<typename S, typename T> struct hash<pair<S, T>> {
		inline size_t operator()(const pair<S, T> & v) const {
			size_t seed = 0;
			hash_combine(seed, v.first);
			hash_combine(seed, v.second);
			return seed;
		}
	};
	// Recursive template code derived from Matthieu M.
	template <class Tuple, size_t Index = std::tuple_size<Tuple>::value - 1>
	struct HashValueImpl {
		static void apply(size_t& seed, Tuple const& tuple) {
			HashValueImpl<Tuple, Index - 1>::apply(seed, tuple);
			hash_combine(seed, std::get<Index>(tuple));
		}
	};
	template <class Tuple>
	struct HashValueImpl<Tuple, 0> {
		static void apply(size_t& seed, Tuple const& tuple) {
			hash_combine(seed, std::get<0>(tuple));
		}
	};
	template <typename ... TT>
	struct hash<std::tuple<TT...>> {
		size_t operator()(std::tuple<TT...> const& tt) const {
			size_t seed = 0;
			HashValueImpl<std::tuple<TT...> >::apply(seed, tt);
			return seed;
		}
	};
}
template<class T>int id(vector<T> &a, T b) {
	return lower_bound(ALL(a), b) - a.begin();
}
ll pow(ll base, ll i, ll mod) {
	ll a = 1;
	while (i) {
		if (i & 1) {
			a *= base;
			a %= mod;
		}
		base *= base;
		base %= mod;
		i /= 2;
	}
	return a;
}
ll gcd(ll a, ll b) {
	while (b) {
		ll c = a%b;
		a = b;
		b = c;
	}
	return a;
}
ll lcm(ll a, ll b) {
	return a / gcd(a, b)*b;
}
int popcnt(unsigned long long a) {
	a = (a & 0x5555555555555555) + (a >> 1 & 0x5555555555555555);
	a = (a & 0x3333333333333333) + (a >> 2 & 0x3333333333333333);
	a = (a & 0x0f0f0f0f0f0f0f0f) + (a >> 4 & 0x0f0f0f0f0f0f0f0f);
	a = (a & 0x00ff00ff00ff00ff) + (a >> 8 & 0x00ff00ff00ff00ff);
	a = (a & 0x0000ffff0000ffff) + (a >> 16 & 0x0000ffff0000ffff);
	return (a & 0xffffffff) + (a >> 32);
}
class unionfind {
	vector<int> par, rank, size_;//????????§??????????????¢???????????????????????????rank???????????????size?????????
public:
	unionfind(int n) :par(n), rank(n), size_(n, 1) {
		iota(ALL(par), 0);
	}
	int find(int x) {
		if (par[x] == x)return x;
		return par[x] = find(par[x]);
	}
	void unite(int x, int y) {
		x = find(x), y = find(y);
		if (x == y)return;
		if (rank[x] < rank[y])swap(x, y);
		par[y] = x;
		size_[x] += size_[y];
		if (rank[x] == rank[y])rank[x]++;
	}
	bool same(int x, int y) {
		return find(x) == find(y);
	}
	int size(int x) {
		return size_[find(x)];
	}
};
template<class T, class Func = function<T(T, T)>>
class segtree {
	vector<T> obj;
	int offset;
	Func updater;
	T e;
	int bufsize(int num) {
		int i = 1;
		for (; num >i; i <<= 1);
		offset = i - 1;
		return (i << 1) - 1;
	}
	T query(int a, int b, int k, int l, int r) {
		if (r <= a || b <= l)return e;
		if (a <= l && r <= b)return obj[k];
		else return updater(query(a, b, k * 2 + 1, l, (l + r) / 2), query(a, b, k * 2 + 2, (l + r) / 2, r));
	}
public:
	T query(int a, int b) {//[a,b)
		return query(a, b, 0, 0, offset + 1);
	}
	void updateall(int l = 0, int r = -1) {
		if (r < 0)r = offset + 1;
		l += offset, r += offset;
		if (l == 0)return;
		do {
			l = l - 1 >> 1, r = r - 1 >> 1;
			for (int i = l; i < r; i++)obj[i] = updater(obj[i * 2 + 1], obj[i * 2 + 2]);
		} while (l);
	}
	void update(int k, T &a) {
		k += offset;
		obj[k] = a;
		while (k) {
			k = k - 1 >> 1;
			obj[k] = updater(obj[k * 2 + 1], obj[k * 2 + 2]);
		}
	}
	segtree(int n, T e, const Func &updater = Func()) :obj(bufsize(n), e), e(e), updater(updater) {}
	segtree(vector<T> &vec, T e, const Func &updater = Func()) :obj(bufsize(vec.size()), e), e(e), updater(updater) {
		copy(vec.begin(), vec.end(), obj.begin() + offset);
		updateall();
	}
	typename T& operator[](int n) {
		return obj[n + offset];
	}
};
template<class T = int>
class BIT {//????¬????BIT????????????????????????????????°??????????????????
	vector<T> bit;
public:
	BIT(int n) :obj(n + 1, 0) {}
	void add(int i, T x) {
		i++;
		while (i <= n) {
			bit[i] += x;
			i += i&-i;
		}
	}
	T sum(int i) {
		T s = 0;
		i++;
		while (i) {
			s += bit[i];
			i &= i - 1;
		}
		return s;
	}
};
template<class T>
class rangeadd {
	BIT b0, b1;
	rangeadd(int n) :b0(n), b1(n);
	void add(int l, int r, T x) {//[l,r)
		b0.add(l, -x(l - 1));
		b1.add(l, x);
		b0.add(r, x*r);
		b1.add(r, -x);
	}
	T sum(int i) {
		return b0.sum(i) + b1.sum(i)*i;
	}
};
template<class T>
class lazysegtree {
	vector<T> obj;
	int offset;
	T e;
	int bufsize(int num) {
		int i = 1;
		for (; num >i; i <<= 1);
		offset = i - 1;
		return (i << 1) - 1;
	}
	T query(int a, int b, int k, int l, int r) {
		T ret(e);
		if (r <= a || b <= l)return e;
		if (a <= l && r <= b)return obj[k];
		else {
			obj[k].propagate(obj[k * 2 + 1], obj[k * 2 + 2]);
			return ret.update(query(a, b, k * 2 + 1, l, (l + r) / 2), query(a, b, k * 2 + 2, (l + r) / 2, r));
		}
	}
	template<class... Param>
	T update(int a, int b, int k, int l, int r,const Param&... param) {
		if (r <= a || b <= l)return e;
		if (a <= l && r <= b) {
			obj[k].update(param);
			return obj[k];
		}
		obj[k].propagate(obj[k * 2 + 1], obj[k * 2 + 2]);
		obj[k].update(update(a, b, k * 2 + 1, l, (l + r) / 2, param), update(a, b, k * 2 + 2, (l + r) / 2, r, param));
	}
public:
	T query(int a, int b) {//[a,b)
		return query(a, b, 0, 0, offset + 1);
	}
	template<class... Param>
	T update(int a, int b, Param&&... param) {
		update(a, b, 0, 0, offset + 1, param);
	}
	/*
	void updateall(int l = 0, int r = -1) {
		if (r < 0)r = offset + 1;
		l += offset, r += offset;
		do {
			l = l - 1 >> 1, r = r - 1 >> 1;
			for (int i = l; i < r; i++)obj[i] = updater(obj[i * 2 + 1], obj[i * 2 + 2]);
		} while (l)
	}
	void update(int k, T &a) {
		k += offset;
		obj[k] = a;
		while (k) {
			k = k - 1 >> 1;
			obj[k] = updater(obj[k * 2 + 1], obj[k * 2 + 2]);
		}
	}*/
	lazysegtree(int n, T e) :obj(bufsize(n), e), e(e) {}
	/*lazysegtree(vector<T> &vec, T e, const Func &updater = Func()) :obj(bufsize(vec.size()), e), e(e), updater(updater) {
		copy(vec.begin(), vec.end(), obj.begin() + offset);
		updateall();
	}
	typename vector<T>::refrence operator[](int n) {
		return obj[n + offset];
	}*/
};//end of lib
//template<class S=void,int ptr_num, class T = char>class trie {
//	umap<T, trie<S, ptr_num, T> next;
//public:
//	S key;
//	trie<S, ptr_num, T>* ptr[ptr_num] = {};
//	trie(S &&data) :key(data) {}
//	trie(const S &data) :key(data) {}
//	void add(T x,S data) {
//		if (!next.find(x))next.insert(x, data);
//	}
//	trie& operator[](T x) {
//		return next[x];
//	}
//	bool find(T x) {
//		retun next.find(x);
//	}
//};
//template<class T=char>class AhoCorasick {
//	trie<pair<bool,int>, 2, T> tree;
//	AhoCorasick(vector<string> p) {
//		int num = 0;
//		vector<decltype(&tree)> que(p.size(),&tree);
//		for (int i = 0;; i++) {
//			bool end = 1;
//			int i = 0;
//			for (auto a : p) {
//				if (i >= a.size())break;
//				end = ;0
//				que[i] = (*que[i])[a[i]];
//				i++;
//			}
//			if (end)break;
//		}
//	}
//};
int main() {
	int n, l;
	cin >> n >> l;
	vpii a(n);
	vi c(n);
	rep(i, n)cin >> a[i].first >> a[i].second;
	rep(i, n)cin >> c[i];
	rep(i, n)a[i].first -= a[i].second;
	sort(ALL(a), greater<>());
	vi b(n+1);
	int max = 0;
	rep(i, n)b[i] = a[i].first;
	rep1(i, n - 1)b[i] += b[i - 1];
	rep1(i, n - 1)c[i] += c[i - 1];
	segtree<int> st1(n, 1e9, [](auto a, auto b) {return min(a, b); }), st2 = st1;
	rep(i, n)st1[i] = b[i] - c[i];
	rep(i, n - 1)st2[i] = b[i + 1] - c[i];
	st1.updateall();
	st2.updateall();
	rep(i, n)if (a[i].first >= 0)max = i + 1;
	int res = 1e9;
	rep(i, n) {
		if (a[i].first + a[i].second >= l)res = 1;
		else if (i < max&&b[i] + a[i].second < l) {
			int p = lower_bound(b.begin(), b.begin() + max, l - a[i].second) - b.begin();
			if (st1.query(0, i) > 0 && st2.query(i, p) - a[i].first>0 && p != max)cmin(res, p + 1);
		}
		else {
			int p = lower_bound(b.begin(), b.begin() + max, l - a[i].first - a[i].second) - b.begin();
			if (st1.query(0, p) > 0 && b[p] + a[i].first + a[i].second >= l)cmin(res, p + 2);
		}
	}
	if (res == 1e9)cout << -1 << endl;
	else cout << res << endl;
}

Compiler output:
a.cc:192:18: error: expected nested-name-specifier before 'T'
  192 |         typename T& operator[](int n) {
      |                  ^
a.cc:192:18: error: expected ';' at end of member declaration
  192 |         typename T& operator[](int n) {
      |                  ^
      |                   ;
a.cc:192:18: error: declaration of 'int segtree<T, Func>::T' shadows template parameter
a.cc:149:10: note: template parameter 'T' declared here
  149 | template<class T, class Func = function<T(T, T)>>
      |          ^~~~~
a.cc:192:21: error: ISO C++ forbids declaration of 'operator[]' with no type [-fpermissive]
  192 |         typename T& operator[](int n) {
      |                     ^~~~~~~~
a.cc: In constructor 'BIT<T>::BIT(int)':
a.cc:200:21: error: class 'BIT<T>' does not have any field named 'obj'
  200 |         BIT(int n) :obj(n + 1, 0) {}
      |                     ^~~
a.cc: In member function 'void BIT<T>::add(int, T)':
a.cc:203:29: error: 'n' was not declared in this scope
  203 |                 while (i <= n) {
      |                             ^
a.cc: At global scope:
a.cc:220:9: error: invalid use of template-name 'BIT' without an argument list
  220 |         BIT b0, b1;
      |         ^~~
a.cc:220:9: error: invalid use of template-name 'BIT' without an argument list
a.cc: In constructor 'rangeadd<T>::rangeadd(int)':
a.cc:221:38: error: expected '{' at end of input
  221 |         rangeadd(int n) :b0(n), b1(n);
      |                                      ^
a.cc: In member function 'T lazysegtree<T>::update(int, int, int, int, int, const Param& ...)':
a.cc:256:38: error: parameter packs not expanded with '...':
  256 |                         obj[k].update(param);
      |                         ~~~~~~~~~~~~~^~~~~~~
a.cc:256:38: note:         'param'
a.cc:260:30: error: parameter packs not expanded with '...':
  260 |                 obj[k].update(update(a, b, k * 2 + 1, l, (l + r) / 2, param), update(a, b, k * 2 + 2, (l + r) / 2, r, param));
      |                 ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a.cc:260:30: note:         'param'
a.cc: In member function 'T lazysegtree<T>::update(int, int, Param&& ...)':
a.cc:268:23: error: parameter packs not expanded with '...':
  268 |                 update(a, b, 0, 0, offset + 1, param);
      |                 ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a.cc:268:23: note:         'param'