Petya and Gena love playing table tennis. A single match is played according to the following rules: a match consists of multiple sets, each set consists of multiple serves. Each serve is won by one of the players, this player scores one point. As soon as one of the players scores t points, he wins the set; then the next set starts and scores of both players are being set to 0. As soon as one of the players wins the total of s sets, he wins the match and the match is over. Here s and t are some positive integer numbers.To spice it up, Petya and Gena choose new numbers s and t before every match. Besides, for the sake of history they keep a record of each match: that is, for each serve they write down the winner. Serve winners are recorded in the chronological order. In a record the set is over as soon as one of the players scores t points and the match is over as soon as one of the players wins s sets.Petya and Gena have found a record of an old match. Unfortunately, the sequence of serves in the record isn't divided into sets and numbers s and t for the given match are also lost. The players now wonder what values of s and t might be. Can you determine all the possible options?

The first line contains a single integer n — the length of the sequence of games (1 ≤ n ≤ 105). The second line contains n space-separated integers ai. If ai = 1, then the i-th serve was won by Petya, if ai = 2, then the i-th serve was won by Gena. It is not guaranteed that at least one option for numbers s and t corresponds to the given record.

In the first line print a single number k — the number of options for numbers s and t. In each of the following k lines print two integers si and ti — the option for numbers s and t. Print the options in the order of increasing si, and for equal si — in the order of increasing ti.

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

const int MAX = 100005;
int n;
int[MAX] a;
int[MAX] f1, f2, pos1, pos2;
Tuple!(int,int)[MAX] ans;

void main() {
    readf(" %s", n);
    foreach(i; 0..n) readf(" %s", a[i]);

    int c1, c2;
    foreach(i; 0..n) {
        f1[i] = c1-1;
        f2[i] = c2-1;
        if (a[i] == 1) {
            pos1[c1++] = i;
        } else {
            pos2[c2++] = i;
        }
    }

    int numOfAns = 0;

match:
    foreach_reverse(t; 1..n+1) {
        int i = 0;
        int win1, win2;
        while (i < n) {
            int end1 = f1[i] + t < c1 ? pos1[f1[i] + t] : n;
            int end2 = f2[i] + t < c2 ? pos2[f2[i] + t] : n;
            int nextEnd = min(end1, end2);
            if (nextEnd >= n) {
                continue match;
            }
            i = nextEnd + 1;
            if (end1 < end2) {
                win1++;
            } else {
                win2++;
            }
        }
        if ((win1 < win2 && a[n-1] == 2) || (win1 > win2 && a[n-1] == 1))
            ans[numOfAns++] = tuple(max(win1, win2), t);
    }

    ans[0..numOfAns].sort!((x, y) => (x[0] == y[0]) ? x[1] < y[1] : x[0] < y[0]);

    writeln(numOfAns);
    foreach(x; ans[0..numOfAns]) writeln(x[0], " ", x[1]);
}

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;
import std.traits;
import std.variant;
import std.concurrency;

void main(string[] args)
{
  auto n = next!int;
  auto a = next!int(n);
  auto pos1 = new int[](n + 1); pos1[] = -1;
  auto pos2 = new int[](n + 1); pos2[] = -1;
  auto cnt1 = new int[](n);
  auto cnt2 = new int[](n);
  foreach(i, ai; a)
    {
      if (i != 0)
	{
	  cnt1[i] = cnt1[i - 1];
	  cnt2[i] = cnt2[i - 1];
	}
      if (ai == 1)
	{
	  cnt1[i]++;
	  pos1[cnt1[i]] = cast(int) i;
	}
      else
	{
	  cnt2[i]++;
	  pos2[cnt2[i]] = cast(int) i;
	}
    }
  foreach(ref c; pos1) if (c == -1) c = n;
  foreach(ref c; pos2) if (c == -1) c = n;
  auto options = new Tuple!(int, int)[](0);
  debug writeln("pos1 = ", pos1);
  debug writeln("pos2 = ", pos2);
 sTest: foreach(s; 1 .. n + 1)
    {
      debug writeln("trying for s = ", s);
      int i = void;
      int ni = void;
      int sets1 = 0;
      int sets2 = 0;
      int next1 = pos1[s];
      int next2 = pos2[s];
      if (next1 < next2)
	{
	  i = next1;
	  sets1++;
	}
      else
	{
	  i = next2;
	  sets2++;
	}
      while (i < n)
	{
	  debug writeln("in i = ", i, " sets1 = ", sets1, " sets2 = ", sets2);
	  if (i == n - 1)
	    {
	      if (sets1 == sets2)
		continue sTest;
	      if (sets1 > sets2)
		{
		  if (a[i] == 1)
		    options ~= tuple(sets1, s);
		}
	      else
		{
		  if (a[i] == 2)
		    options ~= tuple(sets2, s);
		}
	      continue sTest;
	    }

	  next1 = (cnt1[i] + s <= n)? pos1[cnt1[i] + s] : n;
	  next2 = (cnt2[i] + s <= n)? pos2[cnt2[i] + s] : n;
	  if (next1 < next2)
	    {
	      ni = next1;
	      sets1++;
	    }
	  else
	    {
	      ni = next2;
	      sets2++;
	    }

	  i = ni;
	}
    }
  auto soptions = sort(options);
  writeln(options.length);
  foreach(option; options)
    {
      writeln(option[0], " ", option[1]);
    }
}

static this()
{
  popChar;
}

struct Any(T)
{
  static auto read()
  {
    static if (is(T == char))
      {
	auto res = frontChar;
	popChar;
	return res;
      }
  }
}

struct Unsigned(T)
{
  auto read()
  {
    auto res = T(0);
    while(!frontChar.isDigit) popChar;
    do
      {
	res = res * T(10) + T(frontChar - '0');
	popChar;
      }
    while(frontChar.isDigit);
    return res;
  }
}

struct Matrix(T, alias rows, alias cols)
{
  T[][] _cell;
  alias _cell this;
  // Ring constructor
  this(int n)
  {
    final switch(n)
      {
      case 0:
	_cell = new T[][](rows, cols);
	break;
      case 1:
	debug assert(rows == cols);
	_cell = new T[][](rows, cols);
	foreach(i; 0 .. rows)
	  _cell[i][i] = T(1);
	break;
      }
  }
  // Copy constructor
  this(Matrix!(T, rows, cols) other)
  {
    _cell = new T[][](rows, cols);
    foreach(i; 0 .. rows)
      _cell[i][] = other[i][];
  }
  auto opBinary(string op)(Matrix!(T, rows, cols) other)
       if (op == "+" || op == "-")
	 {
	   auto res = Matrix!(T, rows, cols)(0);
	   foreach(i; 0 .. rows)
	     foreach(j; 0 .. cols)
	       res[i][j] = mixin(q{this[i][j]}, op, q{other[i][j]});
	   return res;
	 }
  auto opBinary(string op, alias otherRows, alias otherCols)(Matrix!(T, otherRows, otherCols) other)
       if (op == "*")
	 {
	   debug assert(cols == otherRows);
	   auto res = Matrix!(T, rows, otherCols)(0);
	   foreach(i; 0 .. rows)
	     foreach(k; 0 .. cols)
	       foreach(j; 0 .. otherCols)
		 res[i][j] += this[i][k] * other[k][j];
	   return res;
	 }
  ref auto opOpAssign(string op)(Matrix!(T, rows, cols) other)
  {
    static if (op == "*")
      {
	debug assert(rows == cols);
	alias n = rows;
	auto res = Matrix!(T, n, n)(0);
	T factor;
	foreach(i; 0 .. n)
	  foreach(k; 0 .. n)
	    foreach(j; 0 .. n)
	      res[i][j] += this[i][k] * other[k][j];
	foreach(i; 0 .. n)
	  this[i][] = res[i][];
      }
    else
      {
	foreach(i; 0 .. rows)
	  foreach(j; 0 .. cols)
	    mixin(q{this[i][j] }, text(op, q{=}), q{ other[i][j];});
      }
    return this;
  }
  mixin powMethod;
}

struct Mod(T, alias mod)
{
  alias This = Mod!(T, mod);
  T _rep;
  this(T t)
  {
    _rep = t % mod;
    if (_rep < 0) _rep += mod;
  }
  static auto plain(T t)
  {
    auto res = Mod!(T, mod)();
    res._rep = t;
    return res;
  }
  static auto fromPositive(T t)
  {
    pragma(inline, true);
    return Mod!(T, mod).plain(t % mod);
  }
  static auto fromNegative(T t)
  {
    pragma(inline, true);
    return Mod!(T, mod).plain(t % mod + mod);
  }
  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.plain(resrep);
      }
    else static if (op == "-")
      {
	T resrep = _rep - b._rep;
	if (resrep < 0) resrep += mod;
	return This.plain(resrep);
      }
    else static if (op == "*")
      {
	return This.fromPositive(_rep * b._rep);
      }
  }
  auto opOpAssign(string op)(This b)
  {
    mixin(q{_rep }, text(op, "="), q{b._rep;});
    static if (op == "+")
      {
	if (_rep >= mod) _rep -= mod;
      }
    else static if (op == "-")
      {
	if (_rep < 0) _rep += mod;
      }
    else static if (op == "*")
      {
	_rep %= mod;
      }
    return this;
  }

  auto opBinary(string op)(long exp)
       if (op == "^^")
	 {
	   return pow(exp);
	 }
  mixin powMethod;
}

mixin template powMethod()
{
  auto pow(this ThisType)(long exp)
    {
      auto res = ThisType(1);
      auto pow = ThisType(this);
      while(exp)
	{
	  if (exp & 1) res *= pow;
	  pow *= pow;
	  exp >>= 1;
	}
      return res;
    }
}
// INPUT
char frontChar;
void popChar()
{
  import core.stdc.stdio;
  frontChar = cast(char) getchar;
  if (feof(stdin)) frontChar = ' ';
}
auto makeArray(T, S...)(S s)
{
  enum brackets = () {
    string res;
    foreach(i; 0 .. s.length)
      res ~= "[]";
    return res;
  } ();
  mixin(q{alias Type = T}, brackets, q{;});
  return new Type(s);
}
template isNumberLike(T)
{
  enum isNumberLike = is(typeof((){T test; test = test + test * test; test *= test;}()));
}
void popWhite()
{
  import std.ascii;
  while (frontChar.isWhite) popChar;
}
void print(T...)(T t)
{
  static foreach(ti; t)
    {
      static if (is(typeof(ti) == string))
	{
	  write(ti, " ");
	}
      else static if (isArray!(typeof(ti)))
	{
	  foreach(e; ti) print(e);
	}
      else static if (isTuple!(typeof(ti)))
	{
	  static foreach(i; ti.length) writesp(ti[i]);
	}
      else
	{
	  write(ti, " ");
	}
    }
}
void println(T...)(T t)
{
  static if (t.length == 0)
    writeln;
  static foreach(ti; t)
    {
      print(ti);
      writeln;
    }
}
auto next(alias T, S...)(S s)
{
  pragma(inline, true);
  static if (s.length > 0)
    {
      auto res = makeArray!(typeof(next!T()))(s);
      S t;
      enum loops = () {
	string res;
	foreach(i; 0 .. s.length)
	  {
	    auto ti = text(q{t[}, i, q{]});
	    res ~= text(q{for(}, ti, q{ = 0;}, ti , q{ < s[}, i, q{];}, ti, q{++)});
	  }
	return res;
      } ();
      enum indexing = () {
	string res = "res";
	foreach(i; 0 .. s.length)
	  res ~= text(q{[t[}, i, q{]]});
	return res;
      } ();
      mixin(loops, indexing, q{ = next!T;});
      return res;
    }
  else
    {
      static if (isNumberLike!T)
	{
	  import std.ascii: isDigit;
	  T res;
	  while(frontChar.isWhite) popChar;
	  T multiplier = T(1);
	  if (frontChar == '-')
	    {
	      multiplier = T(-1);
	      popChar;
	    }
	  else if (frontChar == '+')
	    {
	      popChar;
	    }
	  debug assert(frontChar.isDigit);
	  do
	    {
	      res = res * T(10) + T(frontChar - '0');
	      popChar;
	    }
	  while(frontChar.isDigit);
	  return multiplier * res;
	}
      else static if (is(T == string))
	{
	  import std.ascii: isWhite;
	  string res;
	  while(frontChar.isWhite)
	    popChar;
	  while(!frontChar.isWhite)
	    {
	      res ~= frontChar;
	      popChar;
	    }
	  return res;
	}
      else static if (is(T == char))
	{
	  while(frontChar.isWhite) popChar;
	  auto res = frontChar;
	  popChar;
	  return res;
	}
      else
	{
	  return T.read;
	}
    }
}

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

