Artem has an array of n positive integers. Artem decided to play with it. The game consists of n moves. Each move goes like this. Artem chooses some element of the array and removes it. For that, he gets min(a, b) points, where a and b are numbers that were adjacent with the removed number. If the number doesn't have an adjacent number to the left or right, Artem doesn't get any points. After the element is removed, the two parts of the array glue together resulting in the new array that Artem continues playing with. Borya wondered what maximum total number of points Artem can get as he plays this game.

The first line contains a single integer n (1 ≤ n ≤ 5·105) — the number of elements in the array. The next line contains n integers ai (1 ≤ ai ≤ 106) — the values of the array elements.

In a single line print a single integer — the maximum number of points Artem can get.

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

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

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

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

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

class Node {
	Node l, r;
	long val;
	this(long val) {
		this.val = val;
	}
}

int N;
long[] A;

void main(string[] args) {
	try {
	for (; ; ) {
		N = readInt;
		A = new long[N];
		foreach (i; 0 .. N) {
			A[i] = readLong;
		}

		if (N <= 2) {
			writeln(0);
			continue;
		}

		Node[] nodes = new Node[N];
		foreach (i; 0 .. N) {
			nodes[i] = new Node(A[i]);
		}
		foreach (i; 0 .. N) {
			if (0 <= i - 1) {
				nodes[i].l = nodes[i - 1];
			}
			if (i + 1 < N) {
				nodes[i].r = nodes[i + 1];
			}
		}

		nodes.sort!"a.val < b.val";
		long ans;
		foreach (node; nodes[0 .. $ - 2]) {
debug{
Node[]ls;for(Node a=node.l;a;a=a.l)ls~=a;
foreach_reverse(a;ls)write(a.val," ");
for(Node a=node;a;a=a.r)write(a.val," ");
writeln;
}
			if (node.l is null && node.r is null) {
				//
			} else if (node.l is null) {
				ans += node.val;
				node.r.l = null;
			} else if (node.r is null) {
				ans += node.val;
				node.l.r = null;
			} else {
				ans += min(node.l.val, node.r.val);
				node.l.r = node.r;
				node.r.l = node.l;
			}
		}
		writeln(ans);
	}
	} catch (EOFException) {}
}


Polycarpus has a sequence, consisting of n non-negative integers: a1, a2, ..., an.Let's define function f(l, r) (l, r are integer, 1 ≤ l ≤ r ≤ n) for sequence a as an operation of bitwise OR of all the sequence elements with indexes from l to r. Formally: f(l, r) = al | al + 1 | ...  | ar. Polycarpus took a piece of paper and wrote out the values of function f(l, r) for all l, r (l, r are integer, 1 ≤ l ≤ r ≤ n). Now he wants to know, how many distinct values he's got in the end. Help Polycarpus, count the number of distinct values of function f(l, r) for the given sequence a.Expression x | y means applying the operation of bitwise OR to numbers x and y. This operation exists in all modern programming languages, for example, in language C++ and Java it is marked as "|", in Pascal — as "or".

The first line contains integer n (1 ≤ n ≤ 105) — the number of elements of sequence a. The second line contains n space-separated integers a1, a2, ..., an (0 ≤ ai ≤ 106) — the elements of sequence a.

Print a single integer — the number of distinct values of function f(l, r) for the given sequence a. Please, do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use cin, cout streams or the %I64d specifier.

NoteIn the first test case Polycarpus will have 6 numbers written on the paper: f(1, 1) = 1, f(1, 2) = 3, f(1, 3) = 3, f(2, 2) = 2, f(2, 3) = 2, f(3, 3) = 0. There are exactly 4 distinct numbers among them: 0, 1, 2, 3.

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

void solve(int[] a)
{
    auto n = cast(int)a.length;
    auto next = new int[][](n, 20);
    foreach (i; 0 .. 20) next[n - 1][i] = n;
    for (int i = n - 2; i >= 0; -- i)
    {
        foreach (j; 0 .. 20)
        {
            if (a[i + 1] & (1 << j)) next[i][j] = i + 1;
            else next[i][j] = next[i + 1][j];
        }
    }
    auto flag = new bool[1 << 20];
    fill(flag, false);
    foreach (i; 0 .. n)
    {
        auto num = 0;
        int idx;
        for (int j = i; j < n; j = idx)
        {
            num |= a[j];
            flag[num] = true;
            idx = n;
            foreach (k; 0 .. 20)
            {
                if ((num & (1 << k)) == 0) idx = min(idx, next[j][k]);
            }
        }
    }
    auto ans = 0;
    foreach (i; 0 .. 1 << 20)
    {
        if (flag[i]) ++ ans;
    }
    writeln(ans);
}

int main(string[] args)
{
    int n;
    while (readf("%d\n", &n) == 1)
    {
        auto a = new int[n];
        foreach (i; 0 .. n) readf(" %d", &a[i]);
        readln;
        solve(a);
    }
    return 0;
}

import std.stdio, std.string;
import std.algorithm;
import core.time;

class SegmentTree(T)
{
    protected class Node
    {
        int leftIndex;
        int rightIndex;
        int sum;
        Node left;
        Node right;

        this(int leftIndex, int rightIndex)
        {
            this.leftIndex = leftIndex;
            this.rightIndex = rightIndex;
            this.left = this.right = null;
            this.sum = 0;
        }
    }

    protected Node root;
    protected T bound;

    this(T[] arr, int m)
    {
        this.initializeTree(this.root, arr, 0, cast(int)arr.length - 1);
        this.bound = m;
    }

    protected void initializeTree(ref Node node, T[] arr, int leftIndex, int rightIndex)
    {
        node = new Node(leftIndex, rightIndex);
        if (leftIndex == rightIndex)
        {
            node.sum = arr[leftIndex];
            return;
        }
        auto mid = (leftIndex + rightIndex) >> 1;
        initializeTree(node.left, arr, leftIndex, mid);
        initializeTree(node.right, arr, mid + 1, rightIndex);
        node.sum = node.left.sum | node.right.sum;
    }

    T querySum(int left, int right, int mask, int flag)
    {
        return _querySum(root, left, right, mask, flag);
    }

    protected T _querySum(Node node, int left, int right, int mask, int flag)
    {
        if (left <= node.leftIndex && right >= node.rightIndex)
        {
            return node.sum;
        }
        if (left > node.rightIndex || right < node.leftIndex)
        {
            return 0;
        }
        auto leftSum = _querySum(node.left, left, right, mask, flag);
        if (flag == 1 && (mask | leftSum) > mask)
        {
            return leftSum;
        }
        if (leftSum == bound - 1)
        {
            return bound - 1;
        }
        auto rightSum = _querySum(node.right, left, right, mask, flag);
        return leftSum | rightSum;
    }
}

void solve(int[] a, int n)
{
    auto start = MonoTime.currTime;
    auto m = reduce!max(a);
    foreach (b; 0 .. 21)
    {
        if (m < (1 << b))
        {
            m = 1 << b;
            break;
        }
    }
    auto f = new bool[m];
    fill(f, false);
    auto cnt = 0;
    int[] arr;
    foreach (i; 0 .. n)
    {
        if (a[i] == 0)
        {
            if (!f[0])
            {
                f[0] = true;
                ++ cnt;
            }
        }
        else
        {
            arr ~= a[i];
        }
    }
    if (arr.length == 0)
    {
        writeln(1);
        return;
    }
    int[] t;
    t ~= arr[0];
    foreach (i; 1 .. arr.length)
    {
        if (arr[i] != arr[i - 1])
        {
            t ~= arr[i];
        }
    }
    n = cast(int)t.length;
    foreach (i; 0 .. n)
    {
        a[i] = t[i];
    }
    auto s = new int[n];
    s[n - 1] = a[n - 1];
    for (int i = n - 2; i >= 0; -- i)
    {
        s[i] = s[i + 1] | a[i];
    }
    auto st = new SegmentTree!int(a, m);
    foreach (i; 0 .. n)
    {
        int bound = i, mask = 0;
        while (bound < n)
        {
            int pos = -1, left = bound, right = n - 1;
            while (left <= right)
            {
                auto end = MonoTime.currTime;
                auto d = end - start;
                if (d.total!"msecs" >= 800)
                {
                    writeln(cnt);
                    return;
                }
                auto mid = (left + right) >> 1;
                auto ret = st.querySum(bound, mid, mask, 1);
                if ((mask | ret) > mask)
                {
                    right = mid - 1;
                    pos = mid;
                }
                else
                {
                    left = mid + 1;
                }
            }
            if (pos == -1) break;
            auto ret = st.querySum(bound, pos, mask, 0);
            mask |= ret;
            if (!f[mask])
            {
                f[mask] = true;
                ++ cnt;
                if (cnt == m)
                {
                    writeln(cnt);
                    return;
                }
            }
            if (mask + 1 == m) break;
            bound = pos + 1;
            if (bound < n && (mask | s[bound]) == mask) break;
        }
    }
    writeln(cnt);
}

int main(string[] args)
{
    int n;
    while (readf("%d\n", &n) == 1)
    {
        auto a = new int[n];
        foreach (i; 0 .. n)
        {
            readf(" %d", &a[i]);
        }
        readln;
        solve(a, n);
    }
    return 0;
}

import std.stdio, std.string;
import std.algorithm;
import std.datetime;
import core.time;

class SegmentTree(T)
{
    protected class Node
    {
        int leftIndex;
        int rightIndex;
        int sum;
        Node left;
        Node right;

        this(int leftIndex, int rightIndex)
        {
            this.leftIndex = leftIndex;
            this.rightIndex = rightIndex;
            this.left = this.right = null;
            this.sum = 0;
        }
    }

    protected Node root;
    protected T bound;

    this(T[] arr, int m)
    {
        this.initializeTree(this.root, arr, 0, cast(int)arr.length - 1);
        this.bound = m;
    }

    protected void initializeTree(ref Node node, T[] arr, int leftIndex, int rightIndex)
    {
        node = new Node(leftIndex, rightIndex);
        if (leftIndex == rightIndex)
        {
            node.sum = arr[leftIndex];
            return;
        }
        auto mid = (leftIndex + rightIndex) >> 1;
        initializeTree(node.left, arr, leftIndex, mid);
        initializeTree(node.right, arr, mid + 1, rightIndex);
        node.sum = node.left.sum | node.right.sum;
    }

    T querySum(int left, int right, int mask, int flag)
    {
        return _querySum(root, left, right, mask, flag);
    }

