Bytelandian Tree Factory produces trees for all kinds of industrial applications. You have been tasked with optimizing the production of a certain type of tree for an especially large and important order.The tree in question is a rooted tree with $$$n$$$ vertices labelled with distinct integers from $$$0$$$ to $$$n - 1$$$. The vertex labelled $$$0$$$ is the root of the tree, and for any non-root vertex $$$v$$$ the label of its parent $$$p(v)$$$ is less than the label of $$$v$$$.All trees at the factory are made from bamboo blanks. A bamboo is a rooted tree such that each vertex has exactly one child, except for a single leaf vertex with no children. The vertices of a bamboo blank can be labelled arbitrarily before its processing is started.To process a bamboo into another tree a single type of operation can be made: choose an arbitrary non-root vertex $$$v$$$ such that its parent $$$p(v)$$$ is not a root either. The operation consists of changing the parent of $$$v$$$ to its parent's parent $$$p(p(v))$$$. Note that parents of all other vertices remain unchanged, in particular, the subtree of $$$v$$$ does not change.Efficiency is crucial, hence you have to minimize the number of operations to make the desired tree from a bamboo blank. Construct any optimal sequence of operations to produce the desired tree.Note that the labelling of the resulting tree has to coincide with the labelling of the desired tree. Formally, the labels of the roots have to be equal, and for non-root vertices with the same label the labels of their parents should be the same.It is guaranteed that for any test present in this problem an answer exists, and further, an optimal sequence contains at most $$$10^6$$$ operations. Note that any hack that does not meet these conditions will be invalid.

The first line contains a single integer $$$n$$$ — the number of vertices in the tree ($$$2 \leq n \leq 10^5$$$). The second line contains $$$n - 1$$$ integers $$$p(1), \ldots, p(n - 1)$$$ — indices of parent vertices of $$$1, \ldots, n - 1$$$ respectively ($$$0 \leq p(i) < i$$$).

In the first line, print $$$n$$$ distinct integers $$$id_1, \ldots, id_n$$$ — the initial labelling of the bamboo blank starting from the root vertex ($$$0 \leq id_i < n$$$). In the second line, print a single integer $$$k$$$ — the number of operations in your sequence ($$$0 \leq k \leq 10^6$$$). In the third line print $$$k$$$ integers $$$v_1, \ldots, v_k$$$ describing operations in order. The $$$i$$$-th operation consists of changing $$$p(v_i)$$$ to $$$p(p(v_i))$$$. Each operation should be valid, i.e. neither $$$v_i$$$ nor $$$p(v_i)$$$ can be the root of the tree at the moment.

import std.conv, std.functional, std.range, std.stdio, std.string;
import std.algorithm, std.array, std.bigint, std.complex, std.container, std.math, 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 N;
int[] P;
int[][] G;

void main() {
  try {
    for (; ; ) {
      N = readInt();
      P = new int[N];
      P[0] = -1;
      foreach (u; 1 .. N) {
        P[u] = readInt();
      }

      G = new int[][N];
      foreach (u; 1 .. N) {
        G[P[u]] ~= u;
      }

      auto dpSum = new int[N];
      auto dpMin = new int[N];
      auto dpMax = new int[N];
      dpSum[] = 1;
      dpMin[] = N;
      dpMax[] = 0;
      void add(int u, int p) {
        dpSum[p] += dpSum[u];
        if (dpMin[u] >= N) {
          dpMin[u] = 0;
        }
        chmin(dpMin[p], 1 + dpMin[u]);
        chmax(dpMax[p], 1 + dpMax[u]);
      }

      foreach_reverse (u; 1 .. N) {
        add(u, P[u]);
      }
      debug {
        writeln("dpSum = ", dpSum);
        writeln("dpMin = ", dpMin);
        writeln("dpMax = ", dpMax);
      }

      int[] path, ops;
      for (int u = 0; ; ) {
        path ~= u;
        const len = cast(int)(G[u].length);
        if (len == 0) {
          break;
        }
        // 2043 10
        // G[u].sort!((v, w) => (dpSum[v] < dpSum[w]));
        // 5479
        // G[u].sort!((v, w) => (dpSum[v] > dpSum[w]));
        // 2044
        // G[u].sort!((v, w) => (dpMin[v] < dpMin[w]));
        // 3058
        // G[u].sort!((v, w) => (dpMin[v] > dpMin[w]));
        // 2043 7
        G[u].sort!((v, w) => (dpMax[v] < dpMax[w]));
        // 3078
        // G[u].sort!((v, w) => (dpMax[v] > dpMax[w]));
        foreach_reverse (j; 1 .. len) {
          ops ~= G[u][j];
          G[G[u][j - 1]] ~= G[u][j];
          add(G[u][j], G[u][j - 1]);
        }
        u = G[u][0];
      }
      debug {
        writeln("path = ", path);
        writeln("ops = ", ops);
        assert(path.length == N);
        auto p = new int[N];
        p[path[0]] = -1;
        foreach (i; 1 .. N) {
          p[path[i]] = path[i - 1];
        }
        foreach_reverse (u; ops) {
          p[u] = p[p[u]];
        }
        assert(p == P);
      }

      foreach (i; 0 .. N) {
        if (i > 0) write(" ");
        write(path[i]);
      }
      writeln();
      writeln(ops.length);
      int ou;
      foreach_reverse (u; ops) {
        if (ou++) write(" ");
        write(u);
      }
      writeln();
    }
  } catch (EOFException e) {
  }
}

import std.conv, std.functional, std.range, std.stdio, std.string;
import std.algorithm, std.array, std.bigint, std.complex, std.container, std.math, 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 N;
int[] P;
int[][] G;

void main() {
  try {
    for (; ; ) {
      N = readInt();
      P = new int[N];
      P[0] = -1;
      foreach (u; 1 .. N) {
        P[u] = readInt();
      }

      G = new int[][N];
      foreach (u; 1 .. N) {
        G[P[u]] ~= u;
      }

      auto dpSum = new int[N];
      auto dpMin = new int[N];
      auto dpMax = new int[N];
      dpSum[] = 1;
      dpMin[] = N;
      dpMax[] = 0;
      void add(int u, int p) {
        dpSum[p] += dpSum[u];
        if (dpMin[u] >= N) {
          dpMin[u] = 0;
        }
        chmin(dpMin[p], 1 + dpMin[u]);
        chmax(dpMax[p], 1 + dpMax[u]);
      }

      foreach_reverse (u; 1 .. N) {
        add(u, P[u]);
      }
      debug {
        writeln("dpSum = ", dpSum);
        writeln("dpMin = ", dpMin);
        writeln("dpMax = ", dpMax);
      }

      int[] path, ops;
      for (int u = 0; ; ) {
        path ~= u;
        const len = cast(int)(G[u].length);
        if (len == 0) {
          break;
        }
        // 2043 10
        G[u].sort!((v, w) => (dpSum[v] < dpSum[w]));
        // 5479
        // G[u].sort!((v, w) => (dpSum[v] > dpSum[w]));
        // 2044
        // G[u].sort!((v, w) => (dpMin[v] < dpMin[w]));
        // 3058
        // G[u].sort!((v, w) => (dpMin[v] > dpMin[w]));
        // 2043
        // G[u].sort!((v, w) => (dpMax[v] < dpMax[w]));
        // 3078 11
        // G[u].sort!((v, w) => (dpMax[v] > dpMax[w]));
        foreach_reverse (j; 1 .. len) {
          ops ~= G[u][j];
          G[G[u][j - 1]] ~= G[u][j];
          add(G[u][j], G[u][j - 1]);
        }
        u = G[u][0];
      }
      debug {
        writeln("path = ", path);
        writeln("ops = ", ops);
        assert(path.length == N);
        auto p = new int[N];
        p[path[0]] = -1;
        foreach (i; 1 .. N) {
          p[path[i]] = path[i - 1];
        }
        foreach_reverse (u; ops) {
          p[u] = p[p[u]];
        }
        assert(p == P);
      }

      foreach (i; 0 .. N) {
        if (i > 0) write(" ");
        write(path[i]);
      }
      writeln();
      writeln(ops.length);
      int ou;
      foreach_reverse (u; ops) {
        if (ou++) write(" ");
        write(u);
      }
      writeln();
    }
  } catch (EOFException e) {
  }
}


Polycarp found on the street an array $$$a$$$ of $$$n$$$ elements.Polycarp invented his criterion for the beauty of an array. He calls an array $$$a$$$ beautiful if at least one of the following conditions must be met for each different pair of indices $$$i \ne j$$$:   $$$a_i$$$ is divisible by $$$a_j$$$;  or $$$a_j$$$ is divisible by $$$a_i$$$. For example, if:   $$$n=5$$$ and $$$a=[7, 9, 3, 14, 63]$$$, then the $$$a$$$ array is not beautiful (for $$$i=4$$$ and $$$j=2$$$, none of the conditions above is met);  $$$n=3$$$ and $$$a=[2, 14, 42]$$$, then the $$$a$$$ array is beautiful;  $$$n=4$$$ and $$$a=[45, 9, 3, 18]$$$, then the $$$a$$$ array is not beautiful (for $$$i=1$$$ and $$$j=4$$$ none of the conditions above is met); Ugly arrays upset Polycarp, so he wants to remove some elements from the array $$$a$$$ so that it becomes beautiful. Help Polycarp determine the smallest number of elements to remove to make the array $$$a$$$ beautiful.

The first line contains one integer $$$t$$$ ($$$1 \leq t \leq 10$$$) — the number of test cases. Then $$$t$$$ test cases follow. The first line of each test case contains one integer $$$n$$$ ($$$1 \leq n \leq 2 \cdot 10^5$$$) — the length of the array $$$a$$$. The second line of each test case contains $$$n$$$ numbers $$$a_1, a_2, \ldots, a_n$$$ ($$$1 \le a_i \le 2 \cdot 10^5$$$) — elements of the array $$$a$$$.

For each test case output one integer — the minimum number of elements that must be removed to make the array $$$a$$$ beautiful.

NoteIn the first test case, removing $$$7$$$ and $$$14$$$ will make array $$$a$$$ beautiful.In the second test case, the array $$$a$$$ is already beautiful.In the third test case, removing one of the elements $$$45$$$ or $$$18$$$ will make the array $$$a$$$ beautiful.In the fourth test case, the array $$$a$$$ is beautiful.

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