void main ()
{
	int n;
	while (readf (" %s ", &n) > 0)
	{
		auto a = [0] ~ readln.split.map !(to !(int)).array;
		int [] sa = [0];
		foreach (i; 0..n)
		{
			sa ~= sa[i] + (a[i + 1] == 1);
		}
		sa ~= n * 10;
		int [] sb = [0];
		foreach (i; 0..n)
		{
			sb ~= sb[i] + (a[i + 1] == 2);
		}
		sb ~= n * 10;
		int [2] [] res;
		foreach (t; 1..n + 1)
		{
			int pos = 0;
			int ca = 0;
			int cb = 0;
			int last = 0;
			bool ok = true;
			while (pos < n)
			{
				int lo = pos - 1;
				int hi = n;
				while (lo < hi)
				{
					int me = ((lo + hi + 3) >> 1) - 1;
					if (sa[me + 1] - sa[pos] >= t ||
					    sb[me + 1] - sb[pos] >= t)
					{
						hi = me - 1;
					}
					else
					{
						lo = me;
					}
				}

				int next = lo + 1;
				if (sa[next + 1] - sa[pos] == t)
				{
					last = 1;
					ca++;
				}
				else if (sb[next + 1] - sb[pos] == t)
				{
					last = 2;
					cb++;
				}
				else
				{
					assert (next >= n);
					ok = false;
					break;
				}
				pos = next + 1;
			}

			ok &= (last == 1 && ca > cb) ||
			    (last == 2 && ca < cb);
			if (ok)
			{
				res ~= [max (ca, cb), t];
			}
		}

		sort (res);
		writeln (res.length);
		foreach (cur; res)
		{
			writeln (cur[0], ' ', cur[1]);
		}
	}
}

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

const int MAX = 100005;
int n;
int[MAX] a;
int[MAX] f1, f2, pos1, pos2;
Tuple!(int,int)[MAX] ans;

void main() {
    readf(" %s", n);
    foreach(i; 0..n) readf(" %s", a[i]);

    int c1, c2;
    foreach(i; 0..n) {
        f1[i] = c1-1;
        f2[i] = c2-1;
        if (a[i] == 1) {
            pos1[c1++] = i;
        } else {
            pos2[c2++] = i;
        }
    }

    int numOfAns = 0;

match:
    foreach_reverse(t; 1..n+1) {
        int i = 0;
        int win1, win2;
        while (i < n) {
            int end1 = f1[i] + t < c1 ? pos1[f1[i] + t] : n;
            int end2 = f2[i] + t < c2 ? pos2[f2[i] + t] : n;
            int nextEnd = min(end1, end2);
            if (nextEnd >= n) {
                continue match;
            }
            i = nextEnd + 1;
            if (end1 < end2) {
                win1++;
            } else {
                win2++;
            }
        }
        if (win1 != win2)
            ans[numOfAns++] = tuple(max(win1, win2), t);
    }

    writeln(numOfAns);
    foreach(x; ans[0..numOfAns]) writeln(x[0], " ", x[1]);
}

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

const int MAX = 100005;
int n;
int[MAX] a;
int[MAX] f1, f2, pos1, pos2;
Tuple!(int,int)[MAX] ans;

void main() {
    readf(" %s", n);
    foreach(i; 0..n) readf(" %s", a[i]);

    int c1, c2;
    foreach(i; 0..n) {
        f1[i] = c1-1;
        f2[i] = c2-1;
        if (a[i] == 1) {
            pos1[c1++] = i;
        } else {
            pos2[c2++] = i;
        }
    }

    int numOfAns = 0;

match:
    foreach_reverse(t; 1..n+1) {
        int i = 0;
        int win1, win2;
        while (i < n) {
            int end1 = f1[i] + t < c1 ? pos1[f1[i] + t] : n;
            int end2 = f2[i] + t < c2 ? pos2[f2[i] + t] : n;
            int nextEnd = min(end1, end2);
            if (nextEnd >= n) {
                continue match;
            }
            i = nextEnd + 1;
            if (end1 < end2) {
                win1++;
            } else {
                win2++;
            }
        }
        if ((win1 < win2 && a[n-1] == 2) || (win1 > win2 && a[n-1] == 1))
            ans[numOfAns++] = tuple(max(win1, win2), t);
    }

    writeln(numOfAns);
    foreach(x; ans[0..numOfAns]) writeln(x[0], " ", x[1]);
}

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;
import std.traits;
import std.variant;
import std.concurrency;

void main(string[] args)
{
  auto n = next!int;
  auto a = next!int(n);
  auto pos1 = new int[](n + 1); pos1[] = -1;
  auto pos2 = new int[](n + 1); pos2[] = -1;
  auto cnt1 = new int[](n);
  auto cnt2 = new int[](n);
  foreach(i, ai; a)
    {
      if (i != 0)
	{
	  cnt1[i] = cnt1[i - 1];
	  cnt2[i] = cnt2[i - 1];
	}
      if (ai == 1)
	{
	  cnt1[i]++;
	  pos1[cnt1[i]] = cast(int) i;
	}
      else
	{
	  cnt2[i]++;
	  pos2[cnt2[i]] = cast(int) i;
	}
    }
  foreach(ref c; pos1) if (c == -1) c = n;
  foreach(ref c; pos2) if (c == -1) c = n;
  auto options = new Tuple!(int, int)[](0);
  debug writeln("pos1 = ", pos1);
  debug writeln("pos2 = ", pos2);
 sTest: foreach(s; 1 .. n + 1)
    {
      debug writeln("trying for s = ", s);
      int i = void;
      int ni = void;
      int sets1 = 0;
      int sets2 = 0;
      int next1 = pos1[s];
      int next2 = pos2[s];
      if (next1 < next2)
	{
	  i = next1;
	  sets1++;
	}
      else
	{
	  i = next2;
	  sets2++;
	}
      while (i < n)
	{
	  debug writeln("in i = ", i, " sets1 = ", sets1, " sets2 = ", sets2);
	  if (i == n - 1)
	    {
	      if (sets1 == sets2)
		continue sTest;
	      options ~= tuple(max(sets1, sets2), s);
	      continue sTest;
	    }

	  next1 = (cnt1[i] + s <= n)? pos1[cnt1[i] + s] : n;
	  next2 = (cnt2[i] + s <= n)? pos2[cnt2[i] + s] : n;
	  if (next1 < next2)
	    {
	      ni = next1;
	      sets1++;
	    }
	  else
	    {
	      ni = next2;
	      sets2++;
	    }

	  i = ni;
	}
    }
  auto soptions = sort(options);
  writeln(options.length);
  foreach(option; options)
    {
      writeln(option[0], " ", option[1]);
    }
}

static this()
{
  popChar;
}

struct Any(T)
{
  static auto read()
  {
    static if (is(T == char))
      {
	auto res = frontChar;
	popChar;
	return res;
      }
  }
}

struct Unsigned(T)
{
  auto read()
  {
    auto res = T(0);
    while(!frontChar.isDigit) popChar;
    do
      {
	res = res * T(10) + T(frontChar - '0');
	popChar;
      }
    while(frontChar.isDigit);
    return res;
  }
}

struct Matrix(T, alias rows, alias cols)
{
  T[][] _cell;
  alias _cell this;
  // Ring constructor
  this(int n)
  {
    final switch(n)
      {
      case 0:
	_cell = new T[][](rows, cols);
	break;
      case 1:
	debug assert(rows == cols);
	_cell = new T[][](rows, cols);
	foreach(i; 0 .. rows)
	  _cell[i][i] = T(1);
	break;
      }
  }
  // Copy constructor
  this(Matrix!(T, rows, cols) other)
  {
    _cell = new T[][](rows, cols);
    foreach(i; 0 .. rows)
      _cell[i][] = other[i][];
  }
  auto opBinary(string op)(Matrix!(T, rows, cols) other)
       if (op == "+" || op == "-")
	 {
	   auto res = Matrix!(T, rows, cols)(0);
	   foreach(i; 0 .. rows)
	     foreach(j; 0 .. cols)
	       res[i][j] = mixin(q{this[i][j]}, op, q{other[i][j]});
	   return res;
	 }
  auto opBinary(string op, alias otherRows, alias otherCols)(Matrix!(T, otherRows, otherCols) other)
       if (op == "*")
	 {
	   debug assert(cols == otherRows);
	   auto res = Matrix!(T, rows, otherCols)(0);
	   foreach(i; 0 .. rows)
	     foreach(k; 0 .. cols)
	       foreach(j; 0 .. otherCols)
		 res[i][j] += this[i][k] * other[k][j];
	   return res;
	 }
  ref auto opOpAssign(string op)(Matrix!(T, rows, cols) other)
  {
    static if (op == "*")
      {
	debug assert(rows == cols);
	alias n = rows;
	auto res = Matrix!(T, n, n)(0);
	T factor;
	foreach(i; 0 .. n)
	  foreach(k; 0 .. n)
	    foreach(j; 0 .. n)
	      res[i][j] += this[i][k] * other[k][j];
	foreach(i; 0 .. n)
	  this[i][] = res[i][];
      }
    else
      {
	foreach(i; 0 .. rows)
	  foreach(j; 0 .. cols)
	    mixin(q{this[i][j] }, text(op, q{=}), q{ other[i][j];});
      }
    return this;
  }
  mixin powMethod;
}

struct Mod(T, alias mod)
{
  alias This = Mod!(T, mod);
  T _rep;
  this(T t)
  {
    _rep = t % mod;
    if (_rep < 0) _rep += mod;
  }
  static auto plain(T t)
  {
    auto res = Mod!(T, mod)();
    res._rep = t;
    return res;
  }
  static auto fromPositive(T t)
  {
    pragma(inline, true);
    return Mod!(T, mod).plain(t % mod);
  }
  static auto fromNegative(T t)
  {
    pragma(inline, true);
    return Mod!(T, mod).plain(t % mod + mod);
  }
  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.plain(resrep);
      }
    else static if (op == "-")
      {
	T resrep = _rep - b._rep;
	if (resrep < 0) resrep += mod;
	return This.plain(resrep);
      }
    else static if (op == "*")
      {
	return This.fromPositive(_rep * b._rep);
      }
  }
  auto opOpAssign(string op)(This b)
  {
    mixin(q{_rep }, text(op, "="), q{b._rep;});
    static if (op == "+")
      {
	if (_rep >= mod) _rep -= mod;
      }
    else static if (op == "-")
      {
	if (_rep < 0) _rep += mod;
      }
    else static if (op == "*")
      {
	_rep %= mod;
      }
    return this;
  }

  auto opBinary(string op)(long exp)
       if (op == "^^")
	 {
	   return pow(exp);
	 }
  mixin powMethod;
}

mixin template powMethod()
{
  auto pow(this ThisType)(long exp)
    {
      auto res = ThisType(1);
      auto pow = ThisType(this);
      while(exp)
	{
	  if (exp & 1) res *= pow;
	  pow *= pow;
	  exp >>= 1;
	}
      return res;
    }
}
// INPUT
char frontChar;
void popChar()
{
  import core.stdc.stdio;
  frontChar = cast(char) getchar;
  if (feof(stdin)) frontChar = ' ';
}
auto makeArray(T, S...)(S s)
{
  enum brackets = () {
    string res;
    foreach(i; 0 .. s.length)
      res ~= "[]";
    return res;
  } ();
  mixin(q{alias Type = T}, brackets, q{;});
  return new Type(s);
}
template isNumberLike(T)
{
  enum isNumberLike = is(typeof((){T test; test = test + test * test; test *= test;}()));
}
void popWhite()
{
  import std.ascii;
  while (frontChar.isWhite) popChar;
}
void print(T...)(T t)
{
  static foreach(ti; t)
    {
      static if (is(typeof(ti) == string))
	{
	  write(ti, " ");
	}
      else static if (isArray!(typeof(ti)))
	{
	  foreach(e; ti) print(e);
	}
      else static if (isTuple!(typeof(ti)))
	{
	  static foreach(i; ti.length) writesp(ti[i]);
	}
      else
	{
	  write(ti, " ");
	}
    }
}
void println(T...)(T t)
{
  static if (t.length == 0)
    writeln;
  static foreach(ti; t)
    {
      print(ti);
      writeln;
    }
}
auto next(alias T, S...)(S s)
{
  pragma(inline, true);
  static if (s.length > 0)
    {
      auto res = makeArray!(typeof(next!T()))(s);
      S t;
      enum loops = () {
	string res;
	foreach(i; 0 .. s.length)
	  {
	    auto ti = text(q{t[}, i, q{]});
	    res ~= text(q{for(}, ti, q{ = 0;}, ti , q{ < s[}, i, q{];}, ti, q{++)});
	  }
	return res;
      } ();
      enum indexing = () {
	string res = "res";
	foreach(i; 0 .. s.length)
	  res ~= text(q{[t[}, i, q{]]});
	return res;
      } ();
      mixin(loops, indexing, q{ = next!T;});
      return res;
    }
  else
    {
      static if (isNumberLike!T)
	{
	  import std.ascii: isDigit;
	  T res;
	  while(frontChar.isWhite) popChar;
	  T multiplier = T(1);
	  if (frontChar == '-')
	    {
	      multiplier = T(-1);
	      popChar;
	    }
	  else if (frontChar == '+')
	    {
	      popChar;
	    }
	  debug assert(frontChar.isDigit);
	  do
	    {
	      res = res * T(10) + T(frontChar - '0');
	      popChar;
	    }
	  while(frontChar.isDigit);
	  return multiplier * res;
	}
      else static if (is(T == string))
	{
	  import std.ascii: isWhite;
	  string res;
	  while(frontChar.isWhite)
	    popChar;
	  while(!frontChar.isWhite)
	    {
	      res ~= frontChar;
	      popChar;
	    }
	  return res;
	}
      else static if (is(T == char))
	{
	  while(frontChar.isWhite) popChar;
	  auto res = frontChar;
	  popChar;
	  return res;
	}
      else
	{
	  return T.read;
	}
    }
}

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;
import std.traits;
import std.variant;
import std.concurrency;