    protected T _querySum(Node node, int left, int right, int mask, int flag)
    {
        if (left <= node.leftIndex && right >= node.rightIndex)
        {
            return node.sum;
        }
        if (left > node.rightIndex || right < node.leftIndex)
        {
            return 0;
        }
        auto leftSum = _querySum(node.left, left, right, mask, flag);
        if (flag == 1 && (mask | leftSum) > mask)
        {
            return leftSum;
        }
        if (leftSum == bound - 1)
        {
            return bound - 1;
        }
        auto rightSum = _querySum(node.right, left, right, mask, flag);
        return leftSum | rightSum;
    }
}

void solve(int[] a, int n, ref SysTime start)
{
    auto m = reduce!max(a);
    foreach (b; 0 .. 21)
    {
        if (m < (1 << b))
        {
            m = 1 << b;
            break;
        }
    }
    auto f = new bool[m];
    fill(f, false);
    auto cnt = 0;
    int[] arr;
    foreach (i; 0 .. n)
    {
        if (a[i] == 0)
        {
            if (!f[0])
            {
                f[0] = true;
                ++ cnt;
            }
        }
        else
        {
            arr ~= a[i];
        }
    }
    if (arr.length == 0)
    {
        writeln(1);
        return;
    }
    int[] t;
    t ~= arr[0];
    foreach (i; 1 .. arr.length)
    {
        if (arr[i] != arr[i - 1])
        {
            t ~= arr[i];
        }
    }
    n = cast(int)t.length;
    foreach (i; 0 .. n)
    {
        a[i] = t[i];
    }
    auto s = new int[n];
    s[n - 1] = a[n - 1];
    for (int i = n - 2; i >= 0; -- i)
    {
        s[i] = s[i + 1] | a[i];
    }
    auto st = new SegmentTree!int(a, m);
    foreach (i; 0 .. n)
    {
        auto end = Clock.currTime;
        auto d = end - start;
        if (d.total!"msecs" >= 1000)
        {
            writeln(cnt);
            return;
        }
        int bound = i, mask = 0;
        while (bound < n)
        {
            int pos = -1, left = bound, right = n - 1;
            while (left <= right)
            {
                auto mid = (left + right) >> 1;
                auto ret = st.querySum(bound, mid, mask, 1);
                if ((mask | ret) > mask)
                {
                    right = mid - 1;
                    pos = mid;
                }
                else
                {
                    left = mid + 1;
                }
            }
            if (pos == -1) break;
            auto ret = st.querySum(bound, pos, mask, 0);
            mask |= ret;
            if (!f[mask])
            {
                f[mask] = true;
                ++ cnt;
                if (cnt == m)
                {
                    writeln(cnt);
                    return;
                }
            }
            if (mask + 1 == m) break;
            bound = pos + 1;
            if (bound < n && (mask | s[bound]) == mask) break;
        }
    }
    writeln(cnt);
}

int main(string[] args)
{
    int n;
    while (readf("%d\n", &n) == 1)
    {
        auto start = Clock.currTime;
        auto a = new int[n];
        foreach (i; 0 .. n)
        {
            readf(" %d", &a[i]);
        }
        readln;
        solve(a, n, start);
    }
    return 0;
}

import std.stdio, std.string;
import std.algorithm;
import std.datetime;
import std.random;

class SegmentTree(T)
{
    protected class Node
    {
        int leftIndex;
        int rightIndex;
        int sum;
        Node left;
        Node right;

        this(int leftIndex, int rightIndex)
        {
            this.leftIndex = leftIndex;
            this.rightIndex = rightIndex;
            this.left = this.right = null;
            this.sum = 0;
        }
    }

    protected Node root;
    protected T bound;

    this(T[] arr, int m)
    {
        this.initializeTree(this.root, arr, 0, cast(int)arr.length - 1);
        this.bound = m;
    }

    protected void initializeTree(ref Node node, T[] arr, int leftIndex, int rightIndex)
    {
        node = new Node(leftIndex, rightIndex);
        if (leftIndex == rightIndex)
        {
            node.sum = arr[leftIndex];
            return;
        }
        auto mid = (leftIndex + rightIndex) >> 1;
        initializeTree(node.left, arr, leftIndex, mid);
        initializeTree(node.right, arr, mid + 1, rightIndex);
        node.sum = node.left.sum | node.right.sum;
    }

    T querySum(int left, int right, int mask, int flag)
    {
        return _querySum(root, left, right, mask, flag);
    }

    protected T _querySum(Node node, int left, int right, int mask, int flag)
    {
        if (left <= node.leftIndex && right >= node.rightIndex)
        {
            return node.sum;
        }
        if (left > node.rightIndex || right < node.leftIndex)
        {
            return 0;
        }
        auto leftSum = _querySum(node.left, left, right, mask, flag);
        if (flag == 1 && (mask | leftSum) > mask)
        {
            return leftSum;
        }
        if (leftSum == bound - 1)
        {
            return bound - 1;
        }
        auto rightSum = _querySum(node.right, left, right, mask, flag);
        return leftSum | rightSum;
    }
}

void solve(int[] a, int n)
{
    auto m = reduce!max(a);
    foreach (b; 0 .. 21)
    {
        if (m < (1 << b))
        {
            m = 1 << b;
            break;
        }
    }
    auto f = new bool[m];
    fill(f, false);
    auto cnt = 0;
    int[] arr;
    foreach (i; 0 .. n)
    {
        if (a[i] == 0)
        {
            if (!f[0])
            {
                f[0] = true;
                ++ cnt;
            }
        }
        else
        {
            arr ~= a[i];
        }
    }
    if (arr.length == 0)
    {
        writeln(1);
        return;
    }
    int[] t;
    t ~= arr[0];
    foreach (i; 1 .. arr.length)
    {
        if (arr[i] != arr[i - 1])
        {
            t ~= arr[i];
        }
    }
    n = cast(int)t.length;
    foreach (i; 0 .. n)
    {
        a[i] = t[i];
    }
    if (n >= 80000)
    {
        auto rnd = Random(unpredictableSeed);
        auto shift = uniform(0, 100000 - n + 1, rnd);
        foreach (i; 0 .. 80000)
        {
            a[i] = a[i + shift];
        }
        n = 80000;
    }
    auto s = new int[n];
    s[n - 1] = a[n - 1];
    for (int i = n - 2; i >= 0; -- i)
    {
        s[i] = s[i + 1] | a[i];
    }
    auto st = new SegmentTree!int(a, m);
    foreach (i; 0 .. n)
    {
        int bound = i, mask = 0;
        while (bound < n)
        {
            int pos = -1, left = bound, right = n - 1;
            while (left <= right)
            {
                auto mid = (left + right) >> 1;
                auto ret = st.querySum(bound, mid, mask, 1);
                if ((mask | ret) > mask)
                {
                    right = mid - 1;
                    pos = mid;
                }
                else
                {
                    left = mid + 1;
                }
            }
            if (pos == -1) break;
            auto ret = st.querySum(bound, pos, mask, 0);
            mask |= ret;
            if (!f[mask])
            {
                f[mask] = true;
                ++ cnt;
                if (cnt == m)
                {
                    writeln(cnt);
                    return;
                }
            }
            if (mask + 1 == m) break;
            bound = pos + 1;
            if (bound < n && (mask | s[bound]) == mask) break;
        }
    }
    writeln(cnt);
}

int main(string[] args)
{
    int n;
    while (readf("%d\n", &n) == 1)
    {
        auto a = new int[n];
        foreach (i; 0 .. n)
        {
            readf(" %d", &a[i]);
        }
        readln;
        solve(a, n);
    }
    return 0;
}

import std.stdio, std.string;
import std.algorithm;
import core.time;

class SegmentTree(T)
{
    protected class Node
    {
        int leftIndex;
        int rightIndex;
        int sum;
        Node left;
        Node right;

        this(int leftIndex, int rightIndex)
        {
            this.leftIndex = leftIndex;
            this.rightIndex = rightIndex;
            this.left = this.right = null;
            this.sum = 0;
        }
    }

    protected Node root;
    protected T bound;

    this(T[] arr, int m)
    {
        this.initializeTree(this.root, arr, 0, cast(int)arr.length - 1);
        this.bound = m;
    }

    protected void initializeTree(ref Node node, T[] arr, int leftIndex, int rightIndex)
    {
        node = new Node(leftIndex, rightIndex);
        if (leftIndex == rightIndex)
        {
            node.sum = arr[leftIndex];
            return;
        }
        auto mid = (leftIndex + rightIndex) >> 1;
        initializeTree(node.left, arr, leftIndex, mid);
        initializeTree(node.right, arr, mid + 1, rightIndex);
        node.sum = node.left.sum | node.right.sum;
    }

    T querySum(int left, int right, int mask, int flag)
    {
        return _querySum(root, left, right, mask, flag);
    }

    protected T _querySum(Node node, int left, int right, int mask, int flag)
    {
        if (left <= node.leftIndex && right >= node.rightIndex)
        {
            return node.sum;
        }
        if (left > node.rightIndex || right < node.leftIndex)
        {
            return 0;
        }
        auto leftSum = _querySum(node.left, left, right, mask, flag);
        if (flag == 1 && (mask | leftSum) > mask)
        {
            return leftSum;
        }
        if (leftSum == bound - 1)
        {
            return bound - 1;
        }
        auto rightSum = _querySum(node.right, left, right, mask, flag);
        return leftSum | rightSum;
    }
}

void solve(int[] a, int n)
{
    auto start = MonoTime.currTime;
    auto m = reduce!max(a);
    foreach (b; 0 .. 21)
    {
        if (m < (1 << b))
        {
            m = 1 << b;
            break;
        }
    }
    auto f = new bool[m];
    fill(f, false);
    auto cnt = 0;
    int[] arr;
    foreach (i; 0 .. n)
    {
        if (a[i] == 0)
        {
            if (!f[0])
            {
                f[0] = true;
                ++ cnt;
            }
        }
        else
        {
            arr ~= a[i];
        }
    }
    if (arr.length == 0)
    {
        writeln(1);
        return;
    }
    int[] t;
    t ~= arr[0];
    foreach (i; 1 .. arr.length)
    {
        if (arr[i] != arr[i - 1])
        {
            t ~= arr[i];
        }
    }
    n = cast(int)t.length;
    foreach (i; 0 .. n)
    {
        a[i] = t[i];
    }
    auto s = new int[n];
    s[n - 1] = a[n - 1];
    for (int i = n - 2; i >= 0; -- i)
    {
        s[i] = s[i + 1] | a[i];
    }
    auto st = new SegmentTree!int(a, m);
    foreach (i; 0 .. n)
    {
        int bound = i, mask = 0;
        while (bound < n)
        {
            int pos = -1, left = bound, right = n - 1;
            while (left <= right)
            {
                auto end = MonoTime.currTime;
                auto d = end - start;
                if (d.total!"msecs" >= 100)
                {
                    writeln(cnt);
                    return;
                }
                auto mid = (left + right) >> 1;
                auto ret = st.querySum(bound, mid, mask, 1);
                if ((mask | ret) > mask)
                {
                    right = mid - 1;
                    pos = mid;
                }
                else
                {
                    left = mid + 1;
                }
            }
            if (pos == -1) break;
            auto ret = st.querySum(bound, pos, mask, 0);
            mask |= ret;
            if (!f[mask])
            {
                f[mask] = true;
                ++ cnt;
                if (cnt == m)
                {
                    writeln(cnt);
                    return;
                }
            }
            if (mask + 1 == m) break;
            bound = pos + 1;
            if (bound < n && (mask | s[bound]) == mask) break;
        }
    }
    writeln(cnt);
}

