You are playing a computer game, where you lead a party of $$$m$$$ soldiers. Each soldier is characterised by his agility $$$a_i$$$.The level you are trying to get through can be represented as a straight line segment from point $$$0$$$ (where you and your squad is initially located) to point $$$n + 1$$$ (where the boss is located).The level is filled with $$$k$$$ traps. Each trap is represented by three numbers $$$l_i$$$, $$$r_i$$$ and $$$d_i$$$. $$$l_i$$$ is the location of the trap, and $$$d_i$$$ is the danger level of the trap: whenever a soldier with agility lower than $$$d_i$$$ steps on a trap (that is, moves to the point $$$l_i$$$), he gets instantly killed. Fortunately, you can disarm traps: if you move to the point $$$r_i$$$, you disarm this trap, and it no longer poses any danger to your soldiers. Traps don't affect you, only your soldiers.You have $$$t$$$ seconds to complete the level — that is, to bring some soldiers from your squad to the boss. Before the level starts, you choose which soldiers will be coming with you, and which soldiers won't be. After that, you have to bring all of the chosen soldiers to the boss. To do so, you may perform the following actions:  if your location is $$$x$$$, you may move to $$$x + 1$$$ or $$$x - 1$$$. This action consumes one second;  if your location is $$$x$$$ and the location of your squad is $$$x$$$, you may move to $$$x + 1$$$ or to $$$x - 1$$$ with your squad in one second. You may not perform this action if it puts some soldier in danger (i. e. the point your squad is moving into contains a non-disarmed trap with $$$d_i$$$ greater than agility of some soldier from the squad). This action consumes one second;  if your location is $$$x$$$ and there is a trap $$$i$$$ with $$$r_i = x$$$, you may disarm this trap. This action is done instantly (it consumes no time). Note that after each action both your coordinate and the coordinate of your squad should be integers.You have to choose the maximum number of soldiers such that they all can be brought from the point $$$0$$$ to the point $$$n + 1$$$ (where the boss waits) in no more than $$$t$$$ seconds.

The first line contains four integers $$$m$$$, $$$n$$$, $$$k$$$ and $$$t$$$ ($$$1 \le m, n, k, t \le 2 \cdot 10^5$$$, $$$n < t$$$) — the number of soldiers, the number of integer points between the squad and the boss, the number of traps and the maximum number of seconds you may spend to bring the squad to the boss, respectively. The second line contains $$$m$$$ integers $$$a_1$$$, $$$a_2$$$, ..., $$$a_m$$$ ($$$1 \le a_i \le 2 \cdot 10^5$$$), where $$$a_i$$$ is the agility of the $$$i$$$-th soldier. Then $$$k$$$ lines follow, containing the descriptions of traps. Each line contains three numbers $$$l_i$$$, $$$r_i$$$ and $$$d_i$$$ ($$$1 \le l_i \le r_i \le n$$$, $$$1 \le d_i \le 2 \cdot 10^5$$$) — the location of the trap, the location where the trap can be disarmed, and its danger level, respectively.

Print one integer — the maximum number of soldiers you may choose so that you may bring them all to the boss in no more than $$$t$$$ seconds.

NoteIn the first example you may take soldiers with agility $$$3$$$, $$$4$$$ and $$$5$$$ with you. The course of action is as follows:  go to $$$2$$$ without your squad;  disarm the trap $$$2$$$;  go to $$$3$$$ without your squad;  disartm the trap $$$3$$$;  go to $$$0$$$ without your squad;  go to $$$7$$$ with your squad. The whole plan can be executed in $$$13$$$ seconds.

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

void read(T...)(ref T args)
{
  import std.traits;
  static foreach(i; 0 .. T.length)
    static if(isArray!(T[i]))
      foreach(ref e; args[i])
    	read(e);
    else
      readf!" %s"(args[i]);
}
alias r = read;
alias w = writeln;
int main()
{
  int m, n, k, t;
  r(m, n, k, t);
  int[] a;
  a.length = m;
  r(a);
  alias Trap = Tuple!(int, "right", int, "danger");
  Trap[][] pos;
  pos.length = n + 2;
  foreach(i; 0 .. k)
    {
      int l, right, danger;
      r(l, right, danger);
      pos[l] ~= Trap(right, danger);
    }
  bool can(int ag)
  {
    if (ag <= 0) return true;
    int ct = 0;
    for(int i = 0; i < n + 1;)
      {
	int j, objective = i + 1;
	bool deact = false;
	for(j = i + 1; j <= objective; j++)
	    foreach(cell; pos[j])
	      if(cell.danger > ag)
		objective = max(objective, cell.right), deact = true;
	ct += (objective - i) * (1 + 2 * deact);
	if (ct > t) return false;
	i = objective;
      }
    return true;
  }
  auto ag = iota(1, 200000 + 1).assumeSorted!((a, b) => !can(a) && can(b)).equalRange(0)[0];
  auto sortedA = sort!"a < b"(a);
  w(sortedA.upperBound(ag).length + sortedA.equalRange(ag).length);
  return 0;
}

import std.stdio;

void read(T...)(ref T args)
{
  import std.traits;
  static foreach(i; 0 .. T.length)
    static if(isArray!(T[i]))
      foreach(ref e; args[i])
    	read(e);
    else
      readf!" %s"(args[i]);
}
alias r = read;
alias w = writeln;

struct Cell
{
  int right, danger;
  this(bool active, int right, int danger)
  {
    this.right = right;
    this.danger = danger;
  }
}

int main()
{
  import std.container.rbtree;
  import std.algorithm;
  int m, n, k, t;
  r(m, n, k, t);
  int[] a;
  a.length = m;
  Cell[][] pos;
  int[][] deact;
  pos.length = n + 2;
  deact.length = n + 2;
  r(a);
  foreach(i; 0 .. k)
    {
      int l, right, danger;
      r(l, right, danger);
      pos[l] ~= Cell(true, right, danger);
      deact[right] ~= l;
    }
  bool can(int ag)
  {
    int pa = 0;
    int pm = 0;
    int ct = 0;
    bool[] active;
    active.length = n + 2;
    active[] = true;
    while(pa != n + 1)
      {
    	int obj = 0;
    	while(true)
    	  {
    	    bool mustbreak = false;
    	    foreach(cell; pos[pm + 1])
    	      {
    		if (active[pm + 1] && cell.danger > ag)
    		  {
    		    mustbreak = true;
    		    obj = max(obj, cell.right);
    		  }
    	      }
    	    if (mustbreak)
    	      break;
    	    pm++;
    	    pa++;
    	    ct++;
    	    if (ct > t)
    	      return false;
    	    if (pa == n + 1)
    	      {
    		return true;
    	      }
    	  }

    	for(; pm <= obj;)
    	  {
    	    foreach(d; deact[pm])
    	      {
    		active[d] = false;
    	      }
    	    foreach(cell; pos[pm])
    	      {
    		if (active[pm] && cell.danger > ag)
    		  obj = max(obj, cell.right);
    	      }
    	    if (pm == obj)
    	      {
    		break;
    	      }
    	    pm++;
    	    ct++;
    	    if (ct > t)
    	      return false;
    	  }
    	assert(pm == obj);
    	ct += (pm - pa) * 2;
    	pa = obj;
    	if (ct > t)
    	  return false;
      }
    assert(0);
  }
  import std.range;
  auto ag = iota(1, 200000 + 1).map!((a=>cast(int)can(a))).assumeSorted.equalRange(0).length + 1;
  auto sortedA = sort!"a < b"(a);
  w(sortedA.upperBound(ag).length + sortedA.equalRange(ag).length);

  return 0;
}

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

void read(T...)(ref T args)
{
  import std.traits;
  static foreach(i; 0 .. T.length)
    static if(isArray!(T[i]))
      foreach(ref e; args[i])
    	read(e);
    else
      readf!" %s"(args[i]);
}
alias r = read;
alias w = writeln;

struct Cell
{
  int right, danger;
  this(int right, int danger)
  {
    this.right = right;
    this.danger = danger;
  }
}
int main()
{
  int m, n, k, t;
  r(m, n, k, t);
  int[] a;
  a.length = m;
  r(a);
  Cell[][] pos;
  pos.length = n + 2;
  foreach(i; 0 .. k)
    {
      int l, right, danger;
      r(l, right, danger);
      pos[l] ~= Cell(right, danger);
    }
  bool can(int ag)
  {
    if (ag <= 0) return true;
    int ct = 0;
    for(int i = 0; i < n + 1;)
      {
	int j, objective = i + 1;
	bool deact = false;
	for(j = i + 1; j <= objective; j++)
	    foreach(cell; pos[j])
	      if(cell.danger > ag)
		objective = max(objective, cell.right), deact = true;
	ct += (objective - i) * (1 + 2 * deact);
	if (ct > t) return false;
	i = objective;
      }
    return true;
  }
  auto ag = iota(1, 200000 + 1).assumeSorted!((a, b) => !can(a) && can(b)).equalRange(0)[0];
  auto sortedA = sort!"a < b"(a);
  w(sortedA.upperBound(ag).length + sortedA.equalRange(ag).length);
  return 0;
}

import std.stdio;

void read(T...)(ref T args)
{
  import std.traits;
  static foreach(i; 0 .. T.length)
    static if(isArray!(T[i]))
      foreach(ref e; args[i])
    	read(e);
    else
      readf!" %s"(args[i]);
}
alias r = read;
alias w = writeln;

struct Cell
{
  int right, danger;
  this(bool active, int right, int danger)
  {
    this.right = right;
    this.danger = danger;
  }
}

int main()
{
  import std.container.rbtree;
  import std.algorithm;
  int m, n, k, t;
  r(m, n, k, t);
  int[] a;
  a.length = m;
  Cell[][] pos;
  int[][] deact;
  pos.length = n + 2;
  deact.length = n + 2;
  r(a);
  foreach(i; 0 .. k)
    {
      int l, right, danger;
      r(l, right, danger);
      pos[l] ~= Cell(true, right, danger);
      deact[right] ~= l;
    }
  bool can(int ag)
  {
    if (ag <= 0)
      return true;
    int pa = 0;
    int pm = 0;
    int ct = 0;
    bool[] active;
    active.length = n + 2;
    active[] = true;
    while(pa != n + 1)
      {
    	int obj = 0;
    	while(true)
    	  {
    	    bool mustbreak = false;
    	    foreach(cell; pos[pm + 1])
    	      {
    		if (active[pm + 1] && cell.danger > ag)
    		  {
    		    mustbreak = true;
    		    obj = max(obj, cell.right);
    		  }
    	      }
    	    if (mustbreak)
    	      break;
    	    pm++;
    	    pa++;
    	    ct++;
    	    if (ct > t)
    	      return false;
    	    if (pa == n + 1)
    	      {
    		return true;
    	      }
    	  }

    	for(; pm <= obj;)
    	  {
    	    foreach(d; deact[pm])
    	      {
    		active[d] = false;
    	      }
    	    foreach(cell; pos[pm])
    	      {
    		if (active[pm] && cell.danger > ag)
    		  obj = max(obj, cell.right);
    	      }
    	    if (pm == obj)
    	      {
    		break;
    	      }
    	    pm++;
    	    ct++;
    	    if (ct > t)
    	      return false;
    	  }
    	assert(pm == obj);
    	ct += (pm - pa) * 2;
    	pa = obj;
    	if (ct > t)
    	  return false;
      }
    assert(0);
  }
  import std.range;
  auto ag = iota(1, 200000 + 1).assumeSorted!((a, b) => !can(a) && can(b)).equalRange(0)[0];
  auto sortedA = sort!"a < b"(a);
  w(sortedA.upperBound(ag).length + sortedA.equalRange(ag).length);

  return 0;
}

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

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

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

    auto ds = new int[] (k);
    alias trap = Tuple!(int, bool);
    auto open = new int[][] (n+1);
    auto close = new int[][] (n+1);

    foreach (i; 0 .. k) {
        int le, r, d;
        readf("%s %s %s", &le, &r, &d);
        readln;

        ds[i] = d;
        open[le] ~= i;
        close[r] ~= i;
    }

    arr.sort();
    arr.reverse();

    bool isOk(int toBring) {

        int tot = 0;
        int threshold = arr[toBring-1];

        debug { writeln(toBring, ' ', threshold); }

        bool alone = false;
        int soldiersPos = 0;
        int trapsCnt = 0;
        foreach (i; 1 .. n+1) {
            foreach (idx; open[i]) {
                if (ds[idx] <= threshold) { continue; }

                trapsCnt += 1;
                alone = true;
            }

            foreach (idx; close[i]) {
                if (ds[idx] <= threshold) { continue; }

                trapsCnt -= 1;
            }

            if (trapsCnt == 0) {
                if (alone) { tot += 2 * (i - soldiersPos); }
                tot += i - soldiersPos;
                soldiersPos = i;
                alone = false;
            }

            debug { writeln(i, ' ', soldiersPos, ' ', tot); }
        }

        tot += 1;
        return tot <= t;
    }

    int le = 0, r = m;
    while (le < r) {
        int c = (le + r) / 2 + 1;

        if (isOk(c)) { le = c; }
        else { r = c-1; }
    }

    le.writeln;
}

import std.stdio, std.conv, std.string, std.array, std.range, std.algorithm, std.container;
import std.math, std.random, std.bigint, std.datetime, std.format;
void main(string[] args){ if(args.length > 1) if(args[1] == "-debug") DEBUG = 1; solve(); }
void log()(){ writeln(""); } void log(T, A ...)(T t, lazy A a){ if(DEBUG) write(t, " "), log(a); } bool DEBUG = 0;
string rstring(){ static string[] ss; while(!ss.length) ss = readln.chomp.split; string res = ss[0]; ss.popFront; return res; }
T rtype(T)(){ return rstring.to!T; } alias rint = rtype!int, rlong = rtype!long, rreal = rtype!real;
T[] rtypes(T)(int n){ return n.iota.map!(i => rtype!T()).array; } alias rint = rtypes!int, rlong = rtypes!long, rreal = rtypes!real;
T[][] rtypess(T)(int n, int m){ return n.iota.map!(i => rtypes!T(m)).array; } alias rint = rtypess!int, rlong = rtypess!long, rreal = rtypess!real;
T chmin(T)(ref T x, T y){ if(x > y) x = y; return x; } T chmax(T)(ref T x, T y){ if(x < y) x = y; return x; }

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