void main(string[] args)
{
  auto n = next!int;
  auto a = next!int(n);
  auto pos1 = new int[](n + 1); pos1[] = -1;
  auto pos2 = new int[](n + 1); pos2[] = -1;
  auto cnt1 = new int[](n);
  auto cnt2 = new int[](n);
  foreach(i, ai; a)
    {
      if (i != 0)
	{
	  cnt1[i] = cnt1[i - 1];
	  cnt2[i] = cnt2[i - 1];
	}
      if (ai == 1)
	{
	  cnt1[i]++;
	  pos1[cnt1[i]] = cast(int) i;
	}
      else
	{
	  cnt2[i]++;
	  pos2[cnt2[i]] = cast(int) i;
	}
    }
  foreach(ref c; pos1) if (c == -1) c = n;
  foreach(ref c; pos2) if (c == -1) c = n;
  auto options = new Tuple!(int, int)[](0);
  debug writeln("pos1 = ", pos1);
  debug writeln("pos2 = ", pos2);
 sTest: foreach(s; 1 .. n + 1)
    {
      debug writeln("trying for s = ", s);
      int i = void;
      int ni = void;
      int sets1 = 0;
      int sets2 = 0;
      int next1 = pos1[s];
      int next2 = pos2[s];
      if (next1 < next2)
	{
	  i = next1;
	  sets1++;
	}
      else
	{
	  i = next2;
	  sets2++;
	}
      while (i < n)
	{
	  debug writeln("in i = ", i, " sets1 = ", sets1, " sets2 = ", sets2);
	  if (i == n - 1)
	    {
	      if (sets1 == sets2)
		continue sTest;
	      options ~= tuple(s, max(sets1, sets2));
	      continue sTest;
	    }

	  next1 = (cnt1[i] + s <= n)? pos1[cnt1[i] + s] : n;
	  next2 = (cnt2[i] + s <= n)? pos2[cnt2[i] + s] : n;
	  if (next1 < next2)
	    {
	      ni = next1;
	      sets1++;
	    }
	  else
	    {
	      ni = next2;
	      sets2++;
	    }

	  i = ni;
	}
    }
  writeln(options.length);
  foreach(option; options)
    {
      writeln(option[0], " ", option[1]);
    }
}

static this()
{
  popChar;
}

struct Any(T)
{
  static auto read()
  {
    static if (is(T == char))
      {
	auto res = frontChar;
	popChar;
	return res;
      }
  }
}

struct Unsigned(T)
{
  auto read()
  {
    auto res = T(0);
    while(!frontChar.isDigit) popChar;
    do
      {
	res = res * T(10) + T(frontChar - '0');
	popChar;
      }
    while(frontChar.isDigit);
    return res;
  }
}

struct Matrix(T, alias rows, alias cols)
{
  T[][] _cell;
  alias _cell this;
  // Ring constructor
  this(int n)
  {
    final switch(n)
      {
      case 0:
	_cell = new T[][](rows, cols);
	break;
      case 1:
	debug assert(rows == cols);
	_cell = new T[][](rows, cols);
	foreach(i; 0 .. rows)
	  _cell[i][i] = T(1);
	break;
      }
  }
  // Copy constructor
  this(Matrix!(T, rows, cols) other)
  {
    _cell = new T[][](rows, cols);
    foreach(i; 0 .. rows)
      _cell[i][] = other[i][];
  }
  auto opBinary(string op)(Matrix!(T, rows, cols) other)
       if (op == "+" || op == "-")
	 {
	   auto res = Matrix!(T, rows, cols)(0);
	   foreach(i; 0 .. rows)
	     foreach(j; 0 .. cols)
	       res[i][j] = mixin(q{this[i][j]}, op, q{other[i][j]});
	   return res;
	 }
  auto opBinary(string op, alias otherRows, alias otherCols)(Matrix!(T, otherRows, otherCols) other)
       if (op == "*")
	 {
	   debug assert(cols == otherRows);
	   auto res = Matrix!(T, rows, otherCols)(0);
	   foreach(i; 0 .. rows)
	     foreach(k; 0 .. cols)
	       foreach(j; 0 .. otherCols)
		 res[i][j] += this[i][k] * other[k][j];
	   return res;
	 }
  ref auto opOpAssign(string op)(Matrix!(T, rows, cols) other)
  {
    static if (op == "*")
      {
	debug assert(rows == cols);
	alias n = rows;
	auto res = Matrix!(T, n, n)(0);
	T factor;
	foreach(i; 0 .. n)
	  foreach(k; 0 .. n)
	    foreach(j; 0 .. n)
	      res[i][j] += this[i][k] * other[k][j];
	foreach(i; 0 .. n)
	  this[i][] = res[i][];
      }
    else
      {
	foreach(i; 0 .. rows)
	  foreach(j; 0 .. cols)
	    mixin(q{this[i][j] }, text(op, q{=}), q{ other[i][j];});
      }
    return this;
  }
  mixin powMethod;
}

struct Mod(T, alias mod)
{
  alias This = Mod!(T, mod);
  T _rep;
  this(T t)
  {
    _rep = t % mod;
    if (_rep < 0) _rep += mod;
  }
  static auto plain(T t)
  {
    auto res = Mod!(T, mod)();
    res._rep = t;
    return res;
  }
  static auto fromPositive(T t)
  {
    pragma(inline, true);
    return Mod!(T, mod).plain(t % mod);
  }
  static auto fromNegative(T t)
  {
    pragma(inline, true);
    return Mod!(T, mod).plain(t % mod + mod);
  }
  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.plain(resrep);
      }
    else static if (op == "-")
      {
	T resrep = _rep - b._rep;
	if (resrep < 0) resrep += mod;
	return This.plain(resrep);
      }
    else static if (op == "*")
      {
	return This.fromPositive(_rep * b._rep);
      }
  }
  auto opOpAssign(string op)(This b)
  {
    mixin(q{_rep }, text(op, "="), q{b._rep;});
    static if (op == "+")
      {
	if (_rep >= mod) _rep -= mod;
      }
    else static if (op == "-")
      {
	if (_rep < 0) _rep += mod;
      }
    else static if (op == "*")
      {
	_rep %= mod;
      }
    return this;
  }

  auto opBinary(string op)(long exp)
       if (op == "^^")
	 {
	   return pow(exp);
	 }
  mixin powMethod;
}

mixin template powMethod()
{
  auto pow(this ThisType)(long exp)
    {
      auto res = ThisType(1);
      auto pow = ThisType(this);
      while(exp)
	{
	  if (exp & 1) res *= pow;
	  pow *= pow;
	  exp >>= 1;
	}
      return res;
    }
}
// INPUT
char frontChar;
void popChar()
{
  import core.stdc.stdio;
  frontChar = cast(char) getchar;
  if (feof(stdin)) frontChar = ' ';
}
auto makeArray(T, S...)(S s)
{
  enum brackets = () {
    string res;
    foreach(i; 0 .. s.length)
      res ~= "[]";
    return res;
  } ();
  mixin(q{alias Type = T}, brackets, q{;});
  return new Type(s);
}
template isNumberLike(T)
{
  enum isNumberLike = is(typeof((){T test; test = test + test * test; test *= test;}()));
}
void popWhite()
{
  import std.ascii;
  while (frontChar.isWhite) popChar;
}
void print(T...)(T t)
{
  static foreach(ti; t)
    {
      static if (is(typeof(ti) == string))
	{
	  write(ti, " ");
	}
      else static if (isArray!(typeof(ti)))
	{
	  foreach(e; ti) print(e);
	}
      else static if (isTuple!(typeof(ti)))
	{
	  static foreach(i; ti.length) writesp(ti[i]);
	}
      else
	{
	  write(ti, " ");
	}
    }
}
void println(T...)(T t)
{
  static if (t.length == 0)
    writeln;
  static foreach(ti; t)
    {
      print(ti);
      writeln;
    }
}
auto next(alias T, S...)(S s)
{
  pragma(inline, true);
  static if (s.length > 0)
    {
      auto res = makeArray!(typeof(next!T()))(s);
      S t;
      enum loops = () {
	string res;
	foreach(i; 0 .. s.length)
	  {
	    auto ti = text(q{t[}, i, q{]});
	    res ~= text(q{for(}, ti, q{ = 0;}, ti , q{ < s[}, i, q{];}, ti, q{++)});
	  }
	return res;
      } ();
      enum indexing = () {
	string res = "res";
	foreach(i; 0 .. s.length)
	  res ~= text(q{[t[}, i, q{]]});
	return res;
      } ();
      mixin(loops, indexing, q{ = next!T;});
      return res;
    }
  else
    {
      static if (isNumberLike!T)
	{
	  import std.ascii: isDigit;
	  T res;
	  while(frontChar.isWhite) popChar;
	  T multiplier = T(1);
	  if (frontChar == '-')
	    {
	      multiplier = T(-1);
	      popChar;
	    }
	  else if (frontChar == '+')
	    {
	      popChar;
	    }
	  debug assert(frontChar.isDigit);
	  do
	    {
	      res = res * T(10) + T(frontChar - '0');
	      popChar;
	    }
	  while(frontChar.isDigit);
	  return multiplier * res;
	}
      else static if (is(T == string))
	{
	  import std.ascii: isWhite;
	  string res;
	  while(frontChar.isWhite)
	    popChar;
	  while(!frontChar.isWhite)
	    {
	      res ~= frontChar;
	      popChar;
	    }
	  return res;
	}
      else static if (is(T == char))
	{
	  while(frontChar.isWhite) popChar;
	  auto res = frontChar;
	  popChar;
	  return res;
	}
      else
	{
	  return T.read;
	}
    }
}


You are preparing for an exam on scheduling theory. The exam will last for exactly T milliseconds and will consist of n problems. You can either solve problem i in exactly ti milliseconds or ignore it and spend no time. You don't need time to rest after solving a problem, either.Unfortunately, your teacher considers some of the problems too easy for you. Thus, he assigned an integer ai to every problem i meaning that the problem i can bring you a point to the final score only in case you have solved no more than ai problems overall (including problem i).Formally, suppose you solve problems p1, p2, ..., pk during the exam. Then, your final score s will be equal to the number of values of j between 1 and k such that k ≤ apj.You have guessed that the real first problem of the exam is already in front of you. Therefore, you want to choose a set of problems to solve during the exam maximizing your final score in advance. Don't forget that the exam is limited in time, and you must have enough time to solve all chosen problems. If there exist different sets of problems leading to the maximum final score, any of them will do.

The first line contains two integers n and T (1 ≤ n ≤ 2·105; 1 ≤ T ≤ 109) — the number of problems in the exam and the length of the exam in milliseconds, respectively. Each of the next n lines contains two integers ai and ti (1 ≤ ai ≤ n; 1 ≤ ti ≤ 104). The problems are numbered from 1 to n.

In the first line, output a single integer s — your maximum possible final score. In the second line, output a single integer k (0 ≤ k ≤ n) — the number of problems you should solve. In the third line, output k distinct integers p1, p2, ..., pk (1 ≤ pi ≤ n) — the indexes of problems you should solve, in any order. If there are several optimal sets of problems, you may output any of them.

NoteIn the first example, you should solve problems 3, 1, and 4. In this case you'll spend 80 + 100 + 90 = 270 milliseconds, falling within the length of the exam, 300 milliseconds (and even leaving yourself 30 milliseconds to have a rest). Problems 3 and 1 will bring you a point each, while problem 4 won't. You'll score two points.In the second example, the length of the exam is catastrophically not enough to solve even a single problem.In the third example, you have just enough time to solve both problems in 42 + 58 = 100 milliseconds and hand your solutions to the teacher with a smile.

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;

alias Problem = Tuple!(int, "num", long, "time", int, "index");

void main() {
    auto s = readln.split.map!(to!int);
    auto N = s[0];
    auto T = s[1].to!long;
    auto P = new Problem[](N);
    foreach (i; 0..N) {
        s = readln.split.map!(to!int);
        P[i] = tuple(s[0], s[1].to!long, i+1);
    }
    P.sort!"a[1] < b[1]";

    int hi = N+1;
    int lo = 0;
    while (hi - lo > 1) {
        int mid = (hi + lo) / 2;
        long tmp = 0;
        int cnt = 0;
        foreach (p; P) {
            if (p.num < mid) continue;
            tmp += p.time;
            cnt += 1;
            if (cnt >= mid) break;
        }
        if (cnt >= mid && tmp <= T) {
            lo = mid;
        } else {
            hi = mid;
        }
    }

    int[] ans;
    int cnt = 0;
    foreach (p; P) {
        if (p.num >= lo) {
            ans ~= p.index;
            cnt += 1;
        }
        if (cnt >= lo) break;
    }

    lo.writeln;
    lo.writeln;
    if (lo == 0) writeln;
    else ans.map!(to!string).join(" ").writeln;
}

import core.bitop;
import core.checkedint;
//import core.stdc.stdio;
import core.stdc.stdlib: alloca, malloc, calloc, realloc, _Exit;
import core.stdc.string;
import std.algorithm;
import std.array;
import std.ascii;
import std.bigint;
import std.bitmanip;
import std.container;
import std.conv;
import std.exception;
import std.functional;
import std.math;
import std.meta;
import std.numeric;
import std.random;
import std.range;
import std.regex;
import std.stdio;
import std.string;
import std.typecons;

