#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<ll,ll> P;
typedef pair<ll,P> P3;
constexpr ll INF = LLONG_MAX;

template <typename Monoid, typename OperatorMonoid>
struct LazySegmentTree{
private:
    using F = function<Monoid(Monoid, Monoid)>;  // 要素と要素を結合させる関数
    using G = function<Monoid(Monoid, OperatorMonoid)>;  // 要素に作用素を作用させる関数
    using H = function<OperatorMonoid(OperatorMonoid, OperatorMonoid)>;  // 作用素と作用素を結合させる関数
    using P = function<OperatorMonoid(OperatorMonoid, int)>;  // 作用素を作用させる区間の長さによって変化させる関数
    int N;
    vector<Monoid> node;
    vector<OperatorMonoid> lazy;
    F f;
    G g;
    H h;
    P p;
    Monoid e;  // identity element
    OperatorMonoid oe;  // identity element

public:
    LazySegmentTree(){}
    LazySegmentTree(F f, G g, H h, Monoid e, OperatorMonoid oe, P p=[](OperatorMonoid a, int b){return a;}):f(f), g(g), h(h), e(e), oe(oe), p(p){}
    void init(int sz){
        N = 1;
        while(N < sz) N <<= 1;
        node.assign(2*N-1, e);
        lazy.assign(2*N-1, oe);
    }
    void build(vector<Monoid>& v){
        int sz = int(v.size());
        init(sz);
        for(int i=0; i<sz; i++){
            node[i+N-1] = v[i];
        }
        for(int i=N-2; i>=0; i--){
            node[i] = f(node[i*2+1], node[i*2+2]);
        }
    }
    void eval(int k, int len){
        if(lazy[k] != oe){
            node[k] = g(node[k], p(lazy[k], len));
            if(k < N-1){
                lazy[2*k+1] = h(lazy[2*k+1], lazy[k]);
                lazy[2*k+2] = h(lazy[2*k+2], lazy[k]);
            }
            lazy[k] = oe;
        }
    }
    Monoid update(int a, int b, OperatorMonoid x){return update(a, b, x, 0, 0, N);}
    Monoid update(int a, int b, OperatorMonoid x, int k, int l, int r){
        eval(k, r-l);
        if(b <= l || r <= a) return node[k];
        if(a <= l && r <= b){
            lazy[k] = h(lazy[k], x);
            return g(node[k], p(lazy[k], r-l));
        }
        return node[k] = f(update(a,b,x,2*k+1,l,(l+r)/2), update(a,b,x,k*2+2,(l+r)/2,r));
    }
    // [a,b)
    Monoid query(int a, int b){return query(a, b, 0, 0, N);}
    Monoid query(int a, int b, int k, int l, int r){
        eval(k, r-l);
        if(b <= l || r <= a) return e;
        if(a <= l && r <= b) return node[k];
        Monoid vl, vr;
        vl = query(a, b, 2*k+1, l, (l+r)/2);
        vr = query(a, b, 2*k+2, (l+r)/2, r);

        return f(vl, vr);
    }
};

auto fMin = [=](ll a, ll b){return min(a,b);};
auto fMax = [=](ll a, ll b){return max(a,b);};
auto fSum = [=](ll a, ll b){return a+b;};
LazySegmentTree<ll, ll> Rmin(fMin,fSum,fSum,INF,0), Rmax(fMax,fSum,fSum,-INF,0);

template <typename Monoid>
struct SegmentTree{
private:
    using F = function<Monoid(Monoid, Monoid)>;
    int N;
    vector<Monoid> node;
    F f;
    Monoid e;  // identity element

public:
    SegmentTree(){}
    SegmentTree(F f, Monoid e):f(f), e(e){}
    void init(int sz){
        N = 1;
        while(N < sz) N <<= 1;
        node.assign(2*N-1, e);
    }
    void build(vector<Monoid>& v){
        int sz = int(v.size());
        init(sz);
        for(int i=0; i<sz; i++){
            node[i+N-1] = v[i];
        }
        for(int i=N-2; i>=0; i--){
            node[i] = f(node[i*2+1], node[i*2+2]);
        }
    }
    void update(int k, Monoid x){
        k += N-1;
        node[k] = x;
        while(k > 0){
            k = (k-1)/2;
            node[k] = f(node[2*k+1], node[2*k+2]);
        }
    }
    // [a,b)
    Monoid query(int a, int b){return query(a, b, 0, 0, N);}
    Monoid query(int a, int b, int k, int l, int r){
        if(b <= l || r <= a) return e;
        if(a <= l && r <= b) return node[k];
        Monoid vl, vr, vm;
        vl = query(a, b, 2*k+1, l, (l+r)/2);
        vr = query(a, b, 2*k+2, (l+r)/2, r);
        return f(vl, vr);
    }
};

auto fMerge = [](P3 a, P3 b){
    P3 res;
    ll l, m, r;
    l = a.second.first;
    m = a.second.second;
    r = b.second.second;
    if(l == -1) return b;
    if(r == -1) return a;
    res.first = max(a.first, b.first);
    res.first = max(res.first, max(Rmax.query(m,r)-Rmin.query(l,m),0LL));
    res.second = P(l,r);
    return res;
};

SegmentTree<P3> seg(fMerge,P3(0,{-1,-1}));

int main(){
    ll n, q;
    cin >> n >> q;
    vector<ll> a(n+2), b(n+2);
    for(int i=0;i<n;i++){
        cin >> a[i+1];
        b[i+1] = a[i+1];
        a[i+1] += a[i];
    }
    a[n+1] = -INF/2;
    Rmin.build(a);
    Rmax.build(a);
    /*
    for(int i=0;i<=n;i++){
        cout << Rmin.query(i,i+1) << " ";
    }
    cout << endl;
    */
    vector<P3> ls(n+2);
    for(int i=1;i<=n+1;i++){
        ls[i] = P3(a[i]-a[i-1],{i-1,i});
    }
    ls[0] = P3(-INF,{-1,-1});
    ls[n+1] = P3(-INF,{-1,-1});
    seg.build(ls);
    cout << seg.query(0,n+1).first << endl;
    for(int i=0;i<q;i++){
        ll k, x, y;
        cin >> k >> x;
        y = b[k];
        Rmin.update(k,n+2,x-y);
        Rmax.update(k,n+2,x-y);
        b[k] = x;
        seg.update(k,P3(x,{k-1,k}));
        cout << seg.query(0,n+2).first << endl;
        for(int j=0;j<=n;j++){
            //cout << Rmax.query(j,j+1) << endl;
        }
    }
    return 0;
}


Measured memory_bytes: 21016