Polycarp often uses his smartphone. He has already installed $$$n$$$ applications on it. Application with number $$$i$$$ takes up $$$a_i$$$ units of memory.Polycarp wants to free at least $$$m$$$ units of memory (by removing some applications).Of course, some applications are more important to Polycarp than others. He came up with the following scoring system — he assigned an integer $$$b_i$$$ to each application:   $$$b_i = 1$$$ — regular application;  $$$b_i = 2$$$ — important application. According to this rating system, his phone has $$$b_1 + b_2 + \ldots + b_n$$$ convenience points.Polycarp believes that if he removes applications with numbers $$$i_1, i_2, \ldots, i_k$$$, then he will free $$$a_{i_1} + a_{i_2} + \ldots + a_{i_k}$$$ units of memory and lose $$$b_{i_1} + b_{i_2} + \ldots + b_{i_k}$$$ convenience points.For example, if $$$n=5$$$, $$$m=7$$$, $$$a=[5, 3, 2, 1, 4]$$$, $$$b=[2, 1, 1, 2, 1]$$$, then Polycarp can uninstall the following application sets (not all options are listed below):   applications with numbers $$$1, 4$$$ and $$$5$$$. In this case, it will free $$$a_1+a_4+a_5=10$$$ units of memory and lose $$$b_1+b_4+b_5=5$$$ convenience points;  applications with numbers $$$1$$$ and $$$3$$$. In this case, it will free $$$a_1+a_3=7$$$ units of memory and lose $$$b_1+b_3=3$$$ convenience points.  applications with numbers $$$2$$$ and $$$5$$$. In this case, it will free $$$a_2+a_5=7$$$ memory units and lose $$$b_2+b_5=2$$$ convenience points. Help Polycarp, choose a set of applications, such that if removing them will free at least $$$m$$$ units of memory and lose the minimum number of convenience points, or indicate that such a set does not exist.

The first line contains one integer $$$t$$$ ($$$1 \le t \le 10^4$$$) — the number of test cases. Then $$$t$$$ test cases follow. The first line of each test case contains two integers $$$n$$$ and $$$m$$$ ($$$1 \le n \le 2 \cdot 10^5$$$, $$$1 \le m \le 10^9$$$) — the number of applications on Polycarp's phone and the number of memory units to be freed. The second line of each test case contains $$$n$$$ integers $$$a_1, a_2, \ldots, a_n$$$ ($$$1 \le a_i \le 10^9$$$) — the number of memory units used by applications. The third line of each test case contains $$$n$$$ integers $$$b_1, b_2, \ldots, b_n$$$ ($$$1 \le b_i \le 2$$$) — the convenience points of each application. It is guaranteed that the sum of $$$n$$$ over all test cases does not exceed $$$2 \cdot 10^5$$$.

For each test case, output on a separate line:    -1, if there is no set of applications, removing which will free at least $$$m$$$ units of memory;  the minimum number of convenience points that Polycarp will lose if such a set exists.

NoteIn the first test case, it is optimal to remove applications with numbers $$$2$$$ and $$$5$$$, freeing $$$7$$$ units of memory. $$$b_2+b_5=2$$$.In the second test case, by removing the only application, Polycarp will be able to clear only $$$2$$$ of memory units out of the $$$3$$$ needed.In the third test case, it is optimal to remove applications with numbers $$$1$$$, $$$2$$$, $$$3$$$ and $$$4$$$, freeing $$$10$$$ units of memory. $$$b_1+b_2+b_3+b_4=6$$$.In the fourth test case, it is optimal to remove applications with numbers $$$1$$$, $$$3$$$ and $$$4$$$, freeing $$$12$$$ units of memory. $$$b_1+b_3+b_4=4$$$.In the fifth test case, it is optimal to remove applications with numbers $$$1$$$ and $$$2$$$, freeing $$$5$$$ units of memory. $$$b_1+b_2=3$$$.

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

long oper(ref RedBlackTree!(long, "a < b", true) sett, long curmem, long m){
    long mems = curmem;
    long left = mems - m;
    while(sett.length && left >= sett.front){
        mems -= sett.front;
        sett.removeFront;
        left = mems - m;
    }
    return mems;
}

void solve(){
    int n = scan!int;
    long m = scan;
    auto spaces = scanArray;
    auto priority = scanArray!int;

    auto normals = spaces.enumerate.filter!(a => (priority[a[0]] == 1)).map!(a => a[1]);
    auto imps = spaces.enumerate.filter!(a => (priority[a[0]] == 2)).map!(a => a[1]).array;

    imps.sort;
    imps.reverse;

    long mems = normals.sum;
    auto rbt = redBlackTree!(true)(normals);
    int totconv = 1*rbt.length.to!int + 2*imps.length.to!int;
    mems = oper(rbt, mems, m);

    int baseconv = 0;
    int conv = rbt.length.to!int + baseconv;
    int minconv = 2*n+2;
    if(mems >= m){
        minconv = min(conv, minconv);
    }

    foreach(space; imps){
        baseconv += 2;
        mems += space;
        mems = oper(rbt, mems, m);
        conv = rbt.length.to!int + baseconv;
        /* show(rbt.length, baseconv, conv, mems); */
        if(mems >= m){
            minconv = min(conv, minconv);
        }
    }
    int res = totconv - minconv;
    writeln( (res >= 0) ? minconv : -1);
}

void main(){
    long tests = scan;        // Toggle!
    while(tests--) solve;
}

/**************    *****    That's All Folks!    *****    **************/
import std.stdio, std.range, std.conv, std.typecons, std.algorithm, std.container, std.math, std.numeric;
string[] tk; T scan(T=long)(){while(!tk.length)tk = readln.split; string a=tk.front; tk.popFront; return a.to!T;}
T[] scanArray(T=long)(){ auto r = readln.split.to!(T[]); return r; }
void show(A...)(A a){ debug{ foreach(t; a){stderr.write(t, "| ");} stderr.writeln; } }
alias ll = long, tup = Tuple!(long, "x",  long, "y");

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

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

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

void solve() {
    int N; long M; readf("%d %d\n", &N, &M);
    auto A = readarray!long;
    auto B = readarray!int;

    if (A.reduce!"a + b" < M) {
        writeln(-1);
        return;
    }

    int[] C, X;
    for (int i = 0; i < N; i++) {
        (B[i] == 1 ? C : X) ~= i;
    }
    C.sort!( (i, j) => A[i] > A[j] );
    X.sort!( (i, j) => A[i] > A[j] );

    int K = C.length;
    auto S = new long[K+1];
    for (int i = 0; i < K; i++) {
        S[i + 1] = S[i] + A[C[i]];
    }

    long ans = B.reduce!"a+b";
    long xsum = 0;
    for (int i = 0; ; i++) {
        long r = M - xsum;
        if (r > 0) {
            int k = S.lowerbound(r);
            if (k == K+1) {
            } else {
                ans.chmin(2*i + k);
            }
        } else {
            ans.chmin(2*i);
        }
        if (i == X.length) break;
        xsum += A[X[i]];
    }
    writeln(ans);
}

int binsearch(alias pred, T)(in T[] xs) {
    // find the minimum `i` that satisfies `pred(xs[i])`
    // NOTE: if none of the elements satisfies pred(x), returns `xs.length`
    alias C = unaryFun!pred;
    int N = cast(int)(xs.length);
    int lb = 0, ub = N;
    if (C(xs[lb])) {
        return 0;
    } else {
        while (lb + 1 < ub) {
            int mid = (lb + ub) / 2;
            (C(xs[mid]) ? ub : lb) = mid;
        }
        return ub;
    }
}
int lowerbound(T)(in T[] xs, in T x) {
    // find the minimum `i` that satisfies `x <= xs[i]`
    return xs.binsearch!(a => a >= x);
}
int upperbound(T)(in T[] xs, in T x) {
    // find the minimum `i` that satisfies `x < xs[i]`
    return xs.binsearch!(a => a > x);
}

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

void get(Args...)(ref Args args)
{
    import std.traits, std.meta, std.typecons;

    static if (Args.length == 1) {
        alias Arg = Args[0];

        static if (isArray!Arg) {
          static if (isSomeChar!(ElementType!Arg)) {
            args[0] = readln.chomp.to!Arg;
          } else {
            args[0] = readln.split.to!Arg;
          }
        } else static if (isTuple!Arg) {
            auto input = readln.split;
            static foreach (i; 0..Fields!Arg.length) {
                args[0][i] = input[i].to!(Fields!Arg[i]);
            }
        } else {
            args[0] = readln.chomp.to!Arg;
        }
    } else {
        auto input = readln.split;
        assert(input.length == Args.length);

        static foreach (i; 0..Args.length) {
            args[i] = input[i].to!(Args[i]);
        }
    }
}

void get_lines(Args...)(size_t N, ref Args args)
{
    import std.traits, std.range;

    static foreach (i; 0..Args.length) {
        static assert(isArray!(Args[i]));
        args[i].length = N;
    }

    foreach (i; 0..N) {
        static if (Args.length == 1) {
            get(args[0][i]);
        } else {
            auto input = readln.split;
            static foreach (j; 0..Args.length) {
                args[j][i] = input[j].to!(ElementType!(Args[j]));
            }
        }
    }
}

void main()
{
    int T; get(T);
    while (T--) {
        int N; long M; get(N, M);
        long[] aa; get(aa);
        int[] bb; get(bb);
        long[] hs, ls;
        foreach (i; 0..N) {
            if (bb[i] == 2) {
                hs ~= aa[i];
            } else {
                ls ~= aa[i];
            }
        }
        sort!"a > b"(hs);
        sort!"a > b"(ls);
        int res = int.max;

        if (ls.empty) {
            foreach (i, h; hs) {
                M -= h;
                if (M <= 0) res = min(res, (i.to!int + 1) * 2);
            }
        } else {
            auto cs = new long[](ls.length);
            foreach (i; 0..ls.length) {
                if (i) cs[i] = cs[i-1];
                cs[i] += ls[i];
                if (cs[i] >= M) res = min(res, i.to!int + 1);
            }
            long MM = M;
            foreach (i; 0..hs.length) {
                MM -= hs[i];
                int rr = (i + 1).to!int * 2;
                if (MM <= 0) {
                    res = min(res, rr);
                } else if (MM - cs[$-1] > 0) {
                    continue;
                } else {
                    int l = -1, r = cs.length.to!int;
                    while (l + 1 < r) {
                        auto m = (l + r) / 2;
                        if (MM - cs[m] <= 0) {
                            r = m;
                        } else {
                            l = m;
                        }
                    }
                    res = min(res, rr + r + 1);
                }
            }
        }

        writeln(res == int.max ? -1 : res);
    }
}

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

