An infinitely long Line Chillland Collider (LCC) was built in Chillland. There are $$$n$$$ pipes with coordinates $$$x_i$$$ that are connected to LCC. When the experiment starts at time 0, $$$i$$$-th proton flies from the $$$i$$$-th pipe with speed $$$v_i$$$. It flies to the right with probability $$$p_i$$$ and flies to the left with probability $$$(1 - p_i)$$$. The duration of the experiment is determined as the time of the first collision of any two protons. In case there is no collision, the duration of the experiment is considered to be zero.Find the expected value of the duration of the experiment.Illustration for the first example

The first line of input contains one integer $$$n$$$ — the number of pipes ($$$1 \le n \le 10^5$$$). Each of the following $$$n$$$ lines contains three integers $$$x_i$$$, $$$v_i$$$, $$$p_i$$$ — the coordinate of the $$$i$$$-th pipe, the speed of the $$$i$$$-th proton and the probability that the $$$i$$$-th proton flies to the right in percentage points ($$$-10^9 \le x_i \le 10^9, 1 \le v \le 10^6, 0 \le p_i \le 100$$$). It is guaranteed that all $$$x_i$$$ are distinct and sorted in increasing order.

It's possible to prove that the answer can always be represented as a fraction $$$P/Q$$$, where $$$P$$$ is an integer and $$$Q$$$ is a natural number not divisible by $$$998\,244\,353$$$. In this case, print $$$P \cdot Q^{-1}$$$ modulo $$$998\,244\,353$$$.

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

struct ModInt(int M_) {
  alias M = M_;
  int x;
  this(ModInt a) { x = a.x; }
  this(long a) { x = cast(int)(a % M); if (x < 0) x += M; }
  ref ModInt opAssign(long a) { return (this = ModInt(a)); }
  ref ModInt opOpAssign(string op)(ModInt a) {
    static if (op == "+") { x += a.x; if (x >= M) x -= M; }
    else static if (op == "-") { x -= a.x; if (x < 0) x += M; }
    else static if (op == "*") { x = cast(int)((cast(long)(x) * a.x) % M); }
    else static if (op == "/") { this *= a.inv(); }
    else static assert(false);
    return this;
  }
  ref ModInt opOpAssign(string op)(long a) {
    static if (op == "^^") {
      ModInt t2 = this, te = ModInt(1);
      for (long e = a; e; e >>= 1) {
        if (e & 1) te *= t2;
        t2 *= t2;
      }
      x = cast(int)(te.x);
      return this;
    } else return mixin("this " ~ op ~ "= ModInt(a)");
  }
  ModInt inv() const {
    int a = x, b = M, y = 1, z = 0, t;
    for (; ; ) {
      t = a / b; a -= t * b;
      if (a == 0) {
        assert(b == 1 || b == -1);
        return ModInt(b * z);
      }
      y -= t * z;
      t = b / a; b -= t * a;
      if (b == 0) {
        assert(a == 1 || a == -1);
        return ModInt(a * y);
      }
      z -= t * y;
    }
  }
  ModInt opUnary(string op)() const if (op == "-") { return ModInt(-x); }
  ModInt opBinary(string op, T)(T a) const { return mixin("ModInt(this) " ~ op ~ "= a"); }
  ModInt opBinaryRight(string op)(long a) const { return mixin("ModInt(a) " ~ op ~ "= this"); }
  string toString() const { return x.to!string; }
}

enum MO = 998244353;
alias Mint = ModInt!MO;

int root(int[] uf, int u) {
  return (uf[u] < 0) ? u : (uf[u] = uf.root(uf[u]));
}
bool connect(int[] uf, int u, int v) {
  u = uf.root(u);
  v = uf.root(v);
  if (u == v) return false;
  if (uf[u] > uf[v]) swap(u, v);
  uf[u] += uf[v];
  uf[v] = u;
  return true;
}

int N;
long[] X, V;
Mint[] P;

struct Info {
  Mint p, q, s;
  Info opBinary(string op)(ref const(Info) a) const if (op == "*") {
    return Info(p * a.p, q * a.q, s * a.p + q * a.s - q * a.p);
  }
}
enum IDENTITY = Info(Mint(1), Mint(1), Mint(1));
int segN;
Info[] seg;
Info get(int a, int b) {
  Info retL = IDENTITY;
  Info retR = IDENTITY;
  ++b;
  for (a += segN, b += segN; a < b; a >>= 1, b >>= 1) {
    if (a & 1) retL = retL * seg[a++];
    if (b & 1) retR = seg[--b] * retR;
  }
  return retL * retR;
}

void main() {
  try {
    for (; ; ) {
      const N = readInt();
      X = new long[N];
      V = new long[N];
      P = new Mint[N];
      foreach (i; 0 .. N) {
        X[i] = readLong();
        V[i] = readLong();
        P[i] = Mint(readLong()) / 100;
      }

      for (segN = 1; segN < N; segN <<= 1) {}
      seg = new Info[segN << 1];
      seg[] = IDENTITY;
      foreach (i; 0 .. N) {
        seg[segN + i] = Info(P[i], Mint(1) - P[i], Mint(1));
      }
      foreach_reverse (a; 1 .. segN) {
        seg[a] = seg[a << 1] * seg[a << 1 | 1];
      }
      debug {
        foreach (i; 0 .. N) foreach (j; i .. N) {
          writeln(i, " ", j, ": ", get(i, j));
        }
      }

      alias Entry = Tuple!(long, "tp", long, "tq", int, "i", int, "typ");
      Entry[] es;
      foreach (i; 0 .. N - 1) {
        es ~= Entry(X[i + 1] - X[i], V[i] + V[i + 1], i, 0);
        if (V[i] > V[i + 1]) {
          es ~= Entry(X[i + 1] - X[i], V[i] - V[i + 1], i, +1);
        }
        if (V[i] < V[i + 1]) {
          es ~= Entry(X[i + 1] - X[i], V[i + 1] - V[i], i, -1);
        }
      }
      es.sort!((ea, eb) => (ea.tp * eb.tq < eb.tp * ea.tq));

      auto uf = new int[N];
      uf[] = -1;
      /*
        l       r
        o-o-o-o-o
        < <     >
          ll    rr
      */
      auto ls = iota(N).array;
      auto rs = iota(N).array;
      auto lls = new int[N];
      auto rrs = new int[N];
      lls[] = -1;
      rrs[] = N;
      Mint calc(int l, int ll, int rr, int r) {
        chmax(ll, l - 1);
        chmin(rr, r + 1);
        return get(l, ll).q * get(ll + 1, rr - 1).s * get(rr, r).p;
      }
      Mint calcJ(int j) {
        return calc(ls[j], lls[j], rrs[j], rs[j]);
      }

      Mint now = 1;
      Mint ans;
      foreach (ref e; es) {
        debug {
          writeln("e = ", e);
        }
        const i = e.i;
        switch (e.typ) {
          case 0: {
            const jL = uf.root(i);
            const jR = uf.root(i + 1);
            const l = ls[jL];
            const r = rs[jR];
            now *= (calcJ(jL) * calcJ(jR)).inv;
            const lr = min(rrs[jL], i);
            const rl = max(lls[jR], i + 1);
            if (lls[jL] < lr && rl < rrs[jR]) {
              Mint prob = now;
              prob *= calc(l, lls[jL], lr, i);
              prob *= calc(i + 1, rl, rrs[jR], r);
              debug {
                writeln("  prob = ", prob, "; ", prob * 32);
              }
              ans += prob * (Mint(e.tp) * Mint(e.tq).inv);
            }
            // no ><
            uf.connect(i, i + 1);
            const j = uf.root(i);
            ls[j] = l;
            rs[j] = r;
            lls[j] = max(lls[jL], lls[jR]);
            rrs[j] = min(rrs[jL], rrs[jR]);
            if (!(lls[j] < rrs[j])) {
              goto done;
            }
            now *= calcJ(j);
          } break;
          case +1: {
            assert(uf.root(i) == uf.root(i + 1));
            const j = uf.root(i);
            const l = ls[j];
            const r = rs[j];
            const ll = lls[j];
            const rr = min(rrs[j], i);
            now *= calcJ(j).inv;
            if (ll < rr) {
              Mint prob = now;
              prob *= calc(l, ll, rr, r);
              debug {
                writeln("  ", l, " ", ll, " ", rr, " ", r);
                writeln("  prob = ", prob, "; ", prob * 32);
              }
              ans += prob * (Mint(e.tp) * Mint(e.tq).inv);
            }
            // no ><, >>
            chmax(lls[j], i);
            if (!(lls[j] < rrs[j])) {
              goto done;
            }
            now *= calcJ(j);
          } break;
          case -1: {
            assert(uf.root(i) == uf.root(i + 1));
            const j = uf.root(i);
            const l = ls[j];
            const r = rs[j];
            const ll = max(lls[j], i + 1);
            const rr = rrs[j];
            now *= calcJ(j).inv;
            if (ll < rr) {
              Mint prob = now;
              prob *= calc(l, ll, rr, r);
              debug {
                writeln("  ", l, " ", ll, " ", rr, " ", r);
                writeln("  prob = ", prob, "; ", prob * 32);
              }
              ans += prob * (Mint(e.tp) * Mint(e.tq).inv);
            }
            // no ><, <<
            chmin(rrs[j], i + 1);
            if (!(lls[j] < rrs[j])) {
              goto done;
            }
            now *= calcJ(j);
          } break;
          default: assert(false);
        }
        debug {
          foreach (j; 0 .. N) {
            if (uf[j] < 0) {
              writeln(ls[j], " ", lls[j], " ", rrs[j], " ", rs[j]);
            }
          }
          writeln("now = ", now);
        }
      }
     done:
      writeln(ans);

      debug {
        Mint brt;
        foreach (h; 0 .. 1 << N) {
          long tp = 1, tq = 0;
          void check(long tp0, long tq0) {
            if (tp * tq0 > tp0 * tq) {
              tp = tp0;
              tq = tq0;
            }
          }
          foreach (i; 0 .. N - 1) {
            if (!(h & 1 << i) && (h & 1 << i + 1)) {
              check(X[i + 1] - X[i], V[i] + V[i + 1]);
            }
            if (V[i] > V[i + 1]) {
              if (!(h & 1 << i) && !(h & 1 << i + 1)) {
                check(X[i + 1] - X[i], V[i] - V[i + 1]);
              }
            }
            if (V[i] < V[i + 1]) {
              if ((h & 1 << i) && (h & 1 << i + 1)) {
                check(X[i + 1] - X[i], V[i + 1] - V[i]);
              }
            }
          }
          if (tq != 0) {
            Mint prob = 1;
            foreach (i; 0 .. N) {
              prob *= (h & 1 << i) ? (Mint(1) - P[i]) : P[i];
            }
            // writeln(prob, " ", tp, "/", tq);
            brt += prob * Mint(tp) * Mint(tq).inv;
          }
        }
        writeln("brt = ", brt);
      }
    }
  } catch (EOFException e) {
  }
}


After the lessons n groups of schoolchildren went outside and decided to visit Polycarpus to celebrate his birthday. We know that the i-th group consists of si friends (1 ≤ si ≤ 4), and they want to go to Polycarpus together. They decided to get there by taxi. Each car can carry at most four passengers. What minimum number of cars will the children need if all members of each group should ride in the same taxi (but one taxi can take more than one group)?

The first line contains integer n (1 ≤ n ≤ 105) — the number of groups of schoolchildren. The second line contains a sequence of integers s1, s2, ..., sn (1 ≤ si ≤ 4). The integers are separated by a space, si is the number of children in the i-th group.

