import std.stdio;
import std.string;
import std.algorithm;
import std.conv;
import std.range;

void main() {
	int n = readln.chomp.to!int;
	int[] clear = new int[n];

	for (int i = 0; i < 2; i++) {
		auto l = readln.chomp.split.map!(to!int);
		foreach (e; l[1..$]) {
			clear[--e]++;
		}
	}

	if (clear.any!("a == 0")) {
		writeln("Oh, my keyboard!");
	} else {
		writeln("I become the guy.");
	}
}

import std.stdio, std.conv, std.string, std.algorithm, std.range;

void main(string[] argv)
{
	int lvls = to!int(readln.strip);
	auto xList = to!(int[])(readln.strip.split[1..$]);
	auto yList = to!(int[])(readln.strip.split[1..$]);

	if(chain(xList, yList).sort.uniq.array.length >= lvls)
		writeln("I become the guy.");
	else
		writeln("Oh, my keyboard!");
}

import std.stdio;
import std.uni;
import std.string;
import core.stdc.stdio;
import std.array;
import std.algorithm;
import std.string;
import std.math;

int main(string[] argv)
{
	bool[int] levels;
	int n;
	scanf("%d", &n);
	foreach (int i; 0..n)
	{
		levels[i] = false;
	}
	int p;
	scanf("%d", &p);
	foreach (int i; 0..p)
	{
		int a;
		scanf("%d", &a);
		levels[a-1] = true;
	}
	scanf("%d", &p);
	foreach (int i; 0..p)
	{
		int a;
		scanf("%d", &a);
		levels[a-1] = true;
	}

	foreach (int i; 0..n)
	{
		if (levels[i] == false)
		{
			printf("Oh, my keyboard!");
			return 0;
		}
	}
	printf("I become the guy.");
	return 0;
}

import std.stdio;

void main() {
  int n; readf(" %s", &n);
  auto ok = new bool[n];
  for (int i = 0; i < 2; i++) {
    int k; readf(" %s", &k);
    while (k--) {
      int x; readf(" %s", &x);
      x--;
      ok[x] = true;
    }
  }
  bool ans = true;
  foreach (x; ok) {
    ans &= x;
  }
  writeln(ans ? "I become the guy." : "Oh, my keyboard!");
}

import std.stdio;
import std.string;
import std.algorithm;
import std.conv;
import std.range;

void main() {
	int n = readln.chomp.to!int;
	int[] clear = new int[n];

	for (int i = 0; i < 2; i++) {
		auto l = readln.chomp.split.map!(to!int);
		foreach (e; l) {
			clear[--e]++;
		}
	}

	if (clear.any!("a == 0")) {
		writeln("Oh, my keyboard!");
	} else {
		writeln("I become the guy.");
	}
}


import core.bitop;
import std.algorithm;
import std.array;
import std.conv;
import std.range;
import std.stdio;
import std.string;
import std.typecons;

void main ()
{
	int n;
	while (readf (" %s", &n) > 0)
	{
		readln;
		auto a = readln.split.map !(to !(int)).array;
		a[] -= 1;
		auto p = n.iota.array;

		int root (int v)
		{
			if (v == p[v])
			{
				return v;
			}
			return p[v] = root (p[v]);
		}

		bool unite (int u, int v)
		{
			u = root (u);
			v = root (v);
			if (u == v)
			{
				return false;
			}
			p[u] = v;
			return true;
		}

		int res = n;
		foreach (i; 0..n)
		{
			if (unite (i, a[i]))
			{
				res -= 1;
			}
		}
		writeln (res);
		stdout.flush ();
	}
}

import std.stdio;
import std.algorithm;
import std.range;
import std.string;

bool [] used;
int [][] g;
bool can;
void dfs(int v)
{
    used[v] = true;
    for(int i = 0; i < g[v].length; i++)
    {
        if(!used[g[v][i]])
            dfs(g[v][i]);
        else
            can = false;
    }
}
void main(string[] args)
{
    int l1,r1,l2,r2,k,n;
    can = false;
    scanf("%d",&n);
    g.length = n + 1;
    used.length = n + 1;
    int ans = 0;
    for(int i = 1; i <= n; i++)
    {
        scanf("%d",&k);
        g[k].length++;
        g[k][g[k].length - 1] = i;
        used[i] = false;
    }
    for(int i = 1; i <= n; i++)
    {
        can = true;
        if(!used[i])
            dfs(i);
        if(!can){
            ans++;
        }
    }

    writeln(ans);

}

import core.bitop;
import core.checkedint;
import core.simd;
import core.stdc.stdio;
import core.stdc.stdlib;
import core.stdc.string;
import std.algorithm;
import std.array;
import std.ascii;
import std.bigint;
import std.bitmanip;
import std.complex;
import std.container;
import std.conv;
import std.datetime;
import std.format;
import std.functional;
import std.math;
import std.meta;
import std.numeric;
import std.random;
import std.range;
import std.regex;
//import std.stdio;
import std.string;
import std.typecons;
import std.variant;

__gshared:

/+
bool read(T...)(T ptrs) if (ptrs.length > 0) {
    return readf(' ' ~ replicate("%s ", ptrs.length), ptrs) == ptrs.length;
}
+/

T[ ] allocate(T)(size_t n) {
    return (cast(T*)malloc(n * T.sizeof))[0 .. n];
}

auto pairwise(R)(R range) if (isForwardRange!R) {
    return lockstep(range, dropOne(range));
}

struct Dsu(int n) {
    int[n] p;

    void init() {
        iota(n).copy(p[ ]);
    }

    int get(int x) {
        return x == p[x] ? x : (p[x] = get(p[x]));
    }

    void merge(int x, int y) {
        p[get(x)] = get(y);
    }
}

int n;
Dsu!10_000 dsu;

void main() {
    scanf("%d", &n);
    dsu.init();
    foreach (i; 0 .. n) {
        int x;
        scanf("%d", &x);
        dsu.merge(i, x - 1);
    }
    int result = 0;
    foreach (i; 0 .. n)
        if (i == dsu.get(i))
            result++;
    printf("%d\n", result);
}


import core.thread;
import std.conv, std.stdio, std.string;
import std.algorithm, std.array, std.bigint, std.container, std.math, std.range, std.regex;

//	Input
class EOFException : Throwable { this() { super("EOF"); } }
string[] tokens;
string readToken() { for (; tokens.empty; ) { tokens = readln.split; if (stdin.eof) throw new EOFException; } auto token = tokens[0]; tokens.popFront; return token; }
int readInt() { return to!int(readToken); }
long readLong() { return to!long(readToken); }
real readReal() { return to!real(readToken); }

//	chmin/chmax
void chmin(T)(ref T t, in T f) { if (t > f) t = f; }
void chmax(T)(ref T t, in T f) { if (t < f) t = f; }

//	Pair
struct Pair(S, T) {
	S x; T y;
	int opCmp(    const Pair p) const { return (x < p.x) ? -1 : (x > p.x) ? +1 : (y < p.y) ? -1 : (y > p.y) ? +1 : 0; }
	int opCmp(ref const Pair p) const { return (x < p.x) ? -1 : (x > p.x) ? +1 : (y < p.y) ? -1 : (y > p.y) ? +1 : 0; }
	string toString() const { return "(" ~ to!string(x) ~ ", " ~ to!string(y) ~ ")"; }
}
auto pair(S, T)(inout(S) x, inout(T) y) { return Pair!(S, T)(x, y); }

//	Array
int binarySearch(T)(in T[] as, in bool delegate(T) test) { int low = -1, upp = as.length; for (; low + 1 < upp; ) { int mid = (low + upp) >> 1; (test(as[mid]) ? low : upp) = mid; } return upp; }
int lowerBound(T)(in T[] as, in T val) { return as.binarySearch((T a) { return (a <  val); }); }
int upperBound(T)(in T[] as, in T val) { return as.binarySearch((T a) { return (a <= val); }); }
T[] unique(T)(in T[] as) { T[] bs; foreach (a; as) if (bs.empty || bs[$ - 1] != a) bs ~= a; return bs; }

int N;
int[] A;

void main(string[] args) {
	try {
	for (; ; ) {
		N = readInt;
		A = new int[N];
		foreach (i; 0 .. N) {
			A[i] = readInt;
		}

		int[] ps = new int[N];
		foreach (i; 0 .. N) {
			ps[i] = i;
		}
		ps.sort!((a, b) => (A[a] < A[b]));
debug{
writeln(ps);
}
		Pair!(int, int)[] poss;
		for (int i = 0, j; i < N; i = j) {
			for (; j < N && A[ps[i]] == A[ps[j]]; ++j) {}
			if (j - i >= 2) {
				poss ~= pair(i, j);
			}
		}
		int prod = 1;
		foreach (pos; poss) {
			prod *= (pos.y - pos.x);
			chmin(prod, 4);
		}
		if (prod < 3) {
			writeln("NO");
			continue;
		}
		writeln("YES");
		if (poss.count!(a => (a.y - a.x >= 3)) > 0) {
			foreach (i; 0 .. N) { if (i > 0) write(" "); write(ps[i] + 1); } writeln;
			foreach (pos; poss) if (pos.y - pos.x >= 3) {
				swap(ps[pos.x + 1], ps[pos.x + 2]);
				break;
			}
			foreach (i; 0 .. N) { if (i > 0) write(" "); write(ps[i] + 1); } writeln;
			foreach (pos; poss) if (pos.y - pos.x >= 3) {
				swap(ps[pos.x + 0], ps[pos.x + 1]);
				break;
			}
			foreach (i; 0 .. N) { if (i > 0) write(" "); write(ps[i] + 1); } writeln;
		} else {
			assert(poss.length >= 2);
			foreach (i; 0 .. N) { if (i > 0) write(" "); write(ps[i] + 1); } writeln;
			swap(ps[poss[0].x], ps[poss[0].x + 1]);
			foreach (i; 0 .. N) { if (i > 0) write(" "); write(ps[i] + 1); } writeln;
			swap(ps[poss[1].x], ps[poss[1].x + 1]);
			foreach (i; 0 .. N) { if (i > 0) write(" "); write(ps[i] + 1); } writeln;
		}
	}
	} catch (EOFException) {}
}

import std.stdio;
import std.exception;
import std.algorithm;

bool solve() {
	int n;
	if (!readf(" %s", &n))
		return false;
	auto a = new int[n];
	foreach (ref x; a)
		readf(" %s", &x);

	auto p = new int[n];
	foreach (i, ref x; p)
		x = cast(int)i;
	sort!((i, j) => a[i] < a[j])(p);

	int[][] ans;
	ans ~= p.dup;
	foreach (i; 0..n-1) {
		if (a[p[i]] == a[p[i + 1]]) {
			swap(p[i], p[i + 1]);
			ans ~= p.dup;
		}
		if (ans.length == 3)
			break;
	}

	if (ans.length < 3)
		writeln("NO");
	else {
		writeln("YES");
		foreach (i; 0..ans.length) {
			foreach (j; 0..ans[i].length)
				write(ans[i][j] + 1, ' ');
			writeln();
		}
	}

	return true;
}

void main() {
	while (solve()) {}
}

import std.stdio;
import std.algorithm;
import std.typecons;

alias pair = Tuple!(int, "v", int, "id");

void print(ref pair[] a) {
  for (int i = 0; i + 1 < a.length; i++) {
    Assert(a[i].v <= a[i + 1].v);
  }
  for (int i = 0; i < a.length; i++) {
    writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
  }
}

void Assert(bool b) {
  if (!b) {
    int x = 1 - 1;
    writeln(1 / x);
  }
}