int[][] divs;
const int sz = 200002;
void preprocess(){
    divs = new int[][sz];
    for(int k = 1; k < sz; ++k){
        for(int m = 2*k; m < sz; m += k){
            divs[m] ~= k;
        }
    }
}

void solve(){
    auto n = scan!int;
    auto arr = scanArray!int;

    auto cnt = new long[](sz);
    auto push = new long[](sz);
    long maxcnt = 0;

    foreach(el; arr){
        ++cnt[el];
    }
    auto rbt = redBlackTree!int(arr);

    auto uniqs = rbt.array.sort.reverse;
    foreach(el; uniqs){
        foreach(divi; divs[el]){
            push[divi] = max(push[el] + cnt[el], push[divi]);
        }
        maxcnt = max(push[el] + cnt[el], maxcnt);
    }
    writeln(n - maxcnt);
}

void main(){
    long tests = scan;        // Toggle!
    preprocess;
    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, 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; get(N);
        auto memo = new int[](10^^5 * 2 + 1);
        foreach (a; readln.split) memo[a.to!int] += 1;

        auto DP = new int[](10^^5 * 2 + 1);
        foreach (i; 1..10^^5 * 2 + 1) {
            DP[i] += memo[i];
            auto j = i * 2;
            while (j <= 10^^5 * 2) {
                DP[j] = max(DP[i], DP[j]);
                j += i;
            }
        }

        writeln(N - DP.maxElement());
    }
}


You are playing a game similar to Sokoban on an infinite number line. The game is discrete, so you only consider integer positions on the line.You start on a position $$$0$$$. There are $$$n$$$ boxes, the $$$i$$$-th box is on a position $$$a_i$$$. All positions of the boxes are distinct. There are also $$$m$$$ special positions, the $$$j$$$-th position is $$$b_j$$$. All the special positions are also distinct.In one move you can go one position to the left or to the right. If there is a box in the direction of your move, then you push the box to the next position in that direction. If the next position is taken by another box, then that box is also pushed to the next position, and so on. You can't go through the boxes. You can't pull the boxes towards you.You are allowed to perform any number of moves (possibly, zero). Your goal is to place as many boxes on special positions as possible. Note that some boxes can be initially placed on special positions.

The first line contains a single integer $$$t$$$ ($$$1 \le t \le 1000$$$) — the number of testcases. Then descriptions of $$$t$$$ testcases follow. The first line of each testcase contains two integers $$$n$$$ and $$$m$$$ ($$$1 \le n, m \le 2 \cdot 10^5$$$) — the number of boxes and the number of special positions, respectively. The second line of each testcase contains $$$n$$$ distinct integers in the increasing order $$$a_1, a_2, \dots, a_n$$$ ($$$-10^9 \le a_1 < a_2 < \dots < a_n \le 10^9$$$; $$$a_i \neq 0$$$) — the initial positions of the boxes. The third line of each testcase contains $$$m$$$ distinct integers in the increasing order $$$b_1, b_2, \dots, b_m$$$ ($$$-10^9 \le b_1 < b_2 < \dots < b_m \le 10^9$$$; $$$b_i \neq 0$$$) — the special positions. The sum of $$$n$$$ over all testcases doesn't exceed $$$2 \cdot 10^5$$$. The sum of $$$m$$$ over all testcases doesn't exceed $$$2 \cdot 10^5$$$.

For each testcase print a single integer — the maximum number of boxes that can be placed on special positions.

NoteIn the first testcase you can go $$$5$$$ to the right: the box on position $$$1$$$ gets pushed to position $$$6$$$ and the box on position $$$5$$$ gets pushed to position $$$7$$$. Then you can go $$$6$$$ to the left to end up on position $$$-1$$$ and push a box to $$$-2$$$. At the end, the boxes are on positions $$$[-2, 6, 7, 11, 15]$$$, respectively. Among them positions $$$[-2, 6, 7, 15]$$$ are special, thus, the answer is $$$4$$$.In the second testcase you can push the box from $$$-1$$$ to $$$-10^9$$$, then the box from $$$1$$$ to $$$10^9$$$ and obtain the answer $$$2$$$.The third testcase showcases that you are not allowed to pull the boxes, thus, you can't bring them closer to special positions.In the fourth testcase all the boxes are already on special positions, so you can do nothing and still obtain the answer $$$3$$$.In the fifth testcase there are fewer special positions than boxes. You can move either $$$8$$$ or $$$9$$$ to the right to have some box on position $$$10$$$.

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

int solve (int [] a, int [] b)
{
	sort (a);
	sort (b);
	auto n = a.length.to !(int);
	auto m = b.length.to !(int);
	auto isGood = new int [m];

	{
		int i = 0;
		foreach (j; 0..m)
		{
			while (i < n && a[i] < b[j])
			{
				i += 1;
			}
			isGood[j] = (i < n && a[i] == b[j]);
		}
	}

	int curGood = isGood.sum;
	int best = curGood;

	{
		int i = 0;
		int j = 0;
		foreach (k; 0..m)
		{
			curGood -= isGood[k];
			while (i < n && a[i] <= b[k])
			{
				i += 1;
			}
			while (j < m && b[j] <= b[k] - i)
			{
				j += 1;
			}
			best = max (best, curGood + k - j + 1);
		}
	}

	return best;
}

void main ()
{
	auto tests = readln.strip.to !(int);
	foreach (test; 0..tests)
	{
		readln;
		auto a = readln.splitter.map !(to !(int)).array;
		auto b = readln.splitter.map !(to !(int)).array;
		writeln (solve (a.filter !(q{a > 0}).array,
		    b.filter !(q{a > 0}).array) +
		    solve (a.filter !(q{a < 0}).map !(q{-a}).array,
		    b.filter !(q{a < 0}).map !(q{-a}).array));
	}
}

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

int solve (int [] a, int [] b)
{
	sort (a);
	sort (b);
	auto n = a.length.to !(int);
	auto m = b.length.to !(int);
	auto isGood = new int [m];

	{
		int i = 0;
		foreach (j; 0..m)
		{
			while (i < n && a[i] < b[j])
			{
				i += 1;
			}
			isGood[j] = (i < n && a[i] == b[j]);
		}
	}

	int curGood = isGood.sum;
	int best = curGood;

	{
		int i = 0;
		int j = 0;
		foreach (k; 0..m)
		{
			curGood -= isGood[k];
			while (i < n && a[i] <= b[k])
			{
				i += 1;
			}
			int span = min (i, k + 1);
			while (j < m && b[j] <= b[k] - span)
			{
				j += 1;
			}
			best = max (best, curGood + span);
		}
	}

	return best;
}

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;
		writeln (solve (a.filter !(q{a > 0}).array,
		    b.filter !(q{a > 0}).array) +
		    solve (a.filter !(q{a < 0}).map !(q{-a}).array,
		    b.filter !(q{a < 0}).map !(q{-a}).array));
	}
}

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

int solve (int [] a, int [] b)
{
	sort (a);
	sort (b);
	auto n = a.length.to !(int);
	auto m = b.length.to !(int);
	auto isGood = new int [m];

	{
		int i = 0;
		foreach (j; 0..m)
		{
			while (i < n && a[i] < b[j])
			{
				i += 1;
			}
			isGood[j] = (i < n && a[i] == b[j]);
		}
	}

	int curGood = isGood.sum;
	int best = curGood;

	{
		int i = 0;
		int j = 0;
		foreach (k; 0..m)
		{
			curGood -= isGood[k];
			while (i < n && a[i] <= b[k])
			{
				i += 1;
			}
			int span = min (i, k + 1);
			while (j < m && b[j] <= b[k] - span)
			{
				j += 1;
			}
			best = max (best, curGood + min (span, k - j + 1));
		}
	}

	return best;
}

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;
		writeln (solve (a.filter !(q{a > 0}).array,
		    b.filter !(q{a > 0}).array) +
		    solve (a.filter !(q{a < 0}).map !(q{-a}).array,
		    b.filter !(q{a < 0}).map !(q{-a}).array));
	}
}


David was given a red checkered rectangle of size $$$n \times m$$$. But he doesn't like it. So David cuts the original or any other rectangle piece obtained during the cutting into two new pieces along the grid lines. He can do this operation as many times as he wants.As a result, he will get a set of rectangles. Rectangles $$$1 \times 1$$$ are forbidden.David also knows how to paint the cells blue. He wants each rectangle from the resulting set of pieces to be colored such that any pair of adjacent cells by side (from the same piece) have different colors.What is the minimum number of cells David will have to paint?

The first line contains a single integer $$$t$$$ ($$$1 \leq t \leq 10^3$$$) — the number of test cases. The next lines contain descriptions of test cases. The only line of each test case contains two integers $$$n$$$, $$$m$$$ ($$$1 \leq n, m \leq 3 \cdot 10^4$$$, $$$n \cdot m \geq 2$$$).

For each test case print a single integer — the minimum number of cells David will have to paint blue.

NoteThe following pictures show how the initial rectangle can be split and cells colored blue.In the first test case:  In the second test case:  In the third test case:  In the fourth test case:

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

void solve(){
    auto n = scan;
    auto m = scan;
    long a = n / 3;
    long b = m / 3;
    long lefa = n % 3;
    long lefb = m % 3;
    long res = lefb * a + lefa * b + min(lefa, lefb) + (a * b * 3);
    writeln(res);
}

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;
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

void solve(){
    auto n = scan!int;
    auto m = scan!int;
    int minn = min(n, m);
    int maxx = max(n, m);
    int res = min(minn * ((maxx/3) + (maxx % 3 != 0)), maxx *( (minn/3) + (minn % 3 != 0)));
    writeln(res);
}

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;
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");


An army of n droids is lined up in one row. Each droid is described by m integers a1, a2, ..., am, where ai is the number of details of the i-th type in this droid's mechanism. R2-D2 wants to destroy the sequence of consecutive droids of maximum length. He has m weapons, the i-th weapon can affect all the droids in the army by destroying one detail of the i-th type (if the droid doesn't have details of this type, nothing happens to it). A droid is considered to be destroyed when all of its details are destroyed. R2-D2 can make at most k shots. How many shots from the weapon of what type should R2-D2 make to destroy the sequence of consecutive droids of maximum length?

The first line contains three integers n, m, k (1 ≤ n ≤ 105, 1 ≤ m ≤ 5, 0 ≤ k ≤ 109) — the number of droids, the number of detail types and the number of available shots, respectively. Next n lines follow describing the droids. Each line contains m integers a1, a2, ..., am (0 ≤ ai ≤ 108), where ai is the number of details of the i-th type for the respective robot.