__gshared:

alias BitSet(size_t n) = size_t[(n + size_t.sizeof * 8 - 1) / (size_t.sizeof * 8)];

auto getAddrTuple() {
    return tuple();
}

auto getAddrTuple(T, U...)(ref T head, ref U tail) {
    return tuple(&head, getAddrTuple(tail).expand);
}

bool read(T...)(ref T vars) if (vars.length > 0) {
    enum spec = ' ' ~ replicate("%s ", vars.length);
    return readf(spec, getAddrTuple(vars).expand) == vars.length;
}

void memSet(T, size_t n)(ref T[n] a, ubyte value) {
    memset(a.ptr, value, a.sizeof);
}

void memSet(T)(T[ ] a, ubyte value) {
    memset(a.ptr, value, a.length * T.sizeof);
}

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

struct Problem {
    int id, limit, time;

    int opCmp(Problem rhs) const {
        return tuple(time, limit).opCmp(tuple(rhs.time, rhs.limit));
    }
}

int n, total;
Problem[200_000] _problems;
Problem[ ] problems;
RedBlackTree!(Problem, q{a.id < b.id})[200_000] _solvedDist;
RedBlackTree!(Problem, q{a.id < b.id})[ ] solvedDist;
int curCount, bestCount;
RedBlackTree!(Problem, q{a < b}, true) solved;

void run(alias callback)() {
    generate!(redBlackTree!(q{a.id < b.id}, Problem)).take(n).copy(solvedDist);
    int curTime = 0;
    curCount = 0;
    auto solvable = redBlackTree!true(problems);
    solved = redBlackTree!(true, Problem);
    foreach (c; 1 .. n + 1) {
        while (!solved.empty && !solvable.empty && solvable.front.time < solved.front.time) {
            const a = solvable.front;
            solvable.removeFront();
            if (c <= a.limit) {
                const b = solved.front;
                solved.removeFront();
                solvedDist[b.limit - 1].removeKey(b);
                curTime -= b.time - a.time;
                solved.insert(a);
                solvedDist[a.limit - 1].insert(a);
                if (c <= b.limit)
                    solvable.insert(b);
            }
        }
        while (solved.length < c && !solvable.empty && curTime + solvable.front.time <= total) {
            const a = solvable.front;
            solvable.removeFront();
            if (c <= a.limit) {
                curTime += a.time;
                curCount++;
                solved.insert(a);
                solvedDist[a.limit - 1].insert(a);
                if (callback())
                    return;
            }
        }
        foreach (p; solvedDist[c - 1]) {
            assert(p.limit == c);
            solved.removeKey(p);
            curTime -= p.time;
            curCount--;
        }
        solvedDist[c - 1] = null;
    }
}

void main() {
    while (read(n, total)) {
        problems = _problems[0 .. n];
        solvedDist = _solvedDist[0 .. n];
        foreach (int i, ref p; problems) {
            p.id = i + 1;
            read(p.limit, p.time);
        }

        problems.multiSort!(q{a.limit < b.limit}, q{a.time < b.time});
        bestCount = 0;
        run!({
            if (curCount > bestCount)
                bestCount = curCount;
            return false;
        });

        writeln(bestCount, '\n', bestCount);
        run!({
            if (curCount != bestCount)
                return false;
            writefln("%(%s %)", solved[ ].map!q{a.id});
            return true;
        });
        debug writeln();
    }

    stdout.flush();
    _Exit(0);
}

import core.bitop, std.algorithm, std.bigint, std.bitmanip, std.complex,
	std.container, std.conv, std.datetime, std.functional, std.math, std.meta;
import std.numeric : Fft, fft, gcd, inverseFft;
import std.parallelism, std.random, std.range, std.regex, std.stdio, std.string,
	std.traits, std.typecons, std.uni, std.variant;

alias pair(X, Y) = Tuple!(X, "fi", Y, "se");
alias mp = make_pair;
alias pii = pair!(int, int);
alias pll = pair!(long, long);
// alias gcd = std.numeric.gcd;
alias lint = long;
alias rbt = RedBlackTree;
/// struct vector as c++ vector
struct Vec(T)
{
	private Array!T buf;
	alias buf this;
	this(this)
	{
		buf = buf.dup;
	}
	/// construct from length
	this(U)(U length)
			if (is(U == int) || is(U == size_t) || is(U == long) || is(U == ulong) || is(U == uint))
	{
		buf.length = length;
	}
	/// construct from length and default value
	this(U, X)(U length, X val)
			if (isImplicitlyConvertible!(X, T) || (is(U == int)
				|| is(U == size_t) || is(U == long) || is(U == ulong) || is(U == uint)))
	{
		buf.length = length;
		foreach (ref x; buf[])
		{
			x = val;
		}
	}
	/// construct from other array
	this(U)(U[] values...) if (isImplicitlyConvertible!(U, T))
	{
		buf = Array!(T)(values);
	}
	/// construct from other range
	this(Range)(Range r)
			if (isInputRange!Range && isImplicitlyConvertible!(ElementType!Range,
				T) && !is(Range == T[]))
	{
		buf = Array!(T)(r);
	}
	/// integer length
	int size() @property const
	{
		return cast(int) buf.length;
	}
}
///modulo
enum mm = 10 ^^ 9 + 7, mm2 = mm + 2;
public
{
	pure nothrow
	{
		///lcm
		T lcm(T)(auto ref T a, auto ref T b)
		{
			return a / gcd(a, b) * b;
		}
		///make_pair
		pair!(X, Y) make_pair(X, Y)(in X x_, in Y y_)
		{
			return tuple!(X, "fi", Y, "se")(x_, y_);
		}
		///BigInt greatest common divizor
		BigInt biggcd(BigInt a, BigInt b)
		{
			BigInt res = 1;
			while (b)
			{
				if ((a & 1) && (b & 1))
				{
					a -= b;
					a >>= 1;
				}
				else if (a & 1)
				{
					b >>= 1;
				}
				else if (b & 1)
				{
					a >>= 1;
				}
				else
				{
					res <<= 1;
					a >>= 1;
					b >>= 1;
				}
				if (a < b)
					swap(a, b);
			}
			return res * a;
		}
		///square
		@property X sqr(X)(in X a_)
		{
			return a_ * a_;
		}
		///cube
		@property X cub(X)(in X a_)
		{
			return a_ * a_ * a_;
		}
		///posicion lower bound
		size_t lowb(T, X)(T a, auto ref X g)
				if (isRandomAccessRange!T && hasLength!T && is(typeof(g < a[0]) == bool))
		{
			return assumeSorted(a).lowerBound(g).length;
		}
		///posicion upper bound
		size_t upb(T, X)(T a, auto ref X g)
				if (isRandomAccessRange!T && hasLength!T && is(typeof(g < a[0]) == bool))
		{
			return a.length - assumeSorted(a).upperBound(g).length;
		}
		///posicion binary search
		size_t binf(T, X)(T a, auto ref X g)
				if (isRandomAccessRange!T && hasLength!T && is(typeof(g < a[0]) == bool))
		{
			auto pos = lowb(a, g);
			return (g == a[pos]) ? pos : a.length;
		}
		///binary search
		bool binary_search(T, X)(T a, auto ref X g)
				if (isRandomAccessRange!T && hasLength!T && is(typeof(g < a[0]) == bool))
		{
			return assumeSorted(a).contains(g);
		}
	}
	///write an array
	void putarr(X)(in X a, in char ch = ' ') if (isInputRange!X)
	{
		writefln("%(%s" ~ ch ~ "%)", a);
	}
	///write a matrix
	void putarr(X)(in X a)
			if (isInputRange!X && isInputRange!(ElementType!X) && !isSomeString!(ElementType!X))
	{
		writefln("%(%(%s %)\n%)", a);
	}
	///get an array
	bool getarr(X)(X a, in size_t n)
	{
		bool b = 1;
		foreach (ref i; a[0 .. n])
			b = input(&i);
		return b;
	}
	///read without format
	bool input(T...)(auto ref T ptrs) if (ptrs.length > 0)
	{
		return readf!(replicate(" %s", ptrs.length))(ptrs) == ptrs.length;
	}
	///readln without format
	bool read(T...)(auto ref T ptrs) if (ptrs.length > 0)
	{
		const bool fl = readf!(replicate(" %s", ptrs.length))(ptrs) == ptrs.length;
		readln;
		return fl;
	}
	///opening file
	nothrow auto inf(in char* name)
	{
		return freopen(name, "r", core.stdc.stdio.stdin);
	}
	///closing file
	nothrow auto ouf(in char* name)
	{
		return freopen(name, "w", core.stdc.stdio.stdout);
	}
	///parsing array from line
	@property auto arread(T)()
	{
		return readln.splitter.map!(to!(T)).array;
	}
	///outbuffer
	void enter(T...)(T args)
	{
		writeln(args);
		stdout.flush;
	}
}
//foreach_reverse isAlpha isNumber isWhite isLower isUpper toLower toUpper mixin
//cumulativeFold return static heapify join filter foreach
//------------------------------------------program beginning--------------------------

void main()
{
	int n, T;
	read(n, T);
	auto a = new Tuple!(int, int, int)[n];
	foreach (i; 0 .. n)
	{
		read(a[i][0], a[i][1]);
		a[i][2] = i + 1;
	}
	sort!"a[1]<b[1]"(a);
	bool check(int k)
	{
		int c;
		long curt;
		foreach (x; a)
		{
			if (c == k)
				break;
			if (x[0] < k)
				continue;
			c++;
			curt += x[1];
		}
		return c == k && curt <= T;
	}

	int l = 0, r = n;
	while (l < r)
	{
		int m = (l + r + 1) / 2;
		if (check(m))
			l = m;
		else
			r = m - 1;
	}
	int[] ans;
	foreach (x; a)
	{
		if (ans.length == l)
			break;
		if (x[0] < l)
			continue;
		ans ~= x[2];
	}
	writeln(l, '\n', l);
	putarr(ans, ' ');
}

import core.bitop, std.algorithm, std.bigint, std.bitmanip, std.complex,
	std.container, std.conv, std.datetime, std.functional, std.math, std.meta;
import std.numeric : Fft, fft, gcd, inverseFft;
import std.parallelism, std.random, std.range, std.regex, std.stdio, std.string,
	std.traits, std.typecons, std.uni, std.variant;

alias pair(X, Y) = Tuple!(X, "fi", Y, "se");
alias mp = make_pair;
alias pii = pair!(int, int);
alias pll = pair!(long, long);
// alias gcd = std.numeric.gcd;
alias lint = long;
alias rbt = RedBlackTree;
/// struct vector as c++ vector
struct Vec(T)
{
	private Array!T buf;
	alias buf this;
	this(this)
	{
		buf = buf.dup;
	}
	/// construct from length
	this(U)(U length)
			if (is(U == int) || is(U == size_t) || is(U == long) || is(U == ulong) || is(U == uint))
	{
		buf.length = length;
	}
	/// construct from length and default value
	this(U, X)(U length, X val)
			if (isImplicitlyConvertible!(X, T) || (is(U == int)
				|| is(U == size_t) || is(U == long) || is(U == ulong) || is(U == uint)))
	{
		buf.length = length;
		foreach (ref x; buf[])
		{
			x = val;
		}
	}
	/// construct from other array
	this(U)(U[] values...) if (isImplicitlyConvertible!(U, T))
	{
		buf = Array!(T)(values);
	}
	/// construct from other range
	this(Range)(Range r)
			if (isInputRange!Range && isImplicitlyConvertible!(ElementType!Range,
				T) && !is(Range == T[]))
	{
		buf = Array!(T)(r);
	}
	/// integer length
	int size() @property const
	{
		return cast(int) buf.length;
	}
}
///modulo
enum mm = 10 ^^ 9 + 7, mm2 = mm + 2;
public
{
	pure nothrow
	{
		///lcm
		T lcm(T)(auto ref T a, auto ref T b)
		{
			return a / gcd(a, b) * b;
		}
		///make_pair
		pair!(X, Y) make_pair(X, Y)(in X x_, in Y y_)
		{
			return tuple!(X, "fi", Y, "se")(x_, y_);
		}
		///BigInt greatest common divizor
		BigInt biggcd(BigInt a, BigInt b)
		{
			BigInt res = 1;
			while (b)
			{
				if ((a & 1) && (b & 1))
				{
					a -= b;
					a >>= 1;
				}
				else if (a & 1)
				{
					b >>= 1;
				}
				else if (b & 1)
				{
					a >>= 1;
				}
				else
				{
					res <<= 1;
					a >>= 1;
					b >>= 1;
				}
				if (a < b)
					swap(a, b);
			}
			return res * a;
		}
		///square
		@property X sqr(X)(in X a_)
		{
			return a_ * a_;
		}
		///cube
		@property X cub(X)(in X a_)
		{
			return a_ * a_ * a_;
		}
		///posicion lower bound
		size_t lowb(T, X)(T a, auto ref X g)
				if (isRandomAccessRange!T && hasLength!T && is(typeof(g < a[0]) == bool))
		{
			return assumeSorted(a).lowerBound(g).length;
		}
		///posicion upper bound
		size_t upb(T, X)(T a, auto ref X g)
				if (isRandomAccessRange!T && hasLength!T && is(typeof(g < a[0]) == bool))
		{
			return a.length - assumeSorted(a).upperBound(g).length;
		}
		///posicion binary search
		size_t binf(T, X)(T a, auto ref X g)
				if (isRandomAccessRange!T && hasLength!T && is(typeof(g < a[0]) == bool))
		{
			auto pos = lowb(a, g);
			return (g == a[pos]) ? pos : a.length;
		}
		///binary search
		bool binary_search(T, X)(T a, auto ref X g)
				if (isRandomAccessRange!T && hasLength!T && is(typeof(g < a[0]) == bool))
		{
			return assumeSorted(a).contains(g);
		}
	}
	///write an array
	void putarr(X)(in X a, in char ch = ' ') if (isInputRange!X)
	{
		writefln("%(%s" ~ ch ~ "%)", a);
	}
	///write a matrix
	void putarr(X)(in X a)
			if (isInputRange!X && isInputRange!(ElementType!X) && !isSomeString!(ElementType!X))
	{
		writefln("%(%(%s %)\n%)", a);
	}
	///get an array
	bool getarr(X)(X a, in size_t n)
	{
		bool b = 1;
		foreach (ref i; a[0 .. n])
			b = input(&i);
		return b;
	}
	///read without format
	bool input(T...)(auto ref T ptrs) if (ptrs.length > 0)
	{
		return readf!(replicate(" %s", ptrs.length))(ptrs) == ptrs.length;
	}
	///readln without format
	bool read(T...)(auto ref T ptrs) if (ptrs.length > 0)
	{
		const bool fl = readf!(replicate(" %s", ptrs.length))(ptrs) == ptrs.length;
		readln;
		return fl;
	}
	///opening file
	nothrow auto inf(in char* name)
	{
		return freopen(name, "r", core.stdc.stdio.stdin);
	}
	///closing file
	nothrow auto ouf(in char* name)
	{
		return freopen(name, "w", core.stdc.stdio.stdout);
	}
	///parsing array from line
	@property auto arread(T)()
	{
		return readln.splitter.map!(to!(T)).array;
	}
	///outbuffer
	void enter(T...)(T args)
	{
		writeln(args);
		stdout.flush;
	}
}
//foreach_reverse isAlpha isNumber isWhite isLower isUpper toLower toUpper mixin
//cumulativeFold return static heapify join filter foreach
//------------------------------------------program beginning--------------------------

