Leha and Noora decided to go on a trip in the Baltic States. As you know from the previous problem, Leha has lost his car on the parking of the restaurant. Unfortunately, requests to the watchman didn't helped hacker find the car, so friends decided to go hitchhiking.In total, they intended to visit n towns. However it turned out that sights in i-th town are open for visitors only on days from li to ri.What to do? Leha proposed to choose for each town i a day, when they will visit this town, i.e any integer xi in interval [li, ri]. After that Noora choses some subsequence of towns id1, id2, ..., idk, which friends are going to visit, that at first they are strictly increasing, i.e idi < idi + 1 is for all integers i from 1 to k - 1, but also the dates of the friends visits are strictly increasing, i.e xidi < xidi + 1 is true for all integers i from 1 to k - 1.Please help Leha and Noora in choosing such xi for each town i, and such subsequence of towns id1, id2, ..., idk, so that friends can visit maximal number of towns.You may assume, that Leha and Noora can start the trip any day.

The first line contains a single integer n (1 ≤ n ≤ 3·105) denoting the number of towns Leha and Noora intended to visit. Each line i of the n subsequent lines contains two integers li, ri (1 ≤ li ≤ ri ≤ 109), denoting that sights in i-th town are open for visitors on any day .

Print a single integer denoting the maximal number of towns, that Leha and Noora can visit.

NoteConsider the first example.Let's take this plan: let's visit the sight in the second town on the first day, in the third town on the third day and in the fifth town on the fourth. That's would be the optimal answer.

module main;
import std.bigint,std.container,std.array,std.algorithm,std.conv,std.parallelism,
	std.functional,std.math,std.numeric,std.string,std.range,std.complex,std.bitmanip,
	std.typecons,std.regex,std.random,std.uni,std.traits,std.stdio,std.variant,core.bitop,
	std.meta,core.stdc.stdio : freopen;
alias RedBlackTree Rbt;alias redBlackTree rbt;alias BigInt big;
alias pair(X,Y)=Tuple!(X,"fi",Y,"se");alias long lint;const int mod=1_000_000_007;
alias pair!(int,int) pii;alias pair!(long,long) pll;alias BoyerMooreFinder strfind;
alias make_pair mp;alias binary_search bins;alias gcd=std.numeric.gcd;
pure nothrow
{
	T lcm (T)(auto ref T a,auto ref T b){return a/gcd(a,b)*b;}
	pair!(X,Y) make_pair(X,Y)(in X x_,in Y y_){return tuple!(X,"fi",Y,"se")(x_,y_);}
	big gcd(big a,big b){while(b){a%=b;swap(a,b);}return a;}
	@property X sqr(X)(in X a_) {return a_*a_;}
	@property X cub(X)(in X a_) {return a_*a_*a_;}
	int sz(T)(T a) if(hasLength!T){return cast(int)a.length;}
	size_t lowb(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		size_t l=0,r=a.length;
		while(r-l>1)
		{
			auto m=(l+r)>>1;
			if(!(a[m]<g))r=m;
			else l=m;
		}
		return (!(a[l]<g))?l:r;
	}
	size_t upb(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		auto pos=lowb(a,g);
		if(pos==a.length)return pos;
		else return a[pos]==g?pos+1:pos;
	}
	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;
	}
	bool binary_search(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		return binf(a,g)!=a.length;
	}
}
void putarr(X)(in X a,in char ch=' ') if(isInputRange!X && !isInputRange!(ElementEncodingType!X))
{foreach(const ref i;a)write(i,ch);}
void putarr(X)(in X a) if(isInputRange!X && isInputRange!(ElementEncodingType!X))
{
	foreach(ref const i;a)
	{
		foreach(ref const j;i)write(j,' ');
		writeln;
	}
}
bool getarr(X)(X a,in size_t n)
{bool b=1; foreach(ref i;a[0..n])b=input(&i);return b;}
bool input(T...)(auto ref T ptrs) if (ptrs.length > 0)
{
	size_t s=0;
	foreach(ref e;ptrs)
	{
		if(isSomeChar!(Unqual!(typeof(e))))s+=readf(" %c",&e);
		else s+=readf(" %s",&e);
	}
	return s==ptrs.length;
}
bool read(T...)(auto ref T ptrs) if (ptrs.length > 0)
{
	size_t s=0;
	foreach(ref e;ptrs)
	{
		if(isSomeChar!(Unqual!(typeof(e))))s+=readf(" %c",&e);
		else s+=readf(" %s",&e);
	}
	readln;
	return s==ptrs.length;
}
nothrow auto inf(in char* name) {return freopen(name,"r",core.stdc.stdio.stdin);}
nothrow auto ouf(in char* name) {return freopen(name,"w",core.stdc.stdio.stdout);}
@property auto arread(T)(){return readln.splitter.map!(to!(T)).array;}
//foreach_reverse isAlpha isNumber isWhite isLower isUpper toLower toUpper mixin
//cumulativeFold return static heapify join filter foreach
//------------------------------------------program beginning--------------------------
Mt19937 gen;
class item
{
	int prior,key,add,cnt;
	item l,r;
	this()
	{
		l=r=null;
		prior=uniform!int();
		cnt=1;
	}
};
void push(item t)
{
	t.key+=t.add;
	if(t.l)t.l.add+=t.add;
	if(t.r)t.r.add+=t.add;
	t.add=0;
}
int cnt(item t){return t?t.cnt:0;}
void upd(item t)
{
	t.cnt=cnt(t.l)+cnt(t.r)+1;
}
void merge(ref item t,item l,item r)
{
	debug writeln(l !is null);
	debug writeln(r is null);
	debug stdout.flush;
	if(!l || !r){t=l?l:r;return;}
	//assert(false);
	if(l.prior>r.prior)
	{
		push(l);
		merge(l.r,l.r,r);
		t=l;
	}
	else
	{
		push(r);
		merge(r.l,l,r.l);
		t=r;
	}
	upd(t);
}
void split(item t,int val,ref item l,ref item r)
{
	if(!t){l=r=null;return;}
	push(t);
	if(t.key<val)
	{
		split(t.r,val,t.r,r);
		l=t;
	}
	else
	{
		split(t.l,val,l,t.l);
		r=t;
	}
	upd(t);
}
void cut(ref item t)
{
	push(t);
	if(!t.l)
	{
		t=t.r;
		return;
	}
	else cut(t.l);
	upd(t);
}
item root;
item l,r,m,x;
void main()
{
	version(ONLINE_JUDGE){}
	else
	{
		assert(freopen("input.txt","r",core.stdc.stdio.stdin));
		assert(freopen("output.txt","w",core.stdc.stdio.stdout));
	}
	int n;
	read(n);
	foreach(i;0..n)
	{
		int lb,rb;
		read(lb,rb);
		split(root,rb,m,r);
		split(m,lb,l,m);
		if(r)cut(r);
		x=new item;
		x.key=lb;
		if(m)m.add++;
		merge(l,l,x);
		merge(l,l,m);
		merge(root,l,r);
		x=l=r=m=null;
	}
	writeln(cnt(root));
/*loop:while(read(n))
	{

	}*/
}

module main;
import std.bigint,std.container,std.array,std.algorithm,std.conv,std.parallelism,
	std.functional,std.math,std.string,std.range,std.complex,std.bitmanip,
	std.typecons,std.regex,std.random,std.uni,std.traits,std.stdio,std.variant,core.bitop,
	std.meta,core.stdc.stdio : freopen;
