import java.io.*;
import java.util.*;

public class Template implements Runnable {

    BufferedReader in;
    PrintWriter out;
    StringTokenizer tok = new StringTokenizer("");

    void init() throws FileNotFoundException {
        try {
            in = new BufferedReader(new FileReader("input.txt"));
            out = new PrintWriter("output.txt");
        } catch (Exception e) {
            in = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out);
        }
    }

    class GraphBuilder {
        int n, m;
        int[] x, y;
        int index;
        int[] size;

        GraphBuilder(int n, int m) {
            this.n = n;
            this.m = m;
            x = new int[m];
            y = new int[m];
            size = new int[n];
        }

        void add(int u, int v) {
            x[index] = u;
            y[index] = v;
            size[u]++;
            size[v]++;
            index++;
        }

        int[][] build() {
            int[][] graph = new int[n][];
            for (int i = 0; i < n; i++) {
                graph[i] = new int[size[i]];
            }
            for (int i = index - 1; i >= 0; i--) {
                int u = x[i];
                int v = y[i];
                graph[u][--size[u]] = v;
                graph[v][--size[v]] = u;
            }
            return graph;
        }
    }

    String readString() throws IOException {
        while (!tok.hasMoreTokens()) {
            try {
                tok = new StringTokenizer(in.readLine());
            } catch (Exception e) {
                return null;
            }
        }
        return tok.nextToken();
    }

    int readInt() throws IOException {
        return Integer.parseInt(readString());
    }

    int[] readIntArray(int size) throws IOException {
        int[] res = new int[size];
        for (int i = 0; i < size; i++) {
            res[i] = readInt();
        }
        return res;
    }

    long[] readLongArray(int size) throws IOException {
        long[] res = new long[size];
        for (int i = 0; i < size; i++) {
            res[i] = readLong();
        }
        return res;
    }

    long readLong() throws IOException {
        return Long.parseLong(readString());
    }

    double readDouble() throws IOException {
        return Double.parseDouble(readString());
    }

    <T> List<T>[] createGraphList(int size) {
        List<T>[] list = new List[size];
        for (int i = 0; i < size; i++) {
            list[i] = new ArrayList<>();
        }
        return list;
    }

    public static void main(String[] args) {
        new Template().run();
        // new Thread(null, new Template(), "", 1l * 200 * 1024 * 1024).start();
    }

    long timeBegin, timeEnd;

    void time() {
        timeEnd = System.currentTimeMillis();
        System.err.println("Time = " + (timeEnd - timeBegin));
    }

    long memoryTotal, memoryFree;

    void memory() {
        memoryFree = Runtime.getRuntime().freeMemory();
        System.err.println("Memory = " + ((memoryTotal - memoryFree) >> 10)
                + " KB");
    }

    public void run() {
        try {
            timeBegin = System.currentTimeMillis();
            memoryTotal = Runtime.getRuntime().freeMemory();
            init();
            solve();
            out.close();
            if (System.getProperty("ONLINE_JUDGE") == null) {
                time();
                memory();
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(-1);
        }
    }

    int simple(String s) {
        int res = 0;
        while (true) {
            String was = s;
            s = s.replaceFirst("ab", "bba");
            if (s.equals(was)) break;
            res++;
        }
        return res;
    }

    void solve() throws IOException {
        int x1 = readInt();
        int y1 = readInt();

        int x2 = readInt();
        int y2 = readInt();

        int n = readInt();
        int res = 0;
        for (int i = 0; i < n; i++) {
            int a = readInt();
            int b = readInt();
            int c = readInt();

            long val1 = (long) a * x1 + (long) b * y1 + c;
            long val2 = (long) a * x2 + (long) b * y2 + c;

            if (sgn(val1) * sgn(val2) < 0) {
                res++;
            }
        }
        out.println(res);
    }

    long sgn(long v) {
        return v == 0 ? 0 : (v > 0 ? 1 : -1);
    }

}


import java.io.IOException;

public class CF2 {
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		int x1 = sc.nextInt();
		int y1 = sc.nextInt();
		int x2 = sc.nextInt();
		int y2 = sc.nextInt();
		Line original = new Line(new Point(x1,y1) , new Point(x2,y2));
		int n=sc.nextInt();
		int count=0;
		for(int i=0;i<n;i++)
		{
			int a=sc.nextInt();
			int b = sc.nextInt();
			int c = sc.nextInt();
			Line l = new Line(a*1.0/b,1.0,c*1.0/b);
			Point point = l.intersect(original);
			if(point!=null &&point.onSegment(new Point(x1,y1), new Point(x2,y2)));
				count++;
		}
		System.out.println(count);
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashSet;
import java.util.StringTokenizer;

public class CF2 {
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		int x1 = sc.nextInt();
		int y1 = sc.nextInt();
		int x2 = sc.nextInt();
		int y2 = sc.nextInt();
		Line original = new Line(new Point(x1,y1) , new Point(x2,y2));
		int n=sc.nextInt();
		int count=0;
		for(int i=0;i<n;i++)
		{
			int a = sc.nextInt();
			int b = sc.nextInt();
			int c = sc.nextInt();
			Line l = new Line(a,b,c);
			Point point = l.intersect(original);
			//System.out.println(point);
			if(point!=null && point.between(new Point(x1,y1), new Point(x2,y2)))
				count++;
		}
		System.out.println(count);
	}

}
class Point implements Comparable<Point>{

	static final double EPS = 1e-9;

	double x, y;

	Point(double a, double b)
	{
		x = a; y = b;
	}

	public String toString()
	{
		return x+" "+y;
	}

	public int compareTo(Point p)
	{
		if(Math.abs(x - p.x) > EPS) return x > p.x ? 1 : -1;
		if(Math.abs(y - p.y) > EPS) return y > p.y ? 1 : -1;
		return 0;
	}

	public double dist(Point p) { return Math.sqrt(sq(x - p.x) + sq(y - p.y)); }

	static double sq(double x) { return x * x; }

	Point rotate(double angle)				//rotate around (0,0)
	{
		double c = Math.cos(angle), s = Math.sin(angle);
		return new Point(x * c - y * s, x * s + y * c);
	}
	// for integer points and rotation by 90 (counterclockwise) : swap x and y, negate x

	Point rotate(double theta, Point p)			//rotate around p
	{
		Vector v = new Vector(p, new Point(0, 0));
		return translate(v).rotate(theta).translate(v.reverse());
	}

	Point translate(Vector v) { return new Point(x + v.x , y + v.y); }

	Point reflectionPoint(Line l) 	//reflection point of p on line l
	{
		Point p = l.closestPoint(this);
		Vector v = new Vector(this, p);
		return this.translate(v).translate(v);
	}

	boolean between(Point p, Point q)			//it means that it is inside the rectangle created by these points , not on their line
	{
		return x <= Math.max(p.x, q.x) + EPS && x + EPS >= Math.min(p.x, q.x)
				&& y <= Math.max(p.y, q.y) + EPS && y + EPS >= Math.min(p.y, q.y);
	}

	//returns true if it is on the line defined by a and b
	boolean onLine(Point a, Point b)
	{
		if(a.compareTo(b) == 0) return compareTo(a) == 0;
		return Math.abs(new Vector(a, b).cross(new Vector(a, this))) < EPS;
	}

	boolean onSegment(Point a, Point b)
	{
		if(a.compareTo(b) == 0) return compareTo(a) == 0;
		return onRay(a, b) && onRay(b, a);
	}

	//returns true if it is on the ray whose start point is a and passes through b
	boolean onRay(Point a, Point b)
	{
		if(a.compareTo(b) == 0) return compareTo(a) == 0;
		return new Vector(a, b).normalize().equals(new Vector(a, this).normalize());
	}

	// returns true if r is on the left side of line pq (the order is of course importanrt)
	//if true  then p->q->r in counterclockwise direction
	//if false then p->q->r in clockwise direction
	// add EPS to LHS to accepts collinear points (means >=)
	static boolean ccw(Point p, Point q, Point r)			//positive cross product means counter-clockwise
	{
		return new Vector(p, q).cross(new Vector(p, r)) > 0;
	}

	static boolean collinear(Point p, Point q, Point r)
	{
		return Math.abs(new Vector(p, q).cross(new Vector(p, r))) < EPS;			//cross and dot are on vectors only
	}

	static double angle(Point a, Point o, Point b)  // angle AOB
	{
		Vector oa = new Vector(o, a), ob = new Vector(o, b);
		return Math.acos(oa.dot(ob) / Math.sqrt(oa.norm2() * ob.norm2()));			// it returns a positive angle
	}

	static double distToLine(Point p, Point a, Point b) //distance between point p and a line defined by points a, b (a != b)
	{
		if(a.compareTo(b) == 0) return p.dist(a);
		// formula: c = a + u * ab
		Vector ap = new Vector(a, p), ab = new Vector(a, b);
		double u = ap.dot(ab) / ab.norm2();			//u is a unit vector    // note here we divide by the square of ab (norm2)
		// to generate a ratio of the projection to the ab
		// hna momkn  el u tkon negative aw >1 3ady f kol 7aga hatzbot
		Point c = a.translate(ab.scale(u));
		return p.dist(c);
	}
	// Another way: find closest point and calculate the distance between it and p

	static double distToLineSegment(Point p, Point a, Point b)
	{
		Vector ap = new Vector(a, p), ab = new Vector(a, b);
		double u = ap.dot(ab) / ab.norm2();
		if (u < 0.0) return p.dist(a);
		if (u > 1.0) return p.dist(b);
		//8eer kda bat3aml m3ah ka2eno line 3ady 5las !
		return distToLine(p, a, b);
	}
	// Another way: find closest point and calculate the distance between it and p
}
class Vector {

	double x, y;

	Vector(double a, double b) { x = a; y = b; }

	Vector(Point a, Point b) { this(b.x - a.x, b.y - a.y); }

	Vector scale(double s) { return new Vector(x * s, y * s); }              //s is a non-negative value

	double dot(Vector v) { return (x * v.x + y * v.y); }

	double cross(Vector v) { return x * v.y - y * v.x; }

	double norm2() { return x * x + y * y; }					//only returns norm squared

	Vector reverse() { return new Vector(-x, -y); }

	Vector normalize() 					//get the unit vector of this vector
	{
		double d = Math.sqrt(norm2());
		return scale(1 / d);
	}
}

class Scanner
{
	StringTokenizer st;
	BufferedReader br;

	public Scanner(InputStream s){	br = new BufferedReader(new InputStreamReader(s));}

	public String next() throws IOException
	{
		while (st == null || !st.hasMoreTokens())
			st = new StringTokenizer(br.readLine());
		return st.nextToken();
	}

	public int nextInt() throws IOException {return Integer.parseInt(next());}

	public long nextLong() throws IOException {return Long.parseLong(next());}

	public String nextLine() throws IOException {return br.readLine();}

	public double nextDouble() throws IOException
	{
		String x = next();
		StringBuilder sb = new StringBuilder("0");
		double res = 0, f = 1;
		boolean dec = false, neg = false;
		int start = 0;
		if(x.charAt(0) == '-')
		{
			neg = true;
			start++;
		}
		for(int i = start; i < x.length(); i++)
			if(x.charAt(i) == '.')
			{
				res = Long.parseLong(sb.toString());
				sb = new StringBuilder("0");
				dec = true;
			}
			else
			{
				sb.append(x.charAt(i));
				if(dec)
					f *= 10;
			}
		res += Long.parseLong(sb.toString()) / f;
		return res * (neg?-1:1);
	}

	public boolean ready() throws IOException {return br.ready();}
}

class LineSegment implements Comparable {

	Point p, q ;
	double transp;
	LineSegment(Point a, Point b) { p = a; q = b; }

	LineSegment(Point a, Point b , double x) { p = a; q = b; transp=x;}