string FMT_F = "%.10f";

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

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

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

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

T binarySearch(alias pred, T)(T ok, T ng)
{
	while (abs(ok-ng) > 1)
	{
		auto mid = (ok+ng)/2;
		if (unaryFun!pred(mid)) ok = mid;
		else ng = mid;
	}
	return ok;
}

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

		long[] one, two;
		foreach (i; 0..n)
		{
			if (b[i] == 1)
				one ~= a[i];
			else
				two ~= a[i];
		}
		one.sort!"a > b";
		two.sort!"a > b";

		auto c = new long[](two.length+1);
		foreach (i; 0..two.length)
		{
			c[i+1] = c[i] + two[i];
		}

		ans[ti] = long.max;
		long tot;
		foreach (i; 0..one.length+1)
		{
			bool f(int x)
			{
				return tot + c[x] >= m;
			}
			auto r = binarySearch!(f)(cast(int)c.length, -1);
			if (r != c.length)
				ans[ti].chmin(i + r*2);
			if (i != one.length)
				tot += one[i];
		}
	}

	foreach (e; ans)
		writeln(e == long.max ? -1 : e);
	stdout.flush;
	debug readln;
}

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

immutable int infinity = int.max / 2;

void main ()
{
	auto tests = readln.strip.to !(int);
	foreach (test; 0..tests)
	{
		int n, m;
		readf !(" %s %s") (n, m);
		readln;
		auto a = readln.splitter.map !(to !(int)).array;
		auto b = readln.splitter.map !(to !(int)).array;
		int [] [3] p;
		foreach (i; 0..n)
		{
			p[b[i]] ~= a[i];
		}
		foreach (k; 1..3)
		{
			sort !(q{a > b}) (p[k]);
		}

		long done = 0;
		int cur = 0;
		foreach (j; 0..p[2].length)
		{
			done += p[2][j];
			cur += 2;
		}

		int i = 0;
		while (i < p[1].length && done < m)
		{
			done += p[1][i];
			cur += 1;
			i += 1;
		}

		int res = infinity;
		if (done >= m)
		{
			res = min (res, cur);
		}

		foreach_reverse (j; 0..p[2].length)
		{
			done -= p[2][j];
			cur -= 2;

			while (i < p[1].length && done < m)
			{
				done += p[1][i];
				cur += 1;
				i += 1;
			}

			if (done >= m)
			{
				res = min (res, cur);
			}
		}

		writeln (res == infinity ? -1 : res);
	}
}

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

long oper(ref RedBlackTree!(long, "a < b", true) sett, long mems, long m){
    long left = mems - m;
    while(left > 0 && sett.length && sett.front <= left){
        mems -= sett.front;
        sett.removeFront;
        left = mems - m;
    }
    return mems;
}

void solve(){
    int n = scan!int;
    long m = scan;
    auto spaces = scanArray;
    auto priority = scanArray!int;

    auto normals = spaces.enumerate.filter!(a => (priority[a[0]] == 1)).map!(a => a[1]);
    auto imps = spaces.enumerate.filter!(a => (priority[a[0]] == 2)).map!(a => a[1]).array;

    imps.sort;
    imps.reverse;

    long mems = normals.sum;
    auto rbt = redBlackTree!(true)(normals);
    int totconv = rbt.length.to!int + 2*imps.length.to!int;
    oper(rbt, mems, m);

    int conv = rbt.length.to!int;
    int baseconv = 0;
    int minconv = 2*n+2;
    if(mems - m >= 0){
        minconv = min(conv, minconv);
    }

    foreach(space; imps){
        baseconv += 2;
        mems += space;
        mems = oper(rbt, mems, m);
        conv = rbt.length.to!int + baseconv;
        if(mems - m >= 0){
            minconv = min(conv, minconv);
        }
    }
    int res = totconv - minconv;
    writeln( (res >= 0) ? minconv : -1);
}

void main(){
    long tests = scan;        // Toggle!
    while(tests--) solve;
}

/**************    *****    That's All Folks!    *****    **************/
import std.stdio, std.range, std.conv, std.typecons, std.algorithm, std.container, std.math, std.numeric;
string[] tk; T scan(T=long)(){while(!tk.length)tk = readln.split; string a=tk.front; tk.popFront; return a.to!T;}
T[] scanArray(T=long)(){ auto r = readln.split.to!(T[]); return r; }
void show(A...)(A a){ debug{ foreach(t; a){stderr.write(t, "| ");} stderr.writeln; } }
alias ll = long, tup = Tuple!(long, "x",  long, "y");

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

long oper(ref RedBlackTree!(long, "a < b", true) sett, long mems, long m){
    long left = mems - m;
    while(left > 0 && sett.length && sett.front <= left){
        mems -= sett.front;
        sett.removeFront;
        left = mems - m;
    }
    return mems;
}

void solve(){
    int n = scan!int;
    long m = scan;
    auto spaces = scanArray;
    auto priority = scanArray!int;

    auto normals = spaces.enumerate.filter!(a => (priority[a[0]] == 1)).map!(a => a[1]);
    auto imps = spaces.enumerate.filter!(a => (priority[a[0]] == 2)).map!(a => a[1]).array;

    imps.sort;
    imps.reverse;

    long mems = normals.sum;
    auto rbt = redBlackTree!(true)(normals);
    int totconv = rbt.length.to!int + 2*imps.length.to!int;
    oper(rbt, mems, m);

    int conv = rbt.length.to!int;
    int baseconv = 0;
    int minconv = 2*n+2;
    if(mems - m >= 0){
        minconv = min(conv, minconv);
    }

    foreach(space; imps){
        baseconv += 2;
        mems += space;
        oper(rbt, mems, m);
        conv = rbt.length.to!int + baseconv;
        if(mems - m >= 0){
            minconv = min(conv, minconv);
        }
    }
    int res = totconv - minconv;
    writeln( (res >= 0) ? minconv : -1);
}

void main(){
    long tests = scan;        // Toggle!
    while(tests--) solve;
}

/**************    *****    That's All Folks!    *****    **************/
import std.stdio, std.range, std.conv, std.typecons, std.algorithm, std.container, std.math, std.numeric;
string[] tk; T scan(T=long)(){while(!tk.length)tk = readln.split; string a=tk.front; tk.popFront; return a.to!T;}
T[] scanArray(T=long)(){ auto r = readln.split.to!(T[]); return r; }
void show(A...)(A a){ debug{ foreach(t; a){stderr.write(t, "| ");} stderr.writeln; } }
alias ll = long, tup = Tuple!(long, "x",  long, "y");

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

long oper(ref RedBlackTree!(long, "a < b", true) sett, long mems, long m){
    long left = mems - m;
    while(left > 0 && sett.length && sett.front <= left){
        mems -= sett.front;
        sett.removeFront;
        left = mems - m;
    }
    return mems;
}

void solve(){
    int n = scan!int;
    long m = scan;
    auto spaces = scanArray;
    auto priority = scanArray!int;

    auto normals = spaces.enumerate.filter!(a => (priority[a[0]] == 1)).map!(a => a[1]);
    auto imps = spaces.enumerate.filter!(a => (priority[a[0]] == 2)).map!(a => a[1]).array;

    imps.sort;
    imps.reverse;

    long mems = normals.sum;
    auto rbt = redBlackTree!(true)(normals);
    int totconv = rbt.length.to!int + 2*imps.length.to!int;
    oper(rbt, mems, m);

    int conv = rbt.length.to!int;
    int baseconv = 0;
    int minconv = 2*n+2;
    if(mems - m > 0){
        minconv = min(conv, minconv);
    }

    foreach(space; imps){
        baseconv += 2;
        mems += space;
        oper(rbt, mems, m);
        conv = rbt.length.to!int + baseconv;
        if(mems - m > 0){
            minconv = min(conv, minconv);
        }
    }
    int res = totconv - minconv;
    writeln( (res >= 0) ? minconv : -1);
}

void main(){
    long tests = scan;        // Toggle!
    while(tests--) solve;
}

/**************    *****    That's All Folks!    *****    **************/
import std.stdio, std.range, std.conv, std.typecons, std.algorithm, std.container, std.math, std.numeric;
string[] tk; T scan(T=long)(){while(!tk.length)tk = readln.split; string a=tk.front; tk.popFront; return a.to!T;}
T[] scanArray(T=long)(){ auto r = readln.split.to!(T[]); return r; }
void show(A...)(A a){ debug{ foreach(t; a){stderr.write(t, "| ");} stderr.writeln; } }
alias ll = long, tup = Tuple!(long, "x",  long, "y");

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

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

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

void solve() {
    int N; long M; readf("%d %d\n", &N, &M);
    auto A = readarray!long;
    auto B = readarray!int;

    if (A.reduce!"a + b" < M) {
        writeln(-1);
        return;
    }

    int[] C, X;
    for (int i = 0; i < N; i++) {
        (B[i] == 1 ? C : X) ~= i;
    }
    C.sort!( (i, j) => A[i] > A[j] );
    X.sort!( (i, j) => A[i] > A[j] );

    int K = C.length;
    auto S = new long[K+1];
    for (int i = 0; i < K; i++) {
        S[i + 1] = S[i] + A[C[i]];
    }

    long ans = A.reduce!"a+b";
    long xsum = 0;
    for (int i = 0; ; i++) {
        long r = M - xsum;
        if (r > 0) {
            int k = S.lowerbound(r);
            if (k == K+1) {
            } else {
                ans.chmin(2*i + k);
            }
        } else {
            ans.chmin(2*i);
        }
        if (i == X.length) break;
        xsum += A[X[i]];
    }
    writeln(ans);
}