void main()
{
	int n, T;
	read(n, T);
	auto a = new Tuple!(int, int, int)[n];
	foreach (i; 0 .. n)
	{
		read(a[i][0], a[i][1]);
		a[i][2] = i + 1;
	}
	sort!"a[1]<b[1]"(a);
	bool check(int k)
	{
		int c;
		long curt;
		foreach (x; a)
		{
			if (c == k)
				break;
			if (x[0] < k)
				continue;
			c++;
			curt += x[1];
		}
		return curt <= T;
	}

	int l = 0, r = n;
	while (l < r)
	{
		int m = (l + r + 1) / 2;
		if (check(m))
			l = m;
		else
			r = m - 1;
	}
	int[] ans;
	foreach (x; a)
	{
		if (ans.length == l)
			break;
		if (x[0] < l)
			continue;
		ans ~= x[2];
	}
	writeln(l, '\n', l);
	putarr(ans, ' ');
}

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

alias Problem = Tuple!(int, "num", long, "time", int, "index");

void main() {
    auto s = readln.split.map!(to!int);
    auto N = s[0];
    auto T = s[1].to!long;
    auto P = new Problem[](N);
    foreach (i; 0..N) {
        s = readln.split.map!(to!int);
        P[i] = tuple(s[0], s[1].to!long, i+1);
    }
    P.sort!"a[1] < b[1]";

    int hi = N+1;
    int lo = 0;
    while (hi - lo > 1) {
        int mid = (hi + lo) / 2;
        long tmp = 0;
        int cnt = 0;
        foreach (p; P) {
            if (p.num < mid) continue;
            tmp += p.time;
            cnt += 1;
            if (cnt >= mid) break;
        }
        if (cnt >= mid && tmp <= T) {
            lo = mid;
        } else {
            hi = mid;
        }
    }

    int[] ans;
    foreach (i; 0..lo) if (P[i].num >= lo) ans ~= P[i].index;
    lo.writeln;
    lo.writeln;
    ans.map!(to!string).join(" ").writeln;
}

import core.bitop;
import core.checkedint;
//import core.stdc.stdio;
import core.stdc.stdlib: alloca, malloc, calloc, realloc, _Exit;
import core.stdc.string;
import std.algorithm;
import std.array;
import std.ascii;
import std.bigint;
import std.bitmanip;
import std.container;
import std.conv;
import std.exception;
import std.functional;
import std.math;
import std.meta;
import std.numeric;
import std.random;
import std.range;
import std.regex;
import std.stdio;
import std.string;
import std.typecons;

__gshared:

alias BitSet(size_t n) = size_t[(n + size_t.sizeof * 8 - 1) / (size_t.sizeof * 8)];

auto getAddrTuple() {
    return tuple();
}

auto getAddrTuple(T, U...)(ref T head, ref U tail) {
    return tuple(&head, getAddrTuple(tail).expand);
}

bool read(T...)(ref T vars) if (vars.length > 0) {
    enum spec = ' ' ~ replicate("%s ", vars.length);
    return readf(spec, getAddrTuple(vars).expand) == vars.length;
}

void memSet(T, size_t n)(ref T[n] a, ubyte value) {
    memset(a.ptr, value, a.sizeof);
}

void memSet(T)(T[ ] a, ubyte value) {
    memset(a.ptr, value, a.length * T.sizeof);
}

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

struct Problem {
    int id, limit, time;

    int opCmp(Problem rhs) const {
        return tuple(time, limit).opCmp(tuple(rhs.time, rhs.limit));
    }
}

Problem[200_000] _problems;
RedBlackTree!(Problem, q{a.id < b.id})[200_000] _solvedDist;

void main() {
    int n, total;
    while (read(n, total)) {
        auto problems = _problems[0 .. n];
        auto solvedDist = _solvedDist[0 .. n];
        foreach (int i, ref p; problems) {
            p.id = i + 1;
            read(p.limit, p.time);
        }

        problems.multiSort!(q{a.limit < b.limit}, q{a.time < b.time});
        generate!(redBlackTree!(q{a.id < b.id}, Problem)).take(n).copy(solvedDist);
        int bestTime = 10^^9 + 1, bestCount = 0;
        int curTime = 0, curCount = 0;
        auto solvable = redBlackTree!(true, Problem);
        auto solved = redBlackTree!(true, Problem);
        int pLastIndex = 0;
        foreach (c; 1 .. n + 1) {
            for (; pLastIndex < n && problems[pLastIndex].limit <= c; pLastIndex++)
                solvable.insert(problems[pLastIndex]);
            while (!solved.empty && !solvable.empty && solvable.front.time < solved.front.time) {
                const a = solvable.front;
                solvable.removeFront();
                if (c <= a.limit) {
                    const b = solved.front;
                    solved.removeFront();
                    solvedDist[b.limit - 1].removeKey(b);
                    curTime -= b.time - a.time;
                    solved.insert(a);
                    solvedDist[a.limit - 1].insert(a);
                    if (c <= b.limit)
                        solvable.insert(b);
                }
            }
            while (solved.length < c && !solvable.empty && curTime + solvable.front.time <= total) {
                const a = solvable.front;
                solvable.removeFront();
                if (c <= a.limit) {
                    curTime += a.time;
                    curCount++;
                    solved.insert(a);
                    solvedDist[a.limit - 1].insert(a);
                    if (curCount > bestCount) {
                        bestTime = curTime;
                        bestCount = curCount;
                    }
                }
            }
            foreach (p; solvedDist[c - 1]) {
                assert(p.limit == c);
                solved.removeKey(p);
                curTime -= p.time;
                curCount--;
            }
            solvedDist[c - 1] = null;
        }

        writeln(bestCount, '\n', bestCount);
        generate!(redBlackTree!(q{a.id < b.id}, Problem)).take(n).copy(solvedDist);
        curTime = 0;
        curCount = 0;
        solvable.clear();
        solved.clear();
        pLastIndex = 0;
    restoreResult:
        foreach (c; 1 .. n + 1) {
            for (; pLastIndex < n && problems[pLastIndex].limit <= c; pLastIndex++)
                solvable.insert(problems[pLastIndex]);
            while (!solved.empty && !solvable.empty && solvable.front.time < solved.front.time) {
                const a = solvable.front;
                solvable.removeFront();
                if (c <= a.limit) {
                    const b = solved.front;
                    solved.removeFront();
                    solvedDist[b.limit - 1].removeKey(b);
                    curTime -= b.time - a.time;
                    solved.insert(a);
                    solvedDist[a.limit - 1].insert(a);
                    if (c <= b.limit)
                        solvable.insert(b);
                }
            }
            while (solved.length < c && !solvable.empty && curTime + solvable.front.time <= total) {
                const a = solvable.front;
                solvable.removeFront();
                if (c <= a.limit) {
                    curTime += a.time;
                    curCount++;
                    solved.insert(a);
                    solvedDist[a.limit - 1].insert(a);
                    if (curCount == bestCount) {
                        writefln("%(%s %)", solved[ ].map!q{a.id});
                        break restoreResult;
                    }
                }
            }
            foreach (p; solvedDist[c - 1]) {
                assert(p.limit == c);
                solved.removeKey(p);
                curTime -= p.time;
                curCount--;
            }
            solvedDist[c - 1] = null;
        }
        debug writeln();
    }

    stdout.flush();
    _Exit(0);
}


Before becoming a successful trader William got a university degree. During his education an interesting situation happened, after which William started to listen to homework assignments much more attentively. What follows is the correct formal description of the homework assignment:You are given a string $$$s$$$ of length $$$n$$$ only consisting of characters "a", "b" and "c". There are $$$q$$$ queries of format ($$$pos, c$$$), meaning replacing the element of string $$$s$$$ at position $$$pos$$$ with character $$$c$$$. After each query you must output the minimal number of characters in the string, which have to be replaced, so that the string doesn't contain string "abc" as a substring. A valid replacement of a character is replacing it with "a", "b" or "c".A string $$$x$$$ is a substring of a string $$$y$$$ if $$$x$$$ can be obtained from $$$y$$$ by deletion of several (possibly, zero or all) characters from the beginning and several (possibly, zero or all) characters from the end.

The first line contains two integers $$$n$$$ and $$$q$$$ $$$(1 \le n, q \le 10^5)$$$, the length of the string and the number of queries, respectively. The second line contains the string $$$s$$$, consisting of characters "a", "b" and "c". Each of the next $$$q$$$ lines contains an integer $$$i$$$ and character $$$c$$$ $$$(1 \le i \le n)$$$, index and the value of the new item in the string, respectively. It is guaranteed that character's $$$c$$$ value is "a", "b" or "c".

For each query output the minimal number of characters that would have to be replaced so that the string doesn't contain "abc" as a substring.

9 10
abcabcabc
1 a
1 b
2 c
3 a
4 b
5 c
8 a
9 b
1 c
4 a

NoteLet's consider the state of the string after each query:   $$$s =$$$ "abcabcabc". In this case $$$3$$$ replacements can be performed to get, for instance, string $$$s =$$$ "bbcaccabb". This string does not contain "abc" as a substring. $$$s =$$$ "bbcabcabc". In this case $$$2$$$ replacements can be performed to get, for instance, string $$$s =$$$ "bbcbbcbbc". This string does not contain "abc" as a substring. $$$s =$$$ "bccabcabc". In this case $$$2$$$ replacements can be performed to get, for instance, string $$$s =$$$ "bccbbcbbc". This string does not contain "abc" as a substring. $$$s =$$$ "bcaabcabc". In this case $$$2$$$ replacements can be performed to get, for instance, string $$$s =$$$ "bcabbcbbc". This string does not contain "abc" as a substring. $$$s =$$$ "bcabbcabc". In this case $$$1$$$ replacements can be performed to get, for instance, string $$$s =$$$ "bcabbcabb". This string does not contain "abc" as a substring. $$$s =$$$ "bcabccabc". In this case $$$2$$$ replacements can be performed to get, for instance, string $$$s =$$$ "bcabbcabb". This string does not contain "abc" as a substring. $$$s =$$$ "bcabccaac". In this case $$$1$$$ replacements can be performed to get, for instance, string $$$s =$$$ "bcabbcaac". This string does not contain "abc" as a substring. $$$s =$$$ "bcabccaab". In this case $$$1$$$ replacements can be performed to get, for instance, string $$$s =$$$ "bcabbcaab". This string does not contain "abc" as a substring. $$$s =$$$ "ccabccaab". In this case $$$1$$$ replacements can be performed to get, for instance, string $$$s =$$$ "ccabbcaab". This string does not contain "abc" as a substring. $$$s =$$$ "ccaaccaab". In this case the string does not contain "abc" as a substring and no replacements are needed.

immutable multi = false;