import std.numeric: fft,Fft,gcd,inverseFft;
alias big=BigInt;alias pair(X,Y)=Tuple!(X,"fi",Y,"se");
alias lint=long;private const int mod=1_000_000_007;
alias pii=pair!(int,int);alias pll=pair!(long,long);alias mp=make_pair;alias gcd=std.numeric.gcd;
private
{
	pure nothrow
	{
		T lcm (T)(auto ref T a,auto ref T b){return a/gcd(a,b)*b;}
		pair!(X,Y) make_pair(X,Y)(in X x_,in Y y_){return tuple!(X,"fi",Y,"se")(x_,y_);}
		big gcd(big a,big b){while(b){a%=b;swap(a,b);}return a;}
		@property X sqr(X)(in X a_) {return a_*a_;}
		@property X cub(X)(in X a_) {return a_*a_*a_;}
		int sz(T)(T a) if(hasLength!T){return cast(int)a.length;}
		size_t lowb(T,X)(T a,auto ref X g)
		if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
		{
			size_t l=0,r=a.length;
			while(r-l>1)
			{
				auto m=(l+r)>>1;
				if(!(a[m]<g))r=m;
				else l=m;
			}
			return (!(a[l]<g))?l:r;
		}
		size_t upb(T,X)(T a,auto ref X g)
		if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
		{
			size_t l=0,r=a.length;
			while(r-l>1)
			{
				auto m=(l+r)>>1;
				if(g<a[m])r=m;
				else l=m;
			}
			return (g<a[l])?l:r;
		}
		size_t binf(T,X)(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;
		}
		bool binary_search(T,X)(T a,auto ref X g)
		if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
		{
			return binf(a,g)!=a.length;
		}
	}
	void putarr(X)(in X a,in char ch=' ') if(isInputRange!X && !isInputRange!(ElementEncodingType!X))
	{foreach(const ref i;a)write(i,ch);}
	void putarr(X)(in X a) if(isInputRange!X && isInputRange!(ElementEncodingType!X))
	{
		foreach(ref const i;a)
		{
			foreach(ref const j;i)write(j,' ');
			writeln;
		}
	}
	bool getarr(X)(X a,in size_t n)
	{bool b=1; foreach(ref i;a[0..n])b=input(&i);return b;}
	bool input(T...)(auto ref T ptrs) if (ptrs.length > 0)
	{
		size_t s=0;
		foreach(ref e;ptrs)
		{
			if(isSomeChar!(Unqual!(typeof(e))))s+=readf(" %c",&e);
			else s+=readf(" %s",&e);
		}
		return s==ptrs.length;
	}
	bool read(T...)(auto ref T ptrs) if (ptrs.length > 0)
	{
		size_t s=0;
		foreach(ref e;ptrs)
		{
			if(isSomeChar!(Unqual!(typeof(e))))s+=readf(" %c",&e);
			else s+=readf(" %s",&e);
		}
		readln;
		return s==ptrs.length;
	}
	nothrow auto inf(in char* name) {return freopen(name,"r",core.stdc.stdio.stdin);}
	nothrow auto ouf(in char* name) {return freopen(name,"w",core.stdc.stdio.stdout);}
	@property auto arread(T)(){return readln.splitter.map!(to!(T)).array;}
	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--------------------------
private
{
	//Random gen;
	class item
	{
		int key,add,cnt;
		uint prior;
		item l,r;
		this()
		{
			l=r=null;
			prior=uniform!uint;
			cnt=1;
		}
	};
	void push(item t)
	{
		t.key+=t.add;
		if(t.l)t.l.add+=t.add;
		if(t.r)t.r.add+=t.add;
		t.add=0;
	}
	int cnt(item t){return t?t.cnt:0;}
	void upd(item t)
	{
		t.cnt=cnt(t.l)+cnt(t.r)+1;
	}
	void merge(ref item t,item l,item r)
	{
		debug writeln(l !is null);
		debug writeln(r is null);
		debug stdout.flush;
		if(!l || !r){t=l?l:r;return;}
		//assert(false);
		if(l.prior>r.prior)
		{
			push(l);
			merge(l.r,l.r,r);
			t=l;
		}
		else
		{
			push(r);
			merge(r.l,l,r.l);
			t=r;
		}
		upd(t);
	}
	void split(item t,int val,ref item l,ref item r)
	{
		if(!t){l=r=null;return;}
		push(t);
		if(t.key<val)
		{
			split(t.r,val,t.r,r);
			l=t;
		}
		else
		{
			split(t.l,val,l,t.l);
			r=t;
		}
		upd(t);
	}
	void cut(ref item t)
	{
		push(t);
		if(!t.l)
		{
			t=t.r;
			return;
		}
		else cut(t.l);
		upd(t);
	}
	item root;
	item l,r,m,x;
}
void main()
{
	version(ONLINE_JUDGE){}
	else
	{
		assert(freopen("input.txt","r",core.stdc.stdio.stdin));
		assert(freopen("output.txt","w",core.stdc.stdio.stdout));
	}
	int n;
	read(n);
	foreach(i;0..n)
	{
		int lb,rb;
		read(lb,rb);
		split(root,rb,m,r);
		split(m,lb,l,m);
		if(r)cut(r);
		x=new item;
		x.key=lb;
		if(m)m.add++;
		merge(l,l,x);
		merge(l,l,m);
		merge(root,l,r);
		x=l=r=m=null;
	}
	writeln(cnt(root));
/*loop:while(read(n))
	{

	}*/
}

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

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

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

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

uint xrand() {
  static uint x = 314159265, y = 358979323, z = 846264338, w = 327950288;
  uint t = x ^ x << 11; x = y; y = z; z = w; return w = w ^ w >> 19 ^ t ^ t >> 8;
}

class Tree {
  Tree l, r;
  int size;
  int val, ad;
  this(int val) {
    l = r = null;
    size = 1;
    this.val = val;
    this.ad = 0;
  }
  void propagate() {
    if (l) l.ad += ad;
    if (r) r.ad += ad;
    val += ad;
    ad = 0;
  }
  Tree change(Tree l, Tree r) {
    this.l = l;
    this.r = r;
    size = (l ? l.size : 0) + 1 + (r ? r.size : 0);
    return this;
  }
}
Tree merge(Tree a, Tree b) {
  if (!a) return b;
  if (!b) return a;
  a.propagate();
  b.propagate();
  if (xrand() % (a.size + b.size) < a.size) {
    return a.change(a.l, merge(a.r, b));
  } else {
    return b.change(merge(a, b.l), b.r);
  }
}
Tuple!(Tree, Tree) splitGE(Tree a, int key) {
  if (!a) return tuple!(Tree, Tree)(null, null);
  a.propagate();
  if (key <= a.val) {
    auto l = splitGE(a.l, key);
    return tuple(l[0], a.change(l[1], a.r));
  } else {
    auto r = splitGE(a.r, key);
    return tuple(a.change(a.l, r[0]), r[1]);
  }
}
Tuple!(Tree, Tree) splitHead(Tree a) {
  assert(a);
  a.propagate();
  if (a.l) {
    auto l = splitHead(a.l);
    return tuple(l[0], a.change(l[1], a.r));
  } else {
    return tuple(a, a.r);
  }
}
string toStr(Tree a) {
  if (!a) return "";
  return format("<%s (%s+%s) %s>", toStr(a.l), a.val, a.ad, toStr(a.r));
}
int[] toSeq(Tree a, int ad = 0) {
  if (!a) return [];
  ad += a.ad;
  return toSeq(a.l, ad) ~ (a.val + ad) ~ toSeq(a.r, ad);
}

void main() {
  try {
    for (; ; ) {
      const N = readInt();
      auto L = new int[N];
      auto R = new int[N];
      foreach (i; 0 .. N) {
        L[i] = readInt();
        R[i] = readInt();
      }

      debug {
        // O~(\sum_i (R[i] - L[i] + 1))
        int[] lis;
        foreach (i; 0 .. N) {
          foreach_reverse (x; L[i] .. R[i] + 1) {
            const pos = lis.lowerBound(x);
            if (pos == lis.length) {
              lis ~= x;
            } else {
              lis[pos] = x;
            }
          }
          writeln(L[i], " ", R[i], " ", lis);
        }
        writeln("brute: ", lis.length);
      }

      Tree t = null;
      foreach (i; 0 .. N) {
        auto sp0 = t.splitGE(L[i]);
        auto sp1 = sp0[1].splitGE(R[i]);
        if (sp1[1]) {
          sp1[1] = sp1[1].splitHead[1];
        }
        if (sp1[0]) {
          sp1[0].ad += 1;
        }
        debug {
          writeln("  ", sp0[0].toSeq, " ", sp1[0].toSeq, " ", sp1[1].toSeq);
        }
        t = sp0[0].merge(new Tree(L[i])).merge(sp1[0]).merge(sp1[1]);
        debug {
          writeln(L[i], " ", R[i], " ", t.toSeq, " ", t.toStr);
        }
      }
      writeln(t.size);
    }
  } catch (EOFException e) {
  }
}


There are n balls. They are arranged in a row. Each ball has a color (for convenience an integer) and an integer value. The color of the i-th ball is ci and the value of the i-th ball is vi.Squirrel Liss chooses some balls and makes a new sequence without changing the relative order of the balls. She wants to maximize the value of this sequence.The value of the sequence is defined as the sum of following values for each ball (where a and b are given constants):  If the ball is not in the beginning of the sequence and the color of the ball is same as previous ball's color, add (the value of the ball)  ×  a.  Otherwise, add (the value of the ball)  ×  b. You are given q queries. Each query contains two integers ai and bi. For each query find the maximal value of the sequence she can make when a = ai and b = bi.Note that the new sequence can be empty, and the value of an empty sequence is defined as zero.

The first line contains two integers n and q (1 ≤ n ≤ 105; 1 ≤ q ≤ 500). The second line contains n integers: v1, v2, ..., vn (|vi| ≤ 105). The third line contains n integers: c1, c2, ..., cn (1 ≤ ci ≤ n). The following q lines contain the values of the constants a and b for queries. The i-th of these lines contains two integers ai and bi (|ai|, |bi| ≤ 105). In each line integers are separated by single spaces.

For each query, output a line containing an integer — the answer to the query. The i-th line contains the answer to the i-th query in the input order. Please, do not write the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64d specifier.

NoteIn the first example, to achieve the maximal value:  In the first query, you should select 1st, 3rd, and 4th ball.  In the second query, you should select 3rd, 4th, 5th and 6th ball.  In the third query, you should select 2nd and 4th ball. Note that there may be other ways to achieve the maximal value.

import std.stdio;

static immutable N = 100000;
static immutable MAX_NUM = 1000000000000000;

int n, q;
int[] c;
long[] v, f;

int main() {
  auto input = stdin;
  auto output = stdout;
  input.readf(" %d %d", &n, &q);
  v.length = c.length = f.length = n + 1;
  for (int i = 1; i <= n; ++ i) input.readf(" %d", &v[i]);
  for (int i = 1; i <= n; ++ i) input.readf(" %d", &c[i]);
  while (q --) {
    long a, b, max = -MAX_NUM, sec = -MAX_NUM, ans = 0;
    input.readf(" %d %d", &a, &b);
    for (int i = 1; i <= n; ++ i) f[i] = -MAX_NUM;
    for (int i = 1; i <= n; ++ i) {
      long p = f[c[i]] == max ? sec : max, q = f[c[i]];
      bool flag = f[c[i]] == max;
      if (f[c[i]] < v[i] * b) f[c[i]] = v[i] * b;
      if (f[c[i]] < p + v[i] * b) f[c[i]] = p + v[i] * b;
      if (f[c[i]] < q + v[i] * a) f[c[i]] = q + v[i] * a;
      if (f[c[i]] >= max) {
        if (! flag) sec = max;
        max = f[c[i]];
      } else if (f[c[i]] > sec) sec = f[c[i]];
    }
    for (int i = 1; i <= n; ++ i) {
      if (ans < f[i]) ans = f[i];
    }
    output.writeln(ans);
  }
  return 0;
}

import std.stdio;

static immutable N = 100000;
static immutable MAX_NUM = 10000000000;

int n, q;
int[] c;
long[] v, f;

int main() {
  auto input = stdin;
  auto output = stdout;
  input.readf(" %d %d", &n, &q);
  v.length = c.length = f.length = n + 1;
  for (int i = 1; i <= n; ++ i) input.readf(" %d", &v[i]);
  for (int i = 1; i <= n; ++ i) input.readf(" %d", &c[i]);
  while (q --) {
    long a, b, max = -MAX_NUM, sec = -MAX_NUM, ans = 0;
    input.readf(" %d %d", &a, &b);
    for (int i = 1; i <= n; ++ i) f[i] = -MAX_NUM;
    for (int i = 1; i <= n; ++ i) {
      long p = f[c[i]] == max ? sec : max, q = f[c[i]];
      bool flag = f[c[i]] == max;
      if (f[c[i]] < v[i] * b) f[c[i]] = v[i] * b;
      if (f[c[i]] < p + v[i] * b) f[c[i]] = p + v[i] * b;
      if (f[c[i]] < q + v[i] * a) f[c[i]] = q + v[i] * a;
      if (f[c[i]] >= max) {
        if (! flag) sec = max;
        max = f[c[i]];
      } else if (f[c[i]] > sec) sec = f[c[i]];
    }
    for (int i = 1; i <= n; ++ i) {
      if (ans < f[i]) ans = f[i];
    }
    output.writeln(ans);
  }
  return 0;
}

import std.stdio;

static immutable N = 100000;
static immutable MAX_NUM = 1000000000000000000;

int n, q;
int[] c;
long[] v, f;

int main() {
  auto file = stdin;
  file.readf(" %d %d", &n, &q);
  v.length = c.length = n + 1, f.length = N + 1;
  for (int i = 1; i <= n; ++ i) file.readf(" %d", &v[i]);
  for (int i = 1; i <= n; ++ i) file.readf(" %d", &c[i]);
  while (q --) {
    long a, b, max = -MAX_NUM, sec = -MAX_NUM, ans = 0;
    bool flag = false, comp;
    file.readf(" %d %d", &a, &b);
    for (int i = 1; i <= N; ++ i) f[i] = -MAX_NUM;
    for (int i = 1; i <= n; ++ i) {
      long p = f[c[i]] == max ? sec : max, q = f[c[i]];
      comp = f[c[i]] == max;
      if (f[c[i]] < v[i] * b) f[c[i]] = v[i] * b;
      if (f[c[i]] < p + v[i] * b) f[c[i]] = p + v[i] * b;
      if (q > -MAX_NUM && f[c[i]] < q + v[i] * a) f[c[i]] = q + v[i] * a;
      if (f[c[i]] == max) flag = true;
      if (f[c[i]] > max) {
        if (flag || ! comp) sec = max;
        max = f[c[i]];
        flag = false;
      } else if (f[c[i]] > sec) sec = f[c[i]];
    }
    for (int i = 1; i <= N; ++ i) {
      if (ans < f[i]) ans = f[i];
    }
    writeln(ans);
  }
  return 0;
}

import std.stdio;

static immutable N = 100000;
static immutable MAX_NUM = 1000000000000000000;

int n, q;
int[] c;
real[] v, f;
bool[] vis;

int main() {
  auto file = stdin;
  file.readf(" %d %d", &n, &q);
  v.length = c.length = f.length = vis.length = n + 1;
  for (int i = 1; i <= n; ++ i) file.readf(" %f", &v[i]);
  for (int i = 1; i <= n; ++ i) file.readf(" %d", &c[i]);
  while (q --) {
    long a, b;
    real max = -MAX_NUM, sec = -MAX_NUM, ans = 0;
    bool flag = false, comp;
    file.readf(" %d %d", &a, &b);
    for (int i = 1; i <= n; ++ i) f[i] = -MAX_NUM;
    for (int i = 1; i <= n; ++ i) vis[i] = false;
    for (int i = 1; i <= n; ++ i) {
      real p = f[c[i]] == max ? sec : max, q = f[c[i]];
      comp = f[c[i]] == max;
      if (f[c[i]] < v[i] * b) f[c[i]] = v[i] * b;
      if (f[c[i]] < p + v[i] * b) f[c[i]] = p + v[i] * b;
      if (vis[c[i]] && f[c[i]] < q + v[i] * a) f[c[i]] = q + v[i] * a;
      if (! comp && f[c[i]] == max) flag = true;
      if (f[c[i]] > max) {
        if (flag || ! comp) sec = max;
        max = f[c[i]];
        flag = false;
      } else if (f[c[i]] > sec) sec = f[c[i]];
      vis[c[i]] = true;
    }
    for (int i = 1; i <= n; ++ i) {
      if (ans < f[i]) ans = f[i];
    }
    writeln(cast(long) ans);
  }
  return 0;
}

import std.stdio;

static immutable N = 100000;

int n, q;
int[] c;
long[] v, f;
bool[] vis;

int main() {
  auto file = stdin;
  file.readf(" %d %d", &n, &q);
  v.length = c.length = f.length = vis.length = n + 1;
  for (int i = 1; i <= n; ++ i) file.readf(" %d", &v[i]);
  for (int i = 1; i <= n; ++ i) file.readf(" %d", &c[i]);
  while (q --) {
    long a, b, max = 0, sec = 0, ans = 0;
    bool flag = false, comp;
    file.readf(" %d %d", &a, &b);
    for (int i = 1; i <= n; ++ i) f[i] = 0;
    for (int i = 1; i <= n; ++ i) vis[i] = false;
    for (int i = 1; i <= n; ++ i) {
      long p = f[c[i]] == max ? sec : max, q = f[c[i]];
      comp = f[c[i]] == max;
      if (f[c[i]] < v[i] * b) f[c[i]] = v[i] * b;
      if (f[c[i]] < p + v[i] * b) f[c[i]] = p + v[i] * b;
      if (vis[c[i]] && f[c[i]] < q + v[i] * a) f[c[i]] = q + v[i] * a;
      if (! comp && f[c[i]] == max) flag = true;
      if (f[c[i]] > max) {
        if (flag || ! comp) sec = max;
        max = f[c[i]];
        flag = false;
      } else if (f[c[i]] > sec) sec = f[c[i]];
      vis[c[i]] = true;
    }
    for (int i = 1; i <= n; ++ i) {
      if (ans < f[i]) ans = f[i];
    }
    writeln(ans);
  }
  return 0;
}

import std.stdio;

static immutable N = 100000;
static immutable MAX_NUM = 10000000000000;

int n, q;
int[] c;
long[] v, f;
bool[] vis;

int main() {
  auto file = stdin;
  file.readf(" %d %d", &n, &q);
  v.length = c.length = n + 1, f.length = vis.length = N + 1;
  for (int i = 1; i <= n; ++ i) file.readf(" %d", &v[i]);
  for (int i = 1; i <= n; ++ i) file.readf(" %d", &c[i]);
  while (q --) {
    long a, b, max = -MAX_NUM, sec = -MAX_NUM, ans = 0;
    bool flag = false, comp;
    file.readf(" %d %d", &a, &b);
    for (int i = 1; i <= N; ++ i) f[i] = -MAX_NUM;
    for (int i = 1; i <= N; ++ i) vis[i] = false;
    for (int i = 1; i <= n; ++ i) {
      long p = f[c[i]] == max ? sec : max, q = f[c[i]];
      comp = f[c[i]] == max;
      if (f[c[i]] < v[i] * b) f[c[i]] = v[i] * b;
      if (f[c[i]] < p + v[i] * b) f[c[i]] = p + v[i] * b;
      if (vis[c[i]] && f[c[i]] < q + v[i] * a) f[c[i]] = q + v[i] * a;
      if (f[c[i]] == max) flag = true;
      if (f[c[i]] > max) {
        if (flag || ! comp) sec = max;
        max = f[c[i]];
        flag = false;
      } else if (f[c[i]] > sec) sec = f[c[i]];
      vis[c[i]] = true;
    }
    for (int i = 1; i <= N; ++ i) {
      if (ans < f[i]) ans = f[i];
    }
    writeln(ans);
  }
  return 0;
}

import std.stdio;

static immutable N = 100000;

int n, q;
int[] v, c, f;

int main() {
  auto file = stdin;
  file.readf(" %d %d", &n, &q);
  v.length = c.length = n + 1, f.length = N + 1;
  for (int i = 1; i <= n; ++ i) file.readf(" %d", &v[i]);
  for (int i = 1; i <= n; ++ i) file.readf(" %d", &c[i]);
  while (q --) {
    int a, b, max = 0, sec = 0, ans = 0;
    bool flag = false, comp;
    file.readf(" %d %d", &a, &b);
    for (int i = 1; i <= N; ++ i) f[i] = -1000000000;
    for (int i = 1; i <= n; ++ i) {
      int p = f[c[i]] == max ? sec : max, q = f[c[i]];
      comp = f[c[i]] == max;
      if (f[c[i]] < v[i] * b) f[c[i]] = v[i] * b;
      if (f[c[i]] < p + v[i] * b) f[c[i]] = p + v[i] * b;
      if (q > -1000000000 && f[c[i]] < q + v[i] * a) f[c[i]] = q + v[i] * a;
      if (f[c[i]] == max) flag = true;
      if (f[c[i]] > max) {
        if (flag || ! comp) sec = max;
        max = f[c[i]];
        flag = false;
      } else if (f[c[i]] > sec) sec = f[c[i]];
    }
    for (int i = 1; i <= N; ++ i) {
      if (ans < f[i]) ans = f[i];
    }
    writeln(ans);
  }
  return 0;
}

import std.stdio;

static immutable N = 100000;
static immutable MAX_NUM = 10000000000000;

int n, q;
int[] c;
real[] v, f;
bool[] vis;

int main() {
  auto file = stdin;
  file.readf(" %d %d", &n, &q);
  v.length = c.length = f.length = vis.length = n + 1;
  for (int i = 1; i <= n; ++ i) file.readf(" %f", &v[i]);
  for (int i = 1; i <= n; ++ i) file.readf(" %d", &c[i]);
  while (q --) {
    long a, b;
    real max = -MAX_NUM, sec = -MAX_NUM, ans = 0;
    bool flag = false, comp;
    file.readf(" %d %d", &a, &b);
    for (int i = 1; i <= n; ++ i) f[i] = -MAX_NUM;
    for (int i = 1; i <= n; ++ i) vis[i] = false;
    for (int i = 1; i <= n; ++ i) {
      real p = f[c[i]] == max ? sec : max, q = f[c[i]];
      comp = f[c[i]] == max;
      if (f[c[i]] < v[i] * b) f[c[i]] = v[i] * b;
      if (f[c[i]] < p + v[i] * b) f[c[i]] = p + v[i] * b;
      if (vis[c[i]] && f[c[i]] < q + v[i] * a) f[c[i]] = q + v[i] * a;
      if (! comp && f[c[i]] == max) flag = true;
      if (f[c[i]] > max) {
        if (flag || ! comp) sec = max;
        max = f[c[i]];
        flag = false;
      } else if (f[c[i]] > sec) sec = f[c[i]];
      vis[c[i]] = true;
    }
    for (int i = 1; i <= n; ++ i) {
      if (ans < f[i]) ans = f[i];
    }
    writeln(cast(long) ans);
  }
  return 0;
}

import std.stdio;

static immutable N = 100000;

int n, q;
int[] c;
long[] v, f;

int main() {
  auto file = stdin;
  file.readf(" %d %d", &n, &q);
  v.length = c.length = n + 1, f.length = N + 1;
  for (int i = 1; i <= n; ++ i) file.readf(" %d", &v[i]);
  for (int i = 1; i <= n; ++ i) file.readf(" %d", &c[i]);
  while (q --) {
    long a, b, max = 0, sec = 0, ans = 0;
    bool flag = false, comp;
    file.readf(" %d %d", &a, &b);
    for (int i = 1; i <= N; ++ i) f[i] = -1000000000000000000;
    for (int i = 1; i <= n; ++ i) {
      long p = f[c[i]] == max ? sec : max, q = f[c[i]];
      comp = f[c[i]] == max;
      if (f[c[i]] < v[i] * b) f[c[i]] = v[i] * b;
      if (f[c[i]] < p + v[i] * b) f[c[i]] = p + v[i] * b;
      if (q > -1000000000000000000 && f[c[i]] < q + v[i] * a) f[c[i]] = q + v[i] * a;
      if (f[c[i]] == max) flag = true;
      if (f[c[i]] > max) {
        if (flag || ! comp) sec = max;
        max = f[c[i]];
        flag = false;
      } else if (f[c[i]] > sec) sec = f[c[i]];
    }
    for (int i = 1; i <= N; ++ i) {
      if (ans < f[i]) ans = f[i];
    }
    writeln(ans);
  }
  return 0;
}

import std.stdio;

static immutable N = 100000;
static immutable MAX_NUM = 10000000000000;

int n, q;
int[] c;
long[] v, f;
bool[] vis;

int main() {
  auto file = stdin;
  file.readf(" %d %d", &n, &q);
  v.length = c.length = n + 1, f.length = vis.length = N + 1;
  for (int i = 1; i <= n; ++ i) file.readf(" %d", &v[i]);
  for (int i = 1; i <= n; ++ i) file.readf(" %d", &c[i]);
  while (q --) {
    long a, b, max = -MAX_NUM, sec = -MAX_NUM, ans = 0;
    bool flag = false, comp;
    file.readf(" %d %d", &a, &b);
    for (int i = 1; i <= N; ++ i) f[i] = -MAX_NUM;
    for (int i = 1; i <= N; ++ i) vis[i] = false;
    for (int i = 1; i <= n; ++ i) {
      long p = f[c[i]] == max ? sec : max, q = f[c[i]];
      comp = f[c[i]] == max;
      if (f[c[i]] < v[i] * b) f[c[i]] = v[i] * b;
      if (f[c[i]] < p + v[i] * b) f[c[i]] = p + v[i] * b;
      if (vis[c[i]] && f[c[i]] < q + v[i] * a) f[c[i]] = q + v[i] * a;
      if (! comp && f[c[i]] == max) flag = true;
      if (f[c[i]] > max) {
        if (flag || ! comp) sec = max;
        max = f[c[i]];
        flag = false;
      } else if (f[c[i]] > sec) sec = f[c[i]];
      vis[c[i]] = true;
    }
    for (int i = 1; i <= N; ++ i) {
      if (ans < f[i]) ans = f[i];
    }
    writeln(ans);
  }
  return 0;
}

import std.stdio;

static immutable N = 100000;

int n, q;
int[] c;
long[] v, f;

int main() {
  auto file = stdin;
  file.readf(" %d %d", &n, &q);
  v.length = c.length = n + 1, f.length = N + 1;
  for (int i = 1; i <= n; ++ i) file.readf(" %d", &v[i]);
  for (int i = 1; i <= n; ++ i) file.readf(" %d", &c[i]);
  while (q --) {
    long a, b, max = 0, sec = 0, ans = 0;
    bool flag = false, comp;
    file.readf(" %d %d", &a, &b);
    for (int i = 1; i <= N; ++ i) f[i] = -1000000000;
    for (int i = 1; i <= n; ++ i) {
      long p = f[c[i]] == max ? sec : max, q = f[c[i]];
      comp = f[c[i]] == max;
      if (f[c[i]] < v[i] * b) f[c[i]] = v[i] * b;
      if (f[c[i]] < p + v[i] * b) f[c[i]] = p + v[i] * b;
      if (q > -1000000000 && f[c[i]] < q + v[i] * a) f[c[i]] = q + v[i] * a;
      if (f[c[i]] == max) flag = true;
      if (f[c[i]] > max) {
        if (flag || ! comp) sec = max;
        max = f[c[i]];
        flag = false;
      } else if (f[c[i]] > sec) sec = f[c[i]];
    }
    for (int i = 1; i <= N; ++ i) {
      if (ans < f[i]) ans = f[i];
    }
    writeln(ans);
  }
  return 0;
}


Logical quantifiers are very useful tools for expressing claims about a set. For this problem, let's focus on the set of real numbers specifically. The set of real numbers includes zero and negatives. There are two kinds of quantifiers: universal ($$$\forall$$$) and existential ($$$\exists$$$). You can read more about them here.The universal quantifier is used to make a claim that a statement holds for all real numbers. For example:  $$$\forall x,x<100$$$ is read as: for all real numbers $$$x$$$, $$$x$$$ is less than $$$100$$$. This statement is false.  $$$\forall x,x>x-1$$$ is read as: for all real numbers $$$x$$$, $$$x$$$ is greater than $$$x-1$$$. This statement is true. The existential quantifier is used to make a claim that there exists some real number for which the statement holds. For example:  $$$\exists x,x<100$$$ is read as: there exists a real number $$$x$$$ such that $$$x$$$ is less than $$$100$$$. This statement is true.  $$$\exists x,x>x-1$$$ is read as: there exists a real number $$$x$$$ such that $$$x$$$ is greater than $$$x-1$$$. This statement is true. Moreover, these quantifiers can be nested. For example:  $$$\forall x,\exists y,x<y$$$ is read as: for all real numbers $$$x$$$, there exists a real number $$$y$$$ such that $$$x$$$ is less than $$$y$$$. This statement is true since for every $$$x$$$, there exists $$$y=x+1$$$.  $$$\exists y,\forall x,x<y$$$ is read as: there exists a real number $$$y$$$ such that for all real numbers $$$x$$$, $$$x$$$ is less than $$$y$$$. This statement is false because it claims that there is a maximum real number: a number $$$y$$$ larger than every $$$x$$$. Note that the order of variables and quantifiers is important for the meaning and veracity of a statement.There are $$$n$$$ variables $$$x_1,x_2,\ldots,x_n$$$, and you are given some formula of the form $$$$$$ f(x_1,\dots,x_n):=(x_{j_1}<x_{k_1})\land (x_{j_2}<x_{k_2})\land \cdots\land (x_{j_m}<x_{k_m}), $$$$$$where $$$\land$$$ denotes logical AND. That is, $$$f(x_1,\ldots, x_n)$$$ is true if every inequality $$$x_{j_i}<x_{k_i}$$$ holds. Otherwise, if at least one inequality does not hold, then $$$f(x_1,\ldots,x_n)$$$ is false.Your task is to assign quantifiers $$$Q_1,\ldots,Q_n$$$ to either universal ($$$\forall$$$) or existential ($$$\exists$$$) so that the statement $$$$$$ Q_1 x_1, Q_2 x_2, \ldots, Q_n x_n, f(x_1,\ldots, x_n) $$$$$$is true, and the number of universal quantifiers is maximized, or determine that the statement is false for every possible assignment of quantifiers.Note that the order the variables appear in the statement is fixed. For example, if $$$f(x_1,x_2):=(x_1<x_2)$$$ then you are not allowed to make $$$x_2$$$ appear first and use the statement $$$\forall x_2,\exists x_1, x_1<x_2$$$. If you assign $$$Q_1=\exists$$$ and $$$Q_2=\forall$$$, it will only be interpreted as $$$\exists x_1,\forall x_2,x_1<x_2$$$.

The first line contains two integers $$$n$$$ and $$$m$$$ ($$$2\le n\le 2\cdot 10^5$$$; $$$1\le m\le 2\cdot 10^5$$$) — the number of variables and the number of inequalities in the formula, respectively. The next $$$m$$$ lines describe the formula. The $$$i$$$-th of these lines contains two integers $$$j_i$$$,$$$k_i$$$ ($$$1\le j_i,k_i\le n$$$, $$$j_i\ne k_i$$$).

If there is no assignment of quantifiers for which the statement is true, output a single integer $$$-1$$$. Otherwise, on the first line output an integer, the maximum possible number of universal quantifiers. On the next line, output a string of length $$$n$$$, where the $$$i$$$-th character is "A" if $$$Q_i$$$ should be a universal quantifier ($$$\forall$$$), or "E" if $$$Q_i$$$ should be an existential quantifier ($$$\exists$$$). All letters should be upper-case. If there are multiple solutions where the number of universal quantifiers is maximum, print any.

NoteFor the first test, the statement $$$\forall x_1, \exists x_2, x_1<x_2$$$ is true. Answers of "EA" and "AA" give false statements. The answer "EE" gives a true statement, but the number of universal quantifiers in this string is less than in our answer.For the second test, we can show that no assignment of quantifiers, for which the statement is true exists.For the third test, the statement $$$\forall x_1, \forall x_2, \exists x_3, (x_1<x_3)\land (x_2<x_3)$$$ is true: We can set $$$x_3=\max\{x_1,x_2\}+1$$$.

import std.algorithm, std.stdio;
void main () {
	int n, m;
	readf !(" %s %s") (n, m);
	auto adj = new int [] [2] [n];
	foreach (j; 0..m) {
		int u, v;
		readf !(" %s %s") (u, v);
		u -= 1;
		v -= 1;
		adj[u][0] ~= v;
		adj[v][1] ~= u;
	}

	auto vis = new byte [2] [n], ok = true, res = "";
	void recur (int k, int v) {
		if (vis[v][k]) {
			ok &= vis[v][k] > 1;
			return;
		}
		vis[v][k] = 1;
		foreach (u; adj[v][k]) recur (k, u);
		vis[v][k] = 2;
	}
	foreach (i; 0..n) {
		res ~= "AE"[vis[i][].any];
		recur (0, i);
		recur (1, i);
	}

	if (ok) {
		writeln (res.count ('A'));
		writeln (res);
	}
	else writeln (-1);
}

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

void main ()
{
	int n, m;
	while (readf !(" %s %s") (n, m) > 0)
	{
		auto fwd = new int [] [n];
		auto rev = new int [] [n];
		foreach (j; 0..m)
		{
			int u, v;
			readf !(" %s %s") (u, v);
			u -= 1;
			v -= 1;
			fwd[u] ~= v;
			rev[v] ~= u;
		}

		auto fwdVis = new byte [n];
		auto revVis = new byte [n];
		bool ok = true;

		void recur (ref int [] [] adj, ref byte [] vis, int v)
		{
			if (vis[v] > 0)
			{
				if (vis[v] == 1)
				{
					ok = false;
				}
				return;
			}
			vis[v] = 1;
			foreach (u; adj[v])
			{
				recur (adj, vis, u);
			}
			vis[v] = 2;
		}

		string answer;
		foreach (i; 0..n)
		{
			if (!fwdVis[i] && !revVis[i])
			{
				answer ~= 'A';
			}
			else
			{
				answer ~= 'E';
			}
			recur (fwd, fwdVis, i);
			recur (rev, revVis, i);
		}

		if (ok)
		{
			writeln (answer.count ('A'));
			writeln (answer);
		}
		else
		{
			writeln (-1);
		}
	}
}

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

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

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

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

int N, M;
int[] A, B;

int[][][] G;

int[] vis;
bool[][] viss;

bool dfsTop(int u) {
  vis[u] = 1;
  foreach (i; G[0][u]) {
    const v = A[i] ^ B[i] ^ u;
    if (vis[v] == 0) {
      if (!dfsTop(v)) {
        return false;
      }
    } else if (vis[v] == 1) {
      return false;
    }
  }
  vis[u] = 2;
  return true;
}

void dfs(int s, int u) {
  viss[s][u] = true;
  foreach (i; G[s][u]) {
    const v = A[i] ^ B[i] ^ u;
    if (!viss[s][v]) {
      dfs(s, v);
    }
  }
}

void main() {
  try {
    for (; ; ) {
      N = readInt();
      M = readInt();
      A = new int[M];
      B = new int[M];
      foreach (i; 0 .. M) {
        A[i] = readInt() - 1;
        B[i] = readInt() - 1;
      }

      G = new int[][][](2, N);
      foreach (i; 0 .. M) {
        G[0][A[i]] ~= i;
        G[1][B[i]] ~= i;
      }

      vis = new int[N];
      bool ok = true;
      foreach (u; 0 .. N) {
        if (vis[u] == 0) {
          if (!dfsTop(u)) {
            ok = false;
          }
        }
      }
      if (ok) {
        viss = new bool[][](2, N);
        int ansCnt;
        auto ans = new char[N];
        ans[] = 'E';
        foreach (u; 0 .. N) {
          if (!viss[0][u] && !viss[1][u]) {
            ++ansCnt;
            ans[u] = 'A';
          }
          foreach (s; 0 .. 2) {
            if (!viss[s][u]) {
              dfs(s, u);
            }
          }
        }
        writeln(ansCnt);
        writeln(ans);
      } else {
        writeln(-1);
      }
    }
  } catch (EOFException e) {
  }
}

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

void main ()
{
	int n, m;
	while (readf !(" %s %s") (n, m) > 0)
	{
		auto fwd = new int [] [n];
		auto rev = new int [] [n];
		foreach (j; 0..m)
		{
			int u, v;
			readf !(" %s %s") (u, v);
			u -= 1;
			v -= 1;
			fwd[u] ~= v;
			rev[v] ~= u;
		}

		auto fwdVis = new byte [n];
		auto revVis = new byte [n];
		bool ok = true;

		void recur (ref int [] [] adj, ref byte [] vis, int v)
		{
			if (vis[v] > 0)
			{
				if (vis[v] == 1)
				{
					ok = false;
				}
				return;
			}
			vis[v] = 1;
			foreach (u; adj[v])
			{
				recur (adj, vis, u);
			}
			vis[v] = 2;
		}

		string answer;
		foreach (i; 0..n)
		{
			if (!fwdVis[i] && !revVis[i])
			{
				answer ~= 'A';
				recur (fwd, fwdVis, i);
				recur (rev, revVis, i);
			}
			else
			{
				answer ~= 'E';
			}
		}

		if (ok)
		{
			writeln (answer.count ('A'));
			writeln (answer);
		}
		else
		{
			writeln (-1);
		}
	}
}

import std.algorithm, std.stdio;
void main () {
	int n, m;
	readf !(" %s %s") (n, m);
	auto adj = new int [] [] [] (2, n);
	foreach (j; 0..m) {
		int u, v;
		readf !(" %s %s") (u, v);
		u -= 1;
		v -= 1;
		adj[0][u] ~= v;
		adj[1][v] ~= u;
	}

	auto vis = new byte [] [] (2, n), ok = true, res = "";
	void recur (int k, int v) {
		if (vis[k][v]) {
			ok &= vis[k][v] > 1;
			return;
		}
		vis[k][v] = 1;
		foreach (u; adj[k][v]) recur (k, u);
		vis[k][v] = 2;
	}
	foreach (i; 0..n) {
		res ~= "AE"[vis[i].any];
		recur (0, i);
		recur (1, i);
	}

	if (ok) {
		writeln (res.count ('A'));
		writeln (res);
	}
	else writeln (-1);
}

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

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

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

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

int N, M;
int[] A, B;

int[][][] G;

int[] vis;
bool[][] viss;

bool dfsTop(int u) {
  vis[u] = 1;
  foreach (i; G[0][u]) {
    const v = A[i] ^ B[i] ^ u;
    if (vis[v] == 0) {
      if (!dfsTop(v)) {
        return false;
      }
    } else if (vis[v] == 1) {
      return false;
    }
  }
  vis[u] = 2;
  return true;
}

void dfs(int s, int u) {
  viss[s][u] = true;
  foreach (i; G[s][u]) {
    const v = A[i] ^ B[i] ^ u;
    if (!viss[s][v]) {
      dfs(s, v);
    }
  }
}

void main() {
  try {
    for (; ; ) {
      N = readInt();
      M = readInt();
      A = new int[M];
      B = new int[M];
      foreach (i; 0 .. M) {
        A[i] = readInt() - 1;
        B[i] = readInt() - 1;
      }

      G = new int[][][](2, N);
      foreach (i; 0 .. M) {
        G[0][A[i]] ~= i;
        G[1][B[i]] ~= i;
      }

      vis = new int[N];
      bool ok = true;
      foreach (u; 0 .. N) {
        if (vis[u] == 0) {
          if (!dfsTop(u)) {
            ok = false;
          }
        }
      }
      if (ok) {
        viss = new bool[][](2, N);
        auto ans = new char[N];
        ans[] = 'E';
        foreach (u; 0 .. N) {
          if (!viss[0][u] && !viss[1][u]) {
            ans[u] = 'A';
          }
          foreach (s; 0 .. 2) {
            if (!viss[s][u]) {
              dfs(s, u);
            }
          }
        }
        writeln(ans);
      } else {
        writeln(-1);
      }
    }
  } catch (EOFException e) {
  }
}


Codeforces separates its users into $$$4$$$ divisions by their rating:  For Division 1: $$$1900 \leq \mathrm{rating}$$$  For Division 2: $$$1600 \leq \mathrm{rating} \leq 1899$$$  For Division 3: $$$1400 \leq \mathrm{rating} \leq 1599$$$  For Division 4: $$$\mathrm{rating} \leq 1399$$$ Given a $$$\mathrm{rating}$$$, print in which division the $$$\mathrm{rating}$$$ belongs.

The first line of the input contains an integer $$$t$$$ ($$$1 \leq t \leq 10^4$$$) — the number of testcases. The description of each test consists of one line containing one integer $$$\mathrm{rating}$$$ ($$$-5000 \leq \mathrm{rating} \leq 5000$$$).

For each test case, output a single line containing the correct division in the format "Division X", where $$$X$$$ is an integer between $$$1$$$ and $$$4$$$ representing the division for the corresponding rating.

Division 4
Division 4
Division 4
Division 4
Division 3
Division 2
Division 1

NoteFor test cases $$$1-4$$$, the corresponding ratings are $$$-789$$$, $$$1299$$$, $$$1300$$$, $$$1399$$$, so all of them are in division $$$4$$$.For the fifth test case, the corresponding rating is $$$1400$$$, so it is in division $$$3$$$.For the sixth test case, the corresponding rating is $$$1679$$$, so it is in division $$$2$$$.For the seventh test case, the corresponding rating is $$$2300$$$, so it is in division $$$1$$$.

import std;

void main ()
{
	auto tests = readln.strip.to !(int);
	foreach (test; 0..tests)
	{
		auto n = readln.strip.to !(int);
		write ("Division ");
		writeln (1 + (n < 1900) + (n < 1600) + (n < 1400));
	}
}


You are given an array $$$a_1, a_2, \dots , a_n$$$ and two integers $$$m$$$ and $$$k$$$.You can choose some subarray $$$a_l, a_{l+1}, \dots, a_{r-1}, a_r$$$. The cost of subarray $$$a_l, a_{l+1}, \dots, a_{r-1}, a_r$$$ is equal to $$$\sum\limits_{i=l}^{r} a_i - k \lceil \frac{r - l + 1}{m} \rceil$$$, where $$$\lceil x \rceil$$$ is the least integer greater than or equal to $$$x$$$. The cost of empty subarray is equal to zero.For example, if $$$m = 3$$$, $$$k = 10$$$ and $$$a = [2, -4, 15, -3, 4, 8, 3]$$$, then the cost of some subarrays are:  $$$a_3 \dots a_3: 15 - k \lceil \frac{1}{3} \rceil = 15 - 10 = 5$$$;  $$$a_3 \dots a_4: (15 - 3) - k \lceil \frac{2}{3} \rceil = 12 - 10 = 2$$$;  $$$a_3 \dots a_5: (15 - 3 + 4) - k \lceil \frac{3}{3} \rceil = 16 - 10 = 6$$$;  $$$a_3 \dots a_6: (15 - 3 + 4 + 8) - k \lceil \frac{4}{3} \rceil = 24 - 20 = 4$$$;  $$$a_3 \dots a_7: (15 - 3 + 4 + 8 + 3) - k \lceil \frac{5}{3} \rceil = 27 - 20 = 7$$$. Your task is to find the maximum cost of some subarray (possibly empty) of array $$$a$$$.

The first line contains three integers $$$n$$$, $$$m$$$, and $$$k$$$ ($$$1 \le n \le 3 \cdot 10^5, 1 \le m \le 10, 1 \le k \le 10^9$$$). The second line contains $$$n$$$ integers $$$a_1, a_2, \dots, a_n$$$ ($$$-10^9 \le a_i \le 10^9$$$).

Print the maximum cost of some subarray of array $$$a$$$.

import std.stdio, std.conv, std.string, std.array, std.range, std.algorithm, std.container;
import std.math, std.random, std.bigint, std.datetime, std.format;
void main(string[] args){ if(args.length > 1) if(args[1] == "-debug") DEBUG = 1; solve(); }
void log()(){ writeln(""); } void log(T, A ...)(T t, lazy A a){ if(DEBUG) write(t, " "), log(a); } bool DEBUG = 0;
string read(){ static string[] ss; while(!ss.length) ss = readln.chomp.split; string res = ss[0]; ss.popFront; return res; }
// ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- //

void solve(){
	int n = read.to!int;
	int m = read.to!int;
	long k = read.to!long;
	long[] as;
	foreach(i; 0 .. n) as ~= read.to!long;
	log("as:", as);

	long best = 0;
	foreach(r; 0 .. m){
		log("r:", r);
		long[] bs;
		foreach(i, a; as) if(i % m == r) bs ~= a - k; else bs ~= a;
		log("bs:", bs);

		long sum;
		for(int i = r; i < n; i ++){
			if(i % m == r){
				if(sum < 0) sum = 0;
			}

			long b = bs[i];
			sum += b;
			if(sum > best) best = sum;
			log("i:", i, "sum:", sum, "best:", best);

		}
	}

	best.writeln;

}


Ivan is a student at Berland State University (BSU). There are n days in Berland week, and each of these days Ivan might have some classes at the university.There are m working hours during each Berland day, and each lesson at the university lasts exactly one hour. If at some day Ivan's first lesson is during i-th hour, and last lesson is during j-th hour, then he spends j - i + 1 hours in the university during this day. If there are no lessons during some day, then Ivan stays at home and therefore spends 0 hours in the university.Ivan doesn't like to spend a lot of time in the university, so he has decided to skip some lessons. He cannot skip more than k lessons during the week. After deciding which lessons he should skip and which he should attend, every day Ivan will enter the university right before the start of the first lesson he does not skip, and leave it after the end of the last lesson he decides to attend. If Ivan skips all lessons during some day, he doesn't go to the university that day at all.Given n, m, k and Ivan's timetable, can you determine the minimum number of hours he has to spend in the university during one week, if he cannot skip more than k lessons?

The first line contains three integers n, m and k (1 ≤ n, m ≤ 500, 0 ≤ k ≤ 500) — the number of days in the Berland week, the number of working hours during each day, and the number of lessons Ivan can skip, respectively. Then n lines follow, i-th line containing a binary string of m characters. If j-th character in i-th line is 1, then Ivan has a lesson on i-th day during j-th hour (if it is 0, there is no such lesson).

Print the minimum number of hours Ivan has to spend in the university during the week if he skips not more than k lessons.

NoteIn the first example Ivan can skip any of two lessons during the first day, so he spends 1 hour during the first day and 4 hours during the second day.In the second example Ivan can't skip any lessons, so he spends 4 hours every day.

import core.stdc.stdio;
import std.algorithm;
char[505] s;
int[505] c,q;
int[505][505] dp;
int n,m,k;
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	for (int i=1;i<=n;i++)
	{
		scanf("%s",&s);
		int len=0;
		for (int j=0;j<m;j++) if (s[j]=='1') c[++len]=j;
		int l;
		for (l=1;l<=len;l++)
		{
			q[l]=m;
			for (int j=1;j<=len-l+1;j++) q[l]=min(q[l],c[j+l-1]-c[j]+1);
		}
		for (int j=0;j<=k;j++) for (l=min(len,j),dp[i][j]=i*m;l>=0;l--) dp[i][j]=min(dp[i][j],dp[i-1][j-l]+q[len-l]);
	}
	printf("%d\n",dp[n][k]);
	return 0;
}

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

