Arcady is a copywriter. His today's task is to type up an already well-designed story using his favorite text editor.Arcady types words, punctuation signs and spaces one after another. Each letter and each sign (including line feed) requires one keyboard click in order to be printed. Moreover, when Arcady has a non-empty prefix of some word on the screen, the editor proposes a possible autocompletion for this word, more precisely one of the already printed words such that its prefix matches the currently printed prefix if this word is unique. For example, if Arcady has already printed «codeforces», «coding» and «codeforces» once again, then there will be no autocompletion attempt for «cod», but if he proceeds with «code», the editor will propose «codeforces».With a single click Arcady can follow the editor's proposal, i.e. to transform the current prefix to it. Note that no additional symbols are printed after the autocompletion (no spaces, line feeds, etc). What is the minimum number of keyboard clicks Arcady has to perform to print the entire text, if he is not allowed to move the cursor or erase the already printed symbols?A word here is a contiguous sequence of latin letters bordered by spaces, punctuation signs and line/text beginnings/ends. Arcady uses only lowercase letters. For example, there are 20 words in «it's well-known that tic-tac-toe is a paper-and-pencil game for two players, x and o.».

The only line contains Arcady's text, consisting only of lowercase latin letters, spaces, line feeds and the following punctuation signs: «.», «,», «?», «!», «'» and «-». The total amount of symbols doesn't exceed 3·105. It's guaranteed that all lines are non-empty.

Print a single integer — the minimum number of clicks.

snow affects sports such as skiing, snowboarding, and snowmachine travel.
snowboarding is a recreational activity and olympic and paralympic sport.

thun-thun-thunder, thunder, thunder
thunder, thun-, thunder
thun-thun-thunder, thunder
thunder, feel the thunder
lightning then the thunder
thunder, feel the thunder
lightning then the thunder
thunder, thunder

NoteIn sample case one it's optimal to use autocompletion for the first instance of «snowboarding» after typing up «sn» and for the second instance of «snowboarding» after typing up «snowb». This will save 7 clicks.In sample case two it doesn't matter whether to use autocompletion or not.

import core.bitop, std.algorithm, std.bigint, std.compiler, std.container,
	std.bitmanip, std.conv, std.math;
import std.numeric : Fft, fft, gcd, inverseFft;
import std.random, std.range, std.regex, std.stdio, std.string, std.traits,
	std.typecons, std.uni;

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;
///modulo
const int mod = 10 ^^ 9 + 7, mod2 = mod + 2;
public
{
	pure nothrow
	{
		///make_pair
		pair!(X, Y) make_pair(X, Y)(in X x_, in Y y_)
		{
			return tuple!(X, "fi", Y, "se")(x_, y_);
		}
		///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);
		}
	}
	static if (version_minor >= 74)
	{
		///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;
		}
	}
	else
	{
		///read without format
		bool input(T...)(ref T ptrs) if (ptrs.length > 0)
		{
			size_t s;
			foreach (ref e; ptrs)
			{
				if (isSomeChar!(Unqual!(typeof(e))))
					s += readf(" %c", &e);
				else
					s += readf(" %s", &e);
			}
			return s == ptrs.length;
		}
		///readln without format
		bool read(T...)(ref T ptrs) if (ptrs.length > 0)
		{
			size_t s;
			foreach (ref e; ptrs)
			{
				if (isSomeChar!(Unqual!(typeof(e))))
					s += readf(" %c", &e);
				else
					s += readf(" %s", &e);
			}
			readln;
			return s == ptrs.length;
		}
	}
	///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()
{
	version (home)
	{
		assert(freopen("input.txt", "r", core.stdc.stdio.stdin));
	}
	struct node
	{
		bool leaf;
		int cnt;
		int[26] go;
	}

	node[] tr;
	tr.length = 2;
	long gans;
	void add(string s)
	{
		int ans;
		bool fl;
		int len;
		int v = 1;
		tr[v].cnt++;
		foreach (int i; 0 .. cast(int) s.length)
		{
			char c = s[i];
			assert(isAlpha(c));
			// debug enter(c);
			if (tr[v].go[c - 'a'] == 0)
			{
				if (fl && tr[v].leaf && len < i)
				{
					ans -= i;
					ans += len + 1;
				}
				fl = 0;
				tr[v].go[c - 'a'] = cast(int) tr.length;
				tr.length++;
			}
			v = tr[v].go[c - 'a'];
			if (tr[v].cnt == 1 && len == 0)
			{
				fl = 1;
				len = i + 1;
			}
			ans++;
		}
		if (fl && tr[v].leaf && len < cast(int) s.length)
		{
			ans -= s.length;
			ans += len + 1;
		}
		gans += ans;
		if (!tr[v].leaf)
		{
			tr[v].leaf = 1;
			v = 1;
			foreach (c; s)
			{
				tr[v].cnt++;
				v = tr[v].go[c - 'a'];
			}
			tr[v].cnt++;
		}
		debug write(ans, ' ', s, '\n');
	}

	bool sep(char c)
	{
		return c == '\n' || c == ' ' || c == '.' || c == ',' || c == '\''
			|| c == '?' || c == '!' || c == '-';
	}
	//38
	string buf;
	int k;
	while (true)
	{
		buf = readln.strip;
		if (buf.length == 0)
			break;
		k++;
		foreach (c; buf)
		{
			if (sep(c))
				gans++;
		}
		auto a = buf.splitter(ctRegex!(`[.,' ?!-]`)).filter!(x => !x.empty);
		foreach (x; a)
		{
			add(x);
		}
	}
	// debug writeln(k, ' ', gans);
	writeln(gans + k);
}

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;

string text;
string nextWord()
{
  int len = 0;
  auto ntext = text;
  while(!ntext.empty && ntext[0].isAlpha)
    {
      ntext = ntext[1 .. $];
      len++;
    }
  auto res = text[0 .. len];
  text = ntext;
  return res;
}
string nextNonWord()
{
  int len = 0;
  auto ntext = text;
  while(!ntext.empty && !ntext[0].isAlpha)
    {
      ntext = ntext[1 .. $];
      len++;
    }
  auto res = text[0 .. len];
  text = ntext;
  return res;
}

class ptNode
{
  ptNode[26] chTrans;
  bool isTerminal;
  int noTerminalDescendants;
}

int insert(ptNode root, string str)
{
  ptNode node = root;
  auto nodePath = new ptNode[](1);
  nodePath[0] = root;
  auto origstr = str;
  bool isnew = false;
  while(!str.empty)
    {
      if (node.chTrans[str[0] - 'a'] is null)
	node.chTrans[str[0] - 'a'] = new ptNode;
      node = node.chTrans[str[0] - 'a'];
      str = str[1 .. $];
      nodePath ~= node;
    }
  isnew = !nodePath[$ - 1].isTerminal;
  str = origstr;
  int lc = -1;
  int hc = -1;
  foreach(i, pnode; nodePath)
    {
      if (pnode.noTerminalDescendants == 1 && pnode !is root)
	{
	  if (lc == -1)
	    {
	      lc = cast(int)i;
	      hc = cast(int)i;
	    }
	  else
	    {
	      hc = cast(int)i;
	    }
	}
      if (isnew) pnode.noTerminalDescendants++;
    }
  int res = 0;
  if (lc != -1 && nodePath[hc].isTerminal && hc - lc > 1)
    res = cast(int) str.length - (hc - lc) + 1;
  else
    res = cast(int) str.length;
  nodePath[$ - 1].isTerminal = true;
  return res;
}

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

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

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

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

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;

string text;
string nextWord()
{
  string res = null;
  while(!text.empty && text[0].isAlpha)
    {
      res ~= text[0];
      text = text[1 .. $];
    }
  return res;
}
string nextNonWord()
{
  string res = null;
  while(!text.empty && !text[0].isAlpha)
    {
      res ~= text[0];
      text = text[1 .. $];
    }
  return res;
}

class ptNode
{
  ptNode[30] chTrans;
  bool isTerminal;
  int noTerminalDescendants;
}