void solve(int tc)
{
  auto n = readInt!int;
  auto q = readInt!int;
  auto s = cast(char[])readString;
  auto cnt = new int[](n);
  int sm;
  int isAbc(int i)
  {
    if (i + 3 > n) return 0;
    return int(s[i .. i + 3] == "abc");
  }
  foreach(i, ref ci; cnt)
    {
      ci = isAbc(cast(int)i);
    }
  sm = cnt.sum;
  void reCalc(int i)
  {
    if (i < 0 || i >= n) return;
    auto ld = cnt[i];
    auto nw = isAbc(i);
    auto dlt = nw - ld;
    cnt[i] = nw;
    sm += dlt;
  }
  foreach(qi; 0 .. q)
    {
      auto pos = readInt!int - 1;
      auto cString = readString;
      auto c = cString[0];
      s[pos] = c;
      foreach(p; pos - 3 .. pos + 1)
	{
	  reCalc(p);
	}
      sm.writeln;
    }
}

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

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

bool check_abc(char[] s, int i)
{
  if (s[i] == 'a') {
    if (i + 2 < s.length && s[i + 1] == 'b' && s[i + 2] == 'c')
      return true;
  } else if (s[i] == 'b') {
    if (i - 1 >= 0 && i + 1 < s.length && s[i - 1] == 'a' && s[i + 1] == 'c')
      return true;
  } else if (s[i] == 'c'){
    if (i - 2 >= 0 && s[i - 1] == 'b' && s[i - 2] == 'a')
      return true;
  }
  return false;
}

void main()
{
    long n, q;
    readf!" %d %d "(n, q);
    char[] s = readln.strip.dup;
    long ans = 0;
    char last = 'c';
    foreach (ch ; s) {
      if (ch == 'a')
        last = 'a';
      else if (ch == 'b' && last == 'a')
        last = 'b';
      else if (ch == 'c' && last == 'b') {
        ans++;
        last = 'c';
      } else
        last = 'c';
    }
    while (q-- > 0) {
      int pos;
      char ch;
      readf!" %d %c "(pos, ch);
      pos--;
      if (check_abc(s, pos))
        ans--;
      s[pos] = ch;
      if (check_abc(s, pos))
        ans++;
      writeln(ans);
    }
}

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

void main ()
{
	int n, q;
	while (readf !(" %s %s") (n, q) > 0)
	{
		readln;
		auto s = ['x', 'x'] ~ readln.strip.dup ~ ['x', 'x'];
		auto cur = s.count ("abc");
		foreach (j; 0..q)
		{
			int i;
			char ch;
			readf !(" %s %s") (i, ch);
			i += 1;
			cur -= (s[i - 2..i + 1] == "abc");
			cur -= (s[i - 1..i + 2] == "abc");
			cur -= (s[i - 0..i + 3] == "abc");
			s[i] = ch;
			cur += (s[i - 2..i + 1] == "abc");
			cur += (s[i - 1..i + 2] == "abc");
			cur += (s[i - 0..i + 3] == "abc");
			writeln (cur);
		}
	}
}


Let us define two functions f and g on positive integer numbers.   You need to process Q queries. In each query, you will be given three integers l, r and k. You need to print the number of integers x between l and r inclusive, such that g(x) = k.

The first line of the input contains an integer Q (1 ≤ Q ≤ 2 × 105) representing the number of queries.  Q lines follow, each of which contains 3 integers l, r and k (1 ≤ l ≤ r ≤ 106, 1 ≤ k ≤ 9).

For each query, print a single line containing the answer for that query.

NoteIn the first example:  g(33) = 9 as g(33) = g(3 × 3) = g(9) = 9  g(47) = g(48) = g(60) = g(61) = 6  There are no such integers between 47 and 55.  g(4) = g(14) = g(22) = g(27) = g(39) = g(40) = g(41) = g(58) = 4

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

immutable int limit = 10 ^^ 6 + 6;

auto gm = new int [limit];

int g (int n)
{
	if (gm[n] == 0)
	{
		if (n < 10)
		{
			gm[n] = n;
		}
		else
		{
			gm[n] = n.text
			    .map !(q{a - '0'})
			    .filter !(q{a > 0})
			    .fold !(q{a * b}) (1)
			    .g;
		}
	}
	return gm[n];
}

void main ()
{
	auto gm = limit.iota.map !(g).array;
	auto c = new int [limit] [10];
	foreach (d; 1..10)
	{
		foreach (i; 1..limit)
		{
			c[d][i] = c[d][i - 1] + (gm[i] == d);
		}
	}

	int q;
	while (readf (" %s", &q) > 0)
	{
		foreach (r; 0..q)
		{
			int lo, hi, k;
			readf (" %s %s %s", &lo, &hi, &k);
			writeln (c[k][hi] - c[k][lo - 1]);
		}
	}
}

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

enum LIM = 10^^6 + 10;

void main() {
  auto fs = new int[LIM];
  fs[0] = 1;
  foreach (n; 1 .. LIM) {
    fs[n] = fs[n / 10] * ((n % 10 == 0) ? 1 : (n % 10));
  }
  auto gs = new int[LIM];
  foreach (n; 1 .. LIM) {
    gs[n] = (n < 10) ? n : gs[fs[n]];
  }

  auto nums = new int[][](10, LIM);
  foreach (k; 0 .. 10) {
    foreach (n; 1 .. LIM) {
      nums[k][n] = nums[k][n - 1] + ((gs[n] == k) ? 1 : 0);
    }
  }

  try {
    for (; ; ) {
      const Q = readInt();
      foreach (q; 0 .. Q) {
        const l = readInt();
        const r = readInt();
        const k = readInt();
        const ans = nums[k][r] - nums[k][l - 1];
        writeln(ans);
      }
    }
  } catch (EOFException e) {
  }
}


A positive integer number n is written on a blackboard. It consists of not more than 105 digits. You have to transform it into a beautiful number by erasing some of the digits, and you want to erase as few digits as possible.The number is called beautiful if it consists of at least one digit, doesn't have leading zeroes and is a multiple of 3. For example, 0, 99, 10110 are beautiful numbers, and 00, 03, 122 are not.Write a program which for the given n will find a beautiful number such that n can be transformed into this number by erasing as few digits as possible. You can erase an arbitraty set of digits. For example, they don't have to go one after another in the number n.If it's impossible to obtain a beautiful number, print -1. If there are multiple answers, print any of them.

The first line of input contains n — a positive integer number without leading zeroes (1 ≤ n < 10100000).

Print one number — any beautiful number obtained by erasing as few as possible digits. If there is no answer, print  - 1.

NoteIn the first example it is enough to erase only the first digit to obtain a multiple of 3. But if we erase the first digit, then we obtain a number with a leading zero. So the minimum number of digits to be erased is two.

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

string solve (int [] a, int rem, int num)
{
	auto n = cast (int) (a.length);
	foreach_reverse (i; 0..n)
	{
		if (a[i] % 3 == rem)
		{
			a[i] = -1;
			num -= 1;
			if (num == 0)
			{
				break;
			}
		}
	}
	if (num > 0)
	{
		return "";
	}
	a = a.filter !(x => x != -1).array;
	while (a.length > 1 && a[0] == 0)
	{
		a = a[1..$];
	}
	if (a.length == 0)
	{
		return "";
	}
	return a.map !(x => cast (char) (x + '0')).text;
}

string best (string a, string b)
{
	if (a.length > b.length)
	{
		return a;
	}
	return b;
}

void main ()
{
	string s;
	while ((s = readln.strip) != "")
	{
		auto a = s.map !(x => cast (int) (x - '0')).array;
		auto total = cast (int) (sum (a) % 3);
		auto res = "";
		if (total == 0)
		{
			res = s;
		}
		else
		{
			res = best (res, solve (a.dup, total, 1));
			res = best (res, solve (a.dup, 3 - total, 2));
		}
		if (res == "")
		{
			res = "-1";
		}
		writeln (res);
	}
}


The city of Fishtopia can be imagined as a grid of $$$4$$$ rows and an odd number of columns. It has two main villages; the first is located at the top-left cell $$$(1,1)$$$, people who stay there love fishing at the Tuna pond at the bottom-right cell $$$(4, n)$$$. The second village is located at $$$(4, 1)$$$ and its people love the Salmon pond at $$$(1, n)$$$.The mayor of Fishtopia wants to place $$$k$$$ hotels in the city, each one occupying one cell. To allow people to enter the city from anywhere, hotels should not be placed on the border cells.A person can move from one cell to another if those cells are not occupied by hotels and share a side.Can you help the mayor place the hotels in a way such that there are equal number of shortest paths from each village to its preferred pond?

The first line of input contain two integers, $$$n$$$ and $$$k$$$ ($$$3 \leq n \leq 99$$$, $$$0 \leq k \leq 2\times(n-2)$$$), $$$n$$$ is odd, the width of the city, and the number of hotels to be placed, respectively.

Print "YES", if it is possible to place all the hotels in a way that satisfies the problem statement, otherwise print "NO". If it is possible, print an extra $$$4$$$ lines that describe the city, each line should have $$$n$$$ characters, each of which is "#" if that cell has a hotel on it, or "." if not.

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

void main() {
    auto s = readln.split.map!(to!int);
    auto W = s[0];
    auto K = s[1];
    auto A = new bool[][](4, W);
    auto C = W/2;

    "YES".writeln;

    outer: foreach (i; 1..3) {
        foreach (j; 1..C) {
            if (K <= 1) break outer;
            A[i][j] = true;
            A[i][W-j-1] = true;
            K -= 2;
        }
    }

    foreach (i; 1..3) {
        if (K == 0) break;
        A[i][C] = true;
        K -= 1;
    }

    foreach (i; 0..4) A[i].map!(a => a ? '#' : '.').writeln;
}

import std.stdio;
import std.range;
import std.array;
import std.string;
import std.conv;
import std.typecons;
import std.algorithm;
import std.container;
import std.typecons;
import std.random;
import std.csv;
import std.regex;
import std.math;
import core.time;
import std.ascii;
import std.digest.sha;
import std.outbuffer;
import std.numeric;

void main()
{
	int n, k;
	readln.chomp.split.tie(n, k);
	if (2 * (n - 2) < k) {
		"NO".writeln;
		return;
	}
	"YES".writeln;
	char[][] ans = new char[][](4, n);
	foreach (i; 0..4) {
		foreach (j; 0..n) {
			ans[i][j] = '.';
		}
	}
	// vertical
	for (int i = 1; i <= 2; ++i) {
		if (k < n - 2) {
			break;
		}
		for (int j = 1; j < n - 1; ++j) {
			ans[i][j] = '#';
		}
		k -= n - 2;
	}
	immutable MID = n / 2;
	if (k % 2 == 1) {
		ans[2][MID] = '#';
		--k;
	}
	for (int i = 1; k > 0; ++i) {
		ans[2][MID - i] = ans[2][MID + i] = '#';
		k -= 2;
	}
	foreach (s; ans) {
		foreach (c; s) {
			c.write;
		}
		writeln;
	}
}

void tie(R, Args...)(R arr, ref Args args)
		if (isRandomAccessRange!R || isArray!R)
in
{
	assert (arr.length == args.length);
}
body
{
	foreach (i, ref v; args) {
		alias T = typeof(v);
		v = arr[i].to!T;
	}
}

void verbose(Args...)(in Args args)
{
	stderr.write("[");
	foreach (i, ref v; args) {
		if (i) stderr.write(", ");
		stderr.write(v);
	}
	stderr.writeln("]");
}

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

auto rdsp(){return readln.splitter;}
void pick(R,T)(ref R r,ref T t){t=r.front.to!T;r.popFront;}
void readV(T...)(ref T t){auto r=rdsp;foreach(ref v;t)pick(r,v);}

void main()
{
  int n, k; readV(n, k);

  auto b = new bool[][](4, n);

  if (k%2 == 0) {
    foreach (i; 0..k/2)
      b[1][i+1] = b[2][i+1] = true;
  } else if (k <= n-2) {
    foreach (i; 0..k)
      b[1][i+(n-k)/2] = true;
  } else {
    foreach (i; 0..n-2)
      b[1][i+1] = true;
    auto k2 = k-(n-2)+1;
    foreach (i; 0..k2)
      b[2][i+(n-k2)/2] = true;
    b[2][n/2] = false;
  }

  writeln("YES");
  foreach (i; 0..4) {
    foreach (j; 0..n)
      write(b[i][j] ? "#" : ".");
    writeln;
  }
}

import std.stdio;
import std.range;
import std.array;
import std.string;
import std.conv;
import std.typecons;
import std.algorithm;
import std.container;
import std.typecons;
import std.random;
import std.csv;
import std.regex;
import std.math;
import core.time;
import std.ascii;
import std.digest.sha;
import std.outbuffer;
import std.numeric;

void main()
{
	int n, k;
	readln.chomp.split.tie(n, k);
	if (2 * (n - 2) < k) {
		"NO".writeln;
		return;
	}
	char[][] ans = new char[][](4, n);
	foreach (i; 0..4) {
		foreach (j; 0..n) {
			ans[i][j] = '.';
		}
	}
	loop:
	for (int i = 1; i <= 2; ++i) {
		for (int j = 1; j < n - 1; ++j) {
			if (k == 0) {
				break loop;
			}
			ans[i][j] = '#';
			--k;
		}
	}
	"YES".writeln;
	foreach (s; ans) {
		foreach (c; s) {
			writef("%c", c);
		}
		writeln;
	}
}

void tie(R, Args...)(R arr, ref Args args)
		if (isRandomAccessRange!R || isArray!R)
