After the war, the supersonic rocket became the most common public transportation.Each supersonic rocket consists of two "engines". Each engine is a set of "power sources". The first engine has $$$n$$$ power sources, and the second one has $$$m$$$ power sources. A power source can be described as a point $$$(x_i, y_i)$$$ on a 2-D plane. All points in each engine are different.You can manipulate each engine separately. There are two operations that you can do with each engine. You can do each operation as many times as you want. For every power source as a whole in that engine: $$$(x_i, y_i)$$$ becomes $$$(x_i+a, y_i+b)$$$, $$$a$$$ and $$$b$$$ can be any real numbers. In other words, all power sources will be shifted. For every power source as a whole in that engine: $$$(x_i, y_i)$$$ becomes $$$(x_i \cos \theta - y_i \sin \theta, x_i \sin \theta + y_i \cos \theta)$$$, $$$\theta$$$ can be any real number. In other words, all power sources will be rotated.The engines work as follows: after the two engines are powered, their power sources are being combined (here power sources of different engines may coincide). If two power sources $$$A(x_a, y_a)$$$ and $$$B(x_b, y_b)$$$ exist, then for all real number $$$k$$$ that $$$0 \lt k \lt 1$$$, a new power source will be created $$$C_k(kx_a+(1-k)x_b,ky_a+(1-k)y_b)$$$. Then, this procedure will be repeated again with all new and old power sources. After that, the "power field" from all power sources will be generated (can be considered as an infinite set of all power sources occurred).A supersonic rocket is "safe" if and only if after you manipulate the engines, destroying any power source and then power the engine, the power field generated won't be changed (comparing to the situation where no power source erased). Two power fields are considered the same if and only if any power source in one field belongs to the other one as well.Given a supersonic rocket, check whether it is safe or not.

The first line contains two integers $$$n$$$, $$$m$$$ ($$$3 \le n, m \le 10^5$$$) — the number of power sources in each engine. Each of the next $$$n$$$ lines contains two integers $$$x_i$$$ and $$$y_i$$$ ($$$0\leq x_i, y_i\leq 10^8$$$) — the coordinates of the $$$i$$$-th power source in the first engine. Each of the next $$$m$$$ lines contains two integers $$$x_i$$$ and $$$y_i$$$ ($$$0\leq x_i, y_i\leq 10^8$$$) — the coordinates of the $$$i$$$-th power source in the second engine. It is guaranteed that there are no two or more power sources that are located in the same point in each engine.

Print "YES" if the supersonic rocket is safe, otherwise "NO". You can print each letter in an arbitrary case (upper or lower).

NoteThe first sample:    Those near pairs of blue and orange points actually coincide. First, manipulate the first engine: use the second operation with $$$\theta = \pi$$$ (to rotate all power sources $$$180$$$ degrees).The power sources in the first engine become $$$(0, 0)$$$, $$$(0, -2)$$$, and $$$(-2, 0)$$$.  Second, manipulate the second engine: use the first operation with $$$a = b = -2$$$.The power sources in the second engine become $$$(-2, 0)$$$, $$$(0, 0)$$$, $$$(0, -2)$$$, and $$$(-1, -1)$$$.  You can examine that destroying any point, the power field formed by the two engines are always the solid triangle $$$(0, 0)$$$, $$$(-2, 0)$$$, $$$(0, -2)$$$.In the second sample, no matter how you manipulate the engines, there always exists a power source in the second engine that power field will shrink if you destroy it.

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

struct Point
{
	int x;
	int y;

	auto opCmp () (const auto ref Point that)
	{
		if (this.x != that.x)
		{
			return this.x - that.x;
		}
		return this.y - that.y;
	}

	Point opBinary (string op) (const auto ref Point that)
	    if (op == "+" || op == "-")
	{
		Point res;
		res.x = mixin ("this.x " ~ op ~ " that.x");
		res.y = mixin ("this.y " ~ op ~ " that.y");
		return res;
	}

	ref Point opOpAssign (string op) (const auto ref Point that)
	    if (op == "+" || op == "-")
	{
		mixin ("this.x " ~ op ~ "= that.x;");
		mixin ("this.y " ~ op ~ "= that.y;");
		return this;
	}
}

auto vp () (const auto ref Point a, const auto ref Point b)
{
	return a.x * 1L * b.y - a.y * 1L * b.x;
}

auto sp () (const auto ref Point a, const auto ref Point b)
{
	return a.x * 1L * b.x + a.y * 1L * b.y;
}

auto norm2 () (const auto ref Point a)
{
	return a.x * 1L * a.x + a.y * 1L * a.y;
}