int insert(ptNode root, string str)
{
  int surelyInserted = 0;
  int probablyCompleted = 0;
  ptNode node = root;
  auto nodePath = new ptNode[](1);
  nodePath[0] = root;
  auto origstr = str;
  bool isnew = false;
  bool iscompleted = false;
  while(!str.empty)
    {
      if (node.chTrans[str[0] - 'a'] is null)
	{
	  node.chTrans[str[0] - 'a'] = new ptNode;
	}
      node = node.chTrans[str[0] - 'a'];
      str = str[1 .. $];
      nodePath ~= node;
    }
  isnew = !nodePath[$ - 1].isTerminal;
  str = origstr;
  int lc = int.max;
  int hc = int.min;
  foreach(i, pnode; nodePath)
    {
      if (pnode.noTerminalDescendants == 1 && pnode !is root)
	{
	  lc = min(cast(int) i, lc);
	  hc = max(cast(int) i, hc);
	}
      if (isnew) pnode.noTerminalDescendants++;
    }
  int res = 0;
  debug writeln("doing ", str);
  if (lc != int.max && nodePath[hc].isTerminal)
    {
      assert(hc >= lc);
      if (hc - lc > 1)
	{
	  debug writeln("for word ", str, " saved ", hc - lc - 1);
	  debug writeln("from ", lc, " - ", hc);
	  res = cast(int) str.length - (hc - lc) + 1;
	}
      else
	res = cast(int) str.length;
    }
  else
    {
      res = cast(int) str.length;
    }
  nodePath[$ - 1].isTerminal = true;
  return res;
}

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

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

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

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

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;

string text;
string nextWord()
{
  int len = 0;
  auto ntext = text;
  while(!ntext.empty && ntext[0].isAlpha)
    {
      ntext = ntext[1 .. $];
      len++;
    }
  auto res = text[0 .. len];
  text = ntext;
  return res;
}
string nextNonWord()
{
  int len = 0;
  auto ntext = text;
  while(!ntext.empty && !ntext[0].isAlpha)
    {
      ntext = ntext[1 .. $];
      len++;
    }
  auto res = text[0 .. len];
  text = ntext;
  return res;
}

class ptNode
{
  ptNode[26] chTrans;
  bool isTerminal;
  int noTerminalDescendants;
}

int insert(ptNode root, string str)
{
  ptNode node = root;
  auto nodePath = new ptNode[](1);
  nodePath[0] = root;
  auto origstr = str;
  bool isnew = false;
  while(!str.empty)
    {
      if (node.chTrans[str[0] - 'a'] is null)
	node.chTrans[str[0] - 'a'] = new ptNode;
      node = node.chTrans[str[0] - 'a'];
      str = str[1 .. $];
      nodePath ~= node;
    }
  isnew = !nodePath[$ - 1].isTerminal;
  str = origstr;
  int lc = int.max;
  int hc = int.min;
  foreach(i, pnode; nodePath)
    {
      if (pnode.noTerminalDescendants == 1 && pnode !is root)
	{
	  lc = min(cast(int) i, lc);
	  hc = max(cast(int) i, hc);
	}
      if (isnew) pnode.noTerminalDescendants++;
    }
  int res = 0;
  if (lc != int.max && nodePath[hc].isTerminal && hc - lc > 1)
    res = cast(int) str.length - (hc - lc) + 1;
  else
    res = cast(int) str.length;
  nodePath[$ - 1].isTerminal = true;
  return res;
}

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

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

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

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

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;

string text;
string nextWord()
{
  string res = null;
  while(!text.empty && text[0].isAlpha)
    {
      res ~= text[0];
      text = text[1 .. $];
    }
  return res;
}
string nextNonWord()
{
  string res = null;
  while(!text.empty && !text[0].isAlpha)
    {
      res ~= text[0];
      text = text[1 .. $];
    }
  return res;
}

class ptNode
{
  ptNode[26] chTrans;
  bool isTerminal;
  int noTerminalDescendants;
}

int insert(ptNode root, string str)
{
  int surelyInserted = 0;
  int probablyCompleted = 0;
  ptNode node = root;
  auto nodePath = new ptNode[](1);
  nodePath[0] = root;
  auto origstr = str;
  bool isnew = false;
  bool iscompleted = false;
  while(!str.empty)
    {
      if (node.chTrans[str[0] - 'a'] is null)
	{
	  node.chTrans[str[0] - 'a'] = new ptNode;
	}
      node = node.chTrans[str[0] - 'a'];
      str = str[1 .. $];
      nodePath ~= node;
    }
  isnew = !nodePath[$ - 1].isTerminal;
  str = origstr;
  int lc = int.max;
  int hc = int.min;
  foreach(i, pnode; nodePath)
    {
      if (pnode.noTerminalDescendants == 1 && pnode !is root)
	{
	  lc = min(cast(int) i, lc);
	  hc = max(cast(int) i, hc);
	}
      if (isnew) pnode.noTerminalDescendants++;
    }
  int res = 0;
  debug writeln("doing ", str);
  if (lc != int.max && nodePath[hc].isTerminal)
    {
      assert(hc >= lc);
      if (hc - lc > 1)
	{
	  debug writeln("for word ", str, " saved ", hc - lc - 1);
	  debug writeln("from ", lc, " - ", hc);
	  res = cast(int) str.length - (hc - lc) + 1;
	}
      else
	res = cast(int) str.length;
    }
  else
    {
      res = cast(int) str.length;
    }
  nodePath[$ - 1].isTerminal = true;
  return res;
}

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

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

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

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

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;

string text;
string nextWord()
{
  string res = null;
  while(!text.empty && text[0].isAlpha)
    {
      res ~= text[0];
      text = text[1 .. $];
    }
  return res;
}
string nextNonWord()
{
  string res = null;
  while(!text.empty && !text[0].isAlpha)
    {
      res ~= text[0];
      text = text[1 .. $];
    }
  return res;
}

class ptNode
{
  ptNode[30] chTrans;
  bool isTerminal;
  int noTerminalDescendants;
}

int insert(ptNode root, string str)
{
  int surelyInserted = 0;
  int probablyCompleted = 0;
  ptNode node = root;
  auto nodePath = new ptNode[](1);
  nodePath[0] = root;
  auto origstr = str;
  bool isnew = false;
  bool iscompleted = false;
  while(!str.empty)
    {
      if (node.chTrans[str[0] - 'a'] is null)
	{
	  isnew = true;
	  node.chTrans[str[0] - 'a'] = new ptNode;
	}
      node = node.chTrans[str[0] - 'a'];
      str = str[1 .. $];
      nodePath ~= node;
    }
  str = origstr;
  int lc = int.max;
  int hc = int.min;
  foreach(i, pnode; nodePath)
    {
      if (pnode.noTerminalDescendants == 1 && pnode !is root)
	{
	  lc = min(cast(int) i, lc);
	  hc = max(cast(int) i, hc);
	}
      if (isnew) pnode.noTerminalDescendants++;
    }
  int res = 0;
  debug writeln("doing ", str);
  if (lc != int.max && nodePath[hc].isTerminal)
    {
      assert(hc >= lc);
      if (hc - lc > 1)
	{
	  debug writeln("for word ", str, " saved ", hc - lc - 1);
	  debug writeln("from ", lc, " - ", hc);
	  res = cast(int) str.length - (hc - lc) + 1;
	}
      else
	res = cast(int) str.length;
    }
  else
    {
      res = cast(int) str.length;
    }
  nodePath[$ - 1].isTerminal = true;
  return res;
}

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

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

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

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

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;

string text;
string nextWord()
{
  string res = text[0 .. 0];
  while(!text.empty && text[0].isAlpha)
    {
      res.length++;
      text = text[1 .. $];
    }
  return res;
}
string nextNonWord()
{
  string res = text[0 .. 0];
  while(!text.empty && !text[0].isAlpha)
    {
      res.length++;
      text = text[1 .. $];
    }
  return res;
}

class ptNode
{
  ptNode[26] chTrans;
  bool isTerminal;
  int noTerminalDescendants;
}

int insert(ptNode root, string str)
{
  ptNode node = root;
  auto nodePath = new ptNode[](1);
  nodePath[0] = root;
  auto origstr = str;
  bool isnew = false;
  while(!str.empty)
    {
      if (node.chTrans[str[0] - 'a'] is null)
	node.chTrans[str[0] - 'a'] = new ptNode;
      node = node.chTrans[str[0] - 'a'];
      str = str[1 .. $];
      nodePath ~= node;
    }
  isnew = !nodePath[$ - 1].isTerminal;
  str = origstr;
  int lc = int.max;
  int hc = int.min;
  foreach(i, pnode; nodePath)
    {
      if (pnode.noTerminalDescendants == 1 && pnode !is root)
	{
	  lc = min(cast(int) i, lc);
	  hc = max(cast(int) i, hc);
	}
      if (isnew) pnode.noTerminalDescendants++;
    }
  int res = 0;
  if (lc != int.max && nodePath[hc].isTerminal && hc - lc > 1)
    res = cast(int) str.length - (hc - lc) + 1;
  else
    res = cast(int) str.length;
  nodePath[$ - 1].isTerminal = true;
  return res;
}

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

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

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

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