Print the single number — the minimum number of taxis necessary to drive all children to Polycarpus.

NoteIn the first test we can sort the children into four cars like this:  the third group (consisting of four children),  the fourth group (consisting of three children),  the fifth group (consisting of three children),  the first and the second group (consisting of one and two children, correspondingly). There are other ways to sort the groups into four cars.

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

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

void main(){
  auto n = readln.chomp.to!int;
  auto groups = readln.chomp.split(" ").map!(to!int);
  int[int] hash = [1: 0, 2: 0, 3: 0, 4: 0];
  foreach(g; groups){ hash[g] += 1; }
  int taxiNum;

  taxiNum += hash[4];
  taxiNum += hash[3];

  hash[1] = max(0, hash[1] - hash[3]);
  taxiNum += hash[2] / 2;

  hash[2] = hash[2] % 2;
  if(hash[2]){ taxiNum += 1; hash[1] = max(0, hash[1] - 2); }

  taxiNum += hash[1] / 4;
  if(hash[1] % 4){ taxiNum += 1; }

  taxiNum.writeln;
}

import std.stdio;
import std.algorithm;
import std.range;
import std.conv : to;
import std.string : strip;

auto min(T)(T a, T b)
{
    return a <= b ? a : b;
}

void main()
{
    readln;
    uint[5] nums;
    foreach(group; readln.strip.splitter(' ').array.sort.group)
        nums[to!uint(group[0])] = group[1];

    uint taxiNum = nums[4];

    auto oneAndTree = min(nums[3], nums[1]);

    taxiNum += oneAndTree;
    nums[1] -= oneAndTree;
    nums[3] -= oneAndTree;
    taxiNum += nums[3];

    auto ones = nums[1]/4;
    taxiNum += ones;
    nums[1] -= ones*4;

    auto twos = nums[2]/2;
    taxiNum += twos;
    nums[2] -= twos*2;

    if ((nums[1] + nums[2]) > 0)
        taxiNum += (nums[1] + nums[2]*2) > 4 ? 2 : 1;

    writeln(taxiNum);
}

import std.stdio;
import std.string;
import core.stdc.stdio;
import std.container;
import std.algorithm.sorting;
import std.algorithm.comparison;

int main(string[] argv)
{
	int n;
	scanf("%d", &n);
	int[4] s;
	int capacity = 4;
	foreach (i; 0 .. n)
	{
		int num;
		scanf("%d", &num);
		s[num - 1]++;
	}

	int result = 0;
	for (int i = 3; i >= 0; i--)
	{
		switch (i)
		{
			case (3): result += s[i]; break;
			case (2):{
				result += s[i];
				s[0] -= min(s[i], s[0]);
				break;
			}
			case (1):{
				result += (s[i] / 2);
				s[i] -= (s[i] / 2) * 2;
				result += s[i];
				s[0] -= min(2*s[i], s[0]);
				break;
			}
			case (0):{
				result += (s[i] / 4);
				s[i] -= (s[i] / 4) * 4;
				result += s[i] > 0 ? 1 : 0;
				break;
			}
			default:continue;
		}
	}
	printf("%d", result);
	return 0;
}

import std.stdio;
import std.array;
import std.algorithm;
import std.conv;

int main() {
    auto s = stdin.byLine;
    s.popFront();
    auto arr = s.front.split(" ");
    int[4] grps;
    foreach (g; arr) {
        grps[to!int(g) - 1]++;
    }
    int num = grps[3];
    if (grps[0] > grps[2]) grps[0] -= grps[2];
    else grps[0] = 0;
    if (grps[1] % 2) {
        if (grps[0] <= 2) grps[0] = 0;
        else grps[0] -= 2;
        grps[1] /= 2;
        grps[1]++;
    } else {
        grps[1] /= 2;
    }
    if (grps[0] % 4) grps[0] = grps[0] / 4 + 1;
    else grps[0] /= 4;
    num += grps[2] + grps[1] + grps[0];
    writeln(num);
    return 0;
}

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

void main() {
	readln();
	int[] a = readln().chomp.split(" ").map!(to!int).array;
	int[] count = new int[5];
	foreach (i; a) {
		count[i]++;
	}
	a.sort();
	int taxis = 0;
	foreach (i; a.retro) {
		if (count[i] > 0) {
			int cap = 4 - i;
			count[i]--;
			for (int j = i; j >= 1; j--) {
				if (count[j] > 0 && cap >= j) {
					cap -= j;
					count[j]--;
					j++;
				}
			}
			taxis++;
		}
	}
	writeln(taxis);

}

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

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

    int[5] a;
    foreach (e; s) a[e]++;
    a[1] = max(a[1] - a[3], 0);

    writeln(a[4] + a[3] + (a[1] + 2 * a[2] + 3) / 4);
}

import std.c.stdio;
import std.algorithm;
import std.math;

int main()
{
	int n;
	scanf("%d", &n);
	int[] groups = new int[4];
	int temp;
	foreach(i; 0..n)
	{
		scanf("%d", &temp);
		groups[temp-1]++;
	}
	int ansv;
	//4
	ansv += groups[3];
	// 1 and 3
	int temp13 = min(groups[0], groups[2]);
	ansv += temp13;
	groups[0] -= temp13;
	groups[2] -= temp13;
	//2
	ansv += groups[1]/2;
	groups[1] %= 2;
	//1 and 2
	if(groups[1] != 0) {
		ansv++;
		groups[1] = 0;
		if(groups[0] > 2)
			groups[0] -= 2;
		else
			groups[0] = 0;
	}
	if(groups[0] % 4 == 0)
		ansv += groups[0]/4;
	else
		ansv += groups[0]/4 + 1;
	//3
	ansv += groups[2];
	printf("%d", ansv);
	return 0;
}

import std.stdio;
import std.uni;
import std.conv;
import std.container;
import std.functional;
import std.algorithm;
import std.array;
import std.typecons;
import std.range;
import std.numeric;

void main(string[] args)
{
  inputFile = stdin;
  auto n = next!int;
  auto s = next!int(n);
  int[5] cnt;
  foreach(si; s) cnt[si]++;
  int res = 0;
  res += cnt[4];
  res += cnt[3];
  cnt[1] -= min(cnt[3], cnt[1]);
  auto p21 = min(cnt[2], cnt[1] / 2);
  res += p21;
  cnt[2] -= p21;
  cnt[1] -= 2 * p21;
  auto p21b = min(cnt[2], cnt[1]);
  res += p21b;
  cnt[2] -= p21b;
  cnt[1] -= p21b;
  res += cnt[2] / 2 + cnt[2] % 2;
  res += cnt[1] / 4;
  if (cnt[1] % 4 != 0)
    res += 1;
  return res.writeln;
}
ulong bitCnt(long x)
{
  ulong cnt = 0;
  while(x) {cnt += x & 1; x>>=1;}
  return cnt;
}
alias Arr(T) = Mat!(T, 1);
struct Mat(T, size_t dimension)
{
  T[] _baseArray;
  T[] _slice;
  size_t[dimension] _sizes; size_t dim(size_t i) {return _sizes[i];}
  size_t[dimension] _indexer;
  this(T[] baseArray, size_t[dimension] sizes)
  {
    _baseArray = baseArray;
    _sizes = sizes;
    _indexer[dimension - 1] = 1;
    static foreach_reverse(i; 0 .. dimension - 1)
      _indexer[i] = _indexer[i + 1] * _sizes[i + 1];
    auto requiredSize = _indexer[0] * _sizes[0];
    debug assert(_baseArray.length >= requiredSize);
    _slice = _baseArray[0 .. requiredSize];
  }
  this(size_t[dimension] sizes)
  {
    size_t reqSize = 1;
    static foreach(i; 0 .. dimension)
      reqSize *= sizes[i];
    this(new T[](reqSize), sizes);
  }
  ref auto opIndex()
  {
    pragma(inline, true);
    return _slice[];
  }
  ref auto opIndex(I...)(I i)
  {
    pragma(inline, true);
    debug assert(i.length <= dimension);
    size_t index = mixin(iota(0, i.length).map!(j => text("i[", j, "]*_indexer[", j, "]")).join("+"));
    static if (i.length == dimension)
      {
	return _slice[index];
      }
    else
      {
	enum sliceDimension = dimension - i.length;
	size_t[sliceDimension] remSizes = _sizes[i.length .. $];
	auto basePortion = _slice[index .. index + _indexer[i.length - 1]];
 	return Mat!(T, sliceDimension)(basePortion, remSizes);
      }
  }
  static if (dimension == 2)
    {
      auto identity()
      {
	debug assert(dim(0) == dim(1));
	auto n = dim(0);
	auto id = Mat!(T, 2)([n, n]);
	foreach(k; 0 .. n)
	  id[k, k] = T(1);
	return id;
      }
      bool canMultiply(Mat!(T, 2) b)
      {
	return this.dim(1) == b.dim(0);
      }
      auto opBinary(string op)(Mat!(T, 2) b)
	if (op == "*")
	  {
	    debug assert(canMultiply(b));
	    auto res = Mat!(T, 2)([this.dim(0), b.dim(1)]);
	    foreach(i; 0 .. res.dim(0))
	      foreach(k; 0 .. this.dim(1))
		foreach(j; 0 .. res.dim(1))
		  res[i, j] = res[i, j] + this[i, k] * b[k, j];
	    return res;
	  }
      auto opBinary(string op)(ulong exp)
	if (op == "^^")
	  {
	    return this.pow(identity, exp);
	  }
      mixin interiorBinPow;
    }
}

struct Mod(T, ulong mod)
{
  alias This = Mod!(T, mod);
  T _rep; T rep() {return _rep;}
  this(W)(W w)
  {
    _rep = ((cast(T) w)%mod + mod) % mod;
  }
  static auto plainConstruct(T t)
  {
    pragma(inline, true);
    debug assert(t >= 0 && t < mod);
    auto res = Mod!(T, mod).init;
    res._rep = t;
    return res;
  }
  string toString()
  {
    return to!string(rep);
  }
  debug invariant
  {
    assert(_rep >= 0 && _rep < mod);
  }
  auto opBinary(string op)(This b)
  {
    static if (op == "+")
      {
	T resrep = _rep + b._rep;
	if (resrep >= mod) resrep -= mod;
	return This.plainConstruct(resrep);
      }
    else static if (op == "-")
      {
	T resrep = _rep - b._rep;
	if (resrep < 0) resrep += mod;
	return This.plainConstruct(resrep);
      }
    else static if (op == "*")
      {
	return This(_rep * b._rep);
      }
  }
}

mixin template interiorBinPow()
{
  alias ThisType = typeof(this);
  auto pow(ThisType res, ulong exp)
    {
      if (exp < 0) debug assert(0);
      auto pow = this;
      while(exp)
	{
	  if (exp & 1)
	    res = res * pow;
	  pow = pow * pow;
	  exp >>= 1;
	}
      return res;
    }
}

// INPUT
File inputFile;
DList!string _words;
void _wordsFill()
{
  while (_words.empty) _words.insertBack(inputFile.readln.split);
}
string popWord()
{
  _wordsFill;
  auto word = _words.front;
  _words.removeFront;
  return word;
}
string peekWord()
{
  _wordsFill;
  return _words.front;
}
T next(T)()
{
  return to!T(popWord);
}
T peek(T)()
{
  return to!T(peekWord);
}
auto next(T, S...)(S s)
{
  static if (S.length == 0)
    {
      return to!T(popWord);
    }
  else
    {
      auto res = new typeof(next!T(s[1 .. $]))[](cast(size_t)s[0]);
      foreach(ref elem; res)
        elem = next!T(s[1 .. $]);
      return res;
    }
}