void solve(){
	int m = rint, n = rint, k = rint, t = rint;
	long[] as = rlong(m);
	as.sort!"a>b"();

	X[] traps;
	foreach(i; 0 .. k) traps ~= X(rint, rint, rlong);

	bool isOK(int x){
		long a = (x > 0? as[x - 1]: 200_999);
		int[] ls, rs;
		foreach(tr; traps) if(tr.d > a) ls ~= tr.l, rs ~= tr.r;
		ls.sort(), rs.sort();
		auto lq = new Queue!int(ls), rq = new Queue!int(rs);
		int leftpos = 0;
		int time = (n + 1);
		int cnt = 0;
		log("x:", x, "a:", a, "ls:", ls, "rs:", rs, "lq:", lq, "rq:", rq, "leftpos:", leftpos, "cnt:", cnt, "time:", time);
		while(lq.length + rq.length > 0){
			if(lq.length > 0 && lq.peek <= rq.peek){
				if(cnt == 0) leftpos = lq.peek - 1;
				lq.deq, cnt += 1;
			}
			else{
				if(cnt == 1) time += (rq.peek - leftpos) * 2;
				rq.deq, cnt -= 1;
			}
			log("lq:", lq, "rq:", rq, "leftpos:", leftpos, "cnt:", cnt, "time:", time);
		}
//		log("x:", x, "a:", a, "leftend:", leftend, "rightend:", rightend, "time:", time, "isOK:", time <= t);
		return time <= t;

	}

	int ans = uplimit(0, m, &isOK);
	ans.writeln;
}
struct X{
	int l, r;
	long d;
}
// 二分探索テンプレート
T uplimit(T)(T a, T c, bool delegate(T) f){
	if(f(c)) return c; if(! f(a)) return a - 1;
	while(a + 1 < c){ T b = (a + c) / 2; if(f(b)) a = b; else c = b; }
	return a;
}
T downlimit(T)(T a, T c, bool delegate(T) f){
	if(f(a)) return a; if(! f(c)) return c + 1;
	while(a + 1 < c){ T b = (a + c) / 2; if(f(b)) c = b; else a = b; }
	return c;
}
// ----- キュー -----
class Queue(T){
	private T[] xs;
	private uint i, j; // i : 次に読み出す位置　j: 次に書き込む位置
	this(){	}
	this(T[] xs){ this.xs = xs; j = xs.length; }
	void enq(T x){
		while(j + 1 >= xs.length) xs.length = xs.length * 2 + 1;
		xs[j ++] = x;
	}
	ulong length(){ return j - i; }
	bool isEmpty(){ return j == i; }
	T deq(){ assert(i < j); return xs[i ++]; }
	T peek(){ assert(i < j); return xs[i]; }
	T[] array(){ return xs[i .. j]; }
	override string toString(){ return array.to!string; }
}
/*
5 6 4 14
1 2 3 4 5
1 5 2
1 2 5
3 4 5
3 5 3
*/

import std.stdio;

void read(T...)(ref T args)
{
  import std.traits;
  static foreach(i; 0 .. T.length)
    static if(isArray!(T[i]))
      foreach(ref e; args[i])
    	read(e);
    else
      readf!" %s"(args[i]);
}
alias r = read;
alias w = writeln;

struct Cell
{
  int right, danger;
  this(bool active, int right, int danger)
  {
    this.right = right;
    this.danger = danger;
  }
}

int main()
{
  import std.container.rbtree;
  import std.algorithm;
  int m, n, k, t;
  r(m, n, k, t);
  int[] a;
  a.length = m;
  Cell[][] pos;
  int[][] deact;
  pos.length = n + 2;
  deact.length = n + 2;
  r(a);
  foreach(i; 0 .. k)
    {
      int l, right, danger;
      r(l, right, danger);
      pos[l] ~= Cell(true, right, danger);
      deact[right] ~= l;
    }
  bool can(int ag)
  {
    int pa = 0;
    int pm = 0;
    int ct = 0;
    bool[] active;
    active.length = n + 2;
    active[] = true;
    while(pa != n + 1)
      {
    	int obj = 0;
    	while(true)
    	  {
    	    bool mustbreak = false;
    	    foreach(cell; pos[pm + 1])
    	      {
    		if (active[pm + 1] && cell.danger > ag)
    		  {
    		    mustbreak = true;
    		    obj = max(obj, cell.right);
    		  }
    	      }
    	    if (mustbreak)
    	      break;
    	    pm++;
    	    pa++;
    	    ct++;
    	    if (ct > t)
    	      return false;
    	    if (pa == n + 1)
    	      {
    		return true;
    	      }
    	  }

    	for(; pm <= obj;)
    	  {
    	    foreach(d; deact[pm])
    	      {
    		active[d] = false;
    	      }
    	    foreach(cell; pos[pm])
    	      {
    		if (active[pm] && cell.danger > ag)
    		  obj = max(obj, cell.right);
    	      }
    	    if (pm == obj)
    	      {
    		break;
    	      }
    	    pm++;
    	    ct++;
    	    if (ct > t)
    	      return false;
    	  }
    	assert(pm == obj);
    	ct += (pm - pa) * 2;
    	pa = obj;
    	if (ct > t)
    	  return false;
      }
    assert(0);
  }
  import std.range;
  auto ag = iota(1, 200000 + 1).assumeSorted!((a, b)=> cast(int)can(a) < cast(int)can(b)).upperBound(false)[0];
  auto sortedA = sort!"a < b"(a);
  w(sortedA.upperBound(ag).length + sortedA.equalRange(ag).length);

  return 0;
}

import std.stdio;

void read(T...)(ref T args)
{
  import std.traits;
  static foreach(i; 0 .. T.length)
    static if(isArray!(T[i]))
      foreach(ref e; args[i])
    	read(e);
    else
      readf!" %s"(args[i]);
}
alias r = read;
alias w = writeln;

struct Cell
{
  int right, danger;
  this(bool active, int right, int danger)
  {
    this.right = right;
    this.danger = danger;
  }
}

int main()
{
  import std.container.rbtree;
  import std.algorithm;
  int m, n, k, t;
  r(m, n, k, t);
  int[] a;
  a.length = m;
  Cell[][] pos;
  int[][] deact;
  pos.length = n + 2;
  deact.length = n + 2;
  r(a);
  foreach(i; 0 .. k)
    {
      int l, right, danger;
      r(l, right, danger);
      pos[l] ~= Cell(true, right, danger);
      deact[right] ~= l;
    }
  bool can(int ag)
  {
    int pa = 0;
    int pm = 0;
    int ct = 0;
    bool[] active;
    active.length = n + 2;
    active[] = true;
    while(pa != n + 1)
      {
    	int obj = 0;
    	while(true)
    	  {
    	    bool mustbreak = false;
    	    foreach(cell; pos[pm + 1])
    	      {
    		if (active[pm + 1] && cell.danger > ag)
    		  {
    		    mustbreak = true;
    		    obj = max(obj, cell.right);
    		  }
    	      }
    	    if (mustbreak)
    	      break;
    	    pm++;
    	    pa++;
    	    ct++;
    	    if (ct > t)
    	      return false;
    	    if (pa == n + 1)
    	      {
    		return true;
    	      }
    	  }

    	for(; pm <= obj;)
    	  {
    	    foreach(d; deact[pm])
    	      {
    		active[d] = false;
    	      }
    	    foreach(cell; pos[pm])
    	      {
    		if (active[pm] && cell.danger > ag)
    		  obj = max(obj, cell.right);
    	      }
    	    if (pm == obj)
    	      {
    		break;
    	      }
    	    pm++;
    	    ct++;
    	    if (ct > t)
    	      return false;
    	  }
    	assert(pm == obj);
    	ct += (pm - pa) * 2;
    	pa = obj;
    	if (ct > t)
    	  return false;
      }
    assert(0);
  }
  import std.range;
  auto ag = iota(1, 10 + 1).assumeSorted!((a, b)=> cast(int)can(a) < cast(int)can(b)).upperBound(true)[0];
  auto sortedA = sort!"a < b"(a);
  w(sortedA.upperBound(ag).length + sortedA.equalRange(ag).length);

  return 0;
}

import std.stdio;

void read(T...)(ref T args)
{
  import std.traits;
  static foreach(i; 0 .. T.length)
    static if(isArray!(T[i]))
      foreach(ref e; args[i])
    	read(e);
    else
      readf!" %s"(args[i]);
}
alias r = read;
alias w = writeln;

struct Cell
{
  int right, danger;
  this(bool active, int right, int danger)
  {
    this.right = right;
    this.danger = danger;
  }
}

int main()
{
  import std.container.rbtree;
  import std.algorithm;
  int m, n, k, t;
  r(m, n, k, t);
  int[] a;
  a.length = m;
  Cell[][] pos;
  int[][] deact;
  pos.length = n + 2;
  deact.length = n + 2;
  r(a);
  foreach(i; 0 .. k)
    {
      int l, right, danger;
      r(l, right, danger);
      pos[l] ~= Cell(true, right, danger);
      deact[right] ~= l;
    }
  bool can(int ag)
  {
    int pa = 0;
    int pm = 0;
    int ct = 0;
    bool[] active;
    active.length = n + 2;
    active[] = true;
    while(pa != n + 1)
      {
    	int obj = 0;
    	while(true)
    	  {
    	    bool mustbreak = false;
    	    foreach(cell; pos[pm + 1])
    	      {
    		if (active[pm + 1] && cell.danger > ag)
    		  {
    		    mustbreak = true;
    		    obj = max(obj, cell.right);
    		  }
    	      }
    	    if (mustbreak)
    	      break;
    	    pm++;
    	    pa++;
    	    ct++;
    	    if (ct > t)
    	      return false;
    	    if (pa == n + 1)
    	      {
    		return true;
    	      }
    	  }

    	for(; pm <= obj;)
    	  {
    	    foreach(d; deact[pm])
    	      {
    		active[d] = false;
    	      }
    	    foreach(cell; pos[pm])
    	      {
    		if (active[pm] && cell.danger > ag)
    		  obj = max(obj, cell.right);
    	      }
    	    if (pm == obj)
    	      {
    		break;
    	      }
    	    pm++;
    	    ct++;
    	    if (ct > t)
    	      return false;
    	  }
    	assert(pm == obj);
    	ct += (pm - pa) * 2;
    	pa = obj;
    	if (ct > t)
    	  return false;
      }
    assert(0);
  }
  import std.range;
  auto ag = iota(1, 200000 + 1).assumeSorted!((a, b)=> cast(int)can(a) < cast(int)can(b)).upperBound(true)[0];
  auto sortedA = sort!"a < b"(a);
  w(sortedA.upperBound(ag).length + sortedA.equalRange(ag).length);

  return 0;
}

import std.stdio;

void read(T...)(ref T args)
{
  import std.traits;
  static foreach(i; 0 .. T.length)
    static if(isArray!(T[i]))
      foreach(ref e; args[i])
    	read(e);
    else
      readf!" %s"(args[i]);
}
alias r = read;
alias w = writeln;

struct Cell
{
  int right, danger;
  this(bool active, int right, int danger)
  {
    this.right = right;
    this.danger = danger;
  }
}

int main()
{
  import std.container.rbtree;
  import std.algorithm;
  int m, n, k, t;
  r(m, n, k, t);
  int[] a;
  a.length = m;
  Cell[][] pos;
  int[][] deact;
  pos.length = n + 2;
  deact.length = n + 2;
  r(a);
  foreach(i; 0 .. k)
    {
      int l, right, danger;
      r(l, right, danger);
      pos[l] ~= Cell(true, right, danger);
      deact[right] ~= l;
    }
  bool can(int ag)
  {
    int pa = 0;
    int pm = 0;
    int ct = 0;
    bool[] active;
    active.length = n + 2;
    active[] = true;
    while(pa != n + 1)
      {
    	int obj = 0;
    	while(true)
    	  {
    	    bool mustbreak = false;
    	    foreach(cell; pos[pm + 1])
    	      {
    		if (active[pm + 1] && cell.danger > ag)
    		  {
    		    mustbreak = true;
    		    obj = max(obj, cell.right);
    		  }
    	      }
    	    if (mustbreak)
    	      break;
    	    pm++;
    	    pa++;
    	    ct++;
    	    if (ct > t)
    	      return false;
    	    if (pa == n + 1)
    	      {
    		return true;
    	      }
    	  }

    	for(; pm <= obj;)
    	  {
    	    foreach(d; deact[pm])
    	      {
    		active[d] = false;
    	      }
    	    foreach(cell; pos[pm])
    	      {
    		if (active[pm] && cell.danger > ag)
    		  obj = max(obj, cell.right);
    	      }
    	    if (pm == obj)
    	      {
    		break;
    	      }
    	    pm++;
    	    ct++;
    	    if (ct > t)
    	      return false;
    	  }
    	assert(pm == obj);
    	ct += (pm - pa) * 2;
    	pa = obj;
    	if (ct > t)
    	  return false;
      }
    assert(0);
  }
  import std.range;
  auto ag = iota(1, 200000 + 1).assumeSorted!((a, b) => !can(a) && can(b)).equalRange(false).length + 1;
  auto sortedA = sort!"a < b"(a);
  w(sortedA.upperBound(ag).length + sortedA.equalRange(ag).length);

  return 0;
}

import std.stdio;

void read(T...)(ref T args)
{
  import std.traits;
  static foreach(i; 0 .. T.length)
    static if(isArray!(T[i]))
      foreach(ref e; args[i])
	read(e);
    else
      readf!" %s"(args[i]);
}
alias r = read;
alias w = writeln;

