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

#define ios ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define ll long long
#define ull unsigned long long
#define inf INT_MAX
#define llinf LLONG_MAX
#define mt make_tuple
#define mp make_pair
#define parll pair<ll,ll>
#define parii pair<int,int>
#define frs first
#define sec second
#define neparno(x) (x&1)
#define parno(x) (!neparno(x))
#define lowbit(x) (x&-x)
#define nzd __gcd
#define nzs(e1,e2) (e1/nzd(e1,e2))*e2
#define all(V) V.begin(),V.end()
#define fill(V,v) fill(all(V),v)
#define l_b(BRL,brl) lower_bound( BRL.begin(), BRL.end(), brl )-BRL.begin()-1
#define u_b(BRU,bru) upper_bound( BRU.begin(), BRU.end(), bru )-BRU.begin()
#define mxn 100004

struct tacka
{
    ll x;
    ll y;
};

struct duz
{
    tacka t1;
    tacka t2;
};

ll n;
vector <tacka> A(mxn);

bool NaDuzi( duz d1, tacka t )
{
    if ( t.x <= max(d1.t1.x,d1.t2.x)
        && t.x >= min(d1.t1.x,d1.t2.x)
        && (t.y <= max(d1.t1.y,d1.t2.y)
        && t.y >= min(d1.t1.y,d1.t2.y)))
        return true;

    return false;
}

ll Direction( tacka a, tacka b, tacka c )
{
    ll v = (b.y-a.y)*(c.x-b.x)-(b.x-a.x)*(c.y-b.y);
    if ( v == 0 )
    {
        return 0;
    }
    if ( v < 0 )
    {
        return 2;
    }
    return 1;
}

bool DaLiSeSeku( duz d1, duz d2 )
{
    ll dir1 = Direction(d1.t1,d1.t2,d2.t1);
    ll dir2 = Direction(d1.t1,d1.t2,d2.t2);
    ll dir3 = Direction(d2.t1,d2.t2,d1.t1);
    ll dir4 = Direction(d2.t1,d2.t2,d1.t2);
    if ( dir1 != dir2 && dir3 != dir4 )
    {
        return true;
    }
    if ( dir1 == 0 && NaDuzi(d1,d2.t1) )
    {
        return true;
    }
    if ( dir2 == 0 && NaDuzi(d1, d2.t2) )
    {
        return true;
    }
    if ( dir3 == 0 && NaDuzi(d2, d1.t1) )
    {
        return true;
    }
    if ( dir4 == 0 && NaDuzi(d2, d1.t2) )
    {
        return true;
    }
    return false;
}

bool Unutra( vector <tacka> P, ll k, tacka t )
{
    if ( k == 0 )
    {
        return false;
    }
    if ( k == 1 )
    {
        return (t.x==P[0].x && t.y==P[0].y);
    }
    if ( k == 2 )
    {
        return (Direction(P[0],t,P[1]) == 0 && NaDuzi({P[0],P[1]},t));
    }
    duz h = {t,{inf,t.y}};
    ll br = 0;
    ll i = 1;
    do
    {
        duz stranica = {P[i],P[i%k+1]};
        if ( DaLiSeSeku(stranica,h) )
        {
            if ( Direction(stranica.t1,t,stranica.t2) == 0 )
            {
                return NaDuzi(stranica,t);
            }
            br++;
        }
        i = i%k+1;
    } while (i != 1);
    return (neparno(br));
}

ll SveKombinacije( tacka messi )
{
    ll k=((1ll)<<n)-1,rez=0;
    vector <tacka> P;
    for ( ll x = 0; x <= k; x++ )
    {
        ll mask = 1;
        for ( ll i = 0; i <= n-1; i++ )
        {
            if ( x&mask )
            {
                P.push_back(A[i+1]);
            }
            mask <<= 1;
        }
        rez += Unutra(P,P.size(),messi);
        P.clear();
    }
    return rez;
}

void Drugi()
{
    vector <ll> B;
    for ( ll i = 2; i <= n; i++ )
    {
        if ( A[i].x > 0 )
        {
            B.push_back(A[i].x);
        }
        //cout << B.back() << " ";
    }
    //cout << "\n";
    sort(all(B));

    ll k = lower_bound(all(B),A[1].x)-B.begin();
    ll l = k-1;
    ll r = n-1-k+1;
    ll rez = (((1ll)<<l)+((1ll)<<r))-2;
    cout << rez;
    return;
}

int main()
{
    ios;

    cin >> n;
    bool drugi = true;
    for ( ll i = 1; i <= n; i++ )
    {
        cin >> A[i].x >> A[i].y;
        if ( !((i == 1 && A[i].y == 1) || (A[i].y == -1)) )
        {
            drugi = false;
        }
    }
    tacka messi = {0,0};

    if ( n == 3 )
    {
        cout << Unutra(A,3,messi);
        return 0;
    }
    if ( drugi )
    {
        Drugi();
        return 0;
    }
    if ( n <= 18 )
    {
        cout << SveKombinacije(messi);
        return 0;
    }

    return 0;
}