void main() {
    import std.algorithm : min;
    import std.stdio : readf, writeln;

    int n;
    readf!"%d"(n);
    int[4] a;
    foreach (_; 0 .. n) {
        readf!" %d"(n);
        a[n - 1]++;
    }

    int res;
    res += a[3];
    a[0] -= min(a[0], a[2]);
    res += a[2];
    if (a[1] % 2 == 1) {
        a[0] -= min(a[0], 2);
        res++;
    }
    res += a[1] / 2;
    res += a[0] / 4;
    if (a[0] % 4 != 0) {
        res++;
    }
    writeln(res);
}

import std.stdio;
import std.string;
import core.stdc.stdio;
import std.container;
import std.algorithm.sorting;
import std.algorithm.comparison;

int main(string[] argv)
{
	int n;
	scanf("%d", &n);
	int[4] s;
	foreach (i; 0 .. n)
	{
		int num;
		scanf("%d", &num);
		s[num - 1]++;
	}

	int m = min(s[2], s[0]);
	s[3] += m;
	s[2] -= m;
	s[0] -= m;
	m = s[1] / 2;
	s[1] -= m * 2;
	s[3] += m;
	m = min(s[0], s[1]);
	s[0] -= m;
	s[1] -= m;
	s[3] += m;
	m = s[0] / 4;
	s[3] += m;
	s[0] -= m * 4;
	if (s[0] > 0) {
		s[3] += 1;
		s[0] = 0;
	}
	printf ("%d", s[0] + s[1] + s[2] + s[3]);
	return 0;
}

import std.stdio;
import std.string;
import core.stdc.stdio;
import std.container;
import std.algorithm.sorting;
import std.algorithm.comparison;

int main(string[] argv)
{
	int n;
	scanf("%d", &n);
	int[4] s;
	int capacity = 4;
	foreach (i; 0 .. n)
	{
		int num;
		scanf("%d", &num);
		s[num - 1]++;
	}

	int result = 0;
	for (int i = 3; i >= 0; i--)
	{
		switch (i)
		{
			case (3): result += s[i]; break;
			case (2):{
				result += s[i];
				s[0] -= min(s[i], s[0]);
				break;
			}
			case (1):{
				result += (s[i] / 2);
				s[i] -= (s[i] / 2) * 2;
				result += s[i];
				s[0] -= min(2*s[i], s[0]);
				break;
			}
			case (0):{
				result += (s[i] / 4);
				s[i] -= (s[i] / 4) * 4;
				result += s[i];
				break;
			}
			default:continue;
		}
	}
	printf("%d", result);
	return 0;
}

import std.stdio;
import std.string;
import core.stdc.stdio;
import std.container;
import std.algorithm.sorting;
import std.algorithm.comparison;

int main(string[] argv)
{
	int n;
	scanf("%d", &n);
	int[4] s;
	foreach (i; 0 .. n)
	{
		int num;
		scanf("%d", &num);
		s[num - 1]++;
	}

	int m = min(s[2], s[0]);
	s[3] += m;
	s[2] -= m;
	s[0] -= m;
	m = s[1] / 2;
	s[1] -= m * 2;
	s[3] += m;
	printf ("%d", s[0] + s[1] + s[2] + s[3]);
	return 0;
}

import std.stdio;
import std.string;
import core.stdc.stdio;
import std.container;
import std.algorithm.sorting;
import std.algorithm.comparison;

int main(string[] argv)
{
	int n;
	scanf("%d", &n);
	int[4] s;
	foreach (i; 0 .. n)
	{
		int num;
		scanf("%d", &num);
		s[num - 1]++;
	}

	int m = min(s[2], s[0]);
	s[3] += m;
	s[2] -= m;
	s[0] -= m;
	m = s[1] / 2;
	s[1] -= m * 2;
	s[3] += m;
	m = min(s[0], s[1]);
	s[0] -= m;
	s[1] -= m;
	s[3] += m;
	m = s[0] / 4;
	s[3] += m;
	s[0] -= m * 4;
	printf ("%d", s[0] + s[1] + s[2] + s[3]);
	return 0;
}

import std.stdio;
import std.string;
import core.stdc.stdio;
import std.container;
import std.algorithm.sorting;
import std.algorithm.comparison;

int main(string[] argv)
{
	int n;
	scanf("%d", &n);
	int[4] s;
	foreach (i; 0 .. n)
	{
		int num;
		scanf("%d", &num);
		s[num - 1]++;
	}

	int m = min(s[2], s[0]);
	s[3] += m;
	s[2] -= m;
	s[0] -= m;
	m = s[1] / 2;
	s[1] -= m * 2;
	s[3] += m;
	m = s[0] / 4;
	s[3] += m;
	s[0] -= m * 4;
	printf ("%d", s[0] + s[1] + s[2] + s[3]);
	return 0;
}

import std.stdio;
import std.array;
import std.algorithm;
import std.conv;

int main() {
    auto s = stdin.byLine;
    s.popFront();
    auto arr = s.front.split(" ");
    int[4] grps;
    foreach (g; arr) {
        grps[to!int(g) - 1]++;
    }
    int num = grps[3];
    if (grps[0] > grps[2]) grps[0] -= grps[2];
    else grps[0] = 0;
    if (grps[1] % 2) {
        if (grps[0] <= 2) grps[0] = 0;
        else grps[0] -= 2;
        grps[1] /= 2;
        grps[1]++;
    } else {
        grps[2] /= 2;
    }
    if (grps[0] % 4) grps[0] = grps[0] / 4 + 1;
    else grps[0] /= 4;
    num += grps[2] + grps[1] + grps[0];
    writeln(num);
    return 0;
}

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

void main() {
    readln;
    auto s = readln.chomp.split.map!(to!int).array.sort!("a > b").array;

    int count = 0;

    count += s.count(4);
    s = s.filter!("a != 4").array;

    count += s.count(3);
    for (int i = 0; i < s.count(3); i++) {
        if (s.back == 1) s.popBack;
    }

    count += (s.count(2) / 2.0).ceil;

    count += (s.count(1) / 4.0).ceil;

    count.writeln;
}

import std.c.stdio;
import std.algorithm;
import std.math;

int main()
{
	int n;
	scanf("%d", &n);
	int[] groups = new int[4];
	int temp;
	foreach(i; 0..n)
	{
		scanf("%d", &temp);
		groups[temp-1]++;
	}
	int ansv;
	//4
	ansv += groups[3];
	// 1 and 3
	int temp13 = min(groups[0], groups[2]);
	ansv += temp13;
	groups[0] -= temp13;
	groups[2] -= temp13;
	//2
	ansv += groups[1]/2;
	groups[1] %= 2;
	//1 and 2
	if(groups[1] != 0) {
		ansv++;
		groups[1] = 0;
		if(groups[0] > 2)
			groups[0] -= 2;
		else
			groups[0] = 0;
		if(groups[0] % 4 == 0)
			ansv += groups[0]/4;
		else
			ansv += groups[0]/4 + 1;
	}
	//3
	ansv += groups[2];
	printf("%d", ansv);
	return 0;
}

import std.c.stdio;

int main(string[] argv)
{
	int n;
	scanf("%d", &n);
	int[] arr = [0, 0, 0, 0];
	int temp;
	foreach(i; 0..n)
	{
		scanf("%d", &temp);
		arr[temp-1]++;
	}
	if(arr[0] > arr[2])
		arr[2]=0;
	else
		arr[0] = 0;
	if(arr[1] % 2 == 0)
		arr[1] /= 2;
	else
	{
		arr[1] /= 2;
		if(arr[0] == 0)
			arr[0]++;
	}
	printf("%d", arr[0] + arr[1] + arr[2] + arr[3]);
	return 0;
}

import std.stdio;
import std.uni;
import std.conv;
import std.container;
import std.functional;
import std.algorithm;
import std.array;
import std.typecons;
import std.range;
import std.numeric;

void main(string[] args)
{
  inputFile = stdin;
  auto n = next!int;
  auto s = next!int(n);
  int[5] cnt;
  foreach(si; s) cnt[si]++;
  int res = 0;
  res += cnt[4];
  res += cnt[3];
  cnt[1] -= min(cnt[3], cnt[1]);
  auto p21 = min(cnt[2], cnt[1] / 2);
  res += p21;
  cnt[2] -= p21;
  cnt[1] -= 2 * p21;
  auto p21b = min(cnt[2], cnt[1]);
  res += p21b;
  cnt[2] -= p21b;
  cnt[1] -= p21b;
  res += cnt[2] / 2 + cnt[2] % 2;
  res += cnt[1] / 4 + cnt[1] % 4;
  return res.writeln;
}
ulong bitCnt(long x)
{
  ulong cnt = 0;
  while(x) {cnt += x & 1; x>>=1;}
  return cnt;
}
alias Arr(T) = Mat!(T, 1);
struct Mat(T, size_t dimension)
{
  T[] _baseArray;
  T[] _slice;
  size_t[dimension] _sizes; size_t dim(size_t i) {return _sizes[i];}
  size_t[dimension] _indexer;
  this(T[] baseArray, size_t[dimension] sizes)
  {
    _baseArray = baseArray;
    _sizes = sizes;
    _indexer[dimension - 1] = 1;
    static foreach_reverse(i; 0 .. dimension - 1)
      _indexer[i] = _indexer[i + 1] * _sizes[i + 1];
    auto requiredSize = _indexer[0] * _sizes[0];
    debug assert(_baseArray.length >= requiredSize);
    _slice = _baseArray[0 .. requiredSize];
  }
  this(size_t[dimension] sizes)
  {
    size_t reqSize = 1;
    static foreach(i; 0 .. dimension)
      reqSize *= sizes[i];
    this(new T[](reqSize), sizes);
  }
  ref auto opIndex()
  {
    pragma(inline, true);
    return _slice[];
  }
  ref auto opIndex(I...)(I i)
  {
    pragma(inline, true);
    debug assert(i.length <= dimension);
    size_t index = mixin(iota(0, i.length).map!(j => text("i[", j, "]*_indexer[", j, "]")).join("+"));
    static if (i.length == dimension)
      {
	return _slice[index];
      }
    else
      {
	enum sliceDimension = dimension - i.length;
	size_t[sliceDimension] remSizes = _sizes[i.length .. $];
	auto basePortion = _slice[index .. index + _indexer[i.length - 1]];
 	return Mat!(T, sliceDimension)(basePortion, remSizes);
      }
  }
  static if (dimension == 2)
    {
      auto identity()
      {
	debug assert(dim(0) == dim(1));
	auto n = dim(0);
	auto id = Mat!(T, 2)([n, n]);
	foreach(k; 0 .. n)
	  id[k, k] = T(1);
	return id;
      }
      bool canMultiply(Mat!(T, 2) b)
      {
	return this.dim(1) == b.dim(0);
      }
      auto opBinary(string op)(Mat!(T, 2) b)
	if (op == "*")
	  {
	    debug assert(canMultiply(b));
	    auto res = Mat!(T, 2)([this.dim(0), b.dim(1)]);
	    foreach(i; 0 .. res.dim(0))
	      foreach(k; 0 .. this.dim(1))
		foreach(j; 0 .. res.dim(1))
		  res[i, j] = res[i, j] + this[i, k] * b[k, j];
	    return res;
	  }
      auto opBinary(string op)(ulong exp)
	if (op == "^^")
	  {
	    return this.pow(identity, exp);
	  }
      mixin interiorBinPow;
    }
}