struct Cell
{
  int right, danger;
  this(bool active, int right, int danger)
  {
    this.right = right;
    this.danger = danger;
  }
}

int main()
{
  import std.container.rbtree;
  import std.algorithm;
  int m, n, k, t;
  r(m, n, k, t);
  int[] a;
  a.length = m;
  Cell[][] pos;
  int[][] deact;
  pos.length = n + 2;
  deact.length = n + 2;
  r(a);
  foreach(i; 0 .. k)
    {
      int l, right, danger;
      r(l, right, danger);
      pos[l] ~= Cell(true, right, danger);
      deact[right] ~= l;
    }
  bool can(int ag)
  {
    int pa = 0;
    int pm = 0;
    int ct = 0;
    bool[] active;
    active.length = n + 2;
    active[] = true;
    while(pa != n + 1)
      {
	int obj = 0;
	while(true)
	  {
	    bool mustbreak = false;
	    foreach(cell; pos[pm + 1])
		if (active[pm + 1] && cell.danger > ag)
		  {
		    mustbreak = true;
		    obj = max(obj, cell.right);
		  }
	    if (mustbreak)
	      break;
	    pm++;
	    pa++;
	    ct++;
	    if (ct > t)
	      return false;
	    if (pa == n + 1)
		return true;
	  }

	for(; pm <= obj;)
	  {
	    foreach(d; deact[pm])
		active[d] = false;
	    foreach(cell; pos[pm])
		if (active[pm] && cell.danger > ag)
		  obj = max(obj, cell.right);
	    if (pm == obj)
		break;
	    pm++;
	    ct++;
	    if (ct > t)
	      return false;
	  }
	assert(pm == obj);
	ct += (pm - pa) * 2;
	pa = obj;
	if (ct > t)
	  return false;
      }
    assert(0);
  }
  import std.range;
  auto ag = (assumeSorted!((int a, int b) => !can(a) || can(b))(iota(1, 200000 + 1)).lowerBound(true).length + 1);
  auto sortedA = sort!"a <= b"(a);
  auto res = sortedA.upperBound(ag).length;
  w(res);

  return 0;
}

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

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

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

    auto ds = new int[] (k);
    auto open = new int[][] (n+1);
    auto close = new int[][] (n+1);

    foreach (i; 0 .. k) {
        int le, r, d;
        readf("%s %s %s", &le, &r, &d);
        readln;

        ds[i] = d;
        open[le] ~= i;
        close[r] ~= i;
    }

    arr.sort();
    arr.reverse();

    bool isOk(int toBring) {

        int tot = 0;
        int threshold = arr[toBring-1];

        debug { writeln(toBring, ' ', threshold); }

        bool alone = false;
        int soldiersPos = 0;
        auto onPath = new bool[] (k);
        onPath[] = false;
        int onPathCnt = 0;
        foreach (i; 1 .. n+1) {
            foreach (idx; open[i]) {
                if (ds[idx] <= threshold) { continue; }

                onPath[idx] = true;
                onPathCnt += 1;
                alone = true;
            }

            foreach (idx; close[i]) {
                if (onPath[idx]) {
                    onPath[idx] = false;
                    onPathCnt -= 1;
                }
            }

            if (onPathCnt == 0) {
                if (alone) { tot += 2 * (i - soldiersPos); }
                tot += i - soldiersPos;
                soldiersPos = i;
                alone = false;
            }

            debug { writeln(i, ' ', soldiersPos, ' ', onPath, ' ', tot); }
        }

        tot += 1;
        return tot <= t;
    }

    int le = 0, r = n;
    while (le < r) {
        int c = (le + r) / 2 + 1;

        if (isOk(c)) { le = c; }
        else { r = c-1; }
    }

    le.writeln;
}

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

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

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

    auto ds = new int[] (k);
    alias trap = Tuple!(int, bool);
    auto open = new int[][] (n+1);
    auto close = new int[][] (n+1);

    foreach (i; 0 .. k) {
        int le, r, d;
        readf("%s %s %s", &le, &r, &d);
        readln;

        ds[i] = d;
        open[le] ~= i;
        close[r] ~= i;
    }

    arr.sort();
    arr.reverse();

    bool isOk(int toBring) {

        int tot = 0;
        int threshold = arr[toBring-1];

        debug { writeln(toBring, ' ', threshold); }

        bool alone = false;
        int soldiersPos = 0;
        auto onPath = new bool[] (k);
        onPath[] = false;
        int onPathCnt = 0;
        foreach (i; 1 .. n+1) {
            foreach (idx; open[i]) {
                if (ds[idx] <= threshold) { continue; }

                onPath[idx] = true;
                onPathCnt += 1;
                alone = true;
            }

            foreach (idx; close[i]) {
                if (onPath[idx]) {
                    onPath[idx] = false;
                    onPathCnt -= 1;
                }
            }

            if (onPathCnt == 0) {
                if (alone) { tot += 2 * (i - soldiersPos); }
                tot += i - soldiersPos;
                soldiersPos = i;
                alone = false;
            }

            debug { writeln(i, ' ', soldiersPos, ' ', onPath, ' ', tot); }
        }

        tot += 1;
        return tot <= t;
    }

    int le = 0, r = n;
    while (le < r) {
        int c = (le + r) / 2 + 1;

        if (isOk(c)) { le = c; }
        else { r = c-1; }
    }

    le.writeln;
}

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

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

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

    auto ds = new int[] (n);
    alias trap = Tuple!(int, bool);
    auto open = new int[][] (n+1);
    auto close = new int[][] (n+1);

    foreach (i; 0 .. k) {
        int le, r, d;
        readf("%s %s %s", &le, &r, &d);
        readln;

        ds[i] = d;
        open[le] ~= i;
        close[r] ~= i;
    }

    arr.sort();
    arr.reverse();

    bool isOk(int toBring) {

        int tot = 0;
        int threshold = arr[toBring-1];

        debug { writeln(toBring, ' ', threshold); }

        bool alone = false;
        int soldiersPos = 0;
        auto onPath = new bool[] (k+1);
        onPath[] = false;
        int onPathCnt = 0;
        foreach (i; 1 .. n+1) {
            foreach (idx; open[i]) {
                if (ds[idx] <= threshold) { continue; }

                onPath[idx] = true;
                onPathCnt += 1;
                alone = true;
            }

            foreach (idx; close[i]) {
                if (onPath[idx]) {
                    onPath[idx] = false;
                    onPathCnt -= 1;
                }
            }

            if (onPathCnt == 0) {
                if (alone) { tot += 2 * (i - soldiersPos); }
                tot += i - soldiersPos;
                soldiersPos = i;
                alone = false;
            }

            debug { writeln(i, ' ', soldiersPos, ' ', onPath, ' ', tot); }
        }

        tot += 1;
        return tot <= t;
    }

    int le = 0, r = n;
    while (le < r) {
        int c = (le + r) / 2 + 1;

        if (isOk(c)) { le = c; }
        else { r = c-1; }
    }

    le.writeln;
}

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

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

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

    auto ds = new int[] (n);
    alias trap = Tuple!(int, bool);
    auto open = new int[][] (n+1);
    auto close = new int[][] (n+1);

    foreach (i; 0 .. k) {
        int le, r, d;
        readf("%s %s %s", &le, &r, &d);
        readln;

        ds[i] = d;
        open[le] ~= i;
        close[r] ~= i;
    }

    arr.sort();
    arr.reverse();

    bool isOk(int toBring) {

        int tot = 0;
        int threshold = arr[toBring-1];

        debug { writeln(toBring, ' ', threshold); }

        bool alone = false;
        int soldiersPos = 0;
        auto onPath = new bool[] (k+1);
        onPath[] = false;
        int onPathCnt = 0;
        foreach (i; 1 .. n+1) {
            foreach (idx; open[i]) {
                if (ds[idx] <= threshold) { continue; }

                onPath[idx] = true;
                onPathCnt += 1;
                alone = true;
            }

            foreach (idx; close[i]) {
                if (onPath[idx]) {
                    onPath[idx] = false;
                    onPathCnt -= 1;
                }
            }

            if (onPathCnt == 0) {
                if (alone) { tot += 2 * (i - soldiersPos); }
                tot += i - soldiersPos;
                soldiersPos = i;
                alone = false;
            }

            debug { writeln(i, ' ', soldiersPos, ' ', onPath, ' ', tot); }
        }

        tot += 1;
        return tot <= t;
    }

    int le = 0, r = n;
    while (le < r) {
        int c = (le + r) / 2 + 1;

        if (isOk(c)) { le = c; }
        else { r = c-1; }
    }

    le.writeln;
}

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

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

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

    auto ds = new int[] (n);
    alias trap = Tuple!(int, bool);
    auto open = new int[][] (n+1);
    auto close = new int[][] (n+1);

    foreach (i; 0 .. k) {
        int le, r, d;
        readf("%s %s %s", &le, &r, &d);
        readln;

        ds[i] = d;
        open[le] ~= i;
        close[r] ~= i;
    }

    arr.sort();
    arr.reverse();

    bool isOk(int toBring) {

        int tot = 0;
        int threshold = arr[toBring-1];

        debug { writeln(toBring, ' ', threshold); }

        bool alone = false;
        int soldiersPos = 0;
        auto onPath = new bool[] (n+1);
        onPath[] = false;
        int onPathCnt = 0;
        foreach (i; 1 .. n+1) {
            foreach (idx; open[i]) {
                if (ds[idx] <= threshold) { continue; }

                onPath[idx] = true;
                onPathCnt += 1;
                alone = true;
            }

            foreach (idx; close[i]) {
                if (onPath[idx]) {
                    onPath[idx] = false;
                    onPathCnt -= 1;
                }
            }

            if (onPathCnt == 0) {
                if (alone) { tot += 2 * (i - soldiersPos); }
                tot += i - soldiersPos;
                soldiersPos = i;
                alone = false;
            }

            debug { writeln(i, ' ', soldiersPos, ' ', onPath, ' ', tot); }
        }

        tot += 1;
        return tot <= t;
    }

    int le = 0, r = n;
    while (le < r) {
        int c = (le + r) / 2 + 1;

        if (isOk(c)) { le = c; }
        else { r = c-1; }
    }

    le.writeln;
}

import std.stdio, std.conv, std.string, std.array, std.range, std.algorithm, std.container;
import std.math, std.random, std.bigint, std.datetime, std.format;
void main(string[] args){ if(args.length > 1) if(args[1] == "-debug") DEBUG = 1; solve(); }
void log()(){ writeln(""); } void log(T, A ...)(T t, lazy A a){ if(DEBUG) write(t, " "), log(a); } bool DEBUG = 0;
string rstring(){ static string[] ss; while(!ss.length) ss = readln.chomp.split; string res = ss[0]; ss.popFront; return res; }
T rtype(T)(){ return rstring.to!T; } alias rint = rtype!int, rlong = rtype!long, rreal = rtype!real;
T[] rtypes(T)(int n){ return n.iota.map!(i => rtype!T()).array; } alias rint = rtypes!int, rlong = rtypes!long, rreal = rtypes!real;
T[][] rtypess(T)(int n, int m){ return n.iota.map!(i => rtypes!T(m)).array; } alias rint = rtypess!int, rlong = rtypess!long, rreal = rtypess!real;
T chmin(T)(ref T x, T y){ if(x > y) x = y; return x; } T chmax(T)(ref T x, T y){ if(x < y) x = y; return x; }

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

void solve(){
	int m = rint, n = rint, k = rint, t = rint;
	long[] as = rlong(m);
	as.sort!"a>b"();

	X[] traps;
	foreach(i; 0 .. k) traps ~= X(rint, rint, rlong);

	bool isOK(int x){
		long a = (x > 0? as[x - 1]: 200_999);
		int rightend = 0;
		foreach(tr; traps) if(tr.d > a) rightend.chmax(tr.r);
		int time = rightend * 2 + n;
		return (time <= t);
	}

	int ans = uplimit(0, m, &isOK);
	ans.writeln;
}
struct X{
	int l, r;
	long d;
}
// 二分探索テンプレート
T uplimit(T)(T a, T c, bool delegate(T) f){
	if(f(c)) return c; if(! f(a)) return a - 1;
	while(a + 1 < c){ T b = (a + c) / 2; if(f(b)) a = b; else c = b; }
	return a;
}
T downlimit(T)(T a, T c, bool delegate(T) f){
	if(f(a)) return a; if(! f(c)) return c + 1;
	while(a + 1 < c){ T b = (a + c) / 2; if(f(b)) c = b; else a = b; }
	return c;
}

import std.stdio, std.conv, std.string, std.array, std.range, std.algorithm, std.container;
import std.math, std.random, std.bigint, std.datetime, std.format;
void main(string[] args){ if(args.length > 1) if(args[1] == "-debug") DEBUG = 1; solve(); }
void log()(){ writeln(""); } void log(T, A ...)(T t, lazy A a){ if(DEBUG) write(t, " "), log(a); } bool DEBUG = 0;
string rstring(){ static string[] ss; while(!ss.length) ss = readln.chomp.split; string res = ss[0]; ss.popFront; return res; }
T rtype(T)(){ return rstring.to!T; } alias rint = rtype!int, rlong = rtype!long, rreal = rtype!real;
T[] rtypes(T)(int n){ return n.iota.map!(i => rtype!T()).array; } alias rint = rtypes!int, rlong = rtypes!long, rreal = rtypes!real;
T[][] rtypess(T)(int n, int m){ return n.iota.map!(i => rtypes!T(m)).array; } alias rint = rtypess!int, rlong = rtypess!long, rreal = rtypess!real;
T chmin(T)(ref T x, T y){ if(x > y) x = y; return x; } T chmax(T)(ref T x, T y){ if(x < y) x = y; return x; }

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