int binsearch(alias pred, T)(in T[] xs) {
    // find the minimum `i` that satisfies `pred(xs[i])`
    // NOTE: if none of the elements satisfies pred(x), returns `xs.length`
    alias C = unaryFun!pred;
    int N = cast(int)(xs.length);
    int lb = 0, ub = N;
    if (C(xs[lb])) {
        return 0;
    } else {
        while (lb + 1 < ub) {
            int mid = (lb + ub) / 2;
            (C(xs[mid]) ? ub : lb) = mid;
        }
        return ub;
    }
}
int lowerbound(T)(in T[] xs, in T x) {
    // find the minimum `i` that satisfies `x <= xs[i]`
    return xs.binsearch!(a => a >= x);
}
int upperbound(T)(in T[] xs, in T x) {
    // find the minimum `i` that satisfies `x < xs[i]`
    return xs.binsearch!(a => a > x);
}

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

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

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

void solve() {
    int N, M; readf("%d %d\n", &N, &M);
    auto A = readarray!int;
    auto B = readarray!int;

    if (A.reduce!"a + b" < M) {
        writeln(-1);
        return;
    }

    int[] C, X;
    for (int i = 0; i < N; i++) {
        (B[i] == 1 ? C : X) ~= i;
    }
    C.sort!( (i, j) => A[i] > A[j] );
    X.sort!( (i, j) => A[i] > A[j] );

    int K = C.length;
    auto S = new long[K+1];
    for (int i = 0; i < K; i++) {
        S[i + 1] = S[i] + A[C[i]];
    }

    int ans = A.reduce!"a+b";
    long xsum = 0;
    for (int i = 0; ; i++) {
        long r = M - xsum;
        if (r > 0) {
            int k = S.lowerbound(r);
            if (k == K+1) {
            } else {
                ans.chmin(2*i + k);
            }
        } else {
            ans.chmin(2*i);
        }
        if (i == X.length) break;
        xsum += A[X[i]];
    }
    writeln(ans);
}

int binsearch(alias pred, T)(in T[] xs) {
    // find the minimum `i` that satisfies `pred(xs[i])`
    // NOTE: if none of the elements satisfies pred(x), returns `xs.length`
    alias C = unaryFun!pred;
    int N = cast(int)(xs.length);
    int lb = 0, ub = N;
    if (C(xs[lb])) {
        return 0;
    } else {
        while (lb + 1 < ub) {
            int mid = (lb + ub) / 2;
            (C(xs[mid]) ? ub : lb) = mid;
        }
        return ub;
    }
}
int lowerbound(T)(in T[] xs, in T x) {
    // find the minimum `i` that satisfies `x <= xs[i]`
    return xs.binsearch!(a => a >= x);
}
int upperbound(T)(in T[] xs, in T x) {
    // find the minimum `i` that satisfies `x < xs[i]`
    return xs.binsearch!(a => a > x);
}


Uncle Bogdan is in captain Flint's crew for a long time and sometimes gets nostalgic for his homeland. Today he told you how his country introduced a happiness index.There are $$$n$$$ cities and $$$n−1$$$ undirected roads connecting pairs of cities. Citizens of any city can reach any other city traveling by these roads. Cities are numbered from $$$1$$$ to $$$n$$$ and the city $$$1$$$ is a capital. In other words, the country has a tree structure.There are $$$m$$$ citizens living in the country. A $$$p_i$$$ people live in the $$$i$$$-th city but all of them are working in the capital. At evening all citizens return to their home cities using the shortest paths. Every person has its own mood: somebody leaves his workplace in good mood but somebody are already in bad mood. Moreover any person can ruin his mood on the way to the hometown. If person is in bad mood he won't improve it.Happiness detectors are installed in each city to monitor the happiness of each person who visits the city. The detector in the $$$i$$$-th city calculates a happiness index $$$h_i$$$ as the number of people in good mood minus the number of people in bad mood. Let's say for the simplicity that mood of a person doesn't change inside the city.Happiness detector is still in development, so there is a probability of a mistake in judging a person's happiness. One late evening, when all citizens successfully returned home, the government asked uncle Bogdan (the best programmer of the country) to check the correctness of the collected happiness indexes.Uncle Bogdan successfully solved the problem. Can you do the same?More formally, You need to check: "Is it possible that, after all people return home, for each city $$$i$$$ the happiness index will be equal exactly to $$$h_i$$$".

The first line contains a single integer $$$t$$$ ($$$1 \le t \le 10000$$$) — the number of test cases. The first line of each test case contains two integers $$$n$$$ and $$$m$$$ ($$$1 \le n \le 10^5$$$; $$$0 \le m \le 10^9$$$) — the number of cities and citizens. The second line of each test case contains $$$n$$$ integers $$$p_1, p_2, \ldots, p_{n}$$$ ($$$0 \le p_i \le m$$$; $$$p_1 + p_2 + \ldots + p_{n} = m$$$), where $$$p_i$$$ is the number of people living in the $$$i$$$-th city. The third line contains $$$n$$$ integers $$$h_1, h_2, \ldots, h_{n}$$$ ($$$-10^9 \le h_i \le 10^9$$$), where $$$h_i$$$ is the calculated happiness index of the $$$i$$$-th city. Next $$$n − 1$$$ lines contain description of the roads, one per line. Each line contains two integers $$$x_i$$$ and $$$y_i$$$ ($$$1 \le x_i, y_i \le n$$$; $$$x_i \neq y_i$$$), where $$$x_i$$$ and $$$y_i$$$ are cities connected by the $$$i$$$-th road. It's guaranteed that the sum of $$$n$$$ from all test cases doesn't exceed $$$2 \cdot 10^5$$$.

For each test case, print YES, if the collected data is correct, or NO — otherwise. You can print characters in YES or NO in any case.

NoteLet's look at the first test case of the first sample:   At first, all citizens are in the capital. Let's describe one of possible scenarios:   a person from city $$$1$$$: he lives in the capital and is in good mood;  a person from city $$$4$$$: he visited cities $$$1$$$ and $$$4$$$, his mood was ruined between cities $$$1$$$ and $$$4$$$;  a person from city $$$3$$$: he visited cities $$$1$$$ and $$$3$$$ in good mood;  a person from city $$$6$$$: he visited cities $$$1$$$, $$$3$$$ and $$$6$$$, his mood was ruined between cities $$$1$$$ and $$$3$$$;  In total,   $$$h_1 = 4 - 0 = 4$$$,  $$$h_2 = 0$$$,  $$$h_3 = 1 - 1 = 0$$$,  $$$h_4 = 0 - 1 = -1$$$,  $$$h_5 = 0$$$,  $$$h_6 = 0 - 1 = -1$$$,  $$$h_7 = 0$$$. The second case of the first test:   All people have already started in bad mood in the capital — this is the only possible scenario.The first case of the second test:   The second case of the second test:   It can be proven that there is no way to achieve given happiness indexes in both cases of the second test.

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)
	{
		readln;
		auto p = readln.splitter.map !(to !(int)).array;
		auto n = p.length.to !(int);
		auto h = readln.splitter.map !(to !(int)).array;
		auto adj = new int [] [n];
		foreach (j; 0..n - 1)
		{
			auto v = readln.splitter.map !(to !(int)).array;
			v[] -= 1;
			adj[v[0]] ~= v[1];
			adj[v[1]] ~= v[0];
		}

		auto d = new int [n];
		bool ok = true;

		void recur (int v, int w)
		{
			d[v] = p[v];
			foreach (u; adj[v])
			{
				if (u != w)
				{
					recur (u, v);
					d[v] += d[u];
				}
			}
			ok &= (d[v] >= h[v] && (d[v] & 1) == (h[v] & 1));
			h[v] = (d[v] - h[v]) / 2;
		}

		recur (0, -1);

		bool good (int v, int w)
		{
			int cur = 0;
			foreach (u; adj[v])
			{
				if (u != w)
				{
					cur += h[u];
					if (!good (u, v))
					{
						return false;
					}
				}
			}
			return (cur >= h[v] - p[v]);
		}

		writeln (ok && good (0, -1) ? "YES" : "NO");
	}
}

import std.container;
import std.algorithm;
import std.range;
import std.array;
import std.stdio;
import std.utf;

DList!string _words;
void read(T)(out T t)
{
  import std.stdio: readln;
  while(_words.empty)
    {
      import std.array: split;
      foreach(word; readln.split)
        {
          _words.insertBack(word);
        }
    }
  import std.conv: to;
  string word = _words.front;
  _words.removeFront;
  t = to!T(word);
}

size_t ind(T)(T t)
{
  return cast(size_t)t;
}

ref auto at(R, I)(ref R r, I i)
{
  return r[cast(size_t)i];
}

void main()
{
  int t;
  read(t);
  while(t--)
    {
      long n, m;
      read(n), read(m);
      auto p = new long[cast(size_t)n];
      foreach(ref pi; p)
        read(pi);
      auto h = new long[cast(size_t)n];
      foreach(ref hi; h)
        read(hi);
      auto g = new long[cast(size_t)n];
      auto adj = new Appender!(long[])[cast(size_t)n];
      foreach(ref list; adj)
        list = appender!(long[])();
      foreach(i; 0 .. n - 1)
        {
          long x, y;
          read(x), x--;
          read(y), y--;
          adj.at(x).put(y);
          adj.at(y).put(x);
        }
      auto totalp = new long[cast(size_t)n];
      class Impossible: Throwable
      {
        this()
        {
          super("");
        }
      }
      bool isImpossible = false;
      void check(long node, long parent)
      {
        totalp.at(node) = p.at(node);
        long hsum = 0;
        long gsum = 0;
        foreach(w; adj[cast(size_t)node][])
          if (w != parent)
            {
              check(w, node);
              totalp.at(node) += totalp.at(w);
              gsum += g.at(w);
            }
        // s
        if ((h.at(node) + totalp.at(node)) % 2 != 0)
          {
            version(none) writeln(2, " ", node + 1, " ", parent + 1);
            isImpossible = true;
          }
        g.at(node) = (totalp.at(node) + h.at(node))/2;
        bool condition1 = adj[cast(size_t)node][].length > 1 && hsum > h[cast(size_t)node] + p[cast(size_t)node];
        bool condition1p = gsum > g.at(node);
        if(condition1p)
          {
            version(none) writeln(1, " ", node + 1, " ", parent + 1);
            isImpossible = true;
          }
        bool condition2 = h[cast(size_t)node] > totalp[cast(size_t)node] || h[cast(size_t)node] < -totalp[cast(size_t)node];
        bool condition2p = g.at(node) < 0 || g.at(node) > totalp.at(node);
        if (condition2p)
          {
            version(none) writeln(3, " ", node + 1, " ", parent + 1);
            isImpossible = true;
          }
      }
      check(0, -1);
      if (!isImpossible)
        writeln("YES");
      else
        writeln("NO");
    }
}