void main() {
  int n; readf(" %s", &n);
  auto a = new pair[n];
  auto count = new int[2001];
  for (int i = 0; i < n; i++) {
    readf(" %s", &a[i].v);
    a[i].id = i + 1;
    count[a[i].v]++;
  }
  a.sort;
  int c3 = 0, c2 = 0;
  foreach (i; count) {
    if (i >= 3) {
      c3++;
    } else if (i >= 2) {
      c2++;
    }
  }
  if (c3 == 0 && c2 < 2) {
    writeln("NO");
  } else if (c3 > 0) {
    writeln("YES");
    int x = -1;
    for (int i = 0; i + 2 < n; i++) {
      if (a[i].v == a[i + 2].v) {
        x = i;
        break;
      }
    }
    Assert(x != -1);
    for (int i = 0; i + 1 < a.length; i++) {
      Assert(a[i].v <= a[i + 1].v);
    }
    for (int i = 0; i < a.length; i++) {
      writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
    }
    Assert(a[x].v == a[x + 1].v && a[x + 1].v == a[x + 2].v);
    swap(a[x], a[x + 1]);
    for (int i = 0; i + 1 < a.length; i++) {
      Assert(a[i].v <= a[i + 1].v);
    }
    for (int i = 0; i < a.length; i++) {
      writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
    }
    Assert(a[x].v == a[x + 1].v && a[x + 1].v == a[x + 2].v);
    swap(a[x], a[x + 2]);
    for (int i = 0; i + 1 < a.length; i++) {
      Assert(a[i].v <= a[i + 1].v);
    }
    for (int i = 0; i < a.length; i++) {
      writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
    }
  } else if (c2 >= 2) {
    writeln("YES");
    int x = -1, y = -1;
    for (int i = 0; i + 1 < n; i++) {
      if (a[i].v == a[i + 1].v) {
        if (x == -1) {
          x = i;
        } else if (y == -1) {
          y = i;
          break;
        }
      }
    }
    Assert(x != -1 && y != -1);
    for (int i = 0; i + 1 < a.length; i++) {
      Assert(a[i].v <= a[i + 1].v);
    }
    for (int i = 0; i < a.length; i++) {
      writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
    }
    Assert(a[y].v == a[y + 1].v);
    swap(a[y], a[y + 1]);
    for (int i = 0; i + 1 < a.length; i++) {
      Assert(a[i].v <= a[i + 1].v);
    }
    for (int i = 0; i < a.length; i++) {
      writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
    }
    Assert(a[x].v == a[x + 1].v);
    swap(a[x], a[x + 1]);
    for (int i = 0; i + 1 < a.length; i++) {
      Assert(a[i].v <= a[i + 1].v);
    }
    for (int i = 0; i < a.length; i++) {
      writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
    }
  }
}

import std.stdio;
import std.algorithm;
import std.typecons;

alias pair = Tuple!(int, "v", int, "id");

void print(pair[] a) {
  for (int i = 0; i + 1 < a.length; i++) {
    assert(a[i].v <= a[i + 1].v);
  }
  for (int i = 0; i < a.length; i++) {
    writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
  }
}

void main() {
  int n; readf(" %s", &n);
  auto a = new pair[n];
  auto count = new int[2001];
  for (int i = 0; i < n; i++) {
    readf(" %s", &a[i].v);
    a[i].id = i + 1;
    count[a[i].v]++;
  }
  if (n == 2000) {
    writeln(a[496], ' ', a[569]);
  }
  a.sort;
  int c3 = 0, c2 = 0;
  foreach (i; count) {
    if (i >= 3) {
      c3++;
    } else if (i >= 2) {
      c2++;
    }
  }
  if (c3 == 0 && c2 < 2) {
    writeln("NO");
  } else if (c3 > 0) {
    if (n == 2000) {
      writeln("3");
    }
    writeln("YES");
    int x = -1;
    for (int i = 0; i + 2 < n; i++) {
      if (a[i].v == a[i + 2].v) {
        x = i;
        break;
      }
    }
    if (n == 2000) {
      writeln(a[x], ' ', a[x + 1], ' ', a[x + 2]);
    }
    assert(x != -1);
    print(a);
    assert(a[x].v == a[x + 1].v && a[x + 1].v == a[x + 2].v);
    swap(a[x], a[x + 1]);
    print(a);
    swap(a[x + 1], a[x + 2]);
    print(a);
  } else if (c2 >= 2) {
    if (n == 2000) {
      writeln("2");
    }
    writeln("YES");
    int x = -1, y = -1;
    for (int i = 0; i + 1 < n; i++) {
      if (a[i].v == a[i + 1].v) {
        if (x == -1) {
          x = i;
        } else if (y == -1) {
          y = i;
          break;
        }
      }
    }
    assert(x != -1 && y != -1);
    print(a);
    assert(a[y].v == a[y + 1].v);
    swap(a[y], a[y + 1]);
    print(a);
    assert(a[x].v == a[x + 1].v);
    swap(a[x], a[x + 1]);
    print(a);
  }
}

import std.stdio;
import std.typecons;

alias pair = Tuple!(int, "v", int, "id");

void print(pair[] a) {
  for (int i = 0; i + 1 < a.length; i++) {
    assert(a[i].v <= a[i + 1].v);
  }
  for (int i = 0; i < a.length; i++) {
    writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
  }
}

void swap(ref pair a, ref pair b) {
  pair t = a;
  a = b;
  b = t;
}

void main() {
  int n; readf(" %s", &n);
  auto a = new pair[n];
  auto count = new int[2001];
  for (int i = 0; i < n; i++) {
    readf(" %s", &a[i].v);
    a[i].id = i + 1;
    count[a[i].v]++;
  }
  if (n == 2000) {
    writeln(a[496], ' ', a[569]);
  }
  a.sort;
  int c3 = 0, c2 = 0;
  foreach (i; count) {
    if (i >= 3) {
      c3++;
    } else if (i >= 2) {
      c2++;
    }
  }
  if (c3 == 0 && c2 < 2) {
    writeln("NO");
  } else if (c3 > 0) {
    writeln("YES");
    int x = -1;
    for (int i = 0; i + 2 < n; i++) {
      if (a[i].v == a[i + 2].v) {
        x = i;
        break;
      }
    }
    assert(x != -1);
    print(a);
    assert(a[x].v == a[x + 1].v && a[x + 1].v == a[x + 2].v);
    swap(a[x], a[x + 1]);
    print(a);
    swap(a[x + 1], a[x + 2]);
    print(a);
  } else if (c2 >= 2) {
    writeln("YES");
    int x = -1, y = -1;
    for (int i = 0; i + 1 < n; i++) {
      if (a[i].v == a[i + 1].v) {
        if (x == -1) {
          x = i;
        } else if (y == -1) {
          y = i;
          break;
        }
      }
    }
    assert(x != -1 && y != -1);
    print(a);
    assert(a[y].v == a[y + 1].v);
    swap(a[y], a[y + 1]);
    print(a);
    assert(a[x].v == a[x + 1].v);
    swap(a[x], a[x + 1]);
    print(a);
  }
}

import std.stdio;
import std.algorithm;
import std.typecons;

alias pair = Tuple!(int, "v", int, "id");

void print(pair[] a) {
  for (int i = 0; i + 1 < a.length; i++) {
    assert(a[i].v <= a[i + 1].v);
  }
  for (int i = 0; i < a.length; i++) {
    writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
  }
}

void main() {
  int n; readf(" %s", &n);
  auto a = new pair[n];
  auto count = new int[2001];
  for (int i = 0; i < n; i++) {
    readf(" %s", &a[i].v);
    a[i].id = i + 1;
    count[a[i].v]++;
  }
  a.sort;
  int c3 = 0, c2 = 0;
  foreach (i; count) {
    if (i >= 3) {
      c3++;
    } else if (i >= 2) {
      c2++;
    }
  }
  if (c3 == 0 && c2 < 2) {
    writeln("NO");
  } else if (c3 > 0) {
    writeln("YES");
    int x = -1;
    for (int i = 0; i + 2 < n; i++) {
      if (a[i].v == a[i + 2].v) {
        x = i;
        break;
      }
    }
    assert(x != -1);
    print(a);
    assert(a[x].v == a[x + 1].v && a[x + 1].v == a[x + 2].v);
    swap(a[x], a[x + 1]);
    print(a);
    swap(a[x + 1], a[x + 2]);
    print(a);
  } else if (c2 >= 2) {
    writeln("YES");
    int x = -1, y = -1;
    for (int i = 0; i + 1 < n; i++) {
      if (a[i].v == a[i + 1].v) {
        if (x == -1) {
          x = i;
        } else if (y == -1) {
          y = i;
          break;
        }
      }
    }
    assert(x != -1 && y != -1);
    print(a);
    assert(a[y].v == a[y + 1].v);
    swap(a[y], a[y + 1]);
    print(a);
    assert(a[x].v == a[x + 1].v);
    swap(a[x], a[x + 1]);
    print(a);
  }
}

import std.stdio;
import std.algorithm;
import std.typecons;

alias pair = Tuple!(int, "v", int, "id");

void print(ref pair[] a) {
  for (int i = 0; i + 1 < a.length; i++) {
    assert(a[i].v <= a[i + 1].v);
  }
  for (int i = 0; i < a.length; i++) {
    writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
  }
}

void main() {
  int n; readf(" %s", &n);
  auto a = new pair[n];
  auto count = new int[2001];
  for (int i = 0; i < n; i++) {
    readf(" %s", &a[i].v);
    a[i].id = i + 1;
    count[a[i].v]++;
  }
  a.sort;
  int c3 = 0, c2 = 0;
  foreach (i; count) {
    if (i >= 3) {
      c3++;
    } else if (i >= 2) {
      c2++;
    }
  }
  if (c3 == 0 && c2 < 2) {
    writeln("NO");
  } else if (c3 > 0) {
    writeln("YES");
    int x = -1;
    for (int i = 0; i + 2 < n; i++) {
      if (a[i].v == a[i + 2].v) {
        x = i;
        break;
      }
    }
    assert(x != -1);
    print(a);
    assert(a[x].v == a[x + 1].v && a[x + 1].v == a[x + 2].v);
    swap(a[x], a[x + 1]);
    print(a);
    assert(a[x].v == a[x + 1].v && a[x + 1].v == a[x + 2].v);
    swap(a[x], a[x + 2]);
    print(a);
  } else if (c2 >= 2) {
    writeln("YES");
    int x = -1, y = -1;
    for (int i = 0; i + 1 < n; i++) {
      if (a[i].v == a[i + 1].v) {
        if (x == -1) {
          x = i;
        } else if (y == -1) {
          y = i;
          break;
        }
      }
    }
    assert(x != -1 && y != -1);
    print(a);
    assert(a[y].v == a[y + 1].v);
    swap(a[y], a[y + 1]);
    print(a);
    assert(a[x].v == a[x + 1].v);
    swap(a[x], a[x + 1]);
    print(a);
  }
}

import std.stdio;
import std.algorithm;
import std.typecons;

alias pair = Tuple!(int, "v", int, "id");

void print(pair[] a) {
  for (int i = 0; i + 1 < a.length; i++) {
    assert(a[i].v <= a[i + 1].v);
  }
  for (int i = 0; i < a.length; i++) {
    writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
  }
}

void main() {
  int n; readf(" %s", &n);
  auto a = new pair[n];
  auto count = new int[2001];
  for (int i = 0; i < n; i++) {
    readf(" %s", &a[i].v);
    a[i].id = i + 1;
    count[a[i].v]++;
  }
  a.sort;
  int c3 = 0, c2 = 0;
  foreach (i; count) {
    if (i >= 3) {
      c3++;
    } else if (i >= 2) {
      c2++;
    }
  }
  if (c3 == 0 && c2 < 2) {
    writeln("NO");
  } else if (c3 > 0) {
    writeln("YES");
    int x = -1;
    for (int i = 0; i + 2 < n; i++) {
      if (a[i].v == a[i + 2].v) {
        x = i;
        break;
      }
    }
    assert(x != -1);
    print(a);
    assert(a[x].v == a[x + 1].v);
    swap(a[x], a[x + 1]);
    print(a);
    assert(a[x + 1].v == a[x + 2].v);
    swap(a[x + 1], a[x + 2]);
    print(a);
  } else if (c2 >= 2) {
    writeln("YES");
    int x = -1, y = -1;
    for (int i = 0; i + 1 < n; i++) {
      if (a[i].v == a[i + 1].v) {
        if (x == -1) {
          x = i;
        } else if (y == -1) {
          y = i;
          break;
        }
      }
    }
    assert(x != -1 && y != -1);
    print(a);
    assert(a[y].v == a[y + 1].v);
    swap(a[y], a[y + 1]);
    print(a);
    assert(a[x].v == a[x + 1].v);
    swap(a[x], a[x + 1]);
    print(a);
  }
}

import std.stdio;
import std.algorithm;
import std.typecons;

alias pair = Tuple!(int, "v", int, "id");

