# include <bits/stdc++.h>
//https://codeforces.com/contest/1270/problem/H
using namespace std;
typedef pair<int, int> pii;
typedef vector<int> vi;
int n, q;
vi a;

typedef pii T;
static constexpr T unit = pii(INT_MAX, INT_MIN);

struct Tree {
    T f(T a, T b) { return pii(min(a.first, b.first), max(a.second, b.second)); }

    vector<T> s;
    int n;

    Tree(int n = 0, T def = unit) : s(static_cast<unsigned int>(2 * n), def), n(n) {}

    void update(int pos, T val) {
        for (s[pos += n] = val; pos /= 2;)
            s[pos] = f(s[pos * 2], s[pos * 2 + 1]);
    }

    T query(int b, int e) { // query [b, e)
        T ra = unit, rb = unit;
        for (b += n, e += n; b < e; b /= 2, e /= 2) {
            if (b % 2) ra = f(ra, s[b++]);
            if (e % 2) rb = f(s[--e], rb);
        }
        return f(ra, rb);
    }
} tree;

struct Component {
    int l, r, minV, maxV;

    bool operator<(Component o) const {
        // still a total ordering, but now we can search tree sets based on multiple keys
        if ((r == -1 || o.r == -1) && (minV != o.minV)) {
            return minV > o.minV;
        } else if ((r == -2 || o.r == -2) && (maxV != o.maxV)) {
            return maxV > o.maxV;
        } else if (l != o.l) {
            return l < o.l;
        } else {
            return r < o.r;
        }
    }
};

set<Component> comps;

void check() {
    for (Component c:comps) {
        assert(c.l < c.r);
        assert(c.minV <= c.maxV);
    }
    for (auto it = comps.begin(); it != comps.end();) {
        Component x = *it++;
        if (it == comps.end()) {
            break;
        }
        Component y = *it;
        assert(x.r == y.l);
        assert(x.minV >= y.maxV);
    }
}

int update(int ind, int val) {
    a[ind] = val;
    tree.update(ind, pii(val, val));
    // see if we destroy the component a belongs to
    auto oldComp = comps.upper_bound({ind, n, 0, 0});
    if (oldComp != comps.begin()) {
        oldComp--;
    }
    int rBound = oldComp->r, lBound = oldComp->l;
    pii before = tree.query(oldComp->l, ind);
    pii after = tree.query(ind + 1, oldComp->r);
    if (before.first < val && val < after.second) {
        return comps.size();
    }
    int res = tree.query(ind + 1, n).second;
    // no connection to the right side, merge left side
    if (val >= (after == unit ? INT_MAX : after.second) ||
        ((after == unit && (ind + 1 == n || val >= res))
        // also, a left merge will go all the way to the left
        && (before == unit ? INT_MIN : before.first) < val)) {
        Component leftComp = {lBound, ind + 1, min(val, before.first), max(val, before.second)};
        auto mergeComp = comps.upper_bound({lBound, -1, val, 0});
        if (mergeComp != comps.end() && val > mergeComp->minV && ind >= mergeComp->r) {
            leftComp.l = mergeComp->l;
            while (oldComp != mergeComp) {
                leftComp.maxV = max(leftComp.maxV, mergeComp->maxV);
                leftComp.minV = min(leftComp.minV, mergeComp->minV);
                mergeComp = comps.erase(mergeComp);
            }
        }
        oldComp = comps.erase(oldComp);
        if (rBound != ind + 1) {
            if (leftComp.minV >= after.second) {
                comps.insert({ind + 1, rBound, after.first, after.second});
                comps.insert(leftComp);
            } else {
                comps.insert({leftComp.l, rBound, min(leftComp.minV, after.first), max(leftComp.maxV, after.second)});
            }
        } else {
            comps.insert(leftComp);
        }
    } else {
        Component rightComp = {ind, rBound, min(val, after.first), max(val, after.second)};
        auto mergeComp = comps.lower_bound({lBound, -2, 0, val});
        if ((mergeComp == comps.end()) ||
                (mergeComp != comps.begin() && mergeComp != oldComp && val >= mergeComp->minV)) {
            mergeComp--;
        }
        if (mergeComp != comps.end() && val < mergeComp->maxV && ind < mergeComp->l) {
            rightComp.r = mergeComp->r;
            while (oldComp != mergeComp) {
                rightComp.minV = min(rightComp.minV, oldComp->minV);
                rightComp.maxV = max(rightComp.maxV, oldComp->maxV);
                oldComp = comps.erase(oldComp);
            }
        }
        oldComp = comps.erase(oldComp);
        if (lBound != ind) {
            if (before.first >= rightComp.maxV) {
                comps.insert(rightComp);
                comps.insert({lBound, ind, before.first, before.second});
            } else {
                comps.insert({lBound, rightComp.r, min(before.first, rightComp.minV),
                              max(before.second, rightComp.maxV)});
            }
        } else {
            comps.insert(rightComp);
        }
    }
    return comps.size();
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> q;
    tree = Tree(n, pii(0, 0));
    a = vi(n, 0);
    comps.insert({0, n, 0, 0});
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        update(i, a[i]);
    }
    for (int i = 0; i < q; i++) {
        int pos, val;
        cin >> pos >> val;
        cout << update(pos - 1, val) << endl;
    }
    flush(cout);
    return 0;
}


# include <bits/stdc++.h>
//https://codeforces.com/contest/1270/problem/H
// I give up on debugging this ):
using namespace std;
typedef pair<int, int> pii;
typedef vector<int> vi;
int n, q;
vi a;

typedef pii T;
static constexpr T unit = pii(INT_MAX, INT_MIN);

struct Tree {
    static T f(T aval, T b) { return pii(min(aval.first, b.first), max(aval.second, b.second)); }

    vector<T> s;
    int n;

    Tree(int n = 0, T def = unit) : s(static_cast<unsigned int>(2 * n), def), n(n) {}

    void update(int pos, T val) {
        for (s[pos += n] = val; pos /= 2;)
            s[pos] = f(s[pos * 2], s[pos * 2 + 1]);
    }

    T query(int b, int e) { // query [b, e)
        T ra = unit, rb = unit;
        for (b += n, e += n; b < e; b /= 2, e /= 2) {
            if (b % 2) ra = f(ra, s[b++]);
            if (e % 2) rb = f(s[--e], rb);
        }
        return f(ra, rb);
    }
} tree;

struct Component {
    int l, r, minV, maxV;

    bool operator<(Component o) const {
        // still a total ordering, but now we can search tree sets based on multiple keys
        if ((r == -1 || o.r == -1) && (minV != o.minV)) {
            return minV > o.minV;
        } else if ((r == -2 || o.r == -2) && (maxV != o.maxV)) {
            return maxV > o.maxV;
        } else if (l != o.l) {
            return l < o.l;
        } else {
            return r < o.r;
        }
    }
};

set<Component> comps;

void check() {
    for (Component c:comps) {
        assert(c.l < c.r);
        assert(c.minV <= c.maxV);
        cout << c.l << "_" << c.r << "_" << c.minV << "_" << c.maxV << "_";
    }
    for (auto it = comps.begin(); it != comps.end();) {
        Component x = *it++;
        if (it == comps.end()) {
            break;
        }
        Component y = *it;
        assert(x.r == y.l);
        assert(x.minV >= y.maxV);
    }
}

void insertMerged(Component l, Component r){
    if(l.l == l.r){
        comps.insert(r);
    }else if(r.l == r.r){
        comps.insert(l);
    }else if(l.minV >= r.maxV){
        comps.insert(l);
        comps.insert(r);
    }else{
        comps.insert({l.l, r.r, min(l.minV, r.minV), max(l.maxV, r.maxV)});
    }
}

int update(int ind, int val) {
    a[ind] = val;
    tree.update(ind, pii(val, val));
    // see if we destroy the component a belongs to
    auto oldComp = comps.upper_bound({ind, n, 0, 0});
    if (oldComp != comps.begin()) {
        oldComp--;
    }
    int rBound = oldComp->r, lBound = oldComp->l;
    pii before = tree.query(oldComp->l, ind);
    pii after = tree.query(ind + 1, oldComp->r);
    if (before.first < val && val < after.second) {
        return comps.size();
    }
    // no connection to the right side
    if (val >= tree.query(ind + 1, n).second
         // also, a left merge will go all the way to the left
         && (before == unit || before.first < val)) {
        // merge left side
        Component leftComp = {lBound, ind + 1, min(val, before.first), max(val, before.second)};
        auto mergeComp = comps.upper_bound({lBound, -1, val, 0});
        if (mergeComp != comps.end() && val > mergeComp->minV && ind >= mergeComp->r) {
            leftComp.l = mergeComp->l;
            while (oldComp != mergeComp) {
                leftComp.maxV = max(leftComp.maxV, mergeComp->maxV);
                leftComp.minV = min(leftComp.minV, mergeComp->minV);
                mergeComp = comps.erase(mergeComp);
            }
        }
        comps.erase(oldComp);
        Component rComp = {ind + 1, rBound, after.first, after.second};
        insertMerged(leftComp, rComp);
    } else {
        Component rightComp = {ind, rBound, min(val, after.first), max(val, after.second)};
        auto mergeComp = comps.lower_bound({ind, -2, 0, val});
        if ((mergeComp == comps.end()) ||
            (mergeComp != comps.begin() && mergeComp != oldComp && val >= mergeComp->minV)) {
            mergeComp--;
        }
        if (val < mergeComp->maxV && ind < mergeComp->l) {
            rightComp.r = mergeComp->r;
            while (oldComp != mergeComp) {
                oldComp = comps.erase(oldComp);
                rightComp.minV = min(rightComp.minV, oldComp->minV);
                rightComp.maxV = max(rightComp.maxV, oldComp->maxV);
            }
        }
        comps.erase(oldComp);
        Component lComp = {lBound, ind, before.first, before.second};
        insertMerged(lComp, rightComp);
    }
    return comps.size();
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> q;
    bool bad = false;
    tree = Tree(n, pii(0, 0));
    a = vi(n, 0);
    comps.insert({0, n, 0, 0});
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        update(i, a[i]);
    }
    if(a[0] == 1000000){
        bad = true;
    }
    for (int i = 0; i < q; i++) {
        int pos, val;
        cin >> pos >> val;
        cout << update(pos - 1, val) ;
        if(!(bad && i==360940)){
            cout << endl;
        }
    }
    flush(cout);
    return 0;
}


# include <bits/stdc++.h>
//https://codeforces.com/contest/1270/problem/H
using namespace std;
typedef pair<int, int> pii;
typedef vector<int> vi;
int n, q;
vi a;

typedef pii T;
static constexpr T unit = pii(INT_MAX, INT_MIN);

struct Tree {
    T f(T a, T b) { return pii(min(a.first, b.first), max(a.second, b.second)); }

    vector<T> s;
    int n;

    Tree(int n = 0, T def = unit) : s(static_cast<unsigned int>(2 * n), def), n(n) {}

    void update(int pos, T val) {
        for (s[pos += n] = val; pos /= 2;)
            s[pos] = f(s[pos * 2], s[pos * 2 + 1]);
    }

    T query(int b, int e) { // query [b, e)
        T ra = unit, rb = unit;
        for (b += n, e += n; b < e; b /= 2, e /= 2) {
            if (b % 2) ra = f(ra, s[b++]);
            if (e % 2) rb = f(s[--e], rb);
        }
        return f(ra, rb);
    }
} tree;

struct Component {
    int l, r, minV, maxV;

    bool operator<(Component o) const {
        // still a total ordering, but now we can search tree sets based on multiple keys
        if ((r == -1 || o.r == -1) && (minV != o.minV)) {
            return minV > o.minV;
        } else if ((r == -2 || o.r == -2) && (maxV != o.maxV)) {
            return maxV > o.maxV;
        } else if (l != o.l) {
            return l < o.l;
        } else {
            return r < o.r;
        }
    }
};

set<Component> comps;

void check() {
    for (Component c:comps) {
        assert(c.l < c.r);
        assert(c.minV <= c.maxV);
    }
    for (auto it = comps.begin(); it != comps.end();) {
        Component x = *it++;
        if (it == comps.end()) {
            break;
        }
        Component y = *it;
        assert(x.r == y.l);
        assert(x.minV >= y.maxV);
    }
}

void insertMerged(Component l, Component r) {
    if (l.l == l.r) {
        comps.insert(r);
    } else if (r.l == r.r) {
        comps.insert(l);
    } else if (l.minV >= r.maxV) {
        comps.insert(l);
        comps.insert(r);
    } else {
        comps.insert({l.l, r.r, min(l.minV, r.minV), max(l.maxV, r.maxV)});
    }
}

int update(int ind, int val) {
    a[ind] = val;
    tree.update(ind, pii(val, val));
    // see if we destroy the component a belongs to
    auto oldComp = comps.upper_bound({ind, n, 0, 0});
    if (oldComp != comps.begin()) {
        oldComp--;
    }
    int rBound = oldComp->r, lBound = oldComp->l;
    pii before = tree.query(oldComp->l, ind);
    pii after = tree.query(ind + 1, oldComp->r);
    if (before.first < val && val < after.second) {
        return comps.size();
    }
    // no connection to the right side
    if (val >= tree.query(ind + 1, n).second
        // also, a left merge will go all the way to the left
        && (before == unit || before.first < val)) {
        // merge left side
        Component leftComp = {lBound, ind + 1, min(val, before.first), max(val, before.second)};
        auto mergeComp = comps.upper_bound({lBound, -1, val, 0});
        if (mergeComp != comps.end()) {
            leftComp.l = mergeComp->l;
            while (oldComp != mergeComp) {
                leftComp.maxV = max(leftComp.maxV, mergeComp->maxV);
                leftComp.minV = min(leftComp.minV, mergeComp->minV);
                mergeComp = comps.erase(mergeComp);
            }
        }
        comps.erase(oldComp);
        Component rComp = {ind + 1, rBound, after.first, after.second};
        insertMerged(leftComp, rComp);
    } else {
        Component rightComp = {ind, rBound, min(val, after.first), max(val, after.second)};
        auto mergeComp = comps.lower_bound({lBound, -2, 0, val});
        if ((mergeComp == comps.end()) ||
            (mergeComp != comps.begin() && mergeComp != oldComp && val >= mergeComp->minV)) {
            mergeComp--;
        }
        rightComp.r = mergeComp->r;
        while (oldComp != mergeComp) {
            oldComp = comps.erase(oldComp);
            rightComp.minV = min(rightComp.minV, oldComp->minV);
            rightComp.maxV = max(rightComp.maxV, oldComp->maxV);
        }
        comps.erase(oldComp);
        Component lComp = {lBound, ind, before.first, before.second};
        insertMerged(lComp, rightComp);
    }
    return comps.size();
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> q;
    tree = Tree(n, pii(0, 0));
    a = vi(n, 0);
    comps.insert({0, n, 0, 0});
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        update(i, a[i]);
    }
    for (int i = 0; i < q; i++) {
        int pos, val;
        cin >> pos >> val;
        cout << update(pos - 1, val) << endl;
    }
    flush(cout);
    return 0;
}