import std.container;
import std.algorithm;
import std.range;
import std.array;
import std.stdio;
import std.utf;

DList!string _words;
void read(T)(out T t)
{
  import std.stdio: readln;
  while(_words.empty)
    {
      import std.array: split;
      foreach(word; readln.split)
        {
          _words.insertBack(word);
        }
    }
  import std.conv: to;
  string word = _words.front;
  _words.removeFront;
  t = to!T(word);
}

size_t ind(T)(T t)
{
  return cast(size_t)t;
}

ref auto at(R, I)(ref R r, I i)
{
  return r[cast(size_t)i];
}

void main()
{
  int t;
  read(t);
  while(t--)
    {
      long n, m;
      read(n), read(m);
      auto p = new long[cast(size_t)n];
      foreach(ref pi; p)
        read(pi);
      auto h = new long[cast(size_t)n];
      foreach(ref hi; h)
        read(hi);
      auto g = new long[cast(size_t)n];
      auto adj = new Appender!(long[])[cast(size_t)n];
      foreach(ref list; adj)
        list = appender!(long[])();
      foreach(i; 0 .. n - 1)
        {
          long x, y;
          read(x), x--;
          read(y), y--;
          adj.at(x).put(y);
          adj.at(y).put(x);
        }
      auto totalp = new long[cast(size_t)n];
      class Impossible: Throwable
      {
        this()
        {
          super("");
        }
      }
      bool isImpossible = false;
      void check(long node, long parent)
      {
        totalp.at(node) = p.at(node);
        long hsum = 0;
        long gsum = 0;
        bool hasChildren = true;
        foreach(w; adj[cast(size_t)node][])
          if (w != parent)
            {
              check(w, node);
              totalp.at(node) += totalp.at(w);
              gsum += g.at(w);
              hasChildren = true;
            }
        // s
        if ((h.at(node) + totalp.at(node)) % 2 != 0)
          {
            version(none) writeln(2, " ", node + 1, " ", parent + 1);
            isImpossible = true;
          }
        g.at(node) = (totalp.at(node) + h.at(node))/2;
        bool condition1 = adj[cast(size_t)node][].length > 1 && hsum > h[cast(size_t)node] + p[cast(size_t)node];
        bool condition1p = hasChildren && gsum > g.at(node);
        if(condition1p)
          {
            version(none) writeln(1, " ", node + 1, " ", parent + 1);
            isImpossible = true;
          }
        bool condition2 = h[cast(size_t)node] > totalp[cast(size_t)node] || h[cast(size_t)node] < -totalp[cast(size_t)node];
        bool condition2p = g.at(node) < 0 || g.at(node) > totalp.at(node);
        if (condition2p)
          {
            version(none) writeln(3, " ", node + 1, " ", parent + 1);
            isImpossible = true;
          }
      }
      check(0, -1);
      if (!isImpossible)
        writeln("YES");
      else
        writeln("NO");
    }
}

import std.container;
import std.algorithm;
import std.range;
import std.array;
import std.stdio;
import std.utf;

DList!string _words;
void read(T)(out T t)
{
  import std.stdio: readln;
  while(_words.empty)
    {
      import std.array: split;
      foreach(word; readln.split)
        {
          _words.insertBack(word);
        }
    }
  import std.conv: to;
  string word = _words.front;
  _words.removeFront;
  t = to!T(word);
}

size_t ind(T)(T t)
{
  return cast(size_t)t;
}

ref auto at(R, I)(ref R r, I i)
{
  return r[cast(size_t)i];
}

void main()
{
  int t;
  read(t);
  while(t--)
    {
      long n, m;
      read(n), read(m);
      auto p = Array!long();
      p.length = cast(size_t)n;
      foreach(ref pi; p)
        read(pi);
      auto h = Array!long();
      h.length = cast(size_t)n;
      foreach(ref hi; h)
        read(hi);
      auto g = Array!long();
      g.length = cast(size_t)n;
      auto adj = Array!(Appender!(long[]))();
      adj.length = cast(size_t)n;
      foreach(ref list; adj)
        list = appender!(long[])();
      foreach(i; 0 .. n - 1)
        {
          long x, y;
          read(x), x--;
          read(y), y--;
          adj.at(x).put(y);
          adj.at(y).put(x);
        }
      auto totalp = new long[cast(size_t)n];
      class Impossible: Throwable
      {
        this()
        {
          super(null);
        }
      }
      void check(long node, long parent)
      {
        totalp.at(node) = p.at(node);
        long hsum = 0;
        bool hasChildren = true;
        foreach(w; adj.at(node)[])
          if (w != parent)
            {
              check(w, node);
              totalp.at(node) += totalp.at(w);
              hsum += h.at(w);
              hasChildren = true;
            }
        if ((h.at(node) + totalp.at(node)) % 2 != 0
            || hasChildren && hsum > h.at(node) + p.at(node)
            || h.at(node) > totalp.at(node) || h.at(node) < -totalp.at(node))
          throw new Impossible();
      }
      try
        check(0, -1);
      catch(Impossible)
        goto no;
    yes:
      writeln("YES");
      continue;
    no:
      writeln("NO");
    }
}

import std.container;
import std.algorithm;
import std.range;
import std.array;
import std.stdio;
import std.utf;

DList!string _words;
void read(T)(out T t)
{
  import std.stdio: readln;
  while(_words.empty)
    {
      import std.array: split;
      foreach(word; readln.split)
        {
          _words.insertBack(word);
        }
    }
  import std.conv: to;
  string word = _words.front;
  _words.removeFront;
  t = to!T(word);
}

size_t ind(T)(T t)
{
  return cast(size_t)t;
}

ref auto at(R, I)(ref R r, I i)
{
  return r[cast(size_t)i];
}

void main()
{
  int t;
  read(t);
  while(t--)
    {
      long n, m;
      read(n), read(m);
      auto p = new long[cast(size_t)n];
      foreach(ref pi; p)
        read(pi);
      auto h = new long[cast(size_t)n];
      foreach(ref hi; h)
        read(hi);
      auto g = new long[cast(size_t)n];
      auto adj = new Appender!(long[])[cast(size_t)n];
      foreach(ref list; adj)
        list = appender!(long[])();
      foreach(i; 0 .. n - 1)
        {
          long x, y;
          read(x), x--;
          read(y), y--;
          adj.at(x).put(y);
          adj.at(y).put(x);
        }
      auto totalp = new long[cast(size_t)n];
      class Impossible: Throwable
      {
        this()
        {
          super("");
        }
      }
      void check(long node, long parent)
      {
        totalp.at(node) = p.at(node);
        long hsum = 0;
        bool hasChildren = true;
        foreach(w; adj.at(node)[])
          if (w != parent)
            {
              check(w, node);
              totalp.at(node) += totalp.at(w);
              hsum += h.at(w);
              hasChildren = true;
            }
        if ((h.at(node) + totalp.at(node)) % 2 != 0
            || hasChildren && hsum > h.at(node) + p.at(node)
            || h.at(node) > totalp.at(node) || h.at(node) < -totalp.at(node))
          throw new Impossible();
      }
      try
        check(0, -1);
      catch(Impossible)
        goto no;
    yes:
      writeln("YES");
      continue;
    no:
      writeln("NO");
    }
}

import std.container;
import std.algorithm;
import std.range;
import std.array;
import std.stdio;
import std.utf;

DList!string _words;
void read(T)(out T t)
{
  import std.stdio: readln;
  while(_words.empty)
    {
      import std.array: split;
      foreach(word; readln.split)
        {
          _words.insertBack(word);
        }
    }
  import std.conv: to;
  string word = _words.front;
  _words.removeFront;
  t = to!T(word);
}

size_t ind(T)(T t)
{
  return cast(size_t)t;
}

ref auto at(R, I)(ref R r, I i)
{
  return r[cast(size_t)i];
}

void main()
{
  int t;
  read(t);
  while(t--)
    {
      long n, m;
      read(n), read(m);
      auto p = new long[cast(size_t)n];
      foreach(ref pi; p)
        read(pi);
      auto h = new long[cast(size_t)n];
      foreach(ref hi; h)
        read(hi);
      auto g = new long[cast(size_t)n];
      auto adj = new Appender!(long[])[cast(size_t)n];
      foreach(ref list; adj)
        list = appender!(long[])();
      foreach(i; 0 .. n - 1)
        {
          long x, y;
          read(x), x--;
          read(y), y--;
          adj.at(x).put(y);
          adj.at(y).put(x);
        }
      auto totalp = new long[cast(size_t)n];
      class Impossible: Throwable
      {
        this()
        {
          super("");
        }
      }
      bool isImpossible = false;
      void check(long node, long parent)
      {
        totalp.at(node) = p.at(node);
        long hsum = 0;
        long gsum = 0;
        bool hasChildren = true;
        foreach(w; adj[cast(size_t)node][])
          if (w != parent)
            {
              check(w, node);
              totalp.at(node) += totalp.at(w);
              gsum += g.at(w);
              hsum += h.at(w);
              hasChildren = true;
            }
        // s
        if ((h.at(node) + totalp.at(node)) % 2 != 0)
          {
            version(none) writeln(2, " ", node + 1, " ", parent + 1);
            isImpossible = true;
          }
        g.at(node) = (totalp.at(node) + h.at(node))/2;
        bool condition1 = hasChildren && hsum > h.at(node) + p.at(node);
        bool condition1p = hasChildren && gsum > g.at(node);
        if(condition1)
          {
            version(none) writeln(1, " ", node + 1, " ", parent + 1);
            isImpossible = true;
          }
        bool condition2 = h[cast(size_t)node] > totalp[cast(size_t)node] || h[cast(size_t)node] < -totalp[cast(size_t)node];
        bool condition2p = g.at(node) < 0 || g.at(node) > totalp.at(node);
        if (condition2)
          {
            version(none) writeln(3, " ", node + 1, " ", parent + 1);
            isImpossible = true;
          }
      }
      check(0, -1);
      if (!isImpossible)
        writeln("YES");
      else
        writeln("NO");
    }
}

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

