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

#define all(x) (x).begin(), (x).end()
#define sz(x) (int)(x).size()
using LL = long long;

template<class T, size_t D>
struct vec : vector<vec<T, D - 1>> {
    template<class... Args>
    vec(int n = 0, Args... args) 
        : vector<vec<T, D - 1>>(n, vec<T, D - 1>(args...)) {}
};
template<class T>
struct vec<T, 1> : vector<T> {
    vec(int n = 0, T val = T()) 
        : vector<T>(n, val) {}
};

template<class T>
inline bool asMn(T& a, const T& b) {return a > b ? a = b, true : false;}
template<class T>
inline bool asMx(T& a, const T& b) {return a < b ? a = b, true : false;}

inline int nxt(int i, int n) {return i == n - 1 ? 0 : i + 1;}
inline int prv(int i, int n) {return !i ? n - 1 : i - 1;}

const int inf = 1e9;
mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());

template<class maxFlowType>
struct Dinic {
    int n, s, t;
    struct Edge {
        int to, cf;
        Edge(int _to, int _cf) : to(_to), cf(_cf) {}
    };
    vector<Edge> edge;
    vector<vector<int>> edgeSet;
    vector<int> d, iGr;
    maxFlowType maxFlow;
 
    Dinic(int _n, int _s, int _t) : n(_n), s(_s), t(_t) {
        edge.clear(); edge.reserve(8000000);
        edgeSet.assign(n, {}); edgeSet.reserve(4000000);
        maxFlow = 0;
    }

    int addVertex() {
        int ret = n;
        ++n;
        edgeSet.emplace_back(vector<int>());
        return ret;
    }
 
    void addEdge(int u, int v, int c) {
        edgeSet[u].emplace_back(sz(edge)); edge.emplace_back(v, c);
        edgeSet[v].emplace_back(sz(edge)); edge.emplace_back(u, 0);
    }
 
    bool bfs() {
        d.assign(n, inf); d[s] = 0;
        iGr.assign(n, 0);
        queue<int> q; q.emplace(s);
 
        while (sz(q)) {
        int u = q.front(); q.pop();
            for (int i : edgeSet[u]) if (d[edge[i].to] == inf && edge[i].cf) {
                d[edge[i].to] = d[u] + 1;
                q.emplace(edge[i].to);
            }
        }
 
        return d[t] != inf;
    }
 
    int dfs(int u, int flow) {
        if (u == t || !flow) return flow;
 
        for (; iGr[u] < sz(edgeSet[u]); ++iGr[u]) {
            int i = edgeSet[u][iGr[u]];
            if (d[edge[i].to] != d[u] + 1 || !edge[i].cf) continue ;
 
            int nxt = dfs(edge[i].to, min(flow, edge[i].cf));
            if (nxt) {edge[i].cf -= nxt; edge[i ^ 1].cf += nxt; return nxt;}
        }
 
        return 0;
    }
 
    maxFlowType get() {
        while (bfs()) {
            int tmp;
            while ((tmp = dfs(s, inf))) maxFlow += tmp;
        }
 
        return maxFlow;
    }
};
Dinic<int> dn(2, 0, 1);

struct BIT {
    vector<int> a;
    BIT(int n) {a.assign(n, -1);}

    void upd(int pos, int val) {
        for (int i = pos; i < sz(a); i |= i + 1) {
            int tmp = dn.addVertex();
            dn.addEdge(tmp, val, 1);
            if (~a[i])
                dn.addEdge(tmp, a[i], inf);
            a[i] = tmp;
        }
    }
    void get(int pos, int val) {
        for (int i = pos; ~i; i = (i & (i + 1) ) - 1) {
            if (~a[i])
                dn.addEdge(val, a[i], 1);
        }
    }
};

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

    int nBlack; cin >> nBlack;
    vector<pair<int, int>> black(nBlack);
    for (int i = 0; i < nBlack; ++i)
        cin >> black[i].first >> black[i].second;
    sort(all(black));

    int nWhite; cin >> nWhite;
    vector<pair<int, int>> white(nWhite);
    vector<int> idWhite(nWhite), edge(nWhite);
    for (int i = 0; i < nWhite; ++i) {
        cin >> white[i].first >> white[i].second;
        idWhite[i] = dn.addVertex();
        edge[i] = sz(dn.edge);
        dn.addEdge(dn.s, idWhite[i], 1);
    }

    BIT bit(nBlack);
    vector<int> orderBlack(sz(black)); iota(all(orderBlack), 0);
    sort(all(orderBlack), [&](const int& i, const int& j) {
        return black[i].second < black[j].second;
    });
    vector<int> orderWhite(sz(white)); iota(all(orderWhite), 0);
    sort(all(orderWhite), [&](const int& i, const int& j) {
        return white[i].second < white[j].second;
    });
    auto iBlack = orderBlack.begin();
    for (const auto& iWhite : orderWhite) {
        while (iBlack != orderBlack.end() && white[iWhite].second >= black[*iBlack].second) {
            int val = dn.addVertex();
            dn.addEdge(val, dn.t, 1);
            bit.upd(*iBlack, val);
            ++iBlack;
        }

        int tmp = (int)(upper_bound(all(black), make_pair(white[iWhite].first, inf)) - black.begin()) - 1;
        bit.get(tmp, idWhite[iWhite]);
    }

    int curAns = dn.get();
    vector<int> ans(nWhite);
    for (int i = nWhite - 1; ~i; --i) {
        ans[i] = curAns;
        curAns -= !dn.edge[edge[i]].cf;
    }

    for (const auto& i : ans)
        cout << i << '\n';

    return 0;
}