void print(pair[] a) {
  for (int i = 0; i + 1 < a.length; i++) {
    assert(a[i].v <= a[i + 1].v);
  }
  for (int i = 0; i < a.length; i++) {
    writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
  }
}

void main() {
  int n; readf(" %s", &n);
  auto a = new pair[n];
  auto count = new int[2001];
  for (int i = 0; i < n; i++) {
    readf(" %s", &a[i].v);
    a[i].id = i + 1;
    count[a[i].v]++;
  }
  if (n == 2000) {
    writeln(a[496], ' ', a[569]);
  }
  a.sort;
  int c3 = 0, c2 = 0;
  foreach (i; count) {
    if (i >= 3) {
      c3++;
    } else if (i >= 2) {
      c2++;
    }
  }
  if (c3 == 0 && c2 < 2) {
    writeln("NO");
  } else if (c3 > 0) {
    if (n == 2000) {
      writeln("3");
    }
    writeln("YES");
    int x = -1;
    for (int i = 0; i + 2 < n; i++) {
      if (a[i].v == a[i + 2].v) {
        x = i;
        break;
      }
    }
    writeln(a[x], ' ', a[x + 1], ' ', a[x + 2]);
    assert(x != -1);
    print(a);
    assert(a[x].v == a[x + 1].v && a[x + 1].v == a[x + 2].v);
    swap(a[x], a[x + 1]);
    print(a);
    swap(a[x + 1], a[x + 2]);
    print(a);
  } else if (c2 >= 2) {
    if (n == 2000) {
      writeln("2");
    }
    writeln("YES");
    int x = -1, y = -1;
    for (int i = 0; i + 1 < n; i++) {
      if (a[i].v == a[i + 1].v) {
        if (x == -1) {
          x = i;
        } else if (y == -1) {
          y = i;
          break;
        }
      }
    }
    assert(x != -1 && y != -1);
    print(a);
    assert(a[y].v == a[y + 1].v);
    swap(a[y], a[y + 1]);
    print(a);
    assert(a[x].v == a[x + 1].v);
    swap(a[x], a[x + 1]);
    print(a);
  }
}

import std.stdio;
import std.algorithm;
import std.typecons;

alias pair = Tuple!(int, "v", int, "id");

void print(pair[] a) {
  for (int i = 0; i < a.length; i++) {
    writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
  }
}

void main() {
  int n; readf(" %s", &n);
  auto a = new pair[n];
  auto count = new int[2001];
  for (int i = 0; i < n; i++) {
    readf(" %s", &a[i].v);
    a[i].id = i + 1;
    count[a[i].v]++;
  }
  a.sort;
  int c3 = 0, c2 = 0;
  foreach (i; count) {
    if (i >= 3) {
      c3++;
    } else if (i >= 2) {
      c2++;
    }
  }
  if (c3 == 0 && c2 < 2) {
    writeln("NO");
  } else if (c3 > 0) {
    writeln("YES");
    int x = -1;
    for (int i = 0; i < n; i++) {
      if (a[i].v == a[i + 2].v) {
        x = i;
        break;
      }
    }
    print(a);
    swap(a[x], a[x + 1]);
    print(a);
    swap(a[x + 1], a[x + 2]);
    print(a);
  } else if (c2 >= 2) {
    writeln("YES");
    int x = -1, y = -1;
    for (int i = 0; i < n; i++) {
      if (a[i].v == a[i + 1].v) {
        if (x == -1) {
          x = i;
        } else if (y == -1) {
          y = i;
          break;
        }
      }
    }
    print(a);
    swap(a[y], a[y + 1]);
    print(a);
    swap(a[x], a[x + 1]);
    print(a);
  }
}

import std.stdio;
import std.algorithm;
import std.typecons;

alias pair = Tuple!(int, "v", int, "id");

void print(ref pair[] a) {
  for (int i = 0; i + 1 < a.length; i++) {
    assert(a[i].v <= a[i + 1].v);
  }
  for (int i = 0; i < a.length; i++) {
    writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
  }
}

void main() {
  int n; readf(" %s", &n);
  auto a = new pair[n];
  auto count = new int[2001];
  for (int i = 0; i < n; i++) {
    readf(" %s", &a[i].v);
    a[i].id = i + 1;
    count[a[i].v]++;
  }
  a.sort;
  int c3 = 0, c2 = 0;
  foreach (i; count) {
    if (i >= 3) {
      c3++;
    } else if (i >= 2) {
      c2++;
    }
  }
  if (c3 == 0 && c2 < 2) {
    writeln("NO");
  } else if (c3 > 0) {
    writeln("YES");
    int x = -1;
    for (int i = 0; i + 2 < n; i++) {
      if (a[i].v == a[i + 2].v) {
        x = i;
        break;
      }
    }
    assert(x != -1);
    for (int i = 0; i + 1 < a.length; i++) {
      assert(a[i].v <= a[i + 1].v);
    }
    for (int i = 0; i < a.length; i++) {
      writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
    }
    assert(a[x].v == a[x + 1].v && a[x + 1].v == a[x + 2].v);
    swap(a[x], a[x + 1]);
    for (int i = 0; i + 1 < a.length; i++) {
      assert(a[i].v <= a[i + 1].v);
    }
    for (int i = 0; i < a.length; i++) {
      writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
    }
    assert(a[x].v == a[x + 1].v && a[x + 1].v == a[x + 2].v);
    swap(a[x], a[x + 2]);
    for (int i = 0; i + 1 < a.length; i++) {
      assert(a[i].v <= a[i + 1].v);
    }
    for (int i = 0; i < a.length; i++) {
      writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
    }
  } else if (c2 >= 2) {
    writeln("YES");
    int x = -1, y = -1;
    for (int i = 0; i + 1 < n; i++) {
      if (a[i].v == a[i + 1].v) {
        if (x == -1) {
          x = i;
        } else if (y == -1) {
          y = i;
          break;
        }
      }
    }
    assert(x != -1 && y != -1);
    for (int i = 0; i + 1 < a.length; i++) {
      assert(a[i].v <= a[i + 1].v);
    }
    for (int i = 0; i < a.length; i++) {
      writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
    }
    assert(a[y].v == a[y + 1].v);
    swap(a[y], a[y + 1]);
    for (int i = 0; i + 1 < a.length; i++) {
      assert(a[i].v <= a[i + 1].v);
    }
    for (int i = 0; i < a.length; i++) {
      writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
    }
    assert(a[x].v == a[x + 1].v);
    swap(a[x], a[x + 1]);
    for (int i = 0; i + 1 < a.length; i++) {
      assert(a[i].v <= a[i + 1].v);
    }
    for (int i = 0; i < a.length; i++) {
      writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
    }
  }
}

import std.stdio;
import std.algorithm;
import std.typecons;

alias pair = Tuple!(int, "v", int, "id");

void print(pair[] a) {
  for (int i = 0; i < a.length; i++) {
    writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
  }
}

void main() {
  int n; readf(" %s", &n);
  auto a = new pair[n];
  auto count = new int[2001];
  for (int i = 0; i < n; i++) {
    readf(" %s", &a[i].v);
    a[i].id = i + 1;
    count[a[i].v]++;
  }
  a.sort;
  int c3 = 0, c2 = 0;
  foreach (i; count) {
    if (i >= 3) {
      c3++;
    } else if (i >= 2) {
      c2++;
    }
  }
  if (c3 == 0 && c2 < 2) {
    writeln("NO");
  } else if (c3 > 0) {
    writeln("YES");
    int x = -1;
    for (int i = 0; i + 2 < n; i++) {
      if (a[i].v == a[i + 2].v) {
        x = i;
        break;
      }
    }
    print(a);
    swap(a[x], a[x + 1]);
    print(a);
    swap(a[x + 1], a[x + 2]);
    print(a);
  } else if (c2 >= 2) {
    writeln("YES");
    int x = -1, y = -1;
    for (int i = 0; i + 1 < n; i++) {
      if (a[i].v == a[i + 1].v) {
        if (x == -1) {
          x = i;
        } else if (y == -1) {
          y = i;
          break;
        }
      }
    }
    print(a);
    swap(a[y], a[y + 1]);
    print(a);
    swap(a[x], a[x + 1]);
    print(a);
  }
}

import std.stdio;
import std.algorithm;
import std.typecons;

alias pair = Tuple!(int, "v", int, "id");

void print(ref pair[] a) {
  for (int i = 0; i + 1 < a.length; i++) {
    Assert(a[i].v <= a[i + 1].v);
  }
  for (int i = 0; i < a.length; i++) {
    writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
  }
}

void Assert(bool b) {
  if (!b) {
    writeln("FAIL!");
  }
}

void main() {
  int n; readf(" %s", &n);
  auto a = new pair[n];
  auto count = new int[2001];
  for (int i = 0; i < n; i++) {
    readf(" %s", &a[i].v);
    a[i].id = i + 1;
    count[a[i].v]++;
  }
  a.sort;
  int c3 = 0, c2 = 0;
  foreach (i; count) {
    if (i >= 3) {
      c3++;
    } else if (i >= 2) {
      c2++;
    }
  }
  if (c3 == 0 && c2 < 2) {
    writeln("NO");
  } else if (c3 > 0) {
    writeln("YES");
    int x = -1;
    for (int i = 0; i + 2 < n; i++) {
      if (a[i].v == a[i + 2].v) {
        x = i;
        break;
      }
    }
    Assert(x != -1);
    for (int i = 0; i + 1 < a.length; i++) {
      Assert(a[i].v <= a[i + 1].v);
    }
    for (int i = 0; i < a.length; i++) {
      writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
    }
    Assert(a[x].v == a[x + 1].v && a[x + 1].v == a[x + 2].v);
    swap(a[x], a[x + 1]);
    for (int i = 0; i + 1 < a.length; i++) {
      Assert(a[i].v <= a[i + 1].v);
    }
    for (int i = 0; i < a.length; i++) {
      writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
    }
    Assert(a[x].v == a[x + 1].v && a[x + 1].v == a[x + 2].v);
    swap(a[x], a[x + 2]);
    for (int i = 0; i + 1 < a.length; i++) {
      Assert(a[i].v <= a[i + 1].v);
    }
    for (int i = 0; i < a.length; i++) {
      writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
    }
  } else if (c2 >= 2) {
    writeln("YES");
    int x = -1, y = -1;
    for (int i = 0; i + 1 < n; i++) {
      if (a[i].v == a[i + 1].v) {
        if (x == -1) {
          x = i;
        } else if (y == -1) {
          y = i;
          break;
        }
      }
    }
    Assert(x != -1 && y != -1);
    for (int i = 0; i + 1 < a.length; i++) {
      Assert(a[i].v <= a[i + 1].v);
    }
    for (int i = 0; i < a.length; i++) {
      writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
    }
    Assert(a[y].v == a[y + 1].v);
    swap(a[y], a[y + 1]);
    for (int i = 0; i + 1 < a.length; i++) {
      Assert(a[i].v <= a[i + 1].v);
    }
    for (int i = 0; i < a.length; i++) {
      writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
    }
    Assert(a[x].v == a[x + 1].v);
    swap(a[x], a[x + 1]);
    for (int i = 0; i + 1 < a.length; i++) {
      Assert(a[i].v <= a[i + 1].v);
    }
    for (int i = 0; i < a.length; i++) {
      writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
    }
  }
}

import std.stdio;
import std.algorithm;
import std.typecons;

alias pair = Tuple!(int, "v", int, "id");

void print(pair[] a) {
  for (int i = 0; i + 1 < a.length; i++) {
    assert(a[i].v <= a[i + 1].v);
  }
  for (int i = 0; i < a.length; i++) {
    writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
  }
}