	boolean intersect(LineSegment ls)
	{
		Line l1 = new Line(p, q), l2 = new Line(ls.p, ls.q);
		if(l1.parallel(l2))
		{
			if(l1.same(l2))
				return p.between(ls.p, ls.q) || q.between(ls.p, ls.q) || ls.p.between(p, q) || ls.q.between(p, q);
			return false;
		}
		Point c = l1.intersect(l2);
		return c.between(p, q) && c.between(ls.p, ls.q) ;
	}

	Point rightPoint()
	{
		if(p.x>q.x)
			return p;
		else
			return q;
	}
	Point leftPoint()
	{
		if(p.x<q.x)
			return p;
		else
			return q;
	}

	@Override
	public int compareTo(Object o) {
		LineSegment line = (LineSegment) o;
		if(Math.abs(line. leftPoint().y-leftPoint().y)<0)
		{
			//return 0;
			if(line.rightPoint().y>leftPoint().y)
				return -1;
			if(line.rightPoint().y<leftPoint().y)
				return 1;
			return 0;
		}
		if(line. leftPoint().y> leftPoint().y)
			return -1;
		else
			if(line. leftPoint().y< leftPoint().y)
				return 1;
		return 0;
	}

}

class Polygon {
	// Cases to handle: collinear points, polygons with n < 3

	static final double EPS = 1e-9;

	Point[] g; 			//first point = last point, counter-clockwise representation

	Polygon(Point[] o) { g = o; }		//hya da5la bel a5era elzyada

	double perimeter()
	{
		double sum = 0.0;
		for(int i = 0; i < g.length - 1; ++i)
			sum += g[i].dist(g[i+1]);
		return sum;
	}

	double area() 		//clockwise/anti-clockwise check, for convex/concave polygons
	{
		//the method that sums areas of trapezoids under each line i.e summation( y[i]*x[i+1] - x[i]*y[i+1] ) from i=0 to i=n-1
		double area = 0.0;
		for(int i = 0; i < g.length - 1; ++i)
			area += g[i].x * g[i+1].y - g[i].y * g[i+1].x;
		return Math.abs(area) / 2.0;			//negative value in case of clockwise
	}

	boolean isConvex()
	{
		if(g.length <= 3) // point or line
			return false;
		boolean ccw = Point.ccw(g[g.length - 2], g[0], g[1]);		//edit ccw check to accept collinear points
		for(int i = 1; i < g.length - 1; ++i)
			if(Point.ccw(g[i-1], g[i], g[i+1]) != ccw)
				return false;
		return true;
	}

	boolean inside(Point p)	//for convex/concave polygons - winding number algorithm
	{
		double sum = 0.0;
		for(int i = 0; i < g.length - 1; ++i)
		{
			double angle = Point.angle(g[i], p, g[i+1]);			//always positive
			//if angle is zero or 180 -> it lies on the polygon so return true
			if((Math.abs(angle) < EPS || Math.abs(angle - Math.PI) < EPS) && p.between(g[i], g[i+1]))
				return true;
			if(Point.ccw(p, g[i], g[i+1]))		//if it is clockwise angle -> add else -> subtract
				sum += angle;
			else
				sum -= angle;
		}

		return Math.abs(2 * Math.PI - Math.abs(sum)) < EPS;		//abs makes it work for clockwise
	}
	/*
	 * Another way if the polygon is convex
	 * 1. Triangulate the poylgon through p
	 * 2. Check if sum areas == poygon area
	 * 3. Handle empty polygon
	 */

	Polygon cutPolygon(Point a, Point b)	//returns the left part of the polygon, swap a & b for the right part
	{
		Point[] ans = new Point[g.length<<1];
		Line l = new Line(a, b);
		Vector v = new Vector(a, b);

		int size = 0;
		for(int i = 0; i < g.length; ++i)
		{
			double left1 = v.cross(new Vector(a, g[i]));
			double left2 = i == g.length - 1 ? 0 : v.cross(new Vector(a, g[i+1]));		//ba5leh b zero fela5er 3shan mayd5olsh elcondition elly ta7t

			if(left1 + EPS > 0)
				ans[size++] = g[i];
			if(left1 * left2 + EPS < 0)				//this condition succeeds if left1 and left2 have opposite signs 3shan ya5odhom ray7 rag3 !!
				ans[size++] = l.intersect(new Line(g[i], g[i+1]));
		}

		if(size != 0 && ans[0] != ans[size-1])	//necessary in case g[0] is not in the new polygon
			ans[size++] = ans[0];
		return new Polygon(Arrays.copyOf(ans, size));
	}

	static Polygon convexHull(Point[] points)	//all points are unique, remove duplicates, edit ccw to accept collinear points
	{
		int n = points.length;
		Arrays.sort(points);
		Point[] ans = new Point[n<<1];
		int size = 0, start = 0;

		for(int i = 0; i < n; i++)
		{
			Point p = points[i];
			while(size - start >= 2 && !Point.ccw(ans[size-2], ans[size-1], p))	--size;
			ans[size++] = p;
		}
		start = --size;

		for(int i = n-1 ; i >= 0 ; i--)
		{
			Point p = points[i];
			while(size - start >= 2 && !Point.ccw(ans[size-2], ans[size-1], p))	--size;
			ans[size++] = p;
		}
		//			if(size < 0) size = 0			for empty set of points
		return new Polygon(Arrays.copyOf(ans, size));
	}

	Point centroid()		//center of mass
	{
		double cx = 0.0, cy = 0.0;
		for(int i = 0; i < g.length - 1; i++)
		{
			double x1 = g[i].x, y1 = g[i].y;
			double x2 = g[i+1].x, y2 = g[i+1].y;

			double f = x1 * y2 - x2 * y1;
			cx += (x1 + x2) * f;
			cy += (y1 + y2) * f;
		}
		double area = area();		//remove abs
		cx /= 6.0 * area;
		cy /= 6.0 * area;
		return new Point(cx, cy);
	}
	static double polygonArea (int numberOfSides , double SideLength)
	{
		return (SideLength*SideLength*numberOfSides)/ ( 4* Math.tan(Math.PI/numberOfSides) );
	}
}

class Line {

	static final double INF = 1e9, EPS = 1e-9;
	//we always try to make b=1 , if it is 0 then we make a=1
	//herein this representation a =-slope
	double a, b, c;

	Line(Point p, Point q)			//two options :    a=1 , b=0    (vertical)      OR   a=constant , b=1
	{
		if(Math.abs(p.x - q.x) < EPS) {	a = 1; b = 0; c = -p.x;	}	// x-s are equal --> the line is vertical ( a*x + 0*y + c = 0 )
		else
		{
			a = (p.y - q.y) / (q.x - p.x);				//slope = -a/b (ax+by+c=0)
			b = 1.0;
			c = -(a * p.x + p.y);
		}

	}
	Line(double hh , double w , double e)
	{
		if(w==0)
		{
			a=1;b=0;c=e/hh;
		}
		else
		{
			a=hh*1.0/w;b=1;c=e*1.0/w;
		}
	}
	//constructing a line using a point and a slope
	Line(Point p, double m) { a = -m; b = 1; c =  -(a * p.x + p.y); }

	boolean parallel(Line l) { return Math.abs(a - l.a) < EPS && Math.abs(b - l.b) < EPS; }

	boolean same(Line l) { return parallel(l) && Math.abs(c - l.c) < EPS; }

	Point intersect(Line l)
	{
		if(parallel(l))
			return null;
		double x = (b * l.c - c * l.b) / (a * l.b - b * l.a);				//using crammer
		double y;
		if(Math.abs(b) < EPS)			//check whether if the first is vertical or not
			y = -l.a * x - l.c;
		else
			y = -a * x - c;

		return new Point(x, y);
	}

	boolean intersectWithSegment(LineSegment l)
	{
		Point point = intersect(new Line(l.p,l.q));
		return (point!=null &&point.onSegment(l.p, l.q));

	}

	Point closestPoint(Point p)
	{
		if(Math.abs(b) < EPS) return new Point(-c, p.y);
		if(Math.abs(a) < EPS) return new Point(p.x, -c);
		return intersect(new Line(p, 1 / a));
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		int x1 = sc.nextInt();
		int y1 = sc.nextInt();
		int x2 = sc.nextInt();
		int y2 = sc.nextInt();
		Line original = new Line(new Point(x1,y1) , new Point(x2,y2));
		int n=sc.nextInt();
		int count=0;
		for(int i=0;i<n;i++)
		{
			int a=sc.nextInt();
			int b = sc.nextInt();
			int c = sc.nextInt();
			Line l = new Line(a*1.0/b,1.0,c*1.0/b);
			Point point = l.intersect(original);
			if(point!=null &&point.onSegment(new Point(x1,y1), new Point(x2,y2)));
				count++;
		}
		System.out.println(count);
	}

}
class Point implements Comparable<Point>{

	static final double EPS = 1e-9;

	double x, y;

	Point(double a, double b)
	{
		x = a; y = b;
	}

	public String toString()
	{
		return x+" "+y;
	}

	public int compareTo(Point p)
	{
		if(Math.abs(x - p.x) > EPS) return x > p.x ? 1 : -1;
		if(Math.abs(y - p.y) > EPS) return y > p.y ? 1 : -1;
		return 0;
	}

	public double dist(Point p) { return Math.sqrt(sq(x - p.x) + sq(y - p.y)); }

	static double sq(double x) { return x * x; }

	Point rotate(double angle)				//rotate around (0,0)
	{
		double c = Math.cos(angle), s = Math.sin(angle);
		return new Point(x * c - y * s, x * s + y * c);
	}
	// for integer points and rotation by 90 (counterclockwise) : swap x and y, negate x

	Point rotate(double theta, Point p)			//rotate around p
	{
		Vector v = new Vector(p, new Point(0, 0));
		return translate(v).rotate(theta).translate(v.reverse());
	}

	Point translate(Vector v) { return new Point(x + v.x , y + v.y); }

	Point reflectionPoint(Line l) 	//reflection point of p on line l
	{
		Point p = l.closestPoint(this);
		Vector v = new Vector(this, p);
		return this.translate(v).translate(v);
	}

	boolean between(Point p, Point q)			//it means that it is inside the rectangle created by these points , not on their line
	{
		return x <= Math.max(p.x, q.x) + EPS && x + EPS >= Math.min(p.x, q.x)
				&& y <= Math.max(p.y, q.y) + EPS && y + EPS >= Math.min(p.y, q.y);
	}

	//returns true if it is on the line defined by a and b
	boolean onLine(Point a, Point b)
	{
		if(a.compareTo(b) == 0) return compareTo(a) == 0;
		return Math.abs(new Vector(a, b).cross(new Vector(a, this))) < EPS;
	}

	boolean onSegment(Point a, Point b)
	{
		if(a.compareTo(b) == 0) return compareTo(a) == 0;
		return onRay(a, b) && onRay(b, a);
	}

	//returns true if it is on the ray whose start point is a and passes through b
	boolean onRay(Point a, Point b)
	{
		if(a.compareTo(b) == 0) return compareTo(a) == 0;
		return new Vector(a, b).normalize().equals(new Vector(a, this).normalize());
	}

	// returns true if r is on the left side of line pq (the order is of course importanrt)
	//if true  then p->q->r in counterclockwise direction
	//if false then p->q->r in clockwise direction
	// add EPS to LHS to accepts collinear points (means >=)
	static boolean ccw(Point p, Point q, Point r)			//positive cross product means counter-clockwise
	{
		return new Vector(p, q).cross(new Vector(p, r)) > 0;
	}

	static boolean collinear(Point p, Point q, Point r)
	{
		return Math.abs(new Vector(p, q).cross(new Vector(p, r))) < EPS;			//cross and dot are on vectors only
	}

	static double angle(Point a, Point o, Point b)  // angle AOB
	{
		Vector oa = new Vector(o, a), ob = new Vector(o, b);
		return Math.acos(oa.dot(ob) / Math.sqrt(oa.norm2() * ob.norm2()));			// it returns a positive angle
	}

