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.*;
class main {
static AutoCloseable tempOnFrameIconified(Component c, final Object r) {
  return c == null ? null : swing(() -> {
    JFrame f = getFrame(c);
    if (f == null) return null;
    WindowListener l = new WindowAdapter() {
      public void windowIconified(WindowEvent e) {
         AutoCloseable __0 = tempRememberListener(f, "removeWindowListener", this); try {
        pcallF(r);
      } finally { _close(__0); }}
    };
    f.addWindowListener(l);
    return new AutoCloseable() { public String toString() { return "{ swing(new Runnable {  public void run() { try {  f.removeWindowListener(l);..."; } public void close() throws Exception { { swing(new Runnable() {  public void run() { try {  f.removeWindowListener(l); 
} catch (Exception __e) { throw rethrow(__e); } }  public String toString() { return "f.removeWindowListener(l);"; }}); } }};
  });
}
static Object swing(Object f) {
  return swingAndWait(f);
}
static  A swing(F0 f) {
  return (A) swingAndWait(f);
}
static  A swing(IF0 f) {
  return (A) swingAndWait(f);
}
static JFrame getFrame(final Object _o) {
  return swing(new F0() { JFrame get() { try { 
    Object o = _o;
    if (o instanceof ButtonGroup) o = first(buttonsInGroup((ButtonGroup) o));
    if (!(o instanceof Component)) return null;
    Component c = (Component) o;
    while (c != null) {
      if (c instanceof JFrame) return (JFrame) c;
      c = c.getParent();
    }
    return null;
   } catch (Exception __e) { throw rethrow(__e); } }
  public String toString() { return "O o = _o;\r\n    if (o instanceof ButtonGroup) o = first(buttonsInGroup((Button..."; }});
}
static class tempRememberListener_c implements IFieldsToList {
  static String _fieldOrder = "mainObject removeMethod listener";
  Object mainObject;
  String removeMethod;
  Object listener;
  tempRememberListener_c() {}
  tempRememberListener_c(Object mainObject, String removeMethod, Object listener) {
  this.listener = listener;
  this.removeMethod = removeMethod;
  this.mainObject = mainObject;}
  public String toString() { return "tempRememberListener_c(" + mainObject + ", " + removeMethod + ", " + listener + ")"; }
public boolean equals(Object o) {
if (!(o instanceof tempRememberListener_c)) return false;
    tempRememberListener_c x =  (tempRememberListener_c) o;
    return eq(mainObject, x.mainObject) && eq(removeMethod, x.removeMethod) && eq(listener, x.listener);
}
  public int hashCode() {
    int h = 1262836985;
    h = boostHashCombine(h, _hashCode(mainObject));
    h = boostHashCombine(h, _hashCode(removeMethod));
    h = boostHashCombine(h, _hashCode(listener));
    return h;
  }
  public Object[] _fieldsToList() { return new Object[] {mainObject, removeMethod, listener}; }
}
static AutoCloseable tempRememberListener(Object mainObject, String removeMethod, Object listener) {
  return tempHoldInstance(new tempRememberListener_c(mainObject, removeMethod, listener));
}
static Object pcallF(Object f, Object... args) {
  return pcallFunction(f, args);
}
static  A pcallF(F0 f) { try {
  return f == null ? null : f.get();
} catch (Throwable __e) { return null; } }
static  void pcallF(VF1 f, A a) {
  try {
    if (f != null) f.get(a);
  } catch (Throwable __e) { _handleException(__e); }
}
static void _close(AutoCloseable c) {
  if (c != null) try {
    c.close();
  } catch (Throwable e) {
    // Some classes stupidly throw an exception on double-closing
    if (c instanceof javax.imageio.stream.ImageOutputStream)
      return;
    else throw rethrow(e);
  }
}
static RuntimeException rethrow(Throwable t) {
  
  if (t instanceof Error)
    _handleError((Error) t);
  
  throw t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
}
static RuntimeException rethrow(String msg, Throwable t) {
  throw new RuntimeException(msg, t);
}
static void swingAndWait(Runnable r) { try {
  if (isAWTThread())
    r.run();
  else
    EventQueue.invokeAndWait(addThreadInfoToRunnable(r));
} catch (Exception __e) { throw rethrow(__e); } }
static Object swingAndWait(final Object f) {
  if (isAWTThread())
    return callF(f);
  else {
    final Var result = new Var();
    swingAndWait(new Runnable() {  public void run() { try { 
      result.set(callF(f));
    
} catch (Exception __e) { throw rethrow(__e); } }  public String toString() { return "result.set(callF(f));"; }});
    return result.get();
  }
}
// get purpose 1: access a list/array/map (safer version of x.get(y))
static  A get(List l, int idx) {
  return l != null && idx >= 0 && idx < l(l) ? l.get(idx) : null;
}
// seems to conflict with other signatures
/*static  B get(Map map, A key) {
  ret map != null ? map.get(key) : null;
}*/
static  A get(A[] l, int idx) {
  return idx >= 0 && idx < l(l) ? l[idx] : null;
}
// default to false
static boolean get(boolean[] l, int idx) {
  return idx >= 0 && idx < l(l) ? l[idx] : false;
}
// get purpose 2: access a field by reflection or a map
static Object get(Object o, String field) {
  try {
    if (o == null) return null;
    if (o instanceof Class) return get((Class) o, field);
    
    if (o instanceof Map)
      return ((Map) o).get(field);
      
    Field f = getOpt_findField(o.getClass(), field);
    if (f != null) {
      makeAccessible(f);
      return f.get(o);
    }
      
    
  } catch (Exception e) {
    throw asRuntimeException(e);
  }
  throw new RuntimeException("Field '" + field + "' not found in " + o.getClass().getName());
}
static Object get_raw(String field, Object o) {
  return get_raw(o, field);
}
static Object get_raw(Object o, String field) { try {
  if (o == null) return null;
  Field f = get_findField(o.getClass(), field);
  makeAccessible(f);
  return f.get(o);
} catch (Exception __e) { throw rethrow(__e); } }
static Object get(Class c, String field) {
  try {
    Field f = get_findStaticField(c, field);
    makeAccessible(f);
    return f.get(null);
  } catch (Exception e) {
    throw new RuntimeException(e);
  }
}
static Field get_findStaticField(Class> c, String field) {
  Class _c = c;
  do {
    for (Field f : _c.getDeclaredFields())
      if (f.getName().equals(field) && (f.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0)
        return f;
    _c = _c.getSuperclass();
  } while (_c != null);
  throw new RuntimeException("Static field '" + field + "' not found in " + c.getName());
}
static Field get_findField(Class> c, String field) {
  Class _c = c;
  do {
    for (Field f : _c.getDeclaredFields())
      if (f.getName().equals(field))
        return f;
    _c = _c.getSuperclass();
  } while (_c != null);
  throw new RuntimeException("Field '" + field + "' not found in " + c.getName());
}
static Object get(String field, Object o) {
  return get(o, field);
}
static Object first(Object list) {
  return first((Iterable) list);
}
static  A first(List list) {
  return empty(list) ? null : list.get(0);
}
static  A first(A[] bla) {
  return bla == null || bla.length == 0 ? null : bla[0];
}
static  A first(Iterator i) {
  return i == null || !i.hasNext() ? null : i.next();
}
static  A first(Iterable i) {
  if (i == null) return null;
  Iterator it = i.iterator();
  return it.hasNext() ? it.next() : null;
}
static Character first(String s) { return empty(s) ? null : s.charAt(0); }
static  A first(Pair p) {
  return p == null ? null : p.a;
}
static List buttonsInGroup(ButtonGroup g) {
  if (g == null) return ll();
  return asList(g.getElements());
}
static boolean eq(Object a, Object b) {
  return a == b || (a == null ? b == null : b != null && a.equals(b));
}
static int boostHashCombine(int a, int b) {
  return a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2));
}
static int _hashCode(Object a) {
  return a == null ? 0 : a.hashCode();
}
static AutoCloseable tempHoldInstance(Object o) {
  return holdInstance(o);
}
static Object pcallFunction(Object f, Object... args) {
  try { return callFunction(f, args); } catch (Throwable __e) { _handleException(__e); }
  return null;
}
static volatile PersistableThrowable _handleException_lastException;
static List _handleException_onException = synchroList(ll("printStackTrace2"));
static void _handleException(Throwable e) {
  _handleException_lastException = persistableThrowable(e);
  
  Throwable e2 = innerException(e);
  if (e2.getClass() == RuntimeException.class && eq(e2.getMessage(), "Thread cancelled.") || e2 instanceof InterruptedException)
    return;
    
  for (Object f : cloneList(_handleException_onException)) try {
    callF(f, e);
  } catch (Throwable e3) {
    printStackTrace2(e3); // not using pcall here - it could lead to endless loops
  }
}
static void _handleError(Error e) {
  call(javax(), "_handleError", e);
}
static Throwable printStackTrace2(Throwable e) {
  // we go to system.out now - system.err is nonsense
  print(getStackTrace2(e));
  return e;
}
static void printStackTrace2() {
  printStackTrace2(new Throwable());
}
static void printStackTrace2(String msg) {
  printStackTrace2(new Throwable(msg));
}
// TODO: test if android complains about this
static boolean isAWTThread() {
  if (isAndroid()) return false;
  if (isHeadless()) return false;
  return isAWTThread_awt();
}
static boolean isAWTThread_awt() {
  return SwingUtilities.isEventDispatchThread();
}
static Runnable addThreadInfoToRunnable(final Object r) {
  final Object info = _threadInfo();
  return info == null ? asRunnable(r) : new Runnable() {  public void run() { try {  _inheritThreadInfo(info); callF(r); 
} catch (Exception __e) { throw rethrow(__e); } }  public String toString() { return "_inheritThreadInfo(info); callF(r);"; }};
}
static Map> callF_cache = newDangerousWeakHashMap();
  static  A callF(F0 f) {
    return f == null ? null : f.get();
  }
  static  A callF(IF0 f) {
    return f == null ? null : f.get();
  }
  static  void callF(VF1 f, A a) {
    if (f != null) f.get(a);
  }