void main() {
  int n; readf(" %s", &n);
  auto a = new pair[n];
  auto count = new int[2001];
  for (int i = 0; i < n; i++) {
    readf(" %s", &a[i].v);
    a[i].id = i + 1;
    count[a[i].v]++;
  }
  a.sort;
  int c3 = 0, c2 = 0;
  foreach (i; count) {
    if (i >= 3) {
      c3++;
    } else if (i >= 2) {
      c2++;
    }
  }
  if (c3 == 0 && c2 < 2) {
    writeln("NO");
  } else if (c3 > 0) {
    writeln("YES");
    int x = -1;
    for (int i = 0; i + 2 < n; i++) {
      if (a[i].v == a[i + 2].v) {
        x = i;
        break;
      }
    }
    assert(x != -1);
    print(a);
    assert(a[x].v == a[x + 1].v && a[x + 1].v == a[x + 2].v);
    swap(a[x], a[x + 1]);
    print(a);
    swap(a[x], a[x + 2]);
    print(a);
  } else if (c2 >= 2) {
    writeln("YES");
    int x = -1, y = -1;
    for (int i = 0; i + 1 < n; i++) {
      if (a[i].v == a[i + 1].v) {
        if (x == -1) {
          x = i;
        } else if (y == -1) {
          y = i;
          break;
        }
      }
    }
    assert(x != -1 && y != -1);
    print(a);
    assert(a[y].v == a[y + 1].v);
    swap(a[y], a[y + 1]);
    print(a);
    assert(a[x].v == a[x + 1].v);
    swap(a[x], a[x + 1]);
    print(a);
  }
}

import std.stdio;
import std.typecons;

alias pair = Tuple!(int, "v", int, "id");

void print(pair[] a) {
  for (int i = 0; i + 1 < a.length; i++) {
    assert(a[i].v <= a[i + 1].v);
  }
  for (int i = 0; i < a.length; i++) {
    writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
  }
}

void swap(ref pair a, ref pair b) {
  pair t = a;
  a = b;
  b = t;
}

void main() {
  int n; readf(" %s", &n);
  auto a = new pair[n];
  auto count = new int[2001];
  for (int i = 0; i < n; i++) {
    readf(" %s", &a[i].v);
    a[i].id = i + 1;
    count[a[i].v]++;
  }
  a.sort;
  int c3 = 0, c2 = 0;
  foreach (i; count) {
    if (i >= 3) {
      c3++;
    } else if (i >= 2) {
      c2++;
    }
  }
  if (c3 == 0 && c2 < 2) {
    writeln("NO");
  } else if (c3 > 0) {
    writeln("YES");
    int x = -1;
    for (int i = 0; i + 2 < n; i++) {
      if (a[i].v == a[i + 2].v) {
        x = i;
        break;
      }
    }
    assert(x != -1);
    print(a);
    assert(a[x].v == a[x + 1].v && a[x + 1].v == a[x + 2].v);
    swap(a[x], a[x + 1]);
    print(a);
    swap(a[x + 1], a[x + 2]);
    print(a);
  } else if (c2 >= 2) {
    writeln("YES");
    int x = -1, y = -1;
    for (int i = 0; i + 1 < n; i++) {
      if (a[i].v == a[i + 1].v) {
        if (x == -1) {
          x = i;
        } else if (y == -1) {
          y = i;
          break;
        }
      }
    }
    assert(x != -1 && y != -1);
    print(a);
    assert(a[y].v == a[y + 1].v);
    swap(a[y], a[y + 1]);
    print(a);
    assert(a[x].v == a[x + 1].v);
    swap(a[x], a[x + 1]);
    print(a);
  }
}

import std.stdio;
import std.algorithm;
import std.typecons;

alias pair = Tuple!(int, "v", int, "id");

void print(pair[] a) {
  for (int i = 0; i + 1 < a.length; i++) {
    assert(a[i].v <= a[i + 1].v);
  }
  for (int i = 0; i < a.length; i++) {
    writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
  }
}

void main() {
  int n; readf(" %s", &n);
  auto a = new pair[n];
  auto count = new int[2001];
  for (int i = 0; i < n; i++) {
    readf(" %s", &a[i].v);
    a[i].id = i + 1;
    count[a[i].v]++;
  }
  if (n == 2000) {
    writeln(a[496], ' ', a[569]);
  }
  a.sort;
  int c3 = 0, c2 = 0;
  foreach (i; count) {
    if (i >= 3) {
      c3++;
    } else if (i >= 2) {
      c2++;
    }
  }
  if (c3 == 0 && c2 < 2) {
    writeln("NO");
  } else if (c3 > 0) {
    writeln("YES");
    int x = -1;
    for (int i = 0; i + 2 < n; i++) {
      if (a[i].v == a[i + 2].v) {
        x = i;
        break;
      }
    }
    assert(x != -1);
    print(a);
    assert(a[x].v == a[x + 1].v && a[x + 1].v == a[x + 2].v);
    swap(a[x], a[x + 1]);
    print(a);
    swap(a[x + 1], a[x + 2]);
    print(a);
  } else if (c2 >= 2) {
    writeln("YES");
    int x = -1, y = -1;
    for (int i = 0; i + 1 < n; i++) {
      if (a[i].v == a[i + 1].v) {
        if (x == -1) {
          x = i;
        } else if (y == -1) {
          y = i;
          break;
        }
      }
    }
    assert(x != -1 && y != -1);
    print(a);
    assert(a[y].v == a[y + 1].v);
    swap(a[y], a[y + 1]);
    print(a);
    assert(a[x].v == a[x + 1].v);
    swap(a[x], a[x + 1]);
    print(a);
  }
}

import std.stdio;
import std.algorithm;
import std.typecons;

alias pair = Tuple!(int, "v", int, "id");

void print(pair[] a) {
  for (int i = 0; i + 1 < a.length; i++) {
    assert(a[i].v <= a[i + 1].v);
  }
  for (int i = 0; i < a.length; i++) {
    writef("%d%c", a[i].id, i == a.length - 1 ? '\n' : ' ');
  }
}

void main() {
  int n; readf(" %s", &n);
  auto a = new pair[n];
  auto count = new int[2001];
  for (int i = 0; i < n; i++) {
    readf(" %s", &a[i].v);
    a[i].id = i + 1;
    count[a[i].v]++;
  }
  if (n == 2000) {
    writeln(a[496], ' ', a[569]);
  }
  a.sort;
  int c3 = 0, c2 = 0;
  foreach (i; count) {
    if (i >= 3) {
      c3++;
    } else if (i >= 2) {
      c2++;
    }
  }
  if (c3 == 0 && c2 < 2) {
    writeln("NO");
  } else if (c3 > 0) {
    if (n == 2000) {
      writeln("3");
    }
    writeln("YES");
    int x = -1;
    for (int i = 0; i + 2 < n; i++) {
      if (a[i].v == a[i + 2].v) {
        x = i;
        break;
      }
    }
    assert(x != -1);
    print(a);
    assert(a[x].v == a[x + 1].v && a[x + 1].v == a[x + 2].v);
    swap(a[x], a[x + 1]);
    print(a);
    swap(a[x + 1], a[x + 2]);
    print(a);
  } else if (c2 >= 2) {
    if (n == 2000) {
      writeln("2");
    }
    writeln("YES");
    int x = -1, y = -1;
    for (int i = 0; i + 1 < n; i++) {
      if (a[i].v == a[i + 1].v) {
        if (x == -1) {
          x = i;
        } else if (y == -1) {
          y = i;
          break;
        }
      }
    }
    assert(x != -1 && y != -1);
    print(a);
    assert(a[y].v == a[y + 1].v);
    swap(a[y], a[y + 1]);
    print(a);
    assert(a[x].v == a[x + 1].v);
    swap(a[x], a[x + 1]);
    print(a);
  }
}


import std.algorithm, std.conv, std.math, std.range, std.stdio, std.string;
void main () {
	auto n = readln.strip.to!int + 1, a = readln.split.map !(to!int).array ~ 1, m = (n - 1) * (n - 2) / 2;
	auto e = n.iota.filter !(i => a[i]).array, y = a.sum, x = n - y, f = new int [] [] [] (n + 1, y + 1, m + 1);
	f[0][0][] = x * (x - 1) / 2;
	foreach (p; 0..n) foreach (v; 0..y) foreach (g; 0..m + 1) if (f[p][v][g]) foreach (d; 0..x - p + v + 1) {
		auto q = p + d + 1, h = g + abs (q - 1 - e[v]);
		if (h <= m) f[q][v + 1][h] = max (f[q][v + 1][h], f[p][v][g] - d * (d - 1) / 2);
	}
	f[n][y].writefln !("%(%s %)");
}

import std.algorithm, std.conv, std.math, std.range, std.stdio, std.string;

void main () {
	auto n = readln.strip.to !(int);
	auto a = readln.splitter.map !(to !(int)).array;
	auto n1 = a.sum, n0 = n - n1;
	int [] onePos;
	foreach (i; 0..n) if (a[i] == 1) onePos ~= i;
	auto m = n * (n - 1) / 2;
	auto f = new int [] [] [] (n + 1, n1 + 1, m + 1);
	f[0][0][0] = n0 * (n0 - 1) / 2;

	foreach (pos; 0..n) {
		foreach (ones; 0..min (pos + 1, n1)) {
			auto zeroes = pos - ones;
			if (zeroes > n0) continue;
			foreach (cost; 0..m + 1) {
				auto cur = f[pos][ones][cost];
				if (!cur) continue;
				for (int add0 = 0; add0 + zeroes <= n0; add0++) {
					auto subValue = add0 * (add0 - 1) / 2;
					auto newPos = pos + add0 + 1;
					auto newCost = cost + abs (newPos - 1 - onePos[ones]);
					f[newPos][ones + 1][newCost] = max (f[newPos][ones + 1][newCost], cur - subValue);
				}
			}
		}
	}

	auto answer = new int [m + 1];
	foreach (pos; 0..n + 1) {
		auto add0 = n - pos;
		foreach (cost; 0..m + 1) {
			auto subValue = add0 * (add0 - 1) / 2;
			answer[cost] = max (answer[cost],
			    f[pos][n1][cost] - subValue);
		}
	}
	foreach (i; 0..m) answer[i + 1] = max (answer[i + 1], answer[i]);
	writefln !("%(%s %)") (answer);
}

import std.algorithm, std.conv, std.math, std.range, std.stdio, std.string;

void main () {
	auto n = readln.strip.to !(int) + 1;
	auto a = readln.splitter.map !(to !(int)).array ~ 1;
	auto n1 = a.sum, n0 = n - n1;
	int [] onePos;
	foreach (i; 0..n) if (a[i]) onePos ~= i;
	auto m = (n - 1) * (n - 2) / 2;
	auto f = new int [] [] [] (n + 1, n1 + 1, m + 1);
	f[0][0][0] = n0 * (n0 - 1) / 2;

	foreach (pos; 0..n) {
		foreach (ones; 0..min (pos + 1, n1)) {
			auto zeroes = pos - ones;
			if (zeroes > n0) continue;
			foreach (cost; 0..m + 1) {
				auto cur = f[pos][ones][cost];
				if (!cur) continue;
				for (int add0 = 0; add0 + zeroes <= n0; add0++) {
					auto subValue = add0 * (add0 - 1) / 2;
					auto newPos = pos + add0 + 1;
					auto newCost = cost + abs (newPos - 1 - onePos[ones]);
					f[newPos][ones + 1][newCost] = max (f[newPos][ones + 1][newCost], cur - subValue);
				}
			}
		}
	}

	auto z = f[n][n1][0..m + 1].dup;
	foreach (i; 0..m) z[i + 1] = max (z[i + 1], z[i]);
	writefln !("%(%s %)") (z);
}

import std.algorithm, std.conv, std.math, std.range, std.stdio, std.string;
void main () {
	auto n = readln.strip.to!int + 1, a = readln.splitter.map !(to!int).array ~ 1, m = (n - 1) * (n - 2) / 2;
	auto e = n.iota.filter !(i => a[i]).array, y = a.sum, x = n - y, f = new int [] [] [] (n + 1, y + 1, m + 1);
	f[0][0][0] = x * (x - 1) / 2;
	foreach (p; 0..n) foreach (v; 0..min (p + 1, y)) foreach (g; 0..m + 1) {
		auto c = f[p][v][g];
		if (c) foreach (d; 0..x - p + v + 1) {
			auto q = p + d + 1, h = g + abs (q - 1 - e[v]);
			f[q][v + 1][h] = max (f[q][v + 1][h], c - d * (d - 1) / 2);
		}
	}
	auto z = f[n][y][0..m + 1];
	foreach (i; 0..m) z[i + 1] = max (z[i + 1], z[i]);
	z.writefln !("%(%s %)");
}

import std.algorithm;
import std.conv;
import std.math;
import std.range;
import std.stdio;
import std.string;

