#pragma GCC optimize("Ofast") #include using namespace std; #define rep(i, n) for(int i = 0; i < (int)(n); ++i) #define all(x) x.begin(),x.end() #define ln '\n' const long long MOD = 1000000007LL; //const long long MOD = 998244353LL; typedef long long ll; typedef unsigned long long ull; typedef pair pii; typedef pair pll; template inline bool chmax(T &a, T b) { if (a < b) { a = b; return true;} return false; } template inline bool chmin(T &a, T b) { if (a > b) { a = b; return true;} return false; } /////////////////////////////////////////////////////////////////////////////////////////////////// template struct LazySegmentTree { T unitynode; U unitylazy; F f; G g; H h; int N; int height; vector node; vector lazy; LazySegmentTree(F f, G g, H h, T unitynode, U unitylazy) : f(f), g(g), h(h), unitynode(unitynode), unitylazy(unitylazy) {} void init(int sz) { N = 1; height = 0; while (N < sz) { N *= 2; ++height; } node.assign(2*N,unitynode); lazy.assign(2*N,unitylazy); } void set(int k, const T &val) {node[k+N] = val;} void build() { for (int i = N-1; i > 0; --i) { node[i] = f(node[i<<1|0],node[i<<1|1]); } } inline T reflect(int k) { return lazy[k] == unitylazy ? node[k] : g(node[k],lazy[k]); } void eval(int k) { if (lazy[k] == unitylazy) return; if (k < N) { lazy[k<<1|0] = h(lazy[k<<1|0],lazy[k]); lazy[k<<1|1] = h(lazy[k<<1|1],lazy[k]); } node[k] = reflect(k); lazy[k] = unitylazy; } inline void recalc(int k) { while (k >>= 1) { node[k] = f(reflect(k<<1|0),reflect(k<<1|1)); } } // [l,r) (0-indexed) void update(int l, int r, U val) { if (l >= r) return; l += N; r += N-1; for (int i = height; i > 0; --i) { eval(l>>i); eval(r>>i); } int a = l; int b = r++; while (l < r) { if (l & 1) lazy[l] = h(lazy[l],val), ++l; if (r & 1) --r, lazy[r] = h(lazy[r],val); l >>= 1; r >>= 1; } recalc(a); recalc(b); } T get(int l, int r) { if (l >= r) return unitynode; l += N; r += N-1; for (int i = height; i > 0; --i) { eval(l>>i); eval(r>>i); } ++r; T vl = unitynode, vr = unitynode; while (l < r) { if (l & 1) vl = f(vl,reflect(l++)); if (r & 1) vr = f(reflect(--r),vr); l >>= 1; r >>= 1; } return f(vl,vr); } T operator[](int x) {return reflect(x+N);} }; using Tu = tuple; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int N,M; cin >> N >> M; vector A(N); vector X(M); rep(i,N) cin >> A[i]; rep(i,M) { cin >> X[i].first >> X[i].second; --X[i].first; } sort(all(X)); auto f=[](pll a, pll b) { if (a.first==0&&a.second==0) return b; if (b.first==0&&b.second==0) return a; ll p = a.first+b.first; ll q = max(a.second+b.first,b.second); return make_pair(p,q); }; auto g=[](pll a, ll val) { a.first += val; return a; }; auto h=[](ll a, ll b){ return a+b; }; const pll id1 = make_pair(0,0); const ll id2 = 0; ll ng = -1; ll ok = 1e9; while (ok - ng > 1) { ll mid = (ng+ok)/2; LazySegmentTree seg(f,g,h,id1,id2); seg.init(M); rep(i,M) { seg.set(i,make_pair(X[i].second - X[i].first*mid,0)); } seg.build(); bool flag = true; rep(i,N) { if (i) { int k = lower_bound(all(X),make_pair(ll(i),-1LL)) - X.begin(); seg.update(0,k,-mid); seg.update(k,M,+mid); } ll a,b; //cout << a << " " << b << ln; tie(a,b) = seg.get(0,M); //cout << a << " " << b << ln; if (A[i] <= max(a,b)) flag = false; } if (flag) ok = mid; else ng = mid; } if (ok==1e9) cout << -1 << ln; else cout << ok << ln; }