#include <iostream>
#include <iomanip>
#include <sstream>
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cassert>
#include <climits>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
typedef long long ll;
typedef pair<int,int> pii;
const int INF = 1<<29;
const double PI = acos(-1);
const double EPS = 1e-8;

typedef complex<double> Point;
namespace std {
  bool operator < (const Point& a, const Point& b) {
    if (abs(a-b) < EPS) return 0;
    return abs(real(a) - real(b)) < EPS ? real(a) < real(b)+EPS : imag(a) < imag(b)+EPS;
  }
}
double cross(const Point& a, const Point& b) {
  return imag(conj(a)*b);
}
double dot(const Point& a, const Point& b) {
  return real(conj(a)*b);
}
struct L {
  int a,b,c;
  L(int a, int b, int c) : a(a),b(b),c(c) {}
  L() {}
};

bool eq(double a, double b) {
  return abs(a-b) < EPS;
}
bool eqLL(const L &l, const L &m) {
  if (l.b*m.a!=l.a*m.b) return 0;
  if (eq(l.a,0)) return l.b*m.c==l.c*m.b;
  else return l.a*m.c==l.c*m.a;
}
Point crosspoint(const L &l, const L &m) {
  double x = double(-m.b*l.c+l.b*m.c) / (l.a*m.b-m.a*l.b);
  double y = double(m.a*l.c-l.a*m.c) / (l.a*m.b-m.a*l.b);
  return Point(x,y);
}
vector<Point> crosspoint(int A, int B, int C, int D, int E, int F, const L &l) {
  double d = l.a, e = l.b, f = l.c;
  bool flag = 0;
  if (e == 0) {
    flag = 1;
    swap(d,e);
    swap(A,C);
    swap(D,E);
  }
  ll P = A*e*e-B*e*d+C*d*d;
  ll Q = -B*e*f+2*C*d*f+D*e*e-E*e*d;
  ll R = C*f*f-E*e*f+F*e*e;
  //cout << P << " " << Q << " " << R << endl;
  vector<Point> res;
  if (P == 0) {
    double x = (double)-R/Q;
    res.push_back(Point(x,double(-d*x-f)/e));
  } else {
    ll type = Q*Q-4*P*R;
    if (type < 0) ;
    else if (type == 0) {
      double x = (double)-Q/2/P;
      res.push_back(Point(x,double(-d*x-f)/e));
    } else {
      double x = double(-Q+sqrt(type))/2/P;
      res.push_back(Point(x,double(-d*x-f)/e));
      x = double(-Q-sqrt(type))/2/P;
      res.push_back(Point(x,double(-d*x-f)/e));
    }
  }
  if (flag) {
    FOR(it, res) swap(it->real(),it->imag());
  }
  return res;
}

int main() {
  int n;
  while(cin >> n) {
    int A,B,C,D,E,F;
    cin>>A>>B>>C>>D>>E>>F;
    vector<L> ls;
    REP(i,n) {
      int a,b,c; cin >> a >> b >> c;
      L tmp = L(a,b,c);
      bool f = 0;
      FOR(it, ls) {
        if (eqLL(*it, tmp)) f = 1;
      }
      if (!f) ls.push_back(tmp);
    }
    n = ls.size();
    int type = B*B-4*A*C;
    int lnum = 0, tnum = 0;
    set<Point> pset;
    REP(i,n) {
      set<Point> tset;
      REP(j,n) {
        if (i==j) continue;
        Point p = crosspoint(ls[i], ls[j]);
        tset.insert(p);
        pset.insert(p);
      }
      vector<Point> cp = crosspoint(A,B,C,D,E,F,ls[i]);
      FOR(it, cp) {
        tset.insert(*it);
        pset.insert(*it);
      }
      //cout << endl;
      //cout << lnum << " ";
      lnum += tset.size()+1;
    }
    //cout << lnum << endl;
    bool plusflag = 1;
    set<Point> tset;
    REP(i,n) {
      vector<Point> cp = crosspoint(A,B,C,D,E,F,ls[i]);
      if (cp.size()) plusflag = 0;
      FOR(it,cp) {
        tset.insert(*it);
      }
    }
    lnum += tset.size();
    if (abs(type) < EPS) {        // ツ陛コツ閉ィツ静シ
      lnum++;
    } else if (type < 0) {        // ツ妥按円
      if (plusflag) lnum++;
    } else {                      // ツ双ツ凝按静シ
      lnum+=2;
    }
    // FOR(it,pset) cout << *it << endl;
    // cout << lnum << " " << pset.size() << endl;
    cout << lnum-(int)pset.size()+1 << endl;
    break;
  }
}

Measured memory_bytes: 0