immutable int infinity = int.max / 4;

void main ()
{
	int n;
	while (readf !(" %s") (n) > 0)
	{
		readln;
		auto a = readln.splitter.map !(to !(int)).array;

		auto n0 = a.count (0).to !(int);
		auto n1 = a.count (1).to !(int);
		int [] onePos;
		foreach (i; 0..n)
		{
			if (a[i] == 1)
			{
				onePos ~= i;
			}
		}

		auto m = n * (n - 1) / 2;
		auto f = new int [] [] [] (n + 1, n1 + 1, m + n + 1);
		foreach (ref g; f)
		{
			foreach (ref h; g)
			{
				h[] = -infinity;
			}
		}
		f[0][0][0] = n0 * (n0 - 1) / 2;

		debug {int num = 0;}
		foreach (pos; 0..n)
		{
			foreach (ones; 0..min (pos, n1) + 1)
			{
				auto zeroes = pos - ones;
				if (zeroes > n0)
				{
					continue;
				}
				foreach (cost; 0..m + 1)
				{
					auto cur = f[pos][ones][cost];
					if (cur < 0)
					{
						continue;
					}
					if (ones >= n1)
					{
						continue;
					}
					debug {num += 1;}

					for (int add0 = 0; add0 + zeroes <= n0;
					    add0++)
					{
						auto subValue =
						    add0 * (add0 - 1) / 2;
						auto newPos = pos + add0 + 1;
						auto newCost = cost + abs
						    (newPos - 1 -
						    onePos[ones]);
						f[newPos][ones + 1][newCost] =
						    max (f[newPos][ones + 1]
						    [newCost], cur - subValue);
					}
				}
			}
		}
		debug {stderr.writeln (num);}

		auto answer = new int [m + 1];
		foreach (pos; 0..n + 1)
		{
			auto add0 = n - pos;
			foreach (cost; 0..m + 1)
			{
				auto subValue = add0 * (add0 - 1) / 2;
				answer[cost] = max (answer[cost],
				    f[pos][n1][cost] - subValue);
			}
		}
		foreach (i; 0..m)
		{
			answer[i + 1] = max (answer[i + 1], answer[i]);
		}
		writefln !("%(%s %)") (answer);
	}
}

import std.algorithm, std.conv, std.math, std.range, std.stdio, std.string;

void main () {
	auto n = readln.strip.to !(int) + 1, a = readln.splitter.map !(to !(int)).array ~ 1, x = a.sum, y = n - x;
	int [] e;
	foreach (i; 0..n) if (a[i]) e ~= i;
	auto m = (n - 1) * (n - 2) / 2, f = new int [] [] [] (n + 1, y + 1, m + 1);
	f[0][0][0] = x * (x - 1) / 2;

	foreach (p; 0..n) {
		foreach (v; 0..min (p + 1, y)) {
			auto u = p - v;
			if (u > x) continue;
			foreach (g; 0..m + 1) {
				auto c = f[p][v][g];
				if (c) for (int d = 0; d + u <= x; d++) {
					auto s = d * (d - 1) / 2;
					auto q = p + d + 1;
					auto h = g + abs (q - 1 - e[v]);
					f[q][v + 1][h] = max (f[q][v + 1][h], c - s);
				}
			}
		}
	}

	auto z = f[n][y][0..m + 1].dup;
	foreach (i; 0..m) z[i + 1] = max (z[i + 1], z[i]);
	writefln !("%(%s %)") (z);
}


import std.algorithm;
import std.container;
import std.conv;
import std.format;
import std.range;
import std.stdio;
import std.string;

void main() {
    int n,m;
    readf!" %s %s "(n, m);
    int[] a = readln.strip.split.map!(c => to!int(c)-1).array;

    int[] cnt = new int[](n);

    ulong uniq = 0;
    int r = 0;

    auto ans = new dchar[](m);
    foreach (i; 0 .. m) {
        if (cnt[a[i]] == r) {
            uniq++;
        }
        cnt[a[i]]++;

        if (uniq == n) {
            ans[i] = '1';
            r++;
            uniq = cnt.count!(c => c > r);
        } else {
            ans[i] = '0';
        }
    }
    writeln(ans);
}

import std.algorithm;
import std.container;
import std.conv;
import std.format;
import std.range;
import std.stdio;
import std.string;

void main() {
    int n,m;
    readf!" %s %s"(n, m);

    int[] cnt = new int[](n);

    ulong uniq = 0;

    int r = 0;
    foreach (i; 0 .. m) {
        int a; readf!" %s"(a);
        a--;
        if (cnt[a] == r) {
            uniq++;
        }
        cnt[a]++;

        if (uniq == n) {
            write(1);
            r++;
            uniq = cnt.count!(c => c > r);
        } else {
            write(0);
        }
    }
    writeln();
}

import std.algorithm;
import std.container;
import std.conv;
import std.format;
import std.range;
import std.stdio;
import std.string;

void main() {
    int n,m;
    readf!" %s %s"(n, m);

    int[] cnt = new int[](n);

    ulong uniq = 0;
    int r = 0;

    auto ans = new dchar[](m);
    foreach (i; 0 .. m) {
        int a; readf!" %s"(a);
        a--;
        if (cnt[a] == r) {
            uniq++;
        }
        cnt[a]++;

        if (uniq == n) {
            ans[i] = '1';
            r++;
            uniq = cnt.count!(c => c > r);
        } else {
            ans[i] = '0';
        }
    }
    writeln(ans);
}

import std.stdio, std.array, std.string, std.conv, std.algorithm;
import std.typecons, std.range, std.random, std.math, std.container;
import std.numeric, std.bigint, core.bitop, core.stdc.string;

immutable long INF = 1L << 59;

void main() {
    auto s = readln.split.map!(to!int);
    auto N = s[0];
    auto M = s[1];
    auto A = readln.split.map!(to!int).array;

    auto cnt1 = new int[](N+10);
    auto cnt2 = new int[](M+10);
    cnt2[0] = N;
    auto ans = new dchar[](M);
    int mv = 0;

    foreach (i; 0..M) {
        bool ok = false;
        if (cnt1[A[i]] == mv && cnt2[cnt1[A[i]]] == 1) {
            ok = true;
            mv += 1;
        }
        cnt2[cnt1[A[i]]] -= 1;
        cnt1[A[i]] += 1;
        cnt2[cnt1[A[i]]] += 1;
        if (ok) {
            ans[i] = '1';
        } else {
            ans[i] = '0';
        }
    }

    ans.writeln;
}

import std.algorithm;
import std.container;
import std.conv;
import std.format;
import std.range;
import std.stdio;
import std.string;

void main() {
    int n,m;
    readf!" %s %s"(n, m);

    int[] cnt = new int[](n);

    int uniq = 0;

    int r = 0;
    foreach (i; 0 .. m) {
        int a; readf!" %s"(a);
        a--;
        if (cnt[a] == r) {
            uniq++;
        }
        cnt[a]++;

        if (uniq == n) {
            write(1);
            uniq = 0;
            r++;
        } else {
            write(0);
        }
    }
    writeln();
}


import std.stdio, std.array, std.string, std.conv, std.algorithm;
import std.typecons, std.range, std.random, std.math, std.container;
import std.numeric, std.bigint, core.bitop, core.stdc.string;

immutable long MOD = 10^^9 + 7;
immutable long INF = 1L << 59;

void main() {
    auto N = readln.chomp.to!int;
    auto A = readln.split.map!(to!int).array;

    if (A.map!(a => a % 2 == A.front % 2).all) {
        A.map!(to!string).join(" ").writeln;
    } else {
        A.sort();
        A.map!(to!string).join(" ").writeln;
    }
}

import core.stdc.stdio;
import std.stdio;
import std.algorithm;
import std.range;

void main()
{
    int n;
    scanf("%d", &n);
    int[] a = new int[n];
    foreach (i; 0 .. n)
        scanf("%d", &a[i]);

    bool t = (all!"a%2==0"(a)) || (all!"a%2==1"(a));

    if (!t)
        sort(a);
    writefln("%(%d %)", a);
}

import std.stdio, std.conv, std.functional, std.string;
import std.algorithm, std.array, std.container, std.range, std.typecons;
import std.numeric, std.math, std.random;
import core.bitop;

string FMT_F = "%.10f";

static string[] s_rd;
T RD(T = long)() { while(!s_rd.length) s_rd = readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
string RDR()() { return readln.chomp; }
T[] ARR(T = long)(in string str, T fix = 0) { auto r = str.split.to!(T[]); r[] += fix; return r; }
size_t[] MAKE_IDX(alias less = "a < b", Range)(Range range) { auto idx = new size_t[](range.length); makeIndex!(less)(range, idx); return idx;}
size_t MIN_POS(alias less = "a < b", Range)(Range range) { auto r = minPos!(less)(range); return range.length - r.length; }

bool inside(T)(T x, T b, T e) { return x >= b && x < e; }
long lcm(long x, long y) { return x * y / gcd(x, y); }

long mod = 10^^9 + 7;
//long mod = 998244353;
//long mod = 1_000_003;
void moda(ref long x, long y) { x = (x + y) % mod; }
void mods(ref long x, long y) { x = ((x + mod) - (y % mod)) % mod; }
void modm(ref long x, long y) { x = (x * y) % mod; }

void main()
{
	auto N = RD!int;
	auto A = RDR.ARR;
	bool o, e;
	foreach (i; 0..N)
	{
		if (A[i] % 2 == 0)
			e = true;
		else
			o = true;
	}

	if (o && e)
		A.sort();

	A.map!(to!string).join(" ").writeln;
	stdout.flush();
	debug readln();
}

import core.bitop, std.bitmanip;
import core.checkedint;
import std.algorithm, std.functional;
import std.array, std.container;
import std.bigint;
import std.conv;
import std.datetime.stopwatch;
import std.math, std.numeric;
import std.range, std.range.interfaces;
import std.stdio, std.string;
import std.typecons;

void main()
{
    int n;
    readf("%s", &n);
    readln;

    auto arr = readln.chomp.split.map!(to!int).array;

    bool haveOdd = false, haveEven = false;

    foreach (e; arr) {
        haveOdd |= e % 2 == 1;
        haveEven |= e % 2 == 0;
    }

    if (haveOdd && haveEven) {
        arr.sort();
    }

    arr.writefln!"%(%s %)";
}

//prewritten code: https://github.com/antma/algo
import std.algorithm;
import std.array;
import std.conv;
import std.math;
import std.range;
import std.stdio;
import std.string;
import std.traits;

class InputReader {
  private:
  ubyte[] p;
  ubyte[] buffer;
  size_t cur;
  public:
  this () {
    buffer = uninitializedArray!(ubyte[])(16<<20);
    p = stdin.rawRead (buffer);
  }
  final ubyte skipByte (ubyte lo) {
    while (true) {
      auto a = p[cur .. $];
      auto r = a.find! (c => c >= lo);
      if (!r.empty) {
        cur += a.length - r.length;
        return p[cur++];
      }
      p = stdin.rawRead (buffer);
      cur = 0;
      if (p.empty) return 0;
    }
  }
  final ubyte nextByte () {
    if (cur < p.length) {
       return p[cur++];
    }
    p = stdin.rawRead (buffer);
    if (p.empty) return 0;
    cur = 1;
    return p[0];
  }

  template next(T) if (isSigned!T) {
    final T next ()  {
      T res;
      ubyte b = skipByte (45);
      if (b == 45) {
        while (true) {
          b = nextByte ();
          if (b < 48 || b >= 58) {
            return res;
          }
          res = res * 10 - (b - 48);
        }
      } else {
        res = b - 48;
        while (true) {
          b = nextByte ();
          if (b < 48 || b >= 58) {
            return res;
          }
          res = res * 10 + (b - 48);
        }
      }
    }
  }
  template next(T) if (isUnsigned!T) {
    final T next () {
      T res = skipByte (48) - 48;
      while (true) {
        ubyte b = nextByte ();
        if (b < 48 || b >= 58) {
          break;
        }
        res = res * 10 + (b - 48);
      }
      return res;
    }
  }
  final T[] nextA(T) (int n) {
    auto a = uninitializedArray!(T[]) (n);
    foreach (i; 0 .. n) {
      a[i] = next!T;
    }
    return a;
  }
}

import std.container.rbtree;

void main() {
  auto r = new InputReader;
  int n = r.next!int;
  auto a = r.nextA!int(n);
  int[2] c;
  foreach (i; a) {
    ++c[i&1];
  }
  if (!c[0] || !c[1]) {
  } else {
    a.sort();
  }
  writefln ("%(%s %)", a);
}


import std.conv, std.functional, std.range, std.stdio, std.string;
import std.algorithm, std.array, std.bigint, std.bitmanip, std.complex, std.container, std.math, std.mathspecial, std.numeric, std.regex, std.typecons;
import core.bitop;

class EOFException : Throwable { this() { super("EOF"); } }
string[] tokens;
string readToken() { for (; tokens.empty; ) { if (stdin.eof) { throw new EOFException; } tokens = readln.split; } auto token = tokens.front; tokens.popFront; return token; }
int readInt() { return readToken.to!int; }
long readLong() { return readToken.to!long; }
real readReal() { return readToken.to!real; }

bool chmin(T)(ref T t, in T f) { if (t > f) { t = f; return true; } else { return false; } }
bool chmax(T)(ref T t, in T f) { if (t < f) { t = f; return true; } else { return false; } }

int binarySearch(alias pred, T)(in T[] as) { int lo = -1, hi = cast(int)(as.length); for (; lo + 1 < hi; ) { const mid = (lo + hi) >> 1; (unaryFun!pred(as[mid]) ? hi : lo) = mid; } return hi; }
int lowerBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a >= val)); }
int upperBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a > val)); }