Point [] getConvexHull (Point [] p)
{
	auto s = p.minElement;

	auto q = p.filter !(c => c != s).array;
	foreach (ref c; q)
	{
		c -= s;
	}

	q.sort !((a, b) => vp (a, b) < 0 ||
	    (vp (a, b) == 0 && norm2 (a) < norm2 (b)));

	Point [] res;
	res ~= Point (0, 0);
	res ~= q.front;
	q.popFront ();
	foreach (ref c; q)
	{
		while (res.length > 1 && vp (res[$ - 1] - res[$ - 2],
		    c - res[$ - 2]) >= 0)
		{
			res.length -= 1;
		}
		res.assumeSafeAppend ();
		res ~= c;
	}

	debug {writeln (res);}
	foreach (ref c; q)
	{
		c += s;
	}
	return res;
}

alias Record = Tuple !(long, q{sp}, long, q{norm2});

Record [] getSignature (Point [] p)
{
	auto h = getConvexHull (p);
	Record [] res;
	auto n = h.length;
	foreach (i; 0..n)
	{
		auto j = i + 1;
		if (j >= n)
		{
			j -= n;
		}
		auto k = j + 1;
		if (k >= n)
		{
			k -= n;
		}
		res ~= Record (sp (h[j] - h[i], h[k] - h[i]),
		    norm2 (h[j] - h[i]));
	}
	debug {writeln (res);}
	return res;
}

auto getPrefixFunction (R) (R r)
    if (isRandomAccessRange !(R))
{
	int [] p;
	p ~= -1;
	int k = -1;
	foreach (c; r)
	{
		while (k >= 0 && c != r[k])
		{
			k = p[k];
		}
		k += 1;
		p ~= k;
	}
	return p;
}

unittest
{
	assert (getPrefixFunction ("abacaba".representation) ==
	    [-1, 0, 0, 1, 0, 1, 2, 3]);
}

void main ()
{
	int n, m;
	while (readf (" %s %s", &n, &m) > 0)
	{
		auto p = new Point [n];
		foreach (ref c; p)
		{
			readf (" %s %s", &c.x, &c.y);
		}
		auto q = new Point [m];
		foreach (ref c; q)
		{
			readf (" %s %s", &c.x, &c.y);
		}
		auto sigP = getSignature (p);
		auto sigQ = getSignature (q);
		auto ok = sigP.length == sigQ.length;
		if (ok)
		{
			auto pFun = getPrefixFunction (chain (sigP,
			    only (Record (0, 0)), sigQ, sigQ));
			ok = pFun.maxElement >= sigP.length;
		}
		writeln (ok ? "YES" : "NO");
	}
}

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

struct Point
{
	int x;
	int y;

	auto opCmp () (const auto ref Point that)
	{
		if (this.x != that.x)
		{
			return this.x - that.x;
		}
		return this.y - that.y;
	}

	Point opBinary (string op) (const auto ref Point that)
	    if (op == "+" || op == "-")
	{
		Point res;
		res.x = mixin ("this.x " ~ op ~ " that.x");
		res.y = mixin ("this.y " ~ op ~ " that.y");
		return res;
	}

	ref Point opOpAssign (string op) (const auto ref Point that)
	    if (op == "+" || op == "-")
	{
		mixin ("this.x " ~ op ~ "= that.x;");
		mixin ("this.y " ~ op ~ "= that.y;");
		return this;
	}
}

auto vp () (const auto ref Point a, const auto ref Point b)
{
	return a.x * 1L * b.y - a.y * 1L * b.x;
}

auto norm2 () (const auto ref Point a)
{
	return a.x * 1L * a.x + a.y * 1L * a.y;
}

Point [] getConvexHull (Point [] p)
{
	auto s = p.minElement;

	auto q = p.filter !(c => c != s).array;
	foreach (ref c; q)
	{
		c -= s;
	}

	q.sort !((a, b) => vp (a, b) < 0 ||
	    (vp (a, b) == 0 && norm2 (a) < norm2 (b)));

	Point [] res;
	res ~= Point (0, 0);
	res ~= q.front;
	q.popFront ();
	foreach (ref c; q)
	{
		while (res.length > 1 && vp (res[$ - 1] - res[$ - 2],
		    c - res[$ - 2]) >= 0)
		{
			res.length -= 1;
		}
		res.assumeSafeAppend ();
		res ~= c;
	}

	debug {writeln (res);}
	foreach (ref c; q)
	{
		c += s;
	}
	return res;
}

alias Record = Tuple !(long, q{vp}, long, q{norm2});

Record [] getSignature (Point [] p)
{
	auto h = getConvexHull (p);
	Record [] res;
	auto n = h.length;
	foreach (i; 0..n)
	{
		auto j = i + 1;
		if (j >= n)
		{
			j -= n;
		}
		auto k = j + 1;
		if (k >= n)
		{
			k -= n;
		}
		res ~= Record (vp (h[j] - h[i], h[k] - h[i]),
		    norm2 (h[j] - h[i]));
	}
	debug {writeln (res);}
	return res;
}