Print m space-separated integers, where the i-th number is the number of shots from the weapon of the i-th type that the robot should make to destroy the subsequence of consecutive droids of the maximum length. If there are multiple optimal solutions, print any of them.  It is not necessary to make exactly k shots, the number of shots can be less.

NoteIn the first test the second, third and fourth droids will be destroyed. In the second test the first and second droids will be destroyed.

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

class SegmentTree(T)
{
    class Node
    {
        int leftIndex;
        int rightIndex;
        T[5] maximum;
        T[5] minimum;
        Node left;
        Node right;

        this(int leftIndex, int rightIndex, int m)
        {
            this.leftIndex = leftIndex;
            this.rightIndex = rightIndex;
            this.left = this.right = null;
        }
    }

    protected Node root;
    immutable static T bound = T.max;

    this(T[][] arr)
    {
        this.initializeTree(this.root, arr, 0, cast(int)arr.length - 1);
    }

    protected void initializeTree(ref Node node, T[][] arr, int leftIndex, int rightIndex)
    {
        auto m = cast(int)arr[0].length;
        node = new Node(leftIndex, rightIndex, m);
        if (leftIndex == rightIndex)
        {
            foreach (i; 0 .. m)
            {
                node.maximum[i] = node.minimum[i] = arr[leftIndex][i];
            }
            return;
        }
        auto mid = (leftIndex + rightIndex) >> 1;
        initializeTree(node.left, arr, leftIndex, mid);
        initializeTree(node.right, arr, mid + 1, rightIndex);
        foreach (i; 0 .. m)
        {
            node.maximum[i] = max(node.left.maximum[i], node.right.maximum[i]);
            node.minimum[i] = min(node.left.minimum[i], node.right.minimum[i]);
        }
    }

    T[5] queryMax(int left, int right)
    {
        return _queryMax(root, left, right);
    }

    protected T[5] _queryMax(Node node, int left, int right)
    {
        auto m = cast(int)node.maximum.length;
        T[5] res;
        if (left <= node.leftIndex && right >= node.rightIndex)
        {
            foreach (i; 0 .. m)
            {
                res[i] = node.maximum[i];
            }
            return res;
        }
        if (left > node.rightIndex || right < node.leftIndex)
        {
            foreach (i; 0 .. m)
            {
                res[i] = -T.max;
            }
            return res;
        }
        auto leftMax = _queryMax(node.left, left, right);
        auto rightMax = _queryMax(node.right, left, right);
        foreach (i; 0 .. m)
        {
            res[i] = max(leftMax[i], rightMax[i]);
        }
        return res;
    }
}

void solve(int n, int m, int k, int[][] a)
{
    auto st = new SegmentTree!int(a);
    auto sl = -1, sr = -1;
    auto longest = 0;
    auto prev = new int[m];
    foreach (i; 0 .. n)
    {
        auto left = i + longest, right = n - 1;
        if (left >= n)
        {
            break;
        }
        fill(prev, 0);
        if (left > i)
        {
            auto ret = st.queryMax(i, left - 1);
            foreach (j; 0 .. m)
            {
                prev[j] = ret[j];
            }
        }
        while (left <= right)
        {
            auto mid = (left + right) >> 1;
            auto ret = st.queryMax(left, mid);
            auto need = 0;
            foreach (j; 0 .. m)
            {
                need += max(prev[j], ret[j]);
                if (need > k)
                {
                    break;
                }
            }
            if (need > k)
            {
                right = mid - 1;
            }
            else
            {
                left = mid + 1;
                foreach (j; 0 .. m)
                {
                    prev[j] = max(prev[j], ret[j]);
                }
                if (mid - i + 1 > longest)
                {
                    longest = mid - i + 1;
                    sl = i;
                    sr = mid;
                }
            }
        }
    }
    auto s = new int[m];
    fill(s, 0);
    if (longest > 0)
    {
        foreach (i; sl .. sr + 1)
        {
            foreach (j; 0 .. m)
            {
                s[j] = max(s[j], a[i][j]);
            }
        }
    }
    foreach (i; 0 .. m)
    {
        write(s[i]);
        if (i < m)
        {
            write(" ");
        }
    }
    writeln();
}

int main(string[] args)
{
    int n, m, k;
    while (readf("%d %d %d\n", &n, &m, &k) == 3)
    {
        auto a = new int[][](n, m);
        foreach (i; 0 .. n)
        {
            foreach (j; 0 .. m)
            {
                readf(" %d", &a[i][j]);
            }
            readln;
        }
        solve(n, m, k, a);
    }
    return 0;
}

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

class SegmentTree(T)
{
    class Node
    {
        int leftIndex;
        int rightIndex;
        T[] maximum;
        T[] minimum;
        Node left;
        Node right;

        this(int leftIndex, int rightIndex, int m)
        {
            this.maximum = new T[m];
            this.minimum = new T[m];
            this.leftIndex = leftIndex;
            this.rightIndex = rightIndex;
            this.left = this.right = null;
        }
    }

    protected Node root;
    immutable static T bound = T.max;

    this(T[][] arr)
    {
        this.initializeTree(this.root, arr, 0, cast(int)arr.length - 1);
    }

    protected void initializeTree(ref Node node, T[][] arr, int leftIndex, int rightIndex)
    {
        auto m = cast(int)arr[0].length;
        node = new Node(leftIndex, rightIndex, m);
        if (leftIndex == rightIndex)
        {
            foreach (i; 0 .. m)
            {
                node.maximum[i] = node.minimum[i] = arr[leftIndex][i];
            }
            return;
        }
        auto mid = (leftIndex + rightIndex) >> 1;
        initializeTree(node.left, arr, leftIndex, mid);
        initializeTree(node.right, arr, mid + 1, rightIndex);
        foreach (i; 0 .. m)
        {
            node.maximum[i] = max(node.left.maximum[i], node.right.maximum[i]);
            node.minimum[i] = min(node.left.minimum[i], node.right.minimum[i]);
        }
    }

    T[5] queryMax(int left, int right)
    {
        return _queryMax(root, left, right);
    }

    protected T[5] _queryMax(Node node, int left, int right)
    {
        auto m = cast(int)node.maximum.length;
        T[5] res;
        if (left <= node.leftIndex && right >= node.rightIndex)
        {
            foreach (i; 0 .. m)
            {
                res[i] = node.maximum[i];
            }
            return res;
        }
        if (left > node.rightIndex || right < node.leftIndex)
        {
            foreach (i; 0 .. m)
            {
                res[i] = -T.max;
            }
            return res;
        }
        auto leftMax = _queryMax(node.left, left, right);
        auto rightMax = _queryMax(node.right, left, right);
        foreach (i; 0 .. m)
        {
            res[i] = max(leftMax[i], rightMax[i]);
        }
        return res;
    }
}

void solve(int n, int m, int k, int[][] a)
{
    auto st = new SegmentTree!int(a);
    auto sl = -1, sr = -1;
    auto longest = 0;
    auto prev = new int[m];
    foreach (i; 0 .. n)
    {
        auto left = i + longest, right = n - 1;
        if (left >= n)
        {
            break;
        }
        fill(prev, 0);
        if (left > i)
        {
            auto ret = st.queryMax(i, left - 1);
            foreach (j; 0 .. m)
            {
                prev[j] = ret[j];
            }
        }
        while (left <= right)
        {
            auto mid = (left + right) >> 1;
            auto ret = st.queryMax(left, mid);
            auto need = 0;
            foreach (j; 0 .. m)
            {
                need += max(prev[j], ret[j]);
                if (need > k)
                {
                    break;
                }
            }
            if (need > k)
            {
                right = mid - 1;
            }
            else
            {
                left = mid + 1;
                foreach (j; 0 .. m)
                {
                    prev[j] = max(prev[j], ret[j]);
                }
                if (mid - i + 1 > longest)
                {
                    longest = mid - i + 1;
                    sl = i;
                    sr = mid;
                }
            }
        }
    }
    auto s = new int[m];
    fill(s, 0);
    if (longest > 0)
    {
        foreach (i; sl .. sr + 1)
        {
            foreach (j; 0 .. m)
            {
                s[j] = max(s[j], a[i][j]);
            }
        }
    }
    foreach (i; 0 .. m)
    {
        write(s[i]);
        if (i < m)
        {
            write(" ");
        }
    }
    writeln();
}

int main(string[] args)
{
    int n, m, k;
    while (readf("%d %d %d\n", &n, &m, &k) == 3)
    {
        auto a = new int[][](n, m);
        foreach (i; 0 .. n)
        {
            foreach (j; 0 .. m)
            {
                readf(" %d", &a[i][j]);
            }
            readln;
        }
        solve(n, m, k, a);
    }
    return 0;
}

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

class SegmentTree(T)
{
    class Node
    {
        int leftIndex;
        int rightIndex;
        T[] maximum;
        T[] minimum;
        Node left;
        Node right;

        this(int leftIndex, int rightIndex, int m)
        {
            this.maximum = new T[m];
            this.minimum = new T[m];
            this.leftIndex = leftIndex;
            this.rightIndex = rightIndex;
            this.left = this.right = null;
        }
    }

    protected Node root;
    immutable static T bound = T.max;

    this(T[][] arr)
    {
        this.initializeTree(this.root, arr, 0, cast(int)arr.length - 1);
    }

    protected void initializeTree(ref Node node, T[][] arr, int leftIndex, int rightIndex)
    {
        auto m = cast(int)arr[0].length;
        node = new Node(leftIndex, rightIndex, m);
        if (leftIndex == rightIndex)
        {
            foreach (i; 0 .. m)
            {
                node.maximum[i] = node.minimum[i] = arr[leftIndex][i];
            }
            return;
        }
        auto mid = (leftIndex + rightIndex) >> 1;
        initializeTree(node.left, arr, leftIndex, mid);
        initializeTree(node.right, arr, mid + 1, rightIndex);
        foreach (i; 0 .. m)
        {
            node.maximum[i] = max(node.left.maximum[i], node.right.maximum[i]);
            node.minimum[i] = min(node.left.minimum[i], node.right.minimum[i]);
        }
    }

    T count(int left, int right)
    {
        auto m = cast(int)root.maximum.length;
        auto res = 0;
        foreach (i; 0 .. m)
        {
            auto ret = _queryMax(root, left, right, i);
            res += ret;
        }
        return res;
    }