The length of the longest common prefix of two strings $$$s = s_1 s_2 \ldots s_n$$$ and $$$t = t_1 t_2 \ldots t_m$$$ is defined as the maximum integer $$$k$$$ ($$$0 \le k \le min(n,m)$$$) such that $$$s_1 s_2 \ldots s_k$$$ equals $$$t_1 t_2 \ldots t_k$$$.Koa the Koala initially has $$$n+1$$$ strings $$$s_1, s_2, \dots, s_{n+1}$$$.For each $$$i$$$ ($$$1 \le i \le n$$$) she calculated $$$a_i$$$ — the length of the longest common prefix of $$$s_i$$$ and $$$s_{i+1}$$$.Several days later Koa found these numbers, but she couldn't remember the strings.So Koa would like to find some strings $$$s_1, s_2, \dots, s_{n+1}$$$ which would have generated numbers $$$a_1, a_2, \dots, a_n$$$. Can you help her?If there are many answers print any. We can show that answer always exists for the given constraints.

Each test contains multiple test cases. The first line contains $$$t$$$ ($$$1 \le t \le 100$$$) — the number of test cases. Description of the test cases follows. The first line of each test case contains a single integer $$$n$$$ ($$$1 \le n \le 100$$$) — the number of elements in the list $$$a$$$. The second line of each test case contains $$$n$$$ integers $$$a_1, a_2, \ldots, a_n$$$ ($$$0 \le a_i \le 50$$$) — the elements of $$$a$$$. It is guaranteed that the sum of $$$n$$$ over all test cases does not exceed $$$100$$$.

For each test case: Output $$$n+1$$$ lines. In the $$$i$$$-th line print string $$$s_i$$$ ($$$1 \le |s_i| \le 200$$$), consisting of lowercase Latin letters. Length of the longest common prefix of strings $$$s_i$$$ and $$$s_{i+1}$$$ has to be equal to $$$a_i$$$. If there are many answers print any. We can show that answer always exists for the given constraints.

aeren
ari
arousal
around
ari
monogon
monogamy
monthly
kevinvu
kuroni
kurioni
korone
anton
loves
adhoc
problems

NoteIn the $$$1$$$-st test case one of the possible answers is $$$s = [aeren, ari, arousal, around, ari]$$$.Lengths of longest common prefixes are:  Between $$$\color{red}{a}eren$$$ and $$$\color{red}{a}ri$$$ $$$\rightarrow 1$$$  Between $$$\color{red}{ar}i$$$ and $$$\color{red}{ar}ousal$$$ $$$\rightarrow 2$$$  Between $$$\color{red}{arou}sal$$$ and $$$\color{red}{arou}nd$$$ $$$\rightarrow 4$$$  Between $$$\color{red}{ar}ound$$$ and $$$\color{red}{ar}i$$$ $$$\rightarrow 2$$$

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

immutable int len = 51;

void main ()
{
	auto tests = readln.strip.to !(int);
	foreach (test; 0..tests)
	{
		auto n = readln.strip.to !(int);
		auto s = 'b'.repeat (len).array;
		writeln (s);
		foreach (pos; readln.splitter.map !(to !(int)))
		{
			s[pos] ^= 1;
			writeln (s);
		}
	}
}


A non-empty string is called palindrome, if it reads the same from the left to the right and from the right to the left. For example, "abcba", "a", and "abba" are palindromes, while "abab" and "xy" are not.A string is called a substring of another string, if it can be obtained from that string by dropping some (possibly zero) number of characters from the beginning and from the end of it. For example, "abc", "ab", and "c" are substrings of the string "abc", while "ac" and "d" are not.Let's define a palindromic count of the string as the number of its substrings that are palindromes. For example, the palindromic count of the string "aaa" is $$$6$$$ because all its substrings are palindromes, and the palindromic count of the string "abc" is $$$3$$$ because only its substrings of length $$$1$$$ are palindromes.You are given a string $$$s$$$. You can arbitrarily rearrange its characters. You goal is to obtain a string with the maximum possible value of palindromic count.

The first line contains an integer $$$n$$$ ($$$1 \le n \le 100\,000$$$) — the length of string $$$s$$$. The second line contains string $$$s$$$ that consists of exactly $$$n$$$ lowercase characters of Latin alphabet.

Print string $$$t$$$, which consists of the same set of characters (and each characters appears exactly the same number of times) as string $$$s$$$. Moreover, $$$t$$$ should have the maximum possible value of palindromic count among all such strings strings. If there are multiple such strings, print any of them.

NoteIn the first example, string "ololo" has $$$9$$$ palindromic substrings: "o", "l", "o", "l", "o", "olo", "lol", "olo", "ololo". Note, that even though some substrings coincide, they are counted as many times as they appear in the resulting string.In the second example, the palindromic count of string "abccbaghghghgdfd" is $$$29$$$.

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

void main ()
{
	int n;
	while (readf (" %s", &n) > 0)
	{
		readln;
		auto s = readln.strip;
		auto b = s.dup;
		sort (representation (b));
		writeln (b);
	}
}

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

void main() {
    readln;
    auto s = readln.chomp.to!(dchar[]).sort();
    writeln(s);
}

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

    auto line = readln().splitter();
    foreach (ref arg; args) {
        arg = line.front.to!(typeof(arg));
        line.popFront();
    }
    assert(line.empty);
}

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


A permutation of length n is an array containing each integer from 1 to n exactly once. For example, q = [4, 5, 1, 2, 3] is a permutation. For the permutation q the square of permutation is the permutation p that p[i] = q[q[i]] for each i = 1... n. For example, the square of q = [4, 5, 1, 2, 3] is p = q2 = [2, 3, 4, 5, 1].This problem is about the inverse operation: given the permutation p you task is to find such permutation q that q2 = p. If there are several such q find any of them.

The first line contains integer n (1 ≤ n ≤ 106) — the number of elements in permutation p. The second line contains n distinct integers p1, p2, ..., pn (1 ≤ pi ≤ n) — the elements of permutation p.

If there is no permutation q such that q2 = p print the number "-1". If the answer exists print it. The only line should contain n different integers qi (1 ≤ qi ≤ n) — the elements of the permutation q. If there are several solutions print any of them.

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

immutable int NA = -1;

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

		int [] [int] loops;
		auto b = new int [n];
		foreach (i; 0..n)
		{
			if (a[i] != NA)
			{
				int [] loop;
				int j = i;
				do
				{
					int t = j;
					j = a[j];
					a[t] = NA;
					loop ~= j;
				}
				while (j != i);
				debug {writeln (loop);}

				int k = loop.length;
				if (k & 1)
				{
					int pos = 0;
					int s = (k + 1) / 2;
					foreach (r; 0..k)
					{
						int next = (pos + s) % k;
						b[loop[pos]] = loop[next];
						pos = next;
					}
					continue;
				}

				auto p = k in loops;
				if (p)
				{
					auto other = *p;
					foreach (r; 0..k)
					{
						int s = (r + 1) % k;
						b[loop[r]] = other[r];
						b[other[r]] = loop[s];
					}
					loops.remove (k);
				}
				else
				{
					loops[k] = loop;
				}
			}
		}

		if (loops.length == 0)
		{
			writefln ("%(%s %)", b.map !(q{a + 1}));
		}
		else
		{
			writeln (-1);
		}
	}
}