enum inf = 2*10^^9;

void main() {
    int n, m, k;
    scan(n, m, k);

    auto dd = new int[][](n, 0);
    foreach (i ; 0 .. n) {
        auto s = readln.chomp;
        foreach (j, ch; s) {
            if (ch == '1') {
                dd[i] ~= j;
            }
        }
    }

    debug {
        writeln(dd);
    }

    auto ks = new int[][](n, k + 1);

    foreach (i ; 0 .. n) {
        foreach (j ; 0 .. k + 1) {
            if (j >= dd[i].length) {
                ks[i][j] = 0;
            }
            else {
                ks[i][j] = inf;

                int sp = dd[i].length.to!int - j;

                foreach (l ; 0 .. j + 1) {
                    ks[i][j] = min(ks[i][j], dd[i][l + sp - 1] - dd[i][l] + 1);
                }
            }
        }
    }

    debug {
        writeln(ks);
    }

    auto dp = new int[][](n + 1, k + 1);
    fillAll(dp, inf);
    dp[0][0] = 0;

    foreach (i ; 1 .. n + 1) {
        foreach (j ; 0 .. k + 1) {
            foreach (l ; 0 .. j + 1) {
                dp[i][j] = min(dp[i][j], dp[i-1][l] + ks[i-1][j-l]);
            }
        }
    }

    int ans = dp[n][k];
    writeln(ans);
}

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

