Problem: Problem statement

The curve given by one implicit function $ Ax ^ 2 + Bxy + Cy ^ 2 + Dx + Ey + F = 0 $ and the straight line given by $ N $ implicit functions $ A_ix + B_iy + C_i = 0 $ is there. Find out how many regions the plane is divided by these curves and straight lines.

The following is a diagram of the Sample Input dataset.

<image> <image> <image>

Constraint

* $ 1 \ leq N \ leq 20 $
* $ -100 \ leq A, B, C, D, E, F \ leq 100 $
* $ -100 \ leq A_i, B_i, C_i \ leq 100 $
* $ A_i \ neq 0 $ or $ B_i \ neq 0 $
* The curve can be an ellipse (including a perfect circle), a parabola, or a hyperbola.
* The same straight line may exist.



input

Input follows the following format. All given numbers are integers.


$ N $
$ A $ $ B $ $ C $ $ D $ $ E $ $ F $
$ A_1 $ $ B_1 $ $ C_1 $
$ ... $
$ A_N $ $ B_N $ $ C_N $

output

Output the number of areas on one line.

Examples

Input

1
1 0 1 0 0 -1
1 -1 0


Output

4


Input

2
1 0 0 0 -1 0
2 -1 -1
6 9 1


Output

7


Input

2
1 0 -1 0 0 -1
3 0 6
-5 0 -10


Output

6

Solution (in CPP):

Solution:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <set>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-4;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

struct Point {
  double x, y;
  Point() {;}
  Point(double x, double y) : x(x), y(y) {;}
  bool operator<(const Point &rhs) const {
    if (fabs(x - rhs.x) > EPS) { return x < rhs.x; }
    if (fabs(y - rhs.y) > EPS) { return y > rhs.y; }
    return false;
  }
};

int n;
double A,B,C,D,E,F;
double la[30];
double lb[30];
double lc[30];
int node;
int edge;
int hit;
set<Point> points;

double X(double a, double b, double c, double y) {
  assert(fabs(a) > EPS);
  return (-b * y - c) / a;
}

double Y(double a, double b, double c, double x) {
  assert(fabs(b) > EPS);
  return (-a * x - c) / b;
}

vector<Point> CurveLine(int i) {
  bool swaped = false;
  double a1 = A;
  double b1 = B;
  double c1 = C;
  double d1 = D;
  double e1 = E;
  double f1 = F;
  double d2 = la[i];
  double e2 = lb[i];
  double f2 = lc[i];
  if (e2 == 0) {
    swap(a1, c1);
    swap(d1, e1);
    swap(d2, e2);
    swaped = true;
  }
  double P = a1 * e2 * e2 - b1 * e2 * d2 + c1 * d2 * d2;
  double Q = -b1 * e2 * f2 + 2 * c1 * d2 * f2 + d1 * e2 * e2 - e1 * e2 * d2;
  double R = c1 * f2 * f2 - e1 * e2 * f2 + f1 * e2 * e2;
  vector<Point> ret;
  double D = Q * Q - 4 * P * R;
  if (P == 0) {
    double x = -R / Q;
    ret.push_back(Point(x, Y(d2, e2, f2, x)));
  } else if (fabs(D) <= EPS){
    double x = -Q / (2 * P);
    ret.push_back(Point(x, Y(d2, e2, f2, x)));
  } else if (D > 0) {
    double x = (-Q + sqrt(D)) / (2 * P);
    ret.push_back(Point(x, Y(d2, e2, f2, x)));
    x = (-Q - sqrt(D)) / (2 * P);
    ret.push_back(Point(x, Y(d2, e2, f2, x)));
  }
  if (swaped) {
    FORIT(it, ret) { swap(it->x, it->y); }
  }
  return ret;
}

vector<Point> LineLine(int i, int j) {
  double a1 = la[i];
  double b1 = lb[i];
  double c1 = lc[i];
  double a2 = la[j];
  double b2 = lb[j];
  double c2 = lc[j];
  vector<Point> ret;
  if (fabs(a1 * b2 - a2 * b1) > EPS) {
    ret.push_back(Point((-b2 * c1 + b1 * c2) / (a1 *b2 - a2 * b1), (a2 * c1 - a1 * c2) / (a1 * b2 - a2 * b1)));
  }
  return ret;
}

int CntCurve() {
  int ret = 0;
  FORIT(it, points) {
    double x = it->x;
    double y = it->y;
    if (fabs(A * x * x + B * x * y + C * y * y + D * x + E * y + F) <= EPS) { ret++; }
  }
  return ret;
}

int CntLine(int i) {
  int ret = 0;
  FORIT(it, points) {
    if (fabs(la[i] * it->x + lb[i] * it->y + lc[i]) <= EPS) { ret++; }
  }
  return ret;
}

int main() {
  while (scanf("%d", &n) > 0) {
    points.clear();
    hit = 1;
    node = 0;
    edge = 0;
    scanf("%lf %lf %lf %lf %lf %lf", &A, &B, &C, &D, &E, &F);
    {
      int m = 0;
      REP(i, n) {
        scanf("%lf %lf %lf", &la[m], &lb[m], &lc[m]);
        REP(j, m) {
          if (fabs(la[j] * lb[m] - la[m] * lb[j]) <= EPS) {
            if ((la[j] != 0 && fabs(la[j] * lc[m] - la[m] * lc[j]) <= EPS) ||
                (lb[j] != 0 && fabs(lb[j] * lc[m] - lb[m] * lc[j]) <= EPS)) {
              m--;
              break;
            }
          }
        }
        m++;
      }
      n = m;
    }
    vector<Point> temp;
    REP(i, n) {
      vector<Point> ps = CurveLine(i);
      FORIT(it, ps) { points.insert(*it); }
      REP(j, i) {
        vector<Point> ps = LineLine(i, j);
        FORIT(it, ps) { points.insert(*it); }
      }
    }
    node = points.size();
    edge += CntCurve();
    if (fabs(B * B - 4 * A * C) <= EPS) {
      edge++;
    } else if (B * B - 4 * A * C < 0) {
      if (CntCurve() == 0) { hit = 0; }
    } else {
      edge += 2;
    }
    REP(i, n) {
      edge += CntLine(i) + 1;
    }
    printf("%d\n", edge - node + 1 + (1 - hit));
  }
}