int lcm(int a, int b) {
  return a / gcd(a, b) * b;
}

void main() {
  try {
    for (; ; ) {
      const M = readInt();
      const N = readInt();

      auto ans = new int[][](M, N);
      if (M == 1) {
        if (N == 1) {
          ans[0][0] = 0;
        } else {
          foreach (y; 0 .. N) {
            ans[0][y] = 2 + y;
          }
        }
      } else {
        if (N == 1) {
          foreach (x; 0 .. M) {
            ans[x][0] = 2 + x;
          }
        } else {
          foreach (x; 0 .. M) foreach (y; 0 .. N) {
            ans[x][y] = lcm(1 + x, 1 + M + y);
          }
        }
      }
      foreach (x; 0 .. M) {
        foreach (y; 0 .. N) {
          if (y > 0) write(" ");
          write(ans[x][y]);
        }
        writeln();
      }
    }
  } catch (EOFException e) {
  }
}

import std.algorithm;
import std.conv;
import std.range;
import std.stdio;
import std.string;
import std.typecons;

void main ()
{
	int r, c;
	while (readf !(" %s %s") (r, c) > 0)
	{
		if (r == 1 && c == 1)
		{
			writeln (0);
			continue;
		}
		auto a = new int [] [] (r, c);
		foreach (i; 0..r)
		{
			foreach (j; 0..c)
			{
				a[i][j] = (i + 1) * (j + r + 1);
			}
		}
		if (c == 1)
		{
			foreach (i; 0..r)
			{
				foreach (j; 0..c)
				{
					a[i][j] = (i + c + 1) * (j + 1);
				}
			}
		}
		writefln !("%(%(%s %)\n%)") (a);
	}
}

import std.stdio, std.conv, std.string, std.array, std.range, std.algorithm, std.container;
import std.math, std.random, std.bigint, std.datetime, std.format;
void main(string[] args){ if(args.length > 1) if(args[1] == "-debug") DEBUG = 1; solve(); }
void log()(){ writeln(""); } void log(T, A ...)(T t, lazy A a){ if(DEBUG) write(t, " "), log(a); } bool DEBUG = 0;
string rstring(){ static string[] ss; while(!ss.length) ss = readln.chomp.split; string res = ss[0]; ss.popFront; return res; }
T rtype(T)(){ return rstring.to!T; } alias rint = rtype!int, rlong = rtype!long, rreal = rtype!real;
T[] rtypes(T)(int n){ return n.iota.map!(i => rtype!T()).array; } alias rint = rtypes!int, rlong = rtypes!long, rreal = rtypes!real;
T[][] rtypess(T)(int n, int m){ return n.iota.map!(i => rtypes!T(m)).array; } alias rint = rtypess!int, rlong = rtypess!long, rreal = rtypess!real;
T chmin(T)(ref T x, T y){ if(x > y) x = y; return x; } T chmax(T)(ref T x, T y){ if(x < y) x = y; return x; }

// ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- //

void solve(){
	int r = rint, c = rint;
	int[][] ans;
	if(r == 1 && c == 1) ans = [[0]];
	else if(r == 1){
		ans = [[]];
		foreach(j; 0 .. c) ans[0] ~= j + 2;
	}
	else if(c == 1){
		foreach(i ; 0 .. r) ans ~= [i + 2];
	}
	else{
		foreach(i; 0 .. r){
			ans ~= [[]];
			foreach(j; 0 .. c){
				if(i == 0) ans[i] ~=  1 * (j + 2);
				else ans[i] ~= (c + i + 1) * (j + 2);
			}
		}
	}
	foreach(an; ans) an.map!(to!string).array.join(" ").writeln;
}

import std.stdio, std.conv, std.functional, std.string;
import std.algorithm, std.array, std.container, std.range, std.typecons;
import std.bigint, std.numeric, std.math, std.random;
import core.bitop;

string FMT_F = "%.10f";