void main(){
  import std.stdio, std.string, std.conv, std.algorithm;

  int n, m, k; rd(n, m, k);
  auto a=new char[][](n, m);
  foreach(i; 0..n) a[i]=readln.chomp.to!(char[]);

  const int inf=1e9.to!(int);
  auto best=new int[][](n, k+1);
  foreach(i; 0..n){
    fill(best[i], inf);
    auto pos=new int[0];
    foreach(int j; 0..m)if(a[i][j]=='1') pos~=j;
    auto t=pos.length;
    if(t==0){fill(best[i], 0); continue;}
    foreach(l; 0..t)foreach(r; l..t)if(t-(r-l+1)<=k)
      chmin(best[i][t-(r-l+1)], pos[r]-pos[l]+1);
    if(t<=k) best[i][t]=0;
  }
  auto dp=new int[](k+1);
  fill(dp, inf);
  dp[k]=0;
  foreach(i; 0..n){
    auto nex=new int[](k+1);
    fill(nex, inf);
    for(int j=0; j<=k; j++)for(int l=0; l<=j; l++)
      chmin(nex[j-l], dp[j]+best[i][l]);
    dp.swap(nex);
  }
  writeln(reduce!(min)(dp));
}

void chmin(T)(ref T l, T r){if(l>r) l=r;}