    protected T _queryMax(Node node, int left, int right, int idx)
    {
        if (left <= node.leftIndex && right >= node.rightIndex)
        {
            return node.maximum[idx];
        }
        if (left > node.rightIndex || right < node.leftIndex)
        {
            return -T.max;
        }
        auto leftMax = _queryMax(node.left, left, right, idx);
        auto rightMax = _queryMax(node.right, left, right, idx);
        return max(leftMax, rightMax);
    }
}

void solve(int n, int m, int k, int[][] a)
{
    auto st = new SegmentTree!int(a);
    auto sl = -1, sr = -1;
    auto longest = 0;
    foreach (i; 0 .. n)
    {
        auto left = i + longest, right = n - 1;
        if (left >= n)
        {
            break;
        }
        auto leftBound = i;
        auto need = 0;
        while (left <= right)
        {
            auto mid = (left + right) >> 1;
            auto inc = st.count(leftBound, mid);
            if (need + inc <= k)
            {
                left = mid + 1;
                need += inc;
                leftBound = left;
                if (mid - i + 1 > longest)
                {
                    longest = mid - i + 1;
                    sl = i;
                    sr = mid;
                }
            }
            else
            {
                right = mid - 1;
            }
        }
    }
    auto s = new int[m];
    fill(s, 0);
    if (longest > 0)
    {
        foreach (i; sl .. sr + 1)
        {
            foreach (j; 0 .. m)
            {
                s[j] = max(s[j], a[i][j]);
            }
        }
    }
    foreach (i; 0 .. m)
    {
        write(s[i]);
        if (i < m)
        {
            write(" ");
        }
    }
    writeln();
}

int main(string[] args)
{
    int n, m, k;
    while (readf("%d %d %d\n", &n, &m, &k) == 3)
    {
        auto a = new int[][](n, m);
        foreach (i; 0 .. n)
        {
            foreach (j; 0 .. m)
            {
                readf(" %d", &a[i][j]);
            }
            readln;
        }
        solve(n, m, k, a);
    }
    return 0;
}

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

class SegmentTree(T)
{
    class Node
    {
        int leftIndex;
        int rightIndex;
        T[] maximum;
        T[] minimum;
        Node left;
        Node right;

        this(int leftIndex, int rightIndex, int m)
        {
            this.maximum = new T[m];
            this.minimum = new T[m];
            this.leftIndex = leftIndex;
            this.rightIndex = rightIndex;
            this.left = this.right = null;
        }
    }

    protected Node root;
    immutable static T bound = T.max;

    this(T[][] arr)
    {
        this.initializeTree(this.root, arr, 0, cast(int)arr.length - 1);
    }

    protected void initializeTree(ref Node node, T[][] arr, int leftIndex, int rightIndex)
    {
        auto m = cast(int)arr[0].length;
        node = new Node(leftIndex, rightIndex, m);
        if (leftIndex == rightIndex)
        {
            foreach (i; 0 .. m)
            {
                node.maximum[i] = node.minimum[i] = arr[leftIndex][i];
            }
            return;
        }
        auto mid = (leftIndex + rightIndex) >> 1;
        initializeTree(node.left, arr, leftIndex, mid);
        initializeTree(node.right, arr, mid + 1, rightIndex);
        foreach (i; 0 .. m)
        {
            node.maximum[i] = max(node.left.maximum[i], node.right.maximum[i]);
            node.minimum[i] = min(node.left.minimum[i], node.right.minimum[i]);
        }
    }

    T count(int left, int right)
    {
        auto m = cast(int)root.maximum.length;
        auto res = 0;
        foreach (i; 0 .. m)
        {
            auto ret = _queryMax(root, left, right, i);
            res += ret;
        }
        return res;
    }

    protected T _queryMax(Node node, int left, int right, int idx)
    {
        if (left <= node.leftIndex && right >= node.rightIndex)
        {
            return node.maximum[idx];
        }
        if (left > node.rightIndex || right < node.leftIndex)
        {
            return -T.max;
        }
        auto leftMax = _queryMax(node.left, left, right, idx);
        auto rightMax = _queryMax(node.right, left, right, idx);
        return max(leftMax, rightMax);
    }
}

void solve(int n, int m, int k, int[][] a)
{
    auto st = new SegmentTree!int(a);
    auto sl = -1, sr = -1;
    auto longest = 0;
    foreach (i; 0 .. n)
    {
        auto left = i + longest, right = n - 1;
        if (left >= n)
        {
            break;
        }
        auto need = 0;
        while (left <= right)
        {
            auto mid = (left + right) >> 1;
            auto inc = st.count(left, mid);
            if (need + inc <= k)
            {
                left = mid + 1;
                need += inc;
                if (mid - i + 1 > longest)
                {
                    longest = mid - i + 1;
                    sl = i;
                    sr = mid;
                }
            }
            else
            {
                right = mid - 1;
            }
        }
    }
    auto s = new int[m];
    fill(s, 0);
    if (longest > 0)
    {
        foreach (i; sl .. sr + 1)
        {
            foreach (j; 0 .. m)
            {
                s[j] = max(s[j], a[i][j]);
            }
        }
    }
    foreach (i; 0 .. m)
    {
        write(s[i]);
        if (i < m)
        {
            write(" ");
        }
    }
    writeln();
}

int main(string[] args)
{
    int n, m, k;
    while (readf("%d %d %d\n", &n, &m, &k) == 3)
    {
        auto a = new int[][](n, m);
        foreach (i; 0 .. n)
        {
            foreach (j; 0 .. m)
            {
                readf(" %d", &a[i][j]);
            }
            readln;
        }
        solve(n, m, k, a);
    }
    return 0;
}

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

class SegmentTree(T)
{
    class Node
    {
        int leftIndex;
        int rightIndex;
        T[] maximum;
        T[] minimum;
        Node left;
        Node right;

        this(int leftIndex, int rightIndex, int m)
        {
            this.maximum = new T[m];
            this.minimum = new T[m];
            this.leftIndex = leftIndex;
            this.rightIndex = rightIndex;
            this.left = this.right = null;
        }
    }

    protected Node root;
    immutable static T bound = T.max;

    this(T[][] arr)
    {
        this.initializeTree(this.root, arr, 0, cast(int)arr.length - 1);
    }

    protected void initializeTree(ref Node node, T[][] arr, int leftIndex, int rightIndex)
    {
        auto m = cast(int)arr[0].length;
        node = new Node(leftIndex, rightIndex, m);
        if (leftIndex == rightIndex)
        {
            foreach (i; 0 .. m)
            {
                node.maximum[i] = node.minimum[i] = arr[leftIndex][i];
            }
            return;
        }
        auto mid = (leftIndex + rightIndex) >> 1;
        initializeTree(node.left, arr, leftIndex, mid);
        initializeTree(node.right, arr, mid + 1, rightIndex);
        foreach (i; 0 .. m)
        {
            node.maximum[i] = max(node.left.maximum[i], node.right.maximum[i]);
            node.minimum[i] = min(node.left.minimum[i], node.right.minimum[i]);
        }
    }

    T[] queryMax(int left, int right)
    {
        auto m = cast(int)root.maximum.length;
        int[] res;
        foreach (i; 0 .. m)
        {
            auto ret = _queryMax(root, left, right, i);
            res ~= ret;
        }
        return res;
    }

    protected T _queryMax(Node node, int left, int right, int idx)
    {
        if (left <= node.leftIndex && right >= node.rightIndex)
        {
            return node.maximum[idx];
        }
        if (left > node.rightIndex || right < node.leftIndex)
        {
            return -T.max;
        }
        auto leftMax = _queryMax(node.left, left, right, idx);
        auto rightMax = _queryMax(node.right, left, right, idx);
        return max(leftMax, rightMax);
    }
}

void solve(int n, int m, int k, int[][] a)
{
    auto st = new SegmentTree!int(a);
    auto sl = -1, sr = -1;
    auto longest = 0;
    foreach (i; 0 .. n)
    {
        auto left = i + longest, right = n - 1;
        if (left >= n)
        {
            break;
        }
        auto prev = new int[m];
        fill(prev, 0);
        while (left <= right)
        {
            auto mid = (left + right) >> 1;
            auto ret = st.queryMax(left, mid);
            auto need = 0;
            foreach (j; 0 .. m)
            {
                need += max(prev[j], ret[j]);
                if (need > k)
                {
                    break;
                }
            }
            if (need <= k)
            {
                left = mid + 1;
                foreach (j; 0 .. m)
                {
                    prev[j] = max(prev[j], ret[j]);
                }
                if (mid - i + 1 > longest)
                {
                    longest = mid - i + 1;
                    sl = i;
                    sr = mid;
                }
            }
            else
            {
                right = mid - 1;
            }
        }
    }
    auto s = new int[m];
    fill(s, 0);
    if (longest > 0)
    {
        foreach (i; sl .. sr + 1)
        {
            foreach (j; 0 .. m)
            {
                s[j] = max(s[j], a[i][j]);
            }
        }
    }
    foreach (i; 0 .. m)
    {
        write(s[i]);
        if (i < m)
        {
            write(" ");
        }
    }
    writeln();
}

int main(string[] args)
{
    int n, m, k;
    while (readf("%d %d %d\n", &n, &m, &k) == 3)
    {
        auto a = new int[][](n, m);
        foreach (i; 0 .. n)
        {
            foreach (j; 0 .. m)
            {
                readf(" %d", &a[i][j]);
            }
            readln;
        }
        solve(n, m, k, a);
    }
    return 0;
}


The Berland State University is hosting a ballroom dance in celebration of its 100500-th anniversary! n boys and m girls are already busy rehearsing waltz, minuet, polonaise and quadrille moves.We know that several boy&girl pairs are going to be invited to the ball. However, the partners' dancing skill in each pair must differ by at most one.For each boy, we know his dancing skills. Similarly, for each girl we know her dancing skills. Write a code that can determine the largest possible number of pairs that can be formed from n boys and m girls.

The first line contains an integer n (1 ≤ n ≤ 100) — the number of boys. The second line contains sequence a1, a2, ..., an (1 ≤ ai ≤ 100), where ai is the i-th boy's dancing skill. Similarly, the third line contains an integer m (1 ≤ m ≤ 100) — the number of girls. The fourth line contains sequence b1, b2, ..., bm (1 ≤ bj ≤ 100), where bj is the j-th girl's dancing skill.