auto getPrefixFunction (R) (R r)
    if (isRandomAccessRange !(R))
{
	int [] p;
	p ~= -1;
	int k = -1;
	foreach (c; r)
	{
		while (k >= 0 && c != r[k])
		{
			k = p[k];
		}
		k += 1;
		p ~= k;
	}
	return p;
}

unittest
{
	assert (getPrefixFunction ("abacaba".representation) ==
	    [-1, 0, 0, 1, 0, 1, 2, 3]);
}

void main ()
{
	int n, m;
	while (readf (" %s %s", &n, &m) > 0)
	{
		auto p = new Point [n];
		foreach (ref c; p)
		{
			readf (" %s %s", &c.x, &c.y);
		}
		auto q = new Point [m];
		foreach (ref c; q)
		{
			readf (" %s %s", &c.x, &c.y);
		}
		auto sigP = getSignature (p);
		auto sigQ = getSignature (q);
		auto ok = sigP.length == sigQ.length;
		if (ok)
		{
			auto pFun = getPrefixFunction (chain (sigP,
			    only (Record (0, 0)), sigQ, sigQ));
			ok = pFun.maxElement >= sigP.length;
		}
		writeln (ok ? "YES" : "NO");
	}
}

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

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

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

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

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

enum MO = 10^^9 + 403;
alias Mint = ModInt!MO;

struct Point(T) {
  T x, y;
  Pt opBinary(string op)(Pt a) const {
    static if (op == "+") return Pt(x + a.x, y + a.y);
    else static if (op == "-") return Pt(x - a.x, y - a.y);
    else static assert(false);
  }
  Pt opBinary(string op)(T k) const {
    static if (op == "*") return Pt(x * k, y * k);
    else static if (op == "/") return Pt(x / k, y / k);
    else static assert(false);
  }
  T dot(Pt a) const { return x * a.x + y * a.y; }
  T det(Pt a) const { return x * a.y - y * a.x; }
  int opCmp(Pt a) const { return (x < a.x) ? -1 : (x > a.x) ? +1 : (y < a.y) ? -1 : (y > a.y) ? +1 : 0; }
  string toString() const { return "(" ~ x.to!string ~ ", " ~ y.to!string ~ ")"; }
}

alias Pt = Point!long;
long tri(Pt a, Pt b, Pt c) {
  return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
}

Pt[] convexHull(Pt[] ps) {
  auto qs = new Pt[ps.length + 1];
  ps.sort!((a, b) => ((a.x != b.x) ? (a.x < b.x) : (a.y < b.y)));
  int m = 0;
  foreach (p; ps) {
    for (; m > 1 && sgn(tri(qs[m - 2], qs[m - 1], p)) <= 0; --m) {}
    qs[m++] = p;
  }
  const r = m;
  foreach_reverse (p; ps) {
    for (; m > r && sgn(tri(qs[m - 2], qs[m - 1], p)) <= 0; --m) {}
    qs[m++] = p;
  }
  return qs[0 .. m - 1];
}

enum BASES = [20209, 1209, 21479];

void main() {
  try {
    for (; ; ) {
      auto N = new int[2];
      foreach (h; 0 .. 2) {
        N[h] = readInt();
      }
      auto P = new Pt[][2];
      foreach (h; 0 .. 2) {
        P[h] = new Pt[N[h]];
        foreach (i; 0 .. N[h]) {
          P[h][i].x = readLong();
          P[h][i].y = readLong();
        }
      }

      auto seqs = new long[][2];
      foreach (h; 0 .. 2) {
        const qs = convexHull(P[h]);
        const qsLen = cast(int)(qs.length);
        auto edges = new Pt[qsLen];
        foreach (j; 0 .. qsLen) {
          edges[j] = qs[(j + 1) % qsLen] - qs[j];
        }
        foreach (j; 0 .. qsLen) {
          seqs[h] ~= edges[j].dot(edges[j]);
          seqs[h] ~= edges[j].dot(edges[(j + 1) % qsLen]);
        }
        debug {
          writeln("P[h] = ", P);
          writeln("qs = ", qs);
          writeln("seqs[h] = ", seqs[h]);
        }
      }

      bool ans;
      const len = cast(int)(seqs[0].length);
      if (len == seqs[1].length) {
        auto bb = new Mint[][](BASES.length, len + 1);
        foreach (g; 0 .. BASES.length) {
          bb[g][0] = 1;
          foreach (j; 1 .. len + 1) {
            bb[g][j] = bb[g][j - 1] * BASES[g];
          }
        }
        auto ss = new Mint[][][](2, BASES.length, len + 1);
        foreach (h; 0 .. 2) foreach (g; 0 .. BASES.length) {
          foreach (j; 0 .. len) {
            ss[h][g][j + 1] = ss[h][g][j] + bb[g][j] * seqs[h][j];
          }
        }
        debug {
          writeln("ss = ", ss);
        }
        foreach (shift; 0 .. len) {
          if (shift % 2 == 0) {
            bool ok = true;
            foreach (g; 0 .. BASES.length) {
              ok = ok && ((bb[g][shift] * ss[0][g][len]).x == (ss[1][g][len] + (bb[g][len] - 1) * ss[1][g][shift]).x);
            }
            if (ok) {
              debug {
                writeln("shift = ", shift);
              }
              foreach (j; 0 .. len) {
                if (seqs[0][j] != seqs[1][(j + shift) % len]) {
                  ok = false;
                  break;
                }
              }
              if (ok) {
                ans = true;
                break;
              }
            }
          }
        }
      }
      writeln(ans ? "YES" : "NO");
    }
  } catch (EOFException e) {
  }
}

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

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

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

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

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