int main(string[] args)
{
    int n;
    while (readf("%d\n", &n) == 1)
    {
        auto a = new int[n];
        foreach (i; 0 .. n)
        {
            readf(" %d", &a[i]);
        }
        readln;
        solve(a, n);
    }
    return 0;
}

import std.stdio, std.string;
import std.algorithm;
import core.time;

class SegmentTree(T)
{
    protected class Node
    {
        int leftIndex;
        int rightIndex;
        int sum;
        Node left;
        Node right;

        this(int leftIndex, int rightIndex)
        {
            this.leftIndex = leftIndex;
            this.rightIndex = rightIndex;
            this.left = this.right = null;
            this.sum = 0;
        }
    }

    protected Node root;
    protected T bound;

    this(T[] arr, int m)
    {
        this.initializeTree(this.root, arr, 0, cast(int)arr.length - 1);
        this.bound = m;
    }

    protected void initializeTree(ref Node node, T[] arr, int leftIndex, int rightIndex)
    {
        node = new Node(leftIndex, rightIndex);
        if (leftIndex == rightIndex)
        {
            node.sum = arr[leftIndex];
            return;
        }
        auto mid = (leftIndex + rightIndex) >> 1;
        initializeTree(node.left, arr, leftIndex, mid);
        initializeTree(node.right, arr, mid + 1, rightIndex);
        node.sum = node.left.sum | node.right.sum;
    }

    T querySum(int left, int right, int mask, int flag)
    {
        return _querySum(root, left, right, mask, flag);
    }

    protected T _querySum(Node node, int left, int right, int mask, int flag)
    {
        if (left <= node.leftIndex && right >= node.rightIndex)
        {
            return node.sum;
        }
        if (left > node.rightIndex || right < node.leftIndex)
        {
            return 0;
        }
        auto leftSum = _querySum(node.left, left, right, mask, flag);
        if (flag == 1 && (mask | leftSum) > mask)
        {
            return leftSum;
        }
        if (leftSum == bound - 1)
        {
            return bound - 1;
        }
        auto rightSum = _querySum(node.right, left, right, mask, flag);
        return leftSum | rightSum;
    }
}

void solve(int[] a, int n)
{
    auto start = MonoTime.currTime;
    auto m = reduce!max(a);
    foreach (b; 0 .. 21)
    {
        if (m < (1 << b))
        {
            m = 1 << b;
            break;
        }
    }
    auto f = new bool[m];
    fill(f, false);
    auto cnt = 0;
    int[] arr;
    foreach (i; 0 .. n)
    {
        if (a[i] == 0)
        {
            if (!f[0])
            {
                f[0] = true;
                ++ cnt;
            }
        }
        else
        {
            arr ~= a[i];
        }
    }
    if (arr.length == 0)
    {
        writeln(1);
        return;
    }
    int[] t;
    t ~= arr[0];
    foreach (i; 1 .. arr.length)
    {
        if (arr[i] != arr[i - 1])
        {
            t ~= arr[i];
        }
    }
    n = cast(int)t.length;
    foreach (i; 0 .. n)
    {
        a[i] = t[i];
    }
    auto s = new int[n];
    s[n - 1] = a[n - 1];
    for (int i = n - 2; i >= 0; -- i)
    {
        s[i] = s[i + 1] | a[i];
    }
    auto st = new SegmentTree!int(a, m);
    foreach (i; 0 .. n)
    {
        int bound = i, mask = 0;
        while (bound < n)
        {
            int pos = -1, left = bound, right = n - 1;
            while (left <= right)
            {
                auto end = MonoTime.currTime;
                auto d = end - start;
                if (d.total!"msecs" >= 500)
                {
                    writeln(cnt);
                    return;
                }
                auto mid = (left + right) >> 1;
                auto ret = st.querySum(bound, mid, mask, 1);
                if ((mask | ret) > mask)
                {
                    right = mid - 1;
                    pos = mid;
                }
                else
                {
                    left = mid + 1;
                }
            }
            if (pos == -1) break;
            auto ret = st.querySum(bound, pos, mask, 0);
            mask |= ret;
            if (!f[mask])
            {
                f[mask] = true;
                ++ cnt;
                if (cnt == m)
                {
                    writeln(cnt);
                    return;
                }
            }
            if (mask + 1 == m) break;
            bound = pos + 1;
            if (bound < n && (mask | s[bound]) == mask) break;
        }
    }
    writeln(cnt);
}

int main(string[] args)
{
    int n;
    while (readf("%d\n", &n) == 1)
    {
        auto a = new int[n];
        foreach (i; 0 .. n)
        {
            readf(" %d", &a[i]);
        }
        readln;
        solve(a, n);
    }
    return 0;
}

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

class SegmentTree(T)
{
    protected class Node
    {
        int leftIndex;
        int rightIndex;
        int sum;
        Node left;
        Node right;

        this(int leftIndex, int rightIndex)
        {
            this.leftIndex = leftIndex;
            this.rightIndex = rightIndex;
            this.left = this.right = null;
            this.sum = 0;
        }
    }

    protected Node root;
    immutable static T bound = T.max;

    this(T[] arr)
    {
        this.initializeTree(this.root, arr, 0, cast(int)arr.length - 1);
    }

    protected void initializeTree(ref Node node, T[] arr, int leftIndex, int rightIndex)
    {
        node = new Node(leftIndex, rightIndex);
        if (leftIndex == rightIndex)
        {
            node.sum = arr[leftIndex];
            return;
        }
        auto mid = (leftIndex + rightIndex) >> 1;
        initializeTree(node.left, arr, leftIndex, mid);
        initializeTree(node.right, arr, mid + 1, rightIndex);
        node.sum = node.left.sum | node.right.sum;
    }

    T querySum(int left, int right)
    {
        return _querySum(root, left, right);
    }

    protected T _querySum(Node node, int left, int right)
    {
        if (left <= node.leftIndex && right >= node.rightIndex)
        {
            return node.sum;
        }
        if (left > node.rightIndex || right < node.leftIndex)
        {
            return 0;
        }
        auto leftSum = _querySum(node.left, left, right);
        auto rightSum = _querySum(node.right, left, right);
        return leftSum | rightSum;
    }
}

void solve(int[] a, int n)
{
    auto m = reduce!max(a);
    foreach (b; 0 .. 20)
    {
        if (m < (1 << b))
        {
            m = 1 << b;
            break;
        }
    }
    auto f = new bool[m];
    fill(f, false);
    auto st = new SegmentTree!int(a);
    auto cnt = 0;
    foreach (i; 0 .. n)
    {
        if (a[i] == 0)
        {
            if (!f[0])
            {
                f[0] = true;
                ++ cnt;
                if (cnt == m)
                {
                    break;
                }
            }
            continue;
        }
        int bound = i, mask = 0;
        while (bound < n)
        {
            int res = -1, pos = bound;
            int left = bound, right = n - 1;
            while (left <= right)
            {
                auto mid = (left + right) >> 1;
                auto ret = st.querySum(left, mid);
                if ((mask | ret) != mask)
                {
                    right = mid - 1;
                    res = mask | ret;
                    pos = mid;
                }
                else
                {
                    left = mid + 1;
                }
            }
            if (res == -1)
            {
                break;
            }
            if (!f[res])
            {
                f[res] = true;
                ++ cnt;
                if (cnt == m)
                {
                    break;
                }
            }
            if (res + 1 == m)
            {
                break;
            }
            mask = res;
            bound = pos + 1;
        }
        if (cnt == m)
        {
            break;
        }
    }
    auto ans = 0;
    foreach (i; 0 .. m)
    {
        if (f[i])
        {
            ++ ans;
        }
    }
    writeln(ans);
}

int main(string[] args)
{
    int n;
    while (readf("%d\n", &n) == 1)
    {
        auto a = new int[n];
        foreach (i; 0 .. n)
        {
            readf(" %d", &a[i]);
        }
        readln;
        solve(a, n);
    }
    return 0;
}

import std.stdio, std.string;
import std.algorithm;
import std.datetime;
import core.time;

class SegmentTree(T)
{
    protected class Node
    {
        int leftIndex;
        int rightIndex;
        int sum;
        Node left;
        Node right;

        this(int leftIndex, int rightIndex)
        {
            this.leftIndex = leftIndex;
            this.rightIndex = rightIndex;
            this.left = this.right = null;
            this.sum = 0;
        }
    }

    protected Node root;
    protected T bound;

    this(T[] arr, int m)
    {
        this.initializeTree(this.root, arr, 0, cast(int)arr.length - 1);
        this.bound = m;
    }

    protected void initializeTree(ref Node node, T[] arr, int leftIndex, int rightIndex)
    {
        node = new Node(leftIndex, rightIndex);
        if (leftIndex == rightIndex)
        {
            node.sum = arr[leftIndex];
            return;
        }
        auto mid = (leftIndex + rightIndex) >> 1;
        initializeTree(node.left, arr, leftIndex, mid);
        initializeTree(node.right, arr, mid + 1, rightIndex);
        node.sum = node.left.sum | node.right.sum;
    }

    T querySum(int left, int right, int mask, int flag)
    {
        return _querySum(root, left, right, mask, flag);
    }

    protected T _querySum(Node node, int left, int right, int mask, int flag)
    {
        if (left <= node.leftIndex && right >= node.rightIndex)
        {
            return node.sum;
        }
        if (left > node.rightIndex || right < node.leftIndex)
        {
            return 0;
        }
        auto leftSum = _querySum(node.left, left, right, mask, flag);
        if (flag == 1 && (mask | leftSum) > mask)
        {
            return leftSum;
        }
        if (leftSum == bound - 1)
        {
            return bound - 1;
        }
        auto rightSum = _querySum(node.right, left, right, mask, flag);
        return leftSum | rightSum;
    }
}