string FMT_F = "%.10f";

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

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

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

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

void main()
{
	auto t = RD!int;
	auto ans = new bool[](t);
	foreach (ti; 0..t)
	{
		auto n = RD!int;
		auto m = RD!int;
		auto p = RDA!int;
		auto h = RDA!int;
		auto edges = new int[][](n);
		foreach (i; 0..n-1)
		{
			auto x = RD!int-1;
			auto y = RD!int-1;
			edges[x] ~= y;
			edges[y] ~= x;
		}

		bool ok = true;
		long[2] dfs(int pos, int last)
		{
			long cnt0, cnt1;
			foreach (to; edges[pos])
			{
				if (to == last) continue;
				auto r = dfs(to, pos);
				cnt0 += r[0];
				cnt1 += r[1];
			}
			auto d = cnt0 - cnt1;
			auto v = h[pos] - d;
			auto remain = p[pos] - abs(v);
			if (remain < 0 && v > 0)
			{
				debug writeln("d:", d, " v:", v, " remain:", remain);
				debug writeln("cnt:", cnt0, " ", cnt1);
				cnt0 += p[pos];
				v -= p[pos];
				auto u = min(cnt1, abs(remain/2));
				cnt0 += u;
				cnt1 -= u;
				v -= u*2;
				remain += u*2;
				debug writeln("d:", d, " v:", v, " remain:", remain);
				debug writeln("cnt:", cnt0, " ", cnt1);
			}
			if (remain < 0 || remain % 2)
			{
				debug writeln("false pos:", pos, " remain:", remain);
				ok = false;
			}
			if (v > 0)
				cnt0 += v;
			else
				cnt1 += abs(v);
			cnt0 += remain / 2;
			cnt1 += remain / 2;
			return [cnt0, cnt1];
		}
		auto r = dfs(0, -1);
		debug writeln("m:", m, " ", r);
		if (r[0] + r[1] != m)
			ok = false;

		ans[ti] = ok;
	}

	foreach (e; ans)
	{
		writeln(e ? "YES" : "NO");
	}
	stdout.flush;
	debug readln;
}

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)
	{
		readln;
		auto p = readln.splitter.map !(to !(int)).array;
		auto n = p.length.to !(int);
		auto m = p.sum;
		auto h = readln.splitter.map !(to !(int)).array;
		auto adj = new int [] [n];
		foreach (j; 0..n - 1)
		{
			auto v = readln.splitter.map !(to !(int)).array;
			v[] -= 1;
			adj[v[0]] ~= v[1];
			adj[v[1]] ~= v[0];
		}

		auto d = new int [n];
		bool ok = true;

		void recur (int v, int w)
		{
			d[v] = p[v];
			foreach (u; adj[v])
			{
				if (u != w)
				{
					recur (u, v);
					d[v] += d[u];
				}
			}
			ok &= ((d[v] & 1) == (h[v] & 1));
			h[v] = (d[v] - h[v]) / 2;
		}

		recur (0, -1);

		bool good (int v, int w)
		{
			int cur = 0;
			foreach (u; adj[v])
			{
				if (u != w)
				{
					cur += h[u];
					if (!good (u, v))
					{
						return false;
					}
				}
			}
			return (cur >= h[v] - p[v]);
		}

		writeln (ok && good (0, -1) ? "YES" : "NO");
	}
}

import std.container;
import std.algorithm;
import std.range;
import std.array;
import std.stdio;
import std.utf;

DList!string _words;
void read(T)(out T t)
{
  import std.stdio: readln;
  while(_words.empty)
    {
      import std.array: split;
      foreach(word; readln.split)
        {
          _words.insertBack(word);
        }
    }
  import std.conv: to;
  string word = _words.front;
  _words.removeFront;
  t = to!T(word);
}

void main()
{
  int t;
  read(t);
  while(t--)
    {
      long n, m;
      read(n), read(m);
      auto p = new long[cast(size_t)n];
      foreach(ref pi; p)
        read(pi);
      auto h = new long[cast(size_t)n];
      foreach(ref hi; h)
        read(hi);
      auto g = new long[cast(size_t)n];
      auto adj = new Appender!(long[])[cast(size_t)n];
      foreach(ref list; adj)
        list = appender!(long[])();
      foreach(i; 0 .. n - 1)
        {
          long x, y;
          read(x), x--;
          read(y), y--;
          adj[cast(size_t)x].put(y);
          adj[cast(size_t)y].put(x);
        }
      auto totalp = new long[cast(size_t)n];
      class Impossible: Throwable
      {
        this()
        {
          super("");
        }
      }
      bool isImpossible = false;
      void check(long node, long parent)
      {
        totalp[cast(size_t)node] = p[cast(size_t)node];
        long hsum = 0;
        long gsum = 0;
        foreach(w; adj[cast(size_t)node][])
          if (w != parent)
            {
              check(w, node);
              totalp[cast(size_t)node] += totalp[cast(size_t)w];
              hsum += h[cast(size_t)w];
              gsum += g[cast(size_t)w];
            }
        // s
        if ((h[cast(size_t)node] + totalp[cast(size_t)node]) % 2 != 0)
          {
            version(none) writeln(2, " ", node + 1, " ", parent + 1);
            isImpossible = true;
          }
        g[cast(size_t)node] = (totalp[cast(size_t)node] + h[cast(size_t)node])/2;
        bool condition1 = adj[cast(size_t)node][].length > 1 && hsum > h[cast(size_t)node] + p[cast(size_t)node];
        bool condition1p = adj[cast(size_t)node][].length > 1 && gsum > g[cast(size_t)node];
        if(condition1p)
          {
            version(none) writeln(1, " ", node + 1, " ", parent + 1);
            isImpossible = true;
          }
        bool condition2 = h[cast(size_t)node] > totalp[cast(size_t)node] || h[cast(size_t)node] < -totalp[cast(size_t)node];
        bool condition2p = g[cast(size_t)node] < 0 || g[cast(size_t)node] > totalp[cast(size_t)node];
        if (condition2p)
          {
            version(none) writeln(3, " ", node + 1, " ", parent + 1);
            isImpossible = true;
          }
      }
      check(0, -1);
      if (!isImpossible)
        writeln("YES");
      else
        writeln("NO");
    }
}

import std.container;
import std.algorithm;
import std.range;
import std.array;
import std.stdio;
import std.utf;

DList!string _words;
void read(T)(out T t)
{
  import std.stdio: readln;
  while(_words.empty)
    {
      import std.array: split;
      foreach(word; readln.split)
        {
          _words.insertBack(word);
        }
    }
  import std.conv: to;
  string word = _words.front;
  _words.removeFront;
  t = to!T(word);
}

void main()
{
  int t;
  read(t);
  while(t--)
    {
      long n, m;
      read(n), read(m);
      auto p = new long[cast(size_t)n];
      foreach(ref pi; p)
        read(pi);
      auto h = new long[cast(size_t)n];
      foreach(ref hi; h)
        read(hi);
      auto g = new long[cast(size_t)n];
      auto adj = new Appender!(long[])[cast(size_t)n];
      foreach(ref list; adj)
        list = appender!(long[])();
      foreach(i; 0 .. n - 1)
        {
          long x, y;
          read(x), x--;
          read(y), y--;
          adj[cast(size_t)x].put(y);
          adj[cast(size_t)y].put(x);
        }
      auto totalp = new long[cast(size_t)n];
      class Impossible: Throwable
      {
        this()
        {
          super("");
        }
      }
      void check(long node, long parent)
      {
        totalp[cast(size_t)node] = p[cast(size_t)node];
        long hsum = 0;
        long gsum = 0;
        foreach(w; adj[cast(size_t)node][])
          if (w != parent)
            {
              check(w, node);
              totalp[cast(size_t)node] += totalp[cast(size_t)w];
              hsum += h[cast(size_t)w];
              gsum += g[cast(size_t)w];
            }
        // s
        if ((h[cast(size_t)node] + totalp[cast(size_t)node]) % 2 != 0)
          {
            version(none) writeln(2, " ", node + 1, " ", parent + 1);
            throw new Impossible();
          }
        g[cast(size_t)node] = (totalp[cast(size_t)node] + h[cast(size_t)node])/2;
        bool condition1 = adj[cast(size_t)node][].length > 1 && hsum > h[cast(size_t)node] + p[cast(size_t)node];
        bool condition1p = adj[cast(size_t)node][].length > 1 && gsum > g[cast(size_t)node];
        assert(condition1 == condition1p);
        if(condition1p)
          {
            version(none) writeln(1, " ", node + 1, " ", parent + 1);
            throw new Impossible();
          }
        bool condition2 = h[cast(size_t)node] > totalp[cast(size_t)node] || h[cast(size_t)node] < -totalp[cast(size_t)node];
        bool condition2p = g[cast(size_t)node] < 0 || g[cast(size_t)node] > totalp[cast(size_t)node];
        if (condition2p)
          {
            version(none) writeln(3, " ", node + 1, " ", parent + 1);
            throw new Impossible();
          }
      }
      try
        {
          check(0, -1);
        }
      catch(Impossible impossible)
        {
          goto isImpossible;
        }
      writeln("YES");
      continue;
    isImpossible:
      writeln("NO");
    }
}

import std.container;
import std.algorithm;
import std.range;
import std.array;
import std.stdio;
import std.utf;

DList!string _words;
void read(T)(out T t)
{
  import std.stdio: readln;
  while(_words.empty)
    {
      import std.array: split;
      foreach(word; readln.split)
        {
          _words.insertBack(word);
        }
    }
  import std.conv: to;
  string word = _words.front;
  _words.removeFront;
  t = to!T(word);
}