enum MO = 10^^9 + 403;
alias Mint = ModInt!MO;

struct Point(T) {
  T x, y;
  Pt opBinary(string op)(Pt a) const {
    static if (op == "+") return Pt(x + a.x, y + a.y);
    else static if (op == "-") return Pt(x - a.x, y - a.y);
    else static assert(false);
  }
  Pt opBinary(string op)(T k) const {
    static if (op == "*") return Pt(x * k, y * k);
    else static if (op == "/") return Pt(x / k, y / k);
    else static assert(false);
  }
  T dot(Pt a) const { return x * a.x + y * a.y; }
  T det(Pt a) const { return x * a.y - y * a.x; }
  int opCmp(Pt a) const { return (x < a.x) ? -1 : (x > a.x) ? +1 : (y < a.y) ? -1 : (y > a.y) ? +1 : 0; }
  string toString() const { return "(" ~ x.to!string ~ ", " ~ y.to!string ~ ")"; }
}

alias Pt = Point!long;
long tri(Pt a, Pt b, Pt c) {
  return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
}

Pt[] convexHull(Pt[] ps) {
  auto qs = new Pt[ps.length + 1];
  ps.sort!((a, b) => (a.x < b.x));
  int m = 0;
  foreach (p; ps) {
    for (; m > 1 && sgn(tri(qs[m - 2], qs[m - 1], p)) <= 0; --m) {}
    qs[m++] = p;
  }
  const r = m;
  foreach_reverse (p; ps) {
    for (; m > r && sgn(tri(qs[m - 2], qs[m - 1], p)) <= 0; --m) {}
    qs[m++] = p;
  }
  return qs[0 .. m - 1];
}

enum BASES = [2020, 120, 2147];

void main() {
  try {
    for (; ; ) {
      auto N = new int[2];
      foreach (h; 0 .. 2) {
        N[h] = readInt();
      }
      auto P = new Pt[][2];
      foreach (h; 0 .. 2) {
        P[h] = new Pt[N[h]];
        foreach (i; 0 .. N[h]) {
          P[h][i].x = readLong();
          P[h][i].y = readLong();
        }
      }

      auto seqs = new long[][2];
      foreach (h; 0 .. 2) {
        const qs = convexHull(P[h]);
        const qsLen = cast(int)(qs.length);
        auto edges = new Pt[qsLen];
        foreach (j; 0 .. qsLen) {
          edges[j] = qs[(j + 1) % qsLen] - qs[j];
        }
        foreach (j; 0 .. qsLen) {
          seqs[h] ~= edges[j].dot(edges[j]);
          seqs[h] ~= edges[j].dot(edges[(j + 1) % qsLen]);
          seqs[h] ~= edges[j].det(edges[(j + 1) % qsLen]);
        }
        debug {
          writeln("qs = ", qs);
          writeln("seqs[h] = ", seqs[h]);
        }
      }

      bool ans;
      const len = cast(int)(seqs[0].length);
      if (len == seqs[1].length) {
        auto bb = new Mint[][](BASES.length, len + 1);
        foreach (g; 0 .. BASES.length) {
          bb[g][0] = 1;
          foreach (j; 1 .. len + 1) {
            bb[g][j] = bb[g][j - 1] * BASES[g];
          }
        }
        auto ss = new Mint[][][](2, BASES.length, len + 1);
        foreach (h; 0 .. 2) foreach (g; 0 .. BASES.length) {
          foreach (j; 0 .. len) {
            ss[h][g][j + 1] = ss[h][g][j] + bb[g][j] * seqs[h][j];
          }
        }
        debug {
          writeln("ss = ", ss);
        }
        foreach (shift; 0 .. len) {
          if (shift % 3 == 0) {
            bool ok = true;
            foreach (g; 0 .. BASES.length) {
              ok = ok && ((bb[g][shift] * ss[0][g][len]).x == (ss[1][g][len] + (bb[g][len] - 1) * ss[1][g][shift]).x);
            }
            if (ok) {
              debug {
                writeln("shift = ", shift);
              }
              ans = true;
            }
          }
        }
      }
      writeln(ans ? "YES" : "NO");
    }
  } catch (EOFException e) {
  }
}

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

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

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

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