void rd(T...)(ref T x){
  import std.stdio, std.string, std.conv;
  auto l=readln.split;
  assert(l.length==x.length);
  foreach(i, ref e; x){
    e=l[i].to!(typeof(e));
  }
}

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

enum inf = 10000;

void main() {
    int n, m, k;
    scan(n, m, k);

    auto dd = new int[][](n, 0);
    foreach (i ; 0 .. n) {
        auto s = readln.chomp;
        foreach (j, ch; s) {
            if (ch == '1') {
                dd[i] ~= j;
            }
        }
    }

    debug {
        writeln(dd);
    }

    auto ks = new int[][](n, k + 1);

    foreach (i ; 0 .. n) {
        foreach (j ; 0 .. k + 1) {
            if (j >= dd[i].length) {
                ks[i][j] = 0;
            }
            else {
                ks[i][j] = inf;

                int sp = dd[i].length.to!int - j;

                foreach (l ; 0 .. j + 1) {
                    ks[i][j] = min(ks[i][j], dd[i][l + sp - 1] - dd[i][l] + 1);
                }
            }
        }
    }

    debug {
        writeln(ks);
    }

    auto dp = new int[][](n + 1, k + 1);
    fillAll(dp, inf);
    dp[0][0] = 0;

    foreach (i ; 1 .. n + 1) {
        foreach (j ; 0 .. k + 1) {
            foreach (l ; 0 .. j + 1) {
                dp[i][j] = min(dp[i][j], dp[i-1][l] + ks[i-1][j-l]);
            }
        }
    }

    int ans = dp[n][k];
    writeln(ans);
}

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

void main(){
  import std.stdio, std.string, std.conv, std.algorithm;

  int n, m, k; rd(n, m, k);
  auto a=new char[][](n, m);
  foreach(i; 0..n) a[i]=readln.chomp.to!(char[]);

  const int inf=1e9.to!(int);
  auto best=new int[][](n, k+1);
  foreach(i; 0..n){
    fill(best[i], inf);
    auto pos=new int[0];
    foreach(int j; 0..m)if(a[i][j]=='1') pos~=j;
    auto t=pos.length;
    foreach(l; 0..t)foreach(r; l..t)if(t-(r-l+1)<=k)
      chmin(best[i][t-(r-l+1)], pos[r]-pos[l]+1);
  }
  auto dp=new int[](k+1);
  fill(dp, inf);
  dp[k]=0;
  foreach(i; 0..n){
    auto nex=new int[](k+1);
    fill(nex, inf);
    for(int j=0; j<=k; j++)for(int l=0; l<=j; l++)
      chmin(nex[j-l], dp[j]+best[i][l]);
    dp.swap(nex);
  }
  writeln(reduce!(min)(dp));
}

void chmin(T)(ref T l, T r){if(l>r) l=r;}

void rd(T...)(ref T x){
  import std.stdio, std.string, std.conv;
  auto l=readln.split;
  assert(l.length==x.length);
  foreach(i, ref e; x){
    e=l[i].to!(typeof(e));
  }
}

void main(){
  import std.stdio, std.string, std.conv, std.algorithm;

  int n, m, k; rd(n, m, k);
  auto a=new char[][](n, m);
  foreach(i; 0..n) a[i]=readln.chomp.to!(char[]);

  const int inf=1e9.to!(int);
  auto best=new int[][](n, k+1);
  foreach(i; 0..n){
    fill(best[i], inf);
    auto pos=new int[0];
    foreach(int j; 0..m)if(a[i][j]=='1') pos~=j;
    auto t=pos.length;
    if(t==0){fill(best[i], 0); continue;}
    foreach(l; 0..t)foreach(r; l..t)if(t-(r-l+1)<=k)
      chmin(best[i][t-(r-l+1)], pos[r]-pos[l]+1);
  }
  auto dp=new int[](k+1);
  fill(dp, inf);
  dp[k]=0;
  foreach(i; 0..n){
    auto nex=new int[](k+1);
    fill(nex, inf);
    for(int j=0; j<=k; j++)for(int l=0; l<=j; l++)
      chmin(nex[j-l], dp[j]+best[i][l]);
    dp.swap(nex);
  }
  writeln(reduce!(min)(dp));
}

void chmin(T)(ref T l, T r){if(l>r) l=r;}

void rd(T...)(ref T x){
  import std.stdio, std.string, std.conv;
  auto l=readln.split;
  assert(l.length==x.length);
  foreach(i, ref e; x){
    e=l[i].to!(typeof(e));
  }
}


You are wandering in the explorer space of the 2050 Conference.The explorer space can be viewed as an undirected weighted grid graph with size $$$n\times m$$$. The set of vertices is $$$\{(i, j)|1\le i\le n, 1\le j\le m\}$$$. Two vertices $$$(i_1,j_1)$$$ and $$$(i_2, j_2)$$$ are connected by an edge if and only if $$$|i_1-i_2|+|j_1-j_2|=1$$$.At each step, you can walk to any vertex connected by an edge with your current vertex. On each edge, there are some number of exhibits. Since you already know all the exhibits, whenever you go through an edge containing $$$x$$$ exhibits, your boredness increases by $$$x$$$.For each starting vertex $$$(i, j)$$$, please answer the following question: What is the minimum possible boredness if you walk from $$$(i, j)$$$ and go back to it after exactly $$$k$$$ steps?You can use any edge for multiple times but the boredness on those edges are also counted for multiple times. At each step, you cannot stay on your current vertex. You also cannot change direction while going through an edge. Before going back to your starting vertex $$$(i, j)$$$ after $$$k$$$ steps, you can visit $$$(i, j)$$$ (or not) freely.

The first line contains three integers $$$n$$$, $$$m$$$ and $$$k$$$ ($$$2\leq n, m\leq 500, 1\leq k\leq 20$$$). The $$$j$$$-th number ($$$1\le j \le m - 1$$$) in the $$$i$$$-th line of the following $$$n$$$ lines is the number of exibits on the edge between vertex $$$(i, j)$$$ and vertex $$$(i, j+1)$$$.  The $$$j$$$-th number ($$$1\le j\le m$$$) in the $$$i$$$-th line of the following $$$n-1$$$ lines is the number of exibits on the edge between vertex $$$(i, j)$$$ and vertex $$$(i+1, j)$$$.  The number of exhibits on each edge is an integer between $$$1$$$ and $$$10^6$$$.

Output $$$n$$$ lines with $$$m$$$ numbers each. The $$$j$$$-th number in the $$$i$$$-th line, $$$answer_{ij}$$$, should be the minimum possible boredness if you walk from $$$(i, j)$$$ and go back to it after exactly $$$k$$$ steps. If you cannot go back to vertex $$$(i, j)$$$ after exactly $$$k$$$ steps, $$$answer_{ij}$$$ should be $$$-1$$$.

NoteIn the first example, the answer is always $$$10$$$ no matter how you walk.In the second example, $$$answer_{21} = 10$$$, the path is $$$(2,1) \to (1,1) \to (1,2) \to (2,2) \to (2,1)$$$, the boredness is $$$4 + 1 + 2 + 3 = 10$$$.

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

immutable int infinity = int.max / 45;

void main ()
{
	int n, m, k;
	while (readf !(" %s %s %s") (n, m, k) > 0)
	{
		auto a = new int [] [] (n * 2 - 1, m * 2 - 1);
		foreach (ref line; a)
		{
			line[] = infinity;
		}
		foreach (i; 0..n)
		{
			foreach (j; 0..m - 1)
			{
				readf !(" %s") (a[i * 2][j * 2 + 1]);
			}
		}
		foreach (i; 0..n - 1)
		{
			foreach (j; 0..m)
			{
				readf !(" %s") (a[i * 2 + 1][j * 2]);
			}
		}
		auto answer = new int [] [] [] (2, n, m);
		int z = 0;

		if (!(k & 1))
		{
			foreach (i; 0..n)
			{
				foreach (j; 0..m)
				{
					answer[z][i][j] = 0;
				}
			}

			auto d = k / 2;
			for (int step = 0; step < d; step++)
			{
				z ^= 1;
				foreach (i; 0..n)
				{
					foreach (j; 0..m)
					{
						answer[z][i][j] = infinity;
					}
				}
				foreach (i; 0..n)
				{
					foreach (j; 0..m)
					{
						if (i - 1 >= 0)
						{
							answer[z][i][j] = min
							    (answer[z][i][j],
							    answer[!z][i - 1][j] +
							    a[i * 2 - 1][j * 2]);
						}
						if (i + 1 < n)
						{
							answer[z][i][j] = min
							    (answer[z][i][j],
							    answer[!z][i + 1][j] +
							    a[i * 2 + 1][j * 2]);
						}
						if (j - 1 >= 0)
						{
							answer[z][i][j] = min
							    (answer[z][i][j],
							    answer[!z][i][j - 1] +
							    a[i * 2][j * 2 - 1]);
						}
						if (j + 1 < m)
						{
							answer[z][i][j] = min
							    (answer[z][i][j],
							    answer[!z][i][j + 1] +
							    a[i * 2][j * 2 + 1]);
						}
					}
				}
			}
		}

		foreach (i; 0..n)
		{
			foreach (j; 0..m)
			{
				if (answer[z][i][j] == 0)
				{
					answer[z][i][j] = -1;
				}
				else
				{
					answer[z][i][j] *= 2;
				}
			}
		}
		writefln !("%(%(%s %)\n%)") (answer[z]);
	}
}

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

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

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

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

enum INF = 10^^9;

