#include <bits/stdc++.h>
using namespace std;
#define TRACE(x) x
#define WATCH(x) TRACE(cout << #x" = " << x << endl)
#define WATCHR(a, b) TRACE(for (auto it=a; it!=b;) cout << *(it++) << " "; cout << endl)
#define WATCHC(V) TRACE({cout << #V" = "; WATCHR(V.begin(), V.end());})

#define sz(x) int((x).size())
#define all(x) (x).begin(), (x).end()

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vb = vector<bool>;
using vd = vector<double>;
using vs = vector<string>;

template<typename T> void ckmin(T& a, const T& b) { a = min(a, b); }
template<typename T> void ckmax(T& a, const T& b) { a = max(a, b); }

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

/*
 * Supports O(logS) range queries and updates on an array of items.
 * Requires that type T's combine operator is associative and
 * that T() + t = t + T() = t for all T t.
 */
template<typename T> struct seg_tree {
    int S;
    vector<T> value;

    seg_tree<T>(int S) : S(S) {
        value.resize(2 * S);
    }

    // Rebuilds all non-leaf layers of the tree in O(S)
    void rebuild() {
        for (int i = S - 1; i > 0; i--)
            value[i] = value[2 * i] + value[2 * i + 1];
    }

    // Replaces the value at index i with v in O(logS)
    void upd(int i, T v) {
        i += S;
        value[i] = v;
        while (i > 1) {
            i /= 2;
            value[i] = value[2 * i] + value[2 * i + 1];
        }
    }

    // Returns the sum of the values at indices [i, j] in O(logS)
    T query(int i, int j) {
        T res_left, res_right;
        for (i += S, j += S; i <= j; i /= 2, j /= 2) {
            if ((i&1) == 1) res_left = res_left + value[i++];
            if ((j&1) == 0) res_right = value[j--] + res_right;
        }
        return res_left + res_right;
    }
};

template<typename T> struct full_seg_tree : seg_tree<T> {
    int _S;
    full_seg_tree<T>(int _S) : _S(_S), seg_tree<T>(1 << (32 - __builtin_clz(_S - 1))) { }

    /*
     * Returns in O(logS) the first index i such that pred(query(0, i)) evaluates to true.
     * Returns S if no such i exists.
     * Requires that pred(query(0, i)) is non-decreasing in i.
     */
    int lower_bound(function<bool(T)> pred) {
        if (!pred(this->value[1])) return this->_S;
        T pref;
        int v = 1;
        for (int i = 0, j = this->S - 1; v < this->S; ) {
            int m = (j + i) / 2;
            if (pred(pref + this->value[2 * v])) {
                j = m;
                v = 2 * v;
            } else {
                pref = pref + this->value[2 * v];
                i = m + 1;
                v = 2 * v + 1;
            }
        }
        return v - this->S;
    }
};

struct mint {
    int v;
    mint(int v = INT_MAX) : v(v) {}
    mint operator +(const mint& o) { return mint(min(v, o.v)); }
    mint operator -(const mint& o) { assert(false); }
};

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    int N;
    cin >> N;

    vi targ(N);
    for (int i = 0; i < N; i++) {
        cin >> targ[i];
    }

    int Q;
    cin >> Q;
    vvi ops(N);
    for (int q = 0, l, r; q < Q; q++) {
        cin >> l >> r;
        ops[l - 1].push_back(r - 1);
    }

    seg_tree<mint> rmq(N + 1);
    rmq.upd(0, mint(0));

    for (int i = 0; i < N; i++) {
        for (int r : ops[i]) {
            rmq.upd(r + 1, min(rmq.query(r + 1, r + 1).v,
                        rmq.query(i, r).v));
        }
        rmq.upd(i + 1, min(rmq.query(i, i).v + (targ[i] ? 1 : -1),
                    rmq.query(i + 1, i + 1).v));
    }

    int res = rmq.query(N, N).v;
    for (int i = 0; i < N; i++) {
        if (!targ[i]) res++;
    }
    cout << res << endl;

    return 0;
}



Measured memory_bytes: 11264