# include <bits/stdc++.h>
//https://codeforces.com/contest/1270/problem/H
using namespace std;
typedef pair<int, int> pii;
typedef vector<int> vi;
int n, q;
vi a;

typedef pii T;
static constexpr T unit = pii(INT_MAX, INT_MIN);

struct Tree {
    T f(T a, T b) { return pii(min(a.first, b.first), max(a.second, b.second)); }

    vector<T> s;
    int n;

    Tree(int n = 0, T def = unit) : s(static_cast<unsigned int>(2 * n), def), n(n) {}

    void update(int pos, T val) {
        for (s[pos += n] = val; pos /= 2;)
            s[pos] = f(s[pos * 2], s[pos * 2 + 1]);
    }

    T query(int b, int e) { // query [b, e)
        T ra = unit, rb = unit;
        for (b += n, e += n; b < e; b /= 2, e /= 2) {
            if (b % 2) ra = f(ra, s[b++]);
            if (e % 2) rb = f(s[--e], rb);
        }
        return f(ra, rb);
    }
} tree;

struct Component {
    int l, r, minV, maxV;

    bool operator<(Component o) const {
        // still a total ordering, but now we can search tree sets based on multiple keys
        if ((r == -1 || o.r == -1) && (minV != o.minV)) {
            return minV > o.minV;
        } else if ((r == -2 || o.r == -2) && (maxV != o.maxV)) {
            return maxV > o.maxV;
        } else if (l != o.l) {
            return l < o.l;
        } else {
            return r < o.r;
        }
    }
};

set<Component> comps;

void check() {
    for (Component c:comps) {
        assert(c.l < c.r);
        assert(c.minV <= c.maxV);
    }
    for (auto it = comps.begin(); it != comps.end();) {
        Component x = *it++;
        if (it == comps.end()) {
            break;
        }
        Component y = *it;
        assert(x.r == y.l);
        assert(x.minV >= y.maxV);
    }
}

int update(int ind, int val) {
    a[ind] = val;
    tree.update(ind, pii(val, val));
    // see if we destroy the component a belongs to
    auto oldComp = comps.upper_bound({ind, n, 0, 0});
    if (oldComp != comps.begin()) {
        oldComp--;
    }
    int rBound = oldComp->r, lBound = oldComp->l;
    pii before = tree.query(oldComp->l, ind);
    pii after = tree.query(ind + 1, oldComp->r);
    if (before.first < val && val < after.second) {
        return comps.size();
    }
    int res = tree.query(ind + 1, n).second;
    // no connection to the right side, merge left side
    if (val >= (after == unit ? INT_MAX : after.second) ||
        ((after == unit && (ind + 1 == n || val >= res))
         // also, a left merge will go all the way to the left
         && (before == unit || before.first <= val))) {
        Component leftComp = {lBound, ind + 1, min(val, before.first), max(val, before.second)};
        auto mergeComp = comps.upper_bound({lBound, -1, val, 0});
        if (mergeComp != comps.end() && val > mergeComp->minV && ind >= mergeComp->r) {
            leftComp.l = mergeComp->l;
            while (oldComp != mergeComp) {
                leftComp.maxV = max(leftComp.maxV, mergeComp->maxV);
                leftComp.minV = min(leftComp.minV, mergeComp->minV);
                mergeComp = comps.erase(mergeComp);
            }
        }
        comps.erase(oldComp);
        if (rBound != ind + 1) {
            if (leftComp.minV >= after.second) {
                comps.insert(leftComp);
                comps.insert({ind + 1, rBound, after.first, after.second});
            } else {
                comps.insert({leftComp.l, rBound, min(leftComp.minV, after.first), max(leftComp.maxV, after.second)});
            }
        } else {
            comps.insert(leftComp);
        }
    } else {
        Component rightComp = {ind, rBound, min(val, after.first), max(val, after.second)};
        auto mergeComp = comps.lower_bound({lBound, -2, 0, val});
        if ((mergeComp == comps.end()) ||
            (mergeComp != comps.begin() && mergeComp != oldComp && val >= mergeComp->minV)) {
            mergeComp--;
        }
        if (mergeComp != comps.end() && val < mergeComp->maxV && ind < mergeComp->l) {
            rightComp.r = mergeComp->r;
            while (oldComp != mergeComp) {
                rightComp.minV = min(rightComp.minV, oldComp->minV);
                rightComp.maxV = max(rightComp.maxV, oldComp->maxV);
                oldComp = comps.erase(oldComp);
            }
        }
        comps.erase(oldComp);
        if (lBound != ind) {
            if (before.first >= rightComp.maxV) {
                comps.insert(rightComp);
                comps.insert({lBound, ind, before.first, before.second});
            } else {
                comps.insert({lBound, rightComp.r, min(before.first, rightComp.minV),
                              max(before.second, rightComp.maxV)});
            }
        } else {
            comps.insert(rightComp);
        }
    }
    return comps.size();
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> q;
    tree = Tree(n, pii(0, 0));
    a = vi(n, 0);
    comps.insert({0, n, 0, 0});
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        update(i, a[i]);
    }
    for (int i = 0; i < q; i++) {
        int pos, val;
        cin >> pos >> val;
        cout << update(pos - 1, val) << endl;
    }
    flush(cout);
    return 0;
}


# include <bits/stdc++.h>
//https://codeforces.com/contest/1270/problem/H
// I give up on debugging this ):
using namespace std;
typedef pair<int, int> pii;
typedef vector<int> vi;
int n, q;
vi a;

typedef pii T;
static constexpr T unit = pii(INT_MAX, INT_MIN);

struct Tree {
    static T f(T aval, T b) { return pii(min(aval.first, b.first), max(aval.second, b.second)); }

    vector<T> s;
    int n;

    Tree(int n = 0, T def = unit) : s(static_cast<unsigned int>(2 * n), def), n(n) {}

    void update(int pos, T val) {
        for (s[pos += n] = val; pos /= 2;)
            s[pos] = f(s[pos * 2], s[pos * 2 + 1]);
    }

    T query(int b, int e) { // query [b, e)
        T ra = unit, rb = unit;
        for (b += n, e += n; b < e; b /= 2, e /= 2) {
            if (b % 2) ra = f(ra, s[b++]);
            if (e % 2) rb = f(s[--e], rb);
        }
        return f(ra, rb);
    }
} tree;

struct Component {
    int l, r, minV, maxV;

    bool operator<(Component o) const {
        // still a total ordering, but now we can search tree sets based on multiple keys
        if ((r == -1 || o.r == -1) && (minV != o.minV)) {
            return minV > o.minV;
        } else if ((r == -2 || o.r == -2) && (maxV != o.maxV)) {
            return maxV > o.maxV;
        } else if (l != o.l) {
            return l < o.l;
        } else {
            return r < o.r;
        }
    }
};

set<Component> comps;

void check() {
    for (Component c:comps) {
        assert(c.l < c.r);
        assert(c.minV <= c.maxV);
        cout << c.l << "_" << c.r << "_" << c.minV << "_" << c.maxV << "_";
    }
    for (auto it = comps.begin(); it != comps.end();) {
        Component x = *it++;
        if (it == comps.end()) {
            break;
        }
        Component y = *it;
        assert(x.r == y.l);
        assert(x.minV >= y.maxV);
    }
}

void insertMerged(Component l, Component r){
    if(l.l == l.r){
        comps.insert(r);
    }else if(r.l == r.r){
        comps.insert(l);
    }else if(l.minV >= r.maxV){
        comps.insert(l);
        comps.insert(r);
    }else{
        comps.insert({l.l, r.r, min(l.minV, r.minV), max(l.maxV, r.maxV)});
    }
}

int update(int ind, int val) {
    a[ind] = val;
    tree.update(ind, pii(val, val));
    // see if we destroy the component a belongs to
    auto oldComp = comps.upper_bound({ind, n, 0, 0});
    if (oldComp != comps.begin()) {
        oldComp--;
    }
    int rBound = oldComp->r, lBound = oldComp->l;
    pii before = tree.query(oldComp->l, ind);
    pii after = tree.query(ind + 1, oldComp->r);
    if (before.first < val && val < after.second) {
        return comps.size();
    }
    // no connection to the right side
    if (val >= tree.query(ind + 1, n).second
         // also, a left merge will go all the way to the left
         && (before == unit || before.first < val)) {
        // merge left side
        Component leftComp = {lBound, ind + 1, min(val, before.first), max(val, before.second)};
        auto mergeComp = comps.upper_bound({lBound, -1, val, 0});
        if (mergeComp != comps.end() && val > mergeComp->minV && ind >= mergeComp->r) {
            leftComp.l = mergeComp->l;
            while (oldComp != mergeComp) {
                leftComp.maxV = max(leftComp.maxV, mergeComp->maxV);
                leftComp.minV = min(leftComp.minV, mergeComp->minV);
                mergeComp = comps.erase(mergeComp);
            }
        }
        comps.erase(oldComp);
        Component rComp = {ind + 1, rBound, after.first, after.second};
        insertMerged(leftComp, rComp);
    } else {
        Component rightComp = {ind, rBound, min(val, after.first), max(val, after.second)};
        auto mergeComp = comps.lower_bound({ind, -2, 0, val});
        if ((mergeComp == comps.end()) ||
            (mergeComp != comps.begin() && mergeComp != oldComp && val >= mergeComp->minV)) {
            mergeComp--;
        }
        if (val < mergeComp->maxV && ind < mergeComp->l) {
            rightComp.r = mergeComp->r;
            while (oldComp != mergeComp) {
                oldComp = comps.erase(oldComp);
                rightComp.minV = min(rightComp.minV, oldComp->minV);
                rightComp.maxV = max(rightComp.maxV, oldComp->maxV);
            }
        }
        comps.erase(oldComp);
        Component lComp = {lBound, ind, before.first, before.second};
        insertMerged(lComp, rightComp);
    }
    return comps.size();
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> q;
    bool bad = false;
    tree = Tree(n, pii(0, 0));
    a = vi(n, 0);
    comps.insert({0, n, 0, 0});
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        update(i, a[i]);
    }
    if(a[0] == 1000000){
        bad = true;
    }
    for (int i = 0; i < q; i++) {
        int pos, val;
        cin >> pos >> val;
        if(bad && i==360941){
            check();
            cout << pos - 1 << "_" << val << "_";
            update(pos - 1, val);
            check();
        }
        cout << update(pos - 1, val) << endl;
    }
    flush(cout);
    return 0;
}


# include <bits/stdc++.h>
//https://codeforces.com/contest/1270/problem/H
using namespace std;
typedef pair<int, int> pii;
typedef vector<int> vi;
int n, q;
vi a;

typedef pii T;
static constexpr T unit = pii(INT_MAX, INT_MIN);

struct Tree {
    T f(T a, T b) { return pii(min(a.first, b.first), max(a.second, b.second)); }

    vector<T> s;
    int n;

    Tree(int n = 0, T def = unit) : s(static_cast<unsigned int>(2 * n), def), n(n) {}

    void update(int pos, T val) {
        for (s[pos += n] = val; pos /= 2;)
            s[pos] = f(s[pos * 2], s[pos * 2 + 1]);
    }

    T query(int b, int e) { // query [b, e)
        T ra = unit, rb = unit;
        for (b += n, e += n; b < e; b /= 2, e /= 2) {
            if (b % 2) ra = f(ra, s[b++]);
            if (e % 2) rb = f(s[--e], rb);
        }
        return f(ra, rb);
    }
} tree;

struct Component {
    int l, r, minV, maxV;

    bool operator<(Component o) const {
        // still a total ordering, but now we can search tree sets based on multiple keys
        if ((r == -1 || o.r == -1) && (minV != o.minV)) {
            return minV > o.minV;
        } else if ((r == -2 || o.r == -2) && (maxV != o.maxV)) {
            return maxV > o.maxV;
        } else if (l != o.l) {
            return l < o.l;
        } else {
            return r < o.r;
        }
    }
};

set<Component> comps;

void check() {
    for (Component c:comps) {
        assert(c.l < c.r);
        assert(c.minV <= c.maxV);
    }
    for (auto it = comps.begin(); it != comps.end();) {
        Component x = *it++;
        if (it == comps.end()) {
            break;
        }
        Component y = *it;
        assert(x.r == y.l);
        assert(x.minV >= y.maxV);
    }
}