	static double distToLine(Point p, Point a, Point b) //distance between point p and a line defined by points a, b (a != b)
	{
		if(a.compareTo(b) == 0) return p.dist(a);
		// formula: c = a + u * ab
		Vector ap = new Vector(a, p), ab = new Vector(a, b);
		double u = ap.dot(ab) / ab.norm2();			//u is a unit vector    // note here we divide by the square of ab (norm2)
		// to generate a ratio of the projection to the ab
		// hna momkn  el u tkon negative aw >1 3ady f kol 7aga hatzbot
		Point c = a.translate(ab.scale(u));
		return p.dist(c);
	}
	// Another way: find closest point and calculate the distance between it and p

	static double distToLineSegment(Point p, Point a, Point b)
	{
		Vector ap = new Vector(a, p), ab = new Vector(a, b);
		double u = ap.dot(ab) / ab.norm2();
		if (u < 0.0) return p.dist(a);
		if (u > 1.0) return p.dist(b);
		//8eer kda bat3aml m3ah ka2eno line 3ady 5las !
		return distToLine(p, a, b);
	}
	// Another way: find closest point and calculate the distance between it and p
}
class Vector {

	double x, y;

	Vector(double a, double b) { x = a; y = b; }

	Vector(Point a, Point b) { this(b.x - a.x, b.y - a.y); }

	Vector scale(double s) { return new Vector(x * s, y * s); }              //s is a non-negative value

	double dot(Vector v) { return (x * v.x + y * v.y); }

	double cross(Vector v) { return x * v.y - y * v.x; }

	double norm2() { return x * x + y * y; }					//only returns norm squared

	Vector reverse() { return new Vector(-x, -y); }

	Vector normalize() 					//get the unit vector of this vector
	{
		double d = Math.sqrt(norm2());
		return scale(1 / d);
	}
}

class Scanner
{
	StringTokenizer st;
	BufferedReader br;

	public Scanner(InputStream s){	br = new BufferedReader(new InputStreamReader(s));}

	public String next() throws IOException
	{
		while (st == null || !st.hasMoreTokens())
			st = new StringTokenizer(br.readLine());
		return st.nextToken();
	}

	public int nextInt() throws IOException {return Integer.parseInt(next());}

	public long nextLong() throws IOException {return Long.parseLong(next());}

	public String nextLine() throws IOException {return br.readLine();}

	public double nextDouble() throws IOException
	{
		String x = next();
		StringBuilder sb = new StringBuilder("0");
		double res = 0, f = 1;
		boolean dec = false, neg = false;
		int start = 0;
		if(x.charAt(0) == '-')
		{
			neg = true;
			start++;
		}
		for(int i = start; i < x.length(); i++)
			if(x.charAt(i) == '.')
			{
				res = Long.parseLong(sb.toString());
				sb = new StringBuilder("0");
				dec = true;
			}
			else
			{
				sb.append(x.charAt(i));
				if(dec)
					f *= 10;
			}
		res += Long.parseLong(sb.toString()) / f;
		return res * (neg?-1:1);
	}

	public boolean ready() throws IOException {return br.ready();}
}

class LineSegment implements Comparable {

	Point p, q ;
	double transp;
	LineSegment(Point a, Point b) { p = a; q = b; }

	LineSegment(Point a, Point b , double x) { p = a; q = b; transp=x;}

	boolean intersect(LineSegment ls)
	{
		Line l1 = new Line(p, q), l2 = new Line(ls.p, ls.q);
		if(l1.parallel(l2))
		{
			if(l1.same(l2))
				return p.between(ls.p, ls.q) || q.between(ls.p, ls.q) || ls.p.between(p, q) || ls.q.between(p, q);
			return false;
		}
		Point c = l1.intersect(l2);
		return c.between(p, q) && c.between(ls.p, ls.q) ;
	}

	Point rightPoint()
	{
		if(p.x>q.x)
			return p;
		else
			return q;
	}
	Point leftPoint()
	{
		if(p.x<q.x)
			return p;
		else
			return q;
	}

	@Override
	public int compareTo(Object o) {
		LineSegment line = (LineSegment) o;
		if(Math.abs(line. leftPoint().y-leftPoint().y)<0)
		{
			//return 0;
			if(line.rightPoint().y>leftPoint().y)
				return -1;
			if(line.rightPoint().y<leftPoint().y)
				return 1;
			return 0;
		}
		if(line. leftPoint().y> leftPoint().y)
			return -1;
		else
			if(line. leftPoint().y< leftPoint().y)
			return 1;
		return 0;
	}

}

class Polygon {
	// Cases to handle: collinear points, polygons with n < 3

	static final double EPS = 1e-9;

	Point[] g; 			//first point = last point, counter-clockwise representation

	Polygon(Point[] o) { g = o; }		//hya da5la bel a5era elzyada

	double perimeter()
	{
		double sum = 0.0;
		for(int i = 0; i < g.length - 1; ++i)
			sum += g[i].dist(g[i+1]);
		return sum;
	}

	double area() 		//clockwise/anti-clockwise check, for convex/concave polygons
	{
		//the method that sums areas of trapezoids under each line i.e summation( y[i]*x[i+1] - x[i]*y[i+1] ) from i=0 to i=n-1
		double area = 0.0;
		for(int i = 0; i < g.length - 1; ++i)
			area += g[i].x * g[i+1].y - g[i].y * g[i+1].x;
		return Math.abs(area) / 2.0;			//negative value in case of clockwise
	}

	boolean isConvex()
	{
		if(g.length <= 3) // point or line
			return false;
		boolean ccw = Point.ccw(g[g.length - 2], g[0], g[1]);		//edit ccw check to accept collinear points
		for(int i = 1; i < g.length - 1; ++i)
			if(Point.ccw(g[i-1], g[i], g[i+1]) != ccw)
				return false;
		return true;
	}

	boolean inside(Point p)	//for convex/concave polygons - winding number algorithm
	{
		double sum = 0.0;
		for(int i = 0; i < g.length - 1; ++i)
		{
			double angle = Point.angle(g[i], p, g[i+1]);			//always positive
			//if angle is zero or 180 -> it lies on the polygon so return true
			if((Math.abs(angle) < EPS || Math.abs(angle - Math.PI) < EPS) && p.between(g[i], g[i+1]))
				return true;
			if(Point.ccw(p, g[i], g[i+1]))		//if it is clockwise angle -> add else -> subtract
				sum += angle;
			else
				sum -= angle;
		}

		return Math.abs(2 * Math.PI - Math.abs(sum)) < EPS;		//abs makes it work for clockwise
	}
	/*
	 * Another way if the polygon is convex
	 * 1. Triangulate the poylgon through p
	 * 2. Check if sum areas == poygon area
	 * 3. Handle empty polygon
	 */

	Polygon cutPolygon(Point a, Point b)	//returns the left part of the polygon, swap a & b for the right part
	{
		Point[] ans = new Point[g.length<<1];
		Line l = new Line(a, b);
		Vector v = new Vector(a, b);

		int size = 0;
		for(int i = 0; i < g.length; ++i)
		{
			double left1 = v.cross(new Vector(a, g[i]));
			double left2 = i == g.length - 1 ? 0 : v.cross(new Vector(a, g[i+1]));		//ba5leh b zero fela5er 3shan mayd5olsh elcondition elly ta7t

			if(left1 + EPS > 0)
				ans[size++] = g[i];
			if(left1 * left2 + EPS < 0)				//this condition succeeds if left1 and left2 have opposite signs 3shan ya5odhom ray7 rag3 !!
				ans[size++] = l.intersect(new Line(g[i], g[i+1]));
		}

		if(size != 0 && ans[0] != ans[size-1])	//necessary in case g[0] is not in the new polygon
			ans[size++] = ans[0];
		return new Polygon(Arrays.copyOf(ans, size));
	}

	static Polygon convexHull(Point[] points)	//all points are unique, remove duplicates, edit ccw to accept collinear points
	{
		int n = points.length;
		Arrays.sort(points);
		Point[] ans = new Point[n<<1];
		int size = 0, start = 0;

		for(int i = 0; i < n; i++)
		{
			Point p = points[i];
			while(size - start >= 2 && !Point.ccw(ans[size-2], ans[size-1], p))	--size;
			ans[size++] = p;
		}
		start = --size;

		for(int i = n-1 ; i >= 0 ; i--)
		{
			Point p = points[i];
			while(size - start >= 2 && !Point.ccw(ans[size-2], ans[size-1], p))	--size;
			ans[size++] = p;
		}
		//			if(size < 0) size = 0			for empty set of points
		return new Polygon(Arrays.copyOf(ans, size));
	}

	Point centroid()		//center of mass
	{
		double cx = 0.0, cy = 0.0;
		for(int i = 0; i < g.length - 1; i++)
		{
			double x1 = g[i].x, y1 = g[i].y;
			double x2 = g[i+1].x, y2 = g[i+1].y;

			double f = x1 * y2 - x2 * y1;
			cx += (x1 + x2) * f;
			cy += (y1 + y2) * f;
		}
		double area = area();		//remove abs
		cx /= 6.0 * area;
		cy /= 6.0 * area;
		return new Point(cx, cy);
	}
	static double polygonArea (int numberOfSides , double SideLength)
	{
		return (SideLength*SideLength*numberOfSides)/ ( 4* Math.tan(Math.PI/numberOfSides) );
	}
}

class Line {

	static final double INF = 1e9, EPS = 1e-9;
	//we always try to make b=1 , if it is 0 then we make a=1
	//herein this representation a =-slope
	double a, b, c;

	Line(Point p, Point q)			//two options :    a=1 , b=0    (vertical)      OR   a=constant , b=1
	{
		if(Math.abs(p.x - q.x) < EPS) {	a = 1; b = 0; c = -p.x;	}	// x-s are equal --> the line is vertical ( a*x + 0*y + c =0 )
		else
		{
			a = (p.y - q.y) / (q.x - p.x);				//slope = -a/b (ax+by+c=0)
			b = 1.0;
			c = -(a * p.x + p.y);
		}

	}
	Line(double q , double w , double e)
	{
		a=q;b=w;c=e;
	}
	//constructing a line using a point and a slope
	Line(Point p, double m) { a = -m; b = 1; c =  -(a * p.x + p.y); }

	boolean parallel(Line l) { return Math.abs(a - l.a) < EPS && Math.abs(b - l.b) < EPS; }

	boolean same(Line l) { return parallel(l) && Math.abs(c - l.c) < EPS; }

	Point intersect(Line l)
	{
		if(parallel(l))
			return null;
		double x = (b * l.c - c * l.b) / (a * l.b - b * l.a);				//using crammer
		double y;
		if(Math.abs(b) < EPS)			//check whether if the first is vertical or not
			y = -l.a * x - l.c;
		else
			y = -a * x - c;

		return new Point(x, y);
	}

	boolean intersectWithSegment(LineSegment l)
	{
		Point point = intersect(new Line(l.p,l.q));
		return (point!=null &&point.onSegment(l.p, l.q));

	}

	Point closestPoint(Point p)
	{
		if(Math.abs(b) < EPS) return new Point(-c, p.y);
		if(Math.abs(a) < EPS) return new Point(p.x, -c);
		return intersect(new Line(p, 1 / a));
	}

}


import java.io.*;
import java.util.*;
//public final class code
class code
{
	static void solve()throws IOException
	{
		long x1=nextLong();
		long y1=nextLong();
		long x2=nextLong();
		long y2=nextLong();
		int n=nextInt();
		int count=0;
		while(n-->0)
		{
			long a=nextLong();
			long b=nextLong();
			long c=nextLong();
			long first=a*x1+b*y1+c;
			long second=a*x2+b*y2+c;
			if(first>0 && second<0 || first<0 && second>0)
				count++;
		}
		out.println(count);

	}