enum LIM = 105;

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

      int readIt() {
        const str = readToken();
        int ret;
        foreach (i; 0 .. N) {
          ret |= (str[i] - '0') << i;
        }
        return ret;
      }

      auto S = new int[M];
      foreach (j; 0 .. M) {
        S[j] = readIt();
      }
      auto T = new int[Q];
      auto K = new int[Q];
      foreach (q; 0 .. Q) {
        T[q] = readIt();
        K[q] = readInt();
      }

      auto WSum = new int[1 << N];
      foreach (i; 0 .. N) {
        foreach (h; 0 .. 1 << i) {
          WSum[h | 1 << i] = WSum[h] + W[i];
        }
      }

      auto cnt = new int[1 << N];
      foreach (j; 0 .. M) {
        ++cnt[S[j]];
      }
      auto anss = new int[][](1 << N, LIM);
      foreach (t; 0 .. 1 << N) {
        foreach (s; 0 .. 1 << N) {
          const w = WSum[((1 << N) - 1) ^ s ^ t];
          if (w < LIM) {
            anss[t][w] += cnt[s];
          }
        }
        foreach (k; 1 .. LIM) {
          anss[t][k] += anss[t][k - 1];
        }
      }

      foreach (q; 0 .. Q) {
        writeln(anss[T[q]][K[q]]);
      }
    }
  } catch (EOFException e) {
  }
}

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

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

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

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

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

enum MO = 10^^9 + 403;
alias Mint = ModInt!MO;

struct Point(T) {
  T x, y;
  Pt opBinary(string op)(Pt a) const {
    static if (op == "+") return Pt(x + a.x, y + a.y);
    else static if (op == "-") return Pt(x - a.x, y - a.y);
    else static assert(false);
  }
  Pt opBinary(string op)(T k) const {
    static if (op == "*") return Pt(x * k, y * k);
    else static if (op == "/") return Pt(x / k, y / k);
    else static assert(false);
  }
  T dot(Pt a) const { return x * a.x + y * a.y; }
  T det(Pt a) const { return x * a.y - y * a.x; }
  int opCmp(Pt a) const { return (x < a.x) ? -1 : (x > a.x) ? +1 : (y < a.y) ? -1 : (y > a.y) ? +1 : 0; }
  string toString() const { return "(" ~ x.to!string ~ ", " ~ y.to!string ~ ")"; }
}

alias Pt = Point!long;
long tri(Pt a, Pt b, Pt c) {
  return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
}

Pt[] convexHull(Pt[] ps) {
  auto qs = new Pt[ps.length + 1];
  ps.sort!((a, b) => (a.x < b.x));
  int m = 0;
  foreach (p; ps) {
    for (; m > 1 && sgn(tri(qs[m - 2], qs[m - 1], p)) <= 0; --m) {}
    qs[m++] = p;
  }
  const r = m;
  foreach_reverse (p; ps) {
    for (; m > r && sgn(tri(qs[m - 2], qs[m - 1], p)) <= 0; --m) {}
    qs[m++] = p;
  }
  return qs[0 .. m - 1];
}

enum BASES = [20209, 1209, 21479];