struct Mod(T, ulong mod)
{
  alias This = Mod!(T, mod);
  T _rep; T rep() {return _rep;}
  this(W)(W w)
  {
    _rep = ((cast(T) w)%mod + mod) % mod;
  }
  static auto plainConstruct(T t)
  {
    pragma(inline, true);
    debug assert(t >= 0 && t < mod);
    auto res = Mod!(T, mod).init;
    res._rep = t;
    return res;
  }
  string toString()
  {
    return to!string(rep);
  }
  debug invariant
  {
    assert(_rep >= 0 && _rep < mod);
  }
  auto opBinary(string op)(This b)
  {
    static if (op == "+")
      {
	T resrep = _rep + b._rep;
	if (resrep >= mod) resrep -= mod;
	return This.plainConstruct(resrep);
      }
    else static if (op == "-")
      {
	T resrep = _rep - b._rep;
	if (resrep < 0) resrep += mod;
	return This.plainConstruct(resrep);
      }
    else static if (op == "*")
      {
	return This(_rep * b._rep);
      }
  }
}

mixin template interiorBinPow()
{
  alias ThisType = typeof(this);
  auto pow(ThisType res, ulong exp)
    {
      if (exp < 0) debug assert(0);
      auto pow = this;
      while(exp)
	{
	  if (exp & 1)
	    res = res * pow;
	  pow = pow * pow;
	  exp >>= 1;
	}
      return res;
    }
}

// INPUT
File inputFile;
DList!string _words;
void _wordsFill()
{
  while (_words.empty) _words.insertBack(inputFile.readln.split);
}
string popWord()
{
  _wordsFill;
  auto word = _words.front;
  _words.removeFront;
  return word;
}
string peekWord()
{
  _wordsFill;
  return _words.front;
}
T next(T)()
{
  return to!T(popWord);
}
T peek(T)()
{
  return to!T(peekWord);
}
auto next(T, S...)(S s)
{
  static if (S.length == 0)
    {
      return to!T(popWord);
    }
  else
    {
      auto res = new typeof(next!T(s[1 .. $]))[](cast(size_t)s[0]);
      foreach(ref elem; res)
        elem = next!T(s[1 .. $]);
      return res;
    }
}

void main() {
    import std.algorithm : sort, maxElement;
    import std.stdio : readf, writeln;
    import std.range : enumerate, dropExactly, retro;

    int n;
    readf!"%d"(n);
    int[] s;
    s.length = n;
    foreach (i; 0 .. n) {
        readf!" %d"(s[i]);
    }

    enum maxCapacity = 4;
    int res;
    bool[int] whatever;
    foreach (i; 0 .. n) {
        whatever[i] = false;
    }
    auto r = s.sort.retro;
    foreach (i, g1; r.enumerate) {
        auto available = maxCapacity - g1;
        if (whatever[i]) {
            continue;
        }
        res++;
        whatever[i] = true;

        if (available < r.maxElement) {
            continue;
        }

        foreach (j, g2; r.enumerate.dropExactly(i + 1)) {
            if (!whatever[j] && g2 <= available) {
                whatever[j] = true;
                available -= g2;
            }
            if (available < r.maxElement) {
                break;
            }
        }
    }
    writeln(res);
}

void main() {
    import std.algorithm : sort;
    import std.stdio : readf, writeln;
    import std.range : enumerate, dropExactly, retro;

    int n;
    readf!"%d"(n);
    int[] s;
    s.length = n;
    foreach (i; 0 .. n) {
        readf!" %d"(s[i]);
    }

    enum maxCapacity = 4;
    int res;
    bool[int] whatever;
    foreach (i; 0 .. n) {
        whatever[i] = false;
    }
    auto r = s.sort.retro.enumerate;
    foreach (i, g1; r) {
        auto available = maxCapacity - g1;
        if (whatever[i]) {
            continue;
        }
        if (!available) {
            res++;
            continue;
            whatever[i] = true;
        }
        res++;

        foreach (j, g2; r.dropExactly(i + 1)) {
            if (!whatever[j] && g2 <= available) {
                whatever[j] = true;
                available -= g2;
                break;
            }
        }
    }
    writeln(res);
}


Vladik often travels by trains. He remembered some of his trips especially well and I would like to tell you about one of these trips:Vladik is at initial train station, and now n people (including Vladik) want to get on the train. They are already lined up in some order, and for each of them the city code ai is known (the code of the city in which they are going to).Train chief selects some number of disjoint segments of the original sequence of people (covering entire sequence by segments is not necessary). People who are in the same segment will be in the same train carriage. The segments are selected in such way that if at least one person travels to the city x, then all people who are going to city x should be in the same railway carriage. This means that they can’t belong to different segments. Note, that all people who travel to the city x, either go to it and in the same railway carriage, or do not go anywhere at all.Comfort of a train trip with people on segment from position l to position r is equal to XOR of all distinct codes of cities for people on the segment from position l to position r. XOR operation also known as exclusive OR.Total comfort of a train trip is equal to sum of comfort for each segment.Help Vladik to know maximal possible total comfort.

First line contains single integer n (1 ≤ n ≤ 5000) — number of people. Second line contains n space-separated integers a1, a2, ..., an (0 ≤ ai ≤ 5000), where ai denotes code of the city to which i-th person is going.

The output should contain a single integer — maximal possible total comfort.

NoteIn the first test case best partition into segments is: [4, 4] [2, 5, 2] [3], answer is calculated as follows: 4 + (2 xor 5) + 3 = 4 + 7 + 3 = 14In the second test case best partition into segments is: 5 1 [3] 1 5 [2, 4, 2] 5, answer calculated as follows: 3 + (2 xor 4) = 3 + 6 = 9.

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;

void main() {
    immutable int MAX = 5010;

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

    auto L = new int[](MAX);
    auto R = new int[](MAX);
    fill(L, MAX);
    fill(R, -1);

    foreach (i; 0..N) {
        L[A[i]] = min(L[A[i]], i);
        R[A[i]] = max(R[A[i]], i);
    }

    auto mem = new int[](N);
    fill(mem, -1);

    int dp(int i) {
        if (i >= N) return 0;
        if (mem[i] >= 0) return mem[i];

        if (L[A[i]] != i)
            return dp(i + 1);
        int tar = R[A[i]];
        int pos = i + 1;
        int score = A[i];
        while (pos < N && pos <= tar) {
            if (L[A[pos]] < i) {
                score = 0;
                break;
            }
            else if (L[A[pos]] == pos) {
                score ^= A[pos];
            }
            tar = max(tar, R[A[pos]]);
            pos += 1;
        }

        return mem[i] = max(dp(i+1), score + dp(tar+1));
    }

    dp(0).writeln;
}

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

immutable int INF = 10L ^^ 9 + 23;
immutable int MX = 5000;

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

    auto arr = [0] ~ readln.chomp.split.map!(to!int).array;

    auto mxle = new int[] (n+1);
    foreach (i; 1 .. n+1) {
        foreach_reverse (j; 1 .. i+1) {
            if (arr[j] == arr[i]) { mxle[i] = j; }
        }
    }

    auto mxr = new int[] (n+1);
    foreach (i; 1 .. n+1) {
        foreach (j; i .. n+1) {
            if (arr[i] == arr[j]) { mxr[i] = j; }
        }
    }

    debug { mxle.writeln; mxr.writeln; }

    auto dp = new int[] (n+1);
    foreach (i; 1 .. n+1) {
        dp[i] = dp[i-1];

        int cxor = 0, borderle = i, borderr = i;
        foreach_reverse (j; 1 .. i+1) {
            borderr = max(borderr, mxr[j]);
            if (borderr > i) { break; }

            if (j == mxr[j]) { cxor ^= arr[j]; }

            borderle = min(borderle, mxle[j]);
            if (borderle < j) { continue; }

            debug { writeln(i, ' ', j, ' ', cxor); }

            dp[i] = max(dp[i], cxor + dp[j-1]);
        }
    }

    debug { dp.writeln; }

    dp[n].writeln;
}

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

immutable int INF = 10L ^^ 9 + 23;
immutable int MX = 5000;

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

    auto arr = [0] ~ readln.chomp.split.map!(to!int).array;

    auto mxle = new int[] (n+1);
    foreach (i; 1 .. n+1) {
        foreach_reverse (j; 1 .. i+1) {
            if (arr[j] == arr[i]) { mxle[i] = j; }
        }
    }

    auto mxr = new int[] (n+1);
    foreach (i; 1 .. n+1) {
        foreach (j; i .. n+1) {
            if (arr[i] == arr[j]) { mxr[i] = j; }
        }
    }

    debug { mxle.writeln; mxr.writeln; }

    auto dp = new int[] (n+1);
    foreach (i; 1 .. n+1) {
        dp[i] = dp[i-1];

        int cxor = 0, mxxor = 0, borderle = i, borderr = i;
        foreach_reverse (j; 1 .. i+1) {
            borderr = max(borderr, mxr[j]);
            if (borderr > i) { break; }

            if (j == mxr[j]) { cxor ^= arr[j]; }

            borderle = min(borderle, mxle[j]);
            if (borderle < j) { continue; }

            debug { writeln(i, ' ', j, ' ', cxor); }

            dp[i] = max(dp[i], cxor + dp[j-1]);
        }
    }

    debug { dp.writeln; }

    dp[n].writeln;
}

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

void main() {
    immutable int MAX = 5010;

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

    auto L = new int[](MAX);
    auto R = new int[](MAX);
    fill(L, MAX);
    fill(R, -1);

    foreach (i; 0..N) {
        L[A[i]] = min(L[A[i]], i);
        R[A[i]] = max(R[A[i]], i);
    }

    auto mem = new int[](N);
    fill(mem, -1);

    int dp(int i) {
        if (i >= N) return 0;
        if (mem[i] >= 0) return mem[i];

        if (L[A[i]] != i)
            return dp(i + 1);
        int tar = R[A[i]];
        int pos = i + 1;
        int score = A[i];
        while (pos < N && pos <= tar) {
            if (L[A[pos]] < i) {
                score = 0;
                break;
            }
            else if (L[A[pos]] == pos) {
                score ^= A[pos];
            }
            tar = max(tar, R[A[pos]]);
            pos += 1;
        }

        writeln(i, " ", tar);
        return mem[i] = max(dp(i+1), score + dp(tar+1));
    }

    dp(0).writeln;
}


There are n cities in Berland. Each city has its index — an integer number from 1 to n. The capital has index r1. All the roads in Berland are two-way. The road system is such that there is exactly one path from the capital to each city, i.e. the road map looks like a tree. In Berland's chronicles the road map is kept in the following way: for each city i, different from the capital, there is kept number pi — index of the last city on the way from the capital to i.Once the king of Berland Berl XXXIV decided to move the capital from city r1 to city r2. Naturally, after this the old representation of the road map in Berland's chronicles became incorrect. Please, help the king find out a new representation of the road map in the way described above.

The first line contains three space-separated integers n, r1, r2 (2 ≤ n ≤ 5·104, 1 ≤ r1 ≠ r2 ≤ n) — amount of cities in Berland, index of the old capital and index of the new one, correspondingly. The following line contains n - 1 space-separated integers — the old representation of the road map. For each city, apart from r1, there is given integer pi — index of the last city on the way from the capital to city i. All the cities are described in order of increasing indexes.

Output n - 1 numbers — new representation of the road map in the same format.

#!/usr/bin/rdmd
import std.stdio;