The ship crashed into a reef and is sinking. Now the entire crew must be evacuated. All n crew members have already lined up in a row (for convenience let's label them all from left to right with positive integers from 1 to n) and await further instructions. However, one should evacuate the crew properly, in a strict order. Specifically:The first crew members to leave the ship are rats. Then women and children (both groups have the same priority) leave the ship. After that all men are evacuated from the ship. The captain leaves the sinking ship last.If we cannot determine exactly who should leave the ship first for any two members of the crew by the rules from the previous paragraph, then the one who stands to the left in the line leaves the ship first (or in other words, the one whose number in the line is less).For each crew member we know his status as a crew member, and also his name. All crew members have different names. Determine the order in which to evacuate the crew.

The first line contains an integer n, which is the number of people in the crew (1 ≤ n ≤ 100). Then follow n lines. The i-th of those lines contains two words — the name of the crew member who is i-th in line, and his status on the ship. The words are separated by exactly one space. There are no other spaces in the line. The names consist of Latin letters, the first letter is uppercase, the rest are lowercase. The length of any name is from 1 to 10 characters. The status can have the following values: rat for a rat, woman for a woman, child for a child, man for a man, captain for the captain. The crew contains exactly one captain.

Print n lines. The i-th of them should contain the name of the crew member who must be the i-th one to leave the ship.

6
Jack captain
Alice woman
Charlie man
Teddy rat
Bob child
Julia woman

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

void main() {
    int n; readf("%d\n", &n);
    string[] ns = new string[n];
    string[] ks = new string[n];
    foreach (i; 0 .. n) {
        string name, kind; readf("%s %s\n", &name, &kind);
        ns[i] = name;
        ks[i] = kind;
    }
    foreach (i; 0 .. n) {
        if (ks[i] == "rat") {
            writeln(ns[i]);
        }
    }
    foreach (i; 0 .. n) {
        if (ks[i] == "woman" || ks[i] == "child") {
            writeln(ns[i]);
        }
    }
    foreach (i; 0 .. n) {
        if (ks[i] == "man") {
            writeln(ns[i]);
        }
    }
    foreach (i; 0 .. n) {
        if (ks[i] == "captain") {
            writeln(ns[i]);
        }
    }
}

module cf_63A;

import std.stdio;
import std.algorithm;

struct Member {
    string name, type;

    int opCmp(ref const Member other) {
        int[string] TYPE_PRIORITY = [
            "rat": 1, "woman": 2, "child": 2, "man": 3, "captain": 4
        ];

        return TYPE_PRIORITY[type] - TYPE_PRIORITY[other.type];
    }
}

void main() {
    int n;
    Member[] crew;

    readf("%d", &n);
    crew = new Member[n];
    for (int i = 0; i < n; ++i) {
        readf(" %s %s\n", &crew[i].name, &crew[i].type);
    }

    sort!("a < b", SwapStrategy.stable)(crew);
    for (int i = 0; i < crew.length; ++i) {
        writeln(crew[i].name);
    }
}


Lena is a beautiful girl who likes logical puzzles.As a gift for her birthday, Lena got a matrix puzzle!The matrix consists of $$$n$$$ rows and $$$m$$$ columns, and each cell is either black or white. The coordinates $$$(i,j)$$$ denote the cell which belongs to the $$$i$$$-th row and $$$j$$$-th column for every $$$1\leq i \leq n$$$ and $$$1\leq j \leq m$$$. To solve the puzzle, Lena has to choose a cell that minimizes the Manhattan distance to the farthest black cell from the chosen cell.More formally, let there be $$$k \ge 1$$$ black cells in the matrix with coordinates $$$(x_i,y_i)$$$ for every $$$1\leq i \leq k$$$. Lena should choose a cell $$$(a,b)$$$ that minimizes $$$$$$\max_{i=1}^{k}(|a-x_i|+|b-y_i|).$$$$$$As Lena has no skill, she asked you for help. Will you tell her the optimal cell to choose?

There are several test cases in the input data. The first line contains a single integer $$$t$$$ ($$$1\leq t\leq 10\,000$$$) — the number of test cases. This is followed by the test cases description. The first line of each test case contains two integers $$$n$$$ and $$$m$$$ ($$$2\leq n,m \leq 1000$$$)  — the dimensions of the matrix.  The following $$$n$$$ lines contain $$$m$$$ characters each, each character is either 'W' or 'B'. The $$$j$$$-th character in the $$$i$$$-th of these lines is 'W' if the cell $$$(i,j)$$$ is white, and 'B' if the cell $$$(i,j)$$$ is black.  It is guaranteed that at least one black cell exists. It is guaranteed that the sum of $$$n\cdot m$$$ does not exceed $$$10^6$$$.

For each test case, output the optimal cell $$$(a,b)$$$ to choose. If multiple answers exist, output any.

5
3 2
BW
WW
WB
3 3
WWB
WBW
BWW
2 3
BBB
BBB
5 5
BWBWB
WBWBW
BWBWB
WBWBW
BWBWB
9 9
WWWWWWWWW
WWWWWWWWW
BWWWWWWWW
WWWWWWWWW
WWWWBWWWW
WWWWWWWWW
WWWWWWWWW
WWWWWWWWW
WWWWWWWWB

NoteIn the first test case the two black cells have coordinates $$$(1,1)$$$ and $$$(3,2)$$$. The four optimal cells are $$$(1,2)$$$, $$$(2,1)$$$, $$$(2,2)$$$ and $$$(3,1)$$$. It can be shown that no other cell minimizes the maximum Manhattan distance to every black cell.In the second test case it is optimal to choose the black cell $$$(2,2)$$$ with maximum Manhattan distance being $$$2$$$.

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

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

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

alias P = Point!long;
void solve() {
    int N, M; readf("%d %d\n", &N, &M);
    auto F = iota(N).map!(_ => readln.chomp).array;
    P[] ps;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            if (F[i][j] == 'B') {
                ps ~= P(j, i);
            }
        }
    }
    P[] qs = ps.length <= 2 ? ps : convexHull!long(ps);
    int k = cast(int)qs.length;
    P ans;
    bool C(int d) {
        foreach (s; qs) {
            for (int dy = -d; dy <= d; dy++) {
                int adx = d - abs(dy);
                foreach (dx; [-adx, adx]) {
                    long y = s.y + dy;
                    long x = s.x + dx;
                    bool f() {
                        foreach (q; qs) {
                            if (dist_mh(P(x, y), q) > d) return false;
                        }
                        return true;
                    }
                    if (f()) {
                        ans = P(x, y);
                        return true;
                    }
                }
            }
        }
        return false;
    }
    int lb = 0, ub = N+M+1;
    if (C(lb)) {
        ub = lb;
    } else {
        while (lb + 1 < ub) {
            int mid = (lb + ub) / 2;
            (C(mid) ? ub : lb) = mid;
        }
    }
    C(ub);
    writefln("%s %s", ans.y+1, ans.x+1);
}

long dist_mh(P a, P b) {
    return abs(a.x - b.x) + abs(a.y - b.y);
}

struct Point(T) {
    T x, y;
    Point opBinary(string op : "+")(in Point a) const { return Point(x + a.x, y + a.y); }
    Point opBinary(string op : "-")(in Point a) const { return Point(x - a.x, y - a.y); }
}
T det(T)(Point!T a, Point!T b) { return a.x * b.y - a.y * b.x; }

Point!T[] convexHull(T)(in Point!T[] ps_) {
    auto ps = ps_.dup;
    ps.sort!"a.x == b.x ? a.y < b.y : a.x < b.x";
    int n = cast(int)(ps.length);
    int k = 0;
    auto qs = new Point!T[2*n];
    for (int i = 0; i < n; i++) {
        while (k > 1 && (qs[k - 1] - qs[k - 2]).det(ps[i] - qs[k - 1]) <= 0) k--;
        qs[k++] = ps[i];
    }
    for (int i = n - 2, t = k; i >= 0; i--) {
        while (k > t && (qs[k - 1] - qs[k - 2]).det(ps[i] - qs[k - 1]) <= 0) k--;
        qs[k++] = ps[i];
    }
    return qs[0 .. k-1];
}

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

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

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

alias P = Point!long;
void solve() {
    int N, M; readf("%d %d\n", &N, &M);
    auto F = iota(N).map!(_ => readln.chomp).array;
    P[] ps;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            if (F[i][j] == 'B') {
                ps ~= P(j, i);
            }
        }
    }
    P[] qs = ps.length <= 2 ? ps : convexHull!long(ps);
    int k = cast(int)qs.length;
    P ans;
    bool C(int d) {
        auto s = qs[0];
        for (int dy = -d; dy <= d; dy++) {
            int adx = d - abs(dy);
            foreach (dx; [-adx, adx]) {
                long y = s.y + dy;
                long x = s.x + dx;
                bool f() {
                    foreach (q; qs) {
                        if (dist_mh(P(x, y), q) > d) return false;
                    }
                    return true;
                }
                if (f()) {
                    ans = P(x, y);
                    return true;
                }
            }
        }
        return false;
    }
    int lb = 0, ub = N+M+1;
    if (C(lb)) {
        ub = lb;
    } else {
        while (lb + 1 < ub) {
            int mid = (lb + ub) / 2;
            (C(mid) ? ub : lb) = mid;
        }
    }
    C(ub);
    writefln("%s %s", ans.y+1, ans.x+1);
}