Print a single number — the required maximum possible number of pairs.

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, std.bitmanip;

class FordFulkerson {
    int N, source, sink;
    int[][] adj;
    int[][] flow;
    bool[] used;

    this(int n, int s, int t) {
        N = n;
        source = s;
        sink = t;
        assert (s >= 0 && s < N && t >= 0 && t < N);
        adj = new int[][](N);
        flow = new int[][](N, N);
        used = new bool[](N);
    }

    void add_edge(int from, int to, int cap) {
        adj[from] ~= to;
        adj[to] ~= from;
        flow[from][to] = cap;
    }

    int dfs(int v, int min_cap) {
        if (v == sink)
            return min_cap;
        if (used[v])
            return 0;
        used[v] = true;
        foreach (to; adj[v]) {
            if (!used[to] && flow[v][to] > 0) {
                auto bottleneck = dfs(to, min(min_cap, flow[v][to]));
                if (bottleneck == 0) continue;
                flow[v][to] -= bottleneck;
                flow[to][v] += bottleneck;
                return bottleneck;
            }
        }
        return 0;
    }

    int run() {
        int ret = 0;
        while (true) {
            foreach (i; 0..N) used[i] = false;
            int f = dfs(source, int.max);
            if (f > 0)
                ret += f;
            else
                return ret;
        }
    }
}

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

    auto source = N+M;
    auto sink = N+M+1;
    auto ff = new FordFulkerson(N+M+2, source, sink);
    foreach (i; 0..N) ff.add_edge(source, i, 1);
    foreach (i; 0..M) ff.add_edge(i+N, sink, 1);
    foreach (i; 0..N)
        foreach (j; 0..M)
            if (abs(A[i]-B[j]) <= 1)
                ff.add_edge(i, j+N, 1);

    ff.run.writeln;
}


Little Petya very much likes rectangles and especially squares. Recently he has received 8 points on the plane as a gift from his mother. The points are pairwise distinct. Petya decided to split them into two sets each containing 4 points so that the points from the first set lay at the vertexes of some square and the points from the second set lay at the vertexes of a rectangle. Each point of initial 8 should belong to exactly one set. It is acceptable for a rectangle from the second set was also a square. If there are several partitions, Petya will be satisfied by any of them. Help him find such partition. Note that the rectangle and the square from the partition should have non-zero areas. The sides of the figures do not have to be parallel to the coordinate axes, though it might be the case.

You are given 8 pairs of integers, a pair per line — the coordinates of the points Petya has. The absolute value of all coordinates does not exceed 104. It is guaranteed that no two points coincide.

Print in the first output line "YES" (without the quotes), if the desired partition exists. In the second line output 4 space-separated numbers — point indexes from the input, which lie at the vertexes of the square. The points are numbered starting from 1. The numbers can be printed in any order. In the third line print the indexes of points lying at the vertexes of a rectangle in the similar format. All printed numbers should be pairwise distinct. If the required partition does not exist, the first line should contain the word "NO" (without the quotes), after which no output is needed.

NotePay attention to the third example: the figures do not necessarily have to be parallel to the coordinate axes.

import std.stdio;
import std.ascii;
import std.range;
import std.array;
import std.functional;
import std.algorithm;
import std.conv;
import std.container;
import std.math;
import std.numeric;
import std.string;
import std.c.string;
import std.random;
import std.regex;
import std.typecons;

struct Point {
    double x, y;
    Point opBinary(string op)(in Point p) const {
        if (op == "+") return Point(x + p.x, y + p.y);
        else if (op == "-") return Point(x - p.x, y - p.y);
    }
}

double dot(in Point a, in Point b) {
    return a.x * b.x + a.y * b.y;
}

double distance(in Point a, in Point b) {
    auto dx = a.x - b.x,
         dy = a.y - b.y;
    return sqrt(dx * dx + dy * dy);
}

int next(int i) {
    return (i + 1) % 4;
}

const EPS = 1e-9;

bool EQ(double a, double b) {
    return abs(a - b) < EPS;
}

bool isCross(in Point a, in Point b, in Point c) {
    Point x = a - b, y = c - b;
    return EQ(x.dot(y), 0);
}
bool isCross(in Point[] P) {
    assert(P.length == 4);
    foreach (i; 0 .. 4) {
        auto a = i, b = i.next, c = i.next.next;
        if (!isCross(P[a], P[b], P[c])) return false;
    }
    return true;
}

bool isSquare(in Point[] P) {
    assert(P.length == 4);
    if (!isCross(P)) return false;
    auto d = distance(P[0], P[1]);
    foreach (int i; 0 .. 4) {
        auto a = i, b = next(i);
        if (!EQ(distance(P[a], P[b]), d)) return false;
    }
    return true;
}

bool isRectangle(in Point[] P) {
    assert(P.length == 4);
    if (!isCross(P)) return false;
    auto d1 = distance(P[0], P[1]);
    auto d2 = distance(P[1], P[2]);
    return (EQ(d1, distance(P[2], P[3])) && EQ(d2, distance(P[3], P[0])));
}

void main() {
    auto P = new Point[8];
    foreach (i; 0 .. 8) {
        double x, y; scanf("%lf %lf\n", &x, &y);
        P[i] = Point(x, y);
    }

    /*
    writeln("isCross: ", isCross(P[0 .. 4]));
    writeln("isSquare: ", isSquare(P[0 .. 4]));
    writeln("isRectangle: ", isRectangle(P[0 .. 4]));
    */

    import core.bitop;

    bool dfs(int used, int[] p) {
        if (used == (1 << 8) - 1) {
            Point[] P1, P2;
            foreach (i; 0 .. 8) {
                if (i < 4) {
                    P1 ~= P[ p[i] ];
                } else {
                    P2 ~= P[ p[i] ];
                }
            }
            //writeln(P1, P2);
            if (P1.isSquare && P2.isRectangle) {
                writeln("YES");
                writefln("%(%s %)", p[0 .. 4].map!"a + 1");
                writefln("%(%s %)", p[4 .. 8].map!"a + 1");
                return true;
            } else if (P1.isRectangle && P2.isSquare) {
                writeln("YES");
                writefln("%(%s %)", p[4 .. 8].map!"a + 1");
                writefln("%(%s %)", p[0 .. 4].map!"a + 1");
                return true;
            }
            return false;
        }
        foreach (int i; 0 .. 8) {
            if (used & (1 << i)) continue;
            if (dfs(used | 1 << i, p ~ i)) return true;
        }
        return false;
    }

    if (!dfs(0, [])) {
        writeln("NO");
    }
}

import std.stdio;
import std.ascii;
import std.range;
import std.array;
import std.functional;
import std.algorithm;
import std.conv;
import std.container;
import std.math;
import std.numeric;
import std.string;
import std.c.string;
import std.random;
import std.regex;
import std.typecons;

struct Point {
    double x, y;
    Point opBinary(string op)(in Point p) const {
        if (op == "+") return Point(x + p.x, y + p.y);
        else if (op == "-") return Point(x - p.x, y - p.y);
    }
}

double dot(in Point a, in Point b) {
    return a.x * b.x + a.y * b.y;
}

double distance(in Point a, in Point b) {
    auto dx = a.x - b.x,
         dy = a.y - b.y;
    return sqrt(dx * dx + dy * dy);
}

int next(int i) {
    return (i + 1) % 4;
}

const EPS = 1e-9;

bool EQ(double a, double b) {
    return abs(a - b) < EPS;
}

bool isCross(in Point a, in Point b, in Point c) {
    Point x = a - b, y = c - b;
    return EQ(x.dot(y), 0);
}
bool isCross(in Point[] P) {
    assert(P.length == 4);
    foreach (i; 0 .. 4) {
        auto a = i, b = i.next, c = i.next.next;
        if (!isCross(P[a], P[b], P[c])) return false;
    }
    return true;
}

bool isSquare(in Point[] P) {
    assert(P.length == 4);
    if (!isCross(P)) return false;
    auto d = distance(P[0], P[1]);
    foreach (int i; 0 .. 4) {
        auto a = i, b = next(i);
        if (!EQ(distance(P[a], P[b]), d)) return false;
    }
    return true;
}

bool isRectangle(in Point[] P) {
    assert(P.length == 4);
    if (!isCross(P)) return false;
    auto d1 = distance(P[0], P[1]);
    auto d2 = distance(P[1], P[2]);
    return (EQ(d1, distance(P[2], P[3])) && EQ(d2, distance(P[3], P[0])));
}

void main() {
    auto P = new Point[8];
    foreach (i; 0 .. 8) {
        double x, y; scanf("%lf %lf\n", &x, &y);
        P[i] = Point(x, y);
    }

    /*
    writeln("isCross: ", isCross(P[0 .. 4]));
    writeln("isSquare: ", isSquare(P[0 .. 4]));
    writeln("isRectangle: ", isRectangle(P[0 .. 4]));
    */

    import core.bitop;

    bool dfs(int used, int[] p) {
        if (used == (1 << 8) - 1) {
            Point[] P1, P2;
            foreach (i; 0 .. 8) {
                if (i < 4) {
                    P1 ~= P[ p[i] ];
                } else {
                    P2 ~= P[ p[i] ];
                }
            }
            //writeln(P1, P2);
            if (P1.isSquare && P2.isRectangle) {
                writeln("YES");
                writefln("%(%s %)", p[0 .. 4].map!"a + 1");
                writefln("%(%s %)", p[4 .. 8].map!"a + 1");
                return true;
            } else if (P1.isRectangle && P1.isSquare) {
                writeln("YES");
                writefln("%(%s %)", p[4 .. 8].map!"a + 1");
                writefln("%(%s %)", p[0 .. 4].map!"a + 1");
                return true;
            }
            return false;
        }
        foreach (int i; 0 .. 8) {
            if (used & (1 << i)) continue;
            if (dfs(used | 1 << i, p ~ i)) return true;
        }
        return false;
    }

    if (!dfs(0, [])) {
        writeln("NO");
    }
}