void solve(){
	int m = rint, n = rint, k = rint, t = rint;
	long[] as = rlong(m);
	as.sort!"a>b"();

	X[] traps;
	foreach(i; 0 .. k) traps ~= X(rint, rint, rlong);

	bool isOK(int x){
		long a = (x > 0? as[x - 1]: 200_999);
		int leftend = n + 1, rightend = 0;
		foreach(tr; traps) if(tr.d > a){
			leftend.chmin(tr.l);
			rightend.chmax(tr.r);
		}
		if(leftend > rightend) leftend = rightend;
		int time = (rightend - leftend) * 2 + (n + 1);
		log("x:", x, "leftend:", leftend, "rightend:", rightend, "time:", time);
		return (time <= t);
	}

	int ans = uplimit(0, m, &isOK);
	ans.writeln;
}
struct X{
	int l, r;
	long d;
}
// 二分探索テンプレート
T uplimit(T)(T a, T c, bool delegate(T) f){
	if(f(c)) return c; if(! f(a)) return a - 1;
	while(a + 1 < c){ T b = (a + c) / 2; if(f(b)) a = b; else c = b; }
	return a;
}
T downlimit(T)(T a, T c, bool delegate(T) f){
	if(f(a)) return a; if(! f(c)) return c + 1;
	while(a + 1 < c){ T b = (a + c) / 2; if(f(b)) c = b; else a = b; }
	return c;
}

import std.stdio, std.conv, std.string, std.array, std.range, std.algorithm, std.container;
import std.math, std.random, std.bigint, std.datetime, std.format;
void main(string[] args){ if(args.length > 1) if(args[1] == "-debug") DEBUG = 1; solve(); }
void log()(){ writeln(""); } void log(T, A ...)(T t, lazy A a){ if(DEBUG) write(t, " "), log(a); } bool DEBUG = 0;
string rstring(){ static string[] ss; while(!ss.length) ss = readln.chomp.split; string res = ss[0]; ss.popFront; return res; }
T rtype(T)(){ return rstring.to!T; } alias rint = rtype!int, rlong = rtype!long, rreal = rtype!real;
T[] rtypes(T)(int n){ return n.iota.map!(i => rtype!T()).array; } alias rint = rtypes!int, rlong = rtypes!long, rreal = rtypes!real;
T[][] rtypess(T)(int n, int m){ return n.iota.map!(i => rtypes!T(m)).array; } alias rint = rtypess!int, rlong = rtypess!long, rreal = rtypess!real;
T chmin(T)(ref T x, T y){ if(x > y) x = y; return x; } T chmax(T)(ref T x, T y){ if(x < y) x = y; return x; }

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

void solve(){
	int m = rint, n = rint, k = rint, t = rint;
	long[] as = rlong(m);

	X[] traps;
	foreach(i; 0 .. k) traps ~= X(rint, rint, rlong);

	int rightmost = (t - (n + 1)) / 2;

	long dmax = 0;
	foreach(tr; traps) if(tr.r > rightmost) dmax.chmax(tr.d);

	int ans = 0;
	foreach(a; as) if(a >= dmax) ans += 1;
	ans.writeln;
}
struct X{
	int l, r;
	long d;
}

import std.stdio, std.conv, std.string, std.array, std.range, std.algorithm, std.container;
import std.math, std.random, std.bigint, std.datetime, std.format;
void main(string[] args){ if(args.length > 1) if(args[1] == "-debug") DEBUG = 1; solve(); }
void log()(){ writeln(""); } void log(T, A ...)(T t, lazy A a){ if(DEBUG) write(t, " "), log(a); } bool DEBUG = 0;
string rstring(){ static string[] ss; while(!ss.length) ss = readln.chomp.split; string res = ss[0]; ss.popFront; return res; }
T rtype(T)(){ return rstring.to!T; } alias rint = rtype!int, rlong = rtype!long, rreal = rtype!real;
T[] rtypes(T)(int n){ return n.iota.map!(i => rtype!T()).array; } alias rint = rtypes!int, rlong = rtypes!long, rreal = rtypes!real;
T[][] rtypess(T)(int n, int m){ return n.iota.map!(i => rtypes!T(m)).array; } alias rint = rtypess!int, rlong = rtypess!long, rreal = rtypess!real;
T chmin(T)(ref T x, T y){ if(x > y) x = y; return x; } T chmax(T)(ref T x, T y){ if(x < y) x = y; return x; }

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

void solve(){
	int m = rint, n = rint, k = rint, t = rint;
	long[] as = rlong(m);
	as.sort!"a>b"();

	X[] traps;
	foreach(i; 0 .. k) traps ~= X(rint, rint, rlong);

	bool isOK(int x){
		long a = (x > 0? as[x - 1]: 200_999);
		int[] ls, rs;
		foreach(tr; traps) if(tr.d > a) ls ~= tr.l, rs ~= tr.r;
		ls.sort(), rs.sort();
		auto lq = new Queue!int(ls), rq = new Queue!int(rs);
		int leftpos = 0;
		int time = (n + 1);
		int cnt = 0;
		log("x:", x, "a:", a, "ls:", ls, "rs:", rs, "lq:", lq, "rq:", rq, "leftpos:", leftpos, "cnt:", cnt, "time:", time);
		while(lq.length + rq.length > 0){
			if(lq.length > 0 && lq.peek <= rq.peek){
				if(cnt == 0) leftpos = lq.peek;
				lq.deq, cnt += 1;
			}
			else{
				if(cnt == 1) time += (rq.peek - leftpos) * 2;
				rq.deq, cnt -= 1;
			}
			log("lq:", lq, "rq:", rq, "leftpos:", leftpos, "cnt:", cnt, "time:", time);
		}
//		log("x:", x, "a:", a, "leftend:", leftend, "rightend:", rightend, "time:", time, "isOK:", time <= t);
		return time <= t;

	}

	int ans = uplimit(0, m, &isOK);
	ans.writeln;
}
struct X{
	int l, r;
	long d;
}
// 二分探索テンプレート
T uplimit(T)(T a, T c, bool delegate(T) f){
	if(f(c)) return c; if(! f(a)) return a - 1;
	while(a + 1 < c){ T b = (a + c) / 2; if(f(b)) a = b; else c = b; }
	return a;
}
T downlimit(T)(T a, T c, bool delegate(T) f){
	if(f(a)) return a; if(! f(c)) return c + 1;
	while(a + 1 < c){ T b = (a + c) / 2; if(f(b)) c = b; else a = b; }
	return c;
}
// ----- キュー -----
class Queue(T){
	private T[] xs;
	private uint i, j; // i : 次に読み出す位置　j: 次に書き込む位置
	this(){	}
	this(T[] xs){ this.xs = xs; j = xs.length; }
	void enq(T x){
		while(j + 1 >= xs.length) xs.length = xs.length * 2 + 1;
		xs[j ++] = x;
	}
	ulong length(){ return j - i; }
	bool isEmpty(){ return j == i; }
	T deq(){ assert(i < j); return xs[i ++]; }
	T peek(){ assert(i < j); return xs[i]; }
	T[] array(){ return xs[i .. j]; }
	override string toString(){ return array.to!string; }
}
/*
5 6 4 14
1 2 3 4 5
1 5 2
1 2 5
3 4 5
3 5 3
*/


Since Boboniu finished building his Jianghu, he has been doing Kungfu on these mountains every day. Boboniu designs a map for his $$$n$$$ mountains. He uses $$$n-1$$$ roads to connect all $$$n$$$ mountains. Every pair of mountains is connected via roads.For the $$$i$$$-th mountain, Boboniu estimated the tiredness of doing Kungfu on the top of it as $$$t_i$$$. He also estimated the height of each mountain as $$$h_i$$$.A path is a sequence of mountains $$$M$$$ such that for each $$$i$$$ ($$$1 \le i < |M|$$$), there exists a road between $$$M_i$$$ and $$$M_{i+1}$$$. Boboniu would regard the path as a challenge if for each $$$i$$$ ($$$1\le i<|M|$$$), $$$h_{M_i}\le h_{M_{i+1}}$$$.Boboniu wants to divide all $$$n-1$$$ roads into several challenges. Note that each road must appear in exactly one challenge, but a mountain may appear in several challenges. Boboniu wants to minimize the total tiredness to do all the challenges. The tiredness of a challenge $$$M$$$ is the sum of tiredness of all mountains in it, i.e. $$$\sum_{i=1}^{|M|}t_{M_i}$$$. He asked you to find the minimum total tiredness. As a reward for your work, you'll become a guardian in his Jianghu.

The first line contains a single integer $$$n$$$ ($$$2 \le n \le 2 \cdot 10^5$$$), denoting the number of the mountains. The second line contains $$$n$$$ integers $$$t_1, t_2, \ldots, t_n$$$ ($$$1 \le t_i \le 10^6$$$), denoting the tiredness for Boboniu to do Kungfu on each mountain. The third line contains $$$n$$$ integers $$$h_1, h_2, \ldots, h_n$$$ ($$$1 \le h_i \le 10^6$$$), denoting the height of each mountain. Each of the following $$$n - 1$$$ lines contains two integers $$$u_i$$$, $$$v_i$$$ ($$$1 \le u_i, v_i \le n, u_i \neq v_i$$$), denoting the ends of the road. It's guaranteed that all mountains are connected via roads.

Print one integer: the smallest sum of tiredness of all challenges.

NoteFor the first example:  In the picture, the lighter a point is, the higher the mountain it represents. One of the best divisions is:  Challenge $$$1$$$: $$$3 \to 1 \to 2$$$  Challenge $$$2$$$: $$$5 \to 2 \to 4$$$ The total tiredness of Boboniu is $$$(30 + 40 + 10) + (20 + 10 + 50) = 160$$$. It can be shown that this is the minimum total tiredness.

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

void main() {

  immutable Maxn = cast(int)(2e5 + 5);

  int n;
  readf!"%d\n"(n);
  const auto t = readln.splitter.map!(to!(long)).array;
  const auto h = readln.splitter.map!(to!(int)).array;
  int[][Maxn] g;
  int[Maxn] in_deg, out_deg;
  in_deg[] = out_deg[] = 0;
  long ans = 0;
  foreach (i; 1 .. n) {
    int u, v;
    readf!"%d %d\n"(u, v);
    --u, --v;
    ans += t[u] + t[v];
    if (h[u] == h[v]) {
      g[u] ~= v;
      g[v] ~= u;
    }
    else {
      if (h[u] < h[v])
        ++in_deg[u], ++out_deg[v];
      else
        ++out_deg[u], ++in_deg[v];
    }
  }

  bool[Maxn] vis;
  vis[] = false;
  long[2][Maxn] dp;
  foreach (i; 0 .. n)
    dp[i][0] = dp[i][1] = 0L;

  void dfs(int u, int fa) {
    vis[u] = true;
    long[] arr;
    long res = 0;
    foreach (v; g[u]) {
      if (vis[v]) continue;
      dfs(v, u);
      arr ~= dp[v][1] - dp[v][0];
      res += dp[v][0];
    }
    arr.sort;
    const int len = arr.length;
    arr ~= 0;
    for (int i = len; i >= 0; --i) {
      res += arr[i];
      if (fa != -1) {
        dp[u][0] = max(dp[u][0], res + t[u] * min(in_deg[u] + i, out_deg[u] + len - i + 1));
        dp[u][1] = max(dp[u][1], res + t[u] * min(in_deg[u] + i + 1, out_deg[u] + len - i));
      }
      else {
        dp[u][0] = max(dp[u][0], res + t[u] * min(in_deg[u] + i, out_deg[u] + len - i));
      }
    }
  }

  foreach (i; 0 .. n) {
    if (!vis[i]) {
      dfs(i, -1);
      ans -= dp[i][0];
    }
  }
  ans.writeln;

}


Let's call some square matrix with integer values in its cells palindromic if it doesn't change after the order of rows is reversed and it doesn't change after the order of columns is reversed.For example, the following matrices are palindromic:  The following matrices are not palindromic because they change after the order of rows is reversed:  The following matrices are not palindromic because they change after the order of columns is reversed:  You are given $$$n^2$$$ integers. Put them into a matrix of $$$n$$$ rows and $$$n$$$ columns so that each number is used exactly once, each cell contains exactly one number and the resulting matrix is palindromic. If there are multiple answers, print any. If there is no solution, print "NO".

The first line contains one integer $$$n$$$ ($$$1 \le n \le 20$$$). The second line contains $$$n^2$$$ integers $$$a_1, a_2, \dots, a_{n^2}$$$ ($$$1 \le a_i \le 1000$$$) — the numbers to put into a matrix of $$$n$$$ rows and $$$n$$$ columns.

If it is possible to put all of the $$$n^2$$$ numbers into a matrix of $$$n$$$ rows and $$$n$$$ columns so that each number is used exactly once, each cell contains exactly one number and the resulting matrix is palindromic, then print "YES". Then print $$$n$$$ lines with $$$n$$$ space-separated numbers — the resulting matrix. If it's impossible to construct any matrix, then print "NO". You can print each letter in any case (upper or lower). For example, "YeS", "no" and "yES" are all acceptable.