void main()
{
  int t;
  read(t);
  while(t--)
    {
      long n, m;
      read(n), read(m);
      auto p = new long[cast(size_t)n];
      foreach(ref pi; p)
        read(pi);
      auto h = new long[cast(size_t)n];
      foreach(ref hi; h)
        read(hi);
      auto g = new long[cast(size_t)n];
      auto adj = new Appender!(long[])[cast(size_t)n];
      foreach(ref list; adj)
        list = appender!(long[])();
      foreach(i; 0 .. n - 1)
        {
          long x, y;
          read(x), x--;
          read(y), y--;
          adj[cast(size_t)x].put(y);
          adj[cast(size_t)y].put(x);
        }
      auto totalp = new long[cast(size_t)n];
      class Impossible: Throwable
      {
        this()
        {
          super("");
        }
      }
      void check(long node, long parent)
      {
        totalp[cast(size_t)node] = p[cast(size_t)node];
        long hsum = 0;
        long gsum = 0;
        foreach(w; adj[cast(size_t)node][])
          if (w != parent)
            {
              check(w, node);
              totalp[cast(size_t)node] += totalp[cast(size_t)w];
              hsum += h[cast(size_t)w];
              gsum += g[cast(size_t)w];
            }
        // s
        if ((h[cast(size_t)node] + totalp[cast(size_t)node]) % 2 != 0)
          {
            version(none) writeln(2, " ", node + 1, " ", parent + 1);
            throw new Impossible();
          }
        g[cast(size_t)node] = (totalp[cast(size_t)node] + h[cast(size_t)node])/2;
        bool condition1 = adj[cast(size_t)node][].length > 1 && hsum > h[cast(size_t)node] + p[cast(size_t)node];
        bool condition1p = adj[cast(size_t)node][].length > 1 && gsum > g[cast(size_t)node];
        assert(condition1 == condition1p);
        if(condition1)
          {
            version(none) writeln(1, " ", node + 1, " ", parent + 1);
            throw new Impossible();
          }
        bool condition2 = h[cast(size_t)node] > totalp[cast(size_t)node] || h[cast(size_t)node] < -totalp[cast(size_t)node];
        bool condition2p = g[cast(size_t)node] < 0 || g[cast(size_t)node] > totalp[cast(size_t)node];
        if (condition2)
          {
            version(none) writeln(3, " ", node + 1, " ", parent + 1);
            throw new Impossible();
          }
      }
      try
        {
          check(0, -1);
        }
      catch(Impossible impossible)
        {
          goto isImpossible;
        }
      writeln("YES");
      continue;
    isImpossible:
      writeln("NO");
    }
}

import std.container;
import std.algorithm;
import std.range;
import std.array;
import std.stdio;
import std.utf;

DList!string _words;
void read(T)(out T t)
{
  import std.stdio: readln;
  while(_words.empty)
    {
      import std.array: split;
      foreach(word; readln.split)
        {
          _words.insertBack(word);
        }
    }
  import std.conv: to;
  string word = _words.front;
  _words.removeFront;
  t = to!T(word);
}

void main()
{
  int t;
  read(t);
  while(t--)
    {
      long n, m;
      read(n), read(m);
      auto p = new long[cast(size_t)n];
      foreach(ref pi; p)
        read(pi);
      auto h = new long[cast(size_t)n];
      foreach(ref hi; h)
        read(hi);
      writeln("h = ", h);
      auto adj = new Appender!(long[])[cast(size_t)n];
      foreach(ref list; adj)
        list = appender!(long[])();
      foreach(i; 0 .. n - 1)
        {
          long x, y;
          read(x), x--;
          read(y), y--;
          adj[cast(size_t)x].put(y);
          adj[cast(size_t)y].put(x);
        }
      auto totalp = new long[cast(size_t)n];
      class Impossible: Throwable
      {
        this()
        {
          super("");
        }
      }
      void check(long node, long parent)
      {
        totalp[cast(size_t)node] = p[cast(size_t)node];
        long hsum = 0;
        foreach(w; adj[cast(size_t)node][])
          if (w != parent)
            {
              check(w, node);
              totalp[cast(size_t)node] += totalp[cast(size_t)w];
              hsum += h[cast(size_t)w];
            }
        if(adj[cast(size_t)node][].length > 1 && hsum > h[cast(size_t)node] + p[cast(size_t)node])
          {
            version(none) writeln(1, " ", node + 1, " ", parent + 1);
            throw new Impossible();
          }
        if ((h[cast(size_t)node] + totalp[cast(size_t)node]) % 2 != 0)
          {
            version(none) writeln(2, " ", node + 1, " ", parent + 1);
            throw new Impossible();
          }
        if (h[cast(size_t)node] > totalp[cast(size_t)node] || h[cast(size_t)node] < -totalp[cast(size_t)node])
          {
            version(none) writeln(3, " ", node + 1, " ", parent + 1);
            throw new Impossible();
          }
      }
      try
        {
          check(0, -1);
        }
      catch(Impossible impossible)
        {
          goto isImpossible;
        }
      writeln("YES");
      continue;
    isImpossible:
      writeln("NO");
    }
}

import std.container;
import std.algorithm;
import std.range;
import std.array;
import std.stdio;
import std.utf;

DList!string _words;
void read(T)(out T t)
{
  import std.stdio: readln;
  while(_words.empty)
    {
      import std.array: split;
      foreach(word; readln.split)
        {
          _words.insertBack(word);
        }
    }
  import std.conv: to;
  string word = _words.front;
  _words.removeFront;
  t = to!T(word);
}

size_t ind(T)(T t)
{
  return cast(size_t)t;
}

ref auto at(R, I)(ref R r, I i)
{
  return r[cast(size_t)i];
}

void main()
{
  int t;
  read(t);
  while(t--)
    {
      long n, m;
      read(n), read(m);
      auto p = new long[cast(size_t)n];
      foreach(ref pi; p)
        read(pi);
      auto h = new long[cast(size_t)n];
      foreach(ref hi; h)
        read(hi);
      auto g = new long[cast(size_t)n];
      auto adj = new Appender!(long[])[cast(size_t)n];
      foreach(ref list; adj)
        list = appender!(long[])();
      foreach(i; 0 .. n - 1)
        {
          long x, y;
          read(x), x--;
          read(y), y--;
          adj.at(x).put(y);
          adj.at(y).put(x);
        }
      auto totalp = new long[cast(size_t)n];
      class Impossible: Throwable
      {
        this()
        {
          super("");
        }
      }
      bool isImpossible = false;
      void check(long node, long parent)
      {
        totalp.at(node) = p.at(node);
        long hsum = 0;
        long gsum = 0;
        foreach(w; adj[cast(size_t)node][])
          if (w != parent)
            {
              check(w, node);
              totalp.at(node) += totalp.at(w);
              gsum += g.at(w);
            }
        // s
        if ((h.at(node) + totalp.at(node)) % 2 != 0)
          {
            version(none) writeln(2, " ", node + 1, " ", parent + 1);
            isImpossible = true;
          }
        g.at(node) = (totalp.at(node) + h.at(node))/2;
        bool condition1 = adj[cast(size_t)node][].length > 1 && hsum > h[cast(size_t)node] + p[cast(size_t)node];
        bool condition1p = adj.at(node)[].length > 1 && gsum > g.at(node);
        if(condition1p)
          {
            version(none) writeln(1, " ", node + 1, " ", parent + 1);
            isImpossible = true;
          }
        bool condition2 = h[cast(size_t)node] > totalp[cast(size_t)node] || h[cast(size_t)node] < -totalp[cast(size_t)node];
        bool condition2p = g.at(node) < 0 || g.at(node) > totalp.at(node);
        if (condition2p)
          {
            version(none) writeln(3, " ", node + 1, " ", parent + 1);
            isImpossible = true;
          }
      }
      check(0, -1);
      if (!isImpossible)
        writeln("YES");
      else
        writeln("NO");
    }
}

import std.container;
import std.algorithm;
import std.range;
import std.array;
import std.stdio;
import std.utf;

DList!string _words;
void read(T)(out T t)
{
  import std.stdio: readln;
  while(_words.empty)
    {
      import std.array: split;
      foreach(word; readln.split)
        {
          _words.insertBack(word);
        }
    }
  import std.conv: to;
  string word = _words.front;
  _words.removeFront;
  t = to!T(word);
}

void main()
{
  int t;
  read(t);
  while(t--)
    {
      long n, m;
      read(n), read(m);
      auto p = new long[cast(size_t)n];
      foreach(ref pi; p)
        read(pi);
      auto h = new long[cast(size_t)n];
      foreach(ref hi; h)
        read(hi);
      auto adj = new Appender!(long[])[cast(size_t)n];
      foreach(ref list; adj)
        list = appender!(long[])();
      foreach(i; 0 .. n - 1)
        {
          long x, y;
          read(x), x--;
          read(y), y--;
          adj[cast(size_t)x].put(y);
          adj[cast(size_t)y].put(x);
        }
      auto totalp = new long[cast(size_t)n];
      class Impossible: Throwable
      {
        this()
        {
          super("");
        }
      }
      void check(long node, long parent)
      {
        totalp[cast(size_t)node] = p[cast(size_t)node];
        long hsum = 0;
        foreach(w; adj[cast(size_t)node][])
          if (w != parent)
            {
              check(w, node);
              totalp[cast(size_t)node] += totalp[cast(size_t)w];
              hsum += h[cast(size_t)w];
            }
        if(adj[cast(size_t)node][].length > 1 && hsum > h[cast(size_t)node] + p[cast(size_t)node])
          {
            version(none) writeln(1, " ", node + 1, " ", parent + 1);
            throw new Impossible();
          }
        if ((h[cast(size_t)node] + totalp[cast(size_t)node]) % 2 != 0)
          {
            version(none) writeln(2, " ", node + 1, " ", parent + 1);
            throw new Impossible();
          }
        if (h[cast(size_t)node] > totalp[cast(size_t)node] || h[cast(size_t)node] < -totalp[cast(size_t)node])
          {
            version(none) writeln(3, " ", node + 1, " ", parent + 1);
            throw new Impossible();
          }
      }
      try
        {
          check(0, -1);
        }
      catch(Impossible impossible)
        {
          goto isImpossible;
        }
      writeln("YES");
      continue;
    isImpossible:
      writeln("NO");
    }
}

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