long dist_mh(P a, P b) {
    return abs(a.x - b.x) + abs(a.y - b.y);
}

struct Point(T) {
    T x, y;
    Point opBinary(string op : "+")(in Point a) const { return Point(x + a.x, y + a.y); }
    Point opBinary(string op : "-")(in Point a) const { return Point(x - a.x, y - a.y); }
}
T det(T)(Point!T a, Point!T b) { return a.x * b.y - a.y * b.x; }

Point!T[] convexHull(T)(in Point!T[] ps_) {
    auto ps = ps_.dup;
    ps.sort!"a.x == b.x ? a.y < b.y : a.x < b.x";
    int n = cast(int)(ps.length);
    int k = 0;
    auto qs = new Point!T[2*n];
    for (int i = 0; i < n; i++) {
        while (k > 1 && (qs[k - 1] - qs[k - 2]).det(ps[i] - qs[k - 1]) <= 0) k--;
        qs[k++] = ps[i];
    }
    for (int i = n - 2, t = k; i >= 0; i--) {
        while (k > t && (qs[k - 1] - qs[k - 2]).det(ps[i] - qs[k - 1]) <= 0) k--;
        qs[k++] = ps[i];
    }
    return qs[0 .. k];
}

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

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

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

alias P = Point!long;
void solve() {
    int N, M; readf("%d %d\n", &N, &M);
    auto F = iota(N).map!(_ => readln.chomp).array;
    P[] ps;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            if (F[i][j] == 'B') {
                ps ~= P(j, i);
            }
        }
    }
    P[] qs = convexHull!long(ps);
    int k = cast(int)qs.length;
    P ans;
    bool C(int d) {
        auto s = qs[0];
        for (int dy = -d; dy <= d; dy++) {
            int adx = d - abs(dy);
            foreach (dx; [-adx, adx]) {
                long y = s.y + dy;
                long x = s.x + dx;
                bool f() {
                    foreach (q; qs) {
                        if (dist_mh(P(x, y), q) > d) return false;
                    }
                    return true;
                }
                if (f()) {
                    ans = P(x, y);
                    return true;
                }
            }
        }
        return false;
    }
    int lb = 0, ub = N+M+1;
    if (C(lb)) {
        ub = lb;
    } else {
        while (lb + 1 < ub) {
            int mid = (lb + ub) / 2;
            (C(mid) ? ub : lb) = mid;
        }
    }
    C(ub);
    writefln("%s %s", ans.y+1, ans.x+1);
}

long dist_mh(P a, P b) {
    return abs(a.x - b.x) + abs(a.y - b.y);
}

struct Point(T) {
    T x, y;
    Point opBinary(string op : "+")(in Point a) const { return Point(x + a.x, y + a.y); }
    Point opBinary(string op : "-")(in Point a) const { return Point(x - a.x, y - a.y); }
}
T det(T)(Point!T a, Point!T b) { return a.x * b.y - a.y * b.x; }

Point!T[] convexHull(T)(in Point!T[] ps_) {
    auto ps = ps_.dup;
    ps.sort!"a.x == b.x ? a.y < b.y : a.x < b.x";
    int n = cast(int)(ps.length);
    int k = 0;
    auto qs = new Point!T[2*n];
    for (int i = 0; i < n; i++) {
        while (k > 1 && (qs[k - 1] - qs[k - 2]).det(ps[i] - qs[k - 1]) <= 0) k--;
        qs[k++] = ps[i];
    }
    for (int i = n - 2, t = k; i >= 0; i--) {
        while (k > t && (qs[k - 1] - qs[k - 2]).det(ps[i] - qs[k - 1]) <= 0) k--;
        qs[k++] = ps[i];
    }
    return qs[0 .. k];
}

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

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

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

alias P = Point!long;
void solve() {
    int N, M; readf("%d %d\n", &N, &M);
    auto F = iota(N).map!(_ => readln.chomp).array;
    P[] ps;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            if (F[i][j] == 'B') {
                ps ~= P(j, i);
            }
        }
    }
    P[] qs = convexHull!long(ps);
    int k = cast(int)qs.length;
    P ans;
    bool C(int d) {
        auto s = qs[0];
        for (int dy = -d; dy <= d; dy++) {
            int adx = d - abs(dy);
            foreach (dx; [-adx, adx]) {
                long y = s.y + dy;
                long x = s.x + dx;
                bool f() {
                    foreach (q; qs) {
                        if (dist_mh(P(x, y), q) > d) return false;
                    }
                    return true;
                }
                if (f()) {
                    ans = P(x, y);
                    return true;
                }
            }
        }
        return false;
    }
    int lb = 0, ub = N+M+1;
    if (C(lb)) {
        ub = lb;
    } else {
        while (lb + 1 < ub) {
            int mid = (lb + ub) / 2;
            (C(mid) ? ub : lb) = mid;
        }
    }
    C(ub);
    writefln("%s %s", ans.x+1, ans.y+1);
}

long dist_mh(P a, P b) {
    return abs(a.x - b.x) + abs(a.y - b.y);
}

struct Point(T) {
    T x, y;
    Point opBinary(string op : "+")(in Point a) const { return Point(x + a.x, y + a.y); }
    Point opBinary(string op : "-")(in Point a) const { return Point(x - a.x, y - a.y); }
}
T det(T)(Point!T a, Point!T b) { return a.x * b.y - a.y * b.x; }

Point!T[] convexHull(T)(in Point!T[] ps_) {
    auto ps = ps_.dup;
    ps.sort!"a.x == b.x ? a.y < b.y : a.x < b.x";
    int n = cast(int)(ps.length);
    int k = 0;
    auto qs = new Point!T[2*n];
    for (int i = 0; i < n; i++) {
        while (k > 1 && (qs[k - 1] - qs[k - 2]).det(ps[i] - qs[k - 1]) <= 0) k--;
        qs[k++] = ps[i];
    }
    for (int i = n - 2, t = k; i >= 0; i--) {
        while (k > t && (qs[k - 1] - qs[k - 2]).det(ps[i] - qs[k - 1]) <= 0) k--;
        qs[k++] = ps[i];
    }
    return qs[0 .. k];
}

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

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

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

alias P = Point!long;
void solve() {
    int N, M; readf("%d %d\n", &N, &M);
    auto F = iota(N).map!(_ => readln.chomp).array;
    P[] ps;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            if (F[i][j] == 'B') {
                ps ~= P(j, i);
            }
        }
    }
    P[] qs = convexHull!long(ps);
    int k = cast(int)qs.length;
    P ans;
    bool C(int d) {
        auto s = qs[0];
        for (int dy = -d; dy <= d; dy++) {
            int adx = d - abs(dy);
            foreach (dx; [-adx, adx]) {
                long y = s.y + dy;
                long x = s.x + dx;
                bool f() {
                    foreach (q; qs) {
                        if (dist_mh(P(x, y), q) > d) return false;
                    }
                    return true;
                }
                if (f()) {
                    ans = P(x, y);
                    return true;
                }
            }
        }
        return false;
    }
    int lb = 0, ub = N+M+1;
    if (C(lb)) {
        ub = lb;
    } else {
        while (lb + 1 < ub) {
            int mid = (lb + ub) / 2;
            (C(mid) ? ub : lb) = mid;
        }
    }
    C(ub);
    writefln("%s %s", ans.x+1, ans.y+1);
}

long dist_mh(P a, P b) {
    return abs(a.x - b.x) + abs(a.y - b.y);
}

struct Point(T) {
    T x, y;
    Point opBinary(string op : "+")(in Point a) const { return Point(x + a.x, y + a.y); }
    Point opBinary(string op : "-")(in Point a) const { return Point(x - a.x, y - a.y); }
}
T det(T)(Point!T a, Point!T b) { return a.x * b.y - a.y * b.x; }