NoteNote that there exist multiple answers for the first two examples.

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

  int n;
  rd(n);
  auto a = readln.split.to!(int[]);
  sort(a);

  if (n == 1) {
    writeln("YES");
    writeln(a[0]);
    return;
  }

  auto freq = new int[](1234);
  foreach (el; a) {
    freq[el]++;
  }
  if (n % 2 == 0) {
    auto mat = new int[][](n, n);
    int k = 0;
    foreach (i; 0 .. n / 2) {
      foreach (j; 0 .. n / 2) {
        if (k < n * n) {
          if (freq[a[k]] > 0 && freq[a[k]] % 4 == 0) {
            mat[i][j] = mat[n - i - 1][j] = mat[i][n - j - 1] = mat[n - i - 1][n - j - 1] = a[k];
            freq[a[k]] -= 4;
            k += 4;
          }
        }
      }
    }
    if (k != n * n) {
      writeln("NO");
    } else {
      writeln("YES");
      writefln("%(%(%s %)\n%)", mat);
    }
  } else {
    auto mat = new int[][](n, n);
    int od = 0;
    foreach(el; freq) {
      if (el & 1) {
        od++;
      }
    }
    if (od != 1) {
      writeln("NO");
      return;
    }
    foreach (el; a) {
      if (freq[el] % 4 == 1 || freq[el] % 4 == 3) {
        mat[n / 2][n / 2] = el;
        freq[el]--;
        break;
      }
    }
    foreach (i; 0 .. n / 2) {
      foreach (el; a) {
        if (freq[el] % 4 == 2) {
          mat[i][n / 2] = mat[n - i - 1][n / 2] = el;
          freq[el] -= 2;
          break;
        }
      }
    }
    foreach (j; 0 .. n / 2) {
      foreach (el; a) {
        if (freq[el] % 4 == 2) {
          mat[n / 2][j] = mat[n / 2][n - j - 1] = el;
          freq[el] -= 2;
          break;
        }
      }
    }
    foreach (i; 0 .. n / 2) {
      foreach (j; 0 .. n / 2) {
        foreach (el; a) {
          if (freq[el] > 0 && freq[el] % 4 == 0) {
            mat[i][j] = mat[n - i - 1][j] = mat[i][n - j - 1] = mat[n - i - 1][n - j - 1] = el;
            freq[el] -= 4;
            break;
          }
        }
      }
    }
    foreach (i; 0 .. n / 2) {
      if (mat[i][n / 2] == 0) {
        foreach (el; a) {
          if (freq[el] > 0 && freq[el] % 2 == 0) {
            mat[i][n / 2] = mat[n - i - 1][n / 2] = el;
            freq[el] -= 2;
            break;
          }
        }
      }
    }
    foreach (j; 0 .. n / 2) {
      if (mat[n / 2][j] == 0) {
        foreach (el; a) {
          if (freq[el] > 0 && freq[el] % 2 == 0) {
            mat[n / 2][j] = mat[n / 2][n - j - 1] = el;
            freq[el] -= 2;
            break;
          }
        }
      }
    }
    if (freq.any!((el) => (el != 0))) {
      writeln("NO");
    } else {
      writeln("YES");
      foreach (i; 0 .. n) {
        foreach (j; 0 .. n) {
          enforce(mat[i][j] > 0);
          enforce(mat[i][j] == mat[n - i - 1][j]);
          enforce(mat[i][j] == mat[i][n - j - 1]);
          enforce(mat[i][j] == mat[n - i - 1][n - j - 1]);
        }
      }
      writefln("%(%(%s %)\n%)", mat);
    }
  }
}

/*

7
1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3

*/

void rd(T...)(ref T x) {
  import std.stdio : readln;
  import std.string : split;
  import std.conv : to;

  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;
  import std.exception;

  int n;
  rd(n);
  auto a = readln.split.to!(int[]);
  sort(a);

  if (n == 1) {
    writeln("YES");
    writeln(a[0]);
    return;
  }

  auto freq = new int[](1234);
  foreach (el; a) {
    freq[el]++;
  }
  if (n % 2 == 0) {
    auto mat = new int[][](n, n);
    foreach (i; 0 .. n / 2) {
      foreach (j; 0 .. n / 2) {
        foreach (el; a) {
          if (freq[el] > 0 && freq[el] % 4 == 0) {
            mat[i][j] = mat[n - i - 1][j] = mat[i][n - j - 1] = mat[n - i - 1][n - j - 1] = el;
            freq[el] -= 4;
            break;
          }
        }
      }
    }
    if (freq.any!((el) => (el > 0))) {
      writeln("NO");
    } else {
      writeln("YES");
      writefln("%(%(%s %)\n%)", mat);
    }
  } else {
    auto mat = new int[][](n, n);
    foreach (el; a) {
      if (freq[el] % 4 == 1 || freq[el] % 4 == 3) {
        mat[n / 2][n / 2] = el;
        freq[el]--;
        break;
      }
    }
    if (freq.any!((el) => (el & 1))) {
      writeln("NO");
      return;
    }
    foreach (i; 0 .. n / 2) {
      foreach (j; 0 .. n / 2) {
        foreach (el; a) {
          if (freq[el] > 2) {
            mat[i][j] = mat[n - i - 1][j] = mat[i][n - j - 1] = mat[n - i - 1][n - j - 1] = el;
            freq[el] -= 4;
            break;
          }
        }
      }
    }
    foreach (i; 0 .. n / 2) {
      if (mat[i][n / 2] == 0) {
        foreach (el; a) {
          if (freq[el] > 0 && freq[el] % 2 == 0) {
            mat[i][n / 2] = mat[n - i - 1][n / 2] = el;
            freq[el] -= 2;
            break;
          }
        }
      }
    }
    foreach (j; 0 .. n / 2) {
      if (mat[n / 2][j] == 0) {
        foreach (el; a) {
          if (freq[el] > 0 && freq[el] % 2 == 0) {
            mat[n / 2][j] = mat[n / 2][n - j - 1] = el;
            freq[el] -= 2;
            break;
          }
        }
      }
    }
    if (freq.any!((el) => (el > 0))) {
      writeln("NO");
    } else {
      writeln("YES");
      writefln("%(%(%s %)\n%)", mat);
    }
  }
}

/*

7
5 9 5 4 1 9 8 4 5 1 4 10 7 7 8 4 2 4 4 5 4 4 10 3 4 6 8 1 9 9 5 6 8 7 1 8 6 6 7 5 3 1 1 4 7 2 3 3 8

*/

void rd(T...)(ref T x) {
  import std.stdio : readln;
  import std.string : split;
  import std.conv : to;

  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;
  import std.exception;

  int n;
  rd(n);
  auto a = readln.split.to!(int[]);
  sort(a);

  if (n == 1) {
    writeln("YES");
    writeln(a[0]);
    return;
  }

  auto freq = new int[](1234);
  foreach (el; a) {
    freq[el]++;
  }
  if (n % 2 == 0) {
    auto mat = new int[][](n, n);
    int k = 0;
    foreach (i; 0 .. n / 2) {
      foreach (j; 0 .. n / 2) {
        if (k < n * n) {
          if (freq[a[k]] > 0 && freq[a[k]] % 4 == 0) {
            mat[i][j] = mat[n - i - 1][j] = mat[i][n - j - 1] = mat[n - i - 1][n - j - 1] = a[k];
            freq[a[k]] -= 4;
            k += 4;
          }
        }
      }
    }
    if (k != n * n) {
      writeln("NO");
    } else {
      writeln("YES");
      writefln("%(%(%s %)\n%)", mat);
    }
  } else {
    auto mat = new int[][](n, n);
    foreach (el; a) {
      if (freq[el] % 4 == 1 || freq[el] % 4 == 3) {
        mat[n / 2][n / 2] = el;
        freq[el]--;
        break;
      }
    }
    foreach (i; 0 .. n / 2) {
      foreach (el; a) {
        if (freq[el] % 4 == 2) {
          mat[i][n / 2] = mat[n - i - 1][n / 2] = el;
          freq[el] -= 2;
          break;
        }
      }
    }
    foreach (j; 0 .. n / 2) {
      foreach (el; a) {
        if (freq[el] % 4 == 2) {
          mat[n / 2][j] = mat[n / 2][n - j - 1] = el;
          freq[el] -= 2;
          break;
        }
      }
    }
    foreach (i; 0 .. n / 2) {
      foreach (j; 0 .. n / 2) {
        foreach (el; a) {
          if (freq[el] > 0 && freq[el] % 4 == 0) {
            mat[i][j] = mat[n - i - 1][j] = mat[i][n - j - 1] = mat[n - i - 1][n - j - 1] = el;
            freq[el] -= 4;
            break;
          }
        }
      }
    }
    foreach (i; 0 .. n / 2) {
      if (mat[i][n / 2] == 0) {
        foreach (el; a) {
          if (freq[el] > 0 && freq[el] % 2 == 0) {
            mat[i][n / 2] = mat[n - i - 1][n / 2] = el;
            freq[el] -= 2;
            break;
          }
        }
      }
    }
    foreach (j; 0 .. n / 2) {
      if (mat[n / 2][j] == 0) {
        foreach (el; a) {
          if (freq[el] > 0 && freq[el] % 2 == 0) {
            mat[n / 2][j] = mat[n / 2][n - j - 1] = el;
            freq[el] -= 2;
            break;
          }
        }
      }
    }
    if (freq.any!((el) => (el != 0))) {
      writeln("NO");
    } else {
      writeln("YES");
      foreach (i; 0 .. n) {
        foreach (j; 0 .. n) {
          enforce(mat[i][j] > 0);
          enforce(mat[i][j] == mat[n - i - 1][j]);
          enforce(mat[i][j] == mat[i][n - j - 1]);
          enforce(mat[i][j] == mat[n - i - 1][n - j - 1]);
        }
      }
      writefln("%(%(%s %)\n%)", mat);
    }
  }
}

/*

7
1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3

*/

void rd(T...)(ref T x) {
  import std.stdio : readln;
  import std.string : split;
  import std.conv : to;

  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;
  rd(n);
  auto a = readln.split.to!(int[]);
  sort(a);

  if (n == 1) {
    writeln("YES");
    writeln(a[0]);
    return;
  }

  auto freq = new int[](1234);
  foreach (el; a) {
    freq[el]++;
  }
  if (n % 2 == 0) {
    auto mat = new int[][](n, n);
    int k = 0;
    foreach (i; 0 .. n / 2) {
      foreach (j; 0 .. n / 2) {
        if (k < n * n) {
          if (freq[a[k]] > 0 && freq[a[k]] % 4 == 0) {
            mat[i][j] = mat[n - i - 1][j] = mat[i][n - j - 1] = mat[n - i - 1][n - j - 1] = a[k];
            freq[a[k]] -= 4;
            k += 4;
          }
        }
      }
    }
    if (k != n * n) {
      writeln("NO");
    } else {
      writeln("YES");
      writefln("%(%(%s %)\n%)", mat);
    }
  } else {
    auto mat = new int[][](n, n);
    foreach (el; a) {
      if (freq[el] % 4 == 1 || freq[el] % 4 == 3) {
        mat[n / 2][n / 2] = el;
        freq[el]--;
        break;
      }
    }
    foreach (i; 0 .. n / 2) {
      foreach (el; a) {
        if (freq[el] % 4 == 2) {
          mat[i][n / 2] = mat[n - i - 1][n / 2] = el;
          freq[el] -= 2;
          break;
        }
      }
    }
    foreach (j; 0 .. n / 2) {
      foreach (el; a) {
        if (freq[el] % 4 == 2) {
          mat[n / 2][j] = mat[n / 2][n - j - 1] = el;
          freq[el] -= 2;
          break;
        }
      }
    }
    foreach (i; 0 .. n / 2) {
      foreach (j; 0 .. n / 2) {
        foreach (el; a) {
          if (freq[el] > 0 && freq[el] % 4 == 0) {
            mat[i][j] = mat[n - i - 1][j] = mat[i][n - j - 1] = mat[n - i - 1][n - j - 1] = el;
            freq[el] -= 4;
            break;
          }
        }
      }
    }
    foreach (i; 0 .. n / 2) {
      foreach (el; a) {
        if (freq[el] > 0 && freq[el] % 2 == 0) {
          mat[i][n / 2] = mat[n - i - 1][n / 2] = el;
          freq[el] -= 2;
          break;
        }
      }
    }
    foreach (j; 0 .. n / 2) {
      foreach (el; a) {
        if (freq[el] > 0 && freq[el] % 2 == 0) {
          mat[n / 2][j] = mat[n / 2][n - j - 1] = el;
          freq[el] -= 2;
          break;
        }
      }
    }
    if (freq.any!((el) => (el != 0))) {
      writeln("NO");
    } else {
      writeln("YES");
      writefln("%(%(%s %)\n%)", mat);
    }
  }
}

/*

*/

void rd(T...)(ref T x) {
  import std.stdio : readln;
  import std.string : split;
  import std.conv : to;

  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;
  import std.exception;

  int n;
  rd(n);
  auto a = readln.split.to!(int[]);
  sort(a);

  if (n == 1) {
    writeln("YES");
    writeln(a[0]);
    return;
  }

  auto freq = new int[](1234);
  foreach (el; a) {
    freq[el]++;
  }
  if (n % 2 == 0) {
    auto mat = new int[][](n, n);
    foreach (i; 0 .. n / 2) {
      foreach (j; 0 .. n / 2) {
        foreach (el; a) {
          if (freq[el] > 0 && freq[el] % 4 == 0) {
            mat[i][j] = mat[n - i - 1][j] = mat[i][n - j - 1] = mat[n - i - 1][n - j - 1] = el;
            freq[el] -= 4;
            break;
          }
        }
      }
    }
    if (freq.any!((el) => (el > 0))) {
      writeln("NO");
    } else {
      writeln("YES");
      writefln("%(%(%s %)\n%)", mat);
    }
  } else {
    auto mat = new int[][](n, n);
    foreach (el; a) {
      if (freq[el] % 4 == 1 || freq[el] % 4 == 3) {
        mat[n / 2][n / 2] = el;
        freq[el]--;
        break;
      }
    }
    foreach (i; 0 .. n / 2) {
      foreach (j; 0 .. n / 2) {
        foreach (el; a) {
          if (freq[el] > 0 && freq[el] % 4 == 0) {
            mat[i][j] = mat[n - i - 1][j] = mat[i][n - j - 1] = mat[n - i - 1][n - j - 1] = el;
            freq[el] -= 4;
            break;
          }
        }
      }
    }
    foreach (i; 0 .. n / 2) {
      if (mat[i][n / 2] == 0) {
        foreach (el; a) {
          if (freq[el] > 0 && freq[el] % 2 == 0) {
            mat[i][n / 2] = mat[n - i - 1][n / 2] = el;
            freq[el] -= 2;
            break;
          }
        }
      }
    }
    foreach (j; 0 .. n / 2) {
      if (mat[n / 2][j] == 0) {
        foreach (el; a) {
          if (freq[el] > 0 && freq[el] % 2 == 0) {
            mat[n / 2][j] = mat[n / 2][n - j - 1] = el;
            freq[el] -= 2;
            break;
          }
        }
      }
    }
    if (freq.any!((el) => (el != 0))) {
      writeln("NO");
    } else {
      writeln("YES");
      writefln("%(%(%s %)\n%)", mat);
    }
  }
}

