import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collections; import java.util.Scanner; public class aoe_lewin_2 { public static double EPS = 1e-9; public static int PENALTY = 1000000; public static int N, M; public static long R; public static long[] x,y,r; public static long[][] d; public static void main (String[] args) { Scanner in = new Scanner (System.in); PrintWriter out = new PrintWriter(System.out, true); N = in.nextInt(); M = in.nextInt(); R = in.nextInt(); x = new long[N+M]; y = new long[N+M]; r = new long[N+M]; for (int i = 0; i < N; i++) { x[i] = in.nextInt(); y[i] = in.nextInt(); r[i] = in.nextInt(); } for (int i = N; i < N+M; i++) { x[i] = in.nextInt(); y[i] = in.nextInt(); r[i] = 0; } d = new long[N+M][N+M]; for (int i = 0; i < N+M; i++) for (int j = 0; j < N+M; j++) d[i][j] = sq(x[i] - x[j]) + sq(y[i] - y[j]); int best = 1; for (int i = N; i < N+M; i++) best = Math.max(best, solvePoint(i)); for (int i = 0; i < N; i++) { for (int j = i+1; j < N; j++) { best = Math.max(best, solveVillages(i, j)); } } out.printf("%d\n", best); out.close(); System.exit(0); } public static double sq(double x) {return x*x;} public static long sq(long x) {return x*x;} public static int solvePoint(int f) { ArrayList w = new ArrayList(); int cur = 1; for (int i = 0; i < N+M; i++) { if (i == f) continue; long reach = sq(2 * R + r[i]); long dist = d[i][f]; if (dist > reach) continue; double[] q = new double[2]; for (int j = 0; j < 2; j++) { double[] c = getCircle(f, i, R, j); q[j] = Math.atan2(c[1]-y[f],c[0]-x[f]); } int add = i < N ? -PENALTY : 1; if (q[1] < q[0]) cur += add; w.add(new State(q[0] - EPS, add)); w.add(new State(q[1] + EPS, -add)); } Collections.sort(w); int res = cur; for (State s : w) { cur += s.inc; res = Math.max(res, cur); } return res; } public static int solveVillages(int v1, int v2) { int res = 0; for (int i = N; i < N+M; i++) { long dist = d[v1][i]; long reach = sq(r[v1] + r[i] + 2 * R); if (dist > reach) continue; for (int j = 0; j < 2; j++) { double lo = (Math.sqrt(d[v1][i]) - r[v1] - r[i]) / 2., hi = R; for (int iter = 0; iter < 200; iter++) { double mid = (lo + hi) / 2.; double[] c = getCircle(v1,i,mid,j); double d = sq(c[0] - x[v2]) + sq(c[1] - y[v2]); if (d < sq(r[v2] + mid + EPS)) { hi = mid; } else { lo = mid; } } res = Math.max(res, checkCircle(getCircle(v1,i,lo,j),lo)); } } return res; } public static int checkCircle(double[] c, double rad) { for (int k = 0; k < N; k++) { double d = sq(c[0] - x[k]) + sq(c[1] - y[k]); if (d < sq(r[k] + rad - EPS)) { return 0; } } int count = 0; for (int k = N; k < N+M; k++) { double d = sq(c[0] - x[k]) + sq(c[1] - y[k]); if (d <= sq(rad + EPS)) { count++; } } return count; } public static double[] getCircle(int i1, int i2, double rad, int type) { double L = r[i1] + rad; double R = r[i2] + rad; double D = d[i1][i2]; double c = (D+L*L-R*R)/2.; double b = Math.sqrt(D*L*L-c*c); double nx = (x[i2] - x[i1]) / D, ny = (y[i2] - y[i1]) / D; double bx = -ny * b, by = nx * b; double ax = nx * c, ay = ny * c; if (type == 0) return new double[] {x[i1] + ax - bx, y[i1] + ay - by}; else return new double[] {x[i1] + ax + bx, y[i1] + ay + by}; } static class State implements Comparable { public double angle; public int inc; public State (double angle, int inc) { this.angle = angle; this.inc = inc; } public int compareTo(State other) { if (angle < other.angle) return -1; if (angle > other.angle) return 1; return 0; } } }