const int MAX_N = 50009;

int p [MAX_N];

void recur (int b, int a)
{
	if (b == a)
		return;
	recur (p[b], a);
	p[p[b]] = b;
}

void main ()
{
	int a, b, i, n;

	while (readf (" %d %d %d", &n, &a, &b) > 0)
	{
		for (i = 1; i <= n; i++)
			if (i != a)
				readf (" %d", &p[i]);

		p[a] = a;
		recur (b, a);

		for (i = 1; i <= n; i++)
			if (i != b)
				writef ("%d ", p[i]);
		writefln ("");
	}
}


Shaass has n books. He wants to make a bookshelf for all his books. He wants the bookshelf's dimensions to be as small as possible. The thickness of the i-th book is ti and its pages' width is equal to wi. The thickness of each book is either 1 or 2. All books have the same page heights.  Shaass puts the books on the bookshelf in the following way. First he selects some of the books and put them vertically. Then he puts the rest of the books horizontally above the vertical books. The sum of the widths of the horizontal books must be no more than the total thickness of the vertical books. A sample arrangement of the books is depicted in the figure.  Help Shaass to find the minimum total thickness of the vertical books that we can achieve.

The first line of the input contains an integer n, (1 ≤ n ≤ 100). Each of the next n lines contains two integers ti and wi denoting the thickness and width of the i-th book correspondingly, (1 ≤ ti ≤ 2, 1 ≤ wi ≤ 100).

On the only line of the output print the minimum total thickness of the vertical books that we can achieve.

import std.algorithm;
import std.stdio;

void main ()
{
	int n;
	while (readf (" %d", &n) > 0)
	{
		auto t = new int [n];
		auto w = new int [n];
		int m = 0;
		foreach (i; 0..n)
		{
			readf (" %d %d", &t[i], &w[i]);
			m += t[i];
		}

		m += 1;
		auto f = new int [m];
		f[] = int.max / 2;
		f[0] = 0;
		foreach (i; 0..n)
		{
			auto g = f.dup;
			foreach (j; 0..m - t[i])
			{
				g[j + t[i]] = min (g[j + t[i]], f[j] + w[i]);
			}
			f = g;
		}

		int res = int.max / 2;
		foreach (j; 0..m)
		{
			if (f[m - 1 - j] <= j)
			{
				res = min (res, j);
			}
		}
		writeln (res);
	}
}

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

void main ()
{
	int n;
	while (readf (" %s", &n) > 0)
	{
		writeln (n);
		auto t = new int [n];
		auto w = new int [n];
		int m = 0;
		foreach (i; 0..n)
		{
			readf (" %s %s", &t[i], &w[i]);
			m += t[i];
		}

		m += 1;
		auto f = new int [m];
		f[] = int.max;
		f[0] = 0;
		foreach (i; 0..n)
		{
			auto g = f.dup;
			foreach (j; 0..m - t[i])
			{
				g[j + t[i]] = min (g[j + t[i]], f[j] + w[i]);
			}
			f = g;
		}

		int res = int.min;
		foreach (j; 0..m)
		{
			if (f[j] <= j)
			{
				res = max (res, j);
			}
		}
		writeln (res);
	}
}

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

void main ()
{
	int n;
	while (readf (" %s", &n) > 0)
	{
		writeln (n);
		auto t = new int [n];
		auto w = new int [n];
		int m = 0;
		foreach (i; 0..n)
		{
			readf (" %s %s", &t[i], &w[i]);
			m += t[i];
		}

		m += 1;
		auto f = new int [m];
		f[] = int.max;
		f[0] = 0;
		foreach (i; 0..n)
		{
			auto g = f.dup;
			foreach (j; 0..m - t[i])
			{
				g[j + t[i]] = min (g[j + t[i]], f[j] + w[i]);
			}
			f = g;
		}

		int res = int.max;
		foreach (j; 0..m)
		{
			if (f[j] <= j)
			{
				res = min (res, j);
			}
		}
		writeln (res);
	}
}


Mark is asked to take a group photo of $$$2n$$$ people. The $$$i$$$-th person has height $$$h_i$$$ units.To do so, he ordered these people into two rows, the front row and the back row, each consisting of $$$n$$$ people. However, to ensure that everyone is seen properly, the $$$j$$$-th person of the back row must be at least $$$x$$$ units taller than the $$$j$$$-th person of the front row for each $$$j$$$ between $$$1$$$ and $$$n$$$, inclusive.Help Mark determine if this is possible.

The first line contains one integer $$$t$$$ ($$$1\leq t\leq 100$$$) — the number of test cases. Each test case consists of two lines. The first line of each test case contains two positive integers $$$n$$$ and $$$x$$$ ($$$1\leq n\leq 100$$$, $$$1\leq x\leq 10^3$$$) — the number of people in each row and the minimum difference Mark wants. The second line of each test case contains $$$2n$$$ positive integers $$$h_1,h_2,\ldots,h_{2n}$$$ ($$$1\leq h_i\leq 10^3$$$) — the height of each person in units. Note that the sum of $$$n$$$ over all test cases is not bounded.

For each test case, print a single line containing "YES" if Mark could arrange people satisfying his condition and "NO" otherwise. You may print each letter in any case (for example, YES, Yes, yes, yEs will all be recognized as positive answers).

NoteIn the first test case, one possible order is to have the third, fifth, and sixth person on the back row and the second, first, and fourth on the front row. The heights of the people will look like this. Back$$$9$$$$$$12$$$$$$16$$$Front$$$3$$$$$$1$$$$$$10$$$ It works because   $$$h_3-h_2 = 9-3 \geq 6$$$,    $$$h_5-h_1 = 12-1\geq 6$$$, and    $$$h_6-h_4 = 16-10\geq 6$$$. In the second test case, it can be shown there is no way to order people in a way that satisfies the condition.In the third test case, the only way to arrange people to satisfy the condition is to have the first person on the back row and the second person on the front row.

// cheese-cracker [2022-07-15]

void solve(){
    int n = scan!int;
    int x = scan!int;
    auto arr = scanArray!int;
    arr.sort;
    for(int i = n; i < 2*n; ++i){
        if(arr[i] < arr[i - n] + x){
            writeln("NO");
            return;
        }
    }
    writeln("YES");
}

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

/*_________________________*That's All Folks!*__________________________*/
import std.stdio, std.range, std.conv, std.typecons, std.algorithm;
import std.container, std.math, std.numeric, std.functional;
string[] tk; alias tup = Tuple!(long, long);
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; } }


Imagine that there is a group of three friends: A, B and С. A owes B 20 rubles and B owes C 20 rubles. The total sum of the debts is 40 rubles. You can see that the debts are not organized in a very optimal manner. Let's rearrange them like that: assume that A owes C 20 rubles and B doesn't owe anything to anybody. The debts still mean the same but the total sum of the debts now equals 20 rubles.This task is a generalisation of a described example. Imagine that your group of friends has n people and you know the debts between the people. Optimize the given debts without changing their meaning. In other words, finally for each friend the difference between the total money he should give and the total money he should take must be the same. Print the minimum sum of all debts in the optimal rearrangement of the debts. See the notes to the test samples to better understand the problem.

The first line contains two integers n and m (1 ≤ n ≤ 100; 0 ≤ m ≤ 104). The next m lines contain the debts. The i-th line contains three integers ai, bi, ci (1 ≤ ai, bi ≤ n; ai ≠ bi; 1 ≤ ci ≤ 100), which mean that person ai owes person bi ci rubles. Assume that the people are numbered by integers from 1 to n. It is guaranteed that the same pair of people occurs at most once in the input. The input doesn't simultaneously contain pair of people (x, y) and pair of people (y, x).

Print a single integer — the minimum sum of debts in the optimal rearrangement.

NoteIn the first sample, you can assume that person number 1 owes 8 rubles to person number 2, 1 ruble to person number 3 and 1 ruble to person number 4. He doesn't owe anybody else anything. In the end, the total debt equals 10.In the second sample, there are no debts.In the third sample, you can annul all the debts.

#!/usr/bin/env rdmd
import std.stdio, std.string, std.conv;
import std.algorithm, std.array;

void main()
{
    for(string S; (S=readln().chomp()).length; )
    {
        auto nm = S.split().map!(to!int)();
        auto n=nm[0], m=nm[1];
        auto d = new int[][](n,n);
        foreach(i;0..m)
        {
            auto abc = readln().split().map!(to!int)();
            d[abc[0]-1][abc[1]-1]=abc[2];
        }
        foreach(k;0..n)
            foreach(i;0..n)
                foreach(j;0..n)
                {
                    auto c = min(d[i][k],d[k][j]);
                    d[i][j] += c;
                    d[i][k] -= c;
                    d[k][j] -= c;
                }
        auto t = 0;
        foreach(i;0..n)
            foreach(j;0..n)
                t += d[i][j];
        writeln(t);
    }
}

#!/usr/bin/env rdmd
import std.stdio, std.string, std.conv;
import std.algorithm, std.array;

void main()
{
    for(string S; (S=readln().chomp()).length; )
    {
        auto nm = S.split().map!(to!int)();
        auto n=nm[0], m=nm[1];
        auto d = new int[][](n,n);
        foreach(i;0..m)
        {
            auto abc = readln().split().map!(to!int)();
            d[abc[0]][abc[1]]=abc[2];
        }
        foreach(k;0..n)
            foreach(i;0..n)
                foreach(j;0..n)
                {
                    auto c = min(d[i][k],d[k][j]);
                    d[i][j] += c;
                    d[i][k] -= c;
                    d[k][j] -= c;
                }
        auto t = 0;
        foreach(i;0..n)
            foreach(j;0..n)
                t += d[i][j];
        writeln(t);
    }
}


You're given an array $$$a$$$ of $$$n$$$ integers, such that $$$a_1 + a_2 + \cdots + a_n = 0$$$.In one operation, you can choose two different indices $$$i$$$ and $$$j$$$ ($$$1 \le i, j \le n$$$), decrement $$$a_i$$$ by one and increment $$$a_j$$$ by one. If $$$i < j$$$ this operation is free, otherwise it costs one coin.How many coins do you have to spend in order to make all elements equal to $$$0$$$?

Each test contains multiple test cases. The first line contains the number of test cases $$$t$$$ ($$$1 \le t \le 5000$$$). Description of the test cases follows. The first line of each test case contains an integer $$$n$$$ ($$$1 \le n \le 10^5$$$)  — the number of elements. The next line contains $$$n$$$ integers $$$a_1, \ldots, a_n$$$ ($$$-10^9 \le a_i \le 10^9$$$). It is given that $$$\sum_{i=1}^n a_i = 0$$$. It is guaranteed that the sum of $$$n$$$ over all test cases does not exceed $$$10^5$$$.

For each test case, print the minimum number of coins we have to spend in order to make all elements equal to $$$0$$$.

NotePossible strategy for the first test case:   Do $$$(i=2, j=3)$$$ three times (free), $$$a = [-3, 2, 0, 1]$$$.  Do $$$(i=2, j=1)$$$ two times (pay two coins), $$$a = [-1, 0, 0, 1]$$$.  Do $$$(i=4, j=1)$$$ one time (pay one coin), $$$a = [0, 0, 0, 0]$$$.

// Vicfred
// https://codeforces.com/contest/1405/problem/B
// greedy
import std.algorithm;
import std.array;
import std.conv;
import std.stdio;
import std.string;