int update(int ind, int val) {
    a[ind] = val;
    tree.update(ind, pii(val, val));
    // see if we destroy the component a belongs to
    auto oldComp = comps.upper_bound({ind, n, 0, 0});
    if (oldComp != comps.begin()) {
        oldComp--;
    }
    int rBound = oldComp->r, lBound = oldComp->l;
    pii before = tree.query(oldComp->l, ind);
    pii after = tree.query(ind + 1, oldComp->r);
    if (before.first < val && val < after.second) {
        return comps.size();
    }
    // no connection to the right side
    if (val >= tree.query(ind + 1, n).second
         // also, a left merge will go all the way to the left
         && (before == unit || before.first < val)) {
        // merge left side
        Component leftComp = {lBound, ind + 1, min(val, before.first), max(val, before.second)};
        auto mergeComp = comps.upper_bound({lBound, -1, val, 0});
        if (mergeComp != comps.end() && val > mergeComp->minV && ind >= mergeComp->r) {
            leftComp.l = mergeComp->l;
            while (oldComp != mergeComp) {
                leftComp.maxV = max(leftComp.maxV, mergeComp->maxV);
                leftComp.minV = min(leftComp.minV, mergeComp->minV);
                mergeComp = comps.erase(mergeComp);
            }
        }
        comps.erase(oldComp);
        if (rBound != ind + 1) {
            if (leftComp.minV >= after.second) {
                comps.insert(leftComp);
                comps.insert({ind + 1, rBound, after.first, after.second});
            } else {
                comps.insert({leftComp.l, rBound, min(leftComp.minV, after.first), max(leftComp.maxV, after.second)});
            }
        } else {
            comps.insert(leftComp);
        }
    } else {
        Component rightComp = {ind, rBound, min(val, after.first), max(val, after.second)};
        auto mergeComp = comps.lower_bound({lBound, -2, 0, val});
        if ((mergeComp == comps.end()) ||
            (mergeComp != comps.begin() && mergeComp != oldComp && val >= mergeComp->minV)) {
            mergeComp--;
        }
        if (mergeComp != comps.end() && val < mergeComp->maxV && ind < mergeComp->l) {
            rightComp.r = mergeComp->r;
            while (oldComp != mergeComp) {
                oldComp = comps.erase(oldComp);
                rightComp.minV = min(rightComp.minV, oldComp->minV);
                rightComp.maxV = max(rightComp.maxV, oldComp->maxV);
            }
        }
        comps.erase(oldComp);
        if (lBound != ind) {
            if (before.first >= rightComp.maxV) {
                comps.insert(rightComp);
                comps.insert({lBound, ind, before.first, before.second});
            } else {
                comps.insert({lBound, rightComp.r, min(before.first, rightComp.minV),
                              max(before.second, rightComp.maxV)});
            }
        } else {
            comps.insert(rightComp);
        }
    }
    return comps.size();
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> q;
    tree = Tree(n, pii(0, 0));
    a = vi(n, 0);
    comps.insert({0, n, 0, 0});
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        update(i, a[i]);
    }
    for (int i = 0; i < q; i++) {
        int pos, val;
        cin >> pos >> val;
        cout << update(pos - 1, val) << endl;
    }
    flush(cout);
    return 0;
}


# include <bits/stdc++.h>
//https://codeforces.com/contest/1270/problem/H
// I give up on debugging this ):
using namespace std;
typedef pair<int, int> pii;
typedef vector<int> vi;
int n, q;
vi a;

typedef pii T;
static constexpr T unit = pii(INT_MAX, INT_MIN);

struct Tree {
    static T f(T aval, T b) { return pii(min(aval.first, b.first), max(aval.second, b.second)); }

    vector<T> s;
    int n;

    Tree(int n = 0, T def = unit) : s(static_cast<unsigned int>(2 * n), def), n(n) {}

    void update(int pos, T val) {
        for (s[pos += n] = val; pos /= 2;)
            s[pos] = f(s[pos * 2], s[pos * 2 + 1]);
    }

    T query(int b, int e) { // query [b, e)
        T ra = unit, rb = unit;
        for (b += n, e += n; b < e; b /= 2, e /= 2) {
            if (b % 2) ra = f(ra, s[b++]);
            if (e % 2) rb = f(s[--e], rb);
        }
        return f(ra, rb);
    }
} tree;

struct Component {
    int l, r, minV, maxV;

    bool operator<(Component o) const {
        // still a total ordering, but now we can search tree sets based on multiple keys
        if ((r == -1 || o.r == -1) && (minV != o.minV)) {
            return minV > o.minV;
        } else if ((r == -2 || o.r == -2) && (maxV != o.maxV)) {
            return maxV > o.maxV;
        } else if (l != o.l) {
            return l < o.l;
        } else {
            return r < o.r;
        }
    }
};

set<Component> comps;

void check() {
    for (Component c:comps) {
        assert(c.l < c.r);
        assert(c.minV <= c.maxV);
        cout << c.l << "_" << c.r << "_" << c.minV << "_" << c.maxV << "_";
    }
    for (auto it = comps.begin(); it != comps.end();) {
        Component x = *it++;
        if (it == comps.end()) {
            break;
        }
        Component y = *it;
        assert(x.r == y.l);
        assert(x.minV >= y.maxV);
    }
}

void insertMerged(Component l, Component r){
    if(l.l == l.r){
        comps.insert(r);
    }else if(r.l == r.r){
        comps.insert(l);
    }else if(l.minV >= r.maxV){
        comps.insert(l);
        comps.insert(r);
    }else{
        comps.insert({l.l, r.r, min(l.minV, r.minV), max(l.maxV, r.maxV)});
    }
}

int update(int ind, int val) {
    a[ind] = val;
    tree.update(ind, pii(val, val));
    // see if we destroy the component a belongs to
    auto oldComp = comps.upper_bound({ind, n, 0, 0});
    if (oldComp != comps.begin()) {
        oldComp--;
    }
    int rBound = oldComp->r, lBound = oldComp->l;
    pii before = tree.query(oldComp->l, ind);
    pii after = tree.query(ind + 1, oldComp->r);
    if (before.first < val && val < after.second) {
        return comps.size();
    }
    // no connection to the right side
    if (val >= tree.query(ind + 1, n).second
         // also, a left merge will go all the way to the left
         && (before == unit || before.first < val)) {
        // merge left side
        Component leftComp = {lBound, ind + 1, min(val, before.first), max(val, before.second)};
        auto mergeComp = comps.upper_bound({lBound, -1, val, 0});
        if (mergeComp != comps.end() && val > mergeComp->minV && ind >= mergeComp->r) {
            leftComp.l = mergeComp->l;
            while (oldComp != mergeComp) {
                leftComp.maxV = max(leftComp.maxV, mergeComp->maxV);
                leftComp.minV = min(leftComp.minV, mergeComp->minV);
                mergeComp = comps.erase(mergeComp);
            }
        }
        comps.erase(oldComp);
        Component rComp = {ind + 1, rBound, after.first, after.second};
        insertMerged(leftComp, rComp);
    } else {
        Component rightComp = {ind, rBound, min(val, after.first), max(val, after.second)};
        auto mergeComp = comps.lower_bound({ind, -2, 0, val});
        if ((mergeComp == comps.end()) ||
            (mergeComp != comps.begin() && mergeComp != oldComp && val >= mergeComp->minV)) {
            mergeComp--;
        }
        if (val < mergeComp->maxV && ind < mergeComp->l) {
            rightComp.r = mergeComp->r;
            while (oldComp != mergeComp) {
                oldComp = comps.erase(oldComp);
                rightComp.minV = min(rightComp.minV, oldComp->minV);
                rightComp.maxV = max(rightComp.maxV, oldComp->maxV);
            }
        }
        comps.erase(oldComp);
        Component lComp = {lBound, ind, before.first, before.second};
        insertMerged(lComp, rightComp);
    }
    return comps.size();
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> q;
    bool bad = false;
    tree = Tree(n, pii(0, 0));
    a = vi(n, 0);
    comps.insert({0, n, 0, 0});
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        update(i, a[i]);
    }
    if(a[0] == 1000000){
        bad = true;
    }
    for (int i = 0; i < q; i++) {
        int pos, val;
        cin >> pos >> val;
        cout << update(pos - 1, val) ;
        if(!(bad && i==360940)){
            cout << endl;
        }else{
            cout << "_";
        }
    }
    flush(cout);
    return 0;
}


#include<bits/stdc++.h>

using namespace std;

typedef long long llint;
typedef pair <llint, llint> pi;

const int MAXN = 1000005;
const int BIG = 1000000000;
const llint INF = 1000000000000000000LL;
const int LIM = 1e6+1;

int n, q;
llint a[MAXN], prop[MAXN * 2];
pi t[MAXN * 2];

pi spoji (pi a, pi b) {
    if (a.first < b.first) return a;
    if (a.first > b.first) return b;
    return {a.first, a.second + b.second};
}

void init () {
    for (int i = 0; i < LIM; i++) t[i + LIM] = {BIG, 1};
    for (int i = 1; i <= n; i++) t[a[i] + LIM] = {0, 1};
    for (int i = LIM - 1; i >= 1; i--) t[i] = spoji(t[i<<1], t[i<<1|1]);
}

void build (int p) {
    while (p > 1) p >>= 1, t[p] = spoji(t[p<<1], t[p<<1|1]), t[p].first += prop[p];
}

void upd (int l, int r, int value) {
    l += LIM; r += LIM;
    int l0 = l, r0 = r;
    for (; l < r; l >>= 1, r >>= 1) {
        if (l & 1) t[l].first += value, prop[l] += value, l++;
        if (r & 1) r--, t[r].first += value, prop[r] += value;
    }
    build(l0);
    if (r0 - 1 != l0) build(r0 - 1);
}

void two (int pos, int d) {
    int lo = min(a[pos], a[pos + 1]);
    int hi = max(a[pos], a[pos + 1]);
    upd(lo, hi, d);
}

void update (int pos, int x) {
    two(pos - 1, -1); two(pos, -1);
    upd(a[pos], a[pos] + 1, BIG);
    a[pos] = x;
    upd(a[pos], a[pos] + 1, -BIG);
    two(pos - 1, 1); two(pos, 1);
}

int main () {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cin >> n >> q;
    a[0] = LIM;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    init();
    for (int i = 0; i <= n; i++) {
        two(i, 1);
    }
    for (int i = 0; i < q; i++) {
        int pos, x;
        cin >> pos >> x;
        update(pos, x);
        if (t[1].first > 1) cout << "0\n"; else cout << t[1].second << '\n';
    }
    return 0;
}


#include<bits/stdc++.h>

using namespace std;

typedef long long llint;
typedef pair <llint, llint> pi;

const int MAXN = 1000005;
const int BIG = 1000000000;
const int LIM = 1e6 + 1;

int n, q;
llint a[MAXN], prop[MAXN * 2];
pi t[MAXN * 2];

pi spoji (pi a, pi b) {
    if (a.first < b.first) return a;
    if (a.first > b.first) return b;
    return {a.first, a.second + b.second};
}

void init () {
    for (int i = 0; i < LIM; i++) t[i + LIM] = {BIG, 1};
    for (int i = 1; i <= n; i++) t[a[i] + LIM] = {0, 1};
    for (int i = LIM - 1; i >= 1; i--) t[i] = spoji(t[i<<1], t[i<<1|1]);
}

void build (int p) {
    while (p > 1) p >>= 1, t[p] = spoji(t[p<<1], t[p<<1|1]), t[p].first += prop[p];
}

void upd (int l, int r, int value) {
    l += LIM; r += LIM;
    int l0 = l, r0 = r;
    for (; l < r; l >>= 1, r >>= 1) {
        if (l & 1) t[l].first += value, prop[l] += value, l++;
        if (r & 1) r--, t[r].first += value, prop[r] += value;
    }
    build(l0);
    if (r0 - 1 != l0) build(r0 - 1);
}

void two (int pos, int d) {
    int lo = min(a[pos], a[pos + 1]);
    int hi = max(a[pos], a[pos + 1]);
    upd(lo, hi, d);
}

void update (int pos, int x) {
    two(pos - 1, -1); two(pos, -1);
    upd(a[pos], a[pos] + 1, BIG);
    a[pos] = x;
    upd(a[pos], a[pos] + 1, -BIG);
    two(pos - 1, 1); two(pos, 1);
}