ATMs of a well-known bank of a small country are arranged so that they can not give any amount of money requested by the user. Due to the limited size of the bill dispenser (the device that is directly giving money from an ATM) and some peculiarities of the ATM structure, you can get at most k bills from it, and the bills may be of at most two distinct denominations.For example, if a country uses bills with denominations 10, 50, 100, 500, 1000 and 5000 burles, then at k = 20 such ATM can give sums 100 000 burles and 96 000 burles, but it cannot give sums 99 000 and 101 000 burles.Let's suppose that the country uses bills of n distinct denominations, and the ATM that you are using has an unlimited number of bills of each type. You know that during the day you will need to withdraw a certain amount of cash q times. You know that when the ATM has multiple ways to give money, it chooses the one which requires the minimum number of bills, or displays an error message if it cannot be done. Determine the result of each of the q of requests for cash withdrawal.

The first line contains two integers n, k (1 ≤ n ≤ 5000, 1 ≤ k ≤ 20). The next line contains n space-separated integers ai (1 ≤ ai ≤ 107) — the denominations of the bills that are used in the country. Numbers ai follow in the strictly increasing order. The next line contains integer q (1 ≤ q ≤ 20) — the number of requests for cash withdrawal that you will make. The next q lines contain numbers xi (1 ≤ xi ≤ 2·108) — the sums of money in burles that you are going to withdraw from the ATM.

For each request for cash withdrawal print on a single line the minimum number of bills it can be done, or print  - 1, if it is impossible to get the corresponding sum.

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

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

		alias Pair = Tuple !(int, q{x}, int, q{y});
		Pair [] v;
		foreach (i; 0..n)
		{
			foreach (u; 0..k + 1)
			{
				v ~= Pair (a[i] * u, u);
			}
		}
		sort (v);

		int q;
		readf (" %s", &q);
		foreach (r; 0..q)
		{
			int s;
			readf (" %s", &s);
			auto u = v;
			int res = k + 1;
			while (!u.empty)
			{
				while (!u.empty && u.front.x + u.back.x > s)
				{
					u.popBack ();
				}
				while (!u.empty && u.front.x + u.back.x == s)
				{
					res = min (res, u.front.y + u.back.y);
					u.popBack ();
				}
				if (!u.empty)
				{
					u.popFront ();
				}
			}
			if (res > k)
			{
				res = -1;
			}
			writeln (res);
		}
	}
}

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, k;
    readf("%s %s", &n, &k);
    readln;

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

    int q;
    readf("%s", &q);
    readln;

    int[int] cnt;
    cnt[0] = 0;
    foreach (e; a) {
        int cursum = 0;
        foreach (i; 1 .. k+1) {
            cursum += e;
            cnt[cursum] = min(i, cnt.get(cursum, k));
        }
    }

    debug { cnt.writeln; }

    while (q--) {
        int x;
        readf("%s", &x);
        readln;

        int ans = k+1;
        foreach (val; cnt.keys) {
            if (val > x) { continue; }

            int rst = x - val;
            int tot = cnt.get(val, k+1) + cnt.get(rst, k+1);

            ans = min(ans, tot);
        }

        if (ans == k+1) { ans = -1; }

        ans.writeln;
    }
}

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, k;
    readf("%s %s", &n, &k);
    readln;

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

    int q;
    readf("%s", &q);
    readln;

    int[int] cnt;
    foreach (e; a) {
        int cursum = 0;
        foreach (i; 1 .. k+1) {
            cursum += e;
            cnt[cursum] = min(i, cnt.get(cursum, k));
        }
    }

    debug { cnt.writeln; }

    while (q--) {
        int x;
        readf("%s", &x);
        readln;

        int ans = k+1;
        foreach (val; cnt.keys) {
            if (val > x) { continue; }

            int rst = x - val;
            int tot = cnt.get(val, k+1) + cnt.get(rst, k+1);

            ans = min(ans, tot);
        }

        if (ans == k+1) { ans = -1; }

        ans.writeln;
    }
}


There are quite a lot of ways to have fun with inflatable balloons. For example, you can fill them with water and see what happens.Grigory and Andrew have the same opinion. So, once upon a time, they went to the shop and bought $$$n$$$ packets with inflatable balloons, where $$$i$$$-th of them has exactly $$$a_i$$$ balloons inside.They want to divide the balloons among themselves. In addition, there are several conditions to hold:  Do not rip the packets (both Grigory and Andrew should get unbroken packets);  Distribute all packets (every packet should be given to someone);  Give both Grigory and Andrew at least one packet;  To provide more fun, the total number of balloons in Grigory's packets should not be equal to the total number of balloons in Andrew's packets. Help them to divide the balloons or determine that it's impossible under these conditions.

The first line of input contains a single integer $$$n$$$ ($$$1 \le n \le 10$$$) — the number of packets with balloons. The second line contains $$$n$$$ integers: $$$a_1$$$, $$$a_2$$$, $$$\ldots$$$, $$$a_n$$$ ($$$1 \le a_i \le 1000$$$) — the number of balloons inside the corresponding packet.

If it's impossible to divide the balloons satisfying the conditions above, print $$$-1$$$. Otherwise, print an integer $$$k$$$ — the number of packets to give to Grigory followed by $$$k$$$ distinct integers from $$$1$$$ to $$$n$$$ — the indices of those. The order of packets doesn't matter. If there are multiple ways to divide balloons, output any of them.

NoteIn the first test Grigory gets $$$3$$$ balloons in total while Andrey gets $$$1$$$.In the second test there's only one way to divide the packets which leads to equal numbers of balloons.In the third test one of the boys won't get a packet at all.

import std.algorithm;
import std.array;
import std.bitmanip;
import std.container;
import std.conv;
import std.functional;
import std.math;
import std.range;
import std.stdio;
import std.string;
import std.typecons;

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

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

    if (n == 1 || (n == 2 && arr[0] == arr[1])) {
        writeln(-1);
        return;
    }

    auto a = arr.minIndex;

    writeln(1);
    writeln(a+1);
}

import std.algorithm;
import std.array;
import std.bitmanip;
import std.container;
import std.conv;
import std.functional;
import std.math;
import std.range;
import std.stdio;
import std.string;
import std.typecons;

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

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

    if (n == 1 || (n == 2 && arr[0] == arr[1])) {
        writeln(-1);
        return;
    }

    auto a = arr.minIndex;

    writeln(a+1);
}


The Bad Luck Island is inhabited by three kinds of species: r rocks, s scissors and p papers. At some moments of time two random individuals meet (all pairs of individuals can meet equiprobably), and if they belong to different species, then one individual kills the other one: a rock kills scissors, scissors kill paper, and paper kills a rock. Your task is to determine for each species what is the probability that this species will be the only one to inhabit this island after a long enough period of time.

The single line contains three integers r, s and p (1 ≤ r, s, p ≤ 100) — the original number of individuals in the species of rock, scissors and paper, respectively.

Print three space-separated real numbers: the probabilities, at which the rocks, the scissors and the paper will be the only surviving species, respectively. The answer will be considered correct if the relative or absolute error of each number doesn't exceed 10 - 9.

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

double saiki(int r, int s, int p, int t, double[][][] dp)
{
    if (dp[r][s][p] != -1)
    {
        return dp[r][s][p];
    }
    if (t == 0)
    {
        if (r == 0) dp[r][s][p] = 0.0;
        else if (s == 0 && p == 0) dp[r][s][p] = 1.0;
    }
    else if (t == 1)
    {
        if (s == 0) dp[r][s][p] = 0.0;
        else if (r == 0 && p == 0) dp[r][s][p] = 1.0;
    }
    else
    {
        if (p == 0) dp[r][s][p] = 0.0;
        else if (r == 0 && s == 0) dp[r][s][p] = 1.0;
    }
    if (dp[r][s][p] == 0.0 || dp[r][s][p] == 1.0)
    {
        return dp[r][s][p];
    }
    auto res = 0.0;
    auto choices = (r + s + p) * (r + s + p - 1) / 2;
    if (r > 0 && s > 0)
    {
        auto ret = saiki(r, s - 1, p, t, dp);
        res += ret * cast(double)(r * s) / choices;
    }
    if (s > 0 && p > 0)
    {
        auto ret = saiki(r, s, p - 1, t, dp);
        res += ret * cast(double)(s * p) / choices;
    }
    if (p > 0 && r > 0)
    {
        auto ret = saiki(r - 1, s, p, t, dp);
        res += ret * cast(double)(p * r) / choices;
    }
    res /= (1.0 - cast(double)(r * (r - 1) + s * (s - 1) + p * (p - 1)) / 2 / choices);
    dp[r][s][p] = res;
    return res;
}

void solve(int r, int s, int p)
{
    auto dp = new double[][][](r + 1, s + 1, p + 1);
    foreach (t; 0 .. 3)
    {
        foreach (i; 0 .. r + 1)
        {
            foreach (j; 0 .. s + 1)
            {
                fill(dp[i][j], -1);
            }
        }
        auto ret = saiki(r, s, p, t, dp);
        writef("%.10f", ret);
        if (t < 2)
        {
            write(" ");
        }
    }
    writeln();
}

int main(string[] args)
{
    int r, s, p;
    while (readf("%d %d %d\n", &r, &s, &p) == 3)
    {
        solve(r, s, p);
    }
    return 0;
}


This is the hard version of this problem. The only difference is the constraint on $$$k$$$ — the number of gifts in the offer. In this version: $$$2 \le k \le n$$$.Vasya came to the store to buy goods for his friends for the New Year. It turned out that he was very lucky — today the offer "$$$k$$$ of goods for the price of one" is held in store.Using this offer, Vasya can buy exactly $$$k$$$ of any goods, paying only for the most expensive of them. Vasya decided to take this opportunity and buy as many goods as possible for his friends with the money he has.More formally, for each good, its price is determined by $$$a_i$$$ — the number of coins it costs. Initially, Vasya has $$$p$$$ coins. He wants to buy the maximum number of goods. Vasya can perform one of the following operations as many times as necessary:  Vasya can buy one good with the index $$$i$$$ if he currently has enough coins (i.e $$$p \ge a_i$$$). After buying this good, the number of Vasya's coins will decrease by $$$a_i$$$, (i.e it becomes $$$p := p - a_i$$$).  Vasya can buy a good with the index $$$i$$$, and also choose exactly $$$k-1$$$ goods, the price of which does not exceed $$$a_i$$$, if he currently has enough coins (i.e $$$p \ge a_i$$$). Thus, he buys all these $$$k$$$ goods, and his number of coins decreases by $$$a_i$$$ (i.e it becomes $$$p := p - a_i$$$). Please note that each good can be bought no more than once.For example, if the store now has $$$n=5$$$ goods worth $$$a_1=2, a_2=4, a_3=3, a_4=5, a_5=7$$$, respectively, $$$k=2$$$, and Vasya has $$$6$$$ coins, then he can buy $$$3$$$ goods. A good with the index $$$1$$$ will be bought by Vasya without using the offer and he will pay $$$2$$$ coins. Goods with the indices $$$2$$$ and $$$3$$$ Vasya will buy using the offer and he will pay $$$4$$$ coins. It can be proved that Vasya can not buy more goods with six coins.Help Vasya to find out the maximum number of goods he can buy.