/*

7
1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3

*/

void rd(T...)(ref T x) {
  import std.stdio : readln;
  import std.string : split;
  import std.conv : to;

  auto l = readln.split;
  assert(l.length == x.length);
  foreach (i, ref e; x)
    e = l[i].to!(typeof(e));
}


Polycarp is a frequent user of the very popular messenger. He's chatting with his friends all the time. He has $$$n$$$ friends, numbered from $$$1$$$ to $$$n$$$.Recall that a permutation of size $$$n$$$ is an array of size $$$n$$$ such that each integer from $$$1$$$ to $$$n$$$ occurs exactly once in this array.So his recent chat list can be represented with a permutation $$$p$$$ of size $$$n$$$. $$$p_1$$$ is the most recent friend Polycarp talked to, $$$p_2$$$ is the second most recent and so on.Initially, Polycarp's recent chat list $$$p$$$ looks like $$$1, 2, \dots, n$$$ (in other words, it is an identity permutation).After that he receives $$$m$$$ messages, the $$$j$$$-th message comes from the friend $$$a_j$$$. And that causes friend $$$a_j$$$ to move to the first position in a permutation, shifting everyone between the first position and the current position of $$$a_j$$$ by $$$1$$$. Note that if the friend $$$a_j$$$ is in the first position already then nothing happens.For example, let the recent chat list be $$$p = [4, 1, 5, 3, 2]$$$:   if he gets messaged by friend $$$3$$$, then $$$p$$$ becomes $$$[3, 4, 1, 5, 2]$$$;  if he gets messaged by friend $$$4$$$, then $$$p$$$ doesn't change $$$[4, 1, 5, 3, 2]$$$;  if he gets messaged by friend $$$2$$$, then $$$p$$$ becomes $$$[2, 4, 1, 5, 3]$$$. For each friend consider all position he has been at in the beginning and after receiving each message. Polycarp wants to know what were the minimum and the maximum positions.

The first line contains two integers $$$n$$$ and $$$m$$$ ($$$1 \le n, m \le 3 \cdot 10^5$$$) — the number of Polycarp's friends and the number of received messages, respectively. The second line contains $$$m$$$ integers $$$a_1, a_2, \dots, a_m$$$ ($$$1 \le a_i \le n$$$) — the descriptions of the received messages.

Print $$$n$$$ pairs of integers. For each friend output the minimum and the maximum positions he has been in the beginning and after receiving each message.

NoteIn the first example, Polycarp's recent chat list looks like this:   $$$[1, 2, 3, 4, 5]$$$  $$$[3, 1, 2, 4, 5]$$$  $$$[5, 3, 1, 2, 4]$$$  $$$[1, 5, 3, 2, 4]$$$  $$$[4, 1, 5, 3, 2]$$$ So, for example, the positions of the friend $$$2$$$ are $$$2, 3, 4, 4, 5$$$, respectively. Out of these $$$2$$$ is the minimum one and $$$5$$$ is the maximum one. Thus, the answer for the friend $$$2$$$ is a pair $$$(2, 5)$$$.In the second example, Polycarp's recent chat list looks like this:   $$$[1, 2, 3, 4]$$$  $$$[1, 2, 3, 4]$$$  $$$[2, 1, 3, 4]$$$  $$$[4, 2, 1, 3]$$$

//prewritten code: https://github.com/antma/algo
module Solution;
import std.algorithm;
import std.array;
import std.conv;
import std.functional;
import std.math;
import std.range;
import std.stdio;
import std.string;
import std.traits;
import std.bitmanip;
import core.bitop;
import std.exception;

final class InputReader {
  private:
  ubyte[] p, buffer;
  bool eof;
  bool rawRead () {
    if (eof) {
      return false;
    }
    p = stdin.rawRead (buffer);
    if (p.empty) {
      eof = true;
      return false;
    }
    return true;
  }
  ubyte nextByte(bool check) () {
    static if (check) {
      if (p.empty) {
        if (!rawRead ()) {
          return 0;
        }
      }
    }
    auto r = p.front;
    p.popFront ();
    return r;
  }
  public:
  this () {
    buffer = uninitializedArray!(ubyte[])(16<<20);
  }
  bool seekByte (in ubyte lo) {
    while (true) {
      p = p.find! (c => c >= lo);
      if (!p.empty) {
        return false;
      }
      if (!rawRead ()) {
        return true;
      }
    }
  }
  template next(T) if (isSigned!T) {
    T next ()  {
      if (seekByte (45)) {
        return 0;
      }
      T res;
      ubyte b = nextByte!false ();
      if (b == 45) {
        while (true) {
          b = nextByte!true ();
          if (b < 48 || b >= 58) {
            return res;
          }
          res = res * 10 - (b - 48);
        }
      } else {
        res = b - 48;
        while (true) {
          b = nextByte!true ();
          if (b < 48 || b >= 58) {
            return res;
          }
          res = res * 10 + (b - 48);
        }
      }
    }
  }
  template next(T) if (isUnsigned!T) {
    T next () {
      if (seekByte (48)) {
        return 0;
      }
      T res = nextByte!false () - 48;
      while (true) {
        ubyte b = nextByte!true ();
        if (b < 48 || b >= 58) {
          break;
        }
        res = res * 10 + (b - 48);
      }
      return res;
    }
  }
  T[] nextA(T) (in int n) {
    auto a = uninitializedArray!(T[]) (n);
    foreach (i; 0 .. n) {
      a[i] = next!T;
    }
    return a;
  }
}

alias MoResult = int;

struct MoQuery {
  int u, v;//inclusive
  MoResult res;
}

abstract class MoState {
  public:
  @property
  abstract bool fastReset () const;
  abstract void reset ();
  //[l, r)
  abstract void add (int l, int r);
  abstract void del (int l, int r);
  abstract MoResult result () const;
}

struct MoRange {
  int l, r;
  bool fastReset;
  static immutable d = [3, 0, 0, 1];
  static long hilbert (const int x, const int y, const int k, const int a) {
    if (k < 0) return 0L;
    immutable int m = ~(1 << k), o = 3 & (((x >> k) ^ 3 * (y >> k)) + a);
    immutable long b = hilbert (x & m, y & m, k - 1, a + d[o]), ss = 1L << (2 * k);
    return ss * o + (o == 1 || o == 2 ? b : (ss - (b + 1)));
  }
  static size_t[] makeIdx (in MoQuery[] queries, const int t) {
    immutable nq = queries.length;
    auto x = uninitializedArray!(long[])(nq);
    foreach (i, const ref q; queries) {
      x[i] = hilbert (q.u, q.v, t, 0);
    }
    auto idx = uninitializedArray!(size_t[])(nq);
    makeIndex (x, idx);
    return idx;
  }
  void move (MoState s, ref MoQuery q) {
    if (l > r || (fastReset && (l > q.v || r < q.u))) {
      l = q.u;
      r = l - 1;
      s.reset ();
    }
    if (r < q.v) {
      s.add (r + 1, q.v + 1);
      r = q.v;
    } else if (r > q.v) {
      s.del (q.v + 1, r + 1);
      r = q.v;
    }
    if (l > q.u) {
      s.add (q.u, l);
      l = q.u;
    } else if (l < q.u) {
      s.del (l, q.u);
      l = q.u;
    }
    q.res = s.result ();
  }
  void processQueries (MoState s, MoQuery[] queries) {
    l = 0; r = -1; fastReset = s.fastReset;
    auto idx = makeIdx (queries, bsr (reduce!max(0, queries.map!(t => t.v)) + 1));
    foreach (j; idx) {
      move (s, queries[j]);
    }
  }
}

final class EState : MoState {
  private:
  uint[] x;
  int[] ba;
  int sz;
  public:
  @property
  override bool fastReset () const {
    return false;
  }
  override void reset () {
    ba[] = 0;
    sz = 0;
  }
  //[l, r)
  override void add (int l, int r) {
    foreach (k; x[l .. r]) {
      if (++ba[k] == 1) ++sz;
    }
  }
  override void del (int l, int r) {
    foreach (k; x[l .. r]) {
      if (!--ba[k]) --sz;
    }
  }
  override MoResult result () const {
    return sz;
  }
  this (uint[] x, int n) {
    this.x = x;
    ba = new int[n];
  }
}

void test (in int n, uint[] a) {
  debug stderr.writeln ("a = ", a);
  auto v = new int[n];
  foreach (i; 0 .. n) {
    v[i] = i;
  }
  auto prev = uninitializedArray!(int[]) (n);

  MoQuery[] q;

  prev[] = -1;
  foreach (i, j; a) {
    immutable int pos = i.to!int;
    if (prev[j] >= 0) {
      q ~= MoQuery (prev[j] + 1, i.to!int - 1);
    }
    prev[j] = pos;
  }
  foreach (i; 0 .. n) {
    q ~= MoQuery (prev[i] + 1, a.length.to!int - 1);
  }

  auto state = new EState (a, n);
  MoRange rng;
  rng.processQueries (state, q);
  state = null;

  int cur;
  prev[] = -1;
  foreach (i, j; a) {
    immutable int pos = i.to!int;
    if (prev[j] >= 0) {
      auto k = q[cur++].res;
      v[j] = max (v[j], k);
    }
    prev[j] = pos;
  }

  foreach (i; 0 .. n) {
    auto k = q[cur++].res;
    v[i] = max (v[i], k);
  }

  q = null;

  foreach (i; 0 .. n) {
    int j = v[i];
    int u = i;
    if (prev[i] >= n) {
      u = 0;
    }
    writeln (u + 1, ' ', j + 1);
  }
}

void main() {
  auto r = new InputReader ();
  immutable n = r.next!uint;
  immutable m = r.next!uint;
  auto a = uninitializedArray!(uint[]) (n + m);
  foreach (i; 0 .. n) a[i] = n - 1 - i;
  foreach (i; 0 .. m) a[n+i] = r.next!uint - 1;
  a.length -= uniq (a).copy (a).length;
  test (n, a);
}

//prewritten code: https://github.com/antma/algo
module Solution;
import std.algorithm;
import std.array;
import std.conv;
import std.functional;
import std.math;
import std.range;
import std.stdio;
import std.string;
import std.traits;
import std.bitmanip;
import core.bitop;
import std.exception;

final class InputReader {
  private:
  ubyte[] p, buffer;
  bool eof;
  bool rawRead () {
    if (eof) {
      return false;
    }
    p = stdin.rawRead (buffer);
    if (p.empty) {
      eof = true;
      return false;
    }
    return true;
  }
  ubyte nextByte(bool check) () {
    static if (check) {
      if (p.empty) {
        if (!rawRead ()) {
          return 0;
        }
      }
    }
    auto r = p.front;
    p.popFront ();
    return r;
  }
  public:
  this () {
    buffer = uninitializedArray!(ubyte[])(16<<20);
  }
  bool seekByte (in ubyte lo) {
    while (true) {
      p = p.find! (c => c >= lo);
      if (!p.empty) {
        return false;
      }
      if (!rawRead ()) {
        return true;
      }
    }
  }
  template next(T) if (isSigned!T) {
    T next ()  {
      if (seekByte (45)) {
        return 0;
      }
      T res;
      ubyte b = nextByte!false ();
      if (b == 45) {
        while (true) {
          b = nextByte!true ();
          if (b < 48 || b >= 58) {
            return res;
          }
          res = res * 10 - (b - 48);
        }
      } else {
        res = b - 48;
        while (true) {
          b = nextByte!true ();
          if (b < 48 || b >= 58) {
            return res;
          }
          res = res * 10 + (b - 48);
        }
      }
    }
  }
  template next(T) if (isUnsigned!T) {
    T next () {
      if (seekByte (48)) {
        return 0;
      }
      T res = nextByte!false () - 48;
      while (true) {
        ubyte b = nextByte!true ();
        if (b < 48 || b >= 58) {
          break;
        }
        res = res * 10 + (b - 48);
      }
      return res;
    }
  }
  T[] nextA(T) (in int n) {
    auto a = uninitializedArray!(T[]) (n);
    foreach (i; 0 .. n) {
      a[i] = next!T;
    }
    return a;
  }
}

alias MoResult = int;

struct MoQuery {
  int u, v;//inclusive
  MoResult res;
}

abstract class MoState {
  public:
  @property
  abstract bool fastReset () const;
  abstract void reset ();
  //[l, r)
  abstract void add (int l, int r);
  abstract void del (int l, int r);
  abstract MoResult result () const;
}

struct MoRange {
  int l, r;
  bool fastReset;
  static immutable hilbertDirs = [3, 0, 0, 1];
  static long hilbert (int x, int y, int k, int a) {
    if (k < 0) return 0L;
    int m = 1 << k, o = 3 & (((x >> k) ^ 3 * (y >> k)) + a);
    long ss = 1L << (2 * k), b = hilbert (x & ~m, y & ~m, k - 1, a + hilbertDirs[o]);
    return ss * o + (o == 1 || o == 2 ? b : (ss - (b + 1)));
  }
  void move (MoState s, ref MoQuery q) {
    if (l > r || (fastReset && (l > q.v || r < q.u))) {
      l = q.u;
      r = l - 1;
      s.reset ();
    }
    if (r < q.v) {
      s.add (r + 1, q.v + 1);
      r = q.v;
    } else if (r > q.v) {
      s.del (q.v + 1, r + 1);
      r = q.v;
    }
    if (l > q.u) {
      s.add (q.u, l);
      l = q.u;
    } else if (l < q.u) {
      s.del (l, q.u);
      l = q.u;
    }
    q.res = s.result ();
  }
  void processQueries (MoState s, MoQuery[] queries) {
    l = 0;
    r = -1;
    fastReset = s.fastReset;
    auto nq = queries.length;
    auto n = reduce!max(queries.map!(t => t.v));
    debug stderr.writeln ("n = ", n);
    auto t = bsr (n + 1);
    auto x = queries.map!(q => hilbert (q.u, q.v, t, 0)).array;
    auto idx = uninitializedArray!(size_t[]) (nq);
    makeIndex (x, idx);
    x = null;
    foreach (j; idx) {
      move (s, queries[j]);
    }
  }
}