void main() {
  try {
    for (; ; ) {
      auto N = new int[2];
      foreach (h; 0 .. 2) {
        N[h] = readInt();
      }
      auto P = new Pt[][2];
      foreach (h; 0 .. 2) {
        P[h] = new Pt[N[h]];
        foreach (i; 0 .. N[h]) {
          P[h][i].x = readLong();
          P[h][i].y = readLong();
        }
      }

      auto seqs = new long[][2];
      foreach (h; 0 .. 2) {
        const qs = convexHull(P[h]);
        const qsLen = cast(int)(qs.length);
        auto edges = new Pt[qsLen];
        foreach (j; 0 .. qsLen) {
          edges[j] = qs[(j + 1) % qsLen] - qs[j];
        }
        foreach (j; 0 .. qsLen) {
          seqs[h] ~= edges[j].dot(edges[j]);
          seqs[h] ~= edges[j].dot(edges[(j + 1) % qsLen]);
        }
        debug {
          writeln("qs = ", qs);
          writeln("seqs[h] = ", seqs[h]);
        }
      }

      bool ans;
      const len = cast(int)(seqs[0].length);
      if (len == seqs[1].length) {
        auto bb = new Mint[][](BASES.length, len + 1);
        foreach (g; 0 .. BASES.length) {
          bb[g][0] = 1;
          foreach (j; 1 .. len + 1) {
            bb[g][j] = bb[g][j - 1] * BASES[g];
          }
        }
        auto ss = new Mint[][][](2, BASES.length, len + 1);
        foreach (h; 0 .. 2) foreach (g; 0 .. BASES.length) {
          foreach (j; 0 .. len) {
            ss[h][g][j + 1] = ss[h][g][j] + bb[g][j] * seqs[h][j];
          }
        }
        debug {
          writeln("ss = ", ss);
        }
        foreach (shift; 0 .. len) {
          if (shift % 2 == 0) {
            bool ok = true;
            foreach (g; 0 .. BASES.length) {
              ok = ok && ((bb[g][shift] * ss[0][g][len]).x == (ss[1][g][len] + (bb[g][len] - 1) * ss[1][g][shift]).x);
            }
            if (ok) {
              debug {
                writeln("shift = ", shift);
              }
              foreach (j; 0 .. len) {
                ok = ok && (seqs[0][j] == seqs[1][(j + shift) % len]);
              }
              if (ok) {
                ans = true;
                debug {
                } else {
                  break;
                }
              }
            }
          }
        }
      }
      writeln(ans ? "YES" : "NO");
    }
  } catch (EOFException e) {
  }
}

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

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

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

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

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

enum MO = 10^^9 + 403;
alias Mint = ModInt!MO;

struct Point(T) {
  T x, y;
  Pt opBinary(string op)(Pt a) const {
    static if (op == "+") return Pt(x + a.x, y + a.y);
    else static if (op == "-") return Pt(x - a.x, y - a.y);
    else static assert(false);
  }
  Pt opBinary(string op)(T k) const {
    static if (op == "*") return Pt(x * k, y * k);
    else static if (op == "/") return Pt(x / k, y / k);
    else static assert(false);
  }
  T dot(Pt a) const { return x * a.x + y * a.y; }
  T det(Pt a) const { return x * a.y - y * a.x; }
  int opCmp(Pt a) const { return (x < a.x) ? -1 : (x > a.x) ? +1 : (y < a.y) ? -1 : (y > a.y) ? +1 : 0; }
  string toString() const { return "(" ~ x.to!string ~ ", " ~ y.to!string ~ ")"; }
}

alias Pt = Point!long;
long tri(Pt a, Pt b, Pt c) {
  return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
}

Pt[] convexHull(Pt[] ps) {
  auto qs = new Pt[ps.length + 1];
  ps.sort!((a, b) => (a.x < b.x));
  int m = 0;
  foreach (p; ps) {
    for (; m > 1 && sgn(tri(qs[m - 2], qs[m - 1], p)) <= 0; --m) {}
    qs[m++] = p;
  }
  const r = m;
  foreach_reverse (p; ps) {
    for (; m > r && sgn(tri(qs[m - 2], qs[m - 1], p)) <= 0; --m) {}
    qs[m++] = p;
  }
  return qs[0 .. m - 1];
}

enum BASES = [2020, 120, 2147];

void main() {
  try {
    for (; ; ) {
      auto N = new int[2];
      foreach (h; 0 .. 2) {
        N[h] = readInt();
      }
      auto P = new Pt[][2];
      foreach (h; 0 .. 2) {
        P[h] = new Pt[N[h]];
        foreach (i; 0 .. N[h]) {
          P[h][i].x = readLong();
          P[h][i].y = readLong();
        }
      }

      auto seqs = new long[][2];
      foreach (h; 0 .. 2) {
        const qs = convexHull(P[h]);
        const qsLen = cast(int)(qs.length);
        auto edges = new Pt[qsLen];
        foreach (j; 0 .. qsLen) {
          edges[j] = qs[(j + 1) % qsLen] - qs[j];
        }
        foreach (j; 0 .. qsLen) {
          seqs[h] ~= edges[j].dot(edges[j]);
          seqs[h] ~= edges[j].dot(edges[(j + 1) % qsLen]);
        }
        debug {
          writeln("qs = ", qs);
          writeln("seqs[h] = ", seqs[h]);
        }
      }

      bool ans;
      const len = cast(int)(seqs[0].length);
      if (len == seqs[1].length) {
        auto bb = new Mint[][](BASES.length, len + 1);
        foreach (g; 0 .. BASES.length) {
          bb[g][0] = 1;
          foreach (j; 1 .. len + 1) {
            bb[g][j] = bb[g][j - 1] * BASES[g];
          }
        }
        auto ss = new Mint[][][](2, BASES.length, len + 1);
        foreach (h; 0 .. 2) foreach (g; 0 .. BASES.length) {
          foreach (j; 0 .. len) {
            ss[h][g][j + 1] = ss[h][g][j] + bb[g][j] * seqs[h][j];
          }
        }
        debug {
          writeln("ss = ", ss);
        }
        foreach (shift; 0 .. len) {
          if (shift % 2 == 0) {
            bool ok = true;
            foreach (g; 0 .. BASES.length) {
              ok = ok && ((bb[g][shift] * ss[0][g][len]).x == (ss[1][g][len] + (bb[g][len] - 1) * ss[1][g][shift]).x);
            }
            if (ok) {
              debug {
                writeln("shift = ", shift);
              }
              ans = true;
            }
          }
        }
      }
      writeln(ans ? "YES" : "NO");
    }
  } catch (EOFException e) {
  }
}


