#include <iostream>
#include <vector>
#include <math.h>
#include <limits>
using namespace std ;
using ll = long long ;
using pt = pair<ll, ll> ;
using rat = pair<ll, ll> ;
using rpt = pair<rat, rat> ;
using line = pair<pt, pt> ;
const int MAX = 32 ;
rpt inter[MAX][MAX] ;
rat pos(ll num, ll den) {
   if (den < 0)
      return {-num, -den} ;
   else
      return {num, den} ;
}
rpt lineline(line a, line b) {
   auto [p1, p2] = a ;
   auto [p3, p4] = b ;
   auto [x1, y1] = p1 ;
   auto [x2, y2] = p2 ;
   auto [x3, y3] = p3 ;
   auto [x4, y4] = p4 ;
   auto d = (x1-x2)*(y3-y4)-(y1-y2)*(x3-x4) ;
   if (d == 0)
      return {{1,0},{1,0}} ;
   return {pos((x1*y2-y1*x2)*(x3-x4)-(x1-x2)*(x3*y4-y3*x4),d),
           pos((x1*y2-y1*x2)*(y3-y4)-(y1-y2)*(x3*y4-y3*x4),d)} ;
}
int eq(rat &a, rat &b) {
   return a.first * b.second == a.second * b.first ;
}
int eq(rpt &a, rpt &b) {
   return eq(a.first, b.first) && eq(a.second, b.second) ;
}
int cmp(rat &a, rat &b) {
   ll t = a.first * b.second - a.second * b.first ;
   if (t < 0)
      return -1 ;
   if (t > 0)
      return 1 ;
   return 0 ;
}
int inbounds(rpt &p, rpt &a, rpt &b) {
   return (cmp(p.first, a.first) * cmp(b.first, p.first) >= 0) &&
          (cmp(p.second, a.second) * cmp(b.second, p.second) >= 0) ;
}
int segseg(int a, int b, int c, int d, int e, int f) {
   auto &cross = inter[b][e] ;
   if (cross.first.second == 0)
      return 0 ;
   return inbounds(cross, inter[a][b], inter[b][c]) &&
          inbounds(cross, inter[d][e], inter[e][f]) ;
}
vector<int> poly ;
vector<line> v ;
int n ;
ll r = 0 ;
void recur(int lastlin, ll used, int togo) {
   int ps = poly.size() ;
   if (togo == 0) {
      if (eq(inter[poly[0]][poly[1]], inter[poly[ps-2]][poly[ps-1]]))
         return ;
      poly.push_back(poly[1]) ;
      for (int j=1; j+2<=ps-2; j++) {
         if (segseg(poly[j], poly[j+1], poly[j+2],
                    poly[ps-2], poly[ps-1], poly[ps])) {
            poly.pop_back() ;
            return ;
         }
      }
      poly.pop_back() ;
      r++ ;
      return ;
   }
   for (int i=0; i<n; i++)
      if (togo == 1 ? i == 0 : ((used >> i) & 1) == 0) {
         if (ps > 1 && eq(inter[i][poly[ps-1]], inter[poly[ps-1]][poly[ps-2]]))
            continue ;
         if (inter[i][poly[ps-1]].first.second != 0) {
            int good = 1 ;
            for (int j=0; good && j+2<=ps-2; j++) {
               if (segseg(poly[j], poly[j+1], poly[j+2],
                          poly[ps-2], poly[ps-1], i))
                  good = 0 ;
            }
            if (good) {
               poly.push_back(i) ;
               recur(i, used | (1LL << i), togo-1) ;
               poly.pop_back() ;
            }
         }
      }
}
int main() {
   cin >> n ;
   v.resize(n) ;
   for (auto &[p1, p2] : v) {
      auto& [x1, y1] = p1 ;
      auto& [x2, y2] = p2 ;
      cin >> x1 >> y1 >> x2 >> y2 ;
   }
   for (int i=0; i<n; i++)
      for (int j=0; j<n; j++)
         if (i != j)
            inter[i][j] = lineline(v[i], v[j]) ;
   poly.push_back(0) ;
   recur(0, 1, n) ;
   poly.pop_back() ;
   if (r & 1)
      cout << "Odd? " << r << endl ;
   cout << (r>>1) << endl ;
}