final class EState : MoState {
  private:
  uint[] x;
  int[] ba;
  int sz;
  public:
  @property
  override bool fastReset () const {
    return false;
  }
  override void reset () {
    ba[] = 0;
    sz = 0;
  }
  //[l, r)
  override void add (int l, int r) {
    foreach (k; x[l .. r]) {
      if (++ba[k] == 1) ++sz;
    }
  }
  override void del (int l, int r) {
    foreach (k; x[l .. r]) {
      if (!--ba[k]) --sz;
    }
  }
  override MoResult result () const {
    return sz;
  }
  this (uint[] x, int n) {
    this.x = x;
    ba = new int[n];
  }
}

void test (in int n, uint[] a) {
  debug stderr.writeln ("a = ", a);
  auto v = new int[n];
  foreach (i; 0 .. n) {
    v[i] = i;
  }
  auto prev = uninitializedArray!(int[]) (n);

  MoQuery[] q;

  prev[] = -1;
  foreach (i, j; a) {
    immutable int pos = i.to!int;
    if (prev[j] >= 0) {
      q ~= MoQuery (prev[j] + 1, i.to!int - 1);
    }
    prev[j] = pos;
  }
  foreach (i; 0 .. n) {
    q ~= MoQuery (prev[i] + 1, a.length.to!int - 1);
  }

  auto state = new EState (a, n);
  MoRange rng;
  rng.processQueries (state, q);
  state = null;

  int cur;
  prev[] = -1;
  foreach (i, j; a) {
    immutable int pos = i.to!int;
    if (prev[j] >= 0) {
      auto k = q[cur++].res;
      v[j] = max (v[j], k);
    }
    prev[j] = pos;
  }

  foreach (i; 0 .. n) {
    auto k = q[cur++].res;
    v[i] = max (v[i], k);
  }

  q = null;

  foreach (i; 0 .. n) {
    int j = v[i];
    int u = i;
    if (prev[i] >= n) {
      u = 0;
    }
    writeln (u + 1, ' ', j + 1);
  }
}

void main() {
  auto r = new InputReader ();
  immutable n = r.next!uint;
  immutable m = r.next!uint;
  auto a = uninitializedArray!(uint[]) (n + m);
  foreach (i; 0 .. n) a[i] = n - 1 - i;
  foreach (i; 0 .. m) a[n+i] = r.next!uint - 1;
  a.length -= uniq (a).copy (a).length;
  test (n, a);
}

//prewritten code: https://github.com/antma/algo
import std.algorithm;
import std.array;
import std.conv;
import std.functional;
import std.math;
import std.range;
import std.stdio;
import std.string;
import std.traits;
import std.bitmanip;
import core.bitop;

final class SegmentTree(T = int, alias op="a+b", T zero) {
  private:
  T [] t;
  size_t n;
  void build () {
    foreach_reverse (i; 1 .. n) {
      immutable k = i << 1;
      t[i] = binaryFun!op (t[k], t[k+1]);
    }
  }
  public:
  void update (size_t p, T v) {
    for (t[p += n] = v; p > 1; p >>= 1) {
      t[p>>1] = binaryFun!op (t[p], t[p ^ 1]);
    }
  }
  T reduce (size_t l, size_t r) {
    T res = zero;
    for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
      if (l & 1) {
        res = binaryFun!op (res, t[l++]);
      }
      if (r & 1) {
        res = binaryFun!op (t[--r], res);
      }
    }
    return res;
  }
  this (T[] a) {
    n = a.length;
    t = uninitializedArray!(T[])(n);
    t ~= a;
    build ();
  }
}

final class InputReader {
  private:
  ubyte[] p, buffer;
  bool eof;
  bool rawRead () {
    if (eof) {
      return false;
    }
    p = stdin.rawRead (buffer);
    if (p.empty) {
      eof = true;
      return false;
    }
    return true;
  }
  ubyte nextByte(bool check) () {
    static if (check) {
      if (p.empty) {
        if (!rawRead ()) {
          return 0;
        }
      }
    }
    auto r = p.front;
    p.popFront ();
    return r;
  }
  public:
  this () {
    buffer = uninitializedArray!(ubyte[])(16<<20);
  }
  bool seekByte (in ubyte lo) {
    while (true) {
      p = p.find! (c => c >= lo);
      if (!p.empty) {
        return false;
      }
      if (!rawRead ()) {
        return true;
      }
    }
  }
  template next(T) if (isSigned!T) {
    T next ()  {
      if (seekByte (45)) {
        return 0;
      }
      T res;
      ubyte b = nextByte!false ();
      if (b == 45) {
        while (true) {
          b = nextByte!true ();
          if (b < 48 || b >= 58) {
            return res;
          }
          res = res * 10 - (b - 48);
        }
      } else {
        res = b - 48;
        while (true) {
          b = nextByte!true ();
          if (b < 48 || b >= 58) {
            return res;
          }
          res = res * 10 + (b - 48);
        }
      }
    }
  }
  template next(T) if (isUnsigned!T) {
    T next () {
      if (seekByte (48)) {
        return 0;
      }
      T res = nextByte!false () - 48;
      while (true) {
        ubyte b = nextByte!true ();
        if (b < 48 || b >= 58) {
          break;
        }
        res = res * 10 + (b - 48);
      }
      return res;
    }
  }
  T[] nextA(T) (in int n) {
    auto a = uninitializedArray!(T[]) (n);
    foreach (i; 0 .. n) {
      a[i] = next!T;
    }
    return a;
  }
}

uint[] mrg (uint[] a, uint[] b) {
  return merge (a, b).uniq.array;
}

struct MoQuery {
  int u;
  int v;
}

alias R = int;
final class MoRange {
  private:
  immutable uint[] x;
  int l, r;
  //CUSTOM
  BitArray ba;
  int sz;

  static long hilbert (int x, int y, int k, int a) {
    static immutable d = [3, 0, 0, 1];
    if (k < 0) return 0L;
    int m = 1 << k, o = 3 & (((x >> k) ^ 3 * (y >> k)) + a);
    long ss = 1L << (2 * k), b = hilbert (x & ~m, y & ~m, k - 1, a + d[o]);
    return ss * o + (o == 1 || o == 2 ? b : (ss - (b + 1)));
  }

  void clear () {
    //CUSTOM
    ba[] = false;
    sz = 0;
  }

  R move (ref in MoQuery q) {
    if (l > r || l > q.v || r < q.u) {
      l = q.u;
      r = l - 1;
      clear ();
    }
    if (r < q.v) {
      add (r + 1, q.v + 1);
      r = q.v;
    } else if (r > q.v) {
      del (q.v + 1, r + 1);
      r = q.v;
    }
    if (l > q.u) {
      add (q.u, l);
      l = q.u;
    } else if (l < q.u) {
      del (l, q.u);
      l = q.u;
    }
    //CUSTOM
    return sz;
  }
  void add (const int a, const int b) {
    debug stderr.writefln ("add (%d, %d)", a, b);
    foreach (k; x[a .. b]) {
      if (!ba[k]) {
        ba[k] = true;
        ++sz;
      }
    }
  }
  void del (const int a, const int b) {
    foreach (k; x[a .. b]) {
      //assert (freq[k] > 0, format!"freq[%d] = %d" (k, freq[k]));
      if (ba[k]) {
        ba[k] = false;
        --sz;
      }
    }
  }
  int[] processQueries (in MoQuery[] queries) {
    l = 0;
    r = -1;
    auto nq = queries.length;
    auto n = reduce!max(queries.map!(t => t.v));
    auto s = bsr (n);
    auto x = queries.map!(q => hilbert (q.u, q.v, s, 0)).array;
    auto idx = uninitializedArray!(size_t[]) (nq);
    makeIndex (x, idx);
    auto res = uninitializedArray!(R[]) (nq);
    foreach (j; idx) {
      if (queries[j].u > queries[j].v) res[j] = 0;
      else res[j] = move (queries[j]);
    }
    return res;
  }
  this (in uint[] a, int n) {
    x = a.idup;
    //CUSTOM
    ba.length = n;
  }
}

alias ST = SegmentTree!(uint[], mrg, []);

void test (in int n, uint[] a) {
  debug stderr.writeln ("a = ", a);
  auto v = new int[n];
  foreach (i; 0 .. n) {
    v[i] = i;
  }
  auto prev = uninitializedArray!(int[]) (n);

  MoQuery[] q;

  prev[] = -1;
  foreach (i, j; a) {
    immutable int pos = i.to!int;
    if (prev[j] >= 0) {
      q ~= MoQuery (prev[j] + 1, i.to!int - 1);
    }
    prev[j] = pos;
  }
  foreach (i; 0 .. n) {
    q ~= MoQuery (prev[i] + 1, a.length.to!int - 1);
  }

  auto solve = new MoRange (a, n);
  auto res = solve.processQueries (q);

  int cur;
  prev[] = -1;
  foreach (i, j; a) {
    immutable int pos = i.to!int;
    if (prev[j] >= 0) {
      auto k = res[cur++];
      v[j] = max (v[j], k);
    }
    prev[j] = pos;
  }
  foreach (i; 0 .. n) {
    auto k = res[cur++];
    v[i] = max (v[i], k);
  }

  foreach (i; 0 .. n) {
    int j = v[i];
    int u = i;
    if (prev[i] >= n) {
      u = 0;
    }
    writeln (u + 1, ' ', j + 1);
  }
}

void main() {
  auto r = new InputReader ();
  immutable n = r.next!uint;
  immutable m = r.next!uint;
  auto a = r.nextA!uint (m);
  foreach (i; 0 .. m) --a[i];
  auto b = new uint[n];
  foreach (i; 0 .. n) b[i] = n - 1 - i;
  b ~= a;
  a = b;
  b = null;
  //a.length -= uniq (a).copy (a).length;
  test (n, a);
}

//prewritten code: https://github.com/antma/algo
import std.algorithm;
import std.array;
import std.conv;
import std.functional;
import std.math;
import std.range;
import std.stdio;
import std.string;
import std.traits;
import std.bitmanip;
import core.bitop;

final class SegmentTree(T = int, alias op="a+b", T zero) {
  private:
  T [] t;
  size_t n;
  void build () {
    foreach_reverse (i; 1 .. n) {
      immutable k = i << 1;
      t[i] = binaryFun!op (t[k], t[k+1]);
    }
  }
  public:
  void update (size_t p, T v) {
    for (t[p += n] = v; p > 1; p >>= 1) {
      t[p>>1] = binaryFun!op (t[p], t[p ^ 1]);
    }
  }
  T reduce (size_t l, size_t r) {
    T res = zero;
    for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
      if (l & 1) {
        res = binaryFun!op (res, t[l++]);
      }
      if (r & 1) {
        res = binaryFun!op (t[--r], res);
      }
    }
    return res;
  }
  this (T[] a) {
    n = a.length;
    t = uninitializedArray!(T[])(n);
    t ~= a;
    build ();
  }
}

final class InputReader {
  private:
  ubyte[] p, buffer;
  bool eof;
  bool rawRead () {
    if (eof) {
      return false;
    }
    p = stdin.rawRead (buffer);
    if (p.empty) {
      eof = true;
      return false;
    }
    return true;
  }
  ubyte nextByte(bool check) () {
    static if (check) {
      if (p.empty) {
        if (!rawRead ()) {
          return 0;
        }
      }
    }
    auto r = p.front;
    p.popFront ();
    return r;
  }
  public:
  this () {
    buffer = uninitializedArray!(ubyte[])(16<<20);
  }
  bool seekByte (in ubyte lo) {
    while (true) {
      p = p.find! (c => c >= lo);
      if (!p.empty) {
        return false;
      }
      if (!rawRead ()) {
        return true;
      }
    }
  }
  template next(T) if (isSigned!T) {
    T next ()  {
      if (seekByte (45)) {
        return 0;
      }
      T res;
      ubyte b = nextByte!false ();
      if (b == 45) {
        while (true) {
          b = nextByte!true ();
          if (b < 48 || b >= 58) {
            return res;
          }
          res = res * 10 - (b - 48);
        }
      } else {
        res = b - 48;
        while (true) {
          b = nextByte!true ();
          if (b < 48 || b >= 58) {
            return res;
          }
          res = res * 10 + (b - 48);
        }
      }
    }
  }
  template next(T) if (isUnsigned!T) {
    T next () {
      if (seekByte (48)) {
        return 0;
      }
      T res = nextByte!false () - 48;
      while (true) {
        ubyte b = nextByte!true ();
        if (b < 48 || b >= 58) {
          break;
        }
        res = res * 10 + (b - 48);
      }
      return res;
    }
  }
  T[] nextA(T) (in int n) {
    auto a = uninitializedArray!(T[]) (n);
    foreach (i; 0 .. n) {
      a[i] = next!T;
    }
    return a;
  }
}

uint[] mrg (uint[] a, uint[] b) {
  return merge (a, b).uniq.array;
}

struct MoQuery {
  int u;
  int v;
}

alias R = int;
final class MoRange {
  private:
  immutable uint[] x;
  int l, r;
  //CUSTOM
  BitArray ba;
  int sz;

  static long hilbert (int x, int y, int k, int a) {
    static immutable d = [3, 0, 0, 1];
    if (k < 0) return 0L;
    int m = 1 << k, o = 3 & (((x >> k) ^ 3 * (y >> k)) + a);
    long ss = 1L << (2 * k), b = hilbert (x & ~m, y & ~m, k - 1, a + d[o]);
    return ss * o + (o == 1 || o == 2 ? b : (ss - (b + 1)));
  }

  void clear () {
    //CUSTOM
    ba[] = false;
    sz = 0;
  }