Point!T[] convexHull(T)(in Point!T[] ps_) {
    auto ps = ps_.dup;
    ps.sort!"a.x == b.x ? a.y < b.y : a.x < b.x";
    int n = cast(int)(ps.length);
    int k = 0;
    auto qs = new Point!T[2*n];
    for (int i = 0; i < n; i++) {
        while (k > 1 && (qs[k - 1] - qs[k - 2]).det(ps[i] - qs[k - 1]) <= 0) k--;
        qs[k++] = ps[i];
    }
    for (int i = n - 2, t = k; i >= 0; i--) {
        while (k > t && (qs[k - 1] - qs[k - 2]).det(ps[i] - qs[k - 1]) <= 0) k--;
        qs[k++] = ps[i];
    }
    return qs[0 .. k-1];
}

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

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

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

alias P = Point!long;
void solve() {
    int N, M; readf("%d %d\n", &N, &M);
    auto F = iota(N).map!(_ => readln.chomp).array;
    P[] ps;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            if (F[i][j] == 'B') {
                ps ~= P(j, i);
            }
        }
    }
    P[] qs = convexHull!long(ps);
    int k = cast(int)qs.length;
    P ans;
    bool C(int d) {
        auto s = qs[0];
        for (int dy = -d; dy <= d; dy++) {
            int adx = d - abs(dy);
            foreach (dx; [-adx, adx]) {
                long y = s.y + dy;
                long x = s.x + dx;
                bool f() {
                    foreach (q; qs) {
                        if (dist_mh(P(x, y), q) > d) return false;
                    }
                    return true;
                }
                if (f()) {
                    ans = P(x, y);
                    return true;
                }
            }
        }
        return false;
    }
    int lb = 0, ub = N+M+1;
    if (C(lb)) {
        ub = lb;
    } else {
        while (lb + 1 < ub) {
            int mid = (lb + ub) / 2;
            (C(mid) ? ub : lb) = mid;
        }
    }
    writefln("%s %s", ans.x+1, ans.y+1);
}

long dist_mh(P a, P b) {
    return abs(a.x - b.x) + abs(a.y - b.y);
}

struct Point(T) {
    T x, y;
    Point opBinary(string op : "+")(in Point a) const { return Point(x + a.x, y + a.y); }
    Point opBinary(string op : "-")(in Point a) const { return Point(x - a.x, y - a.y); }
}
T det(T)(Point!T a, Point!T b) { return a.x * b.y - a.y * b.x; }

Point!T[] convexHull(T)(in Point!T[] ps_) {
    auto ps = ps_.dup;
    ps.sort!"a.x == b.x ? a.y < b.y : a.x < b.x";
    int n = cast(int)(ps.length);
    int k = 0;
    auto qs = new Point!T[2*n];
    for (int i = 0; i < n; i++) {
        while (k > 1 && (qs[k - 1] - qs[k - 2]).det(ps[i] - qs[k - 1]) <= 0) k--;
        qs[k++] = ps[i];
    }
    for (int i = n - 2, t = k; i >= 0; i--) {
        while (k > t && (qs[k - 1] - qs[k - 2]).det(ps[i] - qs[k - 1]) <= 0) k--;
        qs[k++] = ps[i];
    }
    return qs[0 .. k-1];
}


Permutation $$$p$$$ is a sequence of integers $$$p=[p_1, p_2, \dots, p_n]$$$, consisting of $$$n$$$ distinct (unique) positive integers between $$$1$$$ and $$$n$$$, inclusive. For example, the following sequences are permutations: $$$[3, 4, 1, 2]$$$, $$$[1]$$$, $$$[1, 2]$$$. The following sequences are not permutations: $$$[0]$$$, $$$[1, 2, 1]$$$, $$$[2, 3]$$$, $$$[0, 1, 2]$$$.The important key is in the locked box that you need to open. To open the box you need to enter secret code. Secret code is a permutation $$$p$$$ of length $$$n$$$. You don't know this permutation, you only know the array $$$q$$$ of prefix maximums of this permutation. Formally:  $$$q_1=p_1$$$,  $$$q_2=\max(p_1, p_2)$$$,  $$$q_3=\max(p_1, p_2,p_3)$$$,  ...  $$$q_n=\max(p_1, p_2,\dots,p_n)$$$. You want to construct any possible suitable permutation (i.e. any such permutation, that calculated $$$q$$$ for this permutation is equal to the given array).

The first line contains integer number $$$t$$$ ($$$1 \le t \le 10^4$$$) — the number of test cases in the input. Then $$$t$$$ test cases follow. The first line of a test case contains one integer $$$n$$$ $$$(1 \le n \le 10^{5})$$$ — the number of elements in the secret code permutation $$$p$$$. The second line of a test case contains $$$n$$$ integers $$$q_1, q_2, \dots, q_n$$$ $$$(1 \le q_i \le n)$$$ — elements of the array $$$q$$$ for secret permutation. It is guaranteed that $$$q_i \le q_{i+1}$$$ for all $$$i$$$ ($$$1 \le i < n$$$). The sum of all values $$$n$$$ over all the test cases in the input doesn't exceed $$$10^5$$$.

For each test case, print:   If it's impossible to find such a permutation $$$p$$$, print "-1" (without quotes).  Otherwise, print $$$n$$$ distinct integers $$$p_1, p_2, \dots, p_n$$$ ($$$1 \le p_i \le n$$$). If there are multiple possible answers, you can print any of them.

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

string FMT_F = "%.10f";

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

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

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

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

void main()
{
	auto t = RD!int;
	auto ans = new int[][](t);
	foreach (i; 0..t)
	{
		auto n = RD!int;
		auto q = RDA!int;
		ans[i] ~= q[0];
		int cnt;
		auto used = new bool[](n+1);
		used[0] = true;
		used[q[0]] = true;
		foreach (j; 1..n)
		{
			if (q[j] == q[j-1])
			{
				while (used[cnt]) ++cnt;
				if (cnt > q[j])
				{
					ans[i] = [];
					break;
				}
				ans[i] ~= cnt;
				used[cnt] = true;
			}
			else
			{
				if (used[q[j]])
				{
					ans[i] = [];
					break;
				}
				ans[i] ~= q[j];
				used[q[j]] = true;
			}
		}
	}

	foreach (e; ans)
	{
		if (e.empty)
			writeln(-1);
		else
			e.map!(to!string).join(" ").writeln;
	}

	stdout.flush();
	debug readln();
}


One day Sasha visited the farmer 2D and his famous magnetic farm. On this farm, the crop grows due to the influence of a special magnetic field. Maintaining of the magnetic field is provided by $$$n$$$ machines, and the power of the $$$i$$$-th machine is $$$a_i$$$. This year 2D decided to cultivate a new culture, but what exactly he didn't say. For the successful growth of the new culture, it is necessary to slightly change the powers of the machines. 2D can at most once choose an arbitrary integer $$$x$$$, then choose one machine and reduce the power of its machine by $$$x$$$ times, and at the same time increase the power of one another machine by $$$x$$$ times (powers of all the machines must stay positive integers). Note that he may not do that if he wants. More formally, 2D can choose two such indices $$$i$$$ and $$$j$$$, and one integer $$$x$$$ such that $$$x$$$ is a divisor of $$$a_i$$$, and change powers as following: $$$a_i = \frac{a_i}{x}$$$, $$$a_j = a_j \cdot x$$$Sasha is very curious, that's why he wants to calculate the minimum total power the farmer can reach. There are too many machines, and Sasha can't cope with computations, help him!

The first line contains one integer $$$n$$$ ($$$2 \le n \le 5 \cdot 10^4$$$) — the number of machines. The second line contains $$$n$$$ integers $$$a_1, a_2, \ldots, a_n$$$ ($$$1 \le a_i \le 100$$$) — the powers of the machines.

Print one integer — minimum total power.

NoteIn the first example, the farmer can reduce the power of the $$$4$$$-th machine by $$$2$$$ times, and increase the power of the $$$1$$$-st machine by $$$2$$$ times, then the powers will be: $$$[2, 2, 3, 2, 5]$$$.In the second example, the farmer can reduce the power of the $$$3$$$-rd machine by $$$2$$$ times, and increase the power of the $$$2$$$-nd machine by $$$2$$$ times. At the same time, the farmer can leave is be as it is and the total power won't change.In the third example, it is optimal to leave it be as it is.

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

immutable long INF = 10L ^^ 18 + 23;