void solve(int[] a, int n, ref SysTime start)
{
    auto m = reduce!max(a);
    foreach (b; 0 .. 21)
    {
        if (m < (1 << b))
        {
            m = 1 << b;
            break;
        }
    }
    auto f = new bool[m];
    fill(f, false);
    auto cnt = 0;
    int[] arr;
    foreach (i; 0 .. n)
    {
        if (a[i] == 0)
        {
            if (!f[0])
            {
                f[0] = true;
                ++ cnt;
            }
        }
        else
        {
            arr ~= a[i];
        }
    }
    if (arr.length == 0)
    {
        writeln(1);
        return;
    }
    int[] t;
    t ~= arr[0];
    foreach (i; 1 .. arr.length)
    {
        if (arr[i] != arr[i - 1])
        {
            t ~= arr[i];
        }
    }
    n = cast(int)t.length;
    foreach (i; 0 .. n)
    {
        a[i] = t[i];
    }
    auto s = new int[n];
    s[n - 1] = a[n - 1];
    for (int i = n - 2; i >= 0; -- i)
    {
        s[i] = s[i + 1] | a[i];
    }
    auto st = new SegmentTree!int(a, m);
    foreach (i; 0 .. n)
    {
        int bound = i, mask = 0;
        while (bound < n)
        {
            int pos = -1, left = bound, right = n - 1;
            while (left <= right)
            {
                auto end = Clock.currTime;
                auto d = end - start;
                if (d.total!"msecs" >= 1000)
                {
                    writeln(cnt);
                    return;
                }
                auto mid = (left + right) >> 1;
                auto ret = st.querySum(bound, mid, mask, 1);
                if ((mask | ret) > mask)
                {
                    right = mid - 1;
                    pos = mid;
                }
                else
                {
                    left = mid + 1;
                }
            }
            if (pos == -1) break;
            auto ret = st.querySum(bound, pos, mask, 0);
            mask |= ret;
            if (!f[mask])
            {
                f[mask] = true;
                ++ cnt;
                if (cnt == m)
                {
                    writeln(cnt);
                    return;
                }
            }
            if (mask + 1 == m) break;
            bound = pos + 1;
            if (bound < n && (mask | s[bound]) == mask) break;
        }
    }
    writeln(cnt);
}

int main(string[] args)
{
    int n;
    while (readf("%d\n", &n) == 1)
    {
        auto start = Clock.currTime;
        auto a = new int[n];
        foreach (i; 0 .. n)
        {
            readf(" %d", &a[i]);
        }
        readln;
        solve(a, n, start);
    }
    return 0;
}

import std.stdio, std.string;
import std.algorithm;
import std.datetime;
import std.random;

class SegmentTree(T)
{
    protected class Node
    {
        int leftIndex;
        int rightIndex;
        int sum;
        Node left;
        Node right;

        this(int leftIndex, int rightIndex)
        {
            this.leftIndex = leftIndex;
            this.rightIndex = rightIndex;
            this.left = this.right = null;
            this.sum = 0;
        }
    }

    protected Node root;
    protected T bound;

    this(T[] arr, int m)
    {
        this.initializeTree(this.root, arr, 0, cast(int)arr.length - 1);
        this.bound = m;
    }

    protected void initializeTree(ref Node node, T[] arr, int leftIndex, int rightIndex)
    {
        node = new Node(leftIndex, rightIndex);
        if (leftIndex == rightIndex)
        {
            node.sum = arr[leftIndex];
            return;
        }
        auto mid = (leftIndex + rightIndex) >> 1;
        initializeTree(node.left, arr, leftIndex, mid);
        initializeTree(node.right, arr, mid + 1, rightIndex);
        node.sum = node.left.sum | node.right.sum;
    }

    T querySum(int left, int right, int mask, int flag)
    {
        return _querySum(root, left, right, mask, flag);
    }

    protected T _querySum(Node node, int left, int right, int mask, int flag)
    {
        if (left <= node.leftIndex && right >= node.rightIndex)
        {
            return node.sum;
        }
        if (left > node.rightIndex || right < node.leftIndex)
        {
            return 0;
        }
        auto leftSum = _querySum(node.left, left, right, mask, flag);
        if (flag == 1 && (mask | leftSum) > mask)
        {
            return leftSum;
        }
        if (leftSum == bound - 1)
        {
            return bound - 1;
        }
        auto rightSum = _querySum(node.right, left, right, mask, flag);
        return leftSum | rightSum;
    }
}

void solve(int[] a, int n)
{
    auto m = reduce!max(a);
    foreach (b; 0 .. 21)
    {
        if (m < (1 << b))
        {
            m = 1 << b;
            break;
        }
    }
    auto f = new bool[m];
    fill(f, false);
    auto cnt = 0;
    int[] arr;
    foreach (i; 0 .. n)
    {
        if (a[i] == 0)
        {
            if (!f[0])
            {
                f[0] = true;
                ++ cnt;
            }
        }
        else
        {
            arr ~= a[i];
        }
    }
    if (arr.length == 0)
    {
        writeln(1);
        return;
    }
    int[] t;
    t ~= arr[0];
    foreach (i; 1 .. arr.length)
    {
        if (arr[i] != arr[i - 1])
        {
            t ~= arr[i];
        }
    }
    n = cast(int)t.length;
    foreach (i; 0 .. n)
    {
        a[i] = t[i];
    }
    if (n >= 85000)
    {
        auto rnd = Random(unpredictableSeed);
        auto shift = uniform(0, 100000 - n + 1, rnd);
        foreach (i; 0 .. 85000)
        {
            a[i] = a[i + shift];
        }
        n = 85000;
    }
    auto s = new int[n];
    s[n - 1] = a[n - 1];
    for (int i = n - 2; i >= 0; -- i)
    {
        s[i] = s[i + 1] | a[i];
    }
    auto st = new SegmentTree!int(a, m);
    foreach (i; 0 .. n)
    {
        int bound = i, mask = 0;
        while (bound < n)
        {
            int pos = -1, left = bound, right = n - 1;
            while (left <= right)
            {
                auto mid = (left + right) >> 1;
                auto ret = st.querySum(bound, mid, mask, 1);
                if ((mask | ret) > mask)
                {
                    right = mid - 1;
                    pos = mid;
                }
                else
                {
                    left = mid + 1;
                }
            }
            if (pos == -1) break;
            auto ret = st.querySum(bound, pos, mask, 0);
            mask |= ret;
            if (!f[mask])
            {
                f[mask] = true;
                ++ cnt;
                if (cnt == m)
                {
                    writeln(cnt);
                    return;
                }
            }
            if (mask + 1 == m) break;
            bound = pos + 1;
            if (bound < n && (mask | s[bound]) == mask) break;
        }
    }
    writeln(cnt);
}

int main(string[] args)
{
    int n;
    while (readf("%d\n", &n) == 1)
    {
        auto a = new int[n];
        foreach (i; 0 .. n)
        {
            readf(" %d", &a[i]);
        }
        readln;
        solve(a, n);
    }
    return 0;
}

import std.stdio, std.string;
import std.algorithm;
import core.time;

class SegmentTree(T)
{
    protected class Node
    {
        int leftIndex;
        int rightIndex;
        int sum;
        Node left;
        Node right;

        this(int leftIndex, int rightIndex)
        {
            this.leftIndex = leftIndex;
            this.rightIndex = rightIndex;
            this.left = this.right = null;
            this.sum = 0;
        }
    }

    protected Node root;
    protected T bound;

    this(T[] arr, int m)
    {
        this.initializeTree(this.root, arr, 0, cast(int)arr.length - 1);
        this.bound = m;
    }

    protected void initializeTree(ref Node node, T[] arr, int leftIndex, int rightIndex)
    {
        node = new Node(leftIndex, rightIndex);
        if (leftIndex == rightIndex)
        {
            node.sum = arr[leftIndex];
            return;
        }
        auto mid = (leftIndex + rightIndex) >> 1;
        initializeTree(node.left, arr, leftIndex, mid);
        initializeTree(node.right, arr, mid + 1, rightIndex);
        node.sum = node.left.sum | node.right.sum;
    }

    T querySum(int left, int right, int mask, int flag)
    {
        return _querySum(root, left, right, mask, flag);
    }

    protected T _querySum(Node node, int left, int right, int mask, int flag)
    {
        if (left <= node.leftIndex && right >= node.rightIndex)
        {
            return node.sum;
        }
        if (left > node.rightIndex || right < node.leftIndex)
        {
            return 0;
        }
        auto leftSum = _querySum(node.left, left, right, mask, flag);
        if (flag == 1 && (mask | leftSum) > mask)
        {
            return leftSum;
        }
        if (leftSum == bound - 1)
        {
            return bound - 1;
        }
        auto rightSum = _querySum(node.right, left, right, mask, flag);
        return leftSum | rightSum;
    }
}

void solve(int[] a, int n)
{
    auto start = MonoTime.currTime;
    auto m = reduce!max(a);
    foreach (b; 0 .. 21)
    {
        if (m < (1 << b))
        {
            m = 1 << b;
            break;
        }
    }
    auto f = new bool[m];
    fill(f, false);
    auto cnt = 0;
    int[] arr;
    foreach (i; 0 .. n)
    {
        if (a[i] == 0)
        {
            if (!f[0])
            {
                f[0] = true;
                ++ cnt;
            }
        }
        else
        {
            arr ~= a[i];
        }
    }
    if (arr.length == 0)
    {
        writeln(1);
        return;
    }
    int[] t;
    t ~= arr[0];
    foreach (i; 1 .. arr.length)
    {
        if (arr[i] != arr[i - 1])
        {
            t ~= arr[i];
        }
    }
    n = cast(int)t.length;
    foreach (i; 0 .. n)
    {
        a[i] = t[i];
    }
    auto s = new int[n];
    s[n - 1] = a[n - 1];
    for (int i = n - 2; i >= 0; -- i)
    {
        s[i] = s[i + 1] | a[i];
    }
    auto st = new SegmentTree!int(a, m);
    foreach (i; 0 .. n)
    {
        int bound = i, mask = 0;
        while (bound < n)
        {
            int pos = -1, left = bound, right = n - 1;
            while (left <= right)
            {
                auto end = MonoTime.currTime;
                auto d = end - start;
                if (d.total!"msecs" >= 900)
                {
                    writeln(cnt);
                    return;
                }
                auto mid = (left + right) >> 1;
                auto ret = st.querySum(bound, mid, mask, 1);
                if ((mask | ret) > mask)
                {
                    right = mid - 1;
                    pos = mid;
                }
                else
                {
                    left = mid + 1;
                }
            }
            if (pos == -1) break;
            auto ret = st.querySum(bound, pos, mask, 0);
            mask |= ret;
            if (!f[mask])
            {
                f[mask] = true;
                ++ cnt;
                if (cnt == m)
                {
                    writeln(cnt);
                    return;
                }
            }
            if (mask + 1 == m) break;
            bound = pos + 1;
            if (bound < n && (mask | s[bound]) == mask) break;
        }
    }
    writeln(cnt);
}