  R move (ref in MoQuery q) {
    if (l > r || l > q.v || r < q.u) {
      l = q.u;
      r = l - 1;
      clear ();
    }
    if (r < q.v) {
      add (r + 1, q.v + 1);
      r = q.v;
    } else if (r > q.v) {
      del (q.v + 1, r + 1);
      r = q.v;
    }
    if (l > q.u) {
      add (q.u, l);
      l = q.u;
    } else if (l < q.u) {
      del (l, q.u);
      l = q.u;
    }
    //CUSTOM
    return sz;
  }
  void add (const int a, const int b) {
    debug stderr.writefln ("add (%d, %d)", a, b);
    foreach (k; x[a .. b]) {
      if (!ba[k]) {
        ba[k] = true;
        ++sz;
      }
    }
  }
  void del (const int a, const int b) {
    foreach (k; x[a .. b]) {
      //assert (freq[k] > 0, format!"freq[%d] = %d" (k, freq[k]));
      if (ba[k]) {
        ba[k] = false;
        --sz;
      }
    }
  }
  int[] processQueries (in MoQuery[] queries) {
    l = 0;
    r = -1;
    auto nq = queries.length;
    auto n = reduce!max(queries.map!(t => t.v));
    auto s = bsr (n);
    auto x = queries.map!(q => hilbert (q.u, q.v, s, 0)).array;
    auto idx = uninitializedArray!(size_t[]) (nq);
    makeIndex (x, idx);
    auto res = uninitializedArray!(R[]) (nq);
    foreach (j; idx) {
      if (queries[j].u > queries[j].v) res[j] = 0;
      else res[j] = move (queries[j]);
    }
    return res;
  }
  this (in uint[] a, int n) {
    x = a.idup;
    //CUSTOM
    ba.length = n;
  }
}

alias ST = SegmentTree!(uint[], mrg, []);

void test (in int n, uint[] a) {
  debug stderr.writeln ("a = ", a);
  auto v = new int[n];
  foreach (i; 0 .. n) {
    v[i] = i;
  }
  auto prev = uninitializedArray!(int[]) (n);

  MoQuery[] q;

  prev[] = -1;
  foreach (i, j; a) {
    immutable int pos = i.to!int;
    if (prev[j] >= 0) {
      q ~= MoQuery (prev[j] + 1, i.to!int - 1);
    }
    prev[j] = pos;
  }
  foreach (i; 0 .. n) {
    q ~= MoQuery (prev[i] + 1, a.length.to!int - 1);
  }

  auto solve = new MoRange (a, n);
  auto res = solve.processQueries (q);

  int cur;
  prev[] = -1;
  foreach (i, j; a) {
    immutable int pos = i.to!int;
    if (prev[j] >= 0) {
      auto k = res[cur++];
      v[j] = max (v[j], k);
    }
    prev[j] = pos;
  }
  foreach (i; 0 .. n) {
    auto k = res[cur++];
    v[i] = max (v[i], k);
  }

  foreach (i; 0 .. n) {
    int j = v[i];
    int u = i;
    if (prev[i] >= n) {
      u = 0;
    }
    writeln (u + 1, ' ', j + 1);
  }
}

void main() {
  auto r = new InputReader ();
  immutable n = r.next!uint;
  immutable m = r.next!uint;
  auto a = r.nextA!uint (m);
  foreach (i; 0 .. m) --a[i];
  auto b = new uint[n];
  foreach (i; 0 .. n) b[i] = n - 1 - i;
  b ~= a;
  a = b;
  b = null;
  a.length -= uniq (a).copy (a).length;
  test (n, a);
}

//prewritten code: https://github.com/antma/algo
import std.algorithm;
import std.array;
import std.conv;
import std.functional;
import std.math;
import std.range;
import std.stdio;
import std.string;
import std.traits;
import std.bitmanip;
import core.bitop;

final class SegmentTree(T = int, alias op="a+b", T zero) {
  private:
  T [] t;
  size_t n;
  void build () {
    foreach_reverse (i; 1 .. n) {
      immutable k = i << 1;
      t[i] = binaryFun!op (t[k], t[k+1]);
    }
  }
  public:
  void update (size_t p, T v) {
    for (t[p += n] = v; p > 1; p >>= 1) {
      t[p>>1] = binaryFun!op (t[p], t[p ^ 1]);
    }
  }
  T reduce (size_t l, size_t r) {
    T res = zero;
    for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
      if (l & 1) {
        res = binaryFun!op (res, t[l++]);
      }
      if (r & 1) {
        res = binaryFun!op (t[--r], res);
      }
    }
    return res;
  }
  this (T[] a) {
    n = a.length;
    t = uninitializedArray!(T[])(n);
    t ~= a;
    build ();
  }
}

final class InputReader {
  private:
  ubyte[] p, buffer;
  bool eof;
  bool rawRead () {
    if (eof) {
      return false;
    }
    p = stdin.rawRead (buffer);
    if (p.empty) {
      eof = true;
      return false;
    }
    return true;
  }
  ubyte nextByte(bool check) () {
    static if (check) {
      if (p.empty) {
        if (!rawRead ()) {
          return 0;
        }
      }
    }
    auto r = p.front;
    p.popFront ();
    return r;
  }
  public:
  this () {
    buffer = uninitializedArray!(ubyte[])(16<<20);
  }
  bool seekByte (in ubyte lo) {
    while (true) {
      p = p.find! (c => c >= lo);
      if (!p.empty) {
        return false;
      }
      if (!rawRead ()) {
        return true;
      }
    }
  }
  template next(T) if (isSigned!T) {
    T next ()  {
      if (seekByte (45)) {
        return 0;
      }
      T res;
      ubyte b = nextByte!false ();
      if (b == 45) {
        while (true) {
          b = nextByte!true ();
          if (b < 48 || b >= 58) {
            return res;
          }
          res = res * 10 - (b - 48);
        }
      } else {
        res = b - 48;
        while (true) {
          b = nextByte!true ();
          if (b < 48 || b >= 58) {
            return res;
          }
          res = res * 10 + (b - 48);
        }
      }
    }
  }
  template next(T) if (isUnsigned!T) {
    T next () {
      if (seekByte (48)) {
        return 0;
      }
      T res = nextByte!false () - 48;
      while (true) {
        ubyte b = nextByte!true ();
        if (b < 48 || b >= 58) {
          break;
        }
        res = res * 10 + (b - 48);
      }
      return res;
    }
  }
  T[] nextA(T) (in int n) {
    auto a = uninitializedArray!(T[]) (n);
    foreach (i; 0 .. n) {
      a[i] = next!T;
    }
    return a;
  }
}

uint[] mrg (uint[] a, uint[] b) {
  return merge (a, b).uniq.array;
}

struct MoQuery {
  int u;
  int v;
}

alias R = int;
final class MoRange {
  private:
  immutable uint[] x;
  int l, r;
  //CUSTOM
  BitArray ba;
  int sz;

  static long hilbert (int x, int y, int k, int a) {
    static immutable d = [3, 0, 0, 1];
    if (k < 0) return 0L;
    int m = 1 << k, o = 3 & (((x >> k) ^ 3 * (y >> k)) + a);
    long ss = 1L << (2 * k), b = hilbert (x & ~m, y & ~m, k - 1, a + d[o]);
    return ss * o + (o == 1 || o == 2 ? b : (ss - (b + 1)));
  }

  void clear () {
    //CUSTOM
    ba[] = false;
    sz = 0;
  }

  R move (ref in MoQuery q) {
    if (l > r || l > q.v || r < q.u) {
      l = q.u;
      r = l - 1;
      clear ();
    }
    if (r < q.v) {
      add (r + 1, q.v + 1);
      r = q.v;
    } else if (r > q.v) {
      del (q.v + 1, r + 1);
      r = q.v;
    }
    if (l > q.u) {
      add (q.u, l);
      l = q.u;
    } else if (l < q.u) {
      del (l, q.u);
      l = q.u;
    }
    //CUSTOM
    return sz;
  }
  void add (const int a, const int b) {
    debug stderr.writefln ("add (%d, %d)", a, b);
    foreach (k; x[a .. b]) {
      if (!ba[k]) {
        ba[k] = true;
        ++sz;
      }
    }
  }
  void del (const int a, const int b) {
    foreach (k; x[a .. b]) {
      //assert (freq[k] > 0, format!"freq[%d] = %d" (k, freq[k]));
      if (ba[k]) {
        ba[k] = false;
        --sz;
      }
    }
  }
  int[] processQueries (in MoQuery[] queries) {
    l = 0;
    r = -1;
    auto nq = queries.length;
    auto n = reduce!max(queries.map!(t => t.v));
    auto s = bsr (n);
    auto x = queries.map!(q => hilbert (q.u, q.v, s, 0)).array;
    auto idx = uninitializedArray!(size_t[]) (nq);
    makeIndex (x, idx);
    auto res = uninitializedArray!(R[]) (nq);
    foreach (j; idx) {
      res[j] = move (queries[j]);
    }
    return res;
  }
  this (in uint[] a, int n) {
    x = a.idup;
    //CUSTOM
    ba.length = n;
  }
}

alias ST = SegmentTree!(uint[], mrg, []);

void test (in int n, uint[] a) {
  debug stderr.writeln ("a = ", a);
  auto v = new int[n];
  foreach (i; 0 .. n) {
    v[i] = i;
  }
  auto prev = uninitializedArray!(int[]) (n);

  MoQuery[] q;

  prev[] = -1;
  foreach (i, j; a) {
    immutable int pos = i.to!int;
    if (prev[j] >= 0) {
      q ~= MoQuery (prev[j] + 1, i.to!int - 1);
    }
    prev[j] = pos;
  }
  foreach (i; 0 .. n) {
    q ~= MoQuery (prev[i] + 1, a.length.to!int - 1);
  }

  auto solve = new MoRange (a, n);
  auto res = solve.processQueries (q);

  int cur;
  prev[] = -1;
  foreach (i, j; a) {
    immutable int pos = i.to!int;
    if (prev[j] >= 0) {
      auto k = res[cur++];
      v[j] = max (v[j], k);
    }
    prev[j] = pos;
  }
  foreach (i; 0 .. n) {
    auto k = res[cur++];
    v[i] = max (v[i], k);
  }

  foreach (i; 0 .. n) {
    int j = v[i];
    int u = i;
    if (prev[i] >= n) {
      u = 0;
    }
    writeln (u + 1, ' ', j + 1);
  }
}

void main() {
  auto r = new InputReader ();
  immutable n = r.next!uint;
  immutable m = r.next!uint;
  auto a = r.nextA!uint (m);
  foreach (i; 0 .. m) --a[i];
  auto b = new uint[n];
  foreach (i; 0 .. n) b[i] = n - 1 - i;
  b ~= a;
  a = b;
  b = null;
  a.length -= uniq (a).copy (a).length;
  test (n, a);
}


Codeforces user' handle color depends on his rating — it is red if his rating is greater or equal to 2400; it is orange if his rating is less than 2400 but greater or equal to 2200, etc. Each time participant takes part in a rated contest, his rating is changed depending on his performance.Anton wants the color of his handle to become red. He considers his performance in the rated contest to be good if he outscored some participant, whose handle was colored red before the contest and his rating has increased after it.Anton has written a program that analyses contest results and determines whether he performed good or not. Are you able to do the same?

The first line of the input contains a single integer n (1 ≤ n ≤ 100) — the number of participants Anton has outscored in this contest . The next n lines describe participants results: the i-th of them consists of a participant handle namei and two integers beforei and afteri ( - 4000 ≤ beforei, afteri ≤ 4000) — participant's rating before and after the contest, respectively. Each handle is a non-empty string, consisting of no more than 10 characters, which might be lowercase and uppercase English letters, digits, characters «_» and «-» characters. It is guaranteed that all handles are distinct.

Print «YES» (quotes for clarity), if Anton has performed good in the contest and «NO» (quotes for clarity) otherwise.

3
Burunduk1 2526 2537
BudAlNik 2084 2214
subscriber 2833 2749

3
Applejack 2400 2400
Fluttershy 2390 2431
Pinkie_Pie -2500 -2450

NoteIn the first sample, Anton has outscored user with handle Burunduk1, whose handle was colored red before the contest and his rating has increased after the contest.In the second sample, Applejack's rating has not increased after the contest, while both Fluttershy's and Pinkie_Pie's handles were not colored red before the contest.

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

struct IO {
        string read_string() {
                while (tokens.empty) {
                tokens = readln.split;
        }
        auto token = tokens.front;
                tokens.popFront;
                return token;
        }

        int read_int() {
                return read_string.to!int;
        }

        string[] tokens;
}

void main() {
        IO cin;
        int t = 1;
        // int t = cin.read_int;
        while (t--) {
                int n = cin.read_int;
                bool done = false;
                while (n--) {
                        string name = cin.read_string;
                        int prev_rating = cin.read_int;
                        int new_rating = cin.read_int;
                        if (prev_rating >= 2400 && new_rating > prev_rating) done = true;
                }
                if (done) writeln("YES");
                else writeln("NO");
        }
}

#!/usr/bin/env rdmd

import std.stdio;

void main() {
    int n;
    char buffer[10];
    while (readf("%d ", &n) == 1) {
        bool ok = false;
        while (n--) {
            auto s = buffer[ ];
            int before, after;
            readf("%s %d %d ", &s, &before, &after);
            if (after > before && before >= 2400)
            ok = true;
        }
        writeln(ok ? "YES" : "NO");
    }
}

//ahmat
import core.stdc.stdio:scanf,printf,puts;
import core.bitop;
import std.stdio;
import std.string;
import std.algorithm;
import std.functional;
import std.array;
import std.container;
import std.conv;
import std.container;
import std.typecons;
import std.math;
import std.numeric;
pragma(inline,true);

void main(){
    int n=readln.chomp
                .to!int;
    int a,b;
    string s;
    bool r=false;
    while(n--){
        readf!"%s %d %d"(s,a,b);
        readln;
        if(a>=2400 && b>a){
            r=true;
            break;
        }
    }
    writeln(r?"YES":"NO");
}