The first line contains one integer $$$t$$$ ($$$1 \le t \le 10^4$$$) — the number of test cases in the test. The next lines contain a description of $$$t$$$ test cases.  The first line of each test case contains three integers $$$n, p, k$$$ ($$$2 \le n \le 2 \cdot 10^5$$$, $$$1 \le p \le 2\cdot10^9$$$, $$$2 \le k \le n$$$) — the number of goods in the store, the number of coins Vasya has and the number of goods that can be bought by the price of the most expensive of them. The second line of each test case contains $$$n$$$ integers $$$a_i$$$ ($$$1 \le a_i \le 10^4$$$) — the prices of goods. It is guaranteed that the sum of $$$n$$$ for all test cases does not exceed $$$2 \cdot 10^5$$$.

For each test case in a separate line print one integer $$$m$$$ — the maximum number of goods that Vasya can buy.

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

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

    while (t--) {
        int n, p, k;
        readf("%s %s %s", &n, &p, &k);
        readln;

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

        arr.sort();

        auto cost = new int[] (n+1);
        cost[0] = 0;
        foreach (i, e; arr.enumerate(1)) {
            if (i < k) { cost[i.to!int] = cost[i.to!int - 1] + e; }
            else { cost[i.to!int] = cost[i.to!int - k] + e; }
        }

        int ans = 0;
        foreach (i, e; cost) {
            if (e <= p) { ans = i.to!int; }
        }

        ans.writeln;
    }
}

//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;
  }
}

void main() {
  auto r = new InputReader;
  immutable t = r.next!uint;
  auto res = uninitializedArray!(int[]) (t);
  foreach (tid; 0 .. t) {
    immutable n = r.next!uint;
    auto p = r.next!uint;
    immutable k = r.next!uint;
    auto a = r.nextA!uint (n);
    sort (a);
    /*
    auto s = new long[n+1];
    s[0] = 0;
    foreach (i; 1 .. n + 1) s[i] = s[i-1] + a[i-1];
    */
    auto b = new long[n+1];
    b[0] = 0;
    foreach (i; 1 .. n + 1) {
      immutable val = a[i-1];
      b[i] = b[i-1] + val;
      int j = (i - (k - 1));
      if (j >= 1) {
        b[i] = min (b[i], b[j-1] + val);
      }
    }
    int ans;
    foreach_reverse (i; 1 .. n + 1) {
      if (b[i] <= p) {
        ans = i;
        break;
      }
    }
    res[tid] = ans;
  }
  writefln ("%(%s\n%)", res);
}

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(){
	foreach(_; 0 .. rint){
		int n = rint;
		long p = rlong;
		int k = rint;
		long[] as = rlong(n);
		as.sort();
		log("---");
		log("n:", n, "p:", p, "k:", k, "as:", as);

		int ans = 0;
		int tmp1 = 0;
		foreach(r; 0 .. k){
			int tmp2 = tmp1;
			for(int m = 0; r + k * m <= n; m ++){
				log("r:", r, "m:", m, "x:", r + k * m, "tmp1:", tmp1, "tmp2:", tmp2, "f:", tmp2 <= p);
				if(tmp2 <= p) ans.chmax(r + k * m);
				else break;
				if(r + k * m + k - 1 < n) tmp2 += as[r + k * m + k - 1];
				else break;
			}
			tmp1 += as[r];
		}
		ans.writeln;
	}
}

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(){
	foreach(_; 0 .. rint){
		int n = rint;
		long p = rlong;
		int k = rint;
		long[] as = rlong(n);
		as.sort();
		log("---");
		log("n:", n, "p:", p, "k:", k, "as:", as);

		bool f(int x){ // "can buy x or more goods" (not necessarily can by exact x)
			int m = x / k, r = x % k;
			long q;
			foreach(a; as[0 .. r]){
				if(q + a < as[k - 1]) q += a;
				else{
					q = 0;
					r = 0;
					m += 1;
					break;
				}
			}
			foreach(i; 1 .. m + 1) q += as[r + k * i - 1];
			log("x:", x, "m:", m, "r:", r, "q:", q, "f:", q <= p);
			return q <= p;
		}

		int ans = uplimit(0, n, &f);
		ans.writeln;

	}
}

	// 二分探索テンプレート
	T uplimit(T)(T a, T c, bool delegate(T) f){
		if(f(c)) return c; if(! f(a)) return a - 1;
		while(a + 1 < c){ T b = (a + c) / 2; if(f(b)) a = b; else c = b; }
		return a;
	}
	T downlimit(T)(T a, T c, bool delegate(T) f){
		if(f(a)) return a; if(! f(c)) return c + 1;
		while(a + 1 < c){ T b = (a + c) / 2; if(f(b)) c = b; else a = b; }
		return c;
	}

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(){
	foreach(_; 0 .. rint){
		int n = rint;
		long p = rlong;
		int k = rint;
		long[] as = rlong(n);
		as.sort();

		bool f(int x){
			int m = x / k, r = x % k;
			long q;
			log("x:", x, "m:", m, "r:", r);
			foreach(a; as[0 .. r]) q += a;
			foreach(i; 1 .. m + 1) q += as[r + k * m - 1];
			return q <= p;
		}

		int ans = uplimit(0, n, &f);
		ans.writeln;

	}
}

	// 二分探索テンプレート
	T uplimit(T)(T a, T c, bool delegate(T) f){
		if(f(c)) return c; if(! f(a)) return a - 1;
		while(a + 1 < c){ T b = (a + c) / 2; if(f(b)) a = b; else c = b; }
		return a;
	}
	T downlimit(T)(T a, T c, bool delegate(T) f){
		if(f(a)) return a; if(! f(c)) return c + 1;
		while(a + 1 < c){ T b = (a + c) / 2; if(f(b)) c = b; else a = b; }
		return c;
	}

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(){
	foreach(_; 0 .. rint){
		int n = rint;
		long p = rlong;
		int k = rint;
		long[] as = rlong(n);
		as.sort();
		log("---");
		log("n:", n, "p:", p, "k:", k, "as:", as);

		bool f(int x){
			int m = x / k, r = x % k;
			long q;
			foreach(a; as[0 .. r]) q += a;
			foreach(i; 1 .. m + 1) q += as[r + k * i - 1];
			log("x:", x, "m:", m, "r:", r, "q:", q, "f:", q <= p);
			return q <= p;
		}

		int ans = uplimit(0, n, &f);
		ans.writeln;

	}
}

	// 二分探索テンプレート
	T uplimit(T)(T a, T c, bool delegate(T) f){
		if(f(c)) return c; if(! f(a)) return a - 1;
		while(a + 1 < c){ T b = (a + c) / 2; if(f(b)) a = b; else c = b; }
		return a;
	}
	T downlimit(T)(T a, T c, bool delegate(T) f){
		if(f(a)) return a; if(! f(c)) return c + 1;
		while(a + 1 < c){ T b = (a + c) / 2; if(f(b)) c = b; else a = b; }
		return c;
	}


Slastyona and her loyal dog Pushok are playing a meaningless game that is indeed very interesting.The game consists of multiple rounds. Its rules are very simple: in each round, a natural number k is chosen. Then, the one who says (or barks) it faster than the other wins the round. After that, the winner's score is multiplied by k2, and the loser's score is multiplied by k. In the beginning of the game, both Slastyona and Pushok have scores equal to one.Unfortunately, Slastyona had lost her notepad where the history of all n games was recorded. She managed to recall the final results for each games, though, but all of her memories of them are vague. Help Slastyona verify their correctness, or, to put it another way, for each given pair of scores determine whether it was possible for a game to finish with such result or not.

In the first string, the number of games n (1 ≤ n ≤ 350000) is given. Each game is represented by a pair of scores a, b (1 ≤ a, b ≤ 109) – the results of Slastyona and Pushok, correspondingly.

For each pair of scores, answer "Yes" if it's possible for a game to finish with given score, and "No" otherwise. You can output each letter in arbitrary case (upper or lower).

NoteFirst game might have been consisted of one round, in which the number 2 would have been chosen and Pushok would have won.The second game needs exactly two rounds to finish with such result: in the first one, Slastyona would have said the number 5, and in the second one, Pushok would have barked the number 3.

// tested by Hightail - https://github.com/dj3500/hightail
import std.stdio, std.string, std.conv, std.algorithm;
import std.range, std.array, std.math, std.typecons, std.container, core.bitop;
import std.datetime, std.bigint, std.numeric;

int n;

void main() {
    scan(n);

    int a, b;

    while (n--) {
        scan(a, b);
        writeln(judge(a, b) ? "Yes" : "No");
    }
}

bool judge(int a, int b) {
    long btm = 0, top = 10^^6 + 1;
    long ab = 1L*a*b;

    while (top - btm > 1) {
        long mid = btm + (top - btm) / 2;

        if (mid*mid*mid <= ab) {
            btm = mid;
        }
        else {
            top = mid;
        }
    }

    if (btm*btm*btm != ab) {
        return false;
    }

    if (a % btm == 0 && b % btm == 0) {
        return true;
    }
    else {
        return false;
    }
}

void scan(T...)(ref T args) {
    string[] line = readln.split;
    foreach (ref arg; args) {
        arg = line.front.to!(typeof(arg));
        line.popFront();
    }
    assert(line.empty);
}

void fillAll(R, T)(ref R arr, T value) {
    static if (is(typeof(arr[] = value))) {
        arr[] = value;
    }
    else {
        foreach (ref e; arr) {
            fillAll(e, value);
        }
    }
}

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() {
    long[long] cubic;
    for (long i = 1; i * i * i <= 10L ^^ 18; ++i) cubic[i * i * i] = i;

    auto N = readln.chomp.to!int;
    while (N--) {
        auto s = readln.split.map!(to!long);
        auto a = s[0];
        auto b = s[1];
        if (a * b in cubic && a % cubic[a * b] == 0 && b % cubic[a * b] == 0) {
            writeln("Yes");
        } else {
            writeln("No");
        }
    }
}

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)); }

