#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
const double EPS = 1e-6;
const double INF = 1e12;
#define EQ(n,m) (abs((n)-(m)) < EPS)

struct point{
    double x,y;
    point(double x, double y):x(x), y(y){}
    point(){}
    bool operator<(const point &a){
        return !EQ(x, a.x)? x<a.x: y+EPS<a.y;
    }
    bool operator==(const point &a){
        return EQ(x, a.x) && EQ(y, a.y);
    }
};

struct linear{
    double a,b,c;
    bool eq(const linear &l){
        if((abs(a)<EPS) != (abs(l.a)<EPS)) return false;
        if(abs(a)<EPS){
            return EQ(c/b, l.c/l.b);
        }else{
            return EQ(b/a, l.b/l.a) && EQ(c/a, l.c/l.a);
        }
    }
};
struct quadratic{
    double a,b,c,d,e,f;
};

bool crosspointLL(linear s, linear t, point &ret){
    double d = s.a*t.b -t.a*s.b;
    if(EQ(d, 0)) return false;
    ret.x = (s.b*t.c -t.b*s.c) /d;
    ret.y = (-s.a*t.c +t.a*s.c) /d;
    return true;
}

vector<double> solve_quadeq(double a, double b, double c){
    vector<double> ret;
    if(abs(a) < EPS){
        if(abs(b) > EPS) ret.push_back(-c/b);
        return ret;
    }
    double d = b*b -4*a*c;
    if(abs(d) < EPS) d = 0;
    if(d < 0) return ret;
    if(d < 0) d = 0;
    ret.push_back((-b +sqrt(d))/(2*a));
    ret.push_back((-b -sqrt(d))/(2*a));
    return ret;
}
enum type{
    ellipse,
    parabola,
    hyperbola,
};

int main(){
    int n;
    cin >> n;
    quadratic q;
    cin >> q.a >> q.b >> q.c >> q.d >> q.e >> q.f;
    vector<linear> l;
    for(int i=0; i<n; i++){
        linear tmp;
        cin >> tmp.a >> tmp.b >> tmp.c;
        bool ok = true;
        for(int j=0; j<(int)l.size(); j++){
            if(tmp.eq(l[j])){
                ok = false;
                break;
            }
        }
        if(ok){
            l.push_back(tmp);
        }
    }
    n = l.size();
    
    //二次曲線の分類
    double d = q.a*q.c -q.b*q.b/4;
    type t;
    if(EQ(d, 0)){
        t = parabola;
    }else if(d > 0){
        t = ellipse;
    }else{
        t = hyperbola;
    }

    vector<vector<point> > cp(n+1);
    for(int i=0; i<n; i++){
        //二次曲線との交点
        if(EQ(l[i].b, 0)){
            double x = -l[i].c /l[i].a;
            double a,b,c;
            a = q.c;
            b = q.b*x +q.e;
            c = q.a*x*x +q.d*x +q.f;
            vector<double> soly = solve_quadeq(a, b, c);
            for(double y: soly){
                cp[i].emplace_back(x, y);
                cp[n].emplace_back(x, y);
            }
        }else{
            double coef = -l[i].a /l[i].b;
            double con = -l[i].c /l[i].b;
            //y = coef*x +con
            double a,b,c;
            a = q.a +q.b*coef +q.c*coef*coef;
            b = q.b*con +2*q.c*coef*con +q.d +q.e*coef;
            c = q.c*con*con +q.e*con +q.f;
            vector<double> solx = solve_quadeq(a, b, c);
            for(double x: solx){
                cp[i].emplace_back(x, coef*x +con);
                cp[n].emplace_back(x, coef*x +con);
            }
        }

        //直線同士の交点
        for(int j=i+1; j<n; j++){
            point ret;
            if(crosspointLL(l[i], l[j], ret)){
                cp[i].push_back(ret);
                cp[j].push_back(ret);
            }
        }
    }
    for(int i=0; i<n+1; i++){
        sort(cp[i].begin(), cp[i].end());
        cp[i].erase(unique(cp[i].begin(), cp[i].end()), cp[i].end());
    }

    //オイラーの定理
    int vertex=0, edge=0;
    vector<point> cpall;
    for(int i=0; i<n+1; i++){
        edge += cp[i].size() +1;
        cpall.insert(cpall.end(), cp[i].begin(), cp[i].end());
    }
    sort(cpall.begin(), cpall.end());
    cpall.erase(unique(cpall.begin(), cpall.end()), cpall.end());
    
    vertex = cpall.size();
    if(t == ellipse){
        if(!cp[n].empty()){
            edge--;
        }
    }else if(t == hyperbola){
        edge++;
    }
    cout << edge -vertex +1 << endl;
    return 0;
}



Measured memory_bytes: 3288