void main() {
    int t = readln.chomp.to!int;

    while(t--) {
        int n = readln.chomp.to!int;
        long[] a = readln.split.map!(to!long).array;

        long ans = long.max;
        long sum = 0;
        foreach(x; a) {
            sum += x;
            ans = min(ans, sum);
        }

        writefln("%s", -ans);
    }
}

// Cheese-Cracker: cheese-cracker.github.io
import std.stdio, std.conv, std.functional, std.string, std.algorithm, std.array, std.container, std.range, std.typecons, std.bigint, std.numeric, std.math, std.random;

alias ll = long;
int inz(long t){ return to!int(t); }
static string[] tempstr;
T rd(T = long)() { while(!tempstr.length) tempstr = readln.chomp.split; string res = tempstr[0]; tempstr.popFront; return res.to!T; }
T[] rdarr(T = long)(T fix = 0) { auto r = readln.chomp.split.to!(T[]); r[] += fix; return r; }

void play(){
    int n;
    n = to!int(rd);
    ll[] arr;
    arr = rdarr;
    auto set = redBlackTree!(Tuple!(ll, ll));
    foreach(i; 0..n){
        auto t = tuple(arr[i], to!long(i));
        set.insert(t);
    }
    ll cost = 0;
    ll posmon = 0;
    foreach(i; 0..n){
        auto t = tuple(arr[i], to!long(i));
        set.removeKey(t);
        if(arr[i] < 0 && posmon > 0){
            ll take = min(posmon, - arr[i]);
            posmon -= take;
            arr[i] += take;
        }
        cost -= min(arr[i], 0);
        posmon += max(arr[i], 0);
    }
    writeln(cost);
}

int main(){
    ll t = 1;
    t = rd;        // Toggle!
    while(t--) play();  // Let's play!
    stdout.flush;
    return 0;
}

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

string FMT_F = "%.10f";

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

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

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

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

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

		long cnt;
		foreach (i; 0..n)
		{
			cnt += a[i];
			if (cnt < 0)
			{
				ans[ti] += abs(cnt);
				cnt = 0;
			}
		}
	}

	foreach (e; ans)
		writeln(e);
	stdout.flush;
	debug readln;
}


You are given a ternary string (it is a string which consists only of characters '0', '1' and '2').You can swap any two adjacent (consecutive) characters '0' and '1' (i.e. replace "01" with "10" or vice versa) or any two adjacent (consecutive) characters '1' and '2' (i.e. replace "12" with "21" or vice versa).For example, for string "010210" we can perform the following moves:   "010210" $$$\rightarrow$$$ "100210";  "010210" $$$\rightarrow$$$ "001210";  "010210" $$$\rightarrow$$$ "010120";  "010210" $$$\rightarrow$$$ "010201". Note than you cannot swap "02" $$$\rightarrow$$$ "20" and vice versa. You cannot perform any other operations with the given string excluding described above.You task is to obtain the minimum possible (lexicographically) string by using these swaps arbitrary number of times (possibly, zero).String $$$a$$$ is lexicographically less than string $$$b$$$ (if strings $$$a$$$ and $$$b$$$ have the same length) if there exists some position $$$i$$$ ($$$1 \le i \le |a|$$$, where $$$|s|$$$ is the length of the string $$$s$$$) such that for every $$$j < i$$$ holds $$$a_j = b_j$$$, and $$$a_i < b_i$$$.

The first line of the input contains the string $$$s$$$ consisting only of characters '0', '1' and '2', its length is between $$$1$$$ and $$$10^5$$$ (inclusive).

Print a single string — the minimum possible (lexicographically) string you can obtain by using the swaps described above arbitrary number of times (possibly, zero).

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

void main() {
    auto S = readln.chomp;
    auto N = S.length.to!int;
    string A = "";
    string B = "";

    foreach (i; 0..N) {
        if (S[i] == '1') A ~= S[i];
        else B ~= S[i];
    }

    if (B.empty) {
        A.writeln;
        return;
    }

    int x = B.length.to!int;
    foreach (i; 0..B.length.to!int) {
        if (B[i] == '2') {
            x = i;
            break;
        }
    }

    writeln(B[0..x] ~ A ~ B[x..$]);
}

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

void main()
{
    auto s = readln.chomp;

    auto ones = s.count!(x => x == '1');

    auto left = s.filter!(x => x != '1').array;

    debug { left.writeln; }

    auto parts = left.findSplitBefore("2");

    debug { parts.each!writeln; }

    auto ans = parts[0] ~ (cast(dchar)'1').repeat(ones).array ~ parts[1];

    ans.writeln;
}

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

void main() {
    dchar[] s = readln.chomp.to!(dchar[]);
    int n = s.length.to!int;

    int cnt;
    foreach (i ; 0 .. n) {
        if (s[i] == '1') cnt++;
    }

    foreach (i ; 0 .. n) {
        if (s[i] == '0') {
            write('0');
        }
        else if (s[i] == '1') {
            continue;
        }
        else {
            while (cnt > 0) {
                write('1');
                cnt--;
            }
            write('2');
        }
    }

    while (cnt > 0) {
        write('1');
        cnt--;
    }

    writeln;
}

void scan(T...)(ref T args) {
    import std.stdio : readln;
    import std.algorithm : splitter;
    import std.conv : to;
    import std.range.primitives;

    auto line = readln().splitter();
    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.string, std.conv;
import std.range, std.algorithm, std.array, std.typecons, std.container;
import std.math, std.numeric, core.bitop;

void main() {
    dchar[] s = readln.chomp.to!(dchar[]);
    int n = s.length.to!int;

    int l, r;

    while (l < n) {
        while (r < n && s[r] != '0') {
            r++;
        }
        s[l..r].sort();
        r++;
        l = r;
    }

    debug {
        writeln(s);
    }

    l = r = 0;

    while (l < n) {
        while (r < n && s[r] != '2') {
            r++;
        }
        s[l..r].sort();
        r++;
        l = r;
    }

    writeln(s);
}

void scan(T...)(ref T args) {
    import std.stdio : readln;
    import std.algorithm : splitter;
    import std.conv : to;
    import std.range.primitives;

    auto line = readln().splitter();
    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);
        }
    }
}


You are given n numbers a1, a2, ..., an. You can perform at most k operations. For each operation you can multiply one of the numbers by x. We want to make  as large as possible, where  denotes the bitwise OR. Find the maximum possible value of  after performing at most k operations optimally.

The first line contains three integers n, k and x (1 ≤ n ≤ 200 000, 1 ≤ k ≤ 10, 2 ≤ x ≤ 8). The second line contains n integers a1, a2, ..., an (0 ≤ ai ≤ 109).

Output the maximum value of a bitwise OR of sequence elements after performing operations.

NoteFor the first sample, any possible choice of doing one operation will result the same three numbers 1, 1, 2 so the result is . For the second sample if we multiply 8 by 3 two times we'll get 72. In this case the numbers will become 1, 2, 4, 72 so the OR value will be 79 and is the largest possible result.

import std.stdio, std.string;

void solve(int[] a, int k, int x)
{
    auto n = cast(int)a.length;
    auto f = new long[n];
    auto b = new long[n];
    f[0] = 0;
    foreach (i; 1 .. n)
    {
        f[i] = f[i - 1] | a[i - 1];
    }
    b[n - 1] = 0;
    for (int i = n - 2; i >= 0; -- i)
    {
        b[i] = b[i + 1] | a[i + 1];
    }
    long ans = 0;
    foreach (i; 0 .. n)
    {
        long val = a[i];
        foreach (j; 0 .. k)
        {
            val *= x;
        }
        val |= f[i];
        val |= b[i];
        if (val > ans)
        {
            ans = val;
        }
    }
    writeln(ans);
}

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

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

immutable int INF = 10L ^^ 9 + 23;

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

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

    auto orr = new int[][] (n, 2);

    foreach (i, e; arr) {
        orr[i][0] = i == 0 ? e : orr[i-1][0] | e;
    }
    foreach_reverse (i, e; arr) {
        orr[i][1] = i == n-1 ? e : orr[i+1][1] | e;
    }

    long m = pow(x, k);
    long ans = 0;
    foreach (i, e; arr) {
        long val = m * e;
        int leor = i == 0 ? 0 : orr[i-1][0];
        int ror = i == n-1 ? 0 : orr[i+1][1];
        ans = max(ans, leor | val | ror);
    }

    ans.writeln;
}


You are given a sequence of $$$n$$$ integers $$$a_1, a_2, \ldots, a_n$$$.You have to construct two sequences of integers $$$b$$$ and $$$c$$$ with length $$$n$$$ that satisfy:  for every $$$i$$$ ($$$1\leq i\leq n$$$) $$$b_i+c_i=a_i$$$  $$$b$$$ is non-decreasing, which means that for every $$$1<i\leq n$$$, $$$b_i\geq b_{i-1}$$$ must hold  $$$c$$$ is non-increasing, which means that for every $$$1<i\leq n$$$, $$$c_i\leq c_{i-1}$$$ must hold You have to minimize $$$\max(b_i,c_i)$$$. In other words, you have to minimize the maximum number in sequences $$$b$$$ and $$$c$$$.Also there will be $$$q$$$ changes, the $$$i$$$-th change is described by three integers $$$l,r,x$$$. You should add $$$x$$$ to $$$a_l,a_{l+1}, \ldots, a_r$$$. You have to find the minimum possible value of $$$\max(b_i,c_i)$$$ for the initial sequence and for sequence after each change.

The first line contains an integer $$$n$$$ ($$$1\leq n\leq 10^5$$$). The secound line contains $$$n$$$ integers $$$a_1,a_2,\ldots,a_n$$$ ($$$1\leq i\leq n$$$, $$$-10^9\leq a_i\leq 10^9$$$). The third line contains an integer $$$q$$$ ($$$1\leq q\leq 10^5$$$). Each of the next $$$q$$$ lines contains three integers $$$l,r,x$$$ ($$$1\leq l\leq r\leq n,-10^9\leq x\leq 10^9$$$), desribing the next change.

Print $$$q+1$$$ lines. On the $$$i$$$-th ($$$1 \leq i \leq q+1$$$) line, print the answer to the problem for the sequence after $$$i-1$$$ changes.

NoteIn the first test:  The initial sequence $$$a = (2, -1, 7, 3)$$$. Two sequences $$$b=(-3,-3,5,5),c=(5,2,2,-2)$$$ is a possible choice.  After the first change $$$a = (2, -4, 4, 0)$$$. Two sequences $$$b=(-3,-3,5,5),c=(5,-1,-1,-5)$$$ is a possible choice.  After the second change $$$a = (2, -4, 6, 2)$$$. Two sequences $$$b=(-4,-4,6,6),c=(6,0,0,-4)$$$ is a possible choice.

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

void main ()
{
	int n;
	while (readf !(" %s") (n) > 0)
	{
		readln;
		auto a = readln.splitter.map !(to !(int)).array;
		long start = a[0];
		long [] d;
		foreach (i; 1..n)
		{
			d ~= a[i] - a[i - 1];
		}

		long up = 0;
		foreach (ref y; d)
		{
			up += max (y, 0L);
		}
		writeln ((start + up + 1) >> 1);

		int q;
		readf !(" %s") (q);
		foreach (p; 0..q)
		{
			int l, r, x;
			readf !(" %s %s %s") (l, r, x);
			l -= 1;
			r -= 1;
			if (l == 0)
			{
				start += x;
			}
			if (l > 0)
			{
				up -= max (d[l - 1], 0L);
				d[l - 1] += x;
				up += max (d[l - 1], 0L);
			}
			if (r < n - 1)
			{
				up -= max (d[r], 0L);
				d[r] -= x;
				up += max (d[r], 0L);
			}
			writeln ((start + up + 1) >> 1);
		}
	}
}