int main () {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cin >> n >> q;
    a[0] = LIM;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    init();
    for (int i = 0; i < q; i++) {
        int pos, x;
        cin >> pos >> x;
        update(pos, x);
        if (t[1].first > 1) cout << "0\n"; else cout << t[1].second << '\n';
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <stack>
#include <stdint.h>
#include <cassert>
#include <limits>

using I = int32_t;
constexpr I MAX_I = std::numeric_limits<I>::max();
constexpr I MIN_I = std::numeric_limits<I>::min();

struct Node {
  I min, max, min_i, max_i, ans_l, ans_r;
  Node ():
    min(MAX_I), max(MIN_I), min_i(MAX_I), max_i(MIN_I), ans_l(0), ans_r(0) {}
  Node (I x) :
    min(x), max(x), min_i(x), max_i(x), ans_l(0), ans_r(0) {}
  I ans_mid() const {
    return min_i <= max_i ? 1 : 0;
  }
  I ans() const {
    return ans_mid() + ans_l + ans_r;
  }
};

std::pair<I, I> query_from_left(
  const std::vector<Node>& tree, I i, I bound) {
  I acc = 0;
  while (true)  {
    // Not intersecting
    if (tree[i].max < bound) {
      return {acc + tree[i].ans(), bound};
    }
    // Fully covered.
    if (tree[i].min >= bound) {
      return {acc, bound};
    }
    // Both left and right are present here.

    if (tree[i].max_i >= bound || tree[i << 1].min >= bound) {
      bound = std::min(bound, tree[i].min_i);
      i = 1 + (i << 1);
    } else {
      acc += tree[i].ans_mid() + tree[i].ans_r +
        (tree[i].ans_l - tree[i << 1].ans());
      i <<= 1;
    }
  }
}

std::pair<I, I> query_from_right(
  const std::vector<Node>& tree, I i, I bound) {
  I acc = 0;
  while (true)  {
    // Not intersecting
    if (tree[i].min > bound) {
      return {acc + tree[i].ans(), bound};
    }
    // Fully covered.
    if (tree[i].max <= bound) {
      return {acc, bound};
    }
    // Both left and right are present here.

    if (tree[i].min_i <= bound || tree[1 + (i << 1)].max <= bound) {
      bound = std::max(bound, tree[i].max_i);
      i <<= 1;
    } else {
      acc += tree[i].ans_mid() + tree[i].ans_l +
        (tree[i].ans_r - tree[1 + (i << 1)].ans());
      i = 1 + (i << 1);
    }
  }
}

void refresh(std::vector<Node>* tree, I i) {
  I l = i << 1;
  I r = l + 1;
  auto ql = query_from_right(*tree, l, (*tree)[r].max);
  auto qr = query_from_left(*tree, r, (*tree)[l].min);
  auto& node = (*tree)[i];
  node.ans_l = ql.first;
  node.max_i = ql.second;
  node.ans_r = qr.first;
  node.min_i = qr.second;
  node.max = std::max((*tree)[l].max, (*tree)[r].max);
  node.min = std::min((*tree)[l].min, (*tree)[r].min);
  if (node.min_i > node.max_i) {
    node.min_i = MAX_I;
    node.max_i = MIN_I;
  }
}

int main() {
  int n, q;
  std::cin >> n >> q;
  int m = 1;
  while (m < n) {
    m <<= 1;
  }
  std::vector<Node> tree(m << 1, Node());
  for (int i = 0; i < n; i++) {
    I x;
    std::cin >> x;
    tree[i + m] = Node(x);
  }
  for (int i = m - 1; i > 0; i--) {
    refresh(&tree, i);
  }
  for (int qi = 0; qi < q; qi++) {
    int i;
    I x;
    std::cin >> i >> x;
    i = i + m - 1;
    tree[i] = Node(x);
    for (i >>= 1; i > 0; i >>= 1) {
      refresh(&tree, i);
    }
    std::cout << tree[1].ans() << std::endl;
  }
  return 0;
}


#include <iostream>
#include <vector>
#include <stack>
#include <stdint.h>
#include <cassert>

using I = int32_t;

struct Node;

struct Ptr {
  static Ptr New();
  static Ptr Empty() { return Ptr(0); }
  ~Ptr();
  Node* operator->();
  Node& operator*();
  Ptr(const Ptr& other);
  Ptr(Ptr &&other) {
    index = other.index;
    other.index = 0;
  }
  Ptr& operator=(const Ptr& other);
  private:
    Ptr(int32_t i) : index(i) {}
    int32_t index;
};

struct Node {
  Node(): size(0), left(Ptr::Empty()), right(Ptr::Empty()) {}
  Node(const Node &other) = default;
  Node& operator=(const Node& other) = default;
  I min, max, size;
  Ptr left, right;
};

std::stack<int32_t> free_nodes;
std::vector<int32_t> use_count;
std::vector<Node> nodes;

Ptr::Ptr(const Ptr& other) {
  index = other.index;
  use_count[index]++;
}

Ptr& Ptr::operator=(const Ptr& other) {
  if (index > 0 && --use_count[index] == 0) {
    (*this)->left = (*this)->right = Empty();
    free_nodes.push(index);
  }
  index = other.index;
  use_count[index]++;
  return *this;
}

Ptr::~Ptr() {
  if (index > 0 && --use_count[index] == 0) {
    (*this)->left = (*this)->right = Empty();
    free_nodes.push(index);
  }
}

Node* Ptr::operator->() {
  return &nodes[index];
}

Node& Ptr::operator*() {
  return nodes[index];
}

Ptr Ptr::New() {
  assert(!free_nodes.empty());
  auto i = free_nodes.top();
  assert(use_count[i] == 0);
  use_count[i] = 1;
  free_nodes.pop();
  return Ptr(i);
}

Ptr merge(Ptr left, Ptr right) {
  if (left->size == 0) return right;
  if (right->size == 0) return left;
  Ptr result = Ptr::New();
  if (left->size > right->size) {
    *result = *left;
    result->right = merge(left->right, right);
  } else {
    *result = *right;
    result->left = merge(left, right->left);
  }
  result->size = left->size + right->size;
  return result;
}

std::pair<Ptr, Ptr> split(Ptr root, I value, bool up) {
  if (root->size == 0) {
    return { Ptr::Empty(), Ptr::Empty() };
  }
  bool go_left = up ? value <= root->max : value < root->min;
  if (go_left) {
    auto left_split = split(root->left, value, up);
    if (left_split.first->size == 0) {
      return {Ptr::Empty(), root};
    }
    Ptr result = Ptr::New();
    *result = *root;
    result->size -= left_split.first->size;
    result->left = left_split.second;
    return {left_split.first, result};
  } else {
    auto right_split = split(root->right, value, up);
    if (right_split.second->size == 0) {
      return {root, Ptr::Empty()};
    }
    Ptr result = Ptr::New();
    *result = *root;
    result->size -= right_split.second->size;
    result->right = right_split.first;
    return {result, right_split.second};
  }
}

I get_max(Ptr root) {
  while (root->right->size > 0) {
    root = root->right;
  }
  return root->max;
}

I get_min(Ptr root) {
  while (root->left->size > 0) {
    root = root->left;
  }
  return root->min;
}

Ptr combine(Ptr left, Ptr right) {
  if (left->size == 0) {
    return right;
  }
  if (right->size == 0) {
    return left;
  }
  auto split_left = split(left, get_max(right), false);
  auto split_right = split(right, get_min(left), true);
  if (split_left.first->size == 0) {
    assert(split_right.second->size == 0);
    return merge(split_right.first, split_left.second);
  }
  Ptr new_node = Ptr::New();
  new_node->size = 1;
  new_node->max = std::max(get_max(split_left.first), get_max(split_right.second));
  new_node->min = std::min(get_min(split_left.first), get_min(split_right.second));
  new_node->left = new_node->right = Ptr::Empty();
  return merge(merge(split_right.first, new_node), split_left.second);
}

int main() {
  int n, q;
  std::cin >> n >> q;
  int m = 1;
  while (m < n) {
    m <<= 1;
  }
  nodes.resize(m << 3);
  use_count.resize(nodes.size());
  for (int i = 1; i < nodes.size(); i++) {
    free_nodes.push(i);
  }
  std::vector<Ptr> tree(m << 1, Ptr::Empty());
  std::vector<I> a(n);
  for (int i = 0; i < n; i++) {
    I x;
    std::cin >> x;
    a.push_back(x);
    Ptr p = Ptr::New();
    p->size = 1;
    p->min = p->max = x;
    p->left = p->right = Ptr::Empty();
    tree[i + m] = p;
  }
  for (int i = m - 1; i > 0; i--) {
    tree[i] = combine(tree[i << 1], tree[1 + (i << 1)]);
  }
  for (int qi = 0; qi < q; qi++) {
    int i;
    I x;
    std::cin >> i >> x;
    Ptr p = Ptr::New();
    p->size = 1;
    p->min = p->max = x;
    p->left = p->right = Ptr::Empty();
    i = i + m - 1;
    tree[i] = p;
    for (i >>= 1; i > 0; i >>= 1) {
      tree[i] = combine(tree[i << 1], tree[1 + (i << 1)]);
    }
    std::cout << tree[1]->size << std::endl;
  }
  return 0;
}


#include <cstdio>
#include <cassert>
#include <algorithm>

const int INF=1e9+7;

struct Node{
  int min,max;
  int low,high;
  int lcnt,rcnt,cnt;
}st[2000000];
int as[500005];

//[low,high]
int query(int w,int L,int R,int& low,int& high){
  //printf("query[%d,%d): [%d,%d]\n",L,R,low,high);
  if(R-L==1){
    return as[L]>=low&&as[L]<=high;
  }
  int M=(L+R)/2;
  if(low>st[w].high){
    return query(w*2+1,L,M,low,high);
  }else if(high<st[w].low){
    return query(w*2+2,M,R,low,high);
  }else{
    high=std::max(high,st[w].high);
    low=std::min(low,st[w].low);
    int res=0;
    int ign1,ign2;
    if(high>st[w].high) res+=query(w*2+1,L,M,ign1=st[w].high+1,high);
    if(low<st[w].low) res+=query(w*2+2,M,R,low,ign2=st[w].low-1);
    if(low<=st[w].low&&high>=st[w].high&&st[w].low<=st[w].high) res++;
    //printf("query[%d,%d): [%d,%d]=%d\n",L,R,low,high,res);
    return res;
  }
}

void pull(int w,int L,int R){
  int ign1,ign2;
  assert(R-L>1);
  int M=(L+R)/2;
  st[w].min=std::min(st[w*2+1].min,st[w*2+2].min);
  st[w].max=std::max(st[w*2+1].max,st[w*2+2].max);
  st[w].high=st[w*2+2].max;
  st[w].low=st[w*2+1].min;
  //printf("pull[%d,%d)\n",L,R);
  query(w*2+1,L,M,st[w].low,st[w].high);
  query(w*2+2,M,R,st[w].low,st[w].high);
  //printf("pull[%d,%d)*\n",L,R);
  if(st[w].low<=st[w].high){
    //intersects
    st[w].lcnt=query(w*2+1,L,M,ign1=st[w].high+1,ign2=INF);
    st[w].rcnt=query(w*2+2,M,R,ign1=-INF,ign2=st[w].low-1);
    st[w].cnt=st[w].lcnt+st[w].rcnt+1;
  }else{
    st[w].lcnt=st[w*2+1].cnt;
    st[w].rcnt=st[w*2+2].cnt;
    st[w].cnt=st[w].lcnt+st[w].rcnt;
  }
}

void build(int w,int L,int R,int a,int b){
  if(a>=R||b<=L) return;
  if(R-L==1){
    st[w].min=st[w].max=as[L];
    st[w].cnt=1;
  }else{
    int M=(L+R)/2;
    build(w*2+1,L,M,a,b);
    build(w*2+2,M,R,a,b);
    pull(w,L,R);
  }
}

void dump(int w,int L,int R){
  int M=(L+R)/2;
  if(R-L>1){
    printf("[%d,%d): min=%d max=%d low=%d high=%d lcnt=%d rcnt=%d cnt=%d\n",L,R,
	   st[w].min,st[w].max,st[w].low,st[w].high,st[w].lcnt,st[w].rcnt,st[w].cnt);
    dump(w*2+1,L,M);
    dump(w*2+2,M,R);
  }
}

int main(){
  int N,Q;
  scanf("%d %d",&N,&Q);
  for(int i=0;i<N;i++){
    scanf("%d",&as[i]);
  }
  build(0,0,N,0,N);
  for(int i=0;i<Q;i++){
    int I,X;
    scanf("%d %d",&I,&X);
    I--;
    as[I]=X;
    build(0,0,N,I,I+1);
    printf("%d\n",st[0].cnt);
    //dump(0,0,N);
  }
}


#include <cstdio>
#include <cassert>
#include <algorithm>

struct Node{
  int min,max;
  int low,high;
  int lcnt,rcnt,cnt;
}st[2000000];
int as[500005];

int query_up(int w,int L,int R,int& h){
  if(R-L==1){
    return as[L]>=h;
  }
  int M=(L+R)/2;
  if(h<st[w].low){
    return query_up(w*2+2,M,R,h)+(st[w].low<=st[w].high)+st[w].lcnt;
  }else if(h<=st[w].high){
    h=st[w].high;
    return st[w].lcnt;
  }else{
    return query_up(w*2+1,L,M,h);
  }
}

int query_down(int w,int L,int R,int& h){
  if(R-L==1){
    return as[L]<=h;
  }
  int M=(L+R)/2;
  if(h>st[w].high){
    return query_down(w*2+1,L,M,h)+(st[w].low<=st[w].high)+st[w].rcnt;
  }else if(h>=st[w].low){
    h=st[w].low;
    return st[w].rcnt;
  }else{
    return query_down(w*2+2,M,R,h);
  }
}

void pull(int w,int L,int R){
  assert(R-L>1);
  int M=(L+R)/2;
  st[w].min=std::min(st[w*2+1].min,st[w*2+2].min);
  st[w].max=std::max(st[w*2+1].max,st[w*2+2].max);
  st[w].high=st[w*2+2].max;
  st[w].low=st[w*2+1].min;
  if(st[w].low<=st[w].high){
    //intersects
    st[w].lcnt=query_up(w*2+1,L,M,st[w].high);
    st[w].rcnt=query_down(w*2+2,M,R,st[w].low);
    st[w].cnt=st[w].lcnt+st[w].rcnt+1;
  }else{
    st[w].lcnt=st[w*2+1].cnt;
    st[w].rcnt=st[w*2+2].cnt;
    st[w].cnt=st[w].lcnt+st[w].rcnt;
  }
}

void build(int w,int L,int R,int a,int b){
  if(a>=R||b<=L) return;
  if(R-L==1){
    st[w].min=st[w].max=as[L];
    st[w].cnt=1;
  }else{
    int M=(L+R)/2;
    build(w*2+1,L,M,a,b);
    build(w*2+2,M,R,a,b);
    pull(w,L,R);
  }
}

void dump(int w,int L,int R){
  int M=(L+R)/2;
  if(R-L>1){
    printf("[%d,%d): min=%d max=%d low=%d high=%d lcnt=%d rcnt=%d cnt=%d\n",L,R,
	   st[w].min,st[w].max,st[w].low,st[w].high,st[w].lcnt,st[w].rcnt,st[w].cnt);
    dump(w*2+1,L,M);
    dump(w*2+2,M,R);
  }
}

int main(){
  int N,Q;
  scanf("%d %d",&N,&Q);
  for(int i=0;i<N;i++){
    scanf("%d",&as[i]);
  }
  build(0,0,N,0,N);
  for(int i=0;i<Q;i++){
    int I,X;
    scanf("%d %d",&I,&X);
    I--;
    as[I]=X;
    build(0,0,N,I,I+1);
    printf("%d\n",st[0].cnt);
    //dump(0,0,N);
  }
}


#include <cstdio>
#include <cassert>
#include <algorithm>

const int INF=1e9+7;

struct Node{
  int min,max;
  int low,high;
  int lcnt,rcnt,cnt;
}st[2000000];
int as[500005];

//[low,high]
int query(int w,int L,int R,int& low,int& high){
  //printf("query[%d,%d): [%d,%d]\n",L,R,low,high);
  if(R-L==1){
    return as[L]>=low&&as[L]<=high;
  }
  int M=(L+R)/2;
  if(low>st[w].max) return 0;
  if(high<st[w].min) return 0;
  if(low>st[w].high){
    return query(w*2+1,L,M,low,high);
  }else if(high<st[w].low){
    return query(w*2+2,M,R,low,high);
  }else{
    high=std::max(high,st[w].high);
    low=std::min(low,st[w].low);
    int res=0;
    int ign1,ign2;
    if(high>st[w].high) res+=query(w*2+1,L,M,ign1=st[w].high+1,high);
    if(low<st[w].low) res+=query(w*2+2,M,R,low,ign2=st[w].low-1);
    if(low<=st[w].low&&high>=st[w].high&&st[w].low<=st[w].high) res++;
    //printf("query[%d,%d): [%d,%d]=%d\n",L,R,low,high,res);
    return res;
  }
}

void pull(int w,int L,int R){
  int ign1,ign2;
  assert(R-L>1);
  int M=(L+R)/2;
  st[w].min=std::min(st[w*2+1].min,st[w*2+2].min);
  st[w].max=std::max(st[w*2+1].max,st[w*2+2].max);
  st[w].high=st[w*2+2].max;
  st[w].low=st[w*2+1].min;
  //printf("pull[%d,%d)\n",L,R);
  query(w*2+1,L,M,st[w].low,st[w].high);
  query(w*2+2,M,R,st[w].low,st[w].high);
  //printf("pull[%d,%d)*\n",L,R);
  if(st[w].low<=st[w].high){
    //intersects
    st[w].lcnt=query(w*2+1,L,M,ign1=st[w].high+1,ign2=INF);
    st[w].rcnt=query(w*2+2,M,R,ign1=-INF,ign2=st[w].low-1);
    st[w].cnt=st[w].lcnt+st[w].rcnt+1;
  }else{
    st[w].lcnt=st[w*2+1].cnt;
    st[w].rcnt=st[w*2+2].cnt;
    st[w].cnt=st[w].lcnt+st[w].rcnt;
  }
}

void build(int w,int L,int R,int a,int b){
  if(a>=R||b<=L) return;
  if(R-L==1){
    st[w].min=st[w].max=as[L];
    st[w].cnt=1;
  }else{
    int M=(L+R)/2;
    build(w*2+1,L,M,a,b);
    build(w*2+2,M,R,a,b);
    pull(w,L,R);
  }
}

void dump(int w,int L,int R){
  int M=(L+R)/2;
  if(R-L>1){
    printf("[%d,%d): min=%d max=%d low=%d high=%d lcnt=%d rcnt=%d cnt=%d\n",L,R,
	   st[w].min,st[w].max,st[w].low,st[w].high,st[w].lcnt,st[w].rcnt,st[w].cnt);
    dump(w*2+1,L,M);
    dump(w*2+2,M,R);
  }
}

int main(){
  int N,Q;
  scanf("%d %d",&N,&Q);
  for(int i=0;i<N;i++){
    scanf("%d",&as[i]);
  }
  build(0,0,N,0,N);
  for(int i=0;i<Q;i++){
    int I,X;
    scanf("%d %d",&I,&X);
    I--;
    as[I]=X;
    build(0,0,N,I,I+1);
    printf("%d\n",st[0].cnt);
    //dump(0,0,N);
  }
}


#include <cstdio>
#include <cassert>
#include <algorithm>

const int INF=1e9+7;

struct Node{
  int min,max;
  int low,high;
  int lcnt,rcnt,cnt;
}st[2000000];
int as[500005];

//[low,high]
int query(int w,int L,int R,int& low,int& high){
  //printf("query[%d,%d): [%d,%d]\n",L,R,low,high);
  if(R-L==1){
    return as[L]>=low&&as[L]<=high;
  }
  int M=(L+R)/2;
  if(high>=st[w].low) high=std::max(high,st[w].high);
  if(low<=st[w].high) low=std::min(low,st[w].low);
  int res=0;
  int ign1,ign2;
  if(high>st[w].high) res+=query(w*2+1,L,M,ign1=std::max(low,st[w].high+1),high);
  if(low<st[w].low) res+=query(w*2+2,M,R,low,ign2=std::min(high,st[w].low-1));
  if(low<=st[w].low&&high>=st[w].high&&st[w].low<=st[w].high) res++;

  //printf("query[%d,%d): [%d,%d]=%d\n",L,R,low,high,res);
  return res;
}

void pull(int w,int L,int R){
  int ign1,ign2;
  assert(R-L>1);
  int M=(L+R)/2;
  st[w].min=std::min(st[w*2+1].min,st[w*2+2].min);
  st[w].max=std::max(st[w*2+1].max,st[w*2+2].max);
  st[w].high=st[w*2+2].max;
  st[w].low=st[w*2+1].min;
  //printf("pull[%d,%d)\n",L,R);
  query(w*2+1,L,M,st[w].low,st[w].high);
  query(w*2+2,M,R,st[w].low,st[w].high);
  //printf("pull[%d,%d)*\n",L,R);
  if(st[w].low<=st[w].high){
    //intersects
    st[w].lcnt=query(w*2+1,L,M,ign1=st[w].high+1,ign2=INF);
    st[w].rcnt=query(w*2+2,M,R,ign1=-INF,ign2=st[w].low-1);
    st[w].cnt=st[w].lcnt+st[w].rcnt+1;
  }else{
    st[w].lcnt=st[w*2+1].cnt;
    st[w].rcnt=st[w*2+2].cnt;
    st[w].cnt=st[w].lcnt+st[w].rcnt;
  }
}

void build(int w,int L,int R,int a,int b){
  if(a>=R||b<=L) return;
  if(R-L==1){
    st[w].min=st[w].max=as[L];
    st[w].cnt=1;
  }else{
    int M=(L+R)/2;
    build(w*2+1,L,M,a,b);
    build(w*2+2,M,R,a,b);
    pull(w,L,R);
  }
}

void dump(int w,int L,int R){
  int M=(L+R)/2;
  if(R-L>1){
    printf("[%d,%d): min=%d max=%d low=%d high=%d lcnt=%d rcnt=%d cnt=%d\n",L,R,
	   st[w].min,st[w].max,st[w].low,st[w].high,st[w].lcnt,st[w].rcnt,st[w].cnt);
    dump(w*2+1,L,M);
    dump(w*2+2,M,R);
  }
}

int main(){
  int N,Q;
  scanf("%d %d",&N,&Q);
  for(int i=0;i<N;i++){
    scanf("%d",&as[i]);
  }
  build(0,0,N,0,N);
  for(int i=0;i<Q;i++){
    int I,X;
    scanf("%d %d",&I,&X);
    I--;
    as[I]=X;
    build(0,0,N,I,I+1);
    printf("%d\n",st[0].cnt);
    //dump(0,0,N);
  }
}


#include <cstdio>
#include <cassert>
#include <algorithm>

const int INF=1e9+7;

struct Node{
  int min,max;
  int low,high;
  int lcnt,rcnt,cnt;
}st[2000000];
int as[500005];

//[low,high]
int query(int w,int L,int R,int& low,int& high){
  //printf("query[%d,%d): [%d,%d]\n",L,R,low,high);
  if(R-L==1){
    return as[L]>=low&&as[L]<=high;
  }
  int M=(L+R)/2;
  if(low>st[w].max) return 0;
  if(high<st[w].min) return 0;
  if(low<=st[w].min&&high>=st[w].max) return st[w].cnt;
  if(low>st[w].high){
    return query(w*2+1,L,M,low,high);
  }else if(high<st[w].low){
    return query(w*2+2,M,R,low,high);
  }else{
    high=std::max(high,st[w].high);
    low=std::min(low,st[w].low);
    int res=0;
    int ign1,ign2;
    if(high>st[w].high) res+=query(w*2+1,L,M,ign1=st[w].high+1,high);
    if(low<st[w].low) res+=query(w*2+2,M,R,low,ign2=st[w].low-1);
    if(low<=st[w].low&&high>=st[w].high&&st[w].low<=st[w].high) res++;
    //printf("query[%d,%d): [%d,%d]=%d\n",L,R,low,high,res);
    return res;
  }
}

void pull(int w,int L,int R){
  int ign1,ign2;
  assert(R-L>1);
  int M=(L+R)/2;
  st[w].min=std::min(st[w*2+1].min,st[w*2+2].min);
  st[w].max=std::max(st[w*2+1].max,st[w*2+2].max);
  st[w].high=st[w*2+2].max;
  st[w].low=st[w*2+1].min;
  //printf("pull[%d,%d)\n",L,R);
  query(w*2+1,L,M,st[w].low,st[w].high);
  query(w*2+2,M,R,st[w].low,st[w].high);
  //printf("pull[%d,%d)*\n",L,R);
  if(st[w].low<=st[w].high){
    //intersects
    st[w].lcnt=query(w*2+1,L,M,ign1=st[w].high+1,ign2=INF);
    st[w].rcnt=query(w*2+2,M,R,ign1=-INF,ign2=st[w].low-1);
    st[w].cnt=st[w].lcnt+st[w].rcnt+1;
  }else{
    st[w].lcnt=st[w*2+1].cnt;
    st[w].rcnt=st[w*2+2].cnt;
    st[w].cnt=st[w].lcnt+st[w].rcnt;
  }
}

void build(int w,int L,int R,int a,int b){
  if(a>=R||b<=L) return;
  if(R-L==1){
    st[w].min=st[w].max=as[L];
    st[w].cnt=1;
  }else{
    int M=(L+R)/2;
    build(w*2+1,L,M,a,b);
    build(w*2+2,M,R,a,b);
    pull(w,L,R);
  }
}

void dump(int w,int L,int R){
  int M=(L+R)/2;
  if(R-L>1){
    printf("[%d,%d): min=%d max=%d low=%d high=%d lcnt=%d rcnt=%d cnt=%d\n",L,R,
	   st[w].min,st[w].max,st[w].low,st[w].high,st[w].lcnt,st[w].rcnt,st[w].cnt);
    dump(w*2+1,L,M);
    dump(w*2+2,M,R);
  }
}

int main(){
  int N,Q;
  scanf("%d %d",&N,&Q);
  for(int i=0;i<N;i++){
    scanf("%d",&as[i]);
  }
  build(0,0,N,0,N);
  for(int i=0;i<Q;i++){
    int I,X;
    scanf("%d %d",&I,&X);
    I--;
    as[I]=X;
    build(0,0,N,I,I+1);
    printf("%d\n",st[0].cnt);
    //dump(0,0,N);
  }
}


#include <cstdio>
#include <cassert>
#include <algorithm>

const int INF=1e9+7;

struct Node{
  int min,max;
  int low,high;
  int lcnt,rcnt,cnt;
}st[2000000];
int as[500005];

//[low,high]
int query(int w,int L,int R,int& low,int& high){
  if(R-L==1){
    return as[L]>=low&&as[L]<=high;
  }
  int M=(L+R)/2;
  if(high>=st[w].low) high=std::max(high,st[w].high);
  if(low<=st[w].high) low=std::min(low,st[w].low);
  int res=0;
  int ign;
  if(high>st[w].high) res+=query(w*2+1,L,M,ign=st[w].high+1,high);
  if(low<st[w].low) res+=query(w*2+2,M,R,low,ign=st[w].low-1);
  if(low<=st[w].low&&high>=st[w].high&&st[w].low<=st[w].high) res++;
  return res;
}

void pull(int w,int L,int R){
  int ign1,ign2;
  assert(R-L>1);
  int M=(L+R)/2;
  st[w].min=std::min(st[w*2+1].min,st[w*2+2].min);
  st[w].max=std::max(st[w*2+1].max,st[w*2+2].max);
  st[w].high=st[w*2+2].max;
  st[w].low=st[w*2+1].min;
  query(w*2+1,L,M,st[w].low,st[w].high);
  query(w*2+2,M,R,st[w].low,st[w].high);
  if(st[w].low<=st[w].high){
    //intersects
    st[w].lcnt=query(w*2+1,L,M,ign1=st[w].high+1,ign2=INF);
    st[w].rcnt=query(w*2+2,M,R,ign1=-INF,ign2=st[w].low-1);
    st[w].cnt=st[w].lcnt+st[w].rcnt+1;
  }else{
    st[w].lcnt=st[w*2+1].cnt;
    st[w].rcnt=st[w*2+2].cnt;
    st[w].cnt=st[w].lcnt+st[w].rcnt;
  }
}

void build(int w,int L,int R,int a,int b){
  if(a>=R||b<=L) return;
  if(R-L==1){
    st[w].min=st[w].max=as[L];
    st[w].cnt=1;
  }else{
    int M=(L+R)/2;
    build(w*2+1,L,M,a,b);
    build(w*2+2,M,R,a,b);
    pull(w,L,R);
  }
}

void dump(int w,int L,int R){
  int M=(L+R)/2;
  if(R-L>1){
    printf("[%d,%d): min=%d max=%d low=%d high=%d lcnt=%d rcnt=%d cnt=%d\n",L,R,
	   st[w].min,st[w].max,st[w].low,st[w].high,st[w].lcnt,st[w].rcnt,st[w].cnt);
    dump(w*2+1,L,M);
    dump(w*2+2,M,R);
  }
}

int main(){
  int N,Q;
  scanf("%d %d",&N,&Q);
  for(int i=0;i<N;i++){
    scanf("%d",&as[i]);
  }
  build(0,0,N,0,N);
  for(int i=0;i<Q;i++){
    int I,X;
    scanf("%d %d",&I,&X);
    I--;
    as[I]=X;
    build(0,0,N,I,I+1);
    printf("%d\n",st[0].cnt);
    //dump(0,0,N);
  }
}


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

// count-min operations:
// (1) range increment
// (2) count the number of elements equal to the min

struct Node {
    int min, count, lazy;
};

Node operator*(Node a, Node b) {
    Node n;
    n.min = min(a.min + a.lazy, b.min + b.lazy);
    n.count = 0;
    if (a.min + a.lazy == n.min) {
        n.count += a.count;
    }
    if (b.min + b.lazy == n.min) {
        n.count += b.count;
    }
    n.lazy = 0;
    return n;
}

class SegmentTree {
  private:
    int N;
    vector<Node> data;

    void push(int v) {
        const int lazy = data[v].lazy;
        data[v].lazy = 0;
        data[2*v].lazy += lazy;
        data[2*v+1].lazy += lazy;
    }

    void update(int v, int l, int r, int ql, int qr, int x) {
        if (r <= ql || l >= qr) {
            return;
        }
        if (ql <= l && r <= qr) {
            data[v].lazy += x;
            return;
        }
        push(v);
        const int m = (l + r) / 2;
        update(2*v, l, m, ql, qr, x);
        update(2*v+1, m, r, ql, qr, x);
        data[v] = data[2*v] * data[2*v+1];
    }

  public:
    SegmentTree(int N) : N(N), data(4*N) {
        function<void(int, int, int)> build = [&](int v, int l, int r) {
            if (r - l == 1) {
                data[v].count = 1;
                return;
            }
            const int m = (l + r) / 2;
            build(2*v, l, m);
            build(2*v+1, m, r);
            data[v].count = data[2*v].count + data[2*v+1].count;
        };
        build(1, 0, N);
    }

    void update(int ql, int qr, int x) {
        if (qr <= ql) {
            return;
        }
        update(1, 0, N, ql, qr, x);
    }

    int query() const {
        return data[1].count;
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, q;
    cin >> n >> q;

    vector<int> array(n);
    set<pair<int, int>> vals;
    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;
        x = -x;
        array[i] = x;
        vals.insert({x, i});
    }

    SegmentTree tree(n);
    for (auto it = begin(vals); next(it) != end(vals); it++) {
        const int i = it->second;
        const int j = next(it)->second;
        tree.update(j, i, 1);
    }

    while (q--) {
        int j, x;
        cin >> j >> x;
        j--;
        x = -x;

        {
            const auto it = vals.find({array[j], j});
            const int i = it != begin(vals) ? prev(it)->second : -1;
            const int k = next(it) != end(vals) ? next(it)->second : n+1;
            tree.update(k, j, -1);
            tree.update(j, i, -1);
            tree.update(k, i, +1);
        }

        vals.erase({array[j], j});
        array[j] = x;
        vals.insert({array[j], j});

        {
            const auto it = vals.find({array[j], j});
            const int i = it != begin(vals) ? prev(it)->second : -1;
            const int k = next(it) != end(vals) ? next(it)->second : n+1;
            tree.update(k, j, +1);
            tree.update(j, i, +1);
            tree.update(k, i, -1);
        }

        cout << tree.query() << "\n";
    }
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>
#include<set>
using namespace std;
char s[100010];

int main()
{
    while(cin>>s)
    {
        int len=strlen(s),ct=0,flag=1;
        for(int i=len-10;i>=0;i--)
        {
            if(s[i]=='#') break;
            else if(s[i]=='(')  ct++;
            else if(s[i]==')')  ct--;
            if(ct>0)
            {
                flag=0;
                break;
            }
        }
        if(!flag)
        {
            cout<<"-1"<<endl;
            continue;
        }
        int m=0;
        ct=0;
        for(int i=0;i<len;i++)
        {
            if(s[i]=='#')
            {
                s[i]=')';
                m++;
            }
        }
        for(int i=0;i<len;i++)
        {
            if(s[i]=='(')  ct++;
            else ct--;
            if(ct<0)
            {
                flag=0;
                break;
            }
        }
         if(!flag)
        {
            cout<<"-1"<<endl;
            continue;
        }
        for(int i=0;i<m-1;i++)
            cout<<'1'<<endl;
        cout<<1+ct<<endl;
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
using namespace std;
const int MAX = 100009;
int ans[MAX], cnt, pSum[MAX];
string s;
vector <int> index;
int main() {
    ios::sync_with_stdio(false);
    cin >> s;
    for (int i = 0; i < s.length(); i++) {
        if (s[i] == '(') {
            pSum[i]++;
        }
        else if (s[i] == ')') {
            pSum[i]--;
        }
        else if (s[i] == '#') {
            index.push_back(i);
        }
        if (i > 0) {
            pSum[i] += pSum[i - 1];
        }
    }
    int len = s.length() - 1;
    if (pSum[len] < index.size()) {
        puts("-1");
        return 0;
    }
    for (int i = 0; i < index.size(); i++) {
        pSum[index[i]] -= 1;
    }
    pSum[len] -= index.size();
    for (int i = 0; i < index.size() && pSum[len] > 0; i++) {
        ans[i] += min(pSum[len], pSum[index[i]]);
        pSum[len] -= ans[i];
    }
    for (int i = 0; i < index.size(); i++) {
        printf("%d\n", ans[i] + 1);
    }
    puts("");
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
using namespace std;
const int MAX = 100009;
int ans[MAX], cnt, pSum[MAX];
string s;
vector <int> index;
int main() {
    ios::sync_with_stdio(false);
    cin >> s;
    for (int i = 0; i < s.length(); i++) {
        if (s[i] == '(') {
            pSum[i]++;
        }
        else if (s[i] == ')') {
            pSum[i]--;
        }
        else if (s[i] == '#') {
            index.push_back(i);
        }
        if (i > 0) {
            pSum[i] += pSum[i - 1];
        }
    }
    int len = s.length() - 1;
    if (pSum[len] < index.size()) {
        puts("-1");
        return 0;
    }
    pSum[len] -= index.size();
    for (int i = 0; i < index.size() && pSum[len] > 0; i++) {
        ans[i] += min(pSum[len], pSum[index[i]] - 1);
        pSum[len] -= ans[i];
    }
    for (int i = 0; i < index.size(); i++) {
        printf("%d\n", ans[i] + 1);
    }
    puts("");
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
using namespace std;
const int MAX = 100009;
int ans[MAX], cnt, pSum[MAX];
string s;
vector <int> index;
int main() {
    ios::sync_with_stdio(false);
    cin >> s;
    for (int i = 0; i < s.length(); i++) {
        if (s[i] == '(') {
            pSum[i]++;
        }
        else if (s[i] == ')') {
            pSum[i]--;
        }
        else if (s[i] == '#') {
            index.push_back(i);
        }
        if (i > 0) {
            pSum[i] += pSum[i - 1];
        }
    }
    int len = s.length() - 1;
    if (pSum[len] < index.size()) {
        puts("-1");
        return 0;
    }
    pSum[len] -= index.size();
    for (int i = 0; i < index.size() && pSum[len]; i++) {
        ans[i] += min(pSum[len], pSum[i]);
        pSum[len] -= ans[i];
    }
    for (int i = 0; i < index.size(); i++) {
        printf("%d\n", ans[i] + 1);
    }
    puts("");
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
using namespace std;
int main() {
    ios::sync_with_stdio(false);
    string s;
    cin >> s;
    int x = 0, p = 0, d = 0;
    for (char c : s) {
        x += c == '#';
        p += c == '(';
        p -= c == ')';
    }
    vector <int> xs;
    for (char c : s) {
        if (c == '#') {
            int a = --x ? 1 : p < 1 ? 1 : p;
            p -= a;
            d -= a;
            xs.push_back(a);
        }
        d += c == '(';
        d -= c == ')';
        if (d < 0) {
            puts("-1");
            return 0;
        }
    }
    if (d) {
        puts("-1");
    }
    else {
        for (int a : xs) {
            printf("%d\n", a);
        }
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
using namespace std;
const int MAX = 100009;
int ans[MAX], cnt, pSum[MAX];
string s;
vector <int> index;
int main() {
    ios::sync_with_stdio(false);
    cin >> s;
    for (int i = 0; i < s.length(); i++) {
        if (s[i] == '(') {
            pSum[i]++;
        }
        else if (s[i] == ')') {
            pSum[i]--;
        }
        else if (s[i] == '#') {
            pSum[i]--;
            index.push_back(i);
        }
        if (i > 0) {
            pSum[i] += pSum[i - 1];
        }
    }
    int len = s.length() - 1;
    if (pSum[len] < 0) {
        puts("-1");
        return 0;
    }
    for (int i = 0; i < index.size() && pSum[len] > 0; i++) {
        ans[i] += min(pSum[len], pSum[index[i]]);
        pSum[len] -= ans[i];
    }
    for (int i = 0; i < index.size(); i++) {
        printf("%d\n", ans[i] + 1);
    }
    puts("");
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
using namespace std;
const int MAX = 100009;
int ans[MAX], cnt, pSum[MAX];
string s;
vector <int> index;
int main() {
    ios::sync_with_stdio(false);
    cin >> s;
    for (int i = 0; i < s.length(); i++) {
        if (s[i] == '(') {
            pSum[i]++;
        }
        else if (s[i] == ')') {
            pSum[i]--;
        }
        else if (s[i] == '#') {
            index.push_back(i);
        }
        if (i > 0) {
            pSum[i] += pSum[i - 1];
        }
    }
    int len = s.length() - 1;
    if (pSum[len] < index.size()) {
        puts("-1");
        return 0;
    }
    pSum[len] -= index.size();
    for (int i = 0; i < index.size() && pSum[len] > 0; i++) {
        ans[i] += min(pSum[len], pSum[index[i]]);
        pSum[len] -= ans[i];
    }
    for (int i = 0; i < index.size(); i++) {
        printf("%d\n", ans[i] + 1);
    }
    puts("");
    return 0;
}


    #include<bits/stdc++.h>

    using namespace std ;
    int main()
    {
        int ttl =0 ,cl=0,shbak=0,last=-1;;
        string s ;
        cin >> s;
        for(int i = 0 ; i<s.size() ;i++)
        {
            if(s[i]=='(')
                ++ttl;
            else
                --ttl;
            if(ttl<0)
            {
                cout<<"-1"<<endl;
                return 0 ;
            }
            if(s[i] =='#')
                last=i;
        }
        ++ttl;
        for(int i = 0 ; i < s.size() ; i++)
        {
            if(s[i] =='#'&&i!=last)
                cout<<1<<endl;
            else if(s[i]=='#')
                cout<<ttl;

        }
        return 0 ;
    }


    #include<bits/stdc++.h>

    using namespace std ;
    int main()
    {
        int ttl =0 ,cl=0,shbak=0,last=-1,temp=0;
        string s ;
        cin >> s;
        for(int i = 0 ; i<s.size() ;i++)
        {
            if(s[i]=='(')
                ++ttl;
            else
                --ttl;
            if(ttl<0)
            {
                cout<<"-1"<<endl;
                return 0 ;
            }
            if(s[i] =='#')
                last=i;
        }
        ++ttl;
        for(int i = 0 ; i < s.size() ; i++){
            temp+= i==last? -ttl : (s[i]=='('?1:-1);
            if(temp<0)
            {
                cout<<"-1"<<endl;
                return 0 ;
            }
        }

        for(int i = 0 ; i < s.size() ; i++)
        {
            if(s[i] =='#'&&i!=last)
                cout<<1<<endl;
            else if(s[i]=='#')
                cout<<ttl;

        }
        return 0 ;
    }


    #include<bits/stdc++.h>

    using namespace std ;
    int main()
    {
        int ttl =0 ,cl=0,shbak=0,last=-1,temp=0;
        string s ;
        cin >> s;
        for(int i = 0 ; i<s.size() ;i++)
        {
            if(s[i]=='(')
                ++ttl;
            else
                --ttl;
            if(ttl<0)
            {
                cout<<"-1"<<endl;
                return 0 ;
            }
            if(s[i] =='#')
                last=i;
        }
        for(int i = last ; i < s.size() ; i++){
            if(s[i]=='(')
                ++temp;
            else
                --temp;
            if(temp<0)
            {
                cout<<"-1"<<endl;
                return 0 ;
            }
        }

        ++ttl;
        for(int i = 0 ; i < s.size() ; i++)
        {
            if(s[i] =='#'&&i!=last)
                cout<<1<<endl;
            else if(s[i]=='#')
                cout<<ttl;

        }
        return 0 ;
    }


    #include<bits/stdc++.h>

    using namespace std ;
    int main()
    {
        int ttl =0 ,cl=0,shbak=0,last=-1,temp=0;
        string s ;
        cin >> s;
        for(int i = 0 ; i<s.size() ;i++)
        {
            if(s[i]=='(')
                ++ttl;
            else
                --ttl;
            if(ttl<0)
            {
                cout<<"-1"<<endl;
                return 0 ;
            }
            if(s[i] =='#')
                last=i;
        }
        ++ttl;
        for(int i = 0 ; i < s.size() ; i++){
            temp+= i==last? -last : (s[i]=='('?1:-1);
            if(temp<0)
            {
                cout<<"-1"<<endl;
                return 0 ;
            }
        }

        for(int i = 0 ; i < s.size() ; i++)
        {
            if(s[i] =='#'&&i!=last)
                cout<<1<<endl;
            else if(s[i]=='#')
                cout<<ttl;

        }
        return 0 ;
    }


    #include<bits/stdc++.h>

    using namespace std ;
    int main()
    {
        int ttl =0 ,cl=0,shbak=0,last=-1,temp=0;
        string s ;
        cin >> s;
        for(int i = 0 ; i<s.size() ;i++)
        {
            if(s[i]=='(')
                ++ttl;
            else
                --ttl;
            if(ttl<0)
            {
                cout<<"-1"<<endl;
                return 0 ;
            }
            if(s[i] =='#')
                last=i;
        }
        ++ttl;
        for(int i = 0 ; i < s.size() ; i++){
            temp+= i==last? -last : (s[i]=='('?1:-1);
            if(ttl<0)
            {
                cout<<"-1"<<endl;
                return 0 ;
            }
        }

        for(int i = 0 ; i < s.size() ; i++)
        {
            if(s[i] =='#'&&i!=last)
                cout<<1<<endl;
            else if(s[i]=='#')
                cout<<ttl;

        }
        return 0 ;
    }


#include<bits/stdc++.h>

using namespace std ;
int main()
{
    int op =0 ,cl=0;
    string s ;
    cin >> s;
    for(int i = 0 ; i<s.size() ;i++)
    {
        if(s[i]=='(')
            ++op;
        else if(s[i]==')')
            ++cl;
        if(cl > op)
        {
            cout<<"-1"<<endl;
            return 0 ;
        }
    }
    if(cl == op)
    {
        cout<<"-1"<<endl;
        return 0 ;
    }
    op=0,cl=0;
    for(int i = 0 ; i<s.size() ;i++)
    {
        if(s[i]=='(')
            ++op;
        else if(s[i]=='#')
        {
            ++i;
           // cout<<op<<endl;
            while(s[i]==')')
            {
                ++cl;
                ++i;
            }
            --i;
            cout<<op-cl<<" ";
            op=0;
            cl=0;
        }
        else
            ++cl;
    }

    return 0 ;
}


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

char s[100005];
int tot,fl,cnt,fl2;

int main()
{
    scanf("%s",s+1);
    int n=strlen(s+1);
    if(n==1&&s[1]=='#') {puts("-1"); return 0;}
    for(int i=1;i<=n;++i)
    {
        if(s[i]=='(') ++fl;
        else if(s[i]==')') --fl;
        else ++tot,--fl;
    }
    for(int i=1;i<=n;++i)
    {
        if(s[i]=='(') ++fl2;
        else if(s[i]==')') --fl2;
        else
        {
            ++cnt;
            fl2-=cnt==tot?fl+1:1;
        }
        if(fl2<0) {puts("-1"); return 0;}
    }
    if(fl2!=0) {puts("-1"); return 0;}
    for(int i=1;i<tot;++i) puts("1");
    printf("%d\n",fl+1);
    return 0;
}


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

char s[100005];
int tot,fl,cnt,fl2;

int main()
{
    scanf("%s",s+1);
    int n=strlen(s+1);
    for(int i=1;i<=n;++i)
    {
        if(s[i]=='(') ++fl;
        else if(s[i]==')') --fl;
        else ++tot,--fl;
    }
    if(fl<0) {puts("-1"); return 0;}
    for(int i=1;i<=n;++i)
    {
        if(s[i]=='(') ++fl2;
        else if(s[i]==')') --fl2;
        else
        {
            ++cnt;
            fl2-=cnt==tot?fl+1:1;
        }
        if(fl2<0) {puts("-1"); return 0;}
    }
    if(fl2!=0) {puts("-1"); return 0;}
    for(int i=1;i<tot;++i) puts("1");
    printf("%d\n",fl+1);
    return 0;
}


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

char s[100005];
int tot,fl,cnt,fl2;

int main()
{
    scanf("%s",s+1);
    int n=strlen(s+1);
    for(int i=1;i<=n;++i)
    {
        if(s[i]=='(') ++fl;
        else if(s[i]==')') --fl;
        else ++tot,--fl;
    }
    for(int i=1;i<=n;++i)
    {
        if(s[i]=='(') ++fl2;
        else if(s[i]==')') --fl2;
        else
        {
            ++cnt;
            fl2-=cnt==tot?fl+1:1;
        }
        if(fl2<0) {puts("-1"); return 0;}
    }
    if(fl2!=0) {puts("-1"); return 0;}
    for(int i=1;i<tot;++i) puts("1");
    printf("%d\n",fl+1);
    return 0;
}


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

char s[100005];
int tot,fl;

int main()
{
    scanf("%s",s+1);
    int n=strlen(s+1);
    for(int i=1;i<=n;++i)
    {
        if(s[i]=='(') ++fl;
        else --fl;
        if(s[i]=='#') ++tot;
        if(fl<0) {puts("-1"); return 0;}
    }
    for(int i=1;i<tot;++i) puts("1");
    printf("%d\n",fl+1);
    return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define eb emplace_back
#define fr first
#define sc second
#define mk make_pair
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
const double eps = 0.000000001;
const int MOD = 1000000007;
const int N = 100005;
string s;
stack <int> st;
vector <int> ans;
int main()
{
      ios::sync_with_stdio(false);
      cin >> s;
      for (int i = 0; i < (int)s.size(); i ++)
      {
            if (s[i] == '(') st.push(i);
            else if (s[i] == ')')
            {
                  if (st.size() == 0)
                  {
                        printf("-1\n");
                        return 0;
                  }
                  st.pop();
            }
            else
            {
                  ans.pb(1);
                  if (st.size() == 0)
                  {
                        printf("-1\n");
                        return 0;
                  }
                  st.pop();
            }
      }
      bool f = false;
      for (int i = st.top(); i < (int)s.size(); i ++)
            if (s[i] == '#') f = true;
      if (!f)
      {
            printf("-1\n");
            return 0;
      }
      ans.back() += st.size();
      for (int i = 0; i < (int)ans.size(); i ++)
            cout << ans[i] << endl;
      return 0;
}


# include <bits/stdc++.h>

# define pb push_back
# define fr first
# define sc second
# define mk make_pair

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int IMX = (1 << 31) - 1;
const ll LMX = (1ll << 63) - 1;
const ld PI = 3.141592653589793;
const int eps = 1e-10;
const int base = 1e9;
const int N = 400005;

int main() {
    vector <int> v;
    string s;
    cin >> s;
    int ans = 0;
    for (int i = 0; i < s.size(); i ++) {
        if (s[i] == '(') ans ++;
        else if (s[i] == ')') {
            if (ans == 0) {
                cout << -1 << endl;
                return 0;
            }
            ans --;
        }
        else if (s[i] == '#') {
            while (i + 1 < s.size() && s[i + 1] == ')') ans --, i ++;
            if (ans <= 0) {
                cout << -1 << " 0" << endl;
                return 0;
            }
            v.pb(ans);
            ans = 0;
        }
    }
    if (ans > 0) cout << -1 << endl;
    else for (int i = 0; i < v.size(); i ++) cout << v[i] << endl;
    return 0;
}


# include <bits/stdc++.h>

# define pb push_back
# define fr first
# define sc second
# define mk make_pair

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int IMX = (1 << 31) - 1;
const ll LMX = (1ll << 63) - 1;
const ld PI = 3.141592653589793;
const int eps = 1e-10;
const int base = 1e9;
const int N = 400005;

int main() {
    vector <int> v;
    string s;
    cin >> s;
    int ans = 0;
    for (int i = 0; i < s.size(); i ++) {
        if (s[i] == '(') ans ++;
        else if (s[i] == ')') {
            if (ans == 0) {
                cout << -1 << endl;
                return 0;
            }
            ans --;
        }
        else if (s[i] == '#') {
            if (ans == 0) {
                cout << -1 << endl;
                return 0;
            }
            v.pb(ans);
            ans = 0;
        }
    }
    if (ans > 0) cout << -1 << endl;
    else for (int i = 0; i < v.size(); i ++) cout << v[i] << endl;
    return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define eb emplace_back
#define fr first
#define sc second
#define mk make_pair
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
const double eps = 0.000000001;
const int MOD = 1000000007;
const int N = 100005;
string s;
stack <int> st;
vector <int> ans;
int main()
{
      ios::sync_with_stdio(false);
      cin >> s;
      for (int i = 0; i < (int)s.size(); i ++)
      {
            if (s[i] == '(') st.push(i);
            else if (s[i] == ')')
            {
                  if (st.size() == 0)
                  {
                        printf("-1\n");
                        return 0;
                  }
                  st.pop();
            }
            else
            {
                  ans.pb(1);
                  if (st.size() == 0)
                  {
                        printf("-1\n");
                        return 0;
                  }
                  st.pop();
            }
      }
      bool f = false;
      if (st.size() == 0) f = true;
      else
      for (int i = st.top(); i < (int)s.size(); i ++)
            if (s[i] == '#') f = true;
      if (!f)
      {
            printf("-1\n");
            return 0;
      }
      ans.back() += st.size();
      for (int i = 0; i < (int)ans.size(); i ++)
            cout << ans[i] << endl;
      return 0;
}


# include <bits/stdc++.h>

# define pb push_back
# define fr first
# define sc second
# define mk make_pair

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int IMX = (1 << 31) - 1;
const ll LMX = (1ll << 63) - 1;
const ld PI = 3.141592653589793;
const int eps = 1e-10;
const int base = 1e9;
const int N = 400005;

int main() {
    vector <int> v;
    string s;
    cin >> s;
    int ans = 0;
    for (int i = 0; i < s.size(); i ++) {
        if (s[i] == '(') ans ++;
        else if (s[i] == ')') {
            if (ans == 0) {
                cout << -1 << endl;
                return 0;
            }
            ans --;
        }
        else if (s[i] == '#') {
            while (i + 1 < s.size() && s[i + 1] == ')') ans --, i ++;
            if (ans <= 0) {
                cout << -1 << endl;
                return 0;
            }
            v.pb(ans);
            ans = 0;
        }
    }
    if (ans > 0) cout << -1 << endl;
    else for (int i = 0; i < v.size(); i ++) cout << v[i] << endl;
    return 0;
}


# include <bits/stdc++.h>

# define f(i,a,b) for (int i = a; i <= b; i++)
# define _f(i,a,b) for (int i = a; i >= b; i--)
using namespace std;
stack <int> q;
int ans[100001],u,p;

int main() {
	char s[100001];
	scanf("%s", s);
	int t = strlen(s);
	bool flag = false;
	f(i,0,t - 1) {
		if (s[i] == '(') {
			q.push(1);
			continue;
		}
		if (s[i] == ')') {
			if (q.empty()) {
				printf("-1\n");
				return 0;
			}
			q.pop();
			continue;
		}
		if (s[i] == '#') p = i;
	}
	if (q.empty()) {
		printf("-1\n");
		return 0;
	}
	while (!q.empty()) q.pop();
	f(i,0,t - 1) {
		if (s[i] == '(') {
			q.push(1);
			continue;
		}
		if (s[i] == ')') {
			if (q.empty()) {
				printf("-1\n");
				return 0;
			}
			q.pop();
			continue;
		}
		if (s[i] == '#' && i != p) {
			q.pop();
			ans[++u] = 1;
		}
		if (i == p) {
			int m = 0;
			while (!q.empty()) {
				q.pop();
				m++;
			}
			f(j,1,m) q.push(1);
			f(j,i + 1,t - 1) {
				if (s[j] == '(') {
					q.push(1);
					continue;
				}
				if (s[j] == ')') {
					if (q.empty()) {
						printf("-1\n");
						return 0;
					}
					q.pop();
					continue;
				}
			}
			int sum = 0;
			while (!q.empty()) {
				q.pop();
				sum++;
			}
			if (sum) {
				ans[++u] = sum;
				if (sum > m) {
					printf("-1\n");
					return 0;
				}
			}
			else {
				printf("-1\n");
				return 0;
			}
			break;
		}
	}
	f(i,1,u) printf("%d\n", ans[i]);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<algorithm>
#include<queue>
using namespace std;
string a;
char s[10000010];
int n,m,k,b;
int main()
{
	getline(cin,a);
	for(int i=0;i<a.length();i++)
	{
		if(a[i]=='(')
		{
			n++;
		}
		if(a[i]==')')
		{
			m++;
		}
		if(a[i]=='#')
		{
			b++;
		}
	}
	if(n<m||n<m+b||a[a.length()-1]=='('||a[0]==')'||a[0]=='#')
	{
		cout<<-1;
		return 0;
	}
	k=n-m;
	for(int i=1;i<b;i++)
	{
		cout<<1<<endl;
	}
	cout<<k-b+1;
	return 0;
}


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
int main(){
	string s;
    cin>>s;
    int lef=0,rig=0,mid=0,sum=0;
    for(int i=0;i<s.length();i++){
        if(s[i]=='#'){
        	mid++;
        	rig++;
        	if(rig>lef){
        		cout<<-1<<endl;
        		return 0;
			}
		}
        if(s[i]=='(') lef++;
        if(s[i]==')') rig++;
    }
    if(rig>lef){
    	cout<<-1<<endl;
    	return 0;
	}
    int ans=0;
    lef=rig=0;
    for(int i=0;i<s.length();i++){
        if(s[i]=='#'){
        	sum++;
        	if(sum==mid){
        		for(int j=i+1;j<s.length();j++){
        			if(s[j]=='(') ans++;
        			if(s[j]==')') ans--;
				}
				if(ans>0){
					cout<<-1<<endl;
					return 0;
				}
				break;
			}
        }
        if(s[i]=='(') lef++;
        if(s[i]==')') rig++;
    }
    if(lef-rig-mid+1+ans<=0){
    	cout<<-1<<endl;
    	return 0;
	}
    for(int i=1;i<mid;i++) cout<<"1"<<endl;
    cout<<lef-rig-mid+1+ans<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define _for(i,a,b) for(int i=a;i<b;i++)
using namespace std;
char c;
stack<char> s;
vector<int> ans;
int main(){
	ios::sync_with_stdio(0);
	while((c=getchar())!=EOF){
		switch(c){
			case '(':
				s.push(c);
				break;
			case ')':
				if(s.empty()){
					cout<<-1;
					return 0;
				}else
					s.pop();
				break;
			case '#':
				if(s.empty()){
					cout<<-1;
					return 0;
				}else{
					ans.push_back(1);
					s.pop();
				}
				break;
		}
	}
	if(!s.empty()){
		for(auto iter=ans.begin();iter!=ans.end();iter++)
			if(iter!=ans.end()-1) cout<<*iter<<"\n";
			else cout<<(*iter+s.size());
	}else if(s.empty())
		cout<<-1;
	return 0;
}


#include<bits/stdc++.h>
#define MAXN 10005
#define LL long long
using namespace std;
//int a[MAXN];
string a;
int cha,ge,cha2;
int main()
{
	//freopen("train.in","r",stdin);
	//freopen("train.out","w",stdout);
	cin>>a;
	for(int i=0;i<a.length();i++)
	{
		if(a[i]=='(')
		{
			cha++;
		}
		if(a[i]==')' || a[i]=='#')
		{
			cha--;
		}
		if(a[i]=='#')
		{
			ge++;
		}
		if(cha<0)
		{
			cout<<-1;
			return 0;
		}
	}
	cout<<cha<<endl;
	int k=0;
	for(int i=0;i<a.length();i++)
	{
		if(a[i]=='(')
		{
			cha2++;
		}
		if(a[i]==')')
		{
			cha2--;
		}
		if(a[i]=='#')
		{
			k++;
			if(k==ge)
			{
				cha2=cha2-cha;
			}
			cha2--;
		}
		if(cha2<0)
		{
			cout<<-1;
			return 0;
		}
	}
	for(int i=0;i<k-1;i++)
	{
		cout<<1<<endl;
	}
	cout<<cha+1;
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<algorithm>
#include<queue>
using namespace std;
string a;
char s[100010];
int n,m,k,b;
int main()
{
	getline(cin,a);
	for(int i=0;i<a.length();i++)
	{
		if(a[i]=='(')
		{
			n++;
		}
		if(a[i]==')')
		{
			m++;
		}
		if(a[i]=='#')
		{
			b++;
		}
	}
	if(n==m||n<m)
	{
		cout<<-1;
		return 0;
	}
	k=n-m;
	for(int i=1;i<b;i++)
	{
		cout<<1<<endl;
	}
	cout<<k-b+1;
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<algorithm>
#include<queue>
using namespace std;
string a;
int n,m,k,b,c;
int main()
{
	getline(cin,a);
	for(int i=0;i<a.length();i++)
	{
		if(a[i]=='(')
		{
			n++;
			c++;
		}
		if(a[i]==')')
		{
		    c--;
			m++;
		}
		if(a[i]=='#')
		{
		    c--;
			b++;
		}
		if(c<0)
		{
        cout<<-1;
        return 0;
		}
	}
	if(n<m||n<m+b||a[a.length()-1]=='('||a[0]==')'||a[0]=='#')
	{
		cout<<-1;
		return 0;
	}
	k=n-m;
	for(int i=1;i<b;i++)
	{
		cout<<1<<endl;
	}
	cout<<k-b+1;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
char x[1000001];
int main()
{
	int n,i,j,k,ans=0;
	gets(x);
	int l=strlen(x);

	for(i=0;i<l;i++)
	{
		if(x[i]=='(') ans++;
		if(x[i]==')') ans--;
		if(x[i]=='#')
		{
			for(j=i+1;j<l;j++)
			{
				if(x[j]==')')ans--;
				else break;
				//cout<<ans<<" ";
			}
			if(ans>0)cout<<ans<<endl,ans=0;
			else cout<<"-1"<<endl;
			i=j-1;
		}
	}
	return 0;
}


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

int a[10000000];

int main(){
	string s;
	int i,j,m,n,t = 0,k = 0;
	cin >> s;
	for(i=0;i<s.length();i++){
		if(s[i]=='(')t++;
		else if(s[i]==')')t--;
		else{
			j = i+1;
			m = 0;
			while(s[j]==')'){
				m++;
				j++;
			}
			//cout << t << "  " << m << endl;
			if(t-m>0){
				k++;
				a[k] = t-m;
				t = m;
			}
			else{
				printf("-1");
				return 0;
			}
		}
	}
	for(i=1;i<=k;i++){
		printf("%d\n",a[i]);
	}
	return 0;
}


#pragma GCC optimize(2)
#include<cstdio>
#include<vector>
using std::vector;
vector<int>a;
char ch;
int now,siz;
int main()
{
    int cnt=0;
    while((ch=getchar())!=EOF)
    if(ch=='(')cnt++;
    else if(ch==')')
    {cnt--;if(cnt<0){while(now<siz)if(a[now]>1){a[now]--;cnt++;break;}else now++;}if(cnt<0)return puts("-1"),0;}
    else if(ch=='#'){siz++;if(!cnt)return puts("-1"),0;a.push_back(cnt);cnt=0;}
    else if(ch<=15)break;
    if(ch!=0)return puts("-1"),0;
    for(int i=0;i<siz;i++)printf("%d\n",a[i]);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<iomanip>
#include<queue>
using namespace std;
int main(){
	char z[500050];
	cin>>z;
	int len=strlen(z);
	queue<char> q;
	int sum=0;
	for(int i=0;i<len;i++)
	{
		if(z[i]=='(')
		{
			q.push('(');
		}
		else if(z[i]==')')
		{
			if(q.empty())
			{
				cout<<-1;
				return 0;
			}
			else
			{
				q.pop();
			}
		}
		else if(z[i]=='#')
		{
			sum++;
		}
		/*else if(z[i]=='#')
		{
			if(q.empty())
			{
				cout<<-1;
				return 0;
			}
			else
			{
				cout<<1;
				q.pop();
			}
		}*/
	}
	int r=q.size();
	if(r<sum)
	{
		cout<<-1;
		return 0;
	}
	else
	{
		for(int i=1;i<sum;i++)
		{
			cout<<1<<endl;

		}
		cout<<q.size()-sum+1;
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<algorithm>
#include<queue>
using namespace std;
string a;
int n,m,k,b,c;
int main()
{
	getline(cin,a);
	for(int i=0;i<a.length();i++)
	{
		if(a[i]=='(')
		{
			n++;
			c=n;
		}
		if(a[i]==')')
		{
		    c--;
			m++;
		}
		if(a[i]=='#')
		{
		    c--;
			b++;
		}
		if(c<0)
		{
        cout<<-1;
        return 0;
		}
	}
	if(n<m||n<m+b||a[a.length()-1]=='('||a[0]==')'||a[0]=='#')
	{
		cout<<-1;
		return 0;
	}
	k=n-m;
	for(int i=1;i<b;i++)
	{
		cout<<1<<endl;
	}
	cout<<k-b+1;
	return 0;
}


#pragma GCC optimize(2)
#include<cstdio>
#include<vector>
using std::vector;
vector<int>a;
char ch;
int now,siz;
int main()
{
    int cnt=0;
    while((ch=getchar())!=EOF)
    if(ch=='(')cnt++;
    else if(ch==')')
    {cnt--;if(cnt<0){while(now<siz)if(a[now]>1){a[now]--;cnt++;break;}else now++;if(cnt<0)return puts("-1"),0;}}
    else if(ch=='#'){if(!cnt){while(now<siz)if(a[now]>1){a[now]--;cnt++;break;}else now++;if(!cnt)return puts("-1"),0;}siz++;a.push_back(cnt);cnt=0;}
    else if(ch<=15)break;
    if(cnt!=0)return puts("-1"),0;
    for(int i=0;i<siz;i++)printf("%d\n",a[i]);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<algorithm>
#include<queue>
using namespace std;
string a;
char s[10000010];
int n,m,k,b;
int main()
{
	getline(cin,a);
	for(int i=0;i<a.length();i++)
	{
		if(a[i]=='(')
		{
			n++;
		}
		if(a[i]==')')
		{
			m++;
		}
		if(a[i]=='#')
		{
			b++;
		}
	}
	if(n<=m||n<m+b||a[a.length()-1]=='('||a[0]==')'||a[0]=='#')
	{
		cout<<-1;
		return 0;
	}
	k=n-m;
	for(int i=1;i<b;i++)
	{
		cout<<1<<endl;
	}
	cout<<k-b+1;
	return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
char s[300000],n=0;
int main()
{
    int t=0;
    int b=0;
    scanf("%s",s);
    int l=strlen(s);
    for(int i=0;i<l;i++)
    {
        if(s[i]=='(') t++;
        if(s[i]=='#') {if(n==-1) {printf("-1\n");return 0;}else {if(b==1) {printf("1\n");t--;}if(t==0) {printf("-1\n");b=0;} if(t>0) b=1;}}
        if(s[i]==')') {t--;if(t<0) n=-1;}
    }
     if(t>0&&b==1&&n!=-1) printf("%d\n",t);
     else if(b==1) printf("-1\n");
    return 0;
}


# include <queue>
# include <stack>
# include <cstdio>
# include <vector>
# include <cstring>
# include <algorithm>
# define F(i, a, b) for (int i = a; i < b; i++)
using namespace std;
char s[10000050];
int main(){
	scanf("%s", &s);
	int l = strlen(s), now = 0, num = 0, t = 0, n = 0;
	F(i, 0, l){
		if (s[i] == '(') now++;
		if (s[i] == ')') now--;
		if (s[i] == '#'){
			now--;
			num++;
		}
		if (now < 0){
			printf("-1\n");
			return 0;
		}
	}
	F(i, 0, l){
		if (s[i] == '(') n++;
		if (s[i] == ')') n--;
		if (s[i] == '#'){
			t++;
			if (t == num) n -= now;
			n--;
		}
		if (n < 0){
			printf("-1\n");
			return 0;
		}
	}
	F(i, 0, num - 1) printf("1\n");
	printf("%d\n", now + 1);
	return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
char s[300000],n=0;
int main()
{
    int t=0;int p=0;
    int b=0;
    scanf("%s",s);
    int l=strlen(s);
    for(int i=0;i<l;i++)
    {
        if(s[i]=='(') t++;
        if(s[i]=='#')
        {
             p++;t--;n=i;if(t<0) {printf("-1\n");return 0;}
        }
        if(s[i]==')') {t--;if(t<0) {printf("-1\n");return 0;}}
    }
    int m=0;
    for(int i=n+1;i<l;i++)
    {
        if(s[i]=='(') m++;
        if(s[i]==')') m--;
    }if(m>0) {printf("\n");return 0;}
    for(int i=1;i<p;i++)
        printf("1\n");
    printf("%d\n",t+1);
    return 0;
}


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
char a[100005];
int len;
int main(){
	scanf("%s",a);
	len=strlen(a);
	int lef=0,rig=0,mid=0;
	for(int i=0;i<len;i++){
		if(a[i]=='(')	lef++;
		if(a[i]=='#')	mid++;
		if(a[i]==')')	rig++;
	}
	if(lef<mid+rig){
		printf("-1\n");
		return 0;
	}
	for(int i=0;i<mid-1;i++){
		printf("1\n");
	}
	for(int i=len-1;i>=1;i--){
		if(a[i]=='(')	lef--;
		if(a[i]==')')	rig--;
		if(a[i]=='#')	break;
	}
	int sum=lef-rig-(mid-1);
	printf("%d\n",sum);
	return 0;
}


#include <cstdio>
#include <iostream>
#include <cmath>

using namespace std;

string s;
int a, b;
int len;

int main(void)
{
	cin >> s;
int n = s.length();
	int w[n+10];
	for(int i=0; i<s.length(); i++)
	{
		if(s[i] == '(')
		{
			a++;
		}
		else if(s[i] == '#')
		{
			w[++len] = 1;
			a--;
		}
		else if(s[i] == ')')
		{
			a--;
		}
		if(a < 0)
		{
			cout << -1 << endl;
			return 0;
		}
	}
	for(int i=s.length()-1; i>=0; i--)
	{
		if(s[i] == ')')
		{
			b++;
		}
		else if(s[i] == '(')
		{
			b--;
		}
		else if(s[i] == '#')
		{
			break;
		}
		if(b < 0)
		{
			cout << -1 << endl;
			return 0;
		}
	}
	w[len] += a;
	for(int i=1; i<=len; i++)
	{
		cout << w[i] << endl;
	}

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
queue<int>q;
stack<char>p;
int main()
{
    int zuo=0,you=0;

    int y=0;
    string s;
    getline(cin,s);
    for(int i=0;i<s.size()/2;i++){
    if(s[i]=='('&&s[i+1]=='('&&s[s.size()-1-i]==')'&&s[s.size()-2-i]!='(') y++;
    else break;
    }
    for(int i=s.size()-1-y;i>=y;i--) p.push(s[i]);
    while(!p.empty()){
        if(!p.empty()&&p.top()=='('){
             zuo++;
			 p.pop();
        }
        if(!p.empty()&&p.top()==')'){
            you++;
            p.pop();
        }
        if(you>zuo){
        cout<<-1;
        return 0;
        }
        if(!p.empty()&&p.top()=='#'){
        p.pop();
            int duo=zuo-you;
            if(duo<=0){
                cout<<-1;
                return 0;
            }
            int t=0;
            while(!p.empty()&&p.top()!='('&&p.top()!='#'){
                t++;
                p.pop();
                if(duo-t<=0){
                    cout<<-1;
                    return 0;
                }
            }
            q.push(duo-t);
            zuo=0;
            you=0;
        }
        if(you>zuo) {
           cout<<-1;
           return 0;
        }
    }
	while(!q.empty()){
	  cout<<q.front()<<endl;
	  q.pop();
	}
	return 0;
}
// ((((#((#())


# include <bits/stdc++.h>

# define f(i,a,b) for (int i = a; i <= b; i++)
# define _f(i,a,b) for (int i = a; i >= b; i--)
using namespace std;
stack <int> q;
int ans[100001],u,p;

int main() {
	char s[100001];
	scanf("%s", s);
	int t = strlen(s);
	if (s[0] == '#') {
		printf("-1\n");
		return 0;
	}
	bool flag = false;
	f(i,0,t - 1) {
		if (s[i] == '(') {
			q.push(1);
			continue;
		}
		if (s[i] == ')') {
			if (q.empty()) {
				printf("-1\n");
				return 0;
			}
			q.pop();
			continue;
		}
		if (s[i] == '#') p = i;
	}
	if (q.empty()) {
		printf("-1\n");
		return 0;
	}
	while (!q.empty()) q.pop();
	f(i,0,t - 1) {
		if (s[i] == '(') {
			q.push(1);
			continue;
		}
		if (s[i] == ')') {
			if (q.empty()) {
				printf("-1\n");
				return 0;
			}
			q.pop();
			continue;
		}
		if (s[i] == '#' && i != p) {
			q.pop();
			ans[++u] = 1;
		}
		if (i == p) {
			int m = 0;
			while (!q.empty()) {
				q.pop();
				m++;
			}
			f(j,1,m) q.push(1);
			f(j,i + 1,t - 1) {
				if (s[j] == '(') {
					q.push(1);
					continue;
				}
				if (s[j] == ')') {
					if (q.empty()) {
						printf("-1\n");
						return 0;
					}
					q.pop();
					continue;
				}
			}
			int sum = 0;
			while (!q.empty()) {
				q.pop();
				sum++;
			}
			if (sum) {
				ans[++u] = sum;
				if (sum > m) {
					printf("-1\n");
					return 0;
				}
			}
			else {
				printf("-1\n");
				return 0;
			}
		}
	}
	f(i,1,u) printf("%d\n", ans[i]);
	return 0;
}


#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
string s;
int a,b;
int len;
int main(void)
{
	cin>>s;
	int w[s.length()+10];
	for(int i=0;i<s.length();i++)
	{
		if(s[i]=='(')
		{
			a++;
		}
		else if(s[i]=='#')
		{
			w[++len]=1;
			a--;
		}
		else if(s[i]==')')
		{
			a--;
		}
		if(a<0)
		{
			cout<<-1;
			return 0;
		}
	}
	for(int i=s.length()-1;i>=0;i--)
	{
		if(s[i]==')')
		{
			b++;
		}
		else if(s[i]=='(')
		{
			b--;
		}
		else if(s[i]=='#')
		{
			break;
		}
		if(b<0)
		{
			cout<<-1;
			return 0;
		}
	}
	w[len]+=a;
	for(int i=1;i<=len;i++)
	{
		cout<<w[i]<<endl;
	}
	return 0;
}