void main() {
  try {
    for (; ; ) {
      const M = readInt();
      const N = readInt();
      const K = readInt();
      auto yoko = new int[][](M, N - 1);
      foreach (x; 0 .. M) foreach (y; 0 .. N - 1) {
        yoko[x][y] = readInt();
      }
      auto tate = new int[][](M - 1, N);
      foreach (x; 0 .. M - 1) foreach (y; 0 .. N) {
        tate[x][y] = readInt();
      }

      auto ans = new int[][](M, N);
      if (K % 2 == 0) {
        auto dp = new int[][][](K / 2 + 1, M, N);
        foreach (k; 1 .. K / 2 + 1) {
          foreach (x; 0 .. M) foreach (y; 0 .. N) {
            dp[k][x][y] = INF;
          }
        }
        foreach (k; 0 .. K / 2) {
          foreach (x; 0 .. M) foreach (y; 0 .. N - 1) {
            chmin(dp[k + 1][x][y + 1], dp[k][x][y] + yoko[x][y]);
            chmin(dp[k + 1][x][y], dp[k][x][y + 1] + yoko[x][y]);
          }
          foreach (x; 0 .. M - 1) foreach (y; 0 .. N) {
            chmin(dp[k + 1][x + 1][y], dp[k][x][y] + tate[x][y]);
            chmin(dp[k + 1][x][y], dp[k][x + 1][y] + tate[x][y]);
          }
        }
        foreach (x; 0 .. M) foreach (y; 0 .. N) {
          ans[x][y] = 2 * dp[K / 2][x][y];
        }
      } else {
        foreach (x; 0 .. M) foreach (y; 0 .. N) {
          ans[x][y] = -1;
        }
      }

      foreach (x; 0 .. M) {
        foreach (y; 0 .. N) {
          if (y > 0) write(" ");
          write(ans[x][y]);
        }
        writeln;
      }
    }
  } catch (EOFException e) {
  }
}


A little boy Laurenty has been playing his favourite game Nota for quite a while and is now very hungry. The boy wants to make sausage and cheese sandwiches, but first, he needs to buy a sausage and some cheese.The town where Laurenty lives in is not large. The houses in it are located in two rows, n houses in each row. Laurenty lives in the very last house of the second row. The only shop in town is placed in the first house of the first row.The first and second rows are separated with the main avenue of the city. The adjacent houses of one row are separated by streets.Each crosswalk of a street or an avenue has some traffic lights. In order to cross the street, you need to press a button on the traffic light, wait for a while for the green light and cross the street. Different traffic lights can have different waiting time.The traffic light on the crosswalk from the j-th house of the i-th row to the (j + 1)-th house of the same row has waiting time equal to aij (1 ≤ i ≤ 2, 1 ≤ j ≤ n - 1). For the traffic light on the crossing from the j-th house of one row to the j-th house of another row the waiting time equals bj (1 ≤ j ≤ n). The city doesn't have any other crossings.The boy wants to get to the store, buy the products and go back. The main avenue of the city is wide enough, so the boy wants to cross it exactly once on the way to the store and exactly once on the way back home. The boy would get bored if he had to walk the same way again, so he wants the way home to be different from the way to the store in at least one crossing.    Figure to the first sample. Help Laurenty determine the minimum total time he needs to wait at the crossroads.

The first line of the input contains integer n (2 ≤ n ≤ 50) — the number of houses in each row.  Each of the next two lines contains n - 1 space-separated integer — values aij (1 ≤ aij ≤ 100).  The last line contains n space-separated integers bj (1 ≤ bj ≤ 100).

Print a single integer — the least total time Laurenty needs to wait at the crossroads, given that he crosses the avenue only once both on his way to the store and on his way back home.

NoteThe first sample is shown on the figure above. In the second sample, Laurenty's path can look as follows:   Laurenty crosses the avenue, the waiting time is 3;  Laurenty uses the second crossing in the first row, the waiting time is 2;  Laurenty uses the first crossing in the first row, the waiting time is 1;  Laurenty uses the first crossing in the first row, the waiting time is 1;  Laurenty crosses the avenue, the waiting time is 1;  Laurenty uses the second crossing in the second row, the waiting time is 3.  In total we get that the answer equals 11.In the last sample Laurenty visits all the crossings, so the answer is 4.

import std.stdio;
import std.conv;
import std.algorithm;
import std.array;
int[]get()
{
	string[]a=split(readln());
	int[]r;
	for(int i=0;i<a.length;i++)r~=to!int(a[i]);
	return r;
}
void main()
{
	int num;
	readf("%d\n",&num);
	int[]a=get(),b=get(),x=get();
	int mini1=1000000000,mini2=1000000000;
	for(int i=0;i<x.length;i++)
	{
		int now=0;
		for(int j=0;j<i;j++)now+=a[j];
		now+=x[i];
		for(int j=i;j<b.length;j++)now+=b[j];
		if(mini1>now)
		{
			mini2=mini1;
			mini1=now;
		}
		else if(mini2>now)mini2=now;
	}
	printf("%d\n",mini1+mini2);
	readln();
}


Petya is preparing for his birthday. He decided that there would be $$$n$$$ different dishes on the dinner table, numbered from $$$1$$$ to $$$n$$$. Since Petya doesn't like to cook, he wants to order these dishes in restaurants.Unfortunately, all dishes are prepared in different restaurants and therefore Petya needs to pick up his orders from $$$n$$$ different places. To speed up this process, he wants to order courier delivery at some restaurants. Thus, for each dish, there are two options for Petya how he can get it:  the dish will be delivered by a courier from the restaurant $$$i$$$, in this case the courier will arrive in $$$a_i$$$ minutes,  Petya goes to the restaurant $$$i$$$ on his own and picks up the dish, he will spend $$$b_i$$$ minutes on this. Each restaurant has its own couriers and they start delivering the order at the moment Petya leaves the house. In other words, all couriers work in parallel. Petya must visit all restaurants in which he has not chosen delivery, he does this consistently.For example, if Petya wants to order $$$n = 4$$$ dishes and $$$a = [3, 7, 4, 5]$$$, and $$$b = [2, 1, 2, 4]$$$, then he can order delivery from the first and the fourth restaurant, and go to the second and third on your own. Then the courier of the first restaurant will bring the order in $$$3$$$ minutes, the courier of the fourth restaurant will bring the order in $$$5$$$ minutes, and Petya will pick up the remaining dishes in $$$1 + 2 = 3$$$ minutes. Thus, in $$$5$$$ minutes all the dishes will be at Petya's house.Find the minimum time after which all the dishes can be at Petya's home.

The first line contains one positive integer $$$t$$$ ($$$1 \le t \le 2 \cdot 10^5$$$) — the number of test cases. Then $$$t$$$ test cases follow. Each test case begins with a line containing one integer $$$n$$$ ($$$1 \le n \le 2 \cdot 10^5$$$) — the number of dishes that Petya wants to order. The second line of each test case contains $$$n$$$ integers $$$a_1 \ldots a_n$$$ ($$$1 \le a_i \le 10^9$$$) — the time of courier delivery of the dish with the number $$$i$$$. The third line of each test case contains $$$n$$$ integers $$$b_1 \ldots b_n$$$ ($$$1 \le b_i \le 10^9$$$) — the time during which Petya will pick up the dish with the number $$$i$$$. The sum of $$$n$$$ over all test cases does not exceed $$$2 \cdot 10^5$$$.

For each test case output one integer — the minimum time after which all dishes can be at Petya's home.

import std.algorithm, std.container, std.range, std.array, std.ascii, std.bigint, std.conv, std.format, std.math, std.random, std.stdio, std.string, std.typecons;

void main() {
  int t;
  scanf("%d", &t);

  while (t--) {
    int n;
    scanf("%d", &n);

    auto arr = new long[][](n, 2);

    foreach (ref e; arr) scanf("%ld", &e[0]);
    foreach (ref e; arr) scanf("%ld", &e[1]);

    long low = 0, high = arr.fold!((r, x) => r + x[1])(0L);
    while (low < high) {
      auto m = (high + low) / 2;
      if (arr.filter!(a => a[0] > m).map!`a[1]`.sum <= m) {
        high = m;
      } else {
        low = m + 1;
      }
    }
    high.writeln;
  }
}

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

string FMT_F = "%.10f";

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

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

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

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

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

		auto index = a.MAKE_IDX();
		long at, bt = b.sum;
		ans[ti] = bt;
		foreach (i; index)
		{
			bt -= b[i];
			at.chmax(a[i]);
			ans[ti].chmin(max(at, bt));
		}
	}

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

import std.algorithm, std.container, std.range, std.array, std.ascii, std.bigint, std.conv, std.format, std.math, std.random, std.stdio, std.string, std.typecons;

void main() {
  int t;
  scanf("%d", &t);

  while (t--) {
    int n;
    scanf("%d", &n);

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

    foreach (ref e; arr) scanf("%d", &e[0]);
    foreach (ref e; arr) scanf("%d", &e[1]);

    long low = 0, high = arr.fold!((r, x) => r + x[1])(0L);
    while (low < high) {
      auto m = (high + low) / 2;
      if (arr.filter!(a => a[0] > m).map!`a[1]`.sum <= m) {
        high = m;
      } else {
        low = m + 1;
      }
    }
    high.writeln;
  }
}


You are given a string s. Each pair of numbers l and r that fulfill the condition 1 ≤ l ≤ r ≤ |s|, correspond to a substring of the string s, starting in the position l and ending in the position r (inclusive).Let's define the function of two strings F(x, y) like this. We'll find a list of such pairs of numbers for which the corresponding substrings of string x are equal to string y. Let's sort this list of pairs according to the pair's first number's increasing. The value of function F(x, y) equals the number of non-empty continuous sequences in the list.For example: F(babbabbababbab, babb) = 6. The list of pairs is as follows:(1, 4), (4, 7), (9, 12)Its continuous sequences are:   (1, 4)  (4, 7)  (9, 12)  (1, 4), (4, 7)  (4, 7), (9, 12)  (1, 4), (4, 7), (9, 12) Your task is to calculate for the given string s the sum F(s, x) for all x, that x belongs to the set of all substrings of a string s.

The only line contains the given string s, consisting only of small Latin letters (1 ≤ |s| ≤ 105).

Print the single number — the sought sum. Please do not use the %lld specificator to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64d specificator.

NoteIn the first sample the function values at x equal to "a", "aa", "aaa" and "aaaa" equal 10, 6, 3 and 1 correspondingly.In the second sample for any satisfying x the function value is 1.

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

int[] SA_IS(T)(immutable T[] data){
    int size = data.length;
    bool[] isL = new bool[size*2];
    int[] indices = new int[size];
    int maxc=0;
    foreach(c;data) maxc = max(maxc,c);
    int[] bucket = new int[1+maxc];
    SA_IS(data,indices,maxc,isL.ptr,bucket);
    return indices;
}

void CreateBeginIndices(T)(immutable T[] data,int maxVal,int[] bucket){
    bucket[0..maxVal] = 0;
    foreach(d;data) bucket[d]++;
    int sum=0;
    foreach(ref b;bucket){ b += sum; swap(b,sum);}
}

void CreateEndIndices(T)(immutable T[] data,int maxVal,int[] bucket){
    bucket[0..maxVal] = 0;
    foreach(d;data) bucket[d]++;
    int sum=0;
    foreach(i,b;bucket){ sum += b; bucket[i] = sum;}
}

void InduceSort(T)(immutable T[] data,int[] indices,int maxVal,bool[] isL,int[] bucket){
    CreateBeginIndices(data,maxVal,bucket);
    foreach(i;indices) if(i>0) if(isL[i-1]) indices[bucket[data[i-1]]++] = i-1;
}

void InvertInduceSort(T)(immutable T[] data,int[] indices,int maxVal,bool[] isL,int[] bucket){
    CreateEndIndices(data,maxVal,bucket);
    foreach_reverse(i;indices) if(i>0) if(!isL[i-1]) indices[--bucket[data[i-1]]] = i-1;
}

void SA_IS(T)(immutable T[] data,int[] indices,int maxVal,bool* isL,ref int[] bucket){
    int size = data.length;
    for(int i=size-2;i>=0;i--) isL[i] = (data[i] > data[i+1] || (data[i] == data[i+1] && isL[i+1]));
    if(bucket.length < maxVal+1) bucket = new int[maxVal+1];
    CreateEndIndices(data,maxVal,bucket);
    foreach(i;1..size) if(isL[i-1] && !isL[i]) indices[--bucket[data[i]]] = i;
    InduceSort(data,indices,maxVal,isL[0..size],bucket);
    InvertInduceSort(data,indices,maxVal,isL[0..size],bucket);

    int c=0;
    foreach(i;indices) if(i>0) if(isL[i-1] && !isL[i]) indices[c++] = i;
    indices[c..size] = -1;

    int idx=-1;
    int prev=-1;
    foreach(i;indices[0..c]){
        bool diff=false;
        foreach(d;0..size){
            if(prev == -1){ diff = true; break;}
            if(data[i+d] != data[prev+d] || isL[i+d] != isL[prev+d]){ diff = true; break;}
            if(d>0 && isL[i+d-1] && !isL[i+d]) break;
        }
        if(diff){ idx++; prev = i;}
        indices[c+i/2] = idx;
    }
    int _=size;
    foreach_reverse(i;indices[c..size]) if(i >= 0) indices[--_] = i;

    int[] nxdata = indices[size-c..size];
    int[] nxsa = indices[0..c];
    nxsa[] = 0;
    if(c == idx+1) foreach(i;0..c) nxsa[nxdata[i]] = i;
    else SA_IS(cast(immutable int[])nxdata,nxsa,idx,isL+size,bucket);

    _=c;
    foreach_reverse(i;1..size) if(isL[i-1] && !isL[i]) nxdata[--_] = i;
    foreach(ref i;nxsa) i = nxdata[i];
    indices[c..size] = 0;
    CreateEndIndices(data,maxVal,bucket);
    foreach_reverse(ref i;nxsa) swap(indices[--bucket[data[i]]],i);
    InduceSort(data,indices,maxVal,isL[0..size],bucket);
    InvertInduceSort(data,indices,maxVal,isL[0..size],bucket);
}