immutable int A = 100;

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

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

    auto sm = a.sum();

    if (n == 1) {
        sm.writeln;
        return;
    }

    int mxgain = 0;
    for (int i = 2; i < A; ++i) {
        int curbig = -1;
        for (int j = 0; j < n; ++j) {
            if (a[j] % i != 0) continue;

            if (curbig == -1 || a[j] > a[curbig]) curbig = j;
        }

        if (curbig == -1) continue;

        int cursm = -1;
        for (int j = 0; j < n; ++j) {
            if (j == curbig) continue;

            if (cursm == -1 || a[j] < a[cursm]) cursm = j;
        }

        int curgain = (a[curbig] + a[cursm]) - (a[curbig] / i + a[cursm] * i);
        mxgain = max(mxgain, curgain);
    }

    int ans = sm - mxgain;
    ans.writeln;
}

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

immutable long INF = 10L ^^ 18 + 23;

immutable int A = 100;

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

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

    auto sm = a.sum();

    if (n == 1) {
        sm.writeln;
        return;
    }

    int mxgain = 0;
    for (int i = 2; i < A; ++i) {
        int curbig = -1;
        for (int j = 0; j < n; ++j) {
            if (a[j] % i != 0) continue;

            if (curbig == -1 || a[j] > a[curbig]) curbig = j;
        }

        if (curbig == -1) continue;

        int cursm = -1;
        for (int j = 0; j < n; ++j) {
            if (j == curbig) continue;

            if (cursm == -1 || a[j] < cursm) cursm = j;
        }

        int curgain = (a[curbig] + a[cursm]) - (a[curbig] / i + a[cursm] * i);
        mxgain = max(mxgain, curgain);
    }

    int ans = sm - mxgain;
    ans.writeln;
}


This is the hard version of the problem. The only difference is that in this version $$$n \leq 200000$$$. You can make hacks only if both versions of the problem are solved.There are $$$n$$$ potions in a line, with potion $$$1$$$ on the far left and potion $$$n$$$ on the far right. Each potion will increase your health by $$$a_i$$$ when drunk. $$$a_i$$$ can be negative, meaning that potion will decrease will health.You start with $$$0$$$ health and you will walk from left to right, from first potion to the last one. At each potion, you may choose to drink it or ignore it. You must ensure that your health is always non-negative.What is the largest number of potions you can drink?

The first line contains a single integer $$$n$$$ ($$$1 \leq n \leq 200000$$$) — the number of potions.  The next line contains $$$n$$$ integers $$$a_1$$$, $$$a_2$$$, ... ,$$$a_n$$$ ($$$-10^9 \leq a_i \leq 10^9$$$) which represent the change in health after drinking that potion.

Output a single integer, the maximum number of potions you can drink without your health becoming negative.

NoteFor the sample, you can drink $$$5$$$ potions by taking potions $$$1$$$, $$$3$$$, $$$4$$$, $$$5$$$ and $$$6$$$. It is not possible to drink all $$$6$$$ potions because your health will go negative at some point

import std.stdio;
import std.ascii;
import core.stdc.stdio;
import std.container;

int main()
{
    int n = readInt!int;
    auto a = new long[](n);
    foreach(ref ai; a)
    {
        ai = readInt!long;
    }
    auto taken = redBlackTree!(true, long)();
    long maxSum = 0;
    foreach(i, ai; a)
    {
        if (ai >= 0)
        {
            maxSum += ai;
            taken.insert([ai]);
        }
        else
        {
            if (maxSum + ai >= 0)
            {
                taken.insert([ai]);
                maxSum += ai;
            }
            else
            {
                if (taken.length > 0)
                {
                    if (taken.front < ai)
                    {
                        maxSum -= taken.front;
                        taken.removeFront;
                        taken.insert([ai]);
                        maxSum += ai;
                    }
                }
            }
        }
    }
    writeln(taken.length);
    return 0;
}

/* INPUT ROUTINES */
int currChar;
static this()
{
    currChar = getchar();
}
char topChar()
{
    return cast(char) currChar;
}
void popChar()
{
    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;
}


Yaroslav likes algorithms. We'll describe one of his favorite algorithms.  The algorithm receives a string as the input. We denote this input string as a.  The algorithm consists of some number of command. Сommand number i looks either as si >> wi, or as si <> wi, where si and wi are some possibly empty strings of length at most 7, consisting of digits and characters "?".  At each iteration, the algorithm looks for a command with the minimum index i, such that si occurs in a as a substring. If this command is not found the algorithm terminates.  Let's denote the number of the found command as k. In string a the first occurrence of the string sk is replaced by string wk. If the found command at that had form sk >> wk, then the algorithm continues its execution and proceeds to the next iteration. Otherwise, the algorithm terminates.  The value of string a after algorithm termination is considered to be the output of the algorithm. Yaroslav has a set of n positive integers, he needs to come up with his favorite algorithm that will increase each of the given numbers by one. More formally, if we consider each number as a string representing the decimal representation of the number, then being run on each of these strings separately, the algorithm should receive the output string that is a recording of the corresponding number increased by one.Help Yaroslav.

The first line contains integer n (1 ≤ n ≤ 100) — the number of elements in the set. The next n lines contains one positive integer each. All the given numbers are less than 1025.

Print the algorithm which can individually increase each number of the set. In the i-th line print the command number i without spaces. Your algorithm will be launched for each of these numbers. The answer will be considered correct if:      Each line will a correct algorithm command (see the description in the problem statement).  The number of commands should not exceed 50.  The algorithm will increase each of the given numbers by one.  To get a respond, the algorithm will perform no more than 200 iterations for each number.

import std.algorithm;
import std.bigint;
import std.container;
import std.conv;
import std.exception;
import std.functional;
import std.math;
import std.random;
import std.range;
import std.stdio;
import std.string;
import std.typecons;

string gen_random_string (int len)
{
	string res;
	foreach (i; 0..len)
	{
		res ~= cast (char) (uniform !("[]") ('0', '9'));
	}
	debug {writeln (res);}
	return res;
}

string [] gen ()
{
	string [] res;
	immutable int LEN = 6;
	auto sig1 = gen_random_string (LEN);
	auto sig2 = gen_random_string (LEN);
	res ~= to !(string) (9) ~ sig2 ~ ">>" ~
	       sig2 ~ to !(string) (0);
	foreach (d; 0..9)
	{
		res ~= to !(string) (d) ~ sig2 ~ "<>" ~
		       to !(string) (d + 1);
	}
	res ~= sig2 ~ "<>" ~
	       to !(string) (1);
	foreach (d; 0..10)
	{
		res ~= sig1 ~ to !(string) (d) ~ ">>" ~
		       to !(string) (d) ~ sig1;
	}
	res ~= sig1 ~ ">>" ~
	       sig2;
	foreach (d; 0..10)
	{
		res ~= to !(string) (d) ~ ">>" ~
		       sig1 ~ to !(string) (d);
	}
	return res;
}

bool check_all (string [] s, string [] v)
{
	foreach (t; s)
	{
		if (!check_one (t, v))
		{
			return false;
		}
	}
	return true;
}

bool check_one (string t, string [] v)
{
	string cur = t;
	debug {writeln ("before:  ", cur);}
	BigInt before = cur;
main_loop:
	while (true)
	{
find_match:
		foreach (i, w; v)
		{
			auto f = w.findSplit ("<>");
			if (f[1] == "")
			{
				f = w.findSplit (">>");
				if (f[1] == "")
				{
					assert (false);
				}
			}
//			debug {writeln (f);}

			auto g = cur.findSplit (f[0]);
			if (g[1] != "")
			{
				cur = g[0] ~ f[2] ~ g[2];
				debug {writefln ("rule %s: %s", i, cur);}
				if (f[1] == "<>")
				{
					break main_loop;
				}
				continue main_loop;
			}
		}
		break main_loop;
	}
	debug {writeln ("after:   ", cur);}
	BigInt after = cur;
	return (before + 1 == after);
}

void main ()
{
	int n;
	while (readf (" %s ", &n) > 0)
	{
		auto s = new string [n];
		foreach (i; 0..n)
		{
			s[i] = readln ().strip ();
		}
		string [] v;
		do
		{
			v = gen ();
		}
		while (!check_all (s, v));
		foreach (t; v)
		{
			writeln (t);
		}
	}
}