string FMT_F = "%.10f";

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

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

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

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

void main()
{
	auto t = RD!int;
	auto ans = new bool[](t);
	foreach (ti; 0..t)
	{
		auto n = RD!int;
		auto m = RD!int;
		auto p = RDA!int;
		auto h = RDA!int;
		auto edges = new int[][](n);
		foreach (i; 0..n-1)
		{
			auto x = RD!int-1;
			auto y = RD!int-1;
			edges[x] ~= y;
			edges[y] ~= x;
		}

		bool ok = true;
		long[2] dfs(int pos, int last)
		{
			long cnt0, cnt1;
			foreach (to; edges[pos])
			{
				if (to == last) continue;
				auto r = dfs(to, pos);
				cnt0 += r[0];
				cnt1 += r[1];
			}
			auto d = cnt0 - cnt1;
			auto d2 = h[pos] - d;
			auto remain = p[pos] - abs(d2);
			if (remain < 0 && d2 > 0)
			{
				cnt0 -= remain;
				cnt1 += remain;
				d2 += remain;
				remain = 0;
			}
			if (remain < 0 || remain % 2 || cnt0 < 0)
			{
				debug writeln("false pos:", pos, " remain:", remain);
				ok = false;
			}
			if (d2 > 0)
				cnt0 += d2;
			else
				cnt1 += abs(d2);
			cnt0 += remain / 2;
			cnt1 += remain / 2;
			return [cnt0, cnt1];
		}
		auto r = dfs(0, -1);
		debug writeln("m:", m, " ", r);
		if (r[0] + r[1] != m)
			ok = false;

		ans[ti] = ok;
	}

	foreach (e; ans)
	{
		writeln(e ? "YES" : "NO");
	}
	stdout.flush;
	debug readln;
}

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

string FMT_F = "%.10f";

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

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

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

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

void main()
{
	auto t = RD!int;
	auto ans = new bool[](t);
	foreach (ti; 0..t)
	{
		auto n = RD!int;
		auto m = RD!int;
		auto p = RDA!int;
		auto h = RDA!int;
		auto edges = new int[][](n);
		foreach (i; 0..n-1)
		{
			auto x = RD!int-1;
			auto y = RD!int-1;
			edges[x] ~= y;
			edges[y] ~= x;
		}

		bool ok = true;
		long dfs(int pos, int last)
		{
			long cnt = p[pos];
			foreach (to; edges[pos])
			{
				if (to == last) continue;
				cnt += dfs(to, pos);
			}
			auto d = abs(cnt - h[pos]);
			if (d % 2 || abs(h[pos]) > cnt)
				ok = false;
			return cnt;
		}
		if (dfs(0, -1) != m)
			ok = false;

		ans[ti] = ok;
	}

	foreach (e; ans)
	{
		writeln(e ? "YES" : "NO");
	}
	stdout.flush;
	debug readln;
}

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

string FMT_F = "%.10f";

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

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

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

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

void main()
{
	auto t = RD!int;
	auto ans = new bool[](t);
	foreach (ti; 0..t)
	{
		auto n = RD!int;
		auto m = RD!int;
		auto p = RDA!int;
		auto h = RDA!int;
		auto edges = new int[][](n);
		foreach (i; 0..n-1)
		{
			auto x = RD!int-1;
			auto y = RD!int-1;
			edges[x] ~= y;
			edges[y] ~= x;
		}

		bool ok = true;
		int dfs(int pos, int last)
		{
			int cnt = p[pos];
			foreach (to; edges[pos])
			{
				if (to == last) continue;
				cnt += dfs(to, pos);
			}
			auto d = abs(cnt - h[pos]);
			if (d % 2 || abs(h[pos]) > cnt)
				ok = false;
			return cnt;
		}
		dfs(0, -1);

		ans[ti] = ok;
	}

	foreach (e; ans)
	{
		writeln(e ? "YES" : "NO");
	}
	stdout.flush;
	debug readln;
}

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

string FMT_F = "%.10f";

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

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

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

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

void main()
{
	auto t = RD!int;
	auto ans = new bool[](t);
	foreach (ti; 0..t)
	{
		auto n = RD!int;
		auto m = RD!int;
		auto p = RDA!int;
		auto h = RDA!int;
		auto edges = new int[][](n);
		foreach (i; 0..n-1)
		{
			auto x = RD!int-1;
			auto y = RD!int-1;
			edges[x] ~= y;
			edges[y] ~= x;
		}

		bool ok = true;
		int dfs(int pos, int last)
		{
			int cnt = p[pos];
			foreach (to; edges[pos])
			{
				if (to == last) continue;
				cnt += dfs(to, pos);
			}
			auto d = abs(cnt - h[pos]);
			if (d % 2 || abs(h[pos]) > cnt)
				ok = false;
			return cnt;
		}
		if (dfs(0, -1) != m)
			ok = false;

		ans[ti] = ok;
	}

	foreach (e; ans)
	{
		writeln(e ? "YES" : "NO");
	}
	stdout.flush;
	debug readln;
}

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

string FMT_F = "%.10f";

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

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

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

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

void main()
{
	auto t = RD!int;
	auto ans = new bool[](t);
	foreach (ti; 0..t)
	{
		auto n = RD!int;
		auto m = RD!int;
		auto p = RDA!int;
		auto h = RDA!int;
		auto edges = new int[][](n);
		foreach (i; 0..n-1)
		{
			auto x = RD!int-1;
			auto y = RD!int-1;
			edges[x] ~= y;
			edges[y] ~= x;
		}

		bool ok = true;
		long[2] dfs(int pos, int last)
		{
			long cnt0, cnt1;
			foreach (to; edges[pos])
			{
				if (to == last) continue;
				auto r = dfs(to, pos);
				cnt0 += r[0];
				cnt1 += r[1];
			}
			auto d = cnt0 - cnt1;
			auto v = h[pos] - d;
			auto remain = p[pos] - abs(v);
			if (remain < 0 && v > 0)
			{
				cnt0 -= remain;
				cnt1 += remain;
				v += remain;
				remain = 0;
			}
			if (remain < 0 || remain % 2 || cnt1 < 0)
			{
				debug writeln("false pos:", pos, " remain:", remain);
				ok = false;
			}
			if (v > 0)
				cnt0 += v;
			else
				cnt1 += abs(v);
			cnt0 += remain / 2;
			cnt1 += remain / 2;
			return [cnt0, cnt1];
		}
		auto r = dfs(0, -1);
		debug writeln("m:", m, " ", r);
		if (r[0] + r[1] != m)
			ok = false;

		ans[ti] = ok;
	}

	foreach (e; ans)
	{
		writeln(e ? "YES" : "NO");
	}
	stdout.flush;
	debug readln;
}

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

string FMT_F = "%.10f";

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

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

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

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

void main()
{
	auto t = RD!int;
	auto ans = new bool[](t);
	foreach (ti; 0..t)
	{
		auto n = RD!int;
		auto m = RD!int;
		auto p = RDA!int;
		auto h = RDA!int;
		auto edges = new int[][](n);
		foreach (i; 0..n-1)
		{
			auto x = RD!int-1;
			auto y = RD!int-1;
			edges[x] ~= y;
			edges[y] ~= x;
		}

		bool ok = true;
		long dfs(int pos, int last)
		{
			long cnt = p[pos];
			foreach (to; edges[pos])
			{
				if (to == last) continue;
				cnt += dfs(to, pos);
			}
			if ((cnt % 2 != abs(h[pos]) % 2) || (abs(h[pos]) > cnt))
				ok = false;
			return cnt;
		}
		if (dfs(0, -1) != m)
			ok = false;

		ans[ti] = ok;
	}

	foreach (e; ans)
	{
		writeln(e ? "YES" : "NO");
	}
	stdout.flush;
	debug readln;
}


Valerian was captured by Shapur. The victory was such a great one that Shapur decided to carve a scene of Valerian's defeat on a mountain. So he had to find the best place to make his victory eternal!He decided to visit all n cities of Persia to find the best available mountain, but after the recent war he was too tired and didn't want to traverse a lot. So he wanted to visit each of these n cities at least once with smallest possible traverse. Persian cities are connected with bidirectional roads. You can go from any city to any other one using these roads and there is a unique path between each two cities.All cities are numbered 1 to n. Shapur is currently in the city 1 and he wants to visit all other cities with minimum possible traverse. He can finish his travels in any city.Help Shapur find how much He should travel.

First line contains a single natural number n (1 ≤ n ≤ 105) — the amount of cities. Next n - 1 lines contain 3 integer numbers each xi, yi and wi (1 ≤ xi, yi ≤ n, 0 ≤ wi ≤ 2 × 104). xi and yi are two ends of a road and wi is the length of that road.

A single integer number, the minimal length of Shapur's travel. Please, do not use %lld specificator to read or write 64-bit integers in C++. It is preffered to use cout (also you may use %I64d).

// Cheese-Cracker: cheese-cracker.github.io
import std.stdio, std.conv, std.functional, std.string, std.algorithm;
import std.container, std.range, std.typecons, std.numeric, std.math, std.random;

alias ll = long;
alias rbt = redBlackTree;
alias tup = Tuple!(long, long);
static string[] inp;
T rd(T = long)(){while(!inp.length) inp = readln.chomp.split; string a = inp[0]; inp.popFront; return a.to!T;}
T[] rdarr(T = long)(T fix = 0){ auto r = readln.chomp.split.to!(T[]); r[] += fix; return r; }
/*******************************It's a Me, Mario!*******************************************/

tup[][long] adj;
bool[long] vis;

long dfs(ll u){
    vis[u] = 1;
    ll maxw = 0;
    if(u in adj){
        foreach(tup e; adj[u]){
            if(!vis.get(e[0], 0)){
                maxw = max(e[1] + dfs(e[0]), maxw);
            }
        }
    }
    return maxw;
}

void play(){
    int n;
    n = rd!int;
    ll u, v, w;
    ll sumwt = 0;
    foreach(i; 0..n-1){
        u = rd; v = rd; w = rd;
        adj[u] ~= tup(v, w);
        adj[v] ~= tup(u, w);
        sumwt += w;
    }
    ll maxwtpath = dfs(1);
    ll leftw = sumwt - maxwtpath;
    debug writeln("D: ", sumwt, " ", maxwtpath, " ", leftw);
    writeln(maxwtpath + 2*leftw);
}

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