int[] CreateLCP(T)(immutable T[] data,int[] sa){
    int[] lcp = new int[sa.length+1];
    lcp[0] = -1;
    int[] inverIndices = new int[sa.length];
    foreach(i;0..sa.length) inverIndices[sa[i]] = i;
    int lcplen = 0;
    foreach(i;inverIndices){
        if(i>0){
            while(data[sa[i]+lcplen] == data[sa[i-1]+lcplen]){
                ++lcplen;
                if(sa[i]+lcplen>=data.length || sa[i-1]+lcplen>=data.length) break;
            }
            lcp[i] = lcplen;
        }
        lcplen = max(lcplen-1,0);
    }
    return lcp;
}

void main(){
    string input = readln.chomp;
    immutable char[] data = input.toStringz[0..input.length+1];
    int[] sa = SA_IS(data);
    int[] lcp = CreateLCP(data,sa);
    lcp[0..data.length] += 1;
    lcp[data.length] = 0;
    int nc = 0;
    alias Tuple!(int,"lcp",int,"idx") pre;
    pre[] stack = new pre[data.length+1];
    long ans=0;
    foreach(l;0..data.length+1){
        while(nc>1){
            if(stack[nc-1].lcp > lcp[l]){
                if(lcp[l] > stack[nc-2].lcp){
                    ans += cast(long)(l-stack[nc-1].idx)*(l-stack[nc-1].idx+1)/2*(stack[nc-1].lcp-lcp[l]);
                    stack[nc-1].lcp = lcp[l];
                }else{
                    ans += cast(long)(l-stack[nc-1].idx)*(l-stack[nc-1].idx+1)/2*(stack[nc-1].lcp-stack[nc-2].lcp);
                    nc--;
                }
            }else
                break;
        }
        if(nc == 0 || stack[nc-1].lcp < lcp[l])
            stack[nc++] = pre(lcp[l],l);
    }
    ans.writeln;
}

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

int[] SA_IS(T)(immutable T[] data){
	int size = data.length;
	bool[] isL = new bool[size*2];
	int[] indices = new int[size];
	int maxc=0;
	foreach(c;data) maxc = max(maxc,c);
	int[] bucket = new int[1+maxc];
	SA_IS(data,indices,maxc,isL.ptr,bucket);
	return indices;
}

void CreateBeginIndices(T)(immutable T[] data,int maxVal,int[] bucket){
	bucket[0..maxVal] = 0;
	foreach(d;data) bucket[d]++;
	int sum=0;
	foreach(ref b;bucket){ b += sum; swap(b,sum);}
}

void CreateEndIndices(T)(immutable T[] data,int maxVal,int[] bucket){
	bucket[0..maxVal] = 0;
	foreach(d;data) bucket[d]++;
	int sum=0;
	foreach(i,b;bucket){ sum += b; bucket[i] = sum;}
}

void InduceSort(T)(immutable T[] data,int[] indices,int maxVal,bool[] isL,int[] bucket){
	CreateBeginIndices(data,maxVal,bucket);
	foreach(i;indices) if(i>0) if(isL[i-1]) indices[bucket[data[i-1]]++] = i-1;
}

void InvertInduceSort(T)(immutable T[] data,int[] indices,int maxVal,bool[] isL,int[] bucket){
	CreateEndIndices(data,maxVal,bucket);
	foreach_reverse(i;indices) if(i>0) if(!isL[i-1]) indices[--bucket[data[i-1]]] = i-1;
}

void SA_IS(T)(immutable T[] data,int[] indices,int maxVal,bool* isL,ref int[] bucket){
	int size = data.length;
	for(int i=size-2;i>=0;i--) isL[i] = (data[i] > data[i+1] || (data[i] == data[i+1] && isL[i+1]));
	if(bucket.length < maxVal+1) bucket = new int[maxVal+1];
	CreateEndIndices(data,maxVal,bucket);
	foreach(i;1..size) if(isL[i-1] && !isL[i]) indices[--bucket[data[i]]] = i;
	InduceSort(data,indices,maxVal,isL[0..size],bucket);
	InvertInduceSort(data,indices,maxVal,isL[0..size],bucket);

	int c=0;
	foreach(i;indices) if(i>0) if(isL[i-1] && !isL[i]) indices[c++] = i;
	indices[c..size] = -1;

	int idx=-1;
	int prev=-1;
	foreach(i;indices[0..c]){
		bool diff=false;
		foreach(d;0..size){
			if(prev == -1){ diff = true; break;}
			if(data[i+d] != data[prev+d] || isL[i+d] != isL[prev+d]){ diff = true; break;}
			if(d>0 && isL[i+d-1] && !isL[i+d]) break;
		}
		if(diff){ idx++; prev = i;}
		indices[c+i/2] = idx;
	}
	int _=size;
	foreach_reverse(i;indices[c..size]) if(i >= 0) indices[--_] = i;

	int[] nxdata = indices[size-c..size];
	int[] nxsa = indices[0..c];
	nxsa[] = 0;
	if(c == idx+1) foreach(i;0..c) nxsa[nxdata[i]] = i;
	else SA_IS(cast(immutable int[])nxdata,nxsa,idx,isL+size,bucket);

	_=c;
	foreach_reverse(i;1..size) if(isL[i-1] && !isL[i]) nxdata[--_] = i;
	foreach(ref i;nxsa) i = nxdata[i];
	indices[c..size] = 0;
	CreateEndIndices(data,maxVal,bucket);
	foreach_reverse(ref i;nxsa) swap(indices[--bucket[data[i]]],i);
	InduceSort(data,indices,maxVal,isL[0..size],bucket);
	InvertInduceSort(data,indices,maxVal,isL[0..size],bucket);
}

int[] CreateLCP(T)(immutable T[] data,int[] sa){
	int[] lcp = new int[sa.length+1];
	lcp[0] = -1;
	int[] inverIndices = new int[sa.length];
	foreach(i;0..sa.length) inverIndices[sa[i]] = i;
	int lcplen = 0;
	foreach(i;inverIndices){
		if(i>0){
			while(data[sa[i]+lcplen] == data[sa[i-1]+lcplen]){
				++lcplen;
				if(sa[i]+lcplen>=data.length || sa[i-1]+lcplen>=data.length) break;
			}
			lcp[i] = lcplen;
		}
		lcplen = max(lcplen-1,0);
	}
	return lcp;
}

void main(){
	string input = readln.chomp;
	immutable char[] data = input.toStringz[0..input.length+1];
	int[] sa = SA_IS(data);
	int[] lcp = CreateLCP(data,sa);
	lcp[1..data.length] += 1;
	lcp[data.length] = 0;
	int nc = 0;
	int[] stack = new int[data.length+2];
	stack[nc++] = data.length;
	long ans=0;
	foreach(l;1..data.length+1){
		while(nc>1){
			if(lcp[stack[nc-1]] > lcp[l]){
				ans += cast(long)(l-stack[nc-1])*(l-stack[nc-1]+1)/2*(lcp[stack[nc-1]]-lcp[stack[nc-2]]);
				nc--;
			}else
				break;
		}
		if(lcp[stack[nc-1]] < lcp[l])
			stack[nc++] = l;
	}
	ans.writeln;
}


Mahmoud wants to write a new dictionary that contains n words and relations between them. There are two types of relations: synonymy (i. e. the two words mean the same) and antonymy (i. e. the two words mean the opposite). From time to time he discovers a new relation between two words.He know that if two words have a relation between them, then each of them has relations with the words that has relations with the other. For example, if like means love and love is the opposite of hate, then like is also the opposite of hate. One more example: if love is the opposite of hate and hate is the opposite of like, then love means like, and so on.Sometimes Mahmoud discovers a wrong relation. A wrong relation is a relation that makes two words equal and opposite at the same time. For example if he knows that love means like and like is the opposite of hate, and then he figures out that hate means like, the last relation is absolutely wrong because it makes hate and like opposite and have the same meaning at the same time.After Mahmoud figured out many relations, he was worried that some of them were wrong so that they will make other relations also wrong, so he decided to tell every relation he figured out to his coder friend Ehab and for every relation he wanted to know is it correct or wrong, basing on the previously discovered relations. If it is wrong he ignores it, and doesn't check with following relations.After adding all relations, Mahmoud asked Ehab about relations between some words based on the information he had given to him. Ehab is busy making a Codeforces round so he asked you for help.

The first line of input contains three integers n, m and q (2 ≤ n ≤ 105, 1 ≤ m, q ≤ 105) where n is the number of words in the dictionary, m is the number of relations Mahmoud figured out and q is the number of questions Mahmoud asked after telling all relations. The second line contains n distinct words a1, a2, ..., an consisting of small English letters with length not exceeding 20, which are the words in the dictionary. Then m lines follow, each of them contains an integer t (1 ≤ t ≤ 2) followed by two different words xi and yi which has appeared in the dictionary words. If t = 1, that means xi has a synonymy relation with yi, otherwise xi has an antonymy relation with yi. Then q lines follow, each of them contains two different words which has appeared in the dictionary. That are the pairs of words Mahmoud wants to know the relation between basing on the relations he had discovered. All words in input contain only lowercase English letters and their lengths don't exceed 20 characters. In all relations and in all questions the two words are different.

First, print m lines, one per each relation. If some relation is wrong (makes two words opposite and have the same meaning at the same time) you should print "NO" (without quotes) and ignore it, otherwise print "YES" (without quotes). After that print q lines, one per each question. If the two words have the same meaning, output 1. If they are opposites, output 2. If there is no relation between them, output 3. See the samples for better understanding.

3 3 4
hate love like
1 love like
2 love hate
1 hate like
love like
love hate
like hate
hate like

8 6 5
hi welcome hello ihateyou goaway dog cat rat
1 hi welcome
1 ihateyou goaway
2 hello ihateyou
2 hi goaway
2 hi hello
1 hi hello
dog cat
dog hi
hi hello
ihateyou goaway
welcome ihateyou

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

int find(int v, int[] dsu){
    if(dsu[v] == -1) return v;
    return (dsu[v] = find(dsu[v], dsu));
}

void onion(int u, int v, int[] dsu){
    int uid = find(u, dsu);
    int vid = find(v, dsu);
    if(uid != vid){
        dsu[vid] = uid;
    }
}

void play(){
    int n, m, q;
    n = rd!int;
    m = rd!int;
    q = rd!int;
    int[string] cmap;
    foreach(i; 0..n){
        string wd = to!string(rd!(char[]));
        cmap[wd] = i + 1;
    }
    auto dsu = new int[](2*n+5);
    dsu.fill(-1);
    foreach(i; 0..m){
        int typ; string w1, w2;
        readf!(" %d %s %s\n")(typ, w1, w2);
        int num1 = cmap[w1];
        int num2 = cmap[w2];
        if(typ == 1){
            // Sames & Opposites
            if(find(num1, dsu) == find(num2+n, dsu)){
                writeln("NO");
                continue;
            }
            onion(num1, num2, dsu);
            onion(num1+n, num2+n, dsu);
            writeln("YES");
        }else{
            // Crossways
            if(find(num1, dsu) == find(num2, dsu)){
                writeln("NO");
                continue;
            }
            onion(num1, num2+n, dsu);
            onion(num1+n, num2, dsu);
            writeln("YES");
        }
        /* show(dsu); */
    }
    while(q--){
        string w1, w2;
        readf!("%s %s\n")(w1, w2);
        /* show(w1, w2, "x"); */
        /* show(cmap[w1], cmap[w2]); */
        int num1 = cmap[w1];
        int num2 = cmap[w2];
        if(find(num1, dsu) == find(num2, dsu)){
            writeln("1");
        }else if(find(num1, dsu) == find(num2+n, dsu)){
            writeln("2");
        }else{
            writeln("3");
        }
    }
}

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

/**********It's A Me Mario!**********/
import std.stdio, std.conv, std.functional, std.string, std.algorithm;
import std.container, std.range, std.typecons, std.numeric, std.math, std.random;
alias ll = long;
alias rbt = RedBlackTree;
alias sr = SortedRange;
alias tup = Tuple!(long, long);
static string[] inp;
T rd(T = long)(){while(!inp.length) inp = readln.chomp.split; string a = inp[0]; inp.popFront; return a.to!T;}
T[] rdarr(T = long)(T fix = 0){ auto r = readln.chomp.split.to!(T[]); r[] += fix; return r; }
void show(A...)(A a) { debug{ foreach(t; a){ write(t, "| "); } writeln; } }


Smart Beaver became interested in drawing. He draws suns. However, at some point, Smart Beaver realized that simply drawing suns is boring. So he decided to design a program that will process his drawings. You are given a picture drawn by the beaver. It will have two colors: one for the background and one for the suns in the image. Your task will be to count the number of suns in the image and for each of them to count the number of rays.Sun is arbitrarily rotated ellipse with rays. Ray is a segment which connects point on boundary of the ellipse with some point outside ellipse.   An image where all suns are circles.     An image where all suns are ellipses, their axes are parallel to the coordinate axes.     An image where all suns are rotated ellipses.  It is guaranteed that:   No two suns have common points.  The rays’ width is 3 pixels.  The lengths of the ellipsis suns’ axes will lie between 40 and 200 pixels.  No two rays intersect.  The lengths of all rays will lie between 10 and 30 pixels.

