import java.util.*; import java.util.zip.*; import java.util.List; import java.util.regex.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; import java.util.concurrent.locks.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.text.*; import javax.swing.table.*; import java.io.*; import java.net.*; import java.lang.reflect.*; import java.lang.ref.*; import java.lang.management.*; import java.security.*; import java.security.spec.*; import java.awt.*; import java.awt.event.*; import java.awt.image.*; import javax.imageio.*; import java.math.*; // start from center class main { static LongIterator pixelSpiral_longIterator(int w, int h) { return pixelSpiral_longIterator(w/2, h/2, w, h); } // thanks to https://stackoverflow.com/questions/398299/looping-in-a-spiral // firstIntFromLong(l) = x, secondIntFromLong(l) = y static LongIterator pixelSpiral_longIterator(int sx, int sy, int imageWidth, int imageHeight) { return pixelSpiral_longIterator(sx, sy, imageWidth, imageHeight, Integer.MAX_VALUE); } static LongIterator pixelSpiral_longIterator(int sx, int sy, int imageWidth, int imageHeight, int maxPixels) { return new LongIterator() { int x, y, dx, dy = -1; int maxPixels2 = min(maxPixels, sqr(max4(sx+1, imageWidth-sx, sy+1, imageHeight-sy)*2)); int i; long pixel; boolean done = false; void fetch() { while (i++ < maxPixels2) { int px = sx+x, py = sy+y; if ((x == y) || ((x < 0) && (x == -y)) || ((x > 0) && (x == 1-y))) { int t=dx; dx=-dy; dy=t; } x += dx; y += dy; if (px >= 0 && py >= 0 && px < imageWidth && py < imageHeight) { pixel = twoIntsToLong(px, py); return; } } done = true; } { fetch(); } public boolean hasNext() { return !done; } public long next() { long p = pixel; fetch(); return p; } }; } static int min(int a, int b) { return Math.min(a, b); } static long min(long a, long b) { return Math.min(a, b); } static float min(float a, float b) { return Math.min(a, b); } static float min(float a, float b, float c) { return min(min(a, b), c); } static double min(double a, double b) { return Math.min(a, b); } static double min(double[] c) { double x = Double.MAX_VALUE; for (double d : c) x = Math.min(x, d); return x; } static float min(float[] c) { float x = Float.MAX_VALUE; for (float d : c) x = Math.min(x, d); return x; } static byte min(byte[] c) { byte x = 127; for (byte d : c) if (d < x) x = d; return x; } static short min(short[] c) { short x = 0x7FFF; for (short d : c) if (d < x) x = d; return x; } static int min(int[] c) { int x = Integer.MAX_VALUE; for (int d : c) if (d < x) x = d; return x; } static int sqr(int i) { return i*i; } static long sqr(long l) { return l*l; } static double sqr(double d) { return d*d; } static float sqr(float f) { return f*f; } static int max4(int a, int b, int c, int d) { return max(max(a, b, c), d); } static long twoIntsToLong(int a, int b) { return (((long) a) << 32) | (((long) b) & 0xFFFFFFFF); } static int max(int a, int b) { return Math.max(a, b); } static int max(int a, int b, int c) { return max(max(a, b), c); } static long max(int a, long b) { return Math.max((long) a, b); } static long max(long a, long b) { return Math.max(a, b); } static double max(int a, double b) { return Math.max((double) a, b); } static float max(float a, float b) { return Math.max(a, b); } static double max(double a, double b) { return Math.max(a, b); } static int max(Collection c) { int x = Integer.MIN_VALUE; for (int i : c) x = max(x, i); return x; } static double max(double[] c) { if (c.length == 0) return Double.MIN_VALUE; double x = c[0]; for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]); return x; } static float max(float[] c) { if (c.length == 0) return Float.MAX_VALUE; float x = c[0]; for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]); return x; } static byte max(byte[] c) { byte x = -128; for (byte d : c) if (d > x) x = d; return x; } static short max(short[] c) { short x = -0x8000; for (short d : c) if (d > x) x = d; return x; } static int max(int[] c) { int x = Integer.MIN_VALUE; for (int d : c) if (d > x) x = d; return x; } abstract static class LongIterator { abstract boolean hasNext(); abstract long next(); } }