static Object callF(Object f, Object... args) { try {
  if (f instanceof String)
    return callMC((String) f, args);
  if (f instanceof Runnable) {
    ((Runnable) f).run();
    return null;
  }
  if (f == null) return null;
  
  Class c = f.getClass();
  ArrayList methods;
  synchronized(callF_cache) {
    methods = callF_cache.get(c);
    if (methods == null)
      methods = callF_makeCache(c);
  }
  
  int n = l(methods);
  if (n == 0) {
    
    throw fail("No get method in " + getClassName(c));
  }
  if (n == 1) return invokeMethod(methods.get(0), f, args);
  for (int i = 0; i < n; i++) {
    Method m = methods.get(i);
    if (call_checkArgs(m, args, false))
      return invokeMethod(m, f, args);
  }
  throw fail("No matching get method in " + getClassName(c));
} catch (Exception __e) { throw rethrow(__e); } }
// used internally
static ArrayList callF_makeCache(Class c) {
  ArrayList l = new ArrayList();
  Class _c = c;
  do {
    for (Method m : _c.getDeclaredMethods())
      if (m.getName().equals("get")) {
        makeAccessible(m);
        l.add(m);
      }
    if (!l.isEmpty()) break;
    _c = _c.getSuperclass();
  } while (_c != null);
  callF_cache.put(c, l);
  return l;
}
static int l(Object[] a) { return a == null ? 0 : a.length; }
static int l(boolean[] a) { return a == null ? 0 : a.length; }
static int l(byte[] a) { return a == null ? 0 : a.length; }
static int l(short[] a) { return a == null ? 0 : a.length; }
static int l(long[] a) { return a == null ? 0 : a.length; }
static int l(int[] a) { return a == null ? 0 : a.length; }
static int l(float[] a) { return a == null ? 0 : a.length; }
static int l(double[] a) { return a == null ? 0 : a.length; }
static int l(char[] a) { return a == null ? 0 : a.length; }
static int l(Collection c) { return c == null ? 0 : c.size(); }
static int l(Iterator i) { return iteratorCount_int_close(i); } // consumes the iterator && closes it if possible
static int l(Map m) { return m == null ? 0 : m.size(); }
static int l(CharSequence s) { return s == null ? 0 : s.length(); }
static long l(File f) { return f == null ? 0 : f.length(); }
static int l(Object o) {
  return o == null ? 0
    : o instanceof String ? l((String) o)
    : o instanceof Map ? l((Map) o)
    : o instanceof Collection ? l((Collection) o)
    : o instanceof Object[] ? l((Object[]) o)
    : o instanceof boolean[] ? l((boolean[]) o)
    : o instanceof byte[] ? l((byte[]) o)
    : o instanceof char[] ? l((char[]) o)
    : o instanceof short[] ? l((short[]) o)
    : o instanceof int[] ? l((int[]) o)
    : o instanceof float[] ? l((float[]) o)
    : o instanceof double[] ? l((double[]) o)
    : o instanceof long[] ? l((long[]) o)
    : (Integer) call(o, "size");
}
static Field getOpt_findField(Class> c, String field) {
  Class _c = c;
  do {
    for (Field f : _c.getDeclaredFields())
      if (f.getName().equals(field))
        return f;
    _c = _c.getSuperclass();
  } while (_c != null);
  return null;
}
static Field makeAccessible(Field f) {
  try {
    f.setAccessible(true);
  } catch (Throwable e) {
    // Note: The error reporting only works with Java VM option --illegal-access=deny
    vmBus_send("makeAccessible_error",e, f);
  }
  return f;
}
static Method makeAccessible(Method m) {
  try {
    m.setAccessible(true);
  } catch (Throwable e) {
    vmBus_send("makeAccessible_error",e, m);
  }
  return m;
}
static Constructor makeAccessible(Constructor c) {
  try {
    c.setAccessible(true);
  } catch (Throwable e) {
    vmBus_send("makeAccessible_error",e, c);
  }
  return c;
}
static RuntimeException asRuntimeException(Throwable t) {
  
  if (t instanceof Error)
    _handleError((Error) t);
  
  return t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
}
static boolean empty(Collection c) { return c == null || c.isEmpty(); }
static boolean empty(CharSequence s) { return s == null || s.length() == 0; }
static boolean empty(Map map) { return map == null || map.isEmpty(); }
static boolean empty(Object[] o) { return o == null || o.length == 0; }
static boolean empty(Object o) {
  if (o instanceof Collection) return empty((Collection) o);
  if (o instanceof String) return empty((String) o);
  if (o instanceof Map) return empty((Map) o);
  if (o instanceof Object[]) return empty((Object[]) o);
  if (o instanceof byte[]) return empty((byte[]) o);
  if (o == null) return true;
  throw fail("unknown type for 'empty': " + getType(o));
}
static boolean empty(Iterator i) { return i == null || !i.hasNext(); }
static boolean empty(float[] a) { return a == null || a.length == 0; }
static boolean empty(int[] a) { return a == null || a.length == 0; }
static boolean empty(long[] a) { return a == null || a.length == 0; }
static boolean empty(byte[] a) { return a == null || a.length == 0; }
static boolean empty(short[] a) { return a == null || a.length == 0; }
static boolean empty(File f) { return getFileSize(f) == 0; }
static  List ll(A... a) {
  ArrayList l = new ArrayList(a.length);
  if (a != null) for (A x : a) l.add(x);
  return l;
}
static  ArrayList asList(A[] a) {
  return a == null ? new ArrayList() : new ArrayList(Arrays.asList(a));
}
static ArrayList asList(int[] a) {
  if (a == null) return null;
  ArrayList l = emptyList(a.length);
  for (int i : a) l.add(i);
  return l;
}
static ArrayList asList(float[] a) {
  if (a == null) return null;
  ArrayList l = emptyList(a.length);
  for (float i : a) l.add(i);
  return l;
}
static  ArrayList asList(Iterable s) {
  if (s instanceof ArrayList) return (ArrayList) s;
  ArrayList l = new ArrayList();
  if (s != null)
    for (A a : s)
      l.add(a);
  return l;
}
static  ArrayList asList(Enumeration e) {
  ArrayList l = new ArrayList();
  if (e != null)
    while (e.hasMoreElements())
      l.add(e.nextElement());
  return l;
}
static String str(Object o) {
  return o == null ? "null" : o.toString();
}
static String str(char[] c) {
  return new String(c);
}
static ThreadLocal> holdInstance_l = new ThreadLocal();
static AutoCloseable holdInstance(Object o) {
  if (o == null) return null;
  listThreadLocalAdd(holdInstance_l, o);
  return new AutoCloseable() {
    public void close() {
      listThreadLocalPopLast(holdInstance_l);
    }
  };
}
static Object callFunction(Object f, Object... args) {
  return callF(f, args);
}
static  List synchroList() {
  return Collections.synchronizedList(new ArrayList());
}
static  List synchroList(List l) {
  return Collections.synchronizedList(l);
}
static PersistableThrowable persistableThrowable(Throwable e) {
  return e == null ? null : new PersistableThrowable(e);
}
static Throwable innerException(Throwable e) {
  return getInnerException(e);
}
static  ArrayList cloneList(Iterable l) {
  return l instanceof Collection ? cloneList((Collection) l) : asList(l);
}
static  ArrayList cloneList(Collection l) {
  if (l == null) return new ArrayList();
  synchronized(collectionMutex(l)) {
    return new ArrayList(l);
  }
}
static Object call(Object o) {
  return callF(o);
}
// varargs assignment fixer for a single string array argument
static Object call(Object o, String method, String[] arg) {
  return call(o, method, new Object[] {arg});
}
static Object call(Object o, String method, Object... args) {
  //ret call_cached(o, method, args);
  return call_withVarargs(o, method, args);
}
static Class javax() {
  return getJavaX();
}
static volatile StringBuffer local_log = new StringBuffer(); // not redirected
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