static File _f;
void file_io(string fn) { _f = File(fn, "r"); }
static string[] s_rd;
T _RD(T = long)() { while(!s_rd.length) s_rd = readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T _RD(T = long)(File f) { while(!s_rd.length) s_rd = f.readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T[] _RDA(T = long)(T fix = 0) { auto r = readln.chomp.split.to!(T[]); r[] += fix; return r; }
T[] _RDA(T = long)(File f, T fix = 0) { auto r = f.readln.chomp.split.to!(T[]); r[] += fix; return r; }
T RD(T = long)() { if (_f.isOpen) return _RD!T(_f); else return _RD!T; }
T[] RDA(T = long)(T fix = 0) { if (_f.isOpen)  return _RDA!T(_f, fix); else return _RDA!T(fix); }

size_t[] MAKE_IDX(alias less = "a < b", Range)(Range range) { auto idx = new size_t[](range.length); makeIndex!(less)(range, idx); return idx;}
size_t MIN_POS(alias less = "a < b", Range)(Range range) { auto r = minPos!(less)(range); return range.length - r.length; }

void chmin(T)(ref T x, T y) { x = min(x, y); } void chmax(T)(ref T x, T y) { x = max(x, y); }
bool inside(T)(T x, T b, T e) { return x >= b && x < e; }
long lcm(long x, long y) { return x * (y / gcd(x, y)); }

long mod = 10^^9 + 7;
//long mod = 998244353;
//long mod = 1_000_003;
void moda(ref long x, long y) { x = (x + y) % mod; }
void mods(ref long x, long y) { x = ((x + mod) - (y % mod)) % mod; }
void modm(ref long x, long y) { x = (x * y) % mod; }

void main()
{
	auto r = RD!int;
	auto c = RD!int;
	auto ans = new long[][](r, c);
	int x, y;
	if (r < c)
		x = r;
	else
		y = c;
	foreach (i; 0..r)
	{
		foreach (j; 0..c)
		{
			ans[i][j] = lcm(y+i+1, x+j+1);
		}
	}

	if (r == 1 && c == 1)
		writeln(0);
	else
	{
		foreach (i; 0..r)
			ans[i].map!(to!string).join(" ").writeln;
	}
	stdout.flush;
	debug readln;
}

import std.stdio, std.array, std.string, std.conv, std.algorithm;
import std.typecons, std.range, std.random, std.math, std.container;
import std.numeric, std.bigint, core.bitop, core.stdc.stdio;

void main() {
    auto s = readln.split.map!(to!int);
    auto H = s[0];
    auto W = s[1];

    if (H == 1 && W == 1) {
        writeln(0);
        return;
    }

    bool swapped = false;
    if (H > W) swap(H, W), swapped = true;
    auto A = new long[][](H, W);

    auto R = iota(1, H+1).map!(to!long).array;
    auto C = iota(H+1, H+W+1).map!(to!long).array;

    foreach (i; 0..H) foreach (j; 0..W) {
        A[i][j] = R[i] * C[j] / gcd(R[i], C[j]);
    }

    if (!swapped) {
        A.each!(a => a.map!(to!string).join(" ").writeln);
    } else {
        auto ans = new long[][](W, H);
        foreach (i; 0..H) foreach (j; 0..W) ans[j][i] = A[i][j];
        ans.each!(a => a.map!(to!string).join(" ").writeln);
    }

    foreach (i; 0..H) {
        if (A[i].reduce!gcd != R[i]) {
            writeln([H, W]);
            A.each!writeln;
            return;
        }
    }
    foreach (j; 0..W) {
        auto B = H.iota.map!(i => A[i][j]).array;
        if (B.reduce!gcd != C[j]) {
            writeln([H, W]);
            return;
        }
    }
}

import std.stdio, std.array, std.string, std.conv, std.algorithm;
import std.typecons, std.range, std.random, std.math, std.container;
import std.numeric, std.bigint, core.bitop, core.stdc.stdio;

void main() {
    auto s = readln.split.map!(to!int);
    auto H = s[0];
    auto W = s[1];

    if (H == 1 && W == 1) {
        writeln(1);
        return;
    }

    bool swapped = false;
    if (H > W) swap(H, W), swapped = true;
    auto A = new long[][](H, W);

    auto R = iota(1, H+1).map!(to!long).array;
    auto C = iota(H+1, H+W+1).map!(to!long).array;

    foreach (i; 0..H) foreach (j; 0..W) {
        A[i][j] = R[i] * C[j] / gcd(R[i], C[j]);
    }

    if (!swapped) {
        A.each!(a => a.map!(to!string).join(" ").writeln);
    } else {
        auto ans = new long[][](W, H);
        foreach (i; 0..H) foreach (j; 0..W) ans[j][i] = A[i][j];
        ans.each!(a => a.map!(to!string).join(" ").writeln);
    }

}

import std.stdio, std.array, std.string, std.conv, std.algorithm;
import std.typecons, std.range, std.random, std.math, std.container;
import std.numeric, std.bigint, core.bitop, core.stdc.stdio;

void main() {
    auto s = readln.split.map!(to!int);
    auto H = s[0];
    auto W = s[1];
    auto A = new long[][](H, W);

    auto R = iota(1, H+1).map!(to!long).array;
    auto C = iota(H+1, H+W+1).map!(to!long).array;

    foreach (i; 0..H) foreach (j; 0..W) {
        A[i][j] = R[i] * C[j] / gcd(R[i], C[j]);
    }

    A.each!(a => a.map!(to!string).join(" ").writeln);
}

import std.stdio, std.conv, std.functional, std.string;
import std.algorithm, std.array, std.container, std.range, std.typecons;
import std.bigint, std.numeric, std.math, std.random;
import core.bitop;

string FMT_F = "%.10f";

static File _f;
void file_io(string fn) { _f = File(fn, "r"); }
static string[] s_rd;
T _RD(T = long)() { while(!s_rd.length) s_rd = readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T _RD(T = long)(File f) { while(!s_rd.length) s_rd = f.readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T[] _RDA(T = long)(T fix = 0) { auto r = readln.chomp.split.to!(T[]); r[] += fix; return r; }
T[] _RDA(T = long)(File f, T fix = 0) { auto r = f.readln.chomp.split.to!(T[]); r[] += fix; return r; }
T RD(T = long)() { if (_f.isOpen) return _RD!T(_f); else return _RD!T; }
T[] RDA(T = long)(T fix = 0) { if (_f.isOpen)  return _RDA!T(_f, fix); else return _RDA!T(fix); }

size_t[] MAKE_IDX(alias less = "a < b", Range)(Range range) { auto idx = new size_t[](range.length); makeIndex!(less)(range, idx); return idx;}
size_t MIN_POS(alias less = "a < b", Range)(Range range) { auto r = minPos!(less)(range); return range.length - r.length; }

void chmin(T)(ref T x, T y) { x = min(x, y); } void chmax(T)(ref T x, T y) { x = max(x, y); }
bool inside(T)(T x, T b, T e) { return x >= b && x < e; }
long lcm(long x, long y) { return x * (y / gcd(x, y)); }

long mod = 10^^9 + 7;
//long mod = 998244353;
//long mod = 1_000_003;
void moda(ref long x, long y) { x = (x + y) % mod; }
void mods(ref long x, long y) { x = ((x + mod) - (y % mod)) % mod; }
void modm(ref long x, long y) { x = (x * y) % mod; }

void main()
{
	auto r = RD!int;
	auto c = RD!int;
	auto ans = new long[][](r, c);
	foreach (i; 0..r)
	{
		foreach (j; 0..c)
		{
			ans[i][j] = lcm(i+1, r+j+1);
		}
	}

	if (r == 1 && c == 1)
		writeln(0);
	else
	{
		foreach (i; 0..r)
			ans[i].map!(to!string).join(" ").writeln;
	}
	stdout.flush;
	debug readln;
}


// Cheese-Cracker: cheese-cracker.github.io

long oper(ref RedBlackTree!(long, "a < b", true) sett, long curmem, long m){
    long mems = curmem;
    long left = mems - m;
    while(sett.length && left >= sett.front){
        mems -= sett.front;
        sett.removeFront;
        left = mems - m;
    }
    return mems;
}

void solve(){
    int n = scan!int;
    long m = scan;
    auto spaces = scanArray;
    auto priority = scanArray!int;

    auto normals = spaces.enumerate.filter!(a => (priority[a[0]] == 1)).map!(a => a[1]);
    auto imps = spaces.enumerate.filter!(a => (priority[a[0]] == 2)).map!(a => a[1]).array;

    imps.sort;
    imps.reverse;

    long mems = normals.sum;
    auto rbt = redBlackTree!(true)(normals);
    int totconv = 1*rbt.length.to!int + 2*imps.length.to!int;
    mems = oper(rbt, mems, m);

    int baseconv = 0;
    int conv = rbt.length.to!int + baseconv;
    int minconv = 2*n+2;
    if(mems >= m){
        minconv = min(conv, minconv);
    }

    foreach(space; imps){
        baseconv += 2;
        mems += space;
        mems = oper(rbt, mems, m);
        conv = rbt.length.to!int + baseconv;
        /* show(rbt.length, baseconv, conv, mems); */
        if(mems >= m){
            minconv = min(conv, minconv);
        }
    }
    int res = totconv - minconv;
    writeln( (res >= 0) ? minconv : -1);
}

void main(){
    long tests = scan;        // Toggle!
    while(tests--) solve;
}

/**************    *****    That's All Folks!    *****    **************/
import std.stdio, std.range, std.conv, std.typecons, std.algorithm, std.container, std.math, std.numeric;
string[] tk; T scan(T=long)(){while(!tk.length)tk = readln.split; string a=tk.front; tk.popFront; return a.to!T;}
T[] scanArray(T=long)(){ auto r = readln.split.to!(T[]); return r; }
void show(A...)(A a){ debug{ foreach(t; a){stderr.write(t, "| ");} stderr.writeln; } }
alias ll = long, tup = Tuple!(long, "x",  long, "y");

import std.algorithm;
import std.conv;
import std.range;
import std.stdio;
import std.string;

immutable int infinity = int.max / 2;

void main ()
{
	auto tests = readln.strip.to !(int);
	foreach (test; 0..tests)
	{
		int n, m;
		readf !(" %s %s") (n, m);
		readln;
		auto a = readln.splitter.map !(to !(int)).array;
		auto b = readln.splitter.map !(to !(int)).array;
		int [] [3] p;
		foreach (i; 0..n)
		{
			p[b[i]] ~= a[i];
		}
		foreach (k; 1..3)
		{
			sort !(q{a > b}) (p[k]);
		}

		long done = 0;
		int cur = 0;
		foreach (j; 0..p[2].length)
		{
			done += p[2][j];
			cur += 2;
		}

		int i = 0;
		while (i < p[1].length && done < m)
		{
			done += p[1][i];
			cur += 1;
			i += 1;
		}

		int res = infinity;
		if (done >= m)
		{
			res = min (res, cur);
		}

		foreach_reverse (j; 0..p[2].length)
		{
			done -= p[2][j];
			cur -= 2;

			while (i < p[1].length && done < m)
			{
				done += p[1][i];
				cur += 1;
				i += 1;
			}

			if (done >= m)
			{
				res = min (res, cur);
			}
		}

		writeln (res == infinity ? -1 : res);
	}
}

import std.stdio;
import std.functional;
import std.math;
import std.numeric;
import std.container;
import std.typecons;
import std.conv;
import std.array;
import std.string;
import std.range;
import std.algorithm;
import core.bitop;
import core.stdc.stdio : scanf;

T read(T)() { return readln.chomp.to!T; }
T[] readarray(T)() { return readln.chomp.split(" ").map!(to!T).array; }
void chmin(T)(ref T a, in T b) { a = min(a, b); }
void chmax(T)(ref T a, in T b) { a = max(a, b); }

void main() {
    int T = read!int;
    foreach (t; 0 .. T) solve();
}

void solve() {
    int N; long M; readf("%d %d\n", &N, &M);
    auto A = readarray!long;
    auto B = readarray!int;

    if (A.reduce!"a + b" < M) {
        writeln(-1);
        return;
    }

    int[] C, X;
    for (int i = 0; i < N; i++) {
        (B[i] == 1 ? C : X) ~= i;
    }
    C.sort!( (i, j) => A[i] > A[j] );
    X.sort!( (i, j) => A[i] > A[j] );

    int K = C.length;
    auto S = new long[K+1];
    for (int i = 0; i < K; i++) {
        S[i + 1] = S[i] + A[C[i]];
    }

    long ans = B.reduce!"a+b";
    long xsum = 0;
    for (int i = 0; ; i++) {
        long r = M - xsum;
        if (r > 0) {
            int k = S.lowerbound(r);
            if (k == K+1) {
            } else {
                ans.chmin(2*i + k);
            }
        } else {
            ans.chmin(2*i);
        }
        if (i == X.length) break;
        xsum += A[X[i]];
    }
    writeln(ans);
}

int binsearch(alias pred, T)(in T[] xs) {
    // find the minimum `i` that satisfies `pred(xs[i])`
    // NOTE: if none of the elements satisfies pred(x), returns `xs.length`
    alias C = unaryFun!pred;
    int N = cast(int)(xs.length);
    int lb = 0, ub = N;
    if (C(xs[lb])) {
        return 0;
    } else {
        while (lb + 1 < ub) {
            int mid = (lb + ub) / 2;
            (C(xs[mid]) ? ub : lb) = mid;
        }
        return ub;
    }
}
int lowerbound(T)(in T[] xs, in T x) {
    // find the minimum `i` that satisfies `x <= xs[i]`
    return xs.binsearch!(a => a >= x);
}
int upperbound(T)(in T[] xs, in T x) {
    // find the minimum `i` that satisfies `x < xs[i]`
    return xs.binsearch!(a => a > x);
}

import std.stdio, std.algorithm, std.conv, std.array, std.string, std.math, std.typecons, std.numeric, std.container, std.range;

void get(Args...)(ref Args args)
{
    import std.traits, std.meta, std.typecons;

    static if (Args.length == 1) {
        alias Arg = Args[0];

        static if (isArray!Arg) {
          static if (isSomeChar!(ElementType!Arg)) {
            args[0] = readln.chomp.to!Arg;
          } else {
            args[0] = readln.split.to!Arg;
          }
        } else static if (isTuple!Arg) {
            auto input = readln.split;
            static foreach (i; 0..Fields!Arg.length) {
                args[0][i] = input[i].to!(Fields!Arg[i]);
            }
        } else {
            args[0] = readln.chomp.to!Arg;
        }
    } else {
        auto input = readln.split;
        assert(input.length == Args.length);

        static foreach (i; 0..Args.length) {
            args[i] = input[i].to!(Args[i]);
        }
    }
}

void get_lines(Args...)(size_t N, ref Args args)
{
    import std.traits, std.range;

    static foreach (i; 0..Args.length) {
        static assert(isArray!(Args[i]));
        args[i].length = N;
    }

    foreach (i; 0..N) {
        static if (Args.length == 1) {
            get(args[0][i]);
        } else {
            auto input = readln.split;
            static foreach (j; 0..Args.length) {
                args[j][i] = input[j].to!(ElementType!(Args[j]));
            }
        }
    }
}

void main()
{
    int T; get(T);
    while (T--) {
        int N; long M; get(N, M);
        long[] aa; get(aa);
        int[] bb; get(bb);
        long[] hs, ls;
        foreach (i; 0..N) {
            if (bb[i] == 2) {
                hs ~= aa[i];
            } else {
                ls ~= aa[i];
            }
        }
        sort!"a > b"(hs);
        sort!"a > b"(ls);
        int res = int.max;

        if (ls.empty) {
            foreach (i, h; hs) {
                M -= h;
                if (M <= 0) res = min(res, (i.to!int + 1) * 2);
            }
        } else {
            auto cs = new long[](ls.length);
            foreach (i; 0..ls.length) {
                if (i) cs[i] = cs[i-1];
                cs[i] += ls[i];
                if (cs[i] >= M) res = min(res, i.to!int + 1);
            }
            long MM = M;
            foreach (i; 0..hs.length) {
                MM -= hs[i];
                int rr = (i + 1).to!int * 2;
                if (MM <= 0) {
                    res = min(res, rr);
                } else if (MM - cs[$-1] > 0) {
                    continue;
                } else {
                    int l = -1, r = cs.length.to!int;
                    while (l + 1 < r) {
                        auto m = (l + r) / 2;
                        if (MM - cs[m] <= 0) {
                            r = m;
                        } else {
                            l = m;
                        }
                    }
                    res = min(res, rr + r + 1);
                }
            }
        }

        writeln(res == int.max ? -1 : res);
    }
}

import std.stdio, std.conv, std.functional, std.string;
import std.algorithm, std.array, std.container, std.range, std.typecons;
import std.bigint, std.numeric, std.math, std.random;
import core.bitop;

string FMT_F = "%.10f";

static File _f;
void file_io(string fn) { _f = File(fn, "r"); }
static string[] s_rd;
T _RD(T = long)() { while(!s_rd.length) s_rd = readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T _RD(T = long)(File f) { while(!s_rd.length) s_rd = f.readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T[] _RDA(T = long)(T fix = 0) { auto r = readln.chomp.split.to!(T[]); r[] += fix; return r; }
T[] _RDA(T = long)(File f, T fix = 0) { auto r = f.readln.chomp.split.to!(T[]); r[] += fix; return r; }
T RD(T = long)() { if (_f.isOpen) return _RD!T(_f); else return _RD!T; }
T[] RDA(T = long)(T fix = 0) { if (_f.isOpen)  return _RDA!T(_f, fix); else return _RDA!T(fix); }

size_t[] MAKE_IDX(alias less = "a < b", Range)(Range range) { auto idx = new size_t[](range.length); makeIndex!(less)(range, idx); return idx;}
size_t MIN_POS(alias less = "a < b", Range)(Range range) { auto r = minPos!(less)(range); return range.length - r.length; }

void chmin(T)(ref T x, T y) { x = min(x, y); } void chmax(T)(ref T x, T y) { x = max(x, y); }
bool inside(T)(T x, T b, T e) { return x >= b && x < e; }
T lcm(T)(T x, T y) { return x * (y / gcd(x, y)); }

long mod = 10^^9 + 7;
//long mod = 998_244_353;
//long mod = 1_000_003;
void moda(ref long x, long y) { x = (x + y) % mod; }
void mods(ref long x, long y) { x = ((x + mod) - (y % mod)) % mod; }
void modm(ref long x, long y) { x = (x * y) % mod; }
void modpow(ref long x, long y) { if (!y) { x = 1; return; } auto t = x; x.modpow(y>>1); x.modm(x); if (y&1) x.modm(t); }
void modd(ref long x, long y) { y.modpow(mod - 2); x.modm(y); }

T binarySearch(alias pred, T)(T ok, T ng)
{
	while (abs(ok-ng) > 1)
	{
		auto mid = (ok+ng)/2;
		if (unaryFun!pred(mid)) ok = mid;
		else ng = mid;
	}
	return ok;
}

void main()
{
	auto t = RD!int;
	auto ans = new long[](t);
	foreach (ti; 0..t)
	{
		auto n = RD!int;
		auto m = RD!int;
		auto a = RDA;
		auto b = RDA;

		long[] one, two;
		foreach (i; 0..n)
		{
			if (b[i] == 1)
				one ~= a[i];
			else
				two ~= a[i];
		}
		one.sort!"a > b";
		two.sort!"a > b";

		auto c = new long[](two.length+1);
		foreach (i; 0..two.length)
		{
			c[i+1] = c[i] + two[i];
		}

		ans[ti] = long.max;
		long tot;
		foreach (i; 0..one.length+1)
		{
			bool f(int x)
			{
				return tot + c[x] >= m;
			}
			auto r = binarySearch!(f)(cast(int)c.length, -1);
			if (r != c.length)
				ans[ti].chmin(i + r*2);
			if (i != one.length)
				tot += one[i];
		}
	}

	foreach (e; ans)
		writeln(e == long.max ? -1 : e);
	stdout.flush;
	debug readln;
}

// Cheese-Cracker: cheese-cracker.github.io

long oper(ref RedBlackTree!(long, "a < b", true) sett, long mems, long m){
    long left = mems - m;
    while(left > 0 && sett.length && sett.front <= left){
        mems -= sett.front;
        sett.removeFront;
        left = mems - m;
    }
    return mems;
}

void solve(){
    int n = scan!int;
    long m = scan;
    auto spaces = scanArray;
    auto priority = scanArray!int;

    auto normals = spaces.enumerate.filter!(a => (priority[a[0]] == 1)).map!(a => a[1]);
    auto imps = spaces.enumerate.filter!(a => (priority[a[0]] == 2)).map!(a => a[1]).array;

    imps.sort;
    imps.reverse;

    long mems = normals.sum;
    auto rbt = redBlackTree!(true)(normals);
    int totconv = rbt.length.to!int + 2*imps.length.to!int;
    oper(rbt, mems, m);

    int conv = rbt.length.to!int;
    int baseconv = 0;
    int minconv = 2*n+2;
    if(mems - m >= 0){
        minconv = min(conv, minconv);
    }

    foreach(space; imps){
        baseconv += 2;
        mems += space;
        mems = oper(rbt, mems, m);
        conv = rbt.length.to!int + baseconv;
        if(mems - m >= 0){
            minconv = min(conv, minconv);
        }
    }
    int res = totconv - minconv;
    writeln( (res >= 0) ? minconv : -1);
}

void main(){
    long tests = scan;        // Toggle!
    while(tests--) solve;
}

/**************    *****    That's All Folks!    *****    **************/
import std.stdio, std.range, std.conv, std.typecons, std.algorithm, std.container, std.math, std.numeric;
string[] tk; T scan(T=long)(){while(!tk.length)tk = readln.split; string a=tk.front; tk.popFront; return a.to!T;}
T[] scanArray(T=long)(){ auto r = readln.split.to!(T[]); return r; }
void show(A...)(A a){ debug{ foreach(t; a){stderr.write(t, "| ");} stderr.writeln; } }
alias ll = long, tup = Tuple!(long, "x",  long, "y");

// Cheese-Cracker: cheese-cracker.github.io

long oper(ref RedBlackTree!(long, "a < b", true) sett, long mems, long m){
    long left = mems - m;
    while(left > 0 && sett.length && sett.front <= left){
        mems -= sett.front;
        sett.removeFront;
        left = mems - m;
    }
    return mems;
}

void solve(){
    int n = scan!int;
    long m = scan;
    auto spaces = scanArray;
    auto priority = scanArray!int;

    auto normals = spaces.enumerate.filter!(a => (priority[a[0]] == 1)).map!(a => a[1]);
    auto imps = spaces.enumerate.filter!(a => (priority[a[0]] == 2)).map!(a => a[1]).array;

    imps.sort;
    imps.reverse;

    long mems = normals.sum;
    auto rbt = redBlackTree!(true)(normals);
    int totconv = rbt.length.to!int + 2*imps.length.to!int;
    oper(rbt, mems, m);

    int conv = rbt.length.to!int;
    int baseconv = 0;
    int minconv = 2*n+2;
    if(mems - m >= 0){
        minconv = min(conv, minconv);
    }

    foreach(space; imps){
        baseconv += 2;
        mems += space;
        oper(rbt, mems, m);
        conv = rbt.length.to!int + baseconv;
        if(mems - m >= 0){
            minconv = min(conv, minconv);
        }
    }
    int res = totconv - minconv;
    writeln( (res >= 0) ? minconv : -1);
}

void main(){
    long tests = scan;        // Toggle!
    while(tests--) solve;
}

/**************    *****    That's All Folks!    *****    **************/
import std.stdio, std.range, std.conv, std.typecons, std.algorithm, std.container, std.math, std.numeric;
string[] tk; T scan(T=long)(){while(!tk.length)tk = readln.split; string a=tk.front; tk.popFront; return a.to!T;}
T[] scanArray(T=long)(){ auto r = readln.split.to!(T[]); return r; }
void show(A...)(A a){ debug{ foreach(t; a){stderr.write(t, "| ");} stderr.writeln; } }
alias ll = long, tup = Tuple!(long, "x",  long, "y");

// Cheese-Cracker: cheese-cracker.github.io

long oper(ref RedBlackTree!(long, "a < b", true) sett, long mems, long m){
    long left = mems - m;
    while(left > 0 && sett.length && sett.front <= left){
        mems -= sett.front;
        sett.removeFront;
        left = mems - m;
    }
    return mems;
}

void solve(){
    int n = scan!int;
    long m = scan;
    auto spaces = scanArray;
    auto priority = scanArray!int;

    auto normals = spaces.enumerate.filter!(a => (priority[a[0]] == 1)).map!(a => a[1]);
    auto imps = spaces.enumerate.filter!(a => (priority[a[0]] == 2)).map!(a => a[1]).array;

    imps.sort;
    imps.reverse;

    long mems = normals.sum;
    auto rbt = redBlackTree!(true)(normals);
    int totconv = rbt.length.to!int + 2*imps.length.to!int;
    oper(rbt, mems, m);

    int conv = rbt.length.to!int;
    int baseconv = 0;
    int minconv = 2*n+2;
    if(mems - m > 0){
        minconv = min(conv, minconv);
    }

    foreach(space; imps){
        baseconv += 2;
        mems += space;
        oper(rbt, mems, m);
        conv = rbt.length.to!int + baseconv;
        if(mems - m > 0){
            minconv = min(conv, minconv);
        }
    }
    int res = totconv - minconv;
    writeln( (res >= 0) ? minconv : -1);
}

void main(){
    long tests = scan;        // Toggle!
    while(tests--) solve;
}

/**************    *****    That's All Folks!    *****    **************/
import std.stdio, std.range, std.conv, std.typecons, std.algorithm, std.container, std.math, std.numeric;
string[] tk; T scan(T=long)(){while(!tk.length)tk = readln.split; string a=tk.front; tk.popFront; return a.to!T;}
T[] scanArray(T=long)(){ auto r = readln.split.to!(T[]); return r; }
void show(A...)(A a){ debug{ foreach(t; a){stderr.write(t, "| ");} stderr.writeln; } }
alias ll = long, tup = Tuple!(long, "x",  long, "y");

import std.stdio;
import std.functional;
import std.math;
import std.numeric;
import std.container;
import std.typecons;
import std.conv;
import std.array;
import std.string;
import std.range;
import std.algorithm;
import core.bitop;
import core.stdc.stdio : scanf;

T read(T)() { return readln.chomp.to!T; }
T[] readarray(T)() { return readln.chomp.split(" ").map!(to!T).array; }
void chmin(T)(ref T a, in T b) { a = min(a, b); }
void chmax(T)(ref T a, in T b) { a = max(a, b); }

void main() {
    int T = read!int;
    foreach (t; 0 .. T) solve();
}

void solve() {
    int N; long M; readf("%d %d\n", &N, &M);
    auto A = readarray!long;
    auto B = readarray!int;

    if (A.reduce!"a + b" < M) {
        writeln(-1);
        return;
    }

    int[] C, X;
    for (int i = 0; i < N; i++) {
        (B[i] == 1 ? C : X) ~= i;
    }
    C.sort!( (i, j) => A[i] > A[j] );
    X.sort!( (i, j) => A[i] > A[j] );

    int K = C.length;
    auto S = new long[K+1];
    for (int i = 0; i < K; i++) {
        S[i + 1] = S[i] + A[C[i]];
    }

    long ans = A.reduce!"a+b";
    long xsum = 0;
    for (int i = 0; ; i++) {
        long r = M - xsum;
        if (r > 0) {
            int k = S.lowerbound(r);
            if (k == K+1) {
            } else {
                ans.chmin(2*i + k);
            }
        } else {
            ans.chmin(2*i);
        }
        if (i == X.length) break;
        xsum += A[X[i]];
    }
    writeln(ans);
}

int binsearch(alias pred, T)(in T[] xs) {
    // find the minimum `i` that satisfies `pred(xs[i])`
    // NOTE: if none of the elements satisfies pred(x), returns `xs.length`
    alias C = unaryFun!pred;
    int N = cast(int)(xs.length);
    int lb = 0, ub = N;
    if (C(xs[lb])) {
        return 0;
    } else {
        while (lb + 1 < ub) {
            int mid = (lb + ub) / 2;
            (C(xs[mid]) ? ub : lb) = mid;
        }
        return ub;
    }
}
int lowerbound(T)(in T[] xs, in T x) {
    // find the minimum `i` that satisfies `x <= xs[i]`
    return xs.binsearch!(a => a >= x);
}
int upperbound(T)(in T[] xs, in T x) {
    // find the minimum `i` that satisfies `x < xs[i]`
    return xs.binsearch!(a => a > x);
}

import std.stdio;
import std.functional;
import std.math;
import std.numeric;
import std.container;
import std.typecons;
import std.conv;
import std.array;
import std.string;
import std.range;
import std.algorithm;
import core.bitop;
import core.stdc.stdio : scanf;

T read(T)() { return readln.chomp.to!T; }
T[] readarray(T)() { return readln.chomp.split(" ").map!(to!T).array; }
void chmin(T)(ref T a, in T b) { a = min(a, b); }
void chmax(T)(ref T a, in T b) { a = max(a, b); }

void main() {
    int T = read!int;
    foreach (t; 0 .. T) solve();
}

void solve() {
    int N, M; readf("%d %d\n", &N, &M);
    auto A = readarray!int;
    auto B = readarray!int;

    if (A.reduce!"a + b" < M) {
        writeln(-1);
        return;
    }

    int[] C, X;
    for (int i = 0; i < N; i++) {
        (B[i] == 1 ? C : X) ~= i;
    }
    C.sort!( (i, j) => A[i] > A[j] );
    X.sort!( (i, j) => A[i] > A[j] );

    int K = C.length;
    auto S = new long[K+1];
    for (int i = 0; i < K; i++) {
        S[i + 1] = S[i] + A[C[i]];
    }

    int ans = A.reduce!"a+b";
    long xsum = 0;
    for (int i = 0; ; i++) {
        long r = M - xsum;
        if (r > 0) {
            int k = S.lowerbound(r);
            if (k == K+1) {
            } else {
                ans.chmin(2*i + k);
            }
        } else {
            ans.chmin(2*i);
        }
        if (i == X.length) break;
        xsum += A[X[i]];
    }
    writeln(ans);
}

int binsearch(alias pred, T)(in T[] xs) {
    // find the minimum `i` that satisfies `pred(xs[i])`
    // NOTE: if none of the elements satisfies pred(x), returns `xs.length`
    alias C = unaryFun!pred;
    int N = cast(int)(xs.length);
    int lb = 0, ub = N;
    if (C(xs[lb])) {
        return 0;
    } else {
        while (lb + 1 < ub) {
            int mid = (lb + ub) / 2;
            (C(xs[mid]) ? ub : lb) = mid;
        }
        return ub;
    }
}
int lowerbound(T)(in T[] xs, in T x) {
    // find the minimum `i` that satisfies `x <= xs[i]`
    return xs.binsearch!(a => a >= x);
}
int upperbound(T)(in T[] xs, in T x) {
    // find the minimum `i` that satisfies `x < xs[i]`
    return xs.binsearch!(a => a > x);
}