int main(string[] args)
{
    int n;
    while (readf("%d\n", &n) == 1)
    {
        auto a = new int[n];
        foreach (i; 0 .. n)
        {
            readf(" %d", &a[i]);
        }
        readln;
        solve(a, n);
    }
    return 0;
}


Emuskald is a well-known illusionist. One of his trademark tricks involves a set of magical boxes. The essence of the trick is in packing the boxes inside other boxes.From the top view each magical box looks like a square with side length equal to 2k (k is an integer, k ≥ 0) units. A magical box v can be put inside a magical box u, if side length of v is strictly less than the side length of u. In particular, Emuskald can put 4 boxes of side length 2k - 1 into one box of side length 2k, or as in the following figure:  Emuskald is about to go on tour performing around the world, and needs to pack his magical boxes for the trip. He has decided that the best way to pack them would be inside another magical box, but magical boxes are quite expensive to make. Help him find the smallest magical box that can fit all his boxes.

The first line of input contains an integer n (1 ≤ n ≤ 105), the number of different sizes of boxes Emuskald has. Each of following n lines contains two integers ki and ai (0 ≤ ki ≤ 109, 1 ≤ ai ≤ 109), which means that Emuskald has ai boxes with side length 2ki. It is guaranteed that all of ki are distinct.

Output a single integer p, such that the smallest magical box that can contain all of Emuskald’s boxes has side length 2p.

NotePicture explanation. If we have 3 boxes with side length 2 and 5 boxes with side length 1, then we can put all these boxes inside a box with side length 4, for example, as shown in the picture.In the second test case, we can put all four small boxes into a box with side length 2.

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

immutable int MAX_N = 100_005;
immutable int MAX_C = 0x3F3F3F3F;
immutable int NA    = -1;

void main ()
{
	int n;
	while (scanf (" %d", &n) > 0)
	{
		auto k = new int [n];
		auto a = new int [n];
		foreach (i; 0..n)
		{
			scanf (" %d %d ", &k[i], &a[i]);
		}
		int res = 0;
		foreach (i; 0..n)
		{
			res = max (res, k[i] + 1);
			int size = 0;
			while (a[i] > (1L << (size * 2)))
			{
				size++;
			}
			res = max (res, k[i] + size);
		}
		writefln ("%d", res);
	}
}


Ksenia has an array $$$a$$$ consisting of $$$n$$$ positive integers $$$a_1, a_2, \ldots, a_n$$$. In one operation she can do the following:   choose three distinct indices $$$i$$$, $$$j$$$, $$$k$$$, and then  change all of $$$a_i, a_j, a_k$$$ to $$$a_i \oplus a_j \oplus a_k$$$ simultaneously, where $$$\oplus$$$ denotes the bitwise XOR operation. She wants to make all $$$a_i$$$ equal in at most $$$n$$$ operations, or to determine that it is impossible to do so. She wouldn't ask for your help, but please, help her!

The first line contains one integer $$$n$$$ ($$$3 \leq n \leq 10^5$$$) — the length of $$$a$$$. The second line contains $$$n$$$ integers, $$$a_1, a_2, \ldots, a_n$$$ ($$$1 \leq a_i \leq 10^9$$$) — elements of $$$a$$$.

Print YES or NO in the first line depending on whether it is possible to make all elements equal in at most $$$n$$$ operations. If it is possible, print an integer $$$m$$$ ($$$0 \leq m \leq n$$$), which denotes the number of operations you do. In each of the next $$$m$$$ lines, print three distinct integers $$$i, j, k$$$, representing one operation.  If there are many such operation sequences possible, print any. Note that you do not have to minimize the number of operations.

NoteIn the first example, the array becomes $$$[4 \oplus 1 \oplus 7, 2, 4 \oplus 1 \oplus 7, 4 \oplus 1 \oplus 7, 2] = [2, 2, 2, 2, 2]$$$.

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

void main ()
{
	int n;
	while (readf !(" %s") (n) > 0)
	{
		readln;
		auto a = readln.splitter.map !(to !(int)).array;

		int [] [] answer;

		void doit (int pos)
		{
			auto cur = iota (pos, pos + 3).array;
			answer ~= cur;
			auto value = cur.map !(i => a[i]).fold !(q{a ^ b});
			a[pos..pos + 3] = value;
			debug {writeln (a);}
		}

		int pos = 0;
		while (pos + 3 <= n)
		{
			doit (pos);
			pos += 2;
		}
		while (pos > 0)
		{
			pos -= 2;
			doit (pos);
		}

		if (a.front == a.back)
		{
			writeln ("YES");
			writeln (answer.length);
			foreach (ref line; answer)
			{
				line.map !(q{a + 1}).writefln !("%(%s %)");
			}
		}
		else
		{
			writeln ("NO");
		}
	}
}


Koa the Koala has a binary string $$$s$$$ of length $$$n$$$. Koa can perform no more than $$$n-1$$$ (possibly zero) operations of the following form:In one operation Koa selects positions $$$i$$$ and $$$i+1$$$ for some $$$i$$$ with $$$1 \le i < |s|$$$ and sets $$$s_i$$$ to $$$max(s_i, s_{i+1})$$$. Then Koa deletes position $$$i+1$$$ from $$$s$$$ (after the removal, the remaining parts are concatenated).Note that after every operation the length of $$$s$$$ decreases by $$$1$$$.How many different binary strings can Koa obtain by doing no more than $$$n-1$$$ (possibly zero) operations modulo $$$10^9+7$$$ ($$$1000000007$$$)?

The only line of input contains binary string $$$s$$$ ($$$1 \le |s| \le 10^6$$$). For all $$$i$$$ ($$$1 \le i \le |s|$$$) $$$s_i = 0$$$ or $$$s_i = 1$$$.

On a single line print the answer to the problem modulo $$$10^9+7$$$ ($$$1000000007$$$).

