/*
    主要是,一個(gè)能量初始值為S  給出n個(gè)要消滅的敵人
    打敗每個(gè)敵人至少要costi ,然后可以休息,獲取體力ri
    問(wèn)能否打敗所有敵人
    n <= 22    

    若能打敗所有敵人,最后的能量值是唯一的
    即安排一種順序能打敗所有敵人
    對(duì)于costi <= ri的,肯定是先打costi比較小的,所以按照costi升序排

    對(duì)于costi > ri的,我是按costi降序排,錯(cuò)誤
    如
    5
    5 2
    3 3
    然后按照 costi - ri 升序排,也錯(cuò)
    如
    5
    3 2
    5 3       

    正確的是按照ri降序排
    解題報(bào)告說(shuō)跟zoj 3077類似,證明挺有啟示的
    不是一般性,假設(shè)答案的順序是1,2..,n
                 k-1
    必有 S - ∑(costi - ri) >= costk
                 i=1
        我們可以通過(guò)交換所有rj < rj+1的敵人,但最后結(jié)果一樣!!!
    因?yàn)?nbsp;S' >=  costj , S' - (costj - rj) >=  costj+1
    => S' >= costj+1 , S' - (costj+1  - rj+1) >= costj
    所以像冒泡排序那樣交換,最后形成一個(gè)r降序的序列,但效果一樣

    而zoj 3077按照b降序后,dp選擇一部分出來(lái)
    效果跟最優(yōu)解是一樣的(最優(yōu)解其實(shí)就是一個(gè)集合+一定順序,而這個(gè)順序跟按照b降序效果一樣,
    而選擇這個(gè)集合就是dp了)

    如果沒(méi)有沒(méi)有排序,直接dp就保證不了無(wú)后效性
    我想無(wú)后效性就是 先選a再選b 效果跟 先選b再選a,不會(huì)因?yàn)檫x擇了a就不能選擇b了
    所以普通背包問(wèn)題,按照編號(hào)的順序進(jìn)行dp就行了
    
    中大第三本”數(shù)字游戲“ 也是先排序,在dp選擇
*/
 
#include
<iostream>
#include
<cstring>
#include
<map>
#include
<algorithm>
#include
<stack>
#include
<queue>
#include
<cmath>
#include
<string>
#include
<cstdlib>
#include
<vector>
#include
<cstdio>
#include
<set>
#include
<list>

using namespace std;

const int INF = 1000000000;

int main()
{
    
int  T;
    
for(scanf("%d",&T);T--;){
        
int n , S;
        vector
<pair<int,int> > less , _less;
        scanf(
"%d%d",&n,&S);
        
for(int i = 0 ; i < n  ; i++){
            
int p[3] , r;
            scanf(
"%d%d%d%d",&p[0],&p[1],&p[2],&r);
            
int dp[10];
            fill(dp,dp
+10,INF);
            dp[
0= 0;
            
for(int i = 0 ; i < 3 ; i++){
                
int get = 3 - i;
                
for(int j = 0 ; j + get <= 9 ; j++){
                    dp[j
+get= min(dp[j+get] , dp[j] + p[i]);
                }

            }

            
int cost = INF;
            
for(int j = 7 ; j <= 9 ;j++){
                cost 
= min(cost , dp[j]);
            }

            
if(cost < r ){
                less.push_back(make_pair(cost , r));
            }

            
else {
                _less.push_back(make_pair(r , cost));
            }


        }

        sort(less.begin() , less.end());
        sort(_less.begin() , _less.end(),greater
<pair<int,int> >());
        
for(vector<pair<int,int> >::iterator  it = less.begin() ; it != less.end() ; it++){
            S 
-= it->first;
            
if(S <= 0)break;
            S 
+= it->second;
        }

        
for(vector<pair<int,int> >::iterator  it = _less.begin() ; it != _less.end() ; it++){
            S 
-= it->second;
            
if(S <= 0)break;
            S 
+= it->first;
        }

        
if(S > 0){
            printf(
"%d\n",S);
        }

        
else {
            puts(
"no");
        }

    }

    
return 0;
}