#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>

using namespace std;

// Struktura reprezentująca punkt/wektor
struct Point {
    long long x, y;
};

// Iloczyn wektorowy (cross product) wektorów OA i OB
// Zwraca wartość dodatnią, ujemną lub 0
long long cross_product(const Point& O, const Point& A, const Point& B) {
    return (A.x - O.x) * (B.y - O.y) - (A.y - O.y) * (B.x - O.x);
}

// Funkcja sprawdzająca, czy punkt P znajduje się wewnątrz wielokąta wypukłego
bool is_inside_polygon(const Point& P, const vector<Point>& poly) {
    int n = poly.size();
    // Sprawdzamy orientację względem pierwszego i ostatniego boku
    if (cross_product(poly[0], poly[1], P) < 0) return false;
    if (cross_product(poly[0], poly[n - 1], P) > 0) return false;

    // Wyszukiwanie binarne odpowiedniego segmentu kątowego
    int low = 1, high = n - 1;
    while (high - low > 1) {
        int mid = (low + high) / 2;
        if (cross_product(poly[0], poly[mid], P) >= 0) {
            low = mid;
        } else {
            high = mid;
        }
    }
    return cross_product(poly[low], poly[high], P) >= 0;
}

// Komparator do sortowania kątowego wokół punktu P
struct AngularCompare {
    Point P;
    AngularCompare(Point p) : P(p) {}

    // Funkcja pomocnicza określająca półpłaszczyznę (góra/dół)
    int half_plane(const Point& q) const {
        if (q.y == P.y) {
            return q.x < P.x ? 1 : 0;
        }
        return q.y < P.y ? 1 : 0;
    }

    bool operator()(const Point& a, const Point& b) const {
        int hp_a = half_plane(a);
        int hp_b = half_plane(b);
        if (hp_a != hp_b) {
            return hp_a < hp_b;
        }
        long long cp = (a.x - P.x) * (b.y - P.y) - (a.y - P.y) * (b.x - P.x);
        return cp > 0; // Sortowanie przeciwnie do ruchu wskazówek zegara
    }
};

long long solve_for_point(int n, const vector<Point>& poly, const Point& P) {
    // Jeśli punkt jest poza wielokątem, nie może być w żadnym trójkącie
    if (!is_inside_polygon(P, poly)) {
        return 0;
    }

    // Tworzymy listę wierzchołków posortowaną kątowo względem P
    vector<Point> pts = poly;
    sort(pts.begin(), pts.end(), AngularCompare(P));

    // Dublujemy tablicę, aby łatwo symulować cykliczność (gąsienica)
    for (int i = 0; i < n; i++) {
        pts.push_back(pts[i]);
    }

    long long bad_triangles = 0;
    int j = 0;

    // Metoda dwóch wskaźników
    for (int i = 0; i < n; i++) {
        if (j <= i) j = i + 1;
        
        // Rozszerzamy okno gąsienicy tak długo, jak punkty leżą po jednej stronie prostej
        while (j < i + n && cross_product(P, pts[i], pts[j]) > 0) {
            j++;
        }
        
        long long count = j - i - 1;
        if (count >= 2) {
            // Kombinacja symbolu Newtona: count po 2
            bad_triangles += (count * (count - 1)) / 2;
        }
    }

    // Łączna liczba wszystkich trójkątów: n po 3
    long long total_triangles = (1LL * n * (n - 1) * (n - 2)) / 6;

    return total_triangles - bad_triangles;
}

int main() {
    // Optymalizacja wejścia/wyjścia
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n;
    if (!(cin >> n)) return 0;

    vector<Point> poly(n);
    for (int i = 0; i < n; i++) {
        cin >> poly[i].x >> poly[i].y;
    }

    // Upewniamy się, że wielokąt jest zorientowany przeciwnie do wskazówek zegara (CCW)
    // Jeśli wejście jest CW (zgodnie z treścią zadania), odwracamy wektor
    long long area = 0;
    for (int i = 0; i < n; i++) {
        int next = (i + 1) % n;
        area += (poly[i].x * poly[next].y - poly[next].x * poly[i].y);
    }
    if (area < 0) {
        reverse(poly.begin(), poly.end());
    }

    int t;
    if (cin >> t) {
        while (t--) {
            Point P;
            cin >> P.x >> P.y;
            cout << solve_for_point(n, poly, P) << "\n";
        }
    }

    return 0;
}