	///////////////////////////////////////////////////////////
	static final long mod=(long)(1e9+7);
	static final int inf=(int)(1e9);
	static class Pair
	{
		long first,second;
		Pair(int a,int b)
		{
			first=a;
			second=b;
		}
		// public int compareTo(Pair p)
		// {
		// 	return this.second-p.second;
		// }
	}
	static BufferedReader br;
	static StringTokenizer st;
	static PrintWriter out;
	static String nextToken()throws IOException
	{
		while(st==null || !st.hasMoreTokens())
			st=new StringTokenizer(br.readLine());
		return st.nextToken();
	}
	static String nextLine()throws IOException
	{
		return br.readLine();
	}
	static int nextInt()throws IOException
	{
		return Integer.parseInt(nextToken());
	}
	static long nextLong()throws IOException
	{
		return Long.parseLong(nextToken());
	}
	static double nextDouble()throws IOException
	{
		return Double.parseDouble(nextToken());
	}
	public static void main(String args[])throws IOException
	{
		br=new BufferedReader(new InputStreamReader(System.in));
		out=new PrintWriter(new BufferedOutputStream(System.out));
		solve();
		out.close();
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class CF498A {
	static double EPS = 1e-9;
	public static void main(String[] args) throws NumberFormatException, IOException {
		Scanner sc = new Scanner(System.in);

		Point home = new Point(sc.nextInt(), sc.nextInt());
		Point uni = new Point(sc.nextInt(), sc.nextInt());
		LineSegment ls = new LineSegment(home, uni);
		int n = sc.nextInt();
		int ans = 0;
		while(n-- > 0) {
			Line l  = new Line(sc.nextInt(), sc.nextInt(), sc.nextInt());
			if(l.intersectSegment(ls) != null)
				ans++;
		}
		System.out.println(ans);
	}

	static class Point {
		double x, y;
		Point(double x, double y) {this.x = x; this.y = y; }
		boolean between(Point p, Point q) {
			return x < Math.max(p.x, q.x) + EPS && x + EPS > Math.min(p.x, q.x)
					&& y < Math.max(p.y, q.y) + EPS && y + EPS > Math.min(p.y, q.y);

		}
	}

	static class Line {
		double a, b, c;

		Line(double a, double b, double c) {
			this.a = a;
			this.b = b;
			this.c = c;
		}

		Line(Point p, Point q) {
			if(p.x == q.x) {a = 1.0; b = 0.0; c = -p.x; }
			else {
				a = (p.y - q.y) / (q.x - p.x);
				b = 1.0;
				c = - (a * p.x + p.y);
			}
		}
		static double abs (double x) {return Math.abs(x); }

		boolean parallel(Line l) { return abs(a - l.a) < EPS && abs(b - l.b) < EPS; }
		Point intersect(Line l) {
			if(parallel(l))
				return null;
			double x = (b * l.c - l.b * c) / (a * l.b - l.a * b);
			double y;
			if(abs(b) < EPS) //if (b == 0), first line is vertical, substitute in second line equation
				y = -l.c - l.a * x;
			else //only one of the two lines can be vertical
				y = -c - a * x;

			return new Point(x, y);
		}

		Point intersectSegment(LineSegment ls) {
			Line l = new Line(ls.p, ls.q);
			Point c = this.intersect(l);
			if(c.between(ls.p, ls.q))
				return c;
			return null;
		}
	}
	static class LineSegment {
		Point p, q;
		LineSegment(Point p, Point q) {this.p = p; this.q = q;}
	}
	static class Scanner {
		BufferedReader br;
		StringTokenizer st;

		Scanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		String nextLine() throws IOException {
			return br.readLine();
		}

		int nextInt() throws NumberFormatException, IOException {
			return Integer.parseInt(next());
		}

		boolean ready() throws IOException {
			return br.ready();
		}
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class CF498A {
	static double EPS = 1e-9;
	public static void main(String[] args) throws NumberFormatException, IOException {
		Scanner sc = new Scanner(System.in);

		Point home = new Point(sc.nextInt(), sc.nextInt());
		Point uni = new Point(sc.nextInt(), sc.nextInt());
		int n = sc.nextInt();
		int ans = 0;
		while(n-- > 0) {
			Line l  = new Line(sc.nextInt(), sc.nextInt(), sc.nextInt());
			if(!l.onSameSide(home, uni))
				ans++;
		}
		System.out.println(ans);
	}

	static class Point {
		double x, y;
		Point(double x, double y) {this.x = x; this.y = y; }

	}

	static class Line {
		double a, b, c;

		Line(double a, double b, double c) {
			this.a = a;
			this.b = b;
			this.c = c;
		}

		Line(Point p, Point q) {
			if(p.x == q.x) {a = 1.0; b = 0.0; c = -p.x; }
			else {
				a = (p.y - q.y) / (q.x - p.x);
				b = 1.0;
				c = - (a * p.x + p.y);
			}
		}
		boolean onSameSide(Point p, Point q) {
			boolean posP = a * p.x + b* p.y + c > 0.0;
			boolean posQ = a * q.x + b * q.y + c > 0.0;
			return !(posP ^ posQ);
		}

	}
	static class Scanner {
		BufferedReader br;
		StringTokenizer st;

		Scanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		String nextLine() throws IOException {
			return br.readLine();
		}

		int nextInt() throws NumberFormatException, IOException {
			return Integer.parseInt(next());
		}

		boolean ready() throws IOException {
			return br.ready();
		}
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

import geometry.Line;
import geometry.Point;
import geometry.Vector;

public class CF498A {
	static double EPS = 1e-9;
	public static void main(String[] args) throws NumberFormatException, IOException {
		Scanner sc = new Scanner(System.in);

		Point home = new Point(sc.nextInt(), sc.nextInt());
		Point uni = new Point(sc.nextInt(), sc.nextInt());
		LineSegment ls = new LineSegment(home, uni);
		int n = sc.nextInt();
		int ans = 0;
		while(n-- > 0) {
			Line l  = new Line(sc.nextInt(), sc.nextInt(), sc.nextInt());
			Point c1 = l.closestPoint(home);
			Point c2 = l.closestPoint(uni);
			Vector v1 = new Vector(c1, home).normaize();
			Vector v2 = new Vector(c2, uni).normaize();
//			System.out.println(v1.x + " " + v1.y);
//			System.out.println(v2.x + " " + v2.y);
			if(!v1.equals(v2))
				ans++;
		}
		System.out.println(ans);
	}

	static class Point {
		double x, y;
		Point(double x, double y) {this.x = x; this.y = y; }
		boolean between(Point p, Point q) {
			return x < Math.max(p.x, q.x) + EPS && x + EPS > Math.min(p.x, q.x)
					&& y < Math.max(p.y, q.y) + EPS && y + EPS > Math.min(p.y, q.y);

		}

		static boolean ccw(Point p, Point q, Point r)
		{
			return new Vector(p, q).cross(new Vector(p, r)) > 0;
		}
	}
	static class Vector {
		double x, y;
		Vector(Point p, Point q) {
			this.x = q.x - p.x;
			this.y = q.y - p.y;
		}
		double cross(Vector v) {
			return x * v.y - y * v.x;
		}
		double normSqr() { return x*x + y*y; }
		Vector(double x, double y) {this.x = x; this.y = y; }
		Vector scale(double s) { return new Vector(x * s, y * s); }
		Vector normaize() { double d = Math.sqrt(normSqr());
		return scale(1 / d); }
		@Override
		public boolean equals(Object obj) {
			Vector v = (Vector) obj;
			return Math.abs(x - v.x) < EPS && Math.abs(y - v.y) < EPS;
		}
	}
	static class Line {
		double a, b, c;

		Line(double a, double b, double c) {
			this.a = a;
			this.b = b;
			this.c = c;
		}

		Line(Point p, Point q) {
			if(p.x == q.x) {a = 1.0; b = 0.0; c = -p.x; }
			else {
				a = (p.y - q.y) / (q.x - p.x);
				b = 1.0;
				c = - (a * p.x + p.y);
			}
		}
		static double abs (double x) {return Math.abs(x); }

		boolean parallel(Line l) { return abs(a - l.a) < EPS && abs(b - l.b) < EPS; }
		Point intersect(Line l) {
			if(parallel(l))
				return null;
			double x = (b * l.c - l.b * c) / (a * l.b - l.a * b);
			double y;
			if(abs(b) < EPS) //if (b == 0), first line is vertical, substitute in second line equation
				y = -l.c - l.a * x;
			else //only one of the two lines can be vertical
				y = -c - a * x;

			return new Point(x, y);
		}

		Point intersectSegment(LineSegment ls) {
			Line l = new Line(ls.p, ls.q);
			Point c = this.intersect(l);
			System.out.println(c.x + " " + c.y);
			System.out.println(c.between(ls.p, ls.q));
			if(c.between(ls.p, ls.q))
				return c;
			return null;
		}

		Point closestPoint(Point p) {
			if(abs(b) < EPS) return new Point(-c, p.y); //line is x = -c
			if(abs(a) < EPS) return new Point(p.x, -c);// line is y = -c

			return intersect(new Line(p, 1/a)); //since for perpendicular lines m1 = -1/m2 and m1 = -a, then m2 = 1/a
		}
		Line(Point p, double m) {
			a = -m; b = 1.0; c = -(a * p.x + p.y);
		}
	}
	static class LineSegment {
		Point p, q;
		LineSegment(Point p, Point q) {this.p = p; this.q = q;}
	}
	static class Scanner {
		BufferedReader br;
		StringTokenizer st;

		Scanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		String nextLine() throws IOException {
			return br.readLine();
		}

		int nextInt() throws NumberFormatException, IOException {
			return Integer.parseInt(next());
		}

		boolean ready() throws IOException {
			return br.ready();
		}
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class CF498A {
	static double EPS = 1e-9;
	public static void main(String[] args) throws NumberFormatException, IOException {
		Scanner sc = new Scanner(System.in);

		Point home = new Point(sc.nextInt(), sc.nextInt());
		Point uni = new Point(sc.nextInt(), sc.nextInt());
		LineSegment ls = new LineSegment(home, uni);
		int n = sc.nextInt();
		int ans = 0;
		while(n-- > 0) {
			Line l  = new Line(sc.nextInt(), sc.nextInt(), sc.nextInt());
			Point c1 = l.closestPoint(home);
			Point c2 = l.closestPoint(uni);
			Vector v1 = new Vector(c1, home).normaize();
			Vector v2 = new Vector(c2, uni).normaize();
//			System.out.println(v1.x + " " + v1.y);
//			System.out.println(v2.x + " " + v2.y);
			if(!v1.equals(v2))
				ans++;
		}
		System.out.println(ans);
	}

	static class Point {
		double x, y;
		Point(double x, double y) {this.x = x; this.y = y; }
		boolean between(Point p, Point q) {
			return x < Math.max(p.x, q.x) + EPS && x + EPS > Math.min(p.x, q.x)
					&& y < Math.max(p.y, q.y) + EPS && y + EPS > Math.min(p.y, q.y);

		}

		static boolean ccw(Point p, Point q, Point r)
		{
			return new Vector(p, q).cross(new Vector(p, r)) > 0;
		}
	}
	static class Vector {
		double x, y;
		Vector(Point p, Point q) {
			this.x = q.x - p.x;
			this.y = q.y - p.y;
		}
		double cross(Vector v) {
			return x * v.y - y * v.x;
		}
		double normSqr() { return x*x + y*y; }
		Vector(double x, double y) {this.x = x; this.y = y; }
		Vector scale(double s) { return new Vector(x * s, y * s); }
		Vector normaize() { double d = Math.sqrt(normSqr());
		return scale(1 / d); }
		@Override
		public boolean equals(Object obj) {
			Vector v = (Vector) obj;
			return Math.abs(x - v.x) < EPS && Math.abs(y - v.y) < EPS;
		}
	}
	static class Line {
		double a, b, c;

		Line(double a, double b, double c) {
			this.a = a;
			this.b = b;
			this.c = c;
		}

		Line(Point p, Point q) {
			if(p.x == q.x) {a = 1.0; b = 0.0; c = -p.x; }
			else {
				a = (p.y - q.y) / (q.x - p.x);
				b = 1.0;
				c = - (a * p.x + p.y);
			}
		}
		static double abs (double x) {return Math.abs(x); }

		boolean parallel(Line l) { return abs(a - l.a) < EPS && abs(b - l.b) < EPS; }
		Point intersect(Line l) {
			if(parallel(l))
				return null;
			double x = (b * l.c - l.b * c) / (a * l.b - l.a * b);
			double y;
			if(abs(b) < EPS) //if (b == 0), first line is vertical, substitute in second line equation
				y = -l.c - l.a * x;
			else //only one of the two lines can be vertical
				y = -c - a * x;

			return new Point(x, y);
		}

		Point intersectSegment(LineSegment ls) {
			Line l = new Line(ls.p, ls.q);
			Point c = this.intersect(l);
			System.out.println(c.x + " " + c.y);
			System.out.println(c.between(ls.p, ls.q));
			if(c.between(ls.p, ls.q))
				return c;
			return null;
		}

		Point closestPoint(Point p) {
			if(abs(b) < EPS) return new Point(-c, p.y); //line is x = -c
			if(abs(a) < EPS) return new Point(p.x, -c);// line is y = -c

			return intersect(new Line(p, 1/a)); //since for perpendicular lines m1 = -1/m2 and m1 = -a, then m2 = 1/a
		}
		Line(Point p, double m) {
			a = -m; b = 1.0; c = -(a * p.x + p.y);
		}
	}
	static class LineSegment {
		Point p, q;
		LineSegment(Point p, Point q) {this.p = p; this.q = q;}
	}
	static class Scanner {
		BufferedReader br;
		StringTokenizer st;

		Scanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		String nextLine() throws IOException {
			return br.readLine();
		}

		int nextInt() throws NumberFormatException, IOException {
			return Integer.parseInt(next());
		}

		boolean ready() throws IOException {
			return br.ready();
		}
	}
}


import java.util.Scanner;

public class CF {
	static final double EPS=0;
	static class Point{
		double x,y;
		public Point(double x,double y) {
			this.x= x;
			this.y=y;
		}
	}

	static class Line{
		double a,b,c;
		double slope;
		Point pl1,pl2;
		public Line(double d, double bb,double e) {
			a=d;
			b=bb;
			c=e;
			slope=-a/b;
		}
		boolean inter(Line l) {
			return !(this.slope-l.slope==EPS);
		}
		boolean interSeg(Line l,Point p1,Point p2) {
			if(inter(l)) {
				if(this.b==0) {
					pl1= new Point(-c/a,0);
					pl2= new Point(-c/a,1);
				}
				else {
					pl1= new Point(1,-(this.c+this.a)/b);
					pl2= new Point(0,-this.c/b);
				}
				Point v = new Point(pl2.x-pl1.x,pl2.y-pl1.y);
				Point v2=new Point(p1.x-pl1.x,p1.y-pl1.y);
				Point v3=new Point(p2.x-pl1.x,p2.y-pl1.y);
				double cp1 = v.x*v2.y-v.y*v2.x;
				double cp2 = v.x*v3.y-v.y*v3.x;
				return ((cp1>EPS&&cp2<-EPS) ||(cp2>EPS&&cp1<-EPS));
			}
			return false;
		}
	}

	public static void main(String[] args) {
	int xa,ya,xb,yb;
	int c=0;
	Scanner sc = new Scanner(System.in);
	xa= sc.nextInt();
	ya= sc.nextInt();
	xb= sc.nextInt();
	yb= sc.nextInt();
	double slope = ((yb-ya)/(xb-xa));
	int n=sc.nextInt();
	Line base = new Line(-1*slope, 1,slope*xa-ya );
	Line[] arr = new Line[n];
	for(int i =0;i<n;i++) {
		arr[i]=new Line(sc.nextInt(),sc.nextInt(),sc.nextInt());
		if(arr[i].interSeg(base, new Point(xa, ya), new Point(xb, yb))) {
//		if(arr[i].inter(base)) {
		c++;
		}
	}
	System.out.println(c);
}
}


import java.util.Scanner;

public class CF {
	static final double EPS=0;
	static class Point{
		double x,y;
		public Point(double x,double y) {
			this.x= x;
			this.y=y;
		}
	}

	static class Line{
		double a,b,c;
		double slope;
		Point pl1,pl2;
		public Line(double d, double bb,double e) {
			a=d;
			b=bb;
			c=e;
			slope=-a/b;
		}
		boolean inter(Line l) {
			return !(this.slope-l.slope==EPS);
		}
		boolean interSeg(Line l,Point p1,Point p2) {
			if(inter(l)) {
				if(this.b==0) {
					pl1= new Point(-c/a,0);
					pl2= new Point(-c/a,1);
				}
				else {
					pl1= new Point(1,-(this.c+this.a)/b);
					pl2= new Point(0,-this.c/b);
				}
				Point v = new Point(pl2.x-pl1.x,pl2.y-pl1.y);
				Point v2=new Point(p1.x-pl1.x,p1.y-pl1.y);
				Point v3=new Point(p2.x-pl1.x,p2.y-pl1.y);
				double cp1 = v.x*v2.y-v.y*v2.x;
				double cp2 = v.x*v3.y-v.y*v3.x;
				return ((cp1>EPS&&cp2<-EPS) ||(cp2>EPS&&cp1<-EPS));
			}
			return false;
		}
	}

	public static void main(String[] args) {
	double xa,ya,xb,yb;
	int c=0;
	Scanner sc = new Scanner(System.in);
	xa= sc.nextInt();
	ya= sc.nextInt();
	xb= sc.nextInt();
	yb= sc.nextInt();
	double slope = ((yb-ya)/(xb-xa));
	int n=sc.nextInt();
	Line base = new Line(-1*slope, 1,slope*xa-ya );
	Line[] arr = new Line[n];
	for(int i =0;i<n;i++) {
		arr[i]=new Line(sc.nextInt(),sc.nextInt(),sc.nextInt());
		if(arr[i].interSeg(base, new Point(xa, ya), new Point(xb, yb))) {
//		if(arr[i].inter(base)) {
		c++;
		}
	}
	System.out.println(c);
}
}


import java.util.Scanner;

public class CF {
	static final double EPS=0;
	static class Point{
		double x,y;
		public Point(double x,double y) {
			this.x= x;
			this.y=y;
		}
	}

	static class Line{
		double a,b,c;
		double slope;
		Point pl1,pl2;
		public Line(double d, double bb,double e) {
			a=d;
			b=bb;
			c=e;
			slope=-a/b;
		}
		boolean inter(Line l) {
			return !(this.slope-l.slope==EPS);
		}
		boolean interSeg(Line l,Point p1,Point p2) {
			if(inter(l)) {
				if(this.b==0) {
					pl1= new Point(-c/a,0);
					pl2= new Point(-c/a,1);
				}
				else {
					pl1= new Point(1,-(this.c+this.a)/b);
					pl2= new Point(0,-this.c/b);
				}
				Point v = new Point(pl2.x-pl1.x,pl2.y-pl1.y);
				Point v2=new Point(p1.x-pl1.x,p1.y-pl1.y);
				Point v3=new Point(p2.x-pl1.x,p2.y-pl1.y);
				double cp1 = v.x*v2.y-v.y*v2.x;
				double cp2 = v.x*v3.y-v.y*v3.x;
				return ((cp1>EPS&&cp2<-EPS) ||(cp2>EPS&&cp1<-EPS));
			}
			return false;
		}
	}

	public static void main(String[] args) {
	int xa,ya,xb,yb;
	int c=0;
	Scanner sc = new Scanner(System.in);
	xa= sc.nextInt();
	ya= sc.nextInt();
	xb= sc.nextInt();
	yb= sc.nextInt();
	double slope = ((yb-ya)/(xb-xa));
	System.out.println(slope);
	int n=sc.nextInt();
	Line base = new Line(-1*slope, 1,slope*xa-ya );
	Line[] arr = new Line[n];
	for(int i =0;i<n;i++) {
		arr[i]=new Line(sc.nextInt(),sc.nextInt(),sc.nextInt());
		if(arr[i].interSeg(base, new Point(xa, ya), new Point(xb, yb))) {
//		if(arr[i].inter(base)) {
		c++;
		}
	}
	System.out.println(c);
}
}


import java.util.Scanner;

public class CF {
	static final double EPS=0;
	static class Point{
		double x,y;
		public Point(double x,double y) {
			this.x= x;
			this.y=y;
		}
	}

	static class Line{
		double a,b,c;
		double slope;
		Point pl1,pl2;
		public Line(double d, double bb,double e) {
			a=d;
			b=bb;
			c=e;
			slope=-a/b;
		}
		boolean inter(Line l) {
			return (this.slope-l.slope<EPS);
		}
		boolean interSeg(Line l,Point p1,Point p2) {
			if(inter(l)) {
				if(this.b==0) {
					pl1= new Point(-c/a,0);
					pl2= new Point(-c/a,1);
				}
				else {
					pl1= new Point(1,-(this.c+this.a)/b);
					pl2= new Point(0,-this.c/b);
				}
				Point v = new Point(pl2.x-pl1.x,pl2.y-pl1.y);
				Point v2=new Point(p1.x-pl1.x,p1.y-pl1.y);
				Point v3=new Point(p2.x-pl1.x,p2.y-pl1.y);
				double cp1 = v.x*v2.y-v.y*v2.x;
				double cp2 = v.x*v3.y-v.y*v3.x;
				return ((cp1>EPS&&cp2<-EPS) ||(cp2>EPS&&cp1<-EPS));
			}
			return false;
		}
	}

	public static void main(String[] args) {
	int xa,ya,xb,yb;
	int c=0;
	Scanner sc = new Scanner(System.in);
	xa= sc.nextInt();
	ya= sc.nextInt();
	xb= sc.nextInt();
	yb= sc.nextInt();
	double slope = ((yb-ya)/(xb-xa));
	int n=sc.nextInt();
	Line base = new Line(-1*slope, 1,slope*xa-ya );
	Line[] arr = new Line[n];
	for(int i =0;i<n;i++) {
		arr[i]=new Line(sc.nextInt(),sc.nextInt(),sc.nextInt());
		//System.out.println(arr[i].a +"  "+arr[i].b+"  "+arr[i].c);
		if(arr[i].interSeg(base, new Point(xa, ya), new Point(xb, yb))) {
		//if( arr[i].inter(base))	{
		c++;
		}
	}
	System.out.println(c);
}
}


import java.util.Scanner;

public class CF {
	static final double EPS=1e-9;
	static class Point{
		double x,y;
		public Point(double x,double y) {
			this.x= x;
			this.y=y;
		}
	}

	static class Line{
		double a,b,c;
		double slope;
		Point pl1,pl2;
		public Line(double d, double bb,double e) {
			a=d;
			b=bb;
			c=e;
			slope=-a/b;
		}
		boolean inter(Line l) {
			return (this.slope-l.slope<EPS);
		}
		boolean interSeg(Line l,Point p1,Point p2) {
			if(inter(l)) {
				if(this.b==0) {
					pl1= new Point(-c/a,0);
					pl2= new Point(-c/a,1);
				}
				else {
					pl1= new Point(1,-(this.c+this.a)/b);
					pl2= new Point(0,-this.c/b);
				}
				Point v = new Point(pl2.x-pl1.x,pl2.y-pl1.y);
				Point v2=new Point(p1.x-pl1.x,p1.y-pl1.y);
				Point v3=new Point(p2.x-pl1.x,p2.y-pl1.y);
				double cp1 = v.x*v2.y-v.y*v2.x;
				double cp2 = v.x*v3.y-v.y*v3.x;
				return ((cp1>EPS&&cp2<-EPS) ||(cp2>EPS&&cp1<-EPS));
			}
			return false;
		}
	}

	public static void main(String[] args) {
	int xa,ya,xb,yb;
	int c=0;
	Scanner sc = new Scanner(System.in);
	xa= sc.nextInt();
	ya= sc.nextInt();
	xb= sc.nextInt();
	yb= sc.nextInt();
	double slope = ((yb-ya)/(xb-xa));
	int n=sc.nextInt();
	Line base = new Line(-1*slope, 1,slope*xa-ya );
	Line[] arr = new Line[n];
	for(int i =0;i<n;i++) {
		arr[i]=new Line(sc.nextInt(),sc.nextInt(),sc.nextInt());
		//System.out.println(arr[i].a +"  "+arr[i].b+"  "+arr[i].c);
		if(arr[i].interSeg(base, new Point(xa, ya), new Point(xb, yb))) {
		//if( arr[i].inter(base))	{
		c++;
		}
	}
	System.out.println(c);
}
}


package controller;

import java.util.Scanner;

public class CF {
	static final double EPS=0;
	static class Point{
		double x,y;
		public Point(double x,double y) {
			this.x= x;
			this.y=y;
		}
	}

	static class Line{
		double a,b,c;
		double slope;
		Point pl1,pl2;
		public Line(double d, double bb,double e) {
			a=d;
			b=bb;
			c=e;
			slope=-a/b;
		}
		boolean inter(Line l) {
			return (this.slope-l.slope<EPS);
		}
		boolean interSeg(Line l,Point p1,Point p2) {
			if(inter(l)) {
				if(this.b==0) {
					pl1= new Point(-c/a,0);
					pl2= new Point(-c/a,1);
				}
				else {
					pl1= new Point(1,-(this.c+this.a)/b);
					pl2= new Point(0,-this.c/b);
				}
				Point v = new Point(pl2.x-pl1.x,pl2.y-pl1.y);
				Point v2=new Point(p1.x-pl1.x,p1.y-pl1.y);
				Point v3=new Point(p2.x-pl1.x,p2.y-pl1.y);
				double cp1 = v.x*v2.y-v.y*v2.x;
				double cp2 = v.x*v3.y-v.y*v3.x;
				return ((cp1>EPS&&cp2<-EPS) ||(cp2>EPS&&cp1<-EPS));
			}
			return false;
		}
	}

	public static void main(String[] args) {
	int xa,ya,xb,yb;
	int c=0;
	Scanner sc = new Scanner(System.in);
	xa= sc.nextInt();
	ya= sc.nextInt();
	xb= sc.nextInt();
	yb= sc.nextInt();
	double slope = ((yb-ya)/(xb-xa));
	int n=sc.nextInt();
	Line base = new Line(-1*slope, 1,slope*xa-ya );
	Line[] arr = new Line[n];
	for(int i =0;i<n;i++) {
		arr[i]=new Line(sc.nextInt(),sc.nextInt(),sc.nextInt());
		//System.out.println(arr[i].a +"  "+arr[i].b+"  "+arr[i].c);
		if(arr[i].interSeg(base, new Point(xa, ya), new Point(xb, yb))) {
		//if( arr[i].inter(base))	{
		c++;
		}
	}
	System.out.println(c);
}
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Pradyumn Agrawal coderbond007
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        FastReader in = new FastReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskA solver = new TaskA();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskA {
        public void solve(int testNumber, FastReader in, PrintWriter out) {
            int[] x = new int[2];
            int[] y = new int[2];
            in.nextIntArrays(x, y);
            int n = in.nextInt();
            int res = 0;
            for (int i = 0; i < n; i++) {
                int a = in.nextInt();
                int b = in.nextInt();
                int c = in.nextInt();
                long v1 = (a * x[0] + b * y[0] + c);
                long v2 = (a * x[1] + b * y[1] + c);
                if (v1 * v2 < 0) {
                    res += 1;
                }
            }
            out.println(res);
        }

    }

    static class FastReader {
        private InputStream stream;
        private byte[] buf = new byte[8192];
        private int curChar;
        private int pnumChars;
        private FastReader.SpaceCharFilter filter;

        public FastReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (pnumChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= pnumChars) {
                curChar = 0;
                try {
                    pnumChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (pnumChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int nextInt() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c == ',') {
                    c = read();
                }
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public void nextIntArrays(int[]... arrays) {
            for (int i = 0; i < arrays[0].length; i++) {
                for (int j = 0; j < arrays.length; j++) {
                    arrays[j][i] = nextInt();
                }
            }
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Pradyumn Agrawal coderbond007
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        FastReader in = new FastReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskA solver = new TaskA();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskA {
        public void solve(int testNumber, FastReader in, PrintWriter out) {
            long[] x = new long[2];
            long[] y = new long[2];
            in.nextLongArrays(x, y);
            int n = in.nextInt();
            int res = 0;
            for (int i = 0; i < n; i++) {
                long a = in.nextLong();
                long b = in.nextLong();
                long c = in.nextLong();
                int sg1 = Long.signum(a * x[0] + b * y[0] + c);
                int sg2 = Long.signum(a * x[1] + b * y[1] + c);
                if (sg1 != sg2) {
                    res += 1;
                }
            }
            out.println(res);
        }

    }

    static class FastReader {
        private InputStream stream;
        private byte[] buf = new byte[8192];
        private int curChar;
        private int pnumChars;
        private FastReader.SpaceCharFilter filter;

        public FastReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (pnumChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= pnumChars) {
                curChar = 0;
                try {
                    pnumChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (pnumChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int nextInt() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c == ',') {
                    c = read();
                }
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public long nextLong() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public void nextLongArrays(long[]... arrays) {
            for (int i = 0; i < arrays[0].length; i++) {
                for (int j = 0; j < arrays.length; j++) {
                    arrays[j][i] = nextLong();
                }
            }
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }
}


import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.NoSuchElementException;
import java.io.Writer;
import java.math.BigInteger;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Alex
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		OutputWriter out = new OutputWriter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {
    public void solve(int testNumber, InputReader in, OutputWriter out) {
        long x1 = in.readInt(), y1 = in.readInt(), x2 = in.readInt(), y2 = in.readInt(), n = in.readInt();
        int[][] input = IOUtils.readIntTable(in, (int) n, 3);
        int res = 0;
        for (int i = 0; i < input.length; i++) {
            long first = x1 * input[i][0] + y1 * input[i][1] + input[i][2];
            long second = x2 * input[i][0] + y2 * input[i][1] + input[i][2];
            if ((first > 0 && second < 0) || (first < 0 && second > 0)) res++;
        }
        out.print(res);
    }
}

class InputReader {
	private InputStream stream;
	private byte[] buf = new byte[1024];
	private int curChar;
	private int numChars;
	private SpaceCharFilter filter;

	public InputReader(InputStream stream) {
		this.stream = stream;
	}

	public int read() {
		if (numChars == -1)
			throw new InputMismatchException();
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}
	public int readInt() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}
	public boolean isSpaceChar(int c) {
		if (filter != null)
			return filter.isSpaceChar(c);
		return isWhitespace(c);
	}

	public static boolean isWhitespace(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}
	public interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}

class OutputWriter {
	private final PrintWriter writer;

	public OutputWriter(OutputStream outputStream) {
		writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
	}
	public void close() {
		writer.close();
	}
	public void print(int i) {
		writer.print(i);
	}
}

class IOUtils {
	public static int[] readIntArray(InputReader in, int size) {
		int[] array = new int[size];
		for (int i = 0; i < size; i++)
			array[i] = in.readInt();
		return array;
	}
	public static int[][] readIntTable(InputReader in, int rowCount, int columnCount) {
		int[][] table = new int[rowCount][];
		for (int i = 0; i < rowCount; i++)
			table[i] = readIntArray(in, columnCount);
		return table;
	}
}


import java.io.*;
import java.util.InputMismatchException;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Alex
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream;
		try {
			inputStream = new FileInputStream("input.txt");
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		OutputStream outputStream;
		try {
			outputStream = new FileOutputStream("output.txt");
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		InputReader in = new InputReader(inputStream);
		OutputWriter out = new OutputWriter(outputStream);
		NewYear solver = new NewYear();
		int testCount = Integer.parseInt(in.next());
		for (int i = 1; i <= testCount; i++)
			solver.solve(i, in, out);
		out.close();
	}
}

class NewYear {
    public void solve(int testNumber, InputReader in, OutputWriter out) {
        int[] need = IOUtils.readIntArray(in, 3);
        int N = in.readInt();
        int[][] pos = new int[N][3];
        for (int i = 0; i < N; i++) for (int j = 0; j < 3; j++) pos[i][j] = in.readInt();
        for (long i = 0; i < (1 << N); i++) {
            int[] temp = new int[3];
            for (int j = 0; j < N; j++) if ((i >> j) % 2 == 1) for (int k = 0; k < 3; k++) temp[k] += pos[j][k];
            boolean same = true;
            for (int j = 0; j < 3; j++) if (need[j] != temp[j]) {same = false; break; }
            if (same) {out.printLine("Case #"+testNumber+": yes"); return; }
        }
        out.printLine("Case #"+testNumber+": no");
    }
}

class InputReader {
	private InputStream stream;
	private byte[] buf = new byte[1024];
	private int curChar;
	private int numChars;
	private SpaceCharFilter filter;

	public InputReader(InputStream stream) {
		this.stream = stream;
	}

	public int read() {
		if (numChars == -1)
			throw new InputMismatchException();
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}
	public int readInt() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}
	public String readString() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			if (Character.isValidCodePoint(c))
				res.appendCodePoint(c);
			c = read();
		} while (!isSpaceChar(c));
		return res.toString();
	}

	public boolean isSpaceChar(int c) {
		if (filter != null)
			return filter.isSpaceChar(c);
		return isWhitespace(c);
	}

	public static boolean isWhitespace(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}
	public String next() {
		return readString();
	}
	public interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}

class OutputWriter {
	private final PrintWriter writer;

	public OutputWriter(OutputStream outputStream) {
		writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
	}
	public void print(Object...objects) {
		for (int i = 0; i < objects.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(objects[i]);
		}
	}
	public void printLine(Object...objects) {
		print(objects);
		writer.println();
	}
	public void close() {
		writer.close();
	}
}

class IOUtils {
	public static int[] readIntArray(InputReader in, int size) {
		int[] array = new int[size];
		for (int i = 0; i < size; i++)
			array[i] = in.readInt();
		return array;
	}
}


import java.io.*;
import java.util.*;
import java.util.zip.ZipEntry;
import java.math.*;

public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        Input in = new Input(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Task solver = new Task();
        solver.solve(1, in, out);
        out.close();
    }
}

class Task {
    static final long MOD = 1000000007;
    int[] primes;

    public void solve(int testNumber, Input in, PrintWriter out) {
        long x1 = in.nextLong();
        long y1 = in.nextLong();
        long x2 = in.nextLong();
        long y2 = in.nextLong();
        long n = in.nextLong();
        long a = 0;
        long b = 0;
        long c = 0;
        long ans = 0;
        for (int i = 0; i < n; i++) {
            a = in.nextLong();
            b = in.nextLong();
            c = in.nextLong();
            long p1 = a * x1 + b * y1 + c;
            long p2 = a * x2 + b * y2 + c;
            if (p1 * p2 < 0)
                ans++;
        }
        out.println(ans);
    }

    // didn't test
    static class BIT {
        int[] MAX;
        int[] MIN;
        int[] SUM;
        int n;

        public BIT(int n) {
            MAX = new int[n + 1];
            MIN = new int[n + 1];
            SUM = new int[n + 1];
            this.n = n;
        }

        public void setSum(int pos, int val) {
            for (int i = pos; i < n; i += (i & -i)) {
                SUM[i] += val;
            }
        }

        public int getSum(int to) {
            int sum = 0;
            for (int i = to; i > 0; i -= (i & -i)) {
                sum += SUM[i];
            }
            return sum;
        }

        public int getSum(int from, int to) {
            return getSum(to) - getSum(from);
        }

        public void setMax(int pos, int val) {
            for (int i = pos; i < n; i += (i & -i)) {
                MAX[i] = Math.max(val, MAX[i]);
            }
        }

        public int getMax(int to) {
            int max = 0;
            for (int i = to; i > 0; i -= (i & -i)) {
                max = Math.max(max, MAX[i]);
            }
            return max;
        }

        public void setMin(int pos, int val) {
            for (int i = pos; i < n; i += (i & -i)) {
                MIN[i] = Math.min(val, MIN[i]);
            }
        }

        public int getMin(int to) {
            int min = 0;
            for (int i = to; i > 0; i -= (i & -i)) {
                min = Math.min(min, MIN[i]);
            }
            return min;
        }

    }

    // didn't test
    static class DisjointSet {
        int[] set;

        public DisjointSet(int n) {
            set = new int[n];
            for (int i = 0; i < n; i++) {
                set[i] = i;
            }
        }

        public int findSet(int a) {
            if (set[a] == a)
                return a;
            return findSet(set[a]);
        }

        public void unionSet(int a, int b) {
            set[findSet(a)] = findSet(b);
        }

        public boolean isSameSet(int a, int b) {
            return findSet(a) == findSet(b);
        }
    }

    static class SegmentTree {
        int[] MAX;
        int[] MIN;
        int[] SUM;
        int[] data;
        int n;

        public SegmentTree(int[] data) {
            this.n = data.length;
            this.data = data;
            MAX = new int[4 * n + 10];
            MIN = new int[4 * n + 10];
            SUM = new int[4 * n + 10];
            buildTree(1, 0, n - 1);
        }

        public int left(int root) {
            return root << 1;
        }

        public int right(int root) {
            return (root << 1) + 1;
        }

        private void buildTree(int root, int rl, int rr) {
            if (rr == rl) {
                MAX[root] = MIN[root] = SUM[root] = data[rr];
            } else {
                int rm = (rl + rr) >> 1;
                buildTree(left(root), rl, rm);
                buildTree(right(root), rm + 1, rr);
                MAX[root] = Math.max(MAX[left(root)], MAX[right(root)]);
                MIN[root] = Math.min(MIN[left(root)], MIN[right(root)]);
                SUM[root] = SUM[left(root)] + SUM[right(root)];
            }
        }

        public int getMax(int from, int to) {
            return getMax(1, 0, n - 1, from, to);
        }

        private int getMax(int root, int rl, int rr, int from, int to) {
            if (from > rr || to < rl || rl > rr) {
                return -1;
            }
            if (from == rl && to == rr) {
                return MAX[root];
            }
            int rm = (rr + rl) >> 1;
            int m1 = getMax(left(root), rl, rm, from, Math.min(to, rm));
            int m2 = getMax(right(root), rm + 1, rr, Math.max(from, rm + 1), to);
            return Math.max(m1, m2);
        }

        public int getMin(int from, int to) {
            return getMin(1, 0, n - 1, from, to);
        }

        private int getMin(int root, int rl, int rr, int from, int to) {
            if (from > rr || to < rl || rl > rr) {
                return Integer.MAX_VALUE;
            }
            if (from == rl && to == rr) {
                return MIN[root];
            }
            int rm = (rr + rl) >> 1;
            int m1 = getMin(left(root), rl, rm, from, Math.min(to, rm));
            int m2 = getMin(right(root), rm + 1, rr, Math.max(from, rm + 1), to);
            return Math.min(m1, m2);
        }

        public int getSum(int from, int to) {
            return getSum(1, 0, n - 1, from, to);
        }

        private int getSum(int root, int rl, int rr, int from, int to) {
            if (from > rr || to < rl || rl > rr) {
                return 0;
            }
            if (from == rl && to == rr) {
                return SUM[root];
            }
            int rm = (rr + rl) >> 1;
            int m1 = getSum(left(root), rl, rm, from, Math.min(to, rm));
            int m2 = getSum(right(root), rm + 1, rr, Math.max(from, rm + 1), to);
            return m1 + m2;
        }
    }

    private String lcs(String s1, String s2) {
        int n = s1.length();
        int m = s2.length();
        int[][] dp = new int[n + 1][m + 1];
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }
        StringBuilder sb = new StringBuilder();
        int i = n;
        int j = m;
        while (i > 0 && j > 0) {
            if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
                sb.append(s1.charAt(i - 1));
                i--;
                j--;
            } else {
                if (dp[i - 1][j] > dp[i][j - 1]) {
                    i--;
                } else {
                    j--;
                }
            }
        }
        return sb.reverse().toString();
    }

    private boolean isPrime(int n) {
        if (n <= 3)
            return n > 1;
        else if (n % 3 == 0 || n % 2 == 0)
            return false;
        for (long i = 5; i * i <= n; i += 6) {
            if (n % i == 0 || n % (i + 2) == 0)
                return false;
        }
        return true;
    }

    private int[] getPrimes(int n) {
        int len = n + 1;
        boolean[] isPrimes = new boolean[len];
        int[] temps = new int[len];
        int index = 0;
        Arrays.fill(isPrimes, true);
        isPrimes[0] = isPrimes[1] = false;
        for (int i = 2; i * i < len; i++) {
            if (isPrimes[i]) {
                for (int j = i * i; j < len; j += i) {
                    isPrimes[j] = false;
                }
            }
        }
        for (int i = 0; i < len; i++) {
            if (isPrimes[i])
                temps[index++] = i;
        }
        int[] primes = Arrays.copyOf(temps, index);
        return primes;
    }

    static void swap(char[] arrays, int pos1, int pos2) {
        char tmp = arrays[pos1];
        arrays[pos1] = arrays[pos2];
        arrays[pos2] = tmp;
    }

    static void swap(int[] arrays, int pos1, int pos2) {
        int tmp = arrays[pos1];
        arrays[pos1] = arrays[pos2];
        arrays[pos2] = tmp;
    }

    static long modPow(long n, long ex) {
        long res = 1;
        while (ex > 0) {
            if ((ex & 1) == 1)
                res = res * n % MOD;
            n = n * n % MOD;
            ex >>= 1;
        }
        return res;
    }

    static long ModInverse(long n) {
        return modPow(n, MOD - 2);
    }

    static long nCr(int n, int r) {
        if (r > n)
            return -1;
        // return (f[n] * ModInverse((f[r] * f[n - r]) % MOD)) % MOD;
        return 0;
    }
}

class Input {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public Input(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

    public double nextDouble() {
        return Double.parseDouble(next());
    }
}


import java.io.*;
import java.util.*;
import java.util.zip.ZipEntry;
import java.math.*;

public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        Input in = new Input(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Task solver = new Task();
        solver.solve(1, in, out);
        out.close();
    }
}

class Task {
    static final long MOD = 1000000007;
    int[] primes;

    public void solve(int testNumber, Input in, PrintWriter out) {
        long x1 = in.nextLong();
        long y1 = in.nextLong();
        long x2 = in.nextLong();
        long y2 = in.nextLong();
        long n = in.nextLong();
        long a = 0;
        long b = 0;
        long c = 0;
        long ans = 0;
        for (int i = 0; i < n; i++) {
            a = in.nextLong();
            b = in.nextLong();
            c = in.nextLong();
            long p1 = a * x1 + b * y1 + c;
            long p2 = a * x2 + b * y2 + c;
            if ((p1 < 0 && p2 > 0) || (p1 > 0 && p2 < 0))
                ans++;
        }
        out.println(ans);
    }

    // didn't test
    static class BIT {
        int[] MAX;
        int[] MIN;
        int[] SUM;
        int n;

        public BIT(int n) {
            MAX = new int[n + 1];
            MIN = new int[n + 1];
            SUM = new int[n + 1];
            this.n = n;
        }

        public void setSum(int pos, int val) {
            for (int i = pos; i < n; i += (i & -i)) {
                SUM[i] += val;
            }
        }

        public int getSum(int to) {
            int sum = 0;
            for (int i = to; i > 0; i -= (i & -i)) {
                sum += SUM[i];
            }
            return sum;
        }

        public int getSum(int from, int to) {
            return getSum(to) - getSum(from);
        }

        public void setMax(int pos, int val) {
            for (int i = pos; i < n; i += (i & -i)) {
                MAX[i] = Math.max(val, MAX[i]);
            }
        }

        public int getMax(int to) {
            int max = 0;
            for (int i = to; i > 0; i -= (i & -i)) {
                max = Math.max(max, MAX[i]);
            }
            return max;
        }

        public void setMin(int pos, int val) {
            for (int i = pos; i < n; i += (i & -i)) {
                MIN[i] = Math.min(val, MIN[i]);
            }
        }

        public int getMin(int to) {
            int min = 0;
            for (int i = to; i > 0; i -= (i & -i)) {
                min = Math.min(min, MIN[i]);
            }
            return min;
        }

    }

    // didn't test
    static class DisjointSet {
        int[] set;

        public DisjointSet(int n) {
            set = new int[n];
            for (int i = 0; i < n; i++) {
                set[i] = i;
            }
        }

        public int findSet(int a) {
            if (set[a] == a)
                return a;
            return findSet(set[a]);
        }

        public void unionSet(int a, int b) {
            set[findSet(a)] = findSet(b);
        }

        public boolean isSameSet(int a, int b) {
            return findSet(a) == findSet(b);
        }
    }

    static class SegmentTree {
        int[] MAX;
        int[] MIN;
        int[] SUM;
        int[] data;
        int n;

        public SegmentTree(int[] data) {
            this.n = data.length;
            this.data = data;
            MAX = new int[4 * n + 10];
            MIN = new int[4 * n + 10];
            SUM = new int[4 * n + 10];
            buildTree(1, 0, n - 1);
        }

        public int left(int root) {
            return root << 1;
        }

        public int right(int root) {
            return (root << 1) + 1;
        }

        private void buildTree(int root, int rl, int rr) {
            if (rr == rl) {
                MAX[root] = MIN[root] = SUM[root] = data[rr];
            } else {
                int rm = (rl + rr) >> 1;
                buildTree(left(root), rl, rm);
                buildTree(right(root), rm + 1, rr);
                MAX[root] = Math.max(MAX[left(root)], MAX[right(root)]);
                MIN[root] = Math.min(MIN[left(root)], MIN[right(root)]);
                SUM[root] = SUM[left(root)] + SUM[right(root)];
            }
        }

        public int getMax(int from, int to) {
            return getMax(1, 0, n - 1, from, to);
        }

        private int getMax(int root, int rl, int rr, int from, int to) {
            if (from > rr || to < rl || rl > rr) {
                return -1;
            }
            if (from == rl && to == rr) {
                return MAX[root];
            }
            int rm = (rr + rl) >> 1;
            int m1 = getMax(left(root), rl, rm, from, Math.min(to, rm));
            int m2 = getMax(right(root), rm + 1, rr, Math.max(from, rm + 1), to);
            return Math.max(m1, m2);
        }

        public int getMin(int from, int to) {
            return getMin(1, 0, n - 1, from, to);
        }

        private int getMin(int root, int rl, int rr, int from, int to) {
            if (from > rr || to < rl || rl > rr) {
                return Integer.MAX_VALUE;
            }
            if (from == rl && to == rr) {
                return MIN[root];
            }
            int rm = (rr + rl) >> 1;
            int m1 = getMin(left(root), rl, rm, from, Math.min(to, rm));
            int m2 = getMin(right(root), rm + 1, rr, Math.max(from, rm + 1), to);
            return Math.min(m1, m2);
        }

        public int getSum(int from, int to) {
            return getSum(1, 0, n - 1, from, to);
        }

        private int getSum(int root, int rl, int rr, int from, int to) {
            if (from > rr || to < rl || rl > rr) {
                return 0;
            }
            if (from == rl && to == rr) {
                return SUM[root];
            }
            int rm = (rr + rl) >> 1;
            int m1 = getSum(left(root), rl, rm, from, Math.min(to, rm));
            int m2 = getSum(right(root), rm + 1, rr, Math.max(from, rm + 1), to);
            return m1 + m2;
        }
    }

    private String lcs(String s1, String s2) {
        int n = s1.length();
        int m = s2.length();
        int[][] dp = new int[n + 1][m + 1];
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }
        StringBuilder sb = new StringBuilder();
        int i = n;
        int j = m;
        while (i > 0 && j > 0) {
            if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
                sb.append(s1.charAt(i - 1));
                i--;
                j--;
            } else {
                if (dp[i - 1][j] > dp[i][j - 1]) {
                    i--;
                } else {
                    j--;
                }
            }
        }
        return sb.reverse().toString();
    }

    private boolean isPrime(int n) {
        if (n <= 3)
            return n > 1;
        else if (n % 3 == 0 || n % 2 == 0)
            return false;
        for (long i = 5; i * i <= n; i += 6) {
            if (n % i == 0 || n % (i + 2) == 0)
                return false;
        }
        return true;
    }

    private int[] getPrimes(int n) {
        int len = n + 1;
        boolean[] isPrimes = new boolean[len];
        int[] temps = new int[len];
        int index = 0;
        Arrays.fill(isPrimes, true);
        isPrimes[0] = isPrimes[1] = false;
        for (int i = 2; i * i < len; i++) {
            if (isPrimes[i]) {
                for (int j = i * i; j < len; j += i) {
                    isPrimes[j] = false;
                }
            }
        }
        for (int i = 0; i < len; i++) {
            if (isPrimes[i])
                temps[index++] = i;
        }
        int[] primes = Arrays.copyOf(temps, index);
        return primes;
    }

    static void swap(char[] arrays, int pos1, int pos2) {
        char tmp = arrays[pos1];
        arrays[pos1] = arrays[pos2];
        arrays[pos2] = tmp;
    }

    static void swap(int[] arrays, int pos1, int pos2) {
        int tmp = arrays[pos1];
        arrays[pos1] = arrays[pos2];
        arrays[pos2] = tmp;
    }

    static long modPow(long n, long ex) {
        long res = 1;
        while (ex > 0) {
            if ((ex & 1) == 1)
                res = res * n % MOD;
            n = n * n % MOD;
            ex >>= 1;
        }
        return res;
    }

    static long ModInverse(long n) {
        return modPow(n, MOD - 2);
    }

    static long nCr(int n, int r) {
        if (r > n)
            return -1;
        // return (f[n] * ModInverse((f[r] * f[n - r]) % MOD)) % MOD;
        return 0;
    }
}

class Input {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public Input(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

    public double nextDouble() {
        return Double.parseDouble(next());
    }
}


import java.io.*;
import java.util.*;
import java.util.zip.ZipEntry;
import java.math.*;

public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		Input in = new Input(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		Task solver = new Task();
		solver.solve(1, in, out);
		out.close();
	}
}

class Task {
	static final long MOD = 1000000007;
	int[] primes;

	public void solve(int testNumber, Input in, PrintWriter out) {
		int x1 = in.nextInt();
		int y1 = in.nextInt();
		int x2 = in.nextInt();
		int y2 = in.nextInt();
		int n = in.nextInt();
		int a = 0;
		int b = 0;
		int c = 0;
		int ans = 0;
		for (int i = 0; i < n; i++) {
			a = in.nextInt();
			b = in.nextInt();
			c = in.nextInt();
			int p1 = a * x1 + b * y1 + c;
			int p2 = a * x2 + b * y2 + c;
			if (p1 * p2 < 0)
				ans++;
		}
		out.println(ans);
	}

	// didn't test
	static class BIT {
		int[] MAX;
		int[] MIN;
		int[] SUM;
		int n;

		public BIT(int n) {
			MAX = new int[n + 1];
			MIN = new int[n + 1];
			SUM = new int[n + 1];
			this.n = n;
		}

		public void setSum(int pos, int val) {
			for (int i = pos; i < n; i += (i & -i)) {
				SUM[i] += val;
			}
		}

		public int getSum(int to) {
			int sum = 0;
			for (int i = to; i > 0; i -= (i & -i)) {
				sum += SUM[i];
			}
			return sum;
		}

		public int getSum(int from, int to) {
			return getSum(to) - getSum(from);
		}

		public void setMax(int pos, int val) {
			for (int i = pos; i < n; i += (i & -i)) {
				MAX[i] = Math.max(val, MAX[i]);
			}
		}

		public int getMax(int to) {
			int max = 0;
			for (int i = to; i > 0; i -= (i & -i)) {
				max = Math.max(max, MAX[i]);
			}
			return max;
		}

		public void setMin(int pos, int val) {
			for (int i = pos; i < n; i += (i & -i)) {
				MIN[i] = Math.min(val, MIN[i]);
			}
		}

		public int getMin(int to) {
			int min = 0;
			for (int i = to; i > 0; i -= (i & -i)) {
				min = Math.min(min, MIN[i]);
			}
			return min;
		}

	}

	// didn't test
	static class DisjointSet {
		int[] set;

		public DisjointSet(int n) {
			set = new int[n];
			for (int i = 0; i < n; i++) {
				set[i] = i;
			}
		}

		public int findSet(int a) {
			if (set[a] == a)
				return a;
			return findSet(set[a]);
		}

		public void unionSet(int a, int b) {
			set[findSet(a)] = findSet(b);
		}

		public boolean isSameSet(int a, int b) {
			return findSet(a) == findSet(b);
		}
	}

	static class SegmentTree {
		int[] MAX;
		int[] MIN;
		int[] SUM;
		int[] data;
		int n;

		public SegmentTree(int[] data) {
			this.n = data.length;
			this.data = data;
			MAX = new int[4 * n + 10];
			MIN = new int[4 * n + 10];
			SUM = new int[4 * n + 10];
			buildTree(1, 0, n - 1);
		}

		public int left(int root) {
			return root << 1;
		}

		public int right(int root) {
			return (root << 1) + 1;
		}

		private void buildTree(int root, int rl, int rr) {
			if (rr == rl) {
				MAX[root] = MIN[root] = SUM[root] = data[rr];
			} else {
				int rm = (rl + rr) >> 1;
				buildTree(left(root), rl, rm);
				buildTree(right(root), rm + 1, rr);
				MAX[root] = Math.max(MAX[left(root)], MAX[right(root)]);
				MIN[root] = Math.min(MIN[left(root)], MIN[right(root)]);
				SUM[root] = SUM[left(root)] + SUM[right(root)];
			}
		}

		public int getMax(int from, int to) {
			return getMax(1, 0, n - 1, from, to);
		}

		private int getMax(int root, int rl, int rr, int from, int to) {
			if (from > rr || to < rl || rl > rr) {
				return -1;
			}
			if (from == rl && to == rr) {
				return MAX[root];
			}
			int rm = (rr + rl) >> 1;
			int m1 = getMax(left(root), rl, rm, from, Math.min(to, rm));
			int m2 = getMax(right(root), rm + 1, rr, Math.max(from, rm + 1), to);
			return Math.max(m1, m2);
		}

		public int getMin(int from, int to) {
			return getMin(1, 0, n - 1, from, to);
		}

		private int getMin(int root, int rl, int rr, int from, int to) {
			if (from > rr || to < rl || rl > rr) {
				return Integer.MAX_VALUE;
			}
			if (from == rl && to == rr) {
				return MIN[root];
			}
			int rm = (rr + rl) >> 1;
			int m1 = getMin(left(root), rl, rm, from, Math.min(to, rm));
			int m2 = getMin(right(root), rm + 1, rr, Math.max(from, rm + 1), to);
			return Math.min(m1, m2);
		}

		public int getSum(int from, int to) {
			return getSum(1, 0, n - 1, from, to);
		}

		private int getSum(int root, int rl, int rr, int from, int to) {
			if (from > rr || to < rl || rl > rr) {
				return 0;
			}
			if (from == rl && to == rr) {
				return SUM[root];
			}
			int rm = (rr + rl) >> 1;
			int m1 = getSum(left(root), rl, rm, from, Math.min(to, rm));
			int m2 = getSum(right(root), rm + 1, rr, Math.max(from, rm + 1), to);
			return m1 + m2;
		}
	}

	private String lcs(String s1, String s2) {
		int n = s1.length();
		int m = s2.length();
		int[][] dp = new int[n + 1][m + 1];
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
					dp[i][j] = dp[i - 1][j - 1] + 1;
				} else {
					dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
				}
			}
		}
		StringBuilder sb = new StringBuilder();
		int i = n;
		int j = m;
		while (i > 0 && j > 0) {
			if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
				sb.append(s1.charAt(i - 1));
				i--;
				j--;
			} else {
				if (dp[i - 1][j] > dp[i][j - 1]) {
					i--;
				} else {
					j--;
				}
			}
		}
		return sb.reverse().toString();
	}

	private boolean isPrime(int n) {
		if (n <= 3)
			return n > 1;
		else if (n % 3 == 0 || n % 2 == 0)
			return false;
		for (long i = 5; i * i <= n; i += 6) {
			if (n % i == 0 || n % (i + 2) == 0)
				return false;
		}
		return true;
	}

	private int[] getPrimes(int n) {
		int len = n + 1;
		boolean[] isPrimes = new boolean[len];
		int[] temps = new int[len];
		int index = 0;
		Arrays.fill(isPrimes, true);
		isPrimes[0] = isPrimes[1] = false;
		for (int i = 2; i * i < len; i++) {
			if (isPrimes[i]) {
				for (int j = i * i; j < len; j += i) {
					isPrimes[j] = false;
				}
			}
		}
		for (int i = 0; i < len; i++) {
			if (isPrimes[i])
				temps[index++] = i;
		}
		int[] primes = Arrays.copyOf(temps, index);
		return primes;
	}

	static void swap(char[] arrays, int pos1, int pos2) {
		char tmp = arrays[pos1];
		arrays[pos1] = arrays[pos2];
		arrays[pos2] = tmp;
	}

	static void swap(int[] arrays, int pos1, int pos2) {
		int tmp = arrays[pos1];
		arrays[pos1] = arrays[pos2];
		arrays[pos2] = tmp;
	}

	static long modPow(long n, long ex) {
		long res = 1;
		while (ex > 0) {
			if ((ex & 1) == 1)
				res = res * n % MOD;
			n = n * n % MOD;
			ex >>= 1;
		}
		return res;
	}

	static long ModInverse(long n) {
		return modPow(n, MOD - 2);
	}

	static long nCr(int n, int r) {
		if (r > n)
			return -1;
		// return (f[n] * ModInverse((f[r] * f[n - r]) % MOD)) % MOD;
		return 0;
	}
}

class Input {
	public BufferedReader reader;
	public StringTokenizer tokenizer;

	public Input(InputStream stream) {
		reader = new BufferedReader(new InputStreamReader(stream), 32768);
		tokenizer = null;
		tokenizer = null;
	}

	public String next() {
		while (tokenizer == null || !tokenizer.hasMoreTokens()) {
			try {
				tokenizer = new StringTokenizer(reader.readLine());
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
		return tokenizer.nextToken();
	}

	public int nextInt() {
		return Integer.parseInt(next());
	}

	public long nextLong() {
		return Long.parseLong(next());
	}

	public double nextDouble() {
		return Double.parseDouble(next());
	}
}