You are given $$$n$$$ lengths of segments that need to be placed on an infinite axis with coordinates.The first segment is placed on the axis so that one of its endpoints lies at the point with coordinate $$$0$$$. Let's call this endpoint the "start" of the first segment and let's call its "end" as that endpoint that is not the start. The "start" of each following segment must coincide with the "end" of the previous one. Thus, if the length of the next segment is $$$d$$$ and the "end" of the previous one has the coordinate $$$x$$$, the segment can be placed either on the coordinates $$$[x-d, x]$$$, and then the coordinate of its "end" is $$$x - d$$$, or on the coordinates $$$[x, x+d]$$$, in which case its "end" coordinate is $$$x + d$$$.The total coverage of the axis by these segments is defined as their overall union which is basically the set of points covered by at least one of the segments. It's easy to show that the coverage will also be a segment on the axis. Determine the minimal possible length of the coverage that can be obtained by placing all the segments on the axis without changing their order.

The first line contains an integer $$$t$$$ ($$$1 \leq t \leq 1000$$$) — the number of test cases. The next $$$2t$$$ lines contain descriptions of the test cases.  The first line of each test case description contains an integer $$$n$$$ ($$$1 \le n \le 10^4$$$) — the number of segments. The second line of the description contains $$$n$$$ space-separated integers $$$a_i$$$ ($$$1 \le a_i \le 1000$$$) — lengths of the segments in the same order they should be placed on the axis. It is guaranteed that the sum of $$$n$$$ over all test cases does not exceed $$$10^4$$$.

Print $$$t$$$ lines, each line containing the answer to the corresponding test case. The answer to a test case should be a single integer — the minimal possible length of the axis coverage.

NoteIn the third sample test case the segments should be arranged as follows: $$$[0, 6] \rightarrow [4, 6] \rightarrow [4, 7] \rightarrow [-2, 7]$$$. As you can see, the last segment $$$[-2, 7]$$$ covers all the previous ones, and the total length of coverage is $$$9$$$.In the fourth sample test case the segments should be arranged as $$$[0, 6] \rightarrow [-2, 6] \rightarrow [-2, 2] \rightarrow [2, 7]$$$. The union of these segments also occupies the area $$$[-2, 7]$$$ and has the length of $$$9$$$.

immutable multi = true;

void solve(int tc)
{
	immutable maxLowerBound = 2001;
	auto n = readInt!int, a = ma(n, readInt!int), minUpperMem = new int[][](n+1, maxLowerBound);
	int minUpper(int i, int lowerBound)
	{
		pragma(inline, true);
		if (lowerBound < 0) return 4000;
		if (lowerBound >= maxLowerBound) return 4000;
		if (i == n) { return 0; }
		int ansIfAdd, ansIfSubs, ans = 4000;
		{
			auto subAns = lowerBound+a[i] < maxLowerBound? minUpperMem[i+1][lowerBound + a[i]] : 4000;
			ansIfAdd = a[i] + subAns;
			ans = min(ans, ansIfAdd);
		}
		{
			auto subAns = lowerBound - a[i] >= 0? minUpperMem[i+1][lowerBound - a[i]] : 4000;
			ansIfSubs = max(subAns - a[i], 0);
			ans = min(ans, ansIfSubs);
		}
		return ans;
	}
	foreach_reverse(i; 0 .. n + 1)
	{
		foreach(lower; 0 .. maxLowerBound)
		{
			minUpperMem[i][lower] = minUpper(i, lower);
		}
	}
	int minDiff = int.max;
	foreach(lower; 0 .. maxLowerBound)
	{
		auto subAns = minUpperMem[0][lower];
		minDiff = min(minDiff, subAns + lower);
	}
	minDiff.writeln;
}

//{{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
//}}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
	{
		popChar;
	}
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
void writes(T...)(T t)
{
	static foreach(i, ti; t)
	{
		static if (isIterable!(T[i]))
		{
			foreach(e; ti)
			{
				write(e, " ");
			}
		}
	}
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}

immutable multi = true;

void solve(int tc)
{
	auto n = readInt!int, a = ma(n, readInt!int), minUpperMem = new int[][](n+1, 1001);
	int minUpper(int i, int lowerBound)
	{
		pragma(inline, true);
		if (lowerBound < 0) return 4000;
		if (lowerBound > 1000) return 4000;
		if (i == n) { return 0; }
		int ansIfAdd, ansIfSubs, ans = 4000;
		{
			auto subAns = lowerBound+a[i] <= 1000? minUpperMem[i+1][lowerBound + a[i]] : 4000;
			ansIfAdd = a[i] + subAns;
			ans = min(ans, ansIfAdd);
		}
		{
			auto subAns = lowerBound - a[i] >= 0? minUpperMem[i+1][lowerBound - a[i]] : 4000;
			ansIfSubs = max(subAns - a[i], 0);
			ans = min(ans, ansIfSubs);
		}
		return ans;
	}
	foreach_reverse(i; 0 .. n + 1)
	{
		foreach(lower; 0 .. 1000 + 1)
		{
			minUpperMem[i][lower] = minUpper(i, lower);
		}
	}
	int minDiff = int.max;
	foreach(lower; 0 .. 1000 + 1)
	{
		auto subAns = minUpperMem[0][lower];
		minDiff = min(minDiff, subAns + lower);
	}
	minDiff.writeln;
}

//{{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
//}}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
	{
		popChar;
	}
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
void writes(T...)(T t)
{
	static foreach(i, ti; t)
	{
		static if (isIterable!(T[i]))
		{
			foreach(e; ti)
			{
				write(e, " ");
			}
		}
	}
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}


Vlad has $$$n$$$ friends, for each of whom he wants to buy one gift for the New Year.There are $$$m$$$ shops in the city, in each of which he can buy a gift for any of his friends. If the $$$j$$$-th friend ($$$1 \le j \le n$$$) receives a gift bought in the shop with the number $$$i$$$ ($$$1 \le i \le m$$$), then the friend receives $$$p_{ij}$$$ units of joy. The rectangular table $$$p_{ij}$$$ is given in the input.Vlad has time to visit at most $$$n-1$$$ shops (where $$$n$$$ is the number of friends). He chooses which shops he will visit and for which friends he will buy gifts in each of them.Let the $$$j$$$-th friend receive $$$a_j$$$ units of joy from Vlad's gift. Let's find the value $$$\alpha=\min\{a_1, a_2, \dots, a_n\}$$$. Vlad's goal is to buy gifts so that the value of $$$\alpha$$$ is as large as possible. In other words, Vlad wants to maximize the minimum of the joys of his friends.For example, let $$$m = 2$$$, $$$n = 2$$$. Let the joy from the gifts that we can buy in the first shop: $$$p_{11} = 1$$$, $$$p_{12}=2$$$, in the second shop: $$$p_{21} = 3$$$, $$$p_{22}=4$$$.Then it is enough for Vlad to go only to the second shop and buy a gift for the first friend, bringing joy $$$3$$$, and for the second — bringing joy $$$4$$$. In this case, the value $$$\alpha$$$ will be equal to $$$\min\{3, 4\} = 3$$$Help Vlad choose gifts for his friends so that the value of $$$\alpha$$$ is as high as possible. Please note that each friend must receive one gift. Vlad can visit at most $$$n-1$$$ shops (where $$$n$$$ is the number of friends). In the shop, he can buy any number of gifts.

The first line of the input contains an integer $$$t$$$ ($$$1 \le t \le 10^4$$$) — the number of test cases in the input. An empty line is written before each test case. Then there is a line containing integers $$$m$$$ and $$$n$$$ ($$$2 \le n$$$, $$$2 \le n \cdot m \le 10^5$$$) separated by a space — the number of shops and the number of friends, where $$$n \cdot m$$$ is the product of $$$n$$$ and $$$m$$$. Then $$$m$$$ lines follow, each containing $$$n$$$ numbers. The number in the $$$i$$$-th row of the $$$j$$$-th column $$$p_{ij}$$$ ($$$1 \le p_{ij} \le 10^9$$$) is the joy of the product intended for friend number $$$j$$$ in shop number $$$i$$$. It is guaranteed that the sum of the values $$$n \cdot m$$$ over all test cases in the test does not exceed $$$10^5$$$.

Print $$$t$$$ lines, each line must contain the answer to the corresponding test case — the maximum possible value of $$$\alpha$$$, where $$$\alpha$$$ is the minimum of the joys from a gift for all of Vlad's friends.

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 main() {
    int T = read!int;
    foreach (t; 0 .. T) solve();
}

void solve() {
    readln;
    int M, N; readf("%d %d\n", &M, &N);
    auto P = new int[][M];
    foreach (ref L; P) L = readarray!int;

    bool C(int x) {
        bool[int] s;
        for (int j = 0; j < N; j++) {
            int c = 0;
            for (int i = 0; i < M; i++) {
                if (P[i][j] >= x) {
                    c++;
                }
            }
            if (c == 0) return false;
        }
        for (int j = 0; j < N; j++) {
            for (int i = 0; i < M; i++) {
                if (P[i][j] >= x) {
                    if (i in s) return true;
                    s[i] = true;
                }
            }
        }
        return false;
    }
    int lb = 0, ub = 1_000_000_010;
    while (lb + 1 < ub) {
        int mid = (lb + ub) / 2;
        (C(mid) ? lb : ub) = mid;
    }
    writeln(lb);
}

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

void main()
{
  foreach (casenum ; 1 .. readln.strip.to!int + 1) {
    int m, n;
    readf!" %d %d "(m, n);
    int[] frjoy = new int[](n);
    int[][] joy;
    int sharedshopjoy;
    foreach (i ; 0 .. m) {
      joy ~= readln.splitter.map!(to!int).array;
      foreach (j ; 0 .. n)
        frjoy[j] = max(frjoy[j], joy.back[j]);
      joy.back.sort;
      sharedshopjoy = max(sharedshopjoy, joy.back[$ - 2]);
    }
    int ans = frjoy.minElement;
    if (n - 1 < m)
      ans = min(ans, sharedshopjoy);
    writeln(ans);
  }
}