#include <iostream>
#include <iomanip>
#include<vector>
#include <math.h>
using namespace std;

const double eps = 1e-17;

bool IsEq(double d1, double d2)
{
    if (d1 - d2 > -eps && d1 - d2 < eps){
        return true;
    } else {
        return false;
    }
}

class Point2D {
public:
    double x, y;
    Point2D() : x(0), y(0) {}
    Point2D(double _x, double _y) : x(_x), y(_y) {}
    virtual ~Point2D() {}
};

istream& operator >> (istream& input, Point2D& P)
{
    input >> P.x >> P.y;
    return input;
}

class Segment {
public:
    Point2D P, Q;
    Segment() {}
    Segment(const Point2D& _P, const Point2D& _Q) : P(_P), Q(_Q) {}
};

istream& operator >> (istream& input, Segment& Seg)
{
    input >> Seg.P >> Seg.Q;
    return input;
}

class Vector2D : public Point2D {
public:
    Vector2D(double _x, double _y) : Point2D(_x, _y) {}
    Vector2D(const Point2D& P) : Point2D(P) {}
    Vector2D(const Segment& Seg) : Point2D(Seg.Q.x - Seg.P.x, Seg.Q.y - Seg.P.y) {}
    Vector2D(const Point2D& Start, const Point2D& End) : Point2D(End.x - Start.x, End.y - Start.y) {}
    double InnerProd(const Vector2D Vec) const
    {
        return x * Vec.x + y * Vec.y;
    }
    double OuterProd(const Vector2D Vec) const
    {
        return x * Vec.y - y * Vec.x;
    }
    double Length() const
    {
        return sqrt((*this).InnerProd(*this));
    }
};

Vector2D operator * (double d, const Vector2D& V)
{
    return Vector2D(d * V.x, d * V.y);
}

Vector2D operator + (const Vector2D& V1, const Vector2D& V2)
{
    return Vector2D(V1.x + V2.x, V1.y + V2.y);
}

ostream& operator << (ostream& out, const Vector2D& V)
{
    out << V.x << " " << V.y;
    return out;
}

double Dist(const Point2D& P, const Point2D& Q)
{
    Vector2D V(P, Q);
    return V.Length();
}

bool IsPara(const Segment& Seg1, const Segment& Seg2)
{
    Vector2D V1(Seg1), V2(Seg2);
    return IsEq(V1.OuterProd(V2), 0.);
}

double DistAsLine(const Point2D& P, const Segment& Seg)
{
    Vector2D V1(Seg);
    Vector2D V2(Seg.P, P);
    return fabs(V1.OuterProd(V2)) / V1.Length();
}


Vector2D CrossPoint(const Segment& Seg1, const Segment& Seg2)
{
    Vector2D P1(Seg1.P), P2(Seg2.P);
    Vector2D V1(Seg1), V2(Seg2);
    if (!IsPara(Seg1, Seg2)) {
        double t = (P2.OuterProd(V2) - P1.OuterProd(V2)) / V1.OuterProd(V2);
        return P1 + t * V1;
    } else {
        return Point2D();
    }
}

double Dist(const Point2D& P, const Segment& Seg)
{
    Vector2D V1(Seg);
    Vector2D V2(Seg.P, P);
    double IP = V1.InnerProd(V2);
    if (IP < 0.) {
        return Dist(P, Seg.P);
    } else if (IP > V1.InnerProd(V1)) {
        return Dist(P, Seg.Q);
    } else {
        return fabs(V1.OuterProd(V2)) / V1.Length();
    }
}

bool IsOnSeg(const Point2D& P, const Segment& Seg)
{
    Vector2D V(Seg);
    if (Dist(P, Seg) > eps) return false;
    return true;
}

bool IsIntersect(const Segment& Seg1, const Segment& Seg2)
{
    Vector2D P1(Seg1.P), P2(Seg2.P);
    Vector2D V1(Seg1), V2(Seg2);
    if (!IsPara(Seg1, Seg2)) {
        double t = (P2.OuterProd(V2) - P1.OuterProd(V2)) / V1.OuterProd(V2);
        double s = (P2.OuterProd(V1) - P1.OuterProd(V1)) / V1.OuterProd(V2);
        return t > -eps && t < 1 + eps && s > -eps && s < 1 + eps;
    } else {
        if (IsOnSeg(Seg1.P, Seg2) || IsOnSeg(Seg1.Q, Seg2) || IsOnSeg(Seg2.P, Seg1) || IsOnSeg(Seg2.Q, Seg1)) return true;
        return false;
    }
}

double Dist(const Segment& Seg1, const Segment& Seg2)
{
    if (IsIntersect(Seg1, Seg2)) return 0.;
    double Ret = Dist(Seg1.P, Seg2);
    Ret = min(Ret, Dist(Seg1.Q, Seg2));
    Ret = min(Ret, Dist(Seg2.P, Seg1));
    Ret = min(Ret, Dist(Seg2.Q, Seg1));
    return Ret;
}

double AreaPoly(vector<Point2D> vP)
{
    int n = static_cast<int>(vP.size());
    double Ret = 0.;
    Vector2D Prev(vP[0], vP[1]), Now(vP[0], vP[2]);
    for (int i = 2; i < n; ++i) {
        Now = Vector2D(vP[0], vP[i]);
        Ret += Prev.OuterProd(Now);
        Prev = Now;
    }
    Ret /= 2.;
    return Ret;
}

bool IsConvex(vector<Point2D> vP)
{
    int n = static_cast<int>(vP.size());
    vP.push_back(vP[0]);
    vP.push_back(vP[1]);
    Vector2D Prev(vP[0], vP[1]), Now(vP[0], vP[1]);
    for (int i = 1; i <= n; ++i) {
        Now = Vector2D(vP[i], vP[i+1]);
        if (Prev.OuterProd(Now) < 0.) return false;
        Prev =  Now;
    }
    return true;
}

int IsContained(Point2D P, const vector<Point2D>& vP)
{
    int n = static_cast<int>(vP.size());
    for (int i = 0; i < n-1; ++i) {
        if (IsOnSeg(P, Segment(vP[i], vP[i+1]))) return 1;
    }
    if (IsOnSeg(P, Segment(vP[n-1], vP[0]))) return 1;
    int NumCross = 0;
    for (int i = 0; i < n-1; ++i) {
        if (IsIntersect(Segment(P, Point2D(P.x + 100007, P.y + 100009)), Segment(vP[i], vP[i+1]))) {
            NumCross++;
        }
    }
    if (IsIntersect(Segment(P, Point2D(P.x + 100007, P.y + 100009)), Segment(vP[n-1], vP[0]))) {
        NumCross++;
    }
    if (NumCross % 2 == 0) {
        return 0;
    } else {
        return 2;
    }
}

int main(int argc, const char * argv[]) {
    int n;
    cin >> n;
    vector<Point2D> vP(n);
    for (int i = 0; i < n; ++i) {
        cin >> vP[i];
    }
    int q;
    cin >> q;
    Point2D P;
    for (int i = 0; i < q; ++i) {
        cin >> P;
        cout << IsContained(P, vP) << endl;
    }
    
    return 0;
}



Measured memory_bytes: 3228