in
{
	assert (arr.length == args.length);
}
body
{
	foreach (i, ref v; args) {
		alias T = typeof(v);
		v = arr[i].to!T;
	}
}

void verbose(Args...)(in Args args)
{
	stderr.write("[");
	foreach (i, ref v; args) {
		if (i) stderr.write(", ");
		stderr.write(v);
	}
	stderr.writeln("]");
}

import std.stdio;
import std.range;
import std.array;
import std.string;
import std.conv;
import std.typecons;
import std.algorithm;
import std.container;
import std.typecons;
import std.random;
import std.csv;
import std.regex;
import std.math;
import core.time;
import std.ascii;
import std.digest.sha;
import std.outbuffer;
import std.numeric;

void main()
{
	int n, k;
	readln.chomp.split.tie(n, k);
	if (2 * (n - 2) < k) {
		"NO".writeln;
		return;
	}
	char[][] ans = new char[][](4, n);
	foreach (i; 0..4) {
		foreach (j; 0..n) {
			ans[i][j] = '.';
		}
	}
	// vertical
	for (int i = 1; i <= 2; ++i) {
		if (k < n - 2) {
			break;
		}
		for (int j = 1; j < n - 1; ++j) {
			ans[i][j] = '#';
		}
		k -= n - 2;
	}
	immutable MID = n / 2;
	if (k % 2 == 1) {
		ans[2][MID] = '#';
		--k;
	}
	for (int i = 1; k > 0; ++i) {
		ans[2][MID - i] = ans[2][MID + i] = '#';
		k -= 2;
	}
	foreach (s; ans) {
		foreach (c; s) {
			c.write;
		}
		writeln;
	}
}

void tie(R, Args...)(R arr, ref Args args)
		if (isRandomAccessRange!R || isArray!R)
in
{
	assert (arr.length == args.length);
}
body
{
	foreach (i, ref v; args) {
		alias T = typeof(v);
		v = arr[i].to!T;
	}
}

void verbose(Args...)(in Args args)
{
	stderr.write("[");
	foreach (i, ref v; args) {
		if (i) stderr.write(", ");
		stderr.write(v);
	}
	stderr.writeln("]");
}

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

auto rdsp(){return readln.splitter;}
void pick(R,T)(ref R r,ref T t){t=r.front.to!T;r.popFront;}
void readV(T...)(ref T t){auto r=rdsp;foreach(ref v;t)pick(r,v);}

void main()
{
  int n, k; readV(n, k);

  auto isHotel(int i, int j)
  {
    if (i == 0 || i == 3 || j == 0 || j == n-1) return false;
    auto a = j%2 == 1 ? (j-1)*2+(i-1) : (j-2)*2+(i-1)+(n-1);
    return a < k;
  }

  writeln("YES");
  foreach (i; 0..4) {
    foreach (j; 0..n) {
      write(isHotel(i, j) ? "#" : ".");
    }
    writeln;
  }
}

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

auto rdsp(){return readln.splitter;}
void pick(R,T)(ref R r,ref T t){t=r.front.to!T;r.popFront;}
void readV(T...)(ref T t){auto r=rdsp;foreach(ref v;t)pick(r,v);}

void main()
{
  int n, k; readV(n, k);

  auto isHotel(int i, int j)
  {
    if (i == 0 || i == 3 || j == 0 || j == n-1) return false;
    auto a = j%2 == 1 ? (j-1)+(i-1) : (j-2)+(i-1)+(n-1);
    return a < k;
  }

  writeln("YES");
  foreach (i; 0..4) {
    foreach (j; 0..n) {
      write(isHotel(i, j) ? "#" : ".");
    }
    writeln;
  }
}


Treeland is a country in which there are n towns connected by n - 1 two-way road such that it's possible to get from any town to any other town. In Treeland there are 2k universities which are located in different towns. Recently, the president signed the decree to connect universities by high-speed network.The Ministry of Education understood the decree in its own way and decided that it was enough to connect each university with another one by using a cable. Formally, the decree will be done! To have the maximum sum in the budget, the Ministry decided to divide universities into pairs so that the total length of the required cable will be maximum. In other words, the total distance between universities in k pairs should be as large as possible. Help the Ministry to find the maximum total distance. Of course, each university should be present in only one pair. Consider that all roads have the same length which is equal to 1.

The first line of the input contains two integers n and k (2 ≤ n ≤ 200 000, 1 ≤ k ≤ n / 2) — the number of towns in Treeland and the number of university pairs. Consider that towns are numbered from 1 to n.  The second line contains 2k distinct integers u1, u2, ..., u2k (1 ≤ ui ≤ n) — indices of towns in which universities are located.  The next n - 1 line contains the description of roads. Each line contains the pair of integers xj and yj (1 ≤ xj, yj ≤ n), which means that the j-th road connects towns xj and yj. All of them are two-way roads. You can move from any town to any other using only these roads.

Print the maximum possible sum of distances in the division of universities into k pairs.

NoteThe figure below shows one of possible division into pairs in the first test. If you connect universities number 1 and 6 (marked in red) and universities number 2 and 5 (marked in blue) by using the cable, the total distance will equal 6 which will be the maximum sum in this example.

import std.algorithm;
import std.stdio;

void main ()
{
	int n, k;
	while (readf (" %s %s", &n, &k) > 0)
	{
		auto a = new int [] [n];
		auto b = new bool [n];
		b[] = false;
		foreach (i; 0..k * 2)
		{
			int v;
			readf (" %s", &v);
			v--;
			b[v] = true;
		}
		foreach (i; 0..n - 1)
		{
			int u, v;
			readf (" %s %s", &u, &v);
			u--;
			v--;
			a[u] ~= v;
			a[v] ~= u;
		}

		long res = 0;

		int recur (int v, int p)
		{
			int num = 0;
			num += b[v];
			foreach (u; a[v])
			{
				if (u != p)
				{
					int t = recur (u, v);
					res += min (t, 2 * k - t);
					num += t;
				}
			}
			return num;
		}

		recur (0, -1);
		writeln (res);
	}
}

import std.stdio;
import std.algorithm;

int N, K;
int[][] G;
int[] d;
long ans = 0;

void dfs(int v, int par) {
	foreach (u; G[v]) {
		if (u == par) continue;
		dfs(u, v); d[v] += d[u];
	}
	ans += min(d[v], 2 * K - d[v]);
}

void main() {
	readf("%d %d", &N, &K);
	G = new int[][N + 1];
	d = new int[N + 1];
	foreach (i; 0..2*K) {
		int In; readf(" %d", &In); d[In] = 1;
	}
	foreach (i; 1..N) {
		int u, v; readf(" %d %d", &u, &v);
		G[u] ~= v; G[v] ~= u;
	}
	dfs(1, 0);
	writeln(ans);
}


Let's call an undirected graph of n vertices p-interesting, if the following conditions fulfill:   the graph contains exactly 2n + p edges;  the graph doesn't contain self-loops and multiple edges;  for any integer k (1 ≤ k ≤ n), any subgraph consisting of k vertices contains at most 2k + p edges. A subgraph of a graph is some set of the graph vertices and some set of the graph edges. At that, the set of edges must meet the condition: both ends of each edge from the set must belong to the chosen set of vertices. Your task is to find a p-interesting graph consisting of n vertices.

The first line contains a single integer t (1 ≤ t ≤ 5) — the number of tests in the input. Next t lines each contains two space-separated integers: n, p (5 ≤ n ≤ 24; p ≥ 0; ) — the number of vertices in the graph and the interest value for the appropriate test.  It is guaranteed that the required graph exists.

For each of the t tests print 2n + p lines containing the description of the edges of a p-interesting graph: the i-th line must contain two space-separated integers ai, bi (1 ≤ ai, bi ≤ n; ai ≠ bi) — two vertices, connected by an edge in the resulting graph. Consider the graph vertices numbered with integers from 1 to n.  Print the answers to the tests in the order the tests occur in the input. If there are multiple solutions, you can print any of them.

import core.bitop;
import std.algorithm;
import std.array;
import std.bitmanip;
import std.container;
import std.conv;
import std.datetime;
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 solve(int n, int p) {
    Tuple!(int, int)[] ans;
    foreach (i; 0 .. n) {
        ans ~= tuple(i, (i+1) % n);
    }
    foreach (i; 0 .. n) {
        ans ~= tuple(i, (i+2) % n);
    }
    int v = 0, d = 3;
    foreach (_; 0 .. p) {
        ans ~= tuple(v, (v+d) % n);
        v = (v+1) % n;
        if (v == 0) ++d;
    }

    ans.each!(t => writeln(t[0]+1, ' ', t[1]+1));
}

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

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

        solve(n, p);
    }
}

import core.bitop;
import std.algorithm;
import std.array;
import std.bitmanip;
import std.container;
import std.conv;
import std.datetime;
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;

Tuple!(int, int)[] solve(int n, int p) {
    Tuple!(int, int)[] ans;
    foreach (i; 0 .. n) {
        ans ~= tuple(i, (i+1) % n);
    }
    foreach (i; 0 .. n) {
        ans ~= tuple(i, (i+2) % n);
    }
    int v = 0, d = 3;
    foreach (_; 0 .. p) {
        ans ~= tuple(v, (v+d) % n);
        v = (v+1) % n;
        if (v == 0) ++d;
    }

    foreach (ref rw; ans) rw[0] += 1, rw[1] += 1;
    return ans;
}

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

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

        auto ans = solve(n, p);
        ans.each!(t => writeln(t[0], ' ', t[1]));
    }
}

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

void main ()
{
	int tests;
	readf (" %s", &tests);
	foreach (test; 0..tests)
	{
		int n, p;
		readf (" %s %s", &n, &p);
		auto a = new bool [] [] (n, n);
		foreach (i; 0..n)
		{
			int j = (i + 1) % n;
			a[i][j] = a[j][i] = true;
			int k = (j + 1) % n;
			a[i][k] = a[k][i] = true;
		}
		int m = 0;
		foreach (i; 0..n)
		{
			foreach (j; i + 1..n)
			{
				if (m < p && !a[i][j])
				{
					m++;
					a[i][j] = a[j][i] = true;
				}
			}
		}
		foreach (i; 0..n)
		{
			foreach (j; i + 1..n)
			{
				if (a[i][j])
				{
					writefln ("%s %s", i + 1, j + 1);
				}
			}
		}
	}
}

import core.bitop;
import std.algorithm;
import std.array;
import std.bitmanip;
import std.container;
import std.conv;
import std.datetime;
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 solve(int n, int p) {
    Tuple!(int, int)[] ans;
    foreach (i; 0 .. n) {
        ans ~= tuple(i, (i+1) % n);
    }
    foreach (i; 0 .. n) {
        ans ~= tuple(i, (i+2) % n);
    }
    int v = 1, d = 3;
    foreach (_; 0 .. p) {
        ans ~= tuple(v, (v+d) % n);
        v = (v+1) % n;
        if (v == 0) ++d;
    }

    ans.each!(t => writeln(t[0]+1, ' ', t[1]+1));
}

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

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

        solve(n, p);
    }
}


Many countries have such a New Year or Christmas tradition as writing a letter to Santa including a wish list for presents. Vasya is an ordinary programmer boy. Like all ordinary boys, he is going to write the letter to Santa on the New Year Eve (we Russians actually expect Santa for the New Year, not for Christmas). Vasya has come up with an algorithm he will follow while writing a letter. First he chooses two strings, s1 anf s2, consisting of uppercase English letters. Then the boy makes string sk, using a recurrent equation sn = sn - 2 + sn - 1, operation '+' means a concatenation (that is, the sequential record) of strings in the given order. Then Vasya writes down string sk on a piece of paper, puts it in the envelope and sends in to Santa. Vasya is absolutely sure that Santa will bring him the best present if the resulting string sk has exactly x occurrences of substring AC (the short-cut reminds him оf accepted problems). Besides, Vasya decided that string s1 should have length n, and string s2 should have length m. Vasya hasn't decided anything else.At the moment Vasya's got urgent New Year business, so he asks you to choose two strings for him, s1 and s2 in the required manner. Help Vasya.

The first line contains four integers k, x, n, m (3 ≤ k ≤ 50; 0 ≤ x ≤ 109; 1 ≤ n, m ≤ 100).

In the first line print string s1, consisting of n uppercase English letters. In the second line print string s2, consisting of m uppercase English letters. If there are multiple valid strings, print any of them. If the required pair of strings doesn't exist, print "Happy new year!" without the quotes.

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

struct P {
    char a, b;
    long c;
}

P[] gen(int n) {
    if (n == 1) {
        return [P('A', 'A', 0),
                P('C', 'C', 0),
                P('X', 'X', 0)];
    }
    P[] ret;
    static const s = "ACX";
    foreach (i; 0 .. n / 2 + 1) {
        foreach (x; 0 .. 3) {
            foreach (y; 0 .. 3) {
                int r = n - i * 2;
                if (s[x] != 'X') r--;
                if (s[y] != 'X') r--;
                if (r < 0) continue;
                if (n == 2 && s[x] == 'A' && s[y] == 'C') continue;
                ret ~= P(s[x], s[y], i);
            }
        }
    }
    return ret;
}

P step(P a, P b) {
    P ret;
    ret.c = a.c + b.c;
    ret.a = a.a;
    ret.b = b.b;
    if (a.b == 'A' && b.a == 'C') {
        ret.c++;
    }
    return ret;
}