The first line contains two integers h and w — the height and width of the image (1 ≤ h, w ≤ 1600). Next h lines will contain w space-separated integers each. They describe Smart Beaver’s picture. Each number equals either a 0 (the image background), or a 1 (the sun color). The input limits for scoring 30 points are (subproblem F1):    All suns on the image are circles.  The input limits for scoring 70 points are (subproblems F1+F2):    All suns on the image are ellipses with axes parallel to the coordinate axes.  The input limits for scoring 100 points are (subproblems F1+F2+F3):   All suns on the image are ellipses, they can be arbitrarily rotated.

The first line must contain a single number k — the number of suns on the beaver’s image. The second line must contain exactly k space-separated integers, corresponding to the number of rays on each sun. The numbers of the second line must be sorted in the increasing order.

NoteFor each complexity level you are suggested a sample in the initial data. You can download the samples at http://www.abbyy.ru/sun.zip.

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 DIRS = 8, LIM = 4;
immutable int DR [DIRS] = [-1, -1, -1,  0, +1, +1, +1,  0];
immutable int DC [DIRS] = [-1,  0, +1, +1, +1,  0, -1, -1];

int neighbors (bool [] [] a, int i, int j)
{
	int res = 0;
	foreach (d; 0..DIRS)
	{
		res += a[i + DR[d]][j + DC[d]];
	}
	return res;
}

int recur_mark (bool [] [] a, bool [] [] b, int i, int j)
{
	if (!a[i][j] || b[i][j])
	{
		return 0;
	}

	b[i][j] = true;
	int res = 0;

	foreach (d; 0..DIRS)
	{
		int p = i + DR[d];
		int q = j + DC[d];
		if (!a[p][q])
		{
			continue;
		}
		int k = neighbors (a, p, q);
		if (k <= LIM)
		{
			foreach (e; 0..DIRS)
			{
				int u = p + DR[e];
				int v = q + DC[e];
				if (!a[u][v])
				{
					continue;
				}
				int s = neighbors (a, u, v);
				if (s <= LIM && recur_ray (a, b, u, v) >= 5)
				{
					res++;
				}
			}
		}
		else
		{
			res += recur_mark (a, b, p, q);
		}
	}
	return res;
}

int recur_ray (bool [] [] a, bool [] [] b, int i, int j)
{
	if (!a[i][j] || b[i][j])
	{
		return 0;
	}

	b[i][j] = true;
	int res = 1;

	foreach (d; 0..DIRS)
	{
		int p = i + DR[d];
		int q = j + DC[d];
		if (!a[p][q] || b[p][q])
		{
			continue;
		}
		int k = neighbors (a, p, q);
		if (k <= LIM)
		{
			res += recur_ray (a, b, p, q);
		}
	}
	return res;
}

void main ()
{
	int n, m;
	while (scanf (" %d %d", &n, &m) > 0)
	{
		auto a = new bool [] [] (n, m);
		foreach (i; 0..n)
		{
			foreach (j; 0..m)
			{
				int v;
				scanf (" %d", &v);
				a[i][j] = (v == 1);
			}
		}

		auto b = new bool [] [] (n, m);
		foreach (i; 1..n - 1)
		{
			foreach (j; 1..m - 1)
			{
				b[i][j] = (neighbors (a, i, j) == DIRS);
			}
		}

		debug
		{
			writefln ("%(%(%5s %)\n%)", b);
		}

		int suns = 0;
		int [] rays;
		auto c = new bool [] [] (n, m);
		foreach (i; 1..n - 1)
		{
			foreach (j; 1..m - 1)
			{
				if (neighbors (b, i, j) == DIRS)
				{
					foreach (d; 0..DIRS)
					{
						int p = i + DR[d];
						int q = j + DC[d];
						if (neighbors (b, p, q) !=
						    DIRS)
						{
//							c[p][q] = true;
						}
					}
				}
			}
		}

		foreach (i; 1..n - 1)
		{
			foreach (j; 1..m - 1)
			{
				if (a[i][j] && !c[i][j] &&
				    neighbors (b, i, j) == DIRS)
				{
					suns++;
					rays ~= recur_mark (b, c, i, j);
				}
			}
		}

		sort (rays);
		writeln (suns);
		writefln ("%(%s %)", rays);
	}
}

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 DIRS = 8, LIM = 4;
immutable int DR [DIRS] = [-1, -1, -1,  0, +1, +1, +1,  0];
immutable int DC [DIRS] = [-1,  0, +1, +1, +1,  0, -1, -1];

int neighbors (bool [] [] a, int i, int j)
{
	int res = 0;
	foreach (d; 0..DIRS)
	{
		res += a[i + DR[d]][j + DC[d]];
	}
	return res;
}

int recur_mark (bool [] [] a, bool [] [] b, int i, int j)
{
	if (!a[i][j] || b[i][j])
	{
		return 0;
	}

	b[i][j] = true;
	int res = 0;

	foreach (d; 0..DIRS)
	{
		int p = i + DR[d];
		int q = j + DC[d];
		if (!a[p][q])
		{
			continue;
		}
		int k = neighbors (a, p, q);
		if (k >= LIM)
		{
			res += recur_mark (a, b, p, q);
		}
		else
		{
			foreach (e; 0..DIRS)
			{
				int u = p + DR[e];
				int v = q + DC[e];
				if (!a[u][v])
				{
					continue;
				}
				int s = neighbors (a, u, v);
				if (s <= LIM && recur_ray (a, b, u, v) >= 1)
				{
					res++;
				}
			}
		}
	}
	return res;
}

int recur_ray (bool [] [] a, bool [] [] b, int i, int j)
{
	if (!a[i][j] || b[i][j])
	{
		return 0;
	}

	b[i][j] = true;
	int res = 1;

	foreach (d; 0..DIRS)
	{
		int p = i + DR[d];
		int q = j + DC[d];
		if (!a[p][q])
		{
			continue;
		}
		int k = neighbors (a, p, q);
		if (k <= LIM)
		{
			res += recur_ray (a, b, p, q);
		}
	}
	return res;
}

void main ()
{
	int n, m;
	while (scanf (" %d %d", &n, &m) > 0)
	{
		auto a = new bool [] [] (n, m);
		foreach (i; 0..n)
		{
			foreach (j; 0..m)
			{
				int v;
				scanf (" %d", &v);
				a[i][j] = (v == 1);
			}
		}

		auto b = new bool [] [] (n, m);
		foreach (i; 1..n - 1)
		{
			foreach (j; 1..m - 1)
			{
				b[i][j] = (neighbors (a, i, j) == DIRS);
			}
		}

		debug
		{
			writefln ("%(%(%5s %)\n%)", b);
		}

		int suns = 0;
		int [] rays;
		auto c = new bool [] [] (n, m);
		foreach (i; 1..n - 1)
		{
			foreach (j; 1..m - 1)
			{
				if (neighbors (b, i, j) == DIRS)
				{
					foreach (d; 0..DIRS)
					{
						int p = i + DR[d];
						int q = j + DC[d];
						if (neighbors (b, p, q) !=
						    DIRS)
						{
//							c[p][q] = true;
						}
					}
				}
			}
		}

		foreach (i; 1..n - 1)
		{
			foreach (j; 1..m - 1)
			{
				if (a[i][j] && !c[i][j] &&
				    neighbors (b, i, j) == DIRS)
				{
					suns++;
					rays ~= recur_mark (b, c, i, j);
				}
			}
		}

		sort (rays);
		writeln (suns);
		writefln ("%(%s %)", rays);
	}
}

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 DIRS = 8, LIM = 4;
immutable int DR [DIRS] = [-1, -1, -1,  0, +1, +1, +1,  0];
immutable int DC [DIRS] = [-1,  0, +1, +1, +1,  0, -1, -1];

int neighbors (bool [] [] a, int i, int j)
{
	int res = 0;
	foreach (d; 0..DIRS)
	{
		res += a[i + DR[d]][j + DC[d]];
	}
	return res;
}

int recur_mark (bool [] [] a, bool [] [] b, int i, int j)
{
	if (!a[i][j] || b[i][j])
	{
		return 0;
	}

	b[i][j] = true;
	int res = 0;

	foreach (d; 0..DIRS)
	{
		int p = i + DR[d];
		int q = j + DC[d];
		if (!a[p][q])
		{
			continue;
		}
		int k = neighbors (a, p, q);
		if (k >= LIM)
		{
			res += recur_mark (a, b, p, q);
		}
		else
		{
			foreach (e; 0..DIRS)
			{
				int u = p + DR[e];
				int v = q + DC[e];
				if (!a[u][v])
				{
					continue;
				}
				int s = neighbors (a, u, v);
				if (s <= LIM && recur_ray (a, b, u, v) >= 5)
				{
					res++;
				}
			}
		}
	}
	return res;
}

int recur_ray (bool [] [] a, bool [] [] b, int i, int j)
{
	if (!a[i][j] || b[i][j])
	{
		return 0;
	}

	b[i][j] = true;
	int res = 1;

	foreach (d; 0..DIRS)
	{
		int p = i + DR[d];
		int q = j + DC[d];
		if (!a[p][q])
		{
			continue;
		}
		int k = neighbors (a, p, q);
		if (k <= LIM)
		{
			res += recur_ray (a, b, p, q);
		}
	}
	return res;
}

void main ()
{
	int n, m;
	while (scanf (" %d %d", &n, &m) > 0)
	{
		auto a = new bool [] [] (n, m);
		foreach (i; 0..n)
		{
			foreach (j; 0..m)
			{
				int v;
				scanf (" %d", &v);
				a[i][j] = (v == 1);
			}
		}

		auto b = new bool [] [] (n, m);
		foreach (i; 1..n - 1)
		{
			foreach (j; 1..m - 1)
			{
				b[i][j] = (neighbors (a, i, j) == DIRS);
			}
		}

		int suns = 0;
		int [] rays;
		auto c = new bool [] [] (n, m);
		foreach (i; 1..n - 1)
		{
			foreach (j; 1..m - 1)
			{
				if (a[i][j] && !c[i][j] &&
				    neighbors (b, i, j) == DIRS)
				{
					suns++;
					rays ~= recur_mark (b, c, i, j);
				}
			}
		}

		sort (rays);
		writeln (suns);
		writefln ("%(%s %)", rays);
	}
}

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 DIRS = 8, LIM = 4;
immutable int DR [DIRS] = [-1, -1, -1,  0, +1, +1, +1,  0];
immutable int DC [DIRS] = [-1,  0, +1, +1, +1,  0, -1, -1];

int neighbors (bool [] [] a, int i, int j)
{
	int res = 0;
	foreach (d; 0..DIRS)
	{
		res += a[i + DR[d]][j + DC[d]];
	}
	return res;
}

int recur_mark (bool [] [] a, bool [] [] b, int i, int j)
{
	if (!a[i][j] || b[i][j])
	{
		return 0;
	}

	b[i][j] = true;
	int res = 0;

	foreach (d; 0..DIRS)
	{
		int p = i + DR[d];
		int q = j + DC[d];
		if (!a[p][q])
		{
			continue;
		}
		int k = neighbors (a, p, q);
		if (k >= LIM)
		{
			res += recur_mark (a, b, p, q);
		}
		else
		{
			foreach (e; 0..DIRS)
			{
				int u = p + DR[e];
				int v = q + DC[e];
				if (!a[u][v])
				{
					continue;
				}
				int s = neighbors (a, u, v);
				if (s <= LIM && recur_ray (a, b, u, v) >= 9)
				{
					res++;
				}
			}
		}
	}
	return res;
}

int recur_ray (bool [] [] a, bool [] [] b, int i, int j)
{
	if (!a[i][j] || b[i][j])
	{
		return 0;
	}

	b[i][j] = true;
	int res = 1;

	foreach (d; 0..DIRS)
	{
		int p = i + DR[d];
		int q = j + DC[d];
		if (!a[p][q])
		{
			continue;
		}
		int k = neighbors (a, p, q);
		if (k <= LIM)
		{
			res += recur_ray (a, b, p, q);
		}
	}
	return res;
}

void main ()
{
	int n, m;
	while (scanf (" %d %d", &n, &m) > 0)
	{
		auto a = new bool [] [] (n, m);
		foreach (i; 0..n)
		{
			foreach (j; 0..m)
			{
				int v;
				scanf (" %d", &v);
				a[i][j] = (v == 1);
			}
		}

		auto b = new bool [] [] (n, m);
		foreach (i; 1..n - 1)
		{
			foreach (j; 1..m - 1)
			{
				b[i][j] = (neighbors (a, i, j) == DIRS);
			}
		}

		debug
		{
			writefln ("%(%(%5s %)\n%)", b);
		}

		int suns = 0;
		int [] rays;
		auto c = new bool [] [] (n, m);
		foreach (i; 1..n - 1)
		{
			foreach (j; 1..m - 1)
			{
				if (neighbors (b, i, j) == DIRS)
				{
					foreach (d; 0..DIRS)
					{
						int p = i + DR[d];
						int q = j + DC[d];
						if (neighbors (b, p, q) !=
						    DIRS)
						{
//							c[p][q] = true;
						}
					}
				}
			}
		}

		foreach (i; 1..n - 1)
		{
			foreach (j; 1..m - 1)
			{
				if (a[i][j] && !c[i][j] &&
				    neighbors (b, i, j) == DIRS)
				{
					suns++;
					rays ~= recur_mark (b, c, i, j);
				}
			}
		}

		sort (rays);
		writeln (suns);
		writefln ("%(%s %)", rays);
	}
}