Sam has been teaching Jon the Game of Stones to sharpen his mind and help him devise a strategy to fight the white walkers. The rules of this game are quite simple:  The game starts with n piles of stones indexed from 1 to n. The i-th pile contains si stones. The players make their moves alternatively. A move is considered as removal of some number of stones from a pile. Removal of 0 stones does not count as a move. The player who is unable to make a move loses.Now Jon believes that he is ready for battle, but Sam does not think so. To prove his argument, Sam suggested that they play a modified version of the game.In this modified version, no move can be made more than once on a pile. For example, if 4 stones are removed from a pile, 4 stones cannot be removed from that pile again.Sam sets up the game and makes the first move. Jon believes that Sam is just trying to prevent him from going to battle. Jon wants to know if he can win if both play optimally.

First line consists of a single integer n (1 ≤ n ≤ 106) — the number of piles. Each of next n lines contains an integer si (1 ≤ si ≤ 60) — the number of stones in i-th pile.

Print a single line containing "YES" (without quotes) if Jon wins, otherwise print "NO" (without quotes)

NoteIn the first case, Sam removes all the stones and Jon loses.In second case, the following moves are possible by Sam:  In each of these cases, last move can be made by Jon to win the game as follows:

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

alias go = memoize !(goImpl);

int goImpl (int s, long mask)
/*
out (res)
{
	debug {writefln ("go (%s, %s) = %s", s, mask, res);}
}
body
*/
{
	long b = 0L;
	foreach (p; 1..s + 1)
	{
		long q = 1L << p;
		if (!(mask & q))
		{
			b |= 1L << go (s - p, mask | q);
		}
	}
//	debug {writeln (b);}
	int x = 0;
	while (b & (1L << x))
	{
		x += 1;
	}
	return x;
}

void main ()
{
	int [limit] g;
	foreach (s; 0..limit)
	{
		g[s] = go (s, 0L);
		debug {writefln ("g[%s] = %s", s, g[s]);}
	}

	int n;
	while (readf (" %s", &n) > 0)
	{
		int res = 0;
		foreach (i; 0..n)
		{
			int s;
			readf (" %s", &s);
			res ^= g[s];
		}
		writeln (res ? "NO" : "YES");
	}
}


Recently, you bought a brand new smart lamp with programming features. At first, you set up a schedule to the lamp. Every day it will turn power on at moment $$$0$$$ and turn power off at moment $$$M$$$. Moreover, the lamp allows you to set a program of switching its state (states are "lights on" and "lights off"). Unfortunately, some program is already installed into the lamp.The lamp allows only good programs. Good program can be represented as a non-empty array $$$a$$$, where $$$0 < a_1 < a_2 < \dots < a_{|a|} < M$$$. All $$$a_i$$$ must be integers. Of course, preinstalled program is a good program.The lamp follows program $$$a$$$ in next manner: at moment $$$0$$$ turns power and light on. Then at moment $$$a_i$$$ the lamp flips its state to opposite (if it was lit, it turns off, and vice versa). The state of the lamp flips instantly: for example, if you turn the light off at moment $$$1$$$ and then do nothing, the total time when the lamp is lit will be $$$1$$$. Finally, at moment $$$M$$$ the lamp is turning its power off regardless of its state.Since you are not among those people who read instructions, and you don't understand the language it's written in, you realize (after some testing) the only possible way to alter the preinstalled program. You can insert at most one element into the program $$$a$$$, so it still should be a good program after alteration. Insertion can be done between any pair of consecutive elements of $$$a$$$, or even at the begining or at the end of $$$a$$$.Find such a way to alter the program that the total time when the lamp is lit is maximum possible. Maybe you should leave program untouched. If the lamp is lit from $$$x$$$ till moment $$$y$$$, then its lit for $$$y - x$$$ units of time. Segments of time when the lamp is lit are summed up.

First line contains two space separated integers $$$n$$$ and $$$M$$$ ($$$1 \le n \le 10^5$$$, $$$2 \le M \le 10^9$$$) — the length of program $$$a$$$ and the moment when power turns off. Second line contains $$$n$$$ space separated integers $$$a_1, a_2, \dots, a_n$$$ ($$$0 < a_1 < a_2 < \dots < a_n < M$$$) — initially installed program $$$a$$$.

Print the only integer — maximum possible total time when the lamp is lit.

NoteIn the first example, one of possible optimal solutions is to insert value $$$x = 3$$$ before $$$a_1$$$, so program will be $$$[3, 4, 6, 7]$$$ and time of lamp being lit equals $$$(3 - 0) + (6 - 4) + (10 - 7) = 8$$$. Other possible solution is to insert $$$x = 5$$$ in appropriate place.In the second example, there is only one optimal solution: to insert $$$x = 2$$$ between $$$a_1$$$ and $$$a_2$$$. Program will become $$$[1, 2, 10]$$$, and answer will be $$$(1 - 0) + (10 - 2) = 9$$$.In the third example, optimal answer is to leave program untouched, so answer will be $$$(3 - 0) + (7 - 4) = 6$$$.

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

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

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

    a = [0] ~ a ~ [m];

    debug { a.writeln; }

    bool isOn = a.length % 2 == 0;
    auto vals = [0, 0];
    auto mxgain = 0;
    foreach_reverse (i; 0 .. a.length - 1) {
        auto cur = a[i+1] - a[i];
        vals[isOn] += cur;

        if (a[i] + 1 < a[i+1] && !isOn) {
            mxgain = max(mxgain, vals[0] - vals[1] - 1);
        }

        isOn = !isOn;
    }

    auto ans = vals[1] + mxgain;
    ans.writeln;
}


Appleman has a tree with n vertices. Some of the vertices (at least one) are colored black and other vertices are colored white.Consider a set consisting of k (0 ≤ k < n) edges of Appleman's tree. If Appleman deletes these edges from the tree, then it will split into (k + 1) parts. Note, that each part will be a tree with colored vertices.Now Appleman wonders, what is the number of sets splitting the tree in such a way that each resulting part will have exactly one black vertex? Find this number modulo 1000000007 (109 + 7).

The first line contains an integer n (2  ≤ n ≤ 105) — the number of tree vertices.  The second line contains the description of the tree: n - 1 integers p0, p1, ..., pn - 2 (0 ≤ pi ≤ i). Where pi means that there is an edge connecting vertex (i + 1) of the tree and vertex pi. Consider tree vertices are numbered from 0 to n - 1. The third line contains the description of the colors of the vertices: n integers x0, x1, ..., xn - 1 (xi is either 0 or 1). If xi is equal to 1, vertex i is colored black. Otherwise, vertex i is colored white.

Output a single integer — the number of ways to split the tree modulo 1000000007 (109 + 7).

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

immutable int MOD = 1_000_000_007;
immutable int NA = -1;

void main ()
{
	int n;
	while (readf (" %s", &n) > 0)
	{
		auto a = new int [] [n];
		for (int i = 1; i < n; i++)
		{
			int j;
			readf (" %s", &j);
			a[j] ~= i;
			a[i] ~= j;
		}

		auto b = new int [n];
		foreach (ref x; b)
		{
			readf (" %s", &x);
		}

		auto f = new int [2] [n];

		void recur (int v, int p)
		{
			f[v][0] = 1;
			f[v][1] = 0;

			foreach (u; a[v])
			{
				if (u == p)
				{
					continue;
				}

				recur (u, v);

				long c0 = f[u][0] + f[u][1];
				if (c0 >= MOD)
				{
					c0 -= MOD;
				}
				long c1 = f[u][1];

				int n0 = (c0 * f[v][0]) % MOD;
				int n1 = (c1 * f[v][0] + c0 * f[v][1]) % MOD;
				f[v][0] = n0;
				f[v][1] = n1;
			}

			if (b[v])
			{
				f[v][1] = f[v][0];
				f[v][0] = 0;
			}
		}

		recur (0, NA);
		writeln (f[0][1]);
	}
}

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

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

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

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

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

immutable MO = 1000000007L;

int N;
int[] P;
int[] X;
int[][] G;

long[] solve(int u) {
	long[] dp = new long[2];
	dp[X[u]] += 1;
	foreach (v; G[u]) {
		long[] res = solve(v);
		dp[1] = (dp[1] * (res[0] + res[1]) + dp[0] * res[1]) % MO;
		dp[0] = (dp[0] * (res[0] + res[1])                 ) % MO;
	}
debug{
writeln(u," ",dp);
}
	return dp;
}

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

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

		const res = solve(0);
		long ans = (res[1] % MO + MO) % MO;
		writeln(ans);
	}
	} catch (EOFException) {}
}