import std.algorithm, std.conv, std.range, std.stdio, std.string;
void main () {
	auto n = readln.strip.to !(int), a = readln.split.map !(to !(int)).array, s = a[0] + 1L;
	long [] d;
	foreach (i; 1..n) d ~= a[i] - a[i - 1];
	foreach (ref y; d) s += max (y, 0);
	writeln (s >> 1);
	auto q = readln.strip.to !(int);
	foreach (p; 0..q) {
		int l, r, x;
		readf !(" %s %s %s") (l, r, x);
		if (l > 1) {
			l -= 2;
			s -= max (d[l], 0);
			d[l] += x;
			s += max (d[l], 0);
		}
		else s += x;
		if (r < n) {
			r -= 1;
			s -= max (d[r], 0);
			d[r] -= x;
			s += max (d[r], 0);
		}
		writeln (s >> 1);
	}
}

import std.algorithm, std.conv, std.range, std.stdio, std.string;
void main () {
	auto n = readln.strip.to !(int), a = readln.split.map !(to !(int)).array, s = a[0] + 1L;
	long [] d;
	foreach (i; 1..n) d ~= a[i] - a[i - 1];
	foreach (ref y; d) s += max (y, 0);
	writeln (s >> 1);
	auto q = readln.strip.to !(int);
	foreach (p; 0..q) {
		int l, r, x;
		readf !(" %s %s %s") (l, r, x);
		if (l > 0) {
			l -= 2;
			s -= max (d[l], 0);
			d[l] += x;
			s += max (d[l], 0);
		}
		else s += x;
		if (r < n) {
			r -= 1;
			s -= max (d[r], 0);
			d[r] -= x;
			s += max (d[r], 0);
		}
		writeln (s >> 1);
	}
}


Vladik was bored on his way home and decided to play the following game. He took n cards and put them in a row in front of himself. Every card has a positive integer number not exceeding 8 written on it. He decided to find the longest subsequence of cards which satisfies the following conditions:  the number of occurrences of each number from 1 to 8 in the subsequence doesn't differ by more then 1 from the number of occurrences of any other number. Formally, if there are ck cards with number k on them in the subsequence, than for all pairs of integers  the condition |ci - cj| ≤ 1 must hold.  if there is at least one card with number x on it in the subsequence, then all cards with number x in this subsequence must form a continuous segment in it (but not necessarily a continuous segment in the original sequence). For example, the subsequence [1, 1, 2, 2] satisfies this condition while the subsequence [1, 2, 2, 1] doesn't. Note that [1, 1, 2, 2] doesn't satisfy the first condition. Please help Vladik to find the length of the longest subsequence that satisfies both conditions.

The first line contains single integer n (1 ≤ n ≤ 1000) — the number of cards in Vladik's sequence. The second line contains the sequence of n positive integers not exceeding 8 — the description of Vladik's sequence.

Print single integer — the length of the longest subsequence of Vladik's sequence that satisfies both conditions.

NoteIn the first sample all the numbers written on the cards are equal, so you can't take more than one card, otherwise you'll violate the first condition.

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

int search(int target, int[] pos, int dist)
{
    auto left = 0, right = cast(int)pos.length;
    auto idx = -1;
    while (left <= right)
    {
        auto mid = (left + right) >> 1;
        if (pos[mid] == target)
        {
            idx = mid;
            break;
        }
        else if (pos[mid] < target)
        {
            left = mid + 1;
        }
        else
        {
            right = mid - 1;
        }
    }
    if (idx + dist - 1 < cast(int)pos.length)
    {
        return pos[idx + dist - 1] + 1;
    }
    return -1;
}

int saiki(int idx, int mask, int dist, int n, int[] a, int[][] dp, int[][] jump)
{
    if (dp[idx][mask] != -1)
    {
        return dp[idx][mask];
    }
    if (idx == n || mask == 255)
    {
        dp[idx][mask] = int.min;
        if (dist == 0 || mask == 255)
        {
            dp[idx][mask] = 0;
        }
        return dp[idx][mask];
    }
    auto res = saiki(idx + 1, mask, dist, n, a, dp, jump);
    if ((mask & (1 << a[idx])) == 0)
    {
        if (dist > 0 && jump[idx][dist] != -1)
        {
            auto ret = saiki(jump[idx][dist], mask | (1 << a[idx]), dist, n, a, dp, jump);
            if (ret != int.min)
            {
                res = max(res, ret + dist);
            }
        }
        if (jump[idx][dist + 1] != -1)
        {
            auto ret = saiki(jump[idx][dist + 1], mask | (1 << a[idx]), dist, n, a, dp, jump);
            if (ret != int.min)
            {
                res = max(res, ret + dist + 1);
            }
        }
    }
    dp[idx][mask] = res;
    return res;
}

void solve(int[] a, int n)
{
    auto bound = n >> 3;
    if ((bound << 3) != n)
    {
        ++ bound;
    }
    auto jump = new int[][](n, bound + 1);
    auto pos = new int[][8];
    foreach (i; 0 .. n)
    {
        pos[a[i]] ~= i;
    }
    foreach (i; 1 .. bound + 1)
    {
        foreach (j; 0 .. n)
        {
            auto idx = search(j, pos[a[j]], i);
            jump[j][i] = idx;
        }
    }
    auto dp = new int[][](n + 1, 256);
    auto res = 0;
    foreach (i; 0 .. bound)
    {
        foreach (j; 0 .. n + 1)
        {
            fill(dp[j], -1);
        }
        auto ret = saiki(0, 0, i, n, a, dp, jump);
        res = max(res, ret);
    }
    writeln(res);
}

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

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

int search(int target, int[] pos, int dist)
{
    auto left = 0, right = cast(int)pos.length;
    auto idx = -1;
    while (left <= right)
    {
        auto mid = (left + right) >> 1;
        if (pos[mid] == target)
        {
            idx = mid;
            break;
        }
        else if (pos[mid] < target)
        {
            left = mid + 1;
        }
        else
        {
            right = mid - 1;
        }
    }
    if (idx + dist - 1 < cast(int)pos.length)
    {
        return pos[idx + dist - 1] + 1;
    }
    return -1;
}

int saiki(int idx, int mask, int dist, int n, int[] a, int[][] dp, int[][] jump)
{
    if (dp[idx][mask] != -1)
    {
        return dp[idx][mask];
    }
    if (idx == n || mask == 255)
    {
        dp[idx][mask] = int.min;
        if (dist == 0 || mask == 255)
        {
            dp[idx][mask] = 0;
        }
        return dp[idx][mask];
    }
    auto res = saiki(idx + 1, mask, dist, n, a, dp, jump);
    if ((mask & (1 << a[idx])) == 0)
    {
        if (dist > 0 && jump[idx][dist] != -1)
        {
            auto ret = saiki(jump[idx][dist], mask | (1 << a[idx]), dist, n, a, dp, jump);
            if (ret != int.min)
            {
                res = max(res, ret + dist);
            }
        }
        if (dist + 1 + dist * 7 <= n && jump[idx][dist + 1] != -1)
        {
            auto ret = saiki(jump[idx][dist + 1], mask | (1 << a[idx]), dist, n, a, dp, jump);
            if (ret != int.min)
            {
                res = max(res, ret + dist + 1);
            }
        }
    }
    dp[idx][mask] = res;
    return res;
}

void solve(int[] a, int n)
{
    auto bound = n >> 3;
    auto jump = new int[][](n, bound + 2);
    auto pos = new int[][8];
    foreach (i; 0 .. n)
    {
        pos[a[i]] ~= i;
    }
    foreach (i; 1 .. bound + 1)
    {
        foreach (j; 0 .. n)
        {
            auto idx = search(j, pos[a[j]], i);
            jump[j][i] = idx;
        }
    }
    auto dp = new int[][](n + 1, 256);
    auto res = 0;
    foreach (i; 0 .. bound + 1)
    {
        foreach (j; 0 .. n + 1)
        {
            fill(dp[j], -1);
        }
        auto ret = saiki(0, 0, i, n, a, dp, jump);
        res = max(res, ret);
    }
    writeln(res);
}

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


Ksusha the Squirrel is standing at the beginning of a straight road, divided into n sectors. The sectors are numbered 1 to n, from left to right. Initially, Ksusha stands in sector 1. Ksusha wants to walk to the end of the road, that is, get to sector n. Unfortunately, there are some rocks on the road. We know that Ksusha hates rocks, so she doesn't want to stand in sectors that have rocks.Ksusha the squirrel keeps fit. She can jump from sector i to any of the sectors i + 1, i + 2, ..., i + k. Help Ksusha! Given the road description, say if she can reach the end of the road (note, she cannot stand on a rock)?

The first line contains two integers n and k (2 ≤ n ≤ 3·105, 1 ≤ k ≤ 3·105). The next line contains n characters — the description of the road: the i-th character equals ".", if the i-th sector contains no rocks. Otherwise, it equals "#". It is guaranteed that the first and the last characters equal ".".

Print "YES" (without the quotes) if Ksusha can reach the end of the road, otherwise print "NO" (without the quotes).

module _template;
import std.stdio;
import std.string;
import std.algorithm;
import std.container;
import std.range;
import std.math;
import std.numeric;
import std.conv;
import std.typecons;
import std.format;

struct IO {
        string[] tk;
        string readString() {
                while (tk.empty)
                        tk = readln.split;
                auto tkt = tk.front;
                tk.popFront;
                return tkt;
        }
        int readInt() {
                return readString.to!int;
        }
        double readDouble() {
                return readString.to!double;
        }
}

void main() {
        IO cin;
        int t = 1;
        // t = cin.readInt;
        while (t--) {
                int n = cin.readInt;
                int k = cin.readInt;
                string s = cin.readString;
                int count = 0;
                bool fail = false;
                for (int i = 0; i < n; i++) {
                        count = s[i] == '#' ? count + 1 : 0;
                        if (count >= k) fail = true;
                }
                writeln(fail ? "NO" : "YES");
        }
}

import std.stdio;
import std.exception;
import std.algorithm;
import std.math;
import std.typecons;

void main(){
	int n, m;
	string s;
	readf("%d %d\n%s\n", &n, &m, &s);
	int k=0;
	string ans="YES";
	foreach(i; 0..n){
		if (s[i]=='#') k++;
		else{
			if (k>=m) ans="NO";
			k=0;
		}
	}
	writefln("%s", ans);
}


Keshi is throwing a party and he wants everybody in the party to be happy.He has $$$n$$$ friends. His $$$i$$$-th friend has $$$i$$$ dollars. If you invite the $$$i$$$-th friend to the party, he will be happy only if at most $$$a_i$$$ people in the party are strictly richer than him and at most $$$b_i$$$ people are strictly poorer than him.Keshi wants to invite as many people as possible. Find the maximum number of people he can invite to the party so that every invited person would be happy.

The first line contains a single integer $$$t$$$ $$$(1\le t\le 10^4)$$$ — the number of test cases. The description of the test cases follows. The first line of each test case contains a single integer $$$n$$$ $$$(1\le n\le 2 \cdot 10^5)$$$ — the number of Keshi's friends. The $$$i$$$-th of the following $$$n$$$ lines contains two integers $$$a_i$$$ and $$$b_i$$$ $$$(0 \le a_i, b_i < n)$$$. It is guaranteed that the sum of $$$n$$$ over all test cases doesn't exceed $$$2 \cdot 10^5$$$.