// floor(a^(1/k))
ulong floorKthRoot(ulong a, ulong k) {
  import core.bitop : bsr;
  import std.algorithm : min;
  if (a == 0) {
    return 0;
  } else if (k <= 1) {
    return a;
  } else if (k == 2) {
    ulong b = a, x = 0, y = 0;
    for (int e = bsr(a) & ~1; e >= 0; e -= 2) {
      x <<= 1;
      y <<= 1;
      if (b >= (y | 1) << e) {
        b -= (y | 1) << e;
        x |= 1;
        y += 2;
      }
    }
    return x;
  } else if (k <= 40) {
    // min x s.t. x^k >= 2^64
    enum ulong[] HIS =
        [0, 0, 4294967296UL, 2642246, 65536, 7132, 1626, 566, 256, 139, 85, 57,
         41, 31, 24, 20, 16, 14, 12, 11, 10, 9, 8, 7, 7, 6, 6, 6, 5, 5, 5, 5,
         4, 4, 4, 4, 4, 4, 4, 4, 4];
    ulong lo = 1UL << (bsr(a) / k);
    ulong hi = min(1UL << (bsr(a) / k + 1), HIS[cast(size_t)(k)]);
    for (; lo + 1 < hi; ) {
      const ulong mid = (lo + hi) / 2;
      ulong b = mid * mid;
      foreach (i; 2 .. k) b *= mid;
      ((b <= a) ? lo : hi) = mid;
    }
    return lo;
  } else if (k <= 63) {
    return ((1UL << k) <= a) ? 2 : 1;
  } else {
    return 1;
  }
}

void main() {
  try {
    for (; ; ) {
      const numCases = readInt();
      foreach (caseId; 0 .. numCases) {
        const A = readLong();
        const B = readLong();

        const long x = floorKthRoot(A * B, 3);
        const ans = (A * B == x^^3 && A % x == 0 && B % x == 0);
        writeln(ans ? "Yes" : "No");
      }
    }
  } catch (EOFException e) {
  }
}


Bash wants to become a Pokemon master one day. Although he liked a lot of Pokemon, he has always been fascinated by Bulbasaur the most. Soon, things started getting serious and his fascination turned into an obsession. Since he is too young to go out and catch Bulbasaur, he came up with his own way of catching a Bulbasaur.Each day, he takes the front page of the newspaper. He cuts out the letters one at a time, from anywhere on the front page of the newspaper to form the word "Bulbasaur" (without quotes) and sticks it on his wall. Bash is very particular about case — the first letter of "Bulbasaur" must be upper case and the rest must be lower case. By doing this he thinks he has caught one Bulbasaur. He then repeats this step on the left over part of the newspaper. He keeps doing this until it is not possible to form the word "Bulbasaur" from the newspaper.Given the text on the front page of the newspaper, can you tell how many Bulbasaurs he will catch today?Note: uppercase and lowercase letters are considered different.

Input contains a single line containing a string s (1  ≤  |s|  ≤  105) — the text on the front page of the newspaper without spaces and punctuation marks. |s| is the length of the string s. The string s contains lowercase and uppercase English letters, i.e. .

Output a single integer, the answer to the problem.

NoteIn the first case, you could pick: Bulbbasaur.In the second case, there is no way to pick even a single Bulbasaur.In the third case, you can rearrange the string to BulbasaurBulbasauraddrgndgddgargndbb to get two words "Bulbasaur".

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

immutable string str = "Bulbasaur";
void main(string[] args)
{
    string s;
    while((s = readln.strip) != "")
    {
        int [256] num;
        foreach(char c; s)
        {
            num[c]++;
        }
        int res = int.max;
        foreach(char c;str)
        {
            int d =cast(int)(str.count(c));
            res = min(res,num[c]/d);
        }
        writeln(res);
    }
}

module main;
import std.bigint,std.container,std.array,std.algorithm,std.conv,
	std.functional,std.math,std.numeric,std.string,std.range,std.complex,
	std.typecons,std.regex,std.random,std.uni,std.traits,std.variant,
	std.stdio,std.bitmanip;
import core.stdc.stdio : freopen;
alias BitArray bitset;
alias RedBlackTree Rbt;
alias redBlackTree rbt;
alias BigInt big;
alias pair!(int,int) pii;
alias pair!(long,long) pll;
alias BoyerMooreFinder strfind;
alias make_pair mp;
alias binary_search bins;
alias orient_square orsq;
immutable int mod=1000000007;
pure nothrow
{
	T lcm (T)(auto ref T a,auto ref T b)
	{
		return a/gcd(a,b)*b;
	}
	X binpow(X,Y)(X base,Y exp)
		if(is(typeof(exp&1)))
	{
		if(exp<0)return X(0);
		X res=X(1);
		while(exp>0)
		{
			if(exp&1)res*=base;
			base*=base;
			exp>>=1;
		}
		return res;
	}
	auto binpow(X,Y,Z)(X base,Y exp,in Z mm)
		if(is(typeof(exp&1)))
	{
		if(mm==0) return binpow(base,exp);
		if(exp<0)return X(0);
		auto res=X(1)%mm;
		while(exp>0)
		{
			if(exp&1)res=(res*base)%mm;
			base*=base;
			base%=mm;
			exp>>=1;
		}
		return res;
	}
	@property X sqr(X)(in X a_) {return a_*a_;}
	@property X cub(X)(in X a_) {return a_*a_*a_;}
	size_t lowb(T,X)(in T a,auto ref X g)
		if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		size_t l=0,r=a.length;
		while(r-l>1)
		{
			auto m=(l+r)>>1;
			if(!(a[m]<g))r=m;
			else l=m;
		}
		return (!(a[l]<g))?l:r;
	}
	size_t upb(T,X)(in T a,auto ref X g)
		if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		size_t l=0,r=a.length;
		while(r-l>1)
		{
			auto m=(l+r)>>1;
			if(g<a[m])r=m;
			else l=m;
		}
		return (g<a[l])?l:r;
	}
	size_t binf(T,X)(in T a,auto ref X g)
		if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		size_t l=0,r=a.length;
		while(r-l>1)
		{
			auto m=(l+r)>>1;
			if(!(a[m]<g))r=m;
			else l=m;
		}
		return (g==a[l])?l:a.length;
	}
	bool binary_search(T,X)(in T a,auto ref X g)
		if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		return binf(a,g)!=a.length;
	}
	V foldr(R,V,T)(R range,T arg,V nach)
		if(isFunction!T && isInputRange!R && is(typeof(arg(nach,R.front))==V))
	{
		for(;!range.empty;range.popFront()) nach=arg(nach,range.front);
		return nach;
	}
	size_t countr(R,T)(R range,T fun)
		if(isFunction!T && isInputRange!R && is(typeof(fun(R.front))==bool))
	{
		size_t nach;
		for(;!range.empty;range.popFront()) nach+=fun(range.front);
		return nach;
	}
	T orient_square(T)(pair!(T,T)[] figure...)
	{
		auto n=figure.front,t=figure.front;
		figure.popFront();
		T ans=0;
		for(;!figure.empty;figure.popFront())
		{
			ans+=(figure.front.fi-t.fi)*(figure.front.se+t.se);
			t=figure.front;
		}
		return ans+(n.fi-t.fi)*(n.se+t.se);
	}
	real square(T)(pair!(T,T)[] figure...)
		if(is(typeof(figure.front*figure.front)==T))
	{
		return abs(orient_square(figure))/2.000000000000000;
	}
}
void putarr(X)(in X a,in char ch=' '){foreach(const ref i;a)write(i,ch);}
void putarr(X)(in X a,in size_t n,in size_t m)
{
	foreach(i;0..n)
	{
		foreach(j;0..m)write(a[i][j],' ');
		writeln;
	}
}
bool getarr(X)(X a,in size_t n)
{bool b=1; foreach(ref i;a[0..n])b=input(&i);return b;}
bool input(T...)(T ptrs) if (ptrs.length > 0)
{return readf(replicate(" %s", ptrs.length), ptrs)==ptrs.length;}
bool read(T...)(T ptrs) if (ptrs.length > 0)
{return readf(replicate(" %s", ptrs.length)~'\n', ptrs)==ptrs.length;}
struct pair(X,Y)
{
	X first;
	Y second;
	alias first fi;
	alias second se;
	this(X a_,Y b_){
		fi=a_;
		se=b_;
	}
	this(this){fi=fi;se=se;}
	this(A,B)(auto ref pair!(A,B) p) if(is(A:X) && is(B:Y))
	{
		fi=p.fi;
		se=p.se;
	}
	int opCmp(A,B)(in pair!(A,B) s_) const
		if(is(typeof(s_.fi<fi)==bool) && is(typeof(s_.se<se)==bool))
	{
		int cmp=0-(fi<s_.fi)+(fi>s_.fi);
		if(cmp!=0)return cmp;
		else return (0-(se<s_.se)+(se>s_.se));
	}
};
pair!(X,Y) make_pair(X,Y)(in X x_,in Y y_)
{
	pair!(X,Y) pp;
	pp.fi=x_;
	pp.se=y_;
	return pp;
}
nothrow void inf(in char* name) {freopen(name,"r",core.stdc.stdio.stdin);}
nothrow void ouf(in char* name) {freopen(name,"w",core.stdc.stdio.stdout);}
@property auto arread(T)(){return readln.split.map!(to!(T)).array;}
//split strip isAlpha isNumber isWhite isLower isUpper toLower toUpper mixin
//cumulativeFold schwartzSort multiSort partialSort heapify join filter countUntil
//---------------------------------------------------------------program beginning-----------------------------------------------------------------

void main()
{
	string t;
	loop:while((t=readln.strip)!="")
	{
		int[char] q;
		foreach(i;"Bulbasaur")q[i]=0;

		foreach(i;t)q[i]++;
		writeln(min(q['B'],q['b'],q['a']/2,q['u']/2,q['l'],q['s'],q['r']));
	}
}

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

immutable string str = "Bulbasaur";

void main ()
{
	string s;
	while ((s = readln.strip) != "")
	{
		int [256] num;
		foreach (char c; s)
		{
			num[c] += 1;
		}
		int res = int.max;
		foreach (char c; str)
		{
			int d = cast (int) (str.count (c));
			res = min (res, num[c] / d);
		}
		writeln (res);
	}
}