import java.awt.geom.Point2D; import java.util.Comparator; import java.util.Scanner; import java.util.Set; import java.util.TreeSet; public class CakeCutting_artur { static final double eps = 1e-10; static final Comparator comparator = new Comparator() { public int compare(Point2D.Double p, Point2D.Double q) { if (p.distanceSq(q) < eps) return 0; return Math.abs(p.x - q.x) < eps ? Double.compare(p.y, q.y) : Double.compare(p.x, q.x); } }; public static void main(String[] args) { Scanner in = new Scanner(System.in); // ax + by + c = 0 long[][] line = new long[1001][3]; // Intersection points in the circle Set vertices = new TreeSet(comparator); // Intersection points on the lines Set[] segment = new Set[1001]; for (int i = 0; i < segment.length; i++) segment[i] = new TreeSet(comparator); while (true) { long cr = in.nextInt(), cx = in.nextInt(), cy = in.nextInt(); int lines = in.nextInt(); if (lines == 0 && cr == 0 && cx == 0 && cy == 0) break; int n = 0; for (int i = 0; i < lines; i++) { int x1 = in.nextInt(), y1 = in.nextInt(), x2 = in.nextInt(), y2 = in.nextInt(); line[n][0] = y1 - y2; line[n][1] = x2 - x1; line[n][2] = y1 * (x1 - x2) - x1 * (y1 - y2); // delete line if does not cut long dist = line[n][0] * cx + line[n][1] * cy + line[n][2]; long dot = line[n][0] * line[n][0] + line[n][1] * line[n][1]; if (dist * dist >= dot * cr * cr) n--; // delete duplicate lines for (int j = 0; j < n; j++) if (same(line[n], line[j])) n--; n++; } vertices.clear(); for (int i = 0; i < n; i++) segment[i].clear(); for (int i = 0; i < n; i++) for (int j = 0; j < i; j++) if (!parallel(line[i], line[j])) { Point2D.Double p = intersect(line[i], line[j]); if (insideCircle(p, cx, cy, cr)) { vertices.add(p); segment[i].add(p); segment[j].add(p); } } int edges = 0; for (int i = 0; i < n; i++) edges += segment[i].size() + 1; // Euler's formula: vertices - edges + faces = 1 System.out.println(1 + edges - vertices.size()); } } static boolean insideCircle(Point2D.Double p, long cx, long cy, long cr) { return p.distanceSq(cx, cy) < cr * cr + eps; } static boolean parallel(long[] a, long[] b) { return det(a[0], a[1], b[0], b[1]) == 0; } static boolean same(long[] a, long[] b) { return parallel(a, b) && det(a[0], a[2], b[0], b[2]) == 0 && det(a[1], a[2], b[1], b[2]) == 0; } static long det(long a, long b, long c, long d) { return a * d - c * b; } static Point2D.Double intersect(long[] a, long[] b) { long det = det(a[0], a[1], b[0], b[1]); if (det != 0) { double x = -det(a[2], a[1], b[2], b[1]); double y = -det(a[0], a[2], b[0], b[2]); return new Point2D.Double(x / det, y / det); } return null; } }