long stepK(P a, P b, int k) {
    P t;
    foreach (i; 0 .. k) {
        t = step(a, b);
        a = b;
        b = t;
    }
    return t.c;
}

string format(P p, int n) {
    if (n == 1) {
        return p.a.to!string;
    }
    string ret;
    if (p.a != 'X') n--;
    if (p.b != 'X') n--;
    foreach (i; 0 .. p.c) {
        ret ~= "AC";
    }
    foreach (i; ret.length .. n) {
        ret ~= 'X';
    }
    if (p.a != 'X') ret = p.a ~ ret;
    if (p.b != 'X') ret ~= p.b;
    return ret;
}

void main() {
    int k, x, n, m;
    readf("%d %d %d %d\n", &k, &x, &n, &m);
    P[] a, b;
    a = gen(n);
    b = gen(m);
    foreach (i; a) {
        foreach (j; b) {
            if (stepK(i, j, k - 2) == x) {
                writeln(format(i, n));
                writeln(format(j, m));
                return;
            }
        }
    }
    writeln("Happy new year!");
}

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

string solve (int k, int x, int n, int m)
{
	string [2] res;
	bool found = false;

	alias Tuple !(bool, "b", bool, "e", long, "num") part;
	auto cur = new part [k];
	int [2] d = [n, m];

	string build (int p)
	{
		auto c = cur[p];
		string res = "";
		if (c.b)
		{
			res ~= 'C';
		}
		foreach (i; 0..c.num)
		{
			res ~= "AC";
		}
		foreach (i; c.b + c.e + c.num * 2..d[p])
		{
			res ~= 'B';
		}
		if (c.e)
		{
			res ~= 'A';
		}
		return res;
	}

	void gen (int p)
	{
		if (p == 2)
		{
			foreach (i; 2..k)
			{
				cur[i] = part (cur[i - 2].b,
				               cur[i - 1].e,
				               cur[i - 2].num +
				               cur[i - 1].num +
				               (cur[i - 2].e &&
				                cur[i - 1].b));
			}
			if (cur[k - 1].num == x && !found)
			{
				foreach (i; 0..2)
				{
					res[i] = build (i);
				}
			}
		}
		else
		{
			foreach (b; 0..2)
			{
				foreach (e; 0..2)
				{
					int num = 0;
					while (b + e + num * 2 <= d[p])
					{
						cur[p] = part (cast (bool) b,
						               cast (bool) e,
						               num);
						gen (p + 1);
						num++;
					}
				}
			}
		}
	}

	gen (0);

	if (res == ["", ""])
	{
		return "Happy new year!";
	}
	return res[0] ~ '\n' ~ res[1];
}

void main ()
{
	int k, x, n, m;
	while (readf (" %s %s %s %s", &k, &x, &n, &m) > 0)
	{
		writeln (solve (k, x, n, m));
	}
}

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

struct P {
    char a, b;
    int c;
}

P[] gen(int n) {
    P[] ret;
    static const s = "ACX";
    foreach (i; 0 .. n / 2 + 1) {
        foreach (x; 0 .. 3) {
            foreach (y; 0 .. 3) {
                int r = n - i * 2;
                if (s[x] != 'X') r--;
                if (s[y] != 'X') r--;
                if (r < 0) continue;
                ret ~= P(s[x], s[y], i);
            }
        }
    }
    return ret;
}

P step(P a, P b) {
    P ret;
    ret.c = a.c + b.c;
    ret.a = a.a;
    ret.b = b.b;
    if (a.b == 'A' && b.a == 'C') {
        ret.c++;
    }
    return ret;
}

int stepK(P a, P b, int k) {
    P t;
    foreach (i; 0 .. k) {
        t = step(a, b);
        a = b;
        b = t;
    }
    return t.c;
}

string format(P p, int n) {
    string ret;
    if (p.a != 'X') n--;
    if (p.b != 'X') n--;
    if (p.a != 'X') ret ~= p.a;
    foreach (i; 0 .. p.c) {
        ret ~= "AC";
    }
    foreach (i; ret.length .. n) {
        ret ~= 'X';
    }
    if (p.b != 'X') ret ~= p.b;
    return ret;
}

void main() {
    int k, x, n, m;
    readf("%d %d %d %d\n", &k, &x, &n, &m);
    P[] a, b;
    a = gen(n);
    b = gen(m);
    foreach (i; a) {
        foreach (j; b) {
            if (stepK(i, j, k - 2) == x) {
                writeln(format(i, n));
                writeln(format(j, m));
                return;
            }
        }
    }
    writeln("Happy new year!");
}

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

struct P {
    char a, b;
    int c;
}

P[] gen(int n) {
    P[] ret;
    static const s = "ACX";
    foreach (i; 0 .. n / 2 + 1) {
        foreach (x; 0 .. 3) {
            foreach (y; 0 .. 3) {
                int r = n - i * 2;
                if (s[x] != 'X') r--;
                if (s[y] != 'X') r--;
                if (r < 0) continue;
                ret ~= P(s[x], s[y], i);
            }
        }
    }
    return ret;
}

P step(P a, P b) {
    P ret;
    ret.c = a.c + b.c;
    ret.a = a.a;
    ret.b = b.b;
    if (a.b == 'A' && b.a == 'C') {
        ret.c++;
    }
    return ret;
}

int stepK(P a, P b, int k) {
    P t;
    foreach (i; 0 .. k) {
        t = step(a, b);
        a = b;
        b = t;
    }
    return t.c;
}

string format(P p, int n) {
    string ret;
    if (p.a != 'X') n--;
    if (p.b != 'X') n--;
    foreach (i; 0 .. p.c) {
        ret ~= "AC";
    }
    foreach (i; ret.length .. n) {
        ret ~= 'X';
    }
    if (p.a != 'X') ret = p.a ~ ret;
    if (p.a != 'X') ret ~= p.b;
    return ret;
}

void main() {
    int k, x, n, m;
    readf("%d %d %d %d\n", &k, &x, &n, &m);
    P[] a, b;
    a = gen(n);
    b = gen(m);
    foreach (i; a) {
        foreach (j; b) {
            if (stepK(i, j, k - 2) == x) {
                writeln(format(i, n));
                writeln(format(j, m));
                return;
            }
        }
    }
    writeln("Happy new year!");
}

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

struct P {
    char a, b;
    int c;
}

P[] gen(int n) {
    P[] ret;
    static const s = "ACX";
    foreach (i; 0 .. n / 2 + 1) {
        foreach (x; 0 .. 3) {
            foreach (y; 0 .. 3) {
                int r = n - i * 2;
                if (s[x] != 'X') r--;
                if (s[y] != 'X') r--;
                if (r < 0) continue;
                ret ~= P(s[x], s[y], i);
            }
        }
    }
    return ret;
}

P step(P a, P b) {
    P ret;
    ret.c = a.c + b.c;
    ret.a = a.a;
    ret.b = b.b;
    if (a.b == 'A' && b.a == 'C') {
        ret.c++;
    }
    return ret;
}

int stepK(P a, P b, int k) {
    P t;
    foreach (i; 0 .. k) {
        t = step(a, b);
        a = b;
        b = t;
    }
    return t.c;
}

string format(P p, int n) {
    string ret;
    if (p.a != 'X') n--;
    if (p.b != 'X') n--;
    foreach (i; 0 .. p.c) {
        ret ~= "AC";
    }
    foreach (i; ret.length .. n) {
        ret ~= 'X';
    }
    if (p.a != 'X') ret = p.a ~ ret;
    if (p.b != 'X') ret ~= p.b;
    return ret;
}

void main() {
    int k, x, n, m;
    readf("%d %d %d %d\n", &k, &x, &n, &m);
    P[] a, b;
    a = gen(n);
    b = gen(m);
    foreach (i; a) {
        foreach (j; b) {
            if (stepK(i, j, k - 2) == x) {
                writeln(format(i, n));
                writeln(format(j, m));
                return;
            }
        }
    }
    writeln("Happy new year!");
}

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

struct P {
    char a, b;
    long c;
}

P[] gen(int n) {
    P[] ret;
    static const s = "ACX";
    foreach (i; 0 .. n / 2 + 1) {
        foreach (x; 0 .. 3) {
            foreach (y; 0 .. 3) {
                int r = n - i * 2;
                if (s[x] != 'X') r--;
                if (s[y] != 'X') r--;
                if (r < 0) continue;
                ret ~= P(s[x], s[y], i);
            }
        }
    }
    return ret;
}

P step(P a, P b) {
    P ret;
    ret.c = a.c + b.c;
    ret.a = a.a;
    ret.b = b.b;
    if (a.b == 'A' && b.a == 'C') {
        ret.c++;
    }
    return ret;
}

long stepK(P a, P b, int k) {
    P t;
    foreach (i; 0 .. k) {
        t = step(a, b);
        a = b;
        b = t;
    }
    return t.c;
}

string format(P p, int n) {
    string ret;
    if (p.a != 'X') n--;
    if (p.b != 'X') n--;
    foreach (i; 0 .. p.c) {
        ret ~= "AC";
    }
    foreach (i; ret.length .. n) {
        ret ~= 'X';
    }
    if (p.a != 'X') ret = p.a ~ ret;
    if (p.b != 'X') ret ~= p.b;
    return ret;
}

void main() {
    int k, x, n, m;
    readf("%d %d %d %d\n", &k, &x, &n, &m);
    P[] a, b;
    a = gen(n);
    b = gen(m);
    foreach (i; a) {
        foreach (j; b) {
            if (stepK(i, j, k - 2) == x) {
                writeln(format(i, n));
                writeln(format(j, m));
                return;
            }
        }
    }
    writeln("Happy new year!");
}

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

struct P {
    char a, b;
    long c;
}

P[] gen(int n) {
    if (n == 1) {
        return [P('A', 'A', 0),
                P('C', 'C', 0),
                P('X', 'X', 0)];
    }
    P[] ret;
    static const s = "ACX";
    foreach (i; 0 .. n / 2 + 1) {
        foreach (x; 0 .. 3) {
            foreach (y; 0 .. 3) {
                int r = n - i * 2;
                if (s[x] != 'X') r--;
                if (s[y] != 'X') r--;
                if (r < 0) continue;
                ret ~= P(s[x], s[y], i);
            }
        }
    }
    return ret;
}

P step(P a, P b) {
    P ret;
    ret.c = a.c + b.c;
    ret.a = a.a;
    ret.b = b.b;
    if (a.b == 'A' && b.a == 'C') {
        ret.c++;
    }
    return ret;
}

long stepK(P a, P b, int k) {
    P t;
    foreach (i; 0 .. k) {
        t = step(a, b);
        a = b;
        b = t;
    }
    return t.c;
}

string format(P p, int n) {
    if (n == 1) {
        return p.a.to!string;
    }
    string ret;
    if (p.a != 'X') n--;
    if (p.b != 'X') n--;
    foreach (i; 0 .. p.c) {
        ret ~= "AC";
    }
    foreach (i; ret.length .. n) {
        ret ~= 'X';
    }
    if (p.a != 'X') ret = p.a ~ ret;
    if (p.b != 'X') ret ~= p.b;
    return ret;
}

void main() {
    int k, x, n, m;
    readf("%d %d %d %d\n", &k, &x, &n, &m);
    P[] a, b;
    a = gen(n);
    b = gen(m);
    foreach (i; a) {
        foreach (j; b) {
            if (stepK(i, j, k - 2) == x) {
                writeln(format(i, n));
                writeln(format(j, m));
                return;
            }
        }
    }
    writeln("Happy new year!");
}

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

struct P {
    char a, b;
    int c;
}

P[] gen(int n) {
    P[] ret;
    static const s = "ACX";
    foreach (i; 0 .. n / 2 + 1) {
        foreach (x; 0 .. 3) {
            foreach (y; 0 .. 3) {
                int r = n - i * 2;
                if (s[x] != 'X') r--;
                if (s[y] != 'X') r--;
                if (r < 0) continue;
                ret ~= P(s[x], s[y], i);
            }
        }
    }
    return ret;
}

P step(P a, P b) {
    P ret;
    ret.c = a.c + b.c;
    ret.a = a.a;
    ret.b = b.b;
    if (a.b == 'A' && b.a == 'C') {
        ret.c++;
    }
    return ret;
}

int stepK(P a, P b, int k) {
    P t;
    foreach (i; 0 .. k) {
        t = step(a, b);
        a = b;
        b = t;
    }
    return t.c;
}

string format(P p, int n) {
    string ret;
    if (p.a != 'X') n--;
    if (p.b != 'X') n--;
    if (p.a != 'X') ret ~= p.a;
    foreach (i; 0 .. n / 2) {
        ret ~= "AC";
    }
    foreach (i; ret.length .. n) {
        ret ~= 'X';
    }
    if (p.b != 'X') ret ~= p.b;
    return ret;
}

void main() {
    int k, x, n, m;
    readf("%d %d %d %d\n", &k, &x, &n, &m);
    P[] a, b;
    a = gen(n);
    b = gen(m);
    foreach (i; a) {
        foreach (j; b) {
            if (stepK(i, j, k - 2) == x) {
                writeln(format(i, n));
                writeln(format(j, m));
                return;
            }
        }
    }
    writeln("Happy new year!");
}