For each test case print the maximum number of people Keshi can invite.

NoteIn the first test case, he invites the first and the second person. If he invites all of them, the third person won't be happy because there will be more than $$$1$$$ person poorer than him.

immutable multi = true;

void solve(int tc)
{
	auto n = readInt!int;
	auto a = new int[](n);
	auto b = new int[](n);
	foreach(i; 0 .. n)
	{
		a[i] = readInt!int;
		b[i] = readInt!int;
	}
	bool can(int k)
	{
		int left = 0;
		int right = k - 1;
		int elems = 0;
		foreach(i; 0 .. n)
		{
			if (right <= a[i] && left <= b[i]) { left++, right--; elems++;}
		}
		return elems >= k;
	}
	int hi = n;
	int lo = 0;
	int ans = -1;
	while (lo <= hi)
	{
		int mi = (lo + hi)/2;
		if (can(mi))
		{
			ans = mi;
			lo = mi + 1;
		}
		else
		{
			hi = mi - 1;
		}
	}
	assert(ans != -1);
	return writeln(ans);
}

//{{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
//}}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
	{
		popChar;
	}
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
void writes(T...)(T t)
{
	static foreach(i, ti; t)
	{
		static if (isIterable!(T[i]))
		{
			foreach(e; ti)
			{
				write(e, " ");
			}
		}
	}
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}

// 提出解
void solve(){
	foreach(_; 0 .. scan!int){
		int n = scan!int;
		int[] as, bs;
		foreach(i; 0 .. n) as ~= scan!int, bs ~= scan!int;
		log("as:", as);
		log("bs:", bs);

		int calc(int k){
			int[] cs;
			foreach(i; 0 .. n) cs ~= k - 1 - as[i]; // 自分より貧乏な人数の下限
			int cnt;
			foreach(i; 0 .. n){
				if(cs[i] <= cnt && cnt <= bs[i]) cnt += 1;
			}
			log("k:", k, "cs:", cs, "cnt:", cnt);
			return cnt;
		}
		bool isOK(int k){
			return calc(k) >= k;
		}

		int ans = mid(1, n + 2, &isOK) - 1;
		ans.print;
	}
}

// ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- //
// 愚直解
void jury(){
}

// ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- //
// テストケース
void gen(){
}

// ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- //
// テンプレ
import std;
bool DEBUG = 0;
void main(string[] args){
	if(args.canFind("-debug")) DEBUG = 1;
	if(args.canFind("-gen")) gen; else if(args.canFind("-jury")) jury; else solve;
}
void log(A ...)(lazy A a){ if(DEBUG) print(a); }
void print(){ writeln(""); }
void print(T)(T t){ writeln(t); }
void print(T, A ...)(T t, A a){ stdout.write(t, " "), print(a); }
string unsplit(T)(T xs, string d = " "){ return xs.array.to!(string[]).join(d); }
string scan(){
	static string[] ss; while(!ss.length) ss = readln.chomp.split;
	string res = ss[0]; ss.popFront; return res;
}
T scan(T)(){ return scan.to!T; }
T[] scan(T)(int n){ return n.iota.map!(i => scan!T()).array; }
T mini(T)(ref T x, T y){ if(x > y) x = y; return x; }
T maxi(T)(ref T x, T y){ if(x < y) x = y; return x; }
T mid(T)(T l, T r, bool delegate(T) f){
	T m = (l + r) / 2; (f(m)? l: r) = m; return f(l)? f(r - 1)? r: mid(l, r, f): l;
}

// ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- //
// ライブラリ（基本）

class UnionFind{
	this(int n){ foreach(i; 0 .. n) R ~= i, K ~= [i]; } int[] R; int[][] K;
	void unite(int a, int b){
		int ra = R[a], rb = R[b]; if(ra == rb) return;
		if(K[ra].length < K[rb].length) unite(b, a);
		else foreach(k; K[rb]) R[k] = ra, K[ra] ~= k;
	}
	int find(int a){ return R[a]; }
	int getSize(int a){ return K[R[a]].length.to!int; }
}
class Queue(T){
	private T[] xs; private uint i, j;
	this(T[] xs = []){ this.xs = xs; j = xs.length.to!uint; }
	uint length(){ return j - i; }
	bool isEmpty(){ return j == i; }
	void enq(T x){ while(j + 1 >= xs.length) xs.length = xs.length * 2 + 1; xs[j ++] = x; }
	T deq(){ assert(i < j); return xs[i ++]; }
	T peek(){ assert(i < j); return xs[i]; }
	void flush(){ i = j; }
	alias empty = isEmpty, front = peek, popFront = deq, pop = deq, push = enq, top = peek;
	Queue opOpAssign(string op)(T x) if(op == "~"){ enq(x); return this; }
	T opIndex(uint li){ assert(i + li < j); return xs[i + li]; }
	static Queue!T opCall(T[] xs){ return new Queue!T(xs); }
	T[] array(){ return xs[i .. j]; }
	override string toString(){ return array.to!string; }
}
class Stack(T){
	private T[] xs; private uint j;
	this(T[] xs = []){ this.xs = xs; j = xs.length.to!uint; }
	uint length(){ return j; }
	bool isEmpty(){ return j == 0; }
	void push(T x){ while(j + 1 >= xs.length) xs.length = xs.length * 2 + 1; xs[j ++] = x; }
	T pop(){ assert(j > 0); return xs[-- j]; }
	T peek(){ assert(j > 0); return xs[j - 1]; }
	void clear(){ j = 0; }
	alias empty = isEmpty, front = peek, popFront = pop, top = peek;
	Stack opOpAssign(string op)(T x) if(op == "~"){ push(x); return this; }
	T opIndex(uint li){ assert(j > 0 && j - 1 >= li); return xs[j - 1 - li]; }
	static Stack!T opCall(T[] xs = []){ return new Stack!T(xs); }
	T[] array(){ return xs[0 .. j]; }
	override string toString(){ return array.to!string; }
}

// ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- //
// ライブラリ（追加）

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

string FMT_F = "%.10f";

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

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

void chmin(T)(ref T x, T y) { x = min(x, y); } void chmax(T)(ref T x, T y) { x = max(x, y); }
bool inside(T)(T x, T b, T e) { return x >= b && x < e; }
T lcm(T)(T x, T y) { return x * (y / gcd(x, y)); }
double[] rotate(double[] vec, double rad) { return [cos(rad)*vec[0] - sin(rad)*vec[1], sin(rad)*vec[0] + cos(rad)*vec[1]]; }
double norm(double[] vec) { return sqrt(reduce!((a,b)=>a+b*b)(0.0, vec)); }
double dotProd(double[] a, double[] b) { auto r = a.dup; r[] *= b[]; return r.sum; }

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

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

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

		bool f(long x)
		{
			long cnt;
			foreach (i; 0..n)
			{
				if (cnt > b[i]) continue;
				if (x-cnt-1 > a[i]) continue;
				++cnt;
				if (cnt == x) break;
			}
			return cnt == x;
		}
		ans[ti] = binarySearch!(f)(0, n+1);
	}

	foreach (e; ans)
	{
		writeln(e);
	}
	stdout.flush;
	debug readln;
}

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

void main ()
{
	auto tests = readln.strip.to !(int);
	foreach (test; 0..tests)
	{
		int n;
		readf !(" %s") (n);
		auto a = new int [n];
		auto b = new int [n];
		foreach (i; 0..n)
		{
			readf !(" %s %s") (a[i], b[i]);
		}

		bool ok (int lim)
		{
			int down = 0;
			int up = lim - 1;
			foreach (i; 0..n)
			{
				if (b[i] >= down && a[i] >= up)
				{
					down += 1;
					up -= 1;
					if (up < 0)
					{
						return true;
					}
				}
			}
			return false;
		}

		int lo = 1;
		int hi = n + 1;
		while (hi - lo > 1)
		{
			int me = (lo + hi) / 2;
			if (ok (me))
			{
				lo = me;
			}
			else
			{
				hi = me;
			}
		}
		writeln (lo);
	}
}

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

void main() {
  try {
    for (; ; ) {
      const numCases = readInt();
      foreach (caseId; 0 .. numCases) {
        const N = readInt();
        auto A = new int[N];
        auto B = new int[N];
        foreach (i; 0 .. N) {
          A[i] = readInt();
          B[i] = readInt();
        }

        bool check(int k) {
          int now;
          foreach (i; 0 .. N) {
            if (now <= B[i] && k - 1 - now <= A[i]) {
              ++now;
            }
          }
          return (now >= k);
        }

        int lo = 0, hi = N + 1;
        for (; lo + 1 < hi; ) {
          const mid = (lo + hi) / 2;
          (check(mid) ? lo : hi) = mid;
        }
        writeln(lo);
      }
    }
  } catch (EOFException e) {
  }
}


Vladimir wants to modernize partitions in his office. To make the office more comfortable he decided to remove a partition and plant several bamboos in a row. He thinks it would be nice if there are n bamboos in a row, and the i-th from the left is ai meters high. Vladimir has just planted n bamboos in a row, each of which has height 0 meters right now, but they grow 1 meter each day. In order to make the partition nice Vladimir can cut each bamboo once at any height (no greater that the height of the bamboo), and then the bamboo will stop growing.Vladimir wants to check the bamboos each d days (i.e. d days after he planted, then after 2d days and so on), and cut the bamboos that reached the required height. Vladimir wants the total length of bamboo parts he will cut off to be no greater than k meters.What is the maximum value d he can choose so that he can achieve what he wants without cutting off more than k meters of bamboo?

The first line contains two integers n and k (1 ≤ n ≤ 100, 1 ≤ k ≤ 1011) — the number of bamboos and the maximum total length of cut parts, in meters. The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 109) — the required heights of bamboos, in meters.

Print a single integer — the maximum value of d such that Vladimir can reach his goal.

NoteIn the first example Vladimir can check bamboos each 3 days. Then he will cut the first and the second bamboos after 3 days, and the third bamboo after 6 days. The total length of cut parts is 2 + 0 + 1 = 3 meters.

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

void main() {
  try {
    for (; ; ) {
      const N = readInt();
      const K = readLong();
      auto A = new long[N];
      foreach (i; 0 .. N) {
        A[i] = readLong();
      }

      long[] ds;
      foreach (i; 0 .. N) {
        for (long x = 1, y; x <= A[i]; x = y) {
          // [x, y): d
          const d = (A[i] + x - 1) / x;
          y = (d <= 1) ? (A[i] + 1) : ((A[i] + (d - 1) - 1) / (d - 1));
          ds ~= d;
          debug {
            assert(x < y);
            assert((A[i] + x - 1) / x == d);
            assert((A[i] + (y - 1) - 1) / (y - 1) == d);
          }
        }
      }
      ds = ds.sort.uniq.array;
      debug {
        writeln("ds = ", ds);
      }

      bool check(long d) {
        long sum;
        foreach (i; 0 .. N) {
          sum += (A[i] + d - 1) / d * d - A[i];
          if (sum > K) {
            return false;
          }
        }
        return true;
      }

      const dsLen = cast(int)(ds.length);
      ds ~= ds[dsLen - 1] + K + 1;
      long ans;
      foreach_reverse (j; 0 .. dsLen) {
        if (check(ds[j])) {
          long lo = ds[j], hi = ds[j + 1];
          for (; lo + 1 < hi; ) {
            const mid = (lo + hi) / 2;
            (check(mid) ? lo : hi) = mid;
          }
          ans = lo;
          break;
        }
      }
      writeln(ans);
    }
  } catch (EOFException e) {
  }
}