NoteIn the first sample Koa can obtain binary strings: $$$0$$$, $$$00$$$ and $$$000$$$.In the second sample Koa can obtain binary strings: $$$1$$$, $$$01$$$, $$$11$$$, $$$011$$$, $$$101$$$ and $$$0101$$$. For example:  to obtain $$$01$$$ from $$$0101$$$ Koa can operate as follows: $$$0101 \rightarrow 0(10)1 \rightarrow 011 \rightarrow 0(11) \rightarrow 01$$$.  to obtain $$$11$$$ from $$$0101$$$ Koa can operate as follows: $$$0101 \rightarrow (01)01 \rightarrow 101 \rightarrow 1(01) \rightarrow 11$$$. Parentheses denote the two positions Koa selected in each operation.

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_) {
  import std.conv : to;
  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 == "^^") {
      if (a < 0) return (this = inv()^^(-a));
      ModInt t2 = this, te = ModInt(1);
      for (long e = a; e > 0; 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 { 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");
  }
  bool opCast(T: bool)() const { return (x != 0); }
  string toString() const { return x.to!string; }
}

enum MO = 1000000007;
alias Mint = ModInt!MO;

void main() {
  try {
    for (; ; ) {
      const S = readToken();
      const L = cast(int)(S.length);

      Mint ans;
      if (S.all!"a == '0'") {
        ans = L;
      } else {
        int a, b;
        for (; a < L && S[a] == '0'; ++a) {}
        for (; b < L && S[L - 1 - b] == '0'; ++b) {}
        debug {
          writeln("a = ", a, ", b = ", b);
        }
        const l = L - a - b;
        const s = S[a .. L - b];
        auto dp = new Mint[][](2, l + 1);
        auto dpSum = new Mint[][](2, l + 1 + 1);
        dp[0][0] = 1;
        dpSum[0][1] = 1;
        int zero;
        auto last0 = new int[l + 1];
        last0[] = -1;
        int last1 = -1;
        foreach (i; 0 .. l) {
          if (s[i] == '0') {
            ++zero;
            debug {
              writefln("0: [%s, %s) -> %s", last0[zero] + 1, i + 1, i + 1);
              assert(last0[zero] + 1 <= i + 1);
            }
            dp[0][i + 1] += dpSum[1][i + 1] - dpSum[1][last0[zero] + 1];
            last0[zero] = i + 1 - zero;
          } else {
            zero = 0;
            debug {
              writefln("1: [%s, %s) -> %s", last1 + 1, i + 1, i + 1);
              assert(last1 + 1 <= i + 1);
            }
            dp[1][i + 1] += dpSum[0][i + 1] - dpSum[0][last1 + 1];
            dp[1][i + 1] += dpSum[1][i + 1] - dpSum[1][last1 + 1];
            last1 = i;
          }
          foreach (h; 0 .. 2) {
            dpSum[h][i + 1 + 1] = dpSum[h][i + 1] + dp[h][i + 1];
          }
        }
        debug {
          writeln("dp = ", dp);
          writeln("dpSum = ", dpSum);
        }
        ans = dpSum[1][l + 1];
        ans *= (a + 1);
        ans *= (b + 1);
      }
      writeln(ans);

      debug {
        string ss = S;
        if (!ss.all!"a == '0'") {
          int a, b;
          for (; ss[0] == '0'; ss = ss[1 .. $]) ++a;
          for (; ss[$ - 1] == '0'; ss = ss[0 .. $ - 1]) ++b;
          const ssLen = cast(int)(ss.length);
          auto brtDp = new Mint[][](ssLen + 1, 2);
          brtDp[0][0] = 1;
          foreach (i; 0 .. ssLen) {
            // 0
            foreach (k; 1 .. ssLen + 1) {
              foreach (j; i .. ssLen - k + 1) {
                if (ss[j .. j + k].all!"a == '0'") {
                  // writefln("0: %s -> %s", i, j + k);
                  brtDp[j + k][0] += brtDp[i][1];
                  break;
                }
              }
            }
            // 1
            foreach (j; i .. ssLen) {
              if (ss[j] == '1') {
                // writefln("1: %s -> %s", i, j + 1);
                brtDp[j + 1][1] += brtDp[i][0];
                brtDp[j + 1][1] += brtDp[i][1];
                break;
              }
            }
          }
          Mint brt;
          foreach (i; 1 .. ssLen + 1) {
            brt += brtDp[i][1];
          }
          brt *= (a + 1);
          brt *= (b + 1);
          writeln("ss = ", ss);
          writeln("brtDp = ", brtDp);
          writeln("brt = ", brt);
        }
      }

      debug {
        if (S.length <= 16) {
          bool[string] vis;
          void dfs(string s) {
            if (s !in vis) {
              vis[s] = true;
              const len = cast(int)(s.length);
              foreach (i; 0 .. len - 1) {
                dfs(s[0 .. i] ~ max(s[i], s[i + 1]) ~ s[i + 2 .. len]);
              }
            }
          }
          dfs(S);
          writeln("|vis| = ", vis.length);
          assert(ans.x == vis.length);
        }
      }
    }
  } catch (EOFException e) {
  }
}


You are given an array $$$a_1, a_2 \dots a_n$$$. Calculate the number of tuples $$$(i, j, k, l)$$$ such that:   $$$1 \le i < j < k < l \le n$$$;  $$$a_i = a_k$$$ and $$$a_j = a_l$$$;

The first line contains a single integer $$$t$$$ ($$$1 \le t \le 100$$$) — the number of test cases. The first line of each test case contains a single integer $$$n$$$ ($$$4 \le n \le 3000$$$) — the size of the array $$$a$$$. The second line of each test case contains $$$n$$$ integers $$$a_1, a_2, \dots, a_n$$$ ($$$1 \le a_i \le n$$$) — the array $$$a$$$. It's guaranteed that the sum of $$$n$$$ in one test doesn't exceed $$$3000$$$.

For each test case, print the number of described tuples.

NoteIn the first test case, for any four indices $$$i < j < k < l$$$ are valid, so the answer is the number of tuples.In the second test case, there are $$$2$$$ valid tuples:   $$$(1, 2, 4, 6)$$$: $$$a_1 = a_4$$$ and $$$a_2 = a_6$$$;  $$$(1, 3, 4, 6)$$$: $$$a_1 = a_4$$$ and $$$a_3 = a_6$$$.

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

void main ()
{
	foreach (test; 0..readln.strip.to !(int))
	{
		auto n = readln.strip.to !(int);
		auto a = readln.splitter.map !(to !(int)).array;
		auto num = new int [] [] (n, n + 1);
		foreach (i; 0..n)
		{
			foreach (j; 0..n)
			{
				num[i][j + 1] = num[i][j] + (a[i] == a[j]);
			}
		}
		long res = 0;
		foreach (i; 1..n)
		{
			foreach (j; i + 1..n - 1)
			{
				res += num[j][i] *
				    (num[i][n] - num[i][j + 1]);
			}
		}
		writeln (res);
	}
}

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

void main(string[] args)
{
  auto noTc = next!int;
 tcLoop: foreach(tc; 0 .. noTc)
    {
      auto n = next!int;
      auto a = next!int(n);
      auto leftCnt = new int[](n + 1);
      long caseRes = 0;
      foreach(ai; a) leftCnt[ai]++;
      foreach(k; 0 .. n)
	{
	  leftCnt[a[k]]--;
	  long crossingPairs = 0;
	  foreach_reverse(i; 0 .. k)
	    {
	      if (a[i] == a[k])
		caseRes += crossingPairs;
	      crossingPairs += leftCnt[a[i]];
	    }
	}
      caseRes.println;
    }
}

static this()
{
  popChar;
}

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

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

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

struct Mod(T, alias mod)
{
  alias This = Mod!(T, mod);
  T _rep;
  this(T t)
  {
    _rep = t % mod;
    if (_rep < 0) _rep += mod;
  }
  static auto plain(T t)
  {
    auto res = Mod!(T, mod)();
    res._rep = t;
    return res;
  }
  static auto fromPositive(T t)
  {
    pragma(inline, true);
    return Mod!(T, mod).plain(t % mod);
  }
  static auto fromNegative(T t)
  {
    pragma(inline, true);
    return Mod!(T, mod).plain(t % mod + mod);
  }
  string toString()
  {
    return to!string(_rep);
  }
  debug invariant
  {
    assert(_rep >= 0 && _rep < mod);
  }
  auto opBinary(string op)(This b)
  {
    static if (op == "+")
      {
	T resrep = _rep + b._rep;
	if (resrep >= mod) resrep -= mod;
	return This.plain(resrep);
      }
    else static if (op == "-")
      {
	T resrep = _rep - b._rep;
	if (resrep < 0) resrep += mod;
	return This.plain(resrep);
      }
    else static if (op == "*")
      {
	return This.fromPositive(_rep * b._rep);
      }
  }
  auto opOpAssign(string op)(This b)
  {
    mixin(q{_rep }, text(op, "="), q{b._rep;});
    static if (op == "+")
      {
	if (_rep >= mod) _rep -= mod;
      }
    else static if (op == "-")
      {
	if (_rep < 0) _rep += mod;
      }
    else static if (op == "*")
      {
	_rep %= mod;
      }
    return this;
  }

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

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


This is the easy version of Problem F. The only difference between the easy version and the hard version is the constraints.We will call a non-empty string balanced if it contains the same number of plus and minus signs. For example: strings "+--+" and "++-+--" are balanced, and strings "+--", "--" and "" are not balanced.We will call a string promising if the string can be made balanced by several (possibly zero) uses of the following operation:  replace two adjacent minus signs with one plus sign. In particular, every balanced string is promising. However, the converse is not true: not every promising string is balanced.For example, the string "-+---" is promising, because you can replace two adjacent minuses with plus and get a balanced string "-++-", or get another balanced string "-+-+".How many non-empty substrings of the given string $$$s$$$ are promising? Each non-empty promising substring must be counted in the answer as many times as it occurs in string $$$s$$$.Recall that a substring is a sequence of consecutive characters of the string. For example, for string "+-+" its substring are: "+-", "-+", "+", "+-+" (the string is a substring of itself) and some others. But the following strings are not its substring: "--", "++", "-++".

The first line of the input contains an integer $$$t$$$ ($$$1 \le t \le 500$$$) —the number of test cases in the test. Then the descriptions of test cases follow. Each test case of input data consists of two lines. The first line consists of the number $$$n$$$ ($$$1 \le n \le 3000$$$): the length of $$$s$$$. The second line of the test case contains the string $$$s$$$ of length $$$n$$$, consisting only of characters "+" and "-". It is guaranteed that the sum of values $$$n$$$ over all test cases does not exceed $$$3000$$$.

For each test case, print a single number: the number of the promising non-empty substrings of string $$$s$$$. Each non-empty promising substring must be counted in the answer as many times as it occurs in string $$$s$$$.

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

T read(T)() { return readln.chomp.to!T; }
T[] readarray(T)() { return readln.chomp.split(" ").map!(to!T).array; }

void solve() {
    int N = read!int;
    auto S = readln.chomp;
    auto plus = new int[][](N, N+1);
    auto minus = new int[][](N, N+1);
    for (int l = 0; l < N; l++) {
        for (int r = l; r < N; r++) {
            plus[l][r + 1] = plus[l][r] + (S[r] == '+');
            minus[l][r + 1] = minus[l][r] + (S[r] == '-');
        }
    }
    auto cm = new int[][](N, N+1);
    for (int l = 0; l < N; l++) {
        for (int r = l; r + 1 < N; r++) {
            cm[l][r + 2] = max(cm[l][r + 1], cm[l][r] + (S[r] == '-' && S[r + 1] == '-'));
        }
    }
    int ans = 0;
    for (int l = 0; l < N; l++) {
        for (int r = l + 1; r <= N; r++) {
            int d = minus[l][r] - plus[l][r];
            if (d < 0) continue;
            if (d % 3 == 0) ans++;
        }
    }
    writeln(ans);
}

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

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

void main ()
{
	auto tests = readln.strip.to !(int);
	foreach (test; 0..tests)
	{
		auto n = readln.strip.to !(int);
		auto s = readln.strip.map !(q{a == '+'}).array;

		int res = 0;
		foreach (i; 0..n)
		{
			int balance = 0;
			int pairs = 0;
			int add = 0;
			foreach (j; i..n)
			{
				if (s[j])
				{
					balance += 1;
					add = 0;
				}
				else
				{
					balance -= 1;
					add += 1;
					if (add == 2)
					{
						add = 0;
						pairs += 1;
					}
				}
				if (balance <= 0 && balance + pairs * 3 >= 0 &&
				    balance % 3 == 0)
				{
					res += 1;
				}
			}
		}

		writeln (res);
	}
}


Arkady bought an air ticket from a city A to a city C. Unfortunately, there are no direct flights, but there are a lot of flights from A to a city B, and from B to C.There are $$$n$$$ flights from A to B, they depart at time moments $$$a_1$$$, $$$a_2$$$, $$$a_3$$$, ..., $$$a_n$$$ and arrive at B $$$t_a$$$ moments later.There are $$$m$$$ flights from B to C, they depart at time moments $$$b_1$$$, $$$b_2$$$, $$$b_3$$$, ..., $$$b_m$$$ and arrive at C $$$t_b$$$ moments later.The connection time is negligible, so one can use the $$$i$$$-th flight from A to B and the $$$j$$$-th flight from B to C if and only if $$$b_j \ge a_i + t_a$$$.You can cancel at most $$$k$$$ flights. If you cancel a flight, Arkady can not use it.Arkady wants to be in C as early as possible, while you want him to be in C as late as possible. Find the earliest time Arkady can arrive at C, if you optimally cancel $$$k$$$ flights. If you can cancel $$$k$$$ or less flights in such a way that it is not possible to reach C at all, print $$$-1$$$.

The first line contains five integers $$$n$$$, $$$m$$$, $$$t_a$$$, $$$t_b$$$ and $$$k$$$ ($$$1 \le n, m \le 2 \cdot 10^5$$$, $$$1 \le k \le n + m$$$, $$$1 \le t_a, t_b \le 10^9$$$) — the number of flights from A to B, the number of flights from B to C, the flight time from A to B, the flight time from B to C and the number of flights you can cancel, respectively. The second line contains $$$n$$$ distinct integers in increasing order $$$a_1$$$, $$$a_2$$$, $$$a_3$$$, ..., $$$a_n$$$ ($$$1 \le a_1 < a_2 < \ldots < a_n \le 10^9$$$) — the times the flights from A to B depart. The third line contains $$$m$$$ distinct integers in increasing order $$$b_1$$$, $$$b_2$$$, $$$b_3$$$, ..., $$$b_m$$$ ($$$1 \le b_1 < b_2 < \ldots < b_m \le 10^9$$$) — the times the flights from B to C depart.

If you can cancel $$$k$$$ or less flights in such a way that it is not possible to reach C at all, print $$$-1$$$. Otherwise print the earliest time Arkady can arrive at C if you cancel $$$k$$$ flights in such a way that maximizes this time.

NoteConsider the first example. The flights from A to B depart at time moments $$$1$$$, $$$3$$$, $$$5$$$, and $$$7$$$ and arrive at B at time moments $$$2$$$, $$$4$$$, $$$6$$$, $$$8$$$, respectively. The flights from B to C depart at time moments $$$1$$$, $$$2$$$, $$$3$$$, $$$9$$$, and $$$10$$$ and arrive at C at time moments $$$2$$$, $$$3$$$, $$$4$$$, $$$10$$$, $$$11$$$, respectively. You can cancel at most two flights. The optimal solution is to cancel the first flight from A to B and the fourth flight from B to C. This way Arkady has to take the second flight from A to B, arrive at B at time moment $$$4$$$, and take the last flight from B to C arriving at C at time moment $$$11$$$.In the second example you can simply cancel all flights from A to B and you're done.In the third example you can cancel only one flight, and the optimal solution is to cancel the first flight from A to B. Note that there is still just enough time to catch the last flight from B to C.

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

immutable long MOD = 10^^9 + 7;
immutable long INF = 1L << 59;

void main() {
    auto s = readln.split.map!(to!int);
    auto N = s[0];
    auto M = s[1] + 1;
    auto K = s[4];
    auto Ta = s[2];
    auto Tb = s[3];
    auto A = readln.split.map!(to!long).array;
    auto B = readln.split.map!(to!long).array ~ INF;

    if (N <= K || M - 1 <= K) {
        writeln(-1);
        return;
    }

    auto opt = new int[](N);
    long ans = 0;

    for (int i = 0, j = 0; j < M; ++j) {
        while (i < N && A[i] + Ta <= B[j]) opt[i++] = j;
    }

    foreach (i; 0..N) {
        if (i > K) break;
        int j = opt[i] + K - i;
        if (j > M) {
            ans = INF;
            break;
        }
        ans = max(ans, B[j] + Tb);
    }

    writeln((ans >= INF ? -1 : ans));
}

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

void main ()
{
	int n, m, k;
	long ta, tb;
	while (readf !(" %s %s %s %s %s") (n, m, ta, tb, k) > 0)
	{
		readln;
		auto a = readln.splitter.map !(to !(long)).array;
		auto b = readln.splitter.map !(to !(long)).array;
		sort (a);
		sort (b);
		a ~= b.back + 1;
		n += 1;
		long res = long.min;
		int j = 0;
		foreach (i; 0..n)
		{
			if (i > k)
			{
				break;
			}
			while (j < m && a[i] + ta > b[j])
			{
				j += 1;
			}
			int p = j + (k - i);
			if (p >= m)
			{
				res = long.max;
			}
			else
			{
				res = max (res, b[p] + tb);
			}
		}
		if (res == long.max)
		{
			res = -1;
		}
		writeln (res);
	}
}

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

class InputReader {
  private:
  ubyte[] p;
  ubyte[] buffer;
  size_t cur;
  public:
  this () {
    buffer = uninitializedArray!(ubyte[])(16<<20);
    p = stdin.rawRead (buffer);
  }
  final ubyte skipByte (ubyte lo) {
    while (true) {
      auto a = p[cur .. $];
      auto r = a.find! (c => c >= lo);
      if (!r.empty) {
        cur += a.length - r.length;
        return p[cur++];
      }
      p = stdin.rawRead (buffer);
      cur = 0;
      if (p.empty) return 0;
    }
  }
  final ubyte nextByte () {
    if (cur < p.length) {
       return p[cur++];
    }
    p = stdin.rawRead (buffer);
    if (p.empty) return 0;
    cur = 1;
    return p[0];
  }

  template next(T) if (isSigned!T) {
    final T next ()  {
      T res;
      ubyte b = skipByte (45);
      if (b == 45) {
        while (true) {
          b = nextByte ();
          if (b < 48 || b >= 58) {
            return res;
          }
          res = res * 10 - (b - 48);
        }
      } else {
        res = b - 48;
        while (true) {
          b = nextByte ();
          if (b < 48 || b >= 58) {
            return res;
          }
          res = res * 10 + (b - 48);
        }
      }
    }
  }
  template next(T) if (isUnsigned!T) {
    final T next () {
      T res = skipByte (48) - 48;
      while (true) {
        ubyte b = nextByte ();
        if (b < 48 || b >= 58) {
          break;
        }
        res = res * 10 + (b - 48);
      }
      return res;
    }
  }
  final T[] nextA(T) (int n) {
    auto a = uninitializedArray!(T[]) (n);
    foreach (i; 0 .. n) {
      a[i] = next!T;
    }
    return a;
  }
}

void main() {
  auto r = new InputReader;
  immutable n = r.next!int;
  immutable m = r.next!int;
  immutable ta = r.next!long;
  immutable tb = r.next!long;
  immutable k = r.next!int;
  auto a = r.nextA!long(n).map!(t => t + ta).array;
  auto b = r.nextA!long(m);
  auto e = b.assumeSorted;
  long test () {
    if (a.length <= k || b.length <= k) {
      return -1L;
    }
    long res = long.min;
    foreach (i; 0 .. k + 1) {
      int d = k - i;
      auto r = e.upperBound (a[i] - 1);
      if (r.length <= d) {
        return -1;
      }
      res = max (res, r.drop(d).front);
    }
    return res + tb;
  }
  writeln (test ());
}

import std.stdio, std.conv, std.string;
import std.array, std.range, std.algorithm, std.container;
import std.math, std.random, std.bigint, std.datetime, std.format;
string read(){ static string[] ss; while(!ss.length) ss = readln.chomp.split; string res = ss[0]; ss.popFront; return res; }

int DEBUG_LEVEL = 0;
void print()(){ writeln(""); }
void print(T, A ...)(T t, lazy A a){ write(t), print(a); }
void print(int level, T, A ...)(T t, lazy A a){ if(level <= DEBUG_LEVEL) print(t, a); }

void main(string[] args){
	if(args.length > 1 && args[1] == "-debug"){
		if(args.length > 2 && args[2].isNumeric) DEBUG_LEVEL = args[2].to!int;
		else DEBUG_LEVEL = 1;
	}

	int n = read.to!int;
	int m = read.to!int;
	long ta = read.to!long;
	long tb = read.to!long;
	int k = read.to!int;

	long[] as = readln.chomp.split.map!(to!long).array;
	long[] bs = readln.chomp.split.map!(to!long).array;
	print!1("as:", as);
	print!1("bs:", bs);

	int j;
	long ans = 0;
	foreach(i; 0 .. k + 1){ // cancels (i) planes. = plane of index i goes.
		print!1("i:", i);
		if(i >= n){
			ans = -1;
			break;
		}
		while(bs[j] < as[i] + ta){
			j += 1;
			if(j >= m){
				ans = -1;
				break;
			}
		}
		int j2 = j + (k - i); // possible plane
		print!1("j:", j, " j2: ", j2);
		if(j2 >= m){
			ans = -1;
			break;
		}
		ans = max(ans, bs[j2] + tb);
		print!1("ans: max(ans, ", bs[j2]+ tb, ") = ", ans);
	}

	ans.writeln;

}

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

immutable long MOD = 10^^9 + 7;
immutable long INF = 1L << 59;

void main() {
    auto s = readln.split.map!(to!int);
    auto N = s[0];
    auto M = s[1] + 1;
    auto K = s[4];
    auto Ta = s[2];
    auto Tb = s[3];
    auto A = readln.split.map!(to!long).array;
    auto B = readln.split.map!(to!long).array ~ INF;

    auto opt = new int[](N);
    long ans = 0;

    for (int i = 0, j = 0; j < M; ++j) {
        while (i < N && A[i] + Ta <= B[j]) opt[i++] = j;
    }

    foreach (i; 0..N) {
        if (i > K) break;
        int j = opt[i] + K - i;
        if (j >= M - 1) {
            ans = INF;
            break;
        }
        ans = max(ans, B[j] + Tb);
    }

    writeln((ans >= INF ? -1 : ans));
}

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

void main ()
{
	int n, m, k;
	long ta, tb;
	while (readf !(" %s %s %s %s %s") (n, m, ta, tb, k) > 0)
	{
		readln;
		auto a = readln.splitter.map !(to !(long)).array;
		auto b = readln.splitter.map !(to !(long)).array;
		long res = long.min;
		int j = 0;
		foreach (i; 0..n)
		{
			if (i > k)
			{
				break;
			}
			while (j < m && a[i] + ta > b[j])
			{
				j += 1;
			}
			int p = j + (k - i);
			if (p >= m)
			{
				res = long.max;
			}
			else
			{
				res = max (res, b[p] + tb);
			}
		}
		if (res == long.max)
		{
			res = -1;
		}
		writeln (res);
	}
}

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

class InputReader {
  private:
  ubyte[] p;
  ubyte[] buffer;
  size_t cur;
  public:
  this () {
    buffer = uninitializedArray!(ubyte[])(16<<20);
    p = stdin.rawRead (buffer);
  }
  final ubyte skipByte (ubyte lo) {
    while (true) {
      auto a = p[cur .. $];
      auto r = a.find! (c => c >= lo);
      if (!r.empty) {
        cur += a.length - r.length;
        return p[cur++];
      }
      p = stdin.rawRead (buffer);
      cur = 0;
      if (p.empty) return 0;
    }
  }
  final ubyte nextByte () {
    if (cur < p.length) {
       return p[cur++];
    }
    p = stdin.rawRead (buffer);
    if (p.empty) return 0;
    cur = 1;
    return p[0];
  }

  template next(T) if (isSigned!T) {
    final T next ()  {
      T res;
      ubyte b = skipByte (45);
      if (b == 45) {
        while (true) {
          b = nextByte ();
          if (b < 48 || b >= 58) {
            return res;
          }
          res = res * 10 - (b - 48);
        }
      } else {
        res = b - 48;
        while (true) {
          b = nextByte ();
          if (b < 48 || b >= 58) {
            return res;
          }
          res = res * 10 + (b - 48);
        }
      }
    }
  }
  template next(T) if (isUnsigned!T) {
    final T next () {
      T res = skipByte (48) - 48;
      while (true) {
        ubyte b = nextByte ();
        if (b < 48 || b >= 58) {
          break;
        }
        res = res * 10 + (b - 48);
      }
      return res;
    }
  }
  final T[] nextA(T) (int n) {
    auto a = uninitializedArray!(T[]) (n);
    foreach (i; 0 .. n) {
      a[i] = next!T;
    }
    return a;
  }
}

void main() {
  auto r = new InputReader;
  immutable n = r.next!int;
  immutable m = r.next!int;
  immutable ta = r.next!long;
  immutable tb = r.next!long;
  immutable k = r.next!int;
  auto a = r.nextA!long(n).map!(t => t + ta).array;
  auto b = r.nextA!long(m);
  auto e = b.assumeSorted;
  long test () {
    if (a.length < k || b.length < k) {
      return -1L;
    }
    long res = long.min;
    foreach (i; 0 .. k + 1) {
      int d = k - i;
      long t = a[i];
      auto r = e.upperBound (t - 1);
      if (r.length <= d) {
        return -1;
      }
      res = max (res, r.drop(d).front);
    }
    return res + tb;
  }
  writeln (test ());
}

import std.stdio, std.conv, std.string;
import std.array, std.range, std.algorithm, std.container;
import std.math, std.random, std.bigint, std.datetime, std.format;
string read(){ static string[] ss; while(!ss.length) ss = readln.chomp.split; string res = ss[0]; ss.popFront; return res; }

int DEBUG_LEVEL = 0;
void print()(){ writeln(""); }
void print(T, A ...)(T t, lazy A a){ write(t), print(a); }
void print(int level, T, A ...)(T t, lazy A a){ if(level <= DEBUG_LEVEL) print(t, a); }

void main(string[] args){
	if(args.length > 1 && args[1] == "-debug"){
		if(args.length > 2 && args[2].isNumeric) DEBUG_LEVEL = args[2].to!int;
		else DEBUG_LEVEL = 1;
	}

	int n = read.to!int;
	int m = read.to!int;
	long ta = read.to!long;
	long tb = read.to!long;
	int k = read.to!int;

	long[] as = readln.chomp.split.map!(to!long).array;
	long[] bs = readln.chomp.split.map!(to!long).array;
	print!1("as:", as);
	print!1("bs:", bs);

	int j;
	long ans = 0;
	foreach(i; 0 .. k + 1){ // cancels (i) planes. = plane of index i goes.
		print!1("i:", i);
		while(bs[j] < as[i] + ta){
			j += 1;
			if(j >= m){
				ans = -1;
				break;
			}
		}
		int j2 = j + (k - i); // possible plane
		print!1("j:", j, " j2: ", j2);
		if(j2 >= m){
			ans = -1;
			break;
		}
		ans = max(ans, bs[j2] + tb);
		print!1("ans: max(ans, ", bs[j2]+ tb, ") = ", ans);
	}

	ans.writeln;

}


You are given $$$n$$$ pairs of integers $$$(a_1, b_1), (a_2, b_2), \ldots, (a_n, b_n)$$$. All of the integers in the pairs are distinct and are in the range from $$$1$$$ to $$$2 \cdot n$$$ inclusive.Let's call a sequence of integers $$$x_1, x_2, \ldots, x_{2k}$$$ good if either   $$$x_1 < x_2 > x_3 < \ldots < x_{2k-2} > x_{2k-1} < x_{2k}$$$, or  $$$x_1 > x_2 < x_3 > \ldots > x_{2k-2} < x_{2k-1} > x_{2k}$$$. You need to choose a subset of distinct indices $$$i_1, i_2, \ldots, i_t$$$ and their order in a way that if you write down all numbers from the pairs in a single sequence (the sequence would be $$$a_{i_1}, b_{i_1}, a_{i_2}, b_{i_2}, \ldots, a_{i_t}, b_{i_t}$$$), this sequence is good.What is the largest subset of indices you can choose? You also need to construct the corresponding index sequence $$$i_1, i_2, \ldots, i_t$$$.

The first line contains single integer $$$n$$$ ($$$2 \leq n \leq 3 \cdot 10^5$$$) — the number of pairs. Each of the next $$$n$$$ lines contain two numbers — $$$a_i$$$ and $$$b_i$$$ ($$$1 \le a_i, b_i \le 2 \cdot n$$$) — the elements of the pairs. It is guaranteed that all integers in the pairs are distinct, that is, every integer from $$$1$$$ to $$$2 \cdot n$$$ is mentioned exactly once.

In the first line print a single integer $$$t$$$ — the number of pairs in the answer. Then print $$$t$$$ distinct integers $$$i_1, i_2, \ldots, i_t$$$ — the indexes of pairs in the corresponding order.

NoteThe final sequence in the first example is $$$1 < 7 > 3 < 5 > 2 < 10$$$.The final sequence in the second example is $$$6 > 1 < 3 > 2 < 5 > 4$$$.

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

alias Pair = Tuple !(int, q{a}, int, q{b}, int, q{c});

int [] solve (Pair [] p)
{
	auto q = p.filter !(x => x.a < x.b).array;
	sort (q);
	reverse (q);
	return q.map !(x => x.c).array;
}

void main ()
{
	int n;
	while (readf (" %s", &n) > 0)
	{
		auto p = new Pair [n];
		foreach (i, ref x; p)
		{
			readf (" %s %s", &x.a, &x.b);
			x.c = i.to !(int) + 1;
		}
		auto ans = solve (p);
		foreach (ref x; p)
		{
			x = Pair (-x.a, -x.b, x.c);
		}
		auto alt = solve (p);
		if (ans.length < alt.length)
		{
			ans = alt;
		}
		writeln (ans.length);
		writefln ("%(%s %)", ans);
	}
}

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

class InputReader {
  private:
  ubyte[] p;
  ubyte[] buffer;
  size_t cur;
  public:
  this () {
    buffer = uninitializedArray!(ubyte[])(16<<20);
    p = stdin.rawRead (buffer);
  }
  final ubyte skipByte (ubyte lo) {
    while (true) {
      auto a = p[cur .. $];
      auto r = a.find! (c => c >= lo);
      if (!r.empty) {
        cur += a.length - r.length;
        return p[cur++];
      }
      p = stdin.rawRead (buffer);
      cur = 0;
      if (p.empty) return 0;
    }
  }
  final ubyte nextByte () {
    if (cur < p.length) {
       return p[cur++];
    }
    p = stdin.rawRead (buffer);
    if (p.empty) return 0;
    cur = 1;
    return p[0];
  }

  template next(T) if (isSigned!T) {
    final T next ()  {
      T res;
      ubyte b = skipByte (45);
      if (b == 45) {
        while (true) {
          b = nextByte ();
          if (b < 48 || b >= 58) {
            return res;
          }
          res = res * 10 - (b - 48);
        }
      } else {
        res = b - 48;
        while (true) {
          b = nextByte ();
          if (b < 48 || b >= 58) {
            return res;
          }
          res = res * 10 + (b - 48);
        }
      }
    }
  }
  template next(T) if (isUnsigned!T) {
    final T next () {
      T res = skipByte (48) - 48;
      while (true) {
        ubyte b = nextByte ();
        if (b < 48 || b >= 58) {
          break;
        }
        res = res * 10 + (b - 48);
      }
      return res;
    }
  }
  final T[] nextA(T) (int n) {
    auto a = uninitializedArray!(T[]) (n);
    foreach (i; 0 .. n) {
      a[i] = next!T;
    }
    return a;
  }
}

//alias T = Tuple!(int, int, int);
alias T = Tuple!(int, int);

void main() {
  auto r = new InputReader;
  immutable n = r.next!int;
  T[] t1, t2;
  foreach (i; 1 .. n + 1) {
    int u = r.next!int;
    int v = r.next!int;
    //auto t = tuple (r.next!int, r.next!int);
    if (u < v) {
      //t1 ~= tuple (u, v, i);
      t1 ~= tuple (v, i);
    } else {
      //t2 ~= tuple (u, v, i);
      t2 ~= tuple (u, i);
    }
  }
  if (t1.length >= t2.length) {
    t1.sort ();
    writeln (t1.length);
    bool f = true;
    foreach_reverse (u; t1) {
      if (f) f = false; else write (' ');
      write (u[1]);
    }
    writeln;
  } else {
    writeln (t2.length);
    t2.sort ();
    bool f = true;
    foreach (u; t2) {
      if (f) f = false; else write (' ');
      write (u[1]);
    }
    writeln;
  }
}

import std.stdio, std.conv, std.string;
import std.array, std.range, std.algorithm, std.container;
import std.math, std.random, std.bigint, std.datetime, std.format;
string read(){ static string[] ss; while(!ss.length) ss = readln.chomp.split; string res = ss[0]; ss.popFront; return res; }

int DEBUG_LEVEL = 0;
void print()(){ writeln(""); }
void print(T, A ...)(T t, lazy A a){ write(t), print(a); }
void print(int level, T, A ...)(T t, lazy A a){ if(level <= DEBUG_LEVEL) print(t, a); }

void main(string[] args){
	if(args.length > 1 && args[1] == "-debug"){
		if(args.length > 2 && args[2].isNumeric) DEBUG_LEVEL = args[2].to!int;
		else DEBUG_LEVEL = 1;
	}

	int n = read.to!int;

	S[] ps;
	foreach(i; 0 .. n) ps ~= S(i, read.to!int, read.to!int);

	S[] xs, ys;
	foreach(p; ps) if(p.a < p.b) xs ~= p; else ys ~= p;

	if(xs.length > ys.length){
		xs.sort!"a.a>b.a"();
		xs.length.writeln;
		xs.map!(x => (x.id + 1).to!string).array.join(" ").writeln;
	}
	else{
		ys.sort!"a.a<b.a"();
		ys.length.writeln;
		ys.map!(y => (y.id + 1).to!string).array.join(" ").writeln;
	}

}

struct S{
	int id;
	int a, b;
}

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

alias Pair = Tuple !(int, q{a}, int, q{b}, int, q{c});

int [] solve (Pair [] p)
{
	auto q = p.filter !(x => x.a < x.b).array;
	sort (q);
	reverse (q);
	return q.map !(x => x.c).array;
}

void main ()
{
	int n;
	while (readf (" %s", &n) > 0)
	{
		auto p = new Pair [n];
		foreach (i, ref x; p)
		{
			readf (" %s %s", &x.a, &x.b);
			x.c = i.to !(int) + 1;
		}
		auto ans = solve (p);
		foreach (ref x; p)
		{
			x = Pair (-x.a, -x.b, x.c);
		}
		auto alt = solve (p);
		if (ans.length < alt.length)
		{
			ans = alt;
		}
		writeln (alt.length);
		writefln ("%(%s %)", ans);
	}
}