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 java.util.function.*;
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 java.awt.geom.*;
import javax.imageio.*;
import java.math.*;
import java.time.Duration;
import static x30_pkg.x30_util.DynamicObject;
import java.awt.geom.*;
import java.text.*;
import java.text.NumberFormat;
import java.util.TimeZone;
class main {
static void g22drawConnectingCurve(Graphics2D g, Pt start, Pt end) { g22drawConnectingCurve(g, start, end, 4); }
static void g22drawConnectingCurve(Graphics2D g, Pt start, Pt end, int clipAmount) {
var controlY = random(0, 40);
var control = doublePt(avg(start.x, end.x), controlY);
var path = new Path2D.Float();
path.moveTo(start.x, start.y);
path.quadTo(control.x, control.y, end.x, end.y);
var color = oneOf(ll((Color.black), (Color.gray), (Color.red)));
var g2 = (Graphics2D) g.create();
g2.setColor(color);
if (clipAmount != 0) {
Rect clip = rectFromPoints(start.x+clipAmount, 0,
end.x-clipAmount, max(end.y, start.y)-clipAmount);
print("clip", clip);
g2.clipRect(clip.x, clip.y, clip.w, clip.h);
}
g2.draw(path);
}
static int random(int n) { return random(n, defaultRandomGenerator()); }
static int random(int n, Random r) {
return random(r, n);
}
static int random(Random r, int n) {
return n <= 0 ? 0 : getRandomizer(r).nextInt(n);
}
static double random(double max) {
return random()*max;
}
static double random() {
return defaultRandomGenerator().nextInt(100001)/100000.0;
}
static double random(double min, double max) {
return min+random()*(max-min);
}
// min <= value < max
static int random(int min, int max) {
return min+random(max-min);
}
static int random(int min, int max, Random r) {
return random(r, min, max);
}
static int random(Random r, int min, int max) {
return min+random(r, max-min);
}
static A random(List l) {
return oneOf(l);
}
static A random(Collection c) {
if (c instanceof List) return random((List) c);
int i = random(l(c));
return collectionGet(c, i);
}
static Pair random(Map map) {
return entryToPair(random(entries(map)));
}
static DoublePt doublePt(double x) { return doublePt(x, x); }
static DoublePt doublePt(double x, double y) {
return new DoublePt(x, y);
}
static float avg(float a, float b) {
return (a+b)/2;
}
static double avg(double a, double b) {
return (a+b)/2;
}
static double avg(double[] l) {
return doubleAverage(l);
}
static A oneOf(List l) {
if (empty(l)) return null;
int n = l.size();
return n == 1 ? first(l) : l.get(defaultRandomizer().nextInt(n));
}
static char oneOf(String s) {
return empty(s) ? '?' : s.charAt(random(l(s)));
}
static A oneOf(A... l) {
return oneOf(asList(l));
}
static List ll(A... a) {
ArrayList l = new ArrayList(a.length);
if (a != null) for (A x : a) l.add(x);
return l;
}
static Rect rectFromPoints(int x1, int y1, int x2, int y2) {
return pointsRect(x1, y1, x2, y2);
}
static Rect rectFromPoints(Pt a, Pt b) {
return pointsRect(a.x, a.y, b.x, b.y);
}
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;
}
static > A max(A a, A b) {
return cmp(a, b) >= 0 ? a : b;
}
static volatile StringBuffer local_log = new StringBuffer(); // not redirected
static boolean printAlsoToSystemOut = true;
static volatile Appendable print_log = local_log; // might be redirected, e.g. to main bot
// in bytes - will cut to half that
static volatile int print_log_max = 1024*1024;
static volatile int local_log_max = 100*1024;
static boolean print_silent = false; // total mute if set
static Object print_byThread_lock = new Object();
static volatile ThreadLocal