Johnny drives a truck and must deliver a package from his hometown to the district center. His hometown is located at point 0 on a number line, and the district center is located at the point d.Johnny's truck has a gas tank that holds exactly n liters, and his tank is initially full. As he drives, the truck consumes exactly one liter per unit distance traveled. Moreover, there are m gas stations located at various points along the way to the district center. The i-th station is located at the point xi on the number line and sells an unlimited amount of fuel at a price of pi dollars per liter. Find the minimum cost Johnny must pay for fuel to successfully complete the delivery.

The first line of input contains three space separated integers d, n, and m (1 ≤ n ≤ d ≤ 109, 1 ≤ m ≤ 200 000) — the total distance to the district center, the volume of the gas tank, and the number of gas stations, respectively. Each of the next m lines contains two integers xi, pi (1 ≤ xi ≤ d - 1, 1 ≤ pi ≤ 106) — the position and cost of gas at the i-th gas station. It is guaranteed that the positions of the gas stations are distinct.

Print a single integer — the minimum cost to complete the delivery. If there is no way to complete the delivery, print -1.

NoteIn the first sample, Johnny's truck holds 4 liters. He can drive 3 units to the first gas station, buy 2 liters of gas there (bringing the tank to 3 liters total), drive 3 more units to the third gas station, buy 4 liters there to fill up his tank, and then drive straight to the district center. His total cost is 2·5 + 4·3 = 22 dollars.In the second sample, there is no way for Johnny to make it to the district center, as his tank cannot hold enough gas to take him from the latest gas station to the district center.

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

void main ()
{
	int d;
	int n;
	int m;
multitest_loop:
	while (readf (" %s %s %s", &d, &n, &m) > 0)
	{
		alias Station = Tuple !(int, q{x}, int, q{p});
		auto a = new Station [m + 2];
		foreach (ref s; a[0..m])
		{
			readf (" %s %s", &s.x, &s.p);
		}
		a[m] = Station (d, 0);
		a[m + 1] = Station (0, 0);
		sort (a);

		auto s = redBlackTree !((u, v) => u.p < v.p ||
		    (u.p == v.p && u.x < v.x), Station);
		long res = 0;
		int pos = 0;
		s.insert (a.front);
		a.popFront ();
		foreach (ref cur; a)
		{
			int next = cur.x;
			while (pos != next && !s.empty)
			{
				auto fuel = s.front;
				int temp = min (next, fuel.x + n);
				if (temp <= pos)
				{
					s.removeFront ();
				}
				else
				{
					res += (temp - pos) * 1L * fuel.p;
					pos = temp;
				}
			}
			if (pos != next)
			{
				writeln (-1);
				continue multitest_loop;
			}
			s.insert (cur);
		}
		writeln (res);
	}
}

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

void main ()
{
	int d;
	int n;
	int m;
multitest_loop:
	while (readf (" %s %s %s", &d, &n, &m) > 0)
	{
		alias Station = Tuple !(int, q{x}, int, q{p});
		auto a = new Station [m + 2];
		foreach (ref s; a[0..m])
		{
			readf (" %s %s", &s.x, &s.p);
		}
		a[m] = Station (d, 0);
		a[m + 1] = Station (0, 0);
		sort (a);

		auto s = redBlackTree !((u, v) => u.p < v.p, Station);
		long res = 0;
		int pos = 0;
		s.insert (a.front);
		a.popFront ();
		foreach (ref cur; a)
		{
			int next = cur.x;
			while (pos != next && !s.empty)
			{
				auto fuel = s.front;
				int temp = min (next, fuel.x + n);
				if (temp <= pos)
				{
					s.removeFront ();
				}
				else
				{
					res += (temp - pos) * 1L * fuel.p;
					pos = temp;
				}
			}
			if (pos != next)
			{
				writeln (-1);
				continue multitest_loop;
			}
			s.insert (cur);
		}
		writeln (res);
	}
}


The R1 company wants to hold a web search championship. There were n computers given for the competition, each of them is connected to the Internet. The organizers believe that the data transfer speed directly affects the result. The higher the speed of the Internet is, the faster the participant will find the necessary information. Therefore, before the competition started, each computer had its maximum possible data transfer speed measured. On the i-th computer it was ai kilobits per second.There will be k participants competing in the championship, each should get a separate computer. The organizing company does not want any of the participants to have an advantage over the others, so they want to provide the same data transfer speed to each participant's computer. Also, the organizers want to create the most comfortable conditions for the participants, so the data transfer speed on the participants' computers should be as large as possible.The network settings of the R1 company has a special option that lets you to cut the initial maximum data transfer speed of any computer to any lower speed. How should the R1 company configure the network using the described option so that at least k of n computers had the same data transfer speed and the data transfer speed on these computers was as large as possible?

The first line contains two space-separated integers n and k (1 ≤ k ≤ n ≤ 100) — the number of computers and the number of participants, respectively. In the second line you have a space-separated sequence consisting of n integers: a1, a2, ..., an (16 ≤ ai ≤ 32768); number ai denotes the maximum data transfer speed on the i-th computer.

Print a single integer — the maximum Internet speed value. It is guaranteed that the answer to the problem is always an integer.

NoteIn the first test case the organizers can cut the first computer's speed to 30 kilobits. Then two computers (the first and the third one) will have the same speed of 30 kilobits. They should be used as the participants' computers. This answer is optimal.

//ahmat
import std.stdio,std.string,std.math,std.algorithm,
std.array,std.container,std.algorithm,std.numeric,std.bitmanip,
std.range,std.random,std.complex,std.functional,std.typecons,
std.format,std.bigint,core.vararg,core.bitop,std.conv;
int sz(T)(ref T a){return cast(int)a.length;}
alias rbt=RedBlackTree;
alias deq=DList;
alias heap=BinaryHeap;
const long mod=1000_000_007;

void main(){
    int n,k;
    readf!"%d %d "(n,k);
    int[] a=readln.splitter.map!(to!int).array;
    sort!"a>b"(a);
    writeln(a[k-1]);
}


You are given a tree consisting of $$$n$$$ nodes. You want to write some labels on the tree's edges such that the following conditions hold:  Every label is an integer between $$$0$$$ and $$$n-2$$$ inclusive.  All the written labels are distinct.  The largest value among $$$MEX(u,v)$$$ over all pairs of nodes $$$(u,v)$$$ is as small as possible. Here, $$$MEX(u,v)$$$ denotes the smallest non-negative integer that isn't written on any edge on the unique simple path from node $$$u$$$ to node $$$v$$$.

The first line contains the integer $$$n$$$ ($$$2 \le n \le 10^5$$$) — the number of nodes in the tree. Each of the next $$$n-1$$$ lines contains two space-separated integers $$$u$$$ and $$$v$$$ ($$$1 \le u,v \le n$$$) that mean there's an edge between nodes $$$u$$$ and $$$v$$$. It's guaranteed that the given graph is a tree.

Output $$$n-1$$$ integers. The $$$i^{th}$$$ of them will be the number written on the $$$i^{th}$$$ edge (in the input order).

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(); } bool DEBUG = 0;
void log(A ...)(lazy A a){ if(DEBUG) print(a); }
void print(){ writeln(""); } void print(T)(T t){ writeln(t); } void print(T, A ...)(T t, A a){ write(t, " "), print(a); }
string unsplit(T)(T xs){ return xs.array.to!(string[]).join(" "); }
string scan(){ static string[] ss; while(!ss.length) ss = readln.chomp.split; string res = ss[0]; ss.popFront; return res; }
T scan(T)(){ return scan.to!T; } T[] scan(T)(int n){ return n.iota.map!(i => scan!T()).array; }
T lowerTo(T)(ref T x, T y){ if(x > y) x = y; return x; } T raiseTo(T)(ref T x, T y){ if(x < y) x = y; return x; }

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

void solve(){
    int n = scan!int;
    Node[] nodes;
    foreach(i; 0 .. n) nodes ~= new Node(i);

    Edge[] edges;
    foreach(i; 0 .. n - 1){
        edges ~= new Edge(i, nodes[scan!int - 1], nodes[scan!int - 1]);
    }

    Node nd0;
    foreach(nd; nodes) if(nd.edges.length >= 3) nd0 = nd;

    int v = 0;
    if(nd0){
        nd0.edges[0].value = 0;
        nd0.edges[1].value = 1;
        nd0.edges[2].value = 2;
        v += 3;
    }

    foreach(ed; edges) if(ed.value < 0) ed.value = v, v += 1;

    foreach(ed; edges) ed.value.print;

}

class Edge{
    int id;
    Node a, b;
    int value = -1;
    this(int id, Node a, Node b){
        this.id = id;
        this.a = a, this.b = b;
        a.edges ~= this, b.edges ~= this;
    }
}
class Node{
    int id;
    Edge[] edges;
    this(int id){
        this.id = id;
    }
}