#include<bits/stdc++.h>
#define MAXN 100009
#define INF 1000000007
#define LLINF 1000000000000000007
#define mp(x,y) make_pair(x,y)
#define wr cout<<"Continue Debugging!!!"<<endl;
#define ff first
#define ss second
#define lg(x) ceil(log2(x))
#define all(x) x.begin(),x.end()
#define pb(x) push_back(x)
#define ppb() pop_back()
#define tr(i, c) for(typeof((c).begin()) i = (c).begin(); i!=(c).end(); i++)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
template<class T> bool umin(T& a, T b) { if(a > b){ a = b;return 1;}return 0;}
template<class T> bool umax(T& a, T b) { if(a < b){ a = b;return 1;}return 0;}
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
int arr[MAXN],cp[10010],dp[109][10009];
int main(){
	int n,m,x;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		memset(cp,0,sizeof(cp));
		scanf("%d",&x);
		for(int j=1;j<=x;j++)
			scanf("%d",arr+j),arr[j]+=arr[j-1];
		for(int j=1;j<=x;j++)
			for(int k=0;k<=j;k++)
				umax(cp[j],arr[k]+arr[x]-arr[x-j+k]);
		for(int j=1;j<=m;j++)
			for(int k=0;k<=j;k++)
				umax(dp[i][j],dp[i-1][k]+cp[j-k]);
	}
	cout<<dp[n][m]<<endl;
	return 0;
}


#include<bits/stdc++.h>
#define MAXN 100009
#define INF 1000000007
#define LLINF 1000000000000000007
#define mp(x,y) make_pair(x,y)
#define wr cout<<"Continue Debugging!!!"<<endl;
#define ff first
#define ss second
#define lg(x) ceil(log2(x))
#define all(x) x.begin(),x.end()
#define pb(x) push_back(x)
#define ppb() pop_back()
#define tr(i, c) for(typeof((c).begin()) i = (c).begin(); i!=(c).end(); i++)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
template<class T> bool umin(T& a, T b) { if(a > b){ a = b;return 1;}return 0;}
template<class T> bool umax(T& a, T b) { if(a < b){ a = b;return 1;}return 0;}
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
int arr[MAXN],cp[MAXN],dp[109][10009];
int main(){
	int n,m,x;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		scanf("%d",&x);
		for(int j=1;j<=x;j++)
			scanf("%d",arr+j),arr[j]+=arr[j-1];
		for(int j=1;j<=x;j++)
			for(int k=0;k<=j;k++)
				umax(cp[j],arr[k]+arr[x]-arr[x-j+k]);
		for(int j=1;j<=m;j++)
			for(int k=0;k<=j;k++)
				umax(dp[i][j],dp[i-1][k]+cp[j-k]);
		for(int j=1;j<=x;j++)
			cp[j]=0;
	}
	cout<<dp[n][m]<<endl;
	return 0;
}


#include<bits/stdc++.h>
#define MAXN 100009
#define INF 1000000007
#define LLINF 1000000000000000007
#define mp(x,y) make_pair(x,y)
#define wr cout<<"Continue Debugging!!!"<<endl;
#define ff first
#define ss second
#define lg(x) ceil(log2(x))
#define all(x) x.begin(),x.end()
#define pb(x) push_back(x)
#define ppb() pop_back()
#define tr(i, c) for(typeof((c).begin()) i = (c).begin(); i!=(c).end(); i++)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
template<class T> bool umin(T& a, T b) { if(a > b){ a = b;return 1;}return 0;}
template<class T> bool umax(T& a, T b) { if(a < b){ a = b;return 1;}return 0;}
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
int arr[MAXN],cp[MAXN],dp[109][10009];
int main(){
	int n,m,x;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		fill(cp,cp+109,0);
		cin>>x;
		for(int j=1;j<=x;j++)
			cin>>arr[j],arr[j]+=arr[j-1];
		for(int j=1;j<=x;j++)
			for(int k=0;k<=j;k++)
				umax(cp[j],arr[k]+arr[x]-arr[x-j+k]);
		for(int j=1;j<=m;j++)
			for(int k=0;k<=j;k++)
				umax(dp[i][j],dp[i-1][k]+cp[j-k]);
	}
	cout<<dp[n][m]<<endl;
	return 0;
}


#include<bits/stdc++.h>
#define MAXN 100009
#define INF 1000000007
#define LLINF 1000000000000000007
#define mp(x,y) make_pair(x,y)
#define wr cout<<"Continue Debugging!!!"<<endl;
#define ff first
#define ss second
#define lg(x) ceil(log2(x))
#define all(x) x.begin(),x.end()
#define pb(x) push_back(x)
#define ppb() pop_back()
#define tr(i, c) for(typeof((c).begin()) i = (c).begin(); i!=(c).end(); i++)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
template<class T> bool umin(T& a, T b) { if(a > b){ a = b;return 1;}return 0;}
template<class T> bool umax(T& a, T b) { if(a < b){ a = b;return 1;}return 0;}
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
int arr[MAXN],cp[MAXN],dp[109][10009];
int main(){
	int n,m,x;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>x;
		for(int j=1;j<=x;j++)
			cin>>arr[j],arr[j]+=arr[j-1];
		for(int j=1;j<=x;j++)
			for(int k=0;k<=j;k++)
				umax(cp[j],arr[k]+arr[x]-arr[x-j+k]);
		for(int j=1;j<=m;j++)
			for(int k=0;k<=j;k++)
				umax(dp[i][j],dp[i-1][k]+cp[j-k]);
	}
	cout<<dp[n][m]<<endl;
	return 0;
}


//For Future
//By JFantasy

#include <cstdio>
#include <cstring>

const int maxn = 105;

int d[maxn][maxn] , e[maxn];
int data[maxn];
int ans[maxn][maxn];
int n , m;

int getmax( int a , int b )
{
    return a>b?a:b;
}

int getmin( int a , int b )
{
    return a<b?a:b;
}

void cal( int x , int num )
{
    int sum[maxn];
    sum[0] = 0;
    for ( int i = 1; i <= num; i++ ) sum[i] = sum[i-1] + data[i];
    for ( int i = 1; i <= getmin(num,m); i++ ) {
        for ( int j = 0; j <= i; j++ ) {
            d[x][i] = getmax( d[x][i] , sum[j]+sum[num]-sum[num-(i-j)] );
        }
    }
}

int getans()
{
    int tot = 0;
    for ( int i = 1; i <= n; i++ ) {
        for ( int j = 0; j <= e[i]; j++ ) {
            for ( int h = 0; j+h <= m; h++ ) {
                if ( !h || ans[i-1][h] ) ans[i][j+h] = getmax( ans[i][j+h] , ans[i-1][h]+d[i][j] );
                tot = getmax( tot , ans[i][j+h] );
            }
        }
    }
    return tot;
}

int main()
{
    scanf( "%d%d" , &n , &m );
    for ( int i = 1; i <= n; i++ ) {
        scanf( "%d" , &e[i] );
        for ( int j = 1; j <= e[i]; j++ ) scanf( "%d" , &data[j] );
        cal(i,e[i]);
    }
    printf( "%d\n" , getans() );
    return 0;
}


//For Future
//By JFantasy

#include <cstdio>
#include <cstring>

const int maxn = 105;

int d[maxn][maxn] , e[maxn];
int data[maxn];
int ans[maxn][maxn];
int n , m;

int getmax( int a , int b )
{
    return a>b?a:b;
}

int getmin( int a , int b )
{
    return a<b?a:b;
}

void cal( int x , int num )
{
    int sum[maxn];
    sum[0] = 0;
    for ( int i = 1; i <= num; i++ ) sum[i] = sum[i-1] + data[i];
    for ( int i = 1; i <= getmin(num,m); i++ ) {
        for ( int j = 0; j <= i; j++ ) {
            d[x][i] = getmax( d[x][i] , sum[j]+sum[num]-sum[num-(i-j)] );
        }
    }
}

int getans()
{
    int tot = 0;
    for ( int i = 1; i <= n; i++ ) {
        for ( int h = 0; h <= m; h++ ) {
            if ( !ans[i-1][h] && h ) continue;
            for ( int j = 0; j <= e[i] && j+h <= m; j++ ) {
                if ( !h || ans[i-1][h] ) ans[i][j+h] = getmax( ans[i][j+h] , ans[i-1][h]+d[i][j] );
                tot = getmax( tot , ans[i][j+h] );
            }
        }
    }
    return tot;
}

int main()
{
    scanf( "%d%d" , &n , &m );
    for ( int i = 1; i <= n; i++ ) {
        scanf( "%d" , &e[i] );
        for ( int j = 1; j <= e[i]; j++ ) scanf( "%d" , &data[j] );
        cal(i,e[i]);
    }
    printf( "%d\n" , getans() );
    return 0;
}


//For Future
//By JFantasy

#include <cstdio>
#include <cstring>

const int maxn = 105;

int d[maxn][maxn] , e[maxn];
int data[maxn];
int ans[maxn][maxn];
int n , m;

int getmax( int a , int b )
{
    return a>b?a:b;
}

int getmin( int a , int b )
{
    return a<b?a:b;
}

void cal( int x , int num )
{
    int sum[maxn];
    sum[0] = 0;
    for ( int i = 1; i <= num; i++ ) sum[i] = sum[i-1] + data[i];
    for ( int i = 1; i <= getmin(num,m); i++ ) {
        for ( int j = 0; j <= i; j++ ) {
            d[x][i] = getmax( d[x][i] , sum[j]+sum[num]-sum[num-(i-j)] );
        }
    }
}

int getans()
{
    int tot = 0;
    for ( int i = 1; i <= n; i++ ) {
        for ( int h = 0; h <= m; h++ ) {
            if ( !ans[i-1][h] && h ) break;
            for ( int j = 0; j <= e[i] && j+h <= m; j++ ) {
                if ( !h || ans[i-1][h] ) ans[i][j+h] = getmax( ans[i][j+h] , ans[i-1][h]+d[i][j] );
            }
        }
    }
    for ( int i = 0; i <= m; i++ ) tot = getmax( tot , ans[n][i] );
    return tot;
}

int main()
{
    scanf( "%d%d" , &n , &m );
    for ( int i = 1; i <= n; i++ ) {
        scanf( "%d" , &e[i] );
        for ( int j = 1; j <= e[i]; j++ ) scanf( "%d" , &data[j] );
        cal(i,e[i]);
    }
    printf( "%d\n" , getans() );
    return 0;
}


//For Future
//By JFantasy

#include <cstdio>
#include <cstring>

const int maxn = 105;
const int maxm = 10005;

int d[maxn][maxn] , e[maxn];
int data[maxn];
int ans[maxn][maxm];
int n , m;

int getmax( int a , int b )
{
    return a>b?a:b;
}

int getmin( int a , int b )
{
    return a<b?a:b;
}

void cal( int x , int num )
{
    int sum[maxn];
    sum[0] = 0;
    for ( int i = 1; i <= num; i++ ) sum[i] = sum[i-1] + data[i];
    for ( int i = 1; i <= getmin(num,m); i++ ) {
        for ( int j = 0; j <= i; j++ ) {
            d[x][i] = getmax( d[x][i] , sum[j]+sum[num]-sum[num-(i-j)] );
        }
    }
}

int getans()
{
    int tot = 0;
    for ( int i = 1; i <= n; i++ ) {
        for ( int h = 0; h <= m; h++ ) {
            if ( !ans[i-1][h] && h ) break;
            for ( int j = 0; j <= e[i] && j+h <= m; j++ ) {
                if ( !h || ans[i-1][h] ) ans[i][j+h] = getmax( ans[i][j+h] , ans[i-1][h]+d[i][j] );
            }
        }
    }
    for ( int i = 0; i <= m; i++ ) tot = getmax( tot , ans[n][i] );
    return tot;
}

int main()
{
    scanf( "%d%d" , &n , &m );
    for ( int i = 1; i <= n; i++ ) {
        scanf( "%d" , &e[i] );
        for ( int j = 1; j <= e[i]; j++ ) scanf( "%d" , &data[j] );
        cal(i,e[i]);
    }
    printf( "%d\n" , getans() );
    return 0;
}


//For Future
//By JFantasy

#include <cstdio>
#include <cstring>

const int maxn = 105;

int d[maxn][maxn] , e[maxn];
int data[maxn];
int ans[maxn][maxn];
int n , m;

int getmax( int a , int b )
{
    return a>b?a:b;
}

int getmin( int a , int b )
{
    return a<b?a:b;
}

void cal( int x , int num )
{
    int sum[maxn];
    sum[0] = 0;
    for ( int i = 1; i <= num; i++ ) sum[i] = sum[i-1] + data[i];
    for ( int i = 1; i <= getmin(num,m); i++ ) {
        for ( int j = 0; j <= i; j++ ) {
            d[x][i] = getmax( d[x][i] , sum[j]+sum[num]-sum[num-(i-j)] );
        }
    }
}

int getans()
{
    int tot = 0;
    for ( int i = 1; i <= n; i++ ) {
        for ( int h = 0; h <= m; h++ ) {
            if ( !ans[i-1][h] && h ) continue;
            for ( int j = 0; j <= e[i] && j+h <= m; j++ ) {
                ans[i][j+h] = getmax( ans[i][j+h] , ans[i-1][h]+d[i][j] );
            }
        }
    }
    for ( int i = 0; i <= m; i++ ) tot = getmax( tot , ans[n][i] );
    return tot;
}

int main()
{
    scanf( "%d%d" , &n , &m );
    for ( int i = 1; i <= n; i++ ) {
        scanf( "%d" , &e[i] );
        for ( int j = 1; j <= e[i]; j++ ) scanf( "%d" , &data[j] );
        cal(i,e[i]);
    }
    printf( "%d\n" , getans() );
    return 0;
}


/*
8% PR NJ
*/

#include<bits/stdc++.h>
using namespace std ;

#define Nmx 100
#define Mmx 10000
int n , m ;

int originaldata[Nmx+1][Nmx+1] ;
int ultadata[Nmx+1][Nmx+1] ;

int sumdata[Nmx+1][Nmx+1] ;
int ultasumdata[Nmx+1][Nmx+1] ;

int tak[Nmx+1] ;

int GT[Nmx+1+100][Mmx+1+100] ;

int i , j , k , x , u ;
int koyta ; // [1,100]

int achekoyta , select , local_max , l_sum , r_sum , lft , rt ;
int dp[Nmx+1+100][Mmx+1+100] ;

int f( int kontak ,  int available_upay )
{
    //cout << "kontak : " << kontak << " avail : " << available_upay << endl ;
    if( available_upay == 0 )
    {
        return 0 ;
    }
    if( kontak == n )
    {
        return GT[kontak][available_upay] ;
    }
    if( dp[kontak][available_upay] != -1 )
    {
        return dp[kontak][available_upay] ;
    }
    int eitakeache = tak[kontak] ;

    int eitakebest = 0 ;
    for( int eitakeselection = 0 ; eitakeselection <= eitakeache ; eitakeselection++ )
    {
        if( kontak < n )
        {
            eitakebest = max( eitakebest , GT[kontak][eitakeselection] + f( kontak+1 , m-eitakeselection ) ) ;
        }
    }
    dp[kontak][available_upay] = eitakebest ;
    return eitakebest ;
}

int ANS ;
int main()
{

    //freopen( "input.txt" , "r" , stdin ) ;
    cin >> n >> m ;

    for( i = 1 ; i <= n ; i++ )
    {
        cin >> koyta ;
        tak[i] = koyta ;
        for( j = 0 ; j < koyta ; j++ )
        {
            scanf( "%d" , &originaldata[i][j] ) ;
            u = koyta - 1 - j ;
            ultadata[i][u] = originaldata[i][j] ;

            sumdata[i][j] =  originaldata[i][j] ;
            ultasumdata[i][u] = ultadata[i][u] ;

            //ultasumdata[]
        }
        for( x = 1 ; x < koyta ; x++ )
        {
            sumdata[i][x] += sumdata[i][x-1] ;
            ultasumdata[i][x] += ultasumdata[i][x-1] ;
        }
    }
    /*
    for( i = 1 ; i <= n ; i++ )
    {

        cout << "tak : " << i << " = " << endl ;
        cout << "data :" << endl ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << originaldata[i][j] << " " ;
        }
        cout << endl ;
        cout << "ultadata :" << endl ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << ultadata[i][j] << " " ;
        }
        cout << endl;
        cout << "sum : " ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << sumdata[i][j] << " " ;
        }
        cout << endl ;
        cout << "ultasum : " ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << ultasumdata[i][j] << " " ;
        }
        cout << endl ;

        cout << endl << endl ;

    }
    */

    for( i = 1 ; i <= n ; i++ )
    {
        achekoyta = tak[i] ;
        for( select = 1 ; select <= achekoyta ; select++ )
        {
            local_max = 0 ;
            for( lft = select ; lft >= 0 ; lft -- )
            {
                rt = select - lft ;
                if( lft-1 >= 0 ) l_sum = sumdata[i][lft-1] ;
                else l_sum = 0 ;
                if( rt-1 >= 0 ) r_sum = ultasumdata[i][rt-1] ;
                else r_sum = 0 ;

                local_max = max( local_max , l_sum + r_sum ) ;
            }
            GT[i][select] = local_max ;
        }
    }
    /*
    cout << "greedy table :D " << endl ;
    for( i = 1 ; i <= n ; i++ )
    {
        achekoyta = tak[i] ;
        for( select = 0 ; select <= achekoyta ; select++ )
        {
            cout << GT[i][select] << " " ;
        }
        cout << endl ;
    }
    */

    memset( dp , -1 ,sizeof(dp) ) ;
    ANS = f(1,m) ;
    //cout << "ans : " << endl ;
    cout << ANS << endl ;
    //cout << dp[1][m] << endl ;

    return 0 ;
}


/*
8% PR NJ
*/

#include<bits/stdc++.h>
using namespace std ;

#define NINF -1000000000
#define MX 10000

#define Nmx 100
#define Mmx 10000
int n , m ;

int originaldata[Nmx+100][MX+100] ;
int ultadata[Nmx+100][MX+100] ;

int sumdata[Nmx+100][MX+100] ;
int ultasumdata[Nmx+100][MX+100] ;

int tak[MX+100] ;
int newtak[MX+100] ;

int GT[Nmx+100][MX+100] ;

int i , j , k , x , u ;
int koyta ; // [1,100]

int achekoyta , select , local_max , l_sum , r_sum , lft , rt ;
int dp[Nmx+1+100][Mmx+1+100] ;

int f( int kontak ,  int available_upay )
{
    //cout << "kontak : " << kontak << " avail : " << available_upay << endl ;
    if( available_upay == 0 )
    {
        return 0 ;
    }
    if( available_upay > newtak[kontak] )
    {
        return NINF ;
    }

    if( kontak == n )
    {
        return GT[kontak][available_upay] ;
    }

    if( dp[kontak][available_upay] != -1 )
    {
        return dp[kontak][available_upay] ;
    }
    int eitakeache = tak[kontak] ;

    int eitakebest = 0 ;
    for( int eitakeselection = 0 ; eitakeselection <= eitakeache ; eitakeselection++ )
    {
        if( kontak < n )
        {
            //cout << "tak :" << kontak << " selection : " << eitakeselection << endl ;
            //cout << "GT["<<kontak<<"]["<<eitakeselection<<"] :" << GT[kontak][eitakeselection] << endl ;
            //cout << "f(k+1) :" << f( kontak+1 , m-eitakeselection ) << endl ;
            eitakebest = max( eitakebest , GT[kontak][eitakeselection] + f( kontak+1 , available_upay-eitakeselection ) ) ;
            //cout << "eitakebest : " << eitakebest << endl ;
        }
    }
    dp[kontak][available_upay] =  eitakebest  ;
    //cout <<"dp["<< kontak <<"][" << available_upay << "] : " << eitakebest << endl ;
    return eitakebest ;
}

int ANS ;
int main()
{

    //freopen( "input.txt" , "r" , stdin ) ;
    cin >> n >> m ;

    for( i = 1 ; i <= n ; i++ )
    {
        cin >> koyta ;
        newtak[i] = tak[i] = koyta ;
        for( j = 0 ; j < koyta ; j++ )
        {
            scanf( "%d" , &originaldata[i][j] ) ;
            u = koyta - 1 - j ;
            ultadata[i][u] = originaldata[i][j] ;

            sumdata[i][j] =  originaldata[i][j] ;
            ultasumdata[i][u] = ultadata[i][u] ;

            //ultasumdata[]
        }
        for( x = 1 ; x < koyta ; x++ )
        {
            sumdata[i][x] += sumdata[i][x-1] ;
            ultasumdata[i][x] += ultasumdata[i][x-1] ;
        }
    }
    for( i = n-1 ; i >= 1 ; i-- )
    {
        newtak[i] += newtak[i+1] ;
    }
    /*
    cout << "printing tak :" << endl ;
    for( i = 1 ; i <= n ; i++ )
    {
        cout << newtak[i] << " " ;
    }
    cout << endl
    */;

    /*
    for( i = 1 ; i <= n ; i++ )
    {

        cout << "tak : " << i << " = " << endl ;
        cout << "data :" ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << originaldata[i][j] << " " ;
        }
        cout << endl ;
        cout << "ultadata :" ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << ultadata[i][j] << " " ;
        }
        cout << endl;
        cout << "sum : " ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << sumdata[i][j] << " " ;
        }
        cout << endl ;
        cout << "ultasum : " ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << ultasumdata[i][j] << " " ;
        }
        cout << endl ;

        cout << endl << endl ;

    }
    */

    memset( GT , 0 , sizeof(GT) ) ;
    for( i = 1 ; i <= n ; i++ )
    {
        achekoyta = tak[i] ;
        for( select = 1 ; select <= achekoyta ; select++ )
        {
            local_max = 0 ;
            for( lft = select ; lft >= 0 ; lft -- )
            {
                rt = select - lft ;
                if( lft-1 >= 0 ) l_sum = sumdata[i][lft-1] ;
                else l_sum = 0 ;
                if( rt-1 >= 0 ) r_sum = ultasumdata[i][rt-1] ;
                else r_sum = 0 ;

                local_max = max( local_max , l_sum + r_sum ) ;
            }
            GT[i][select] = local_max ;
        }
    }
    /*
    cout << "greedy table :D " << endl ;
    for( i = 1 ; i <= n ; i++ )
    {
        achekoyta = tak[i] ;
        for( select = 0 ; select <= achekoyta ; select++ )
        {
            cout << GT[i][select] << " " ;
        }
        cout << endl ;
    }
    */

    memset( dp , -1 ,sizeof(dp) ) ;
    ANS = f(1,m) ;
    //cout << "ans : " << endl ;
    cout << ANS << endl ;
    //cout << dp[1][m] << endl ;

    return 0 ;
}


/*
8% PR NJ
*/

#include<bits/stdc++.h>
using namespace std ;

#define Nmx 100
#define Mmx 10000
int n , m ;

int originaldata[Nmx+1][Nmx+1] ;
int ultadata[Nmx+1][Nmx+1] ;

int sumdata[Nmx+1][Nmx+1] ;
int ultasumdata[Nmx+1][Nmx+1] ;

int tak[Nmx+1] ;

int GT[Nmx+1+100][Mmx+1+100] ;

int i , j , k , x , u ;
int koyta ; // [1,100]

int achekoyta , select , local_max , l_sum , r_sum , lft , rt ;
int dp[Nmx+1+100][Mmx+1+100] ;

int f( int kontak ,  int available_upay )
{
    //cout << "kontak : " << kontak << " avail : " << available_upay << endl ;
    if( available_upay == 0 )
    {
        return 0 ;
    }

    if( kontak == n )
    {
        if( tak[kontak] < available_upay )
        {
            return 0 ;
        }
        if( GT[kontak][available_upay] != -1 ) return GT[kontak][available_upay] ;
    }

    if( dp[kontak][available_upay] != -1 )
    {
        return dp[kontak][available_upay] ;
    }
    int eitakeache = tak[kontak] ;

    int eitakebest = 0 ;
    for( int eitakeselection = 0 ; eitakeselection <= eitakeache ; eitakeselection++ )
    {
        if( kontak < n )
        {
            //cout << "tak :" << kontak << " selection : " << eitakeselection << endl ;
            //cout << "GT["<<kontak<<"]["<<eitakeselection<<"] :" << GT[kontak][eitakeselection] << endl ;
            //cout << "f(k+1) :" << f( kontak+1 , m-eitakeselection ) << endl ;
            eitakebest = max( eitakebest , GT[kontak][eitakeselection] + f( kontak+1 , available_upay-eitakeselection ) ) ;
            //cout << "eitakebest : " << eitakebest << endl ;
        }
    }
    dp[kontak][available_upay] =  eitakebest  ;
    //cout <<"dp["<< kontak <<"][" << available_upay << "] : " << eitakebest << endl ;
    return eitakebest ;
}

int ANS ;
int main()
{

    //freopen( "input.txt" , "r" , stdin ) ;
    cin >> n >> m ;

    for( i = 1 ; i <= n ; i++ )
    {
        cin >> koyta ;
        tak[i] = koyta ;
        for( j = 0 ; j < koyta ; j++ )
        {
            scanf( "%d" , &originaldata[i][j] ) ;
            u = koyta - 1 - j ;
            ultadata[i][u] = originaldata[i][j] ;

            sumdata[i][j] =  originaldata[i][j] ;
            ultasumdata[i][u] = ultadata[i][u] ;

            //ultasumdata[]
        }
        for( x = 1 ; x < koyta ; x++ )
        {
            sumdata[i][x] += sumdata[i][x-1] ;
            ultasumdata[i][x] += ultasumdata[i][x-1] ;
        }
    }

    /*
    for( i = 1 ; i <= n ; i++ )
    {

        cout << "tak : " << i << " = " << endl ;
        cout << "data :" ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << originaldata[i][j] << " " ;
        }
        cout << endl ;
        cout << "ultadata :" ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << ultadata[i][j] << " " ;
        }
        cout << endl;
        cout << "sum : " ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << sumdata[i][j] << " " ;
        }
        cout << endl ;
        cout << "ultasum : " ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << ultasumdata[i][j] << " " ;
        }
        cout << endl ;

        cout << endl << endl ;

    }
    */

    memset( GT , 0 , sizeof(GT) ) ;
    for( i = 1 ; i <= n ; i++ )
    {
        achekoyta = tak[i] ;
        for( select = 1 ; select <= achekoyta ; select++ )
        {
            local_max = 0 ;
            for( lft = select ; lft >= 0 ; lft -- )
            {
                rt = select - lft ;
                if( lft-1 >= 0 ) l_sum = sumdata[i][lft-1] ;
                else l_sum = 0 ;
                if( rt-1 >= 0 ) r_sum = ultasumdata[i][rt-1] ;
                else r_sum = 0 ;

                local_max = max( local_max , l_sum + r_sum ) ;
            }
            GT[i][select] = local_max ;
        }
    }
    /*
    cout << "greedy table :D " << endl ;
    for( i = 1 ; i <= n ; i++ )
    {
        achekoyta = tak[i] ;
        for( select = 0 ; select <= achekoyta ; select++ )
        {
            cout << GT[i][select] << " " ;
        }
        cout << endl ;
    }
    */

    memset( dp , -1 ,sizeof(dp) ) ;
    ANS = f(1,m) ;
    //cout << "ans : " << endl ;
    cout << ANS << endl ;
    //cout << dp[1][m] << endl ;

    return 0 ;
}


/*
8% PR NJ
*/

#include<bits/stdc++.h>
using namespace std ;

#define NINF -10000000
#define MX 10000

#define Nmx 100
#define Mmx 10000
int n , m ;

int originaldata[Nmx+100][MX+100] ;
int ultadata[Nmx+100][MX+100] ;

int sumdata[Nmx+100][MX+100] ;
int ultasumdata[Nmx+100][MX+100] ;

int tak[MX+100] ;
int newtak[MX+100] ;

int GT[Nmx+100][MX+100] ;

int i , j , k , x , u ;
int koyta ; // [1,100]

int achekoyta , select , local_max , l_sum , r_sum , lft , rt ;
long long dp[Nmx+1+100][Mmx+1+100] ;

int f( int kontak ,  int available_upay )
{
    //cout << "kontak : " << kontak << " avail : " << available_upay << endl ;
    if( available_upay == 0 )
    {
        return 0 ;
    }
    if( available_upay > newtak[kontak] )
    {
        return NINF ;
    }

    if( kontak == n )
    {
        return GT[kontak][available_upay] ;
    }

    if( dp[kontak][available_upay] >= 0 )
    {
        return dp[kontak][available_upay] ;
    }
    int eitakeache = tak[kontak] ;

    int eitakebest = 0 ;
    for( int eitakeselection = 0 ; eitakeselection <= eitakeache ; eitakeselection++ )
    {

            //cout << "tak :" << kontak << " selection : " << eitakeselection << endl ;
            //cout << "GT["<<kontak<<"]["<<eitakeselection<<"] :" << GT[kontak][eitakeselection] << endl ;
            //cout << "f(k+1) :" << f( kontak+1 , m-eitakeselection ) << endl ;
            eitakebest = max( eitakebest , GT[kontak][eitakeselection] + f( kontak+1 , available_upay-eitakeselection ) ) ;
            //cout << "eitakebest : " << eitakebest << endl ;

    }
    dp[kontak][available_upay] =  eitakebest  ;
    //cout <<"dp["<< kontak <<"][" << available_upay << "] : " << eitakebest << endl ;
    return eitakebest ;
}

int ANS ;
int main()
{

    //freopen( "input.txt" , "r" , stdin ) ;
    cin >> n >> m ;

    for( i = 1 ; i <= n ; i++ )
    {
        cin >> koyta ;
        newtak[i] = tak[i] = koyta ;
        for( j = 0 ; j < koyta ; j++ )
        {
            scanf( "%d" , &originaldata[i][j] ) ;
            u = koyta - 1 - j ;
            ultadata[i][u] = originaldata[i][j] ;

            sumdata[i][j] =  originaldata[i][j] ;
            ultasumdata[i][u] = ultadata[i][u] ;

            //ultasumdata[]
        }
        for( x = 1 ; x < koyta ; x++ )
        {
            sumdata[i][x] += sumdata[i][x-1] ;
            ultasumdata[i][x] += ultasumdata[i][x-1] ;
        }
    }
    for( i = n-1 ; i >= 1 ; i-- )
    {
        newtak[i] += newtak[i+1] ;
    }
    /*
    cout << "printing tak :" << endl ;
    for( i = 1 ; i <= n ; i++ )
    {
        cout << newtak[i] << " " ;
    }
    cout << endl
    */;

    /*
    for( i = 1 ; i <= n ; i++ )
    {

        cout << "tak : " << i << " = " << endl ;
        cout << "data :" ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << originaldata[i][j] << " " ;
        }
        cout << endl ;
        cout << "ultadata :" ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << ultadata[i][j] << " " ;
        }
        cout << endl;
        cout << "sum : " ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << sumdata[i][j] << " " ;
        }
        cout << endl ;
        cout << "ultasum : " ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << ultasumdata[i][j] << " " ;
        }
        cout << endl ;

        cout << endl << endl ;

    }
    */

    memset( GT , 0 , sizeof(GT) ) ;
    for( i = 1 ; i <= n ; i++ )
    {
        achekoyta = tak[i] ;
        for( select = 1 ; select <= achekoyta ; select++ )
        {
            local_max = 0 ;
            for( lft = select ; lft >= 0 ; lft -- )
            {
                rt = select - lft ;
                if( lft-1 >= 0 ) l_sum = sumdata[i][lft-1] ;
                else l_sum = 0 ;
                if( rt-1 >= 0 ) r_sum = ultasumdata[i][rt-1] ;
                else r_sum = 0 ;

                local_max = max( local_max , l_sum + r_sum ) ;
            }
            GT[i][select] = local_max ;
        }
    }
    /*
    cout << "greedy table :D " << endl ;
    for( i = 1 ; i <= n ; i++ )
    {
        achekoyta = tak[i] ;
        for( select = 0 ; select <= achekoyta ; select++ )
        {
            cout << GT[i][select] << " " ;
        }
        cout << endl ;
    }
    */

    //dp[0][0] = 0 ;
    memset( dp , NINF ,sizeof(dp) ) ;
    dp[0][0] = 0 ;
    ANS = f(1,m) ;
    //cout << "ans : " << endl ;
    /*
    dp[0][0] = 0 ;
    for( int i = 0 ; i < n ; i++ )
    {
        for( int j = 0 ; j <= m ; j++ )
        {
            for( int extra = 0 ; extra <= tak[i+1] ;  extra++ )
            {
                dp[i+1][j+extra] = max( dp[i+1][j+extra] , dp[i][j] + GT[i+1][extra] ) ;
            }
        }
    }
    ANS = dp[n][m] ;
    */
    cout << ANS << endl ;
    //cout << dp[1][m] << endl ;

    return 0 ;
}


/*
8% PR NJ
*/

#include<bits/stdc++.h>
using namespace std ;

#define MX 10000

#define Nmx 100
#define Mmx 10000
int n , m ;

int originaldata[Nmx+100][MX+100] ;
int ultadata[Nmx+100][MX+100] ;

int sumdata[Nmx+100][MX+100] ;
int ultasumdata[Nmx+100][MX+100] ;

int tak[MX+100] ;

int GT[Nmx+100][MX+100] ;

int i , j , k , x , u ;
int koyta ; // [1,100]

int achekoyta , select , local_max , l_sum , r_sum , lft , rt ;
int dp[Nmx+1+100][Mmx+1+100] ;

int f( int kontak ,  int available_upay )
{
    //cout << "kontak : " << kontak << " avail : " << available_upay << endl ;
    if( available_upay == 0 )
    {
        return 0 ;
    }

    if( kontak == n )
    {
        if( tak[kontak] < available_upay )
        {
            return 0 ;
        }
        if( GT[kontak][available_upay] != -1 ) return GT[kontak][available_upay] ;
    }

    if( dp[kontak][available_upay] != -1 )
    {
        return dp[kontak][available_upay] ;
    }
    int eitakeache = tak[kontak] ;

    int eitakebest = 0 ;
    for( int eitakeselection = 0 ; eitakeselection <= eitakeache ; eitakeselection++ )
    {
        if( kontak < n )
        {
            //cout << "tak :" << kontak << " selection : " << eitakeselection << endl ;
            //cout << "GT["<<kontak<<"]["<<eitakeselection<<"] :" << GT[kontak][eitakeselection] << endl ;
            //cout << "f(k+1) :" << f( kontak+1 , m-eitakeselection ) << endl ;
            eitakebest = max( eitakebest , GT[kontak][eitakeselection] + f( kontak+1 , available_upay-eitakeselection ) ) ;
            //cout << "eitakebest : " << eitakebest << endl ;
        }
    }
    dp[kontak][available_upay] =  eitakebest  ;
    //cout <<"dp["<< kontak <<"][" << available_upay << "] : " << eitakebest << endl ;
    return eitakebest ;
}

int ANS ;
int main()
{

    //freopen( "input.txt" , "r" , stdin ) ;
    cin >> n >> m ;

    for( i = 1 ; i <= n ; i++ )
    {
        cin >> koyta ;
        tak[i] = koyta ;
        for( j = 0 ; j < koyta ; j++ )
        {
            scanf( "%d" , &originaldata[i][j] ) ;
            u = koyta - 1 - j ;
            ultadata[i][u] = originaldata[i][j] ;

            sumdata[i][j] =  originaldata[i][j] ;
            ultasumdata[i][u] = ultadata[i][u] ;

            //ultasumdata[]
        }
        for( x = 1 ; x < koyta ; x++ )
        {
            sumdata[i][x] += sumdata[i][x-1] ;
            ultasumdata[i][x] += ultasumdata[i][x-1] ;
        }
    }

    /*
    for( i = 1 ; i <= n ; i++ )
    {

        cout << "tak : " << i << " = " << endl ;
        cout << "data :" ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << originaldata[i][j] << " " ;
        }
        cout << endl ;
        cout << "ultadata :" ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << ultadata[i][j] << " " ;
        }
        cout << endl;
        cout << "sum : " ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << sumdata[i][j] << " " ;
        }
        cout << endl ;
        cout << "ultasum : " ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << ultasumdata[i][j] << " " ;
        }
        cout << endl ;

        cout << endl << endl ;

    }
    */

    memset( GT , 0 , sizeof(GT) ) ;
    for( i = 1 ; i <= n ; i++ )
    {
        achekoyta = tak[i] ;
        for( select = 1 ; select <= achekoyta ; select++ )
        {
            local_max = 0 ;
            for( lft = select ; lft >= 0 ; lft -- )
            {
                rt = select - lft ;
                if( lft-1 >= 0 ) l_sum = sumdata[i][lft-1] ;
                else l_sum = 0 ;
                if( rt-1 >= 0 ) r_sum = ultasumdata[i][rt-1] ;
                else r_sum = 0 ;

                local_max = max( local_max , l_sum + r_sum ) ;
            }
            GT[i][select] = local_max ;
        }
    }
    /*
    cout << "greedy table :D " << endl ;
    for( i = 1 ; i <= n ; i++ )
    {
        achekoyta = tak[i] ;
        for( select = 0 ; select <= achekoyta ; select++ )
        {
            cout << GT[i][select] << " " ;
        }
        cout << endl ;
    }
    */

    memset( dp , -1 ,sizeof(dp) ) ;
    ANS = f(1,m) ;
    //cout << "ans : " << endl ;
    cout << ANS << endl ;
    //cout << dp[1][m] << endl ;

    return 0 ;
}


/*
8% PR NJ
*/

#include<bits/stdc++.h>
using namespace std ;

#define NINF -10000000
#define MX 10000

#define Nmx 100
#define Mmx 10000
int n , m ;

int originaldata[Nmx+100][MX+100] ;
int ultadata[Nmx+100][MX+100] ;

int sumdata[Nmx+100][MX+100] ;
int ultasumdata[Nmx+100][MX+100] ;

int tak[MX+100] ;
int newtak[MX+100] ;

int GT[Nmx+100][MX+100] ;

int i , j , k , x , u ;
int koyta ; // [1,100]

int achekoyta , select , local_max , l_sum , r_sum , lft , rt ;
long long dp[Nmx+1+100][Mmx+1+100] ;

int f( int kontak ,  int available_upay )
{
    //cout << "kontak : " << kontak << " avail : " << available_upay << endl ;
    if( available_upay == 0 )
    {
        return 0 ;
    }
    if( available_upay > newtak[kontak] )
    {
        return NINF ;
    }

    if( kontak == n )
    {
        return GT[kontak][available_upay] ;
    }

    if( dp[kontak][available_upay] >= 0 )
    {
        return dp[kontak][available_upay] ;
    }
    int eitakeache = tak[kontak] ;

    int eitakebest = 0 ;
    for( int eitakeselection = 0 ; eitakeselection <= eitakeache ; eitakeselection++ )
    {

            //cout << "tak :" << kontak << " selection : " << eitakeselection << endl ;
            //cout << "GT["<<kontak<<"]["<<eitakeselection<<"] :" << GT[kontak][eitakeselection] << endl ;
            //cout << "f(k+1) :" << f( kontak+1 , m-eitakeselection ) << endl ;
            eitakebest = max( eitakebest , GT[kontak][eitakeselection] + f( kontak+1 , available_upay-eitakeselection ) ) ;
            //cout << "eitakebest : " << eitakebest << endl ;

    }
    dp[kontak][available_upay] =  eitakebest  ;
    //cout <<"dp["<< kontak <<"][" << available_upay << "] : " << eitakebest << endl ;
    return eitakebest ;
}

int ANS ;
int main()
{

    //freopen( "input.txt" , "r" , stdin ) ;
    cin >> n >> m ;

    for( i = 1 ; i <= n ; i++ )
    {
        cin >> koyta ;
        newtak[i] = tak[i] = koyta ;
        for( j = 0 ; j < koyta ; j++ )
        {
            scanf( "%d" , &originaldata[i][j] ) ;
            u = koyta - 1 - j ;
            ultadata[i][u] = originaldata[i][j] ;

            sumdata[i][j] =  originaldata[i][j] ;
            ultasumdata[i][u] = ultadata[i][u] ;

            //ultasumdata[]
        }
        for( x = 1 ; x < koyta ; x++ )
        {
            sumdata[i][x] += sumdata[i][x-1] ;
            ultasumdata[i][x] += ultasumdata[i][x-1] ;
        }
    }
    for( i = n-1 ; i >= 1 ; i-- )
    {
        newtak[i] += newtak[i+1] ;
    }
    /*
    cout << "printing tak :" << endl ;
    for( i = 1 ; i <= n ; i++ )
    {
        cout << newtak[i] << " " ;
    }
    cout << endl
    */;

    /*
    for( i = 1 ; i <= n ; i++ )
    {

        cout << "tak : " << i << " = " << endl ;
        cout << "data :" ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << originaldata[i][j] << " " ;
        }
        cout << endl ;
        cout << "ultadata :" ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << ultadata[i][j] << " " ;
        }
        cout << endl;
        cout << "sum : " ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << sumdata[i][j] << " " ;
        }
        cout << endl ;
        cout << "ultasum : " ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << ultasumdata[i][j] << " " ;
        }
        cout << endl ;

        cout << endl << endl ;

    }
    */

    memset( GT , 0 , sizeof(GT) ) ;
    for( i = 1 ; i <= n ; i++ )
    {
        achekoyta = tak[i] ;
        for( select = 1 ; select <= achekoyta ; select++ )
        {
            local_max = 0 ;
            for( lft = select ; lft >= 0 ; lft -- )
            {
                rt = select - lft ;
                if( lft-1 >= 0 ) l_sum = sumdata[i][lft-1] ;
                else l_sum = 0 ;
                if( rt-1 >= 0 ) r_sum = ultasumdata[i][rt-1] ;
                else r_sum = 0 ;

                local_max = max( local_max , l_sum + r_sum ) ;
            }
            GT[i][select] = local_max ;
        }
    }
    /*
    cout << "greedy table :D " << endl ;
    for( i = 1 ; i <= n ; i++ )
    {
        achekoyta = tak[i] ;
        for( select = 0 ; select <= achekoyta ; select++ )
        {
            cout << GT[i][select] << " " ;
        }
        cout << endl ;
    }
    */

    memset( dp , NINF ,sizeof(dp) ) ;
    ANS = f(1,m) ;
    //cout << "ans : " << endl ;
    cout << ANS << endl ;
    //cout << dp[1][m] << endl ;

    return 0 ;
}


/*
8% PR NJ
*/

#include<bits/stdc++.h>
using namespace std ;

#define MX 100000

#define Nmx 100
#define Mmx 10000
int n , m ;

int originaldata[Nmx+100][MX] ;
int ultadata[Nmx+100][MX] ;

int sumdata[Nmx+100][MX] ;
int ultasumdata[Nmx+100][MX] ;

int tak[MX] ;

int GT[Nmx+100][MX] ;

int i , j , k , x , u ;
int koyta ; // [1,100]

int achekoyta , select , local_max , l_sum , r_sum , lft , rt ;
int dp[Nmx+1+100][Mmx+1+100] ;

int f( int kontak ,  int available_upay )
{
    //cout << "kontak : " << kontak << " avail : " << available_upay << endl ;
    if( available_upay == 0 )
    {
        return 0 ;
    }

    if( kontak == n )
    {
        if( tak[kontak] < available_upay )
        {
            return 0 ;
        }
        if( GT[kontak][available_upay] != -1 ) return GT[kontak][available_upay] ;
    }

    if( dp[kontak][available_upay] != -1 )
    {
        return dp[kontak][available_upay] ;
    }
    int eitakeache = tak[kontak] ;

    int eitakebest = 0 ;
    for( int eitakeselection = 0 ; eitakeselection <= eitakeache ; eitakeselection++ )
    {
        if( kontak < n )
        {
            //cout << "tak :" << kontak << " selection : " << eitakeselection << endl ;
            //cout << "GT["<<kontak<<"]["<<eitakeselection<<"] :" << GT[kontak][eitakeselection] << endl ;
            //cout << "f(k+1) :" << f( kontak+1 , m-eitakeselection ) << endl ;
            eitakebest = max( eitakebest , GT[kontak][eitakeselection] + f( kontak+1 , available_upay-eitakeselection ) ) ;
            //cout << "eitakebest : " << eitakebest << endl ;
        }
    }
    dp[kontak][available_upay] =  eitakebest  ;
    //cout <<"dp["<< kontak <<"][" << available_upay << "] : " << eitakebest << endl ;
    return eitakebest ;
}

int ANS ;
int main()
{

    //freopen( "input.txt" , "r" , stdin ) ;
    cin >> n >> m ;

    for( i = 1 ; i <= n ; i++ )
    {
        cin >> koyta ;
        tak[i] = koyta ;
        for( j = 0 ; j < koyta ; j++ )
        {
            scanf( "%d" , &originaldata[i][j] ) ;
            u = koyta - 1 - j ;
            ultadata[i][u] = originaldata[i][j] ;

            sumdata[i][j] =  originaldata[i][j] ;
            ultasumdata[i][u] = ultadata[i][u] ;

            //ultasumdata[]
        }
        for( x = 1 ; x < koyta ; x++ )
        {
            sumdata[i][x] += sumdata[i][x-1] ;
            ultasumdata[i][x] += ultasumdata[i][x-1] ;
        }
    }

    /*
    for( i = 1 ; i <= n ; i++ )
    {

        cout << "tak : " << i << " = " << endl ;
        cout << "data :" ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << originaldata[i][j] << " " ;
        }
        cout << endl ;
        cout << "ultadata :" ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << ultadata[i][j] << " " ;
        }
        cout << endl;
        cout << "sum : " ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << sumdata[i][j] << " " ;
        }
        cout << endl ;
        cout << "ultasum : " ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << ultasumdata[i][j] << " " ;
        }
        cout << endl ;

        cout << endl << endl ;

    }
    */

    memset( GT , 0 , sizeof(GT) ) ;
    for( i = 1 ; i <= n ; i++ )
    {
        achekoyta = tak[i] ;
        for( select = 1 ; select <= achekoyta ; select++ )
        {
            local_max = 0 ;
            for( lft = select ; lft >= 0 ; lft -- )
            {
                rt = select - lft ;
                if( lft-1 >= 0 ) l_sum = sumdata[i][lft-1] ;
                else l_sum = 0 ;
                if( rt-1 >= 0 ) r_sum = ultasumdata[i][rt-1] ;
                else r_sum = 0 ;

                local_max = max( local_max , l_sum + r_sum ) ;
            }
            GT[i][select] = local_max ;
        }
    }
    /*
    cout << "greedy table :D " << endl ;
    for( i = 1 ; i <= n ; i++ )
    {
        achekoyta = tak[i] ;
        for( select = 0 ; select <= achekoyta ; select++ )
        {
            cout << GT[i][select] << " " ;
        }
        cout << endl ;
    }
    */

    memset( dp , -1 ,sizeof(dp) ) ;
    ANS = f(1,m) ;
    //cout << "ans : " << endl ;
    cout << ANS << endl ;
    //cout << dp[1][m] << endl ;

    return 0 ;
}


/*
8% PR NJ
*/

#include<bits/stdc++.h>
using namespace std ;

#define MX 10000

#define Nmx 100
#define Mmx 10000
int n , m ;

int originaldata[Nmx+100][MX+100] ;
int ultadata[Nmx+100][MX+100] ;

int sumdata[Nmx+100][MX+100] ;
int ultasumdata[Nmx+100][MX+100] ;

int tak[MX+100] ;
int newtak[MX+100] ;

int GT[Nmx+100][MX+100] ;

int i , j , k , x , u ;
int koyta ; // [1,100]

int achekoyta , select , local_max , l_sum , r_sum , lft , rt ;
int dp[Nmx+1+100][Mmx+1+100] ;

int f( int kontak ,  int available_upay )
{
    //cout << "kontak : " << kontak << " avail : " << available_upay << endl ;
    if( available_upay == 0 )
    {
        return 0 ;
    }
    if( available_upay > newtak[kontak] )
    {
        return 0 ;
    }

    if( kontak == n )
    {
        return GT[kontak][available_upay] ;
    }

    if( dp[kontak][available_upay] != -1 )
    {
        return dp[kontak][available_upay] ;
    }
    int eitakeache = tak[kontak] ;

    int eitakebest = 0 ;
    for( int eitakeselection = 0 ; eitakeselection <= eitakeache ; eitakeselection++ )
    {
        if( kontak < n )
        {
            //cout << "tak :" << kontak << " selection : " << eitakeselection << endl ;
            //cout << "GT["<<kontak<<"]["<<eitakeselection<<"] :" << GT[kontak][eitakeselection] << endl ;
            //cout << "f(k+1) :" << f( kontak+1 , m-eitakeselection ) << endl ;
            eitakebest = max( eitakebest , GT[kontak][eitakeselection] + f( kontak+1 , available_upay-eitakeselection ) ) ;
            //cout << "eitakebest : " << eitakebest << endl ;
        }
    }
    dp[kontak][available_upay] =  eitakebest  ;
    //cout <<"dp["<< kontak <<"][" << available_upay << "] : " << eitakebest << endl ;
    return eitakebest ;
}

int ANS ;
int main()
{

    //freopen( "input.txt" , "r" , stdin ) ;
    cin >> n >> m ;

    for( i = 1 ; i <= n ; i++ )
    {
        cin >> koyta ;
        newtak[i] = tak[i] = koyta ;
        for( j = 0 ; j < koyta ; j++ )
        {
            scanf( "%d" , &originaldata[i][j] ) ;
            u = koyta - 1 - j ;
            ultadata[i][u] = originaldata[i][j] ;

            sumdata[i][j] =  originaldata[i][j] ;
            ultasumdata[i][u] = ultadata[i][u] ;

            //ultasumdata[]
        }
        for( x = 1 ; x < koyta ; x++ )
        {
            sumdata[i][x] += sumdata[i][x-1] ;
            ultasumdata[i][x] += ultasumdata[i][x-1] ;
        }
    }
    for( i = n-1 ; i >= 1 ; i-- )
    {
        newtak[i] += newtak[i+1] ;
    }
    /*
    cout << "printing tak :" << endl ;
    for( i = 1 ; i <= n ; i++ )
    {
        cout << newtak[i] << " " ;
    }
    cout << endl
    */;

    /*
    for( i = 1 ; i <= n ; i++ )
    {

        cout << "tak : " << i << " = " << endl ;
        cout << "data :" ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << originaldata[i][j] << " " ;
        }
        cout << endl ;
        cout << "ultadata :" ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << ultadata[i][j] << " " ;
        }
        cout << endl;
        cout << "sum : " ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << sumdata[i][j] << " " ;
        }
        cout << endl ;
        cout << "ultasum : " ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << ultasumdata[i][j] << " " ;
        }
        cout << endl ;

        cout << endl << endl ;

    }
    */

    memset( GT , 0 , sizeof(GT) ) ;
    for( i = 1 ; i <= n ; i++ )
    {
        achekoyta = tak[i] ;
        for( select = 1 ; select <= achekoyta ; select++ )
        {
            local_max = 0 ;
            for( lft = select ; lft >= 0 ; lft -- )
            {
                rt = select - lft ;
                if( lft-1 >= 0 ) l_sum = sumdata[i][lft-1] ;
                else l_sum = 0 ;
                if( rt-1 >= 0 ) r_sum = ultasumdata[i][rt-1] ;
                else r_sum = 0 ;

                local_max = max( local_max , l_sum + r_sum ) ;
            }
            GT[i][select] = local_max ;
        }
    }
    /*
    cout << "greedy table :D " << endl ;
    for( i = 1 ; i <= n ; i++ )
    {
        achekoyta = tak[i] ;
        for( select = 0 ; select <= achekoyta ; select++ )
        {
            cout << GT[i][select] << " " ;
        }
        cout << endl ;
    }
    */

    memset( dp , -1 ,sizeof(dp) ) ;
    ANS = f(1,m) ;
    //cout << "ans : " << endl ;
    cout << ANS << endl ;
    //cout << dp[1][m] << endl ;

    return 0 ;
}


/*
8% PR NJ
*/

#include<bits/stdc++.h>
using namespace std ;

#define MX 10000

#define Nmx 100
#define Mmx 10000
int n , m ;

int originaldata[Nmx+100][MX+100] ;
int ultadata[Nmx+100][MX+100] ;

int sumdata[Nmx+100][MX+100] ;
int ultasumdata[Nmx+100][MX+100] ;

int tak[MX+100] ;

int GT[Nmx+100][MX+100] ;

int i , j , k , x , u ;
int koyta ; // [1,100]

int achekoyta , select , local_max , l_sum , r_sum , lft , rt ;
int dp[Nmx+1+100][Mmx+1+100] ;

int f( int kontak ,  int available_upay )
{
    //cout << "kontak : " << kontak << " avail : " << available_upay << endl ;
    if( available_upay == 0 )
    {
        return 0 ;
    }

    if( kontak == n )
    {
        return GT[kontak][available_upay] ;
    }

    if( dp[kontak][available_upay] != -1 )
    {
        return dp[kontak][available_upay] ;
    }
    int eitakeache = tak[kontak] ;

    int eitakebest = 0 ;
    for( int eitakeselection = 0 ; eitakeselection <= eitakeache ; eitakeselection++ )
    {
        if( kontak < n )
        {
            //cout << "tak :" << kontak << " selection : " << eitakeselection << endl ;
            //cout << "GT["<<kontak<<"]["<<eitakeselection<<"] :" << GT[kontak][eitakeselection] << endl ;
            //cout << "f(k+1) :" << f( kontak+1 , m-eitakeselection ) << endl ;
            eitakebest = max( eitakebest , GT[kontak][eitakeselection] + f( kontak+1 , available_upay-eitakeselection ) ) ;
            //cout << "eitakebest : " << eitakebest << endl ;
        }
    }
    dp[kontak][available_upay] =  eitakebest  ;
    //cout <<"dp["<< kontak <<"][" << available_upay << "] : " << eitakebest << endl ;
    return eitakebest ;
}

int ANS ;
int main()
{

    //freopen( "input.txt" , "r" , stdin ) ;
    cin >> n >> m ;

    for( i = 1 ; i <= n ; i++ )
    {
        cin >> koyta ;
        tak[i] = koyta ;
        for( j = 0 ; j < koyta ; j++ )
        {
            scanf( "%d" , &originaldata[i][j] ) ;
            u = koyta - 1 - j ;
            ultadata[i][u] = originaldata[i][j] ;

            sumdata[i][j] =  originaldata[i][j] ;
            ultasumdata[i][u] = ultadata[i][u] ;

            //ultasumdata[]
        }
        for( x = 1 ; x < koyta ; x++ )
        {
            sumdata[i][x] += sumdata[i][x-1] ;
            ultasumdata[i][x] += ultasumdata[i][x-1] ;
        }
    }

    /*
    for( i = 1 ; i <= n ; i++ )
    {

        cout << "tak : " << i << " = " << endl ;
        cout << "data :" ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << originaldata[i][j] << " " ;
        }
        cout << endl ;
        cout << "ultadata :" ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << ultadata[i][j] << " " ;
        }
        cout << endl;
        cout << "sum : " ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << sumdata[i][j] << " " ;
        }
        cout << endl ;
        cout << "ultasum : " ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << ultasumdata[i][j] << " " ;
        }
        cout << endl ;

        cout << endl << endl ;

    }
    */

    memset( GT , 0 , sizeof(GT) ) ;
    for( i = 1 ; i <= n ; i++ )
    {
        achekoyta = tak[i] ;
        for( select = 1 ; select <= achekoyta ; select++ )
        {
            local_max = 0 ;
            for( lft = select ; lft >= 0 ; lft -- )
            {
                rt = select - lft ;
                if( lft-1 >= 0 ) l_sum = sumdata[i][lft-1] ;
                else l_sum = 0 ;
                if( rt-1 >= 0 ) r_sum = ultasumdata[i][rt-1] ;
                else r_sum = 0 ;

                local_max = max( local_max , l_sum + r_sum ) ;
            }
            GT[i][select] = local_max ;
        }
    }
    /*
    cout << "greedy table :D " << endl ;
    for( i = 1 ; i <= n ; i++ )
    {
        achekoyta = tak[i] ;
        for( select = 0 ; select <= achekoyta ; select++ )
        {
            cout << GT[i][select] << " " ;
        }
        cout << endl ;
    }
    */

    memset( dp , -1 ,sizeof(dp) ) ;
    ANS = f(1,m) ;
    //cout << "ans : " << endl ;
    cout << ANS << endl ;
    //cout << dp[1][m] << endl ;

    return 0 ;
}


/*
8% PR NJ
*/

#include<bits/stdc++.h>
using namespace std ;

#define NINF -10000000
#define MX 10000

#define Nmx 100
#define Mmx 10000
int n , m ;

int originaldata[Nmx+100][MX+100] ;
int ultadata[Nmx+100][MX+100] ;

int sumdata[Nmx+100][MX+100] ;
int ultasumdata[Nmx+100][MX+100] ;

int tak[MX+100] ;
int newtak[MX+100] ;

int GT[Nmx+100][MX+100] ;

int i , j , k , x , u ;
int koyta ; // [1,100]

int achekoyta , select , local_max , l_sum , r_sum , lft , rt ;
long long dp[Nmx+1+100][Mmx+1+100] ;

int f( int kontak ,  int available_upay )
{
    //cout << "kontak : " << kontak << " avail : " << available_upay << endl ;
    if( available_upay == 0 )
    {
        return 0 ;
    }
    if( available_upay > newtak[kontak] )
    {
        return NINF ;
    }

    if( kontak == n )
    {
        return GT[kontak][available_upay] ;
    }

    if( dp[kontak][available_upay] >= 0 )
    {
        return dp[kontak][available_upay] ;
    }
    int eitakeache = tak[kontak] ;

    int eitakebest = 0 ;
    for( int eitakeselection = 0 ; eitakeselection <= eitakeache ; eitakeselection++ )
    {

            //cout << "tak :" << kontak << " selection : " << eitakeselection << endl ;
            //cout << "GT["<<kontak<<"]["<<eitakeselection<<"] :" << GT[kontak][eitakeselection] << endl ;
            //cout << "f(k+1) :" << f( kontak+1 , m-eitakeselection ) << endl ;
            eitakebest = max( eitakebest , GT[kontak][eitakeselection] + f( kontak+1 , available_upay-eitakeselection ) ) ;
            //cout << "eitakebest : " << eitakebest << endl ;

    }
    dp[kontak][available_upay] =  eitakebest  ;
    //cout <<"dp["<< kontak <<"][" << available_upay << "] : " << eitakebest << endl ;
    return eitakebest ;
}

int ANS ;
int main()
{

    //freopen( "input.txt" , "r" , stdin ) ;
    cin >> n >> m ;

    for( i = 1 ; i <= n ; i++ )
    {
        cin >> koyta ;
        newtak[i] = tak[i] = koyta ;
        for( j = 0 ; j < koyta ; j++ )
        {
            scanf( "%d" , &originaldata[i][j] ) ;
            u = koyta - 1 - j ;
            ultadata[i][u] = originaldata[i][j] ;

            sumdata[i][j] =  originaldata[i][j] ;
            ultasumdata[i][u] = ultadata[i][u] ;

            //ultasumdata[]
        }
        for( x = 1 ; x < koyta ; x++ )
        {
            sumdata[i][x] += sumdata[i][x-1] ;
            ultasumdata[i][x] += ultasumdata[i][x-1] ;
        }
    }
    for( i = n-1 ; i >= 1 ; i-- )
    {
        newtak[i] += newtak[i+1] ;
    }
    /*
    cout << "printing tak :" << endl ;
    for( i = 1 ; i <= n ; i++ )
    {
        cout << newtak[i] << " " ;
    }
    cout << endl
    */;

    /*
    for( i = 1 ; i <= n ; i++ )
    {

        cout << "tak : " << i << " = " << endl ;
        cout << "data :" ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << originaldata[i][j] << " " ;
        }
        cout << endl ;
        cout << "ultadata :" ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << ultadata[i][j] << " " ;
        }
        cout << endl;
        cout << "sum : " ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << sumdata[i][j] << " " ;
        }
        cout << endl ;
        cout << "ultasum : " ;
        for( j = 0 ; j < tak[i] ; j++ )
        {
            cout << ultasumdata[i][j] << " " ;
        }
        cout << endl ;

        cout << endl << endl ;

    }
    */

    memset( GT , 0 , sizeof(GT) ) ;
    for( i = 1 ; i <= n ; i++ )
    {
        achekoyta = tak[i] ;
        for( select = 1 ; select <= achekoyta ; select++ )
        {
            local_max = 0 ;
            for( lft = select ; lft >= 0 ; lft -- )
            {
                rt = select - lft ;
                if( lft-1 >= 0 ) l_sum = sumdata[i][lft-1] ;
                else l_sum = 0 ;
                if( rt-1 >= 0 ) r_sum = ultasumdata[i][rt-1] ;
                else r_sum = 0 ;

                local_max = max( local_max , l_sum + r_sum ) ;
            }
            GT[i][select] = local_max ;
        }
    }
    /*
    cout << "greedy table :D " << endl ;
    for( i = 1 ; i <= n ; i++ )
    {
        achekoyta = tak[i] ;
        for( select = 0 ; select <= achekoyta ; select++ )
        {
            cout << GT[i][select] << " " ;
        }
        cout << endl ;
    }
    */

    //memset( dp , NINF ,sizeof(dp) ) ;
    //ANS = f(1,m) ;
    //cout << "ans : " << endl ;
    dp[0][0] = 0 ;
    for( int i = 0 ; i < n ; i++ )
    {
        for( int j = 0 ; j <= m ; j++ )
        {
            for( int extra = 0 ; extra <= tak[i+1] ;  extra++ )
            {
                dp[i+1][j+extra] = max( dp[i+1][j+extra] , dp[i][j] + GT[i+1][extra] ) ;
            }
        }
    }
    ANS = dp[n][m] ;
    cout << ANS << endl ;
    //cout << dp[1][m] << endl ;

    return 0 ;
}


#include <iostream>
#include <vector>

using namespace std;

int _count[110],sumcount[110];
int d[110][110];

int main()
 {
   int n,m;
   cin >> n >> m;
   sumcount[0] = 0;
   for (int i=1; i<=n; i++)
    {
        int a[110],b[110];
        cin >> _count[i];
        sumcount[i] = sumcount[i-1] + _count[i];
        b[0] = 0;
        for (int j = 1; j <= _count[i]; j++)
         {
            cin >> a[j];
            b[j] = b[j-1] + a[j];
        }
        d[i][0] = 0;
        for (int j = 1; j<=_count[i]; j++)
         {
                int max = 0;
                for (int left = 0; left<=j; left++)
                 {
                 int ch = b[left] + b[_count[i]] - b[_count[i] - (j-left)];
                 if (ch>max) max = ch;
                }
                d[i][j] = max;
        }
    }
   vector <int> ans[110];
   ans[1].clear();
   ans[1].push_back(0);
   int anss = 0;
   for (int j=1; j<= _count[1]; j++) ans[1].push_back(d[1][j]);
   if (_count[1]>=m) anss = d[1][m];
   for (int i = 2; i<=n; i++)
    {
     ans[i].clear();
     ans[i].push_back(0);
     for (int j = 1; j <= sumcount[i]; j++)
      {
        int max=0;
        for (int last = 0; last<=j; last++)
         if (j-last>=0 && j-last<ans[i-1].size())
         {
          int ch = d[i][last] + ans[i-1][j-last];
          if (ch>max) max = ch;
        }
       ans[i].push_back(max);
       if (j==m)
         if (max>anss) anss = max;
      }
    }
/*
    for (int i= 1; i<=n; i++)
    {
        for (int j= 0; j<ans[i].size(); j++)
         cout<<ans[i][j]<<" ";
         cout<<endl;
    }
*/
   cout <<anss<<endl;
   return 0;
 }


#include <iostream>
#include <vector>

using namespace std;

int _count[102],sumcount[102];
int d[102][102];

int main()
 {
   int n,m;
   cin >> n >> m;
   sumcount[0] = 0;
   for (int i=1; i<=n; i++)
    {
        int a[102],b[102];
        cin >> _count[i];
        sumcount[i] = sumcount[i-1] + _count[i];
        b[0] = 0;
        for (int j = 1; j <= _count[i]; j++)
         {
            cin >> a[j];
            b[j] = b[j-1] + a[j];
        }
        d[i][0] = 0;
        for (int j = 1; j<=_count[i]; j++)
         {
                int max = 0;
                for (int left = 0; left<=j; left++)
                 {
                 int ch = b[left] + b[_count[i]] - b[_count[i] - (j-left)];
                 if (ch>max) max = ch;
                }
                d[i][j] = max;
        }
    }
   vector <int> ans[102];
   ans[1].clear();
   ans[1].push_back(0);
   int anss = 0;
   for (int j=1; j<= _count[1]; j++) ans[1].push_back(d[1][j]);
   if (_count[1]>=m) anss = d[1][m];
   for (int i = 2; i<=n; i++)
    {
     ans[i].clear();
     ans[i].push_back(0);
     for (int j = 1; j <= sumcount[i]; j++)
      {
        int max=0;
        for (int last = 0; last<=j; last++)      // j-last>=0
         if (j-last>=0 && j-last<=_count[i-1])
         {
          int ch = d[i][last] + ans[i-1][j-last];
          if (ch>max) max = ch;
        }
       ans[i].push_back(max);
       if (j==m)
         if (max>anss) anss = max;
      }
    }
/*
    for (int i= 1; i<=n; i++)
    {
        for (int j= 0; j<ans[i].size(); j++)
         cout<<ans[i][j]<<" ";
         cout<<endl;
    }
*/
   cout <<anss<<endl;
   return 0;
 }


#include <iostream>
#include <vector>

using namespace std;

int _count[102],sumcount[102];
int d[102][102];
int ans[10003];

int main()
 {
   int n,m;
   cin >> n >> m;
   sumcount[0] = 0;
   for (int i=1; i<=n; i++)
    {
        int a[110],b[110];
        cin >> _count[i];
        sumcount[i] = sumcount[i-1] + _count[i];
        b[0] = 0;
        for (int j = 1; j <= _count[i]; j++)
         {
            cin >> a[j];
            b[j] = b[j-1] + a[j];
        }
        d[i][0] = 0;
        for (int j = 1; j<=_count[i]; j++)
         {
                int max = 0;
                for (int left = 0; left<=j; left++)
                 {
                 int ch = b[left] + b[_count[i]] - b[_count[i] - (j-left)];
                 if (ch>max) max = ch;
                }
                d[i][j] = max;
        }
    }

//////////////////////////
  ans[0] = 0;
  for (int j = 1; j<= _count[1]; j++) ans[j] = d[1][j];
  for (int i = 2; i<=n; i++)
   {
     for (int j = sumcount[i]; j>=0; j--)
      {
      for (int  k = 0; k <= _count[i]; k++)
       if (j-k >= 0)  ans[j] = max(ans[j], ans[j-k]+d[i][k]);
       else break;
    }
   }
   cout <<ans[m]<<endl;
   return 0;
 }


#include <iostream>
#include <vector>

using namespace std;

int _count[110],sumcount[110];
int d[110][110];

int main()
 {
   int n,m;
   cin >> n >> m;
   sumcount[0] = 0;
   for (int i=1; i<=n; i++)
    {
        int a[110],b[110];
        cin >> _count[i];
        sumcount[i] = sumcount[i-1] + _count[i];
        b[0] = 0;
        for (int j = 1; j <= _count[i]; j++)
         {
            cin >> a[j];
            b[j] = b[j-1] + a[j];
        }
        d[i][0] = 0;
        for (int j = 1; j<=_count[i]; j++)
         {
                int max = 0;
                for (int left = 0; left<=j; left++)
                 {
                 int ch = b[left] + b[_count[i]] - b[_count[i] - (j-left)];
                 if (ch>max) max = ch;
                }
                d[i][j] = max;
        }
    }
   vector <int> ans[110];
   ans[1].clear();
   ans[1].push_back(0);
   int anss = 0;
   for (int j=1; j<= _count[1]; j++) ans[1].push_back(d[1][j]);
   if (_count[1]>=m) anss = d[1][m];

   for (int i = 2; i<=n; i++)
    {
     ans[i].clear();
     ans[i].push_back(0);
     for (int j = 1; j <= sumcount[i]; j++)
      {
        int max;
        if (j<ans[i-1].size()) max = ans[i-1][j];
                            else max = 0;
        for (int last = 0; last<=j; last++)
         if (j-last>=0 && j-last<ans[i-1].size())
         {
          int ch = d[i][last] + ans[i-1][j-last];
          if (ch>max) max = ch;
        }
       ans[i].push_back(max);
       if (j==m)
         if (max>anss) anss = max;
      }
      if (ans[i].size() <= ans[i-1].size())
       {
            cout<<"pizdets" << i<< " "<<ans[i].size()<<endl;
         return 0;
        }
    }
/*
    for (int i= 1; i<=n; i++)
    {
        for (int j= 0; j<ans[i].size(); j++)
         cout<<ans[i][j]<<" ";
         cout<<endl;
    }
*/
   cout <<anss<<endl;
   return 0;
 }


#include <iostream>
#include <vector>

using namespace std;

int _count[102],sumcount[102];
int d[102][102];

int main()
 {
   int n,m;
   cin >> n >> m;
   sumcount[0] = 0;
   for (int i=1; i<=n; i++)
    {
        int a[102],b[102];
        cin >> _count[i];
        sumcount[i] = sumcount[i-1] + _count[i];
        b[0] = 0;
        for (int j = 1; j <= _count[i]; j++)
         {
            cin >> a[j];
            b[j] = b[j-1] + a[j];
        }
        d[i][0] = 0;
        for (int j = 1; j<=_count[i]; j++)
         {
                int max = 0;
                for (int left = 0; left<=j; left++)
                 {
                 int ch = b[left] + b[_count[i]] - b[_count[i] - (j-left)];
                 if (ch>max) max = ch;
                }
                d[i][j] = max;
        }
    }
   vector <int> ans[102];
   ans[1].clear();
   ans[1].push_back(0);
   int anss = 0;
   for (int j=1; j<= _count[1]; j++) ans[1].push_back(d[1][j]);
   for (int i = 2; i<=n; i++)
    {
     ans[i].clear();
     ans[i].push_back(0);
     for (int j = 1; j <= sumcount[i]; j++)
      {
        int max=0;
        for (int last = 0; last<=j; last++)      // j-last>=0
         if (j-last>=0 && j-last<=_count[i-1])
         {
          int ch = d[i][last] + ans[i-1][j-last];
          if (ch>max) max = ch;
        }
       ans[i].push_back(max);
       if (j==m)
         if (max>anss) anss = max;
      }
    }
/*
    for (int i= 1; i<=n; i++)
    {
        for (int j= 0; j<ans[i].size(); j++)
         cout<<ans[i][j]<<" ";
         cout<<endl;
    }
*/
   cout <<anss<<endl;
   return 0;
 }


//
//  E.cpp
//  codeforces
//
//  Created by Bakhodir Ashirmatov on 2/2/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#include <cstdio>
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

int dp[2][10001]={0};
vector<int> a[100];
int sum[100]={0};

int main(){
    int n, m;
    cin>>n>>m;
    for (int i=0; i<n; i++){
        int k;
        cin>>k;
        for (int j=0; j<k; j++){
            int temp;
            cin>>temp;
            a[i].push_back(temp);
            sum[i]+=temp;
        }
    }
    for (int i=0; i<n; i++)
        for (int j=0; j<a[i].size(); j++){
            int temp=0;
            for (int k=0; k<j; k++)
                temp+=a[i][k];
            int mint=sum[i]-temp;
            for (int k=j; k<a[i].size(); k++){
                temp=temp+a[i][k]-a[i][k-j];
                if (mint<sum[i]-temp)
                    mint=sum[i]-temp;
            }
            for (int k=a[i].size()-j; k<=10000; k++)
                if (dp[i&1][k-(a[i].size()-j)]+mint>dp[1-i&1][k])
                    dp[1-i&1][k]=dp[i&1][k-(a[i].size()-j)]+mint;
        }
    cout<<dp[n&1][m];
}


//
//  E.cpp
//  codeforces
//
//  Created by Bakhodir Ashirmatov on 2/2/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#include <cstdio>
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

int dp[2][10001]={0};
vector<int> a[100];
int sum[100]={0};

int main(){
    int n, m;
    cin>>n>>m;
    for (int i=0; i<n; i++){
        int k;
        cin>>k;
        for (int j=0; j<k; j++){
            int temp;
            cin>>temp;
            a[i].push_back(temp);
            sum[i]+=temp;
        }
    }
    int size=0;
    for (int i=0; i<n; i++)
        for (int j=0; j<a[i].size(); j++){
            int temp=0;
            for (int k=0; k<j; k++)
                temp+=a[i][k];
            int mint=sum[i]-temp;
            for (int k=j; k<a[i].size(); k++){
                temp=temp+a[i][k]-a[i][k-j];
                if (mint<sum[i]-temp)
                    mint=sum[i]-temp;
            }
            int r=a[i].size()-j;
            for (int k=r; k<=size; k++)
                if (dp[i&1][k-r]+mint>dp[1-i&1][k])
                    dp[1-i&1][k]=dp[i&1][k-r]+mint;
            size+=a[i].size();
        }
    cout<<dp[n&1][m];
}


//
//  E.cpp
//  codeforces
//
//  Created by Bakhodir Ashirmatov on 2/2/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#include <cstdio>
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

int dp[2][10001]={0};
vector<int> a[100];
int sum[100]={0};

int main(){
    int n, m;
    cin>>n>>m;
    for (int i=0; i<n; i++){
        int k;
        cin>>k;
        for (int j=0; j<k; j++){
            int temp;
            cin>>temp;
            a[i].push_back(temp);
            sum[i]+=temp;
        }
    }
    for (int i=0; i<n; i++)
        for (int j=0; j<a[i].size(); j++){
            int temp=0;
            for (int k=0; k<j; k++)
                temp+=a[i][k];
            int mint=sum[i]-temp;
            for (int k=j; k<a[i].size(); k++){
                temp=temp+a[i][k]-a[i][k-j];
                if (mint<sum[i]-temp)
                    mint=sum[i]-temp;
            }
            int r=a[i].size()-j;
            for (int k=r; k<=10000; k++)
                if (dp[i&1][k-r]+mint>dp[1-i&1][k])
                    dp[1-i&1][k]=dp[i&1][k-r]+mint;
        }
    cout<<dp[n&1][m];
}


//
//  E.cpp
//  codeforces
//
//  Created by Bakhodir Ashirmatov on 2/2/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#include <cstdio>
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

int dp[100][10001]={0};
vector<int> a[100];
int sum[100]={0};

int main(){
    int n, m;
    cin>>n>>m;
    for (int i=0; i<n; i++){
        int k;
        cin>>k;
        for (int j=0; j<k; j++){
            int temp;
            cin>>temp;
            a[i].push_back(temp);
            sum[i]+=temp;
        }
    }
    int size=0;
    for (int i=0; i<n; i++){
        for (int j=0; j<=10000; j++)
            dp[i&1][j]=dp[1-i&1][j];
        for (int j=0; j<a[i].size(); j++){
            int temp=0;
            for (int k=0; k<j; k++)
                temp+=a[i][k];
            int mint=sum[i]-temp;
            for (int k=j; k<a[i].size(); k++){
                temp=temp+a[i][k]-a[i][k-j];
                if (mint<sum[i]-temp)
                    mint=sum[i]-temp;
            }
            int r=a[i].size()-j;
            for (int k=r; k<=10000; k++)
                if (dp[1-i&1][k-r]+mint>dp[i&1][k])
                    dp[i&1][k]=dp[1-i&1][k-r]+mint;
        }
    }
    cout<<dp[1-n&1][m];
}


//
//  E.cpp
//  codeforces
//
//  Created by Bakhodir Ashirmatov on 2/2/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#include <cstdio>
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

int dp[100][10001]={0};
vector<int> a[100];
int sum[100]={0};

int main(){
    int n, m;
    cin>>n>>m;
    for (int i=0; i<n; i++){
        int k;
        cin>>k;
        for (int j=0; j<k; j++){
            int temp;
            cin>>temp;
            a[i].push_back(temp);
            sum[i]+=temp;
        }
    }
    int size=0;
    for (int i=0; i<n; i++){
        size+=a[i].size();
        for (int j=0; j<a[i].size(); j++){
            int temp=0;
            for (int k=0; k<j; k++)
                temp+=a[i][k];
            int mint=sum[i]-temp;
            for (int k=j; k<a[i].size(); k++){
                temp=temp+a[i][k]-a[i][k-j];
                if (mint<sum[i]-temp)
                    mint=sum[i]-temp;
            }
            int r=a[i].size()-j;
            for (int k=r; k<=size; k++)
                if (dp[i][k-r]+mint>dp[1-i&1][k])
                    dp[1-i&1][k]=dp[i&1][k-r]+mint;
        }
    }
    cout<<max(dp[1][m], dp[0][m]);
}


//
//  E.cpp
//  codeforces
//
//  Created by Bakhodir Ashirmatov on 2/2/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#include <cstdio>
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

int dp[100][10001]={0};
vector<int> a[100];
int sum[100]={0};

int main(){
    int n, m;
    cin>>n>>m;
    for (int i=0; i<n; i++){
        int k;
        cin>>k;
        for (int j=0; j<k; j++){
            int temp;
            cin>>temp;
            a[i].push_back(temp);
            sum[i]+=temp;
        }
    }
    int size=0;
    for (int i=0; i<n; i++)
        for (int j=0; j<a[i].size(); j++){
            int temp=0;
            for (int k=0; k<j; k++)
                temp+=a[i][k];
            int mint=sum[i]-temp;
            for (int k=j; k<a[i].size(); k++){
                temp=temp+a[i][k]-a[i][k-j];
                if (mint<sum[i]-temp)
                    mint=sum[i]-temp;
            }
            int r=a[i].size()-j;
            for (int k=r; k<=size; k++)
                if (dp[i][k-r]+mint>dp[1-i&1][k])
                    dp[1-i&1][k]=dp[i&1][k-r]+mint;
            size+=a[i].size();
        }
    cout<<max(dp[1][m], dp[0][m]);
}


////
////  E.cpp
////  codeforces
////
////  Created by Bakhodir Ashirmatov on 2/2/12.
////  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
////
//
//#include <cstdio>
//#include <iostream>
//#include <string>
//#include <vector>
//#include <map>
//#include <set>
//#include <algorithm>
//using namespace std;
//
//int dp[100][10001]={0};
//vector<int> a[100];
//int sum[100]={0};
//
//int main(){
//    int n, m;
//    cin>>n>>m;
//    for (int i=0; i<n; i++){
//        int k;
//        cin>>k;
//        for (int j=0; j<k; j++){
//            int temp;
//            cin>>temp;
//            a[i].push_back(temp);
//            sum[i]+=temp;
//        }
//    }
//    int size=0;
//    for (int i=0; i<n; i++)
//        for (int j=0; j<a[i].size(); j++){
//            int temp=0;
//            for (int k=0; k<j; k++)
//                temp+=a[i][k];
//            int mint=sum[i]-temp;
//            for (int k=j; k<a[i].size(); k++){
//                temp=temp+a[i][k]-a[i][k-j];
//                if (mint<sum[i]-temp)
//                    mint=sum[i]-temp;
//            }
//            int r=a[i].size()-j;
//            for (int k=r; k<=size; k++)
//                if (dp[i][k-r]+mint>dp[1-i&1][k])
//                    dp[1-i&1][k]=dp[i&1][k-r]+mint;
//            size+=a[i].size();
//        }
//    cout<<max(dp[1][m], dp[0][m]);
//}
//


#include <iostream>
#include <cmath>
#include <stdio.h>
#include <cstdlib>
#include <algorithm>
#include <string>
#define N 101

using namespace std;

int n, m, k, i, j, x, y, a[N][N], s[N], d[N], mx[N][N], f[N][N];
int main()
{
//freopen("o.txt", "r", stdin);
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
    cin >> n >> m;
    for (i = 1; i <= n; i++)
    {
        cin >> x;
        d[i] = x;
        s[0] = 0;
        for (j = 1; j <= x; j++)
        {
            cin >> a[i][j];
            s[j] = s[j - 1] + a[i][j];
        }
        for (j = 1; j <= d[i]; j++)
            for (x = 0; x <= j; x++)
                mx[i][j] = max(mx[i][j], s[x] + s[d[i]] - s[d[i] - (j - x)]);
    }
        for (k = 0; k <= m; k++)
    for (i = 1; i <= n; i++)
            for (j = 1; j <= min(k, d[i]); j++)
                f[i][k] = max(f[i][k], f[i - 1][k - j] + mx[i][j]);
    cout  << f[n][m];
return 0;
}


#include <iostream>
#include <cmath>
#include <stdio.h>
#include <cstdlib>
#include <algorithm>
#include <string>
#define N 101

using namespace std;

int n, m, k, i, j, x, y, a[N][N], s[N], d[N], mx[N][N], f[N][N];
int main()
{
//freopen("o.txt", "r", stdin);
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
    cin >> n >> m;
    for (i = 1; i <= n; i++)
    {
        cin >> x;
        d[i] = x;
        s[0] = 0;
        for (j = 1; j <= x; j++)
        {
            cin >> a[i][j];
            s[j] = s[j - 1] + a[i][j];
        }
        for (j = 1; j <= d[i]; j++)
            for (x = 0; x <= j; x++)
                mx[i][j] = max(mx[i][j], s[x] + s[d[i]] - s[d[i] - (j - x)]);
    }
    for (i = 1; i <= n; i++)
        for (k = 0; k <= m; k++)
            for (j = 1; j <= min(k, d[i]); j++)
                f[i][k] = max(f[i][k], f[i - 1][k - j] + mx[i][j]);
    cout  << f[n][m];
return 0;
}


#include <iostream>
#include <cmath>
#include <stdio.h>
#include <cstdlib>
#include <algorithm>
#include <string>
#define N 101

using namespace std;

int n, m, k, i, j, x, y, a[N][N], s[N], d[N], mx[N][N], f[N][N];
int main()
{
freopen("o.txt", "r", stdin);
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
    cin >> n >> m;
    for (i = 1; i <= n; i++)
    {
        cin >> x;
        d[i] = x;
        s[0] = 0;
        for (j = 1; j <= x; j++)
        {
            cin >> a[i][j];
            s[j] = s[j - 1] + a[i][j];
        }
        for (j = 1; j <= d[i]; j++)
            for (x = 0; x <= j; x++)
                mx[i][j] = max(mx[i][j], s[x] + s[d[i]] - s[d[i] - (j - x)]);
    }
    for (i = 1; i <= n; i++)
        for (k = 0; k <= m; k++)
            for (j = 1; j <= min(k, d[i]); j++)
                f[i][k] = max(f[i][k], f[i - 1][k - j] + mx[i][j]);
    cout  << f[n][m];
return 0;
}


#include <iostream>
#include <cmath>
#include <stdio.h>
#include <cstdlib>
#include <algorithm>
#include <string>
#define N 101

using namespace std;

int n, m, k, i, j, x, y, a[N][N], s[N], d[N], mx[N][N], f[N][N];
int main()
{
//freopen("o.txt", "r", stdin);
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
    cin >> n >> m;
    for (i = 1; i <= n; i++)
    {
        cin >> x;
        d[i] = x;
        s[0] = 0;
        for (j = 1; j <= x; j++)
        {
            cin >> a[i][j];
            s[j] = s[j - 1] + a[i][j];
        }
        for (j = 0; j <= d[i]; j++)
            for (x = 0; x <= j; x++)
                mx[i][j] = max(mx[i][j], s[x] + s[d[i]] - s[d[i] - (j - x)]);
    }
    for (i = 1; i <= n; i++)
        for (k = 0; k <= m; k++)
        {
            for (j = 1; j <= d[i]; j++)
                f[i][k + j] = max(f[i][k + j], f[i - 1][k] + mx[i][j]);
        }
    cout  << f[n][m];
return 0;
}


#include <iostream>
#include <cmath>
#include <stdio.h>
#include <cstdlib>
#include <algorithm>
#include <string>
#define N 101

using namespace std;

long long n, m, k, i, j, x, y, s[N], d[N], mx[N][N], f[N][N];
int main()
{
//freopen("o.txt", "r", stdin);
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
    cin >> n >> m;
    for (i = 1; i <= n; i++)
    {
        cin >> x;
        d[i] = x;
        s[0] = 0;
        for (j = 1; j <= x; j++)
        {
            cin >> y;
            s[j] = s[j - 1] + y;
        }
        for (j = 1; j <= d[i]; j++)
            for (x = 0; x <= j; x++)
                mx[i][j] = max(mx[i][j], s[x] + s[d[i]] - s[d[i] - (j - x)]);
    }
    for (i = 1; i <= n; i++)
        for (k = 0; k <= m; k++)
            for (j = 1; j <= min(k, d[i]); j++)
                f[i][k] = max(f[i][k], f[i - 1][k - j] + mx[i][j]);
    cout  << f[n][m];
return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;

const int SZ = 100010;
const int dx[] = {0,1,0,-1};
const int dy[] = {1,0,-1,0};

int g[SZ][105];
int f[SZ],v[SZ],n,m;

int tmp1[SZ],tmp2[SZ];

void calc(int a[])
{
    int x = 1,y = a[0];
    int t = 0,ans = 0;
    while(t < a[0])
    {
        t ++;
        if(a[x] > a[y]) ans += a[x],x ++;
        else if(a[x] < a[y]) ans += a[y],y --;
        else
        {
            for(int i = x;i <= y;i ++)
            {
                int j = y - (i - x);
                if(a[i] != a[j])
                {
                    if(a[i] > a[j]) ans += a[x],x ++;
                    else ans += a[y],y --;
                    break;
                }
            }
        }
        v[t] = ans;
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;i ++)
    {
        scanf("%d",&g[i][0]);
        for(int j = 1;j <= g[i][0];j ++)
            scanf("%d",&g[i][j]);
    }

    for(int i = 1;i <= n;i ++)
    {
        calc(g[i]);
        for(int j = m;j >= 0;j --)
            for(int k = max(0,j - g[i][0]);k <= j;k ++)
                f[j] = max(f[j],f[k] + v[j - k]);
    }
    printf("%d\n",f[m]);
    return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;

const int SZ = 100010;
const int dx[] = {0,1,0,-1};
const int dy[] = {1,0,-1,0};

int g[SZ][105];
int f[SZ],v[SZ],n,m;

int dp[SZ],s1[SZ],s2[SZ];

void calc(int a[])
{
    for(int i = 1;i <= a[0];i ++)
        s1[i] = s1[i - 1] + a[i];
    for(int i = 1;i <= a[0];i ++)
        s2[i] = s2[i - 1] + a[a[0] - i + 1];
    for(int i = 1;i <= a[0];i ++)
    {
        v[i] = 0;
        for(int j = 0;j <= i;j ++)
            v[i] = max(v[i],s1[j] + s2[i - j]);
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;i ++)
    {
        scanf("%d",&g[i][0]);
        for(int j = 1;j <= g[i][0];j ++)
            scanf("%d",&g[i][j]);
    }

    for(int i = 1;i <= n;i ++)
    {
        calc(g[i]);
        for(int j = m;j >= 0;j --)
        {
            for(int k = max(0,j - g[i][0]);k <= j;k ++)
                f[j] = max(f[j],f[k] + v[j - k]);
        }
    }
    printf("%d\n",f[m]);
    return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;

const int SZ = 100010;
const int dx[] = {0,1,0,-1};
const int dy[] = {1,0,-1,0};

int g[SZ][105];
int f[SZ],v[SZ],n,m;

int tmp1[SZ],tmp2[SZ];

void calc(int a[])
{
    int x = 1,y = a[0];
    int t = 0,ans = 0;
    while(t < a[0])
    {
        t ++;
        if(a[x] > a[y]) ans += a[x],x ++;
        else if(a[x] < a[y]) ans += a[y],y --;
        else
        {
            bool flag = 0;
            for(int i = x;i <= y;i ++)
            {
                int j = y - (i - x);
                if(a[i] != a[j])
                {
                    if(a[i] > a[j]) ans += a[x],x ++;
                    else ans += a[y],y --;
                    flag = 1;
                    break;
                }
            }
            if(!flag) ans += a[x],x ++;
        }
        v[t] = ans;
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;i ++)
    {
        scanf("%d",&g[i][0]);
        for(int j = 1;j <= g[i][0];j ++)
            scanf("%d",&g[i][j]);
    }

    for(int i = 1;i <= n;i ++)
    {
        calc(g[i]);
        for(int j = m;j >= 0;j --)
            for(int k = max(0,j - g[i][0]);k <= j;k ++)
                f[j] = max(f[j],f[k] + v[j - k]);
    }
    printf("%d\n",f[m]);
    return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;

const int SZ = 1010;
const int dx[] = {0,1,0,-1};
const int dy[] = {1,0,-1,0};

vector<int> g[SZ];
int f[SZ],v[SZ],n,m;

void calc(int i)
{
    int x = 0,y = g[i].size() - 1;
    int t = 0,ans = 0;
    while(t < g[i].size())
    {
        if(g[i][x] >= g[i][y]) ans += g[i][x],x ++;
        else ans += g[i][y],y --;
        v[++ t] = ans;
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;i ++)
    {
        int k,x; scanf("%d",&k);
        while(k --) scanf("%d",&x),g[i].push_back(x);
    }

    for(int i = 1;i <= n;i ++)
    {
        calc(i);
        for(int j = m;j >= 0;j --)
            for(int k = max(0,j - (int)g[i].size());k <= j;k ++)
                f[j] = max(f[j],f[k] + v[j - k]);

    }
    printf("%d\n",f[m]);
    return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;

const int SZ = 1000010;
const int dx[] = {0,1,0,-1};
const int dy[] = {1,0,-1,0};

vector<int> g[SZ];
int f[SZ],v[SZ],n,m;

void calc(int i)
{
    int x = 0,y = g[i].size() - 1;
    int t = 0,ans = 0;
    while(t < g[i].size())
    {
        if(g[i][x] >= g[i][y]) ans += g[i][x],x ++;
        else ans += g[i][y],y --;
        v[++ t] = ans;
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;i ++)
    {
        int k,x; scanf("%d",&k);
        while(k --) scanf("%d",&x),g[i].push_back(x);
    }

    for(int i = 1;i <= n;i ++)
    {
        calc(i);
        for(int j = m;j >= 0;j --)
            for(int k = max(0,j - (int)g[i].size());k <= j;k ++)
                f[j] = max(f[j],f[k] + v[j - k]);

    }
    printf("%d\n",f[m]);
    return 0;
}


/*
  ------------------------- Hachiikung ---------------------------------
  ---------------------- Worrachate Bosri ------------------------------
  ------ Faculty of Computer Engineering Chulalongkorn University ------
*/
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<string>
#include<utility>
#include<sstream>
using namespace std;
#define REP(i,FN) for(int i=0;i<FN;i++)
#define FOR(i,ST,FN) for(int i=ST;i<=FN;i++)
#define FORD(i,FN,ST) for(int i=FN;i>=ST;i--)
#define FORX(x) for(it=x.begin();it!=x.end();it++)
#define pause system("pause")
#define S scanf
#define P printf
#define X first
#define Y second
#define pb push_back
#define PII pair<int,int>

const int MOD(1000000007);
const int INF((1<<30)-1);
const int MAXN(105);

int a[MAXN],num;

int dp[MAXN][MAXN]={0};

int cnt[MAXN]={0};

int dp2[MAXN*MAXN]={0};

int main(){

    int n,m;
    S("%d%d",&n,&m);

    FOR(i,0,m)
     dp2[i]=-INF;
    dp2[0]=0;

    REP(i,n)
    {
        S("%d",&num);
        REP(j,num)
         S("%d",&a[j]);

        FOR(j,0,num)
         cnt[j]=0;

        dp[0][num-1]=0;

        FORD(j,num-1,0)
         for(int k=0,l=j-1;l<num;k++,l++)
         {
          dp[k][l]=max(dp[k][l+1]+a[l+1],a[k-1]+dp[k-1][l]);
          cnt[num-j]=max(cnt[num-j],dp[k][l]);
         }

        FORD(k,m,0)
        {
         FOR(j,1,num)
         {
             if(k-j<0) break;
             dp2[k]=max(dp2[k],dp2[k-j]+cnt[j]);
         }
        }

    }

    P("%d",dp2[m]);

}


/*
  ------------------------- Hachiikung ---------------------------------
  ---------------------- Worrachate Bosri ------------------------------
  ------ Faculty of Computer Engineering Chulalongkorn University ------
*/
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<string>
#include<utility>
#include<sstream>
using namespace std;
#define REP(i,FN) for(int i=0;i<FN;i++)
#define FOR(i,ST,FN) for(int i=ST;i<=FN;i++)
#define FORD(i,FN,ST) for(int i=FN;i>=ST;i--)
#define FORX(x) for(it=x.begin();it!=x.end();it++)
#define pause system("pause")
#define S scanf
#define P printf
#define X first
#define Y second
#define pb push_back
#define PII pair<int,int>

const int MOD(1000000007);
const int INF((1<<30)-1);
const int MAXN(105);

int a[MAXN],num;

int dp[MAXN][MAXN]={0};

int cnt[MAXN]={0};

int dp2[MAXN*MAXN]={0};

int main(){

    int n,m;
    S("%d%d",&n,&m);

    FOR(i,0,m)
     dp2[i]=-INF;
    dp2[0]=0;

    REP(i,n)
    {
        S("%d",&num);
        REP(j,num)
         S("%d",&a[j]);

        FOR(j,0,num)
         cnt[j]=0;

        dp[0][num-1]=0;

        FORD(j,num-1,0)
         for(int k=0,l=j-1;l<num;k++,l++)
         {
          if(k==0) dp[k][l]=dp[k][l+1]+a[l+1];
          else if(l==num-1) dp[k][l]=a[k-1]+dp[k-1][l];
          else dp[k][l]=max(dp[k][l+1]+a[l+1],a[k-1]+dp[k-1][l]);
          cnt[num-j]=max(cnt[num-j],dp[k][l]);
         }

        FORD(k,m,0)
        {
         FOR(j,1,num)
         {
             if(k-j<0) break;
             dp2[k]=max(dp2[k],dp2[k-j]+cnt[j]);
         }
        }

    }

    P("%d",dp2[m]);

}


/*
  ------------------------- Hachiikung ---------------------------------
  ---------------------- Worrachate Bosri ------------------------------
  ------ Faculty of Computer Engineering Chulalongkorn University ------
*/
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<string>
#include<utility>
#include<sstream>
using namespace std;
#define REP(i,FN) for(int i=0;i<FN;i++)
#define FOR(i,ST,FN) for(int i=ST;i<=FN;i++)
#define FORD(i,FN,ST) for(int i=FN;i>=ST;i--)
#define FORX(x) for(it=x.begin();it!=x.end();it++)
#define pause system("pause")
#define S scanf
#define P printf
#define X first
#define Y second
#define pb push_back
#define PII pair<int,int>

const int MOD(1000000007);
const int INF((1<<30)-1);
const int MAXN(105);

int a[MAXN],num;

int dp[MAXN][MAXN]={0};

int cnt[MAXN]={0};

int dp2[2][MAXN*MAXN]={0};

int main(){

    int n,m;
    S("%d%d",&n,&m);

    FOR(i,0,m)
     dp2[0][i]=dp2[1][i]=-1;
    dp2[0][0]=dp2[1][0]=0;

    bool now=1,prev=0;

    REP(i,n)
    {
        S("%d",&num);
        REP(j,num)
         S("%d",&a[j]);

        FOR(j,0,num)
         cnt[j]=0;

        dp[0][num-1]=0;

        FORD(j,num-1,0)
         for(int k=0,l=j-1;l<num;k++,l++)
         {
          dp[k][l]=max(dp[k][l+1]+a[l+1],a[k-1]+dp[k-1][l]);
          cnt[num-j]=max(cnt[num-j],dp[k][l]);
         }

        FOR(j,1,num)
        {
         FORD(k,m,0)
         {
             if(k-j<0) break;
             if(dp2[prev][k-j]==-1) continue;
             dp2[now][k]=max(dp2[now][k],dp2[prev][k-j]+cnt[j]);
         }
        }

        now=!now,prev=!prev;
    }

    P("%d",dp2[prev][m]);

}


/*
  ------------------------- Hachiikung ---------------------------------
  ---------------------- Worrachate Bosri ------------------------------
  ------ Faculty of Computer Engineering Chulalongkorn University ------
*/
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<string>
#include<utility>
#include<sstream>
using namespace std;
#define REP(i,FN) for(int i=0;i<FN;i++)
#define FOR(i,ST,FN) for(int i=ST;i<=FN;i++)
#define FORD(i,FN,ST) for(int i=FN;i>=ST;i--)
#define FORX(x) for(it=x.begin();it!=x.end();it++)
#define pause system("pause")
#define S scanf
#define P printf
#define X first
#define Y second
#define pb push_back
#define PII pair<int,int>

const int MOD(1000000007);
const int INF((1<<30)-1);
const int MAXN(105);

int a[MAXN],num;

int dp[MAXN][MAXN]={0};

int cnt[MAXN]={0};

int dp2[2][MAXN*MAXN]={0};

int main(){

    int n,m;
    S("%d%d",&n,&m);

    FOR(i,0,m)
     dp2[0][i]=dp2[1][i]=-1;
    dp2[0][0]=dp2[1][0]=0;

    bool now=1,prev=0;

    REP(i,n)
    {
        S("%d",&num);
        REP(j,num)
         S("%d",&a[j]);

        FOR(j,0,num)
         cnt[j]=0;

        dp[0][num-1]=0;

        FORD(j,num-1,0)
         for(int k=0,l=j-1;l<num;k++,l++)
         {
          dp[k][l]=max(dp[k][l+1]+a[l+1],a[k-1]+dp[k-1][l]);
          cnt[num-j]=max(cnt[num-j],dp[k][l]);
         }

        FOR(j,1,num)
        {
         FORD(k,m,0)
         {
             if(k-j<0) break;
             if(dp2[prev][k-j]==-1) continue;
             dp2[now][k]=max(dp2[now][k],max(dp2[prev][k],dp2[prev][k-j]+cnt[j]));
         }
        }

        now=!now,prev=!prev;
    }

    P("%d",dp2[prev][m]);

}


/*
  ------------------------- Hachiikung ---------------------------------
  ---------------------- Worrachate Bosri ------------------------------
  ------ Faculty of Computer Engineering Chulalongkorn University ------
*/
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<string>
#include<utility>
#include<sstream>
using namespace std;
#define REP(i,FN) for(int i=0;i<FN;i++)
#define FOR(i,ST,FN) for(int i=ST;i<=FN;i++)
#define FORD(i,FN,ST) for(int i=FN;i>=ST;i--)
#define FORX(x) for(it=x.begin();it!=x.end();it++)
#define pause system("pause")
#define S scanf
#define P printf
#define X first
#define Y second
#define pb push_back
#define PII pair<int,int>

const int MOD(1000000007);
const int INF((1<<30)-1);
const int MAXN(105);

int a[MAXN],num;

int dp[MAXN][MAXN]={0};

int cnt[MAXN]={0};

int dp2[MAXN*MAXN]={0};

int main(){

    int n,m;
    S("%d%d",&n,&m);

    FOR(i,0,m)
     dp2[i]=-INF;
    dp2[0]=0;

    REP(i,n)
    {
        S("%d",&num);
        REP(j,num)
         S("%d",&a[j]);

        FOR(j,0,num)
         cnt[j]=0;

        dp[0][num-1]=0;

        FORD(j,num-1,0)
         for(int k=0,l=j-1;l<num;k++,l++)
         {
          if(k==0) dp[k][l]=dp[k][l+1]+a[l+1];
          else if(l==j-1) dp[k][l]=a[k-1]+dp[k-1][l];
          else dp[k][l]=max(dp[k][l+1]+a[l+1],a[k-1]+dp[k-1][l]);

          cnt[num-j]=max(cnt[num-j],dp[k][l]);
         }

        FORD(k,m,0)
        {
         FOR(j,1,num)
         {
             if(k-j<0) break;
             dp2[k]=max(dp2[k],dp2[k-j]+cnt[j]);
         }
        }

    }

    P("%d",dp2[m]);

}


/*
  ------------------------- Hachiikung ---------------------------------
  ---------------------- Worrachate Bosri ------------------------------
  ------ Faculty of Computer Engineering Chulalongkorn University ------
*/
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<string>
#include<utility>
#include<sstream>
using namespace std;
#define REP(i,FN) for(int i=0;i<FN;i++)
#define FOR(i,ST,FN) for(int i=ST;i<=FN;i++)
#define FORD(i,FN,ST) for(int i=FN;i>=ST;i--)
#define FORX(x) for(it=x.begin();it!=x.end();it++)
#define pause system("pause")
#define S scanf
#define P printf
#define X first
#define Y second
#define pb push_back
#define PII pair<int,int>

const int MOD(1000000007);
const int INF((1<<30)-1);
const int MAXN(105);

int a[MAXN],num;

int dp[MAXN][MAXN]={0};

int cnt[MAXN]={0};

int dp2[2][MAXN*MAXN]={0};

int main(){

    int n,m;
    S("%d%d",&n,&m);

    FOR(i,0,m)
     dp2[0][i]=dp2[1][i]=-1;
    dp2[0][0]=dp2[1][0]=0;

    bool now=1,prev=0;

    REP(i,n)
    {
        S("%d",&num);
        REP(j,num)
         S("%d",&a[j]);

        FOR(j,0,num)
         cnt[j]=0;

        dp[0][num-1]=0;

        FORD(j,num-1,0)
         for(int k=0,l=j-1;l<num;k++,l++)
         {
          dp[k][l]=max(dp[k][l+1]+a[l+1],a[k-1]+dp[k-1][l]);
          cnt[num-j]=max(cnt[num-j],dp[k][l]);
         }

        FORD(k,m,0)
        {
         FOR(j,1,num)
         {
             if(k-j<0) continue;
             if(dp2[prev][k-j]==-1) continue;
             dp2[now][k]=max(dp2[now][k],dp2[prev][k-j]+cnt[j]);
         }
        }

        FOR(k,0,m)
         dp2[now][k]=max(dp2[now][k],dp2[prev][k]);

        now=!now,prev=!prev;
    }

    P("%d",dp2[prev][m]);

}


/*
  ------------------------- Hachiikung ---------------------------------
  ---------------------- Worrachate Bosri ------------------------------
  ------ Faculty of Computer Engineering Chulalongkorn University ------
*/
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<string>
#include<utility>
#include<sstream>
using namespace std;
#define REP(i,FN) for(int i=0;i<FN;i++)
#define FOR(i,ST,FN) for(int i=ST;i<=FN;i++)
#define FORD(i,FN,ST) for(int i=FN;i>=ST;i--)
#define FORX(x) for(it=x.begin();it!=x.end();it++)
#define pause system("pause")
#define S scanf
#define P printf
#define X first
#define Y second
#define pb push_back
#define PII pair<int,int>

const int MOD(1000000007);
const int INF((1<<30)-1);
const int MAXN(105);

int a[MAXN],num;

int dp[MAXN][MAXN]={0};

int cnt[MAXN]={0};

int dp2[MAXN*MAXN]={0};

int main(){

    int n,m;
    S("%d%d",&n,&m);

    FOR(i,0,m)
     dp2[i]=-1;
    dp2[0]=0;

    REP(i,n)
    {
        S("%d",&num);
        REP(j,num)
         S("%d",&a[j]);

        FOR(j,0,num)
         cnt[j]=0;

        dp[0][num-1]=0;

        FORD(j,num-1,0)
         for(int k=0,l=j-1;l<num;k++,l++)
         {
          dp[k][l]=max(dp[k][l+1]+a[l+1],a[k-1]+dp[k-1][l]);
          cnt[num-j]=max(cnt[num-j],dp[k][l]);
         }

        FORD(k,m,0)
        {
         FOR(j,1,num)
         {
             if(k-j<0) continue;
             if(dp2[k-j]==-1) continue;
             dp2[k]=max(dp2[k],dp2[k-j]+cnt[j]);
         }
        }

    }

    P("%d",dp2[m]);

}


/*
  ------------------------- Hachiikung ---------------------------------
  ---------------------- Worrachate Bosri ------------------------------
  ------ Faculty of Computer Engineering Chulalongkorn University ------
*/
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<string>
#include<utility>
#include<sstream>
using namespace std;
#define REP(i,FN) for(int i=0;i<FN;i++)
#define FOR(i,ST,FN) for(int i=ST;i<=FN;i++)
#define FORD(i,FN,ST) for(int i=FN;i>=ST;i--)
#define FORX(x) for(it=x.begin();it!=x.end();it++)
#define pause system("pause")
#define S scanf
#define P printf
#define X first
#define Y second
#define pb push_back
#define PII pair<int,int>

const int MOD(1000000007);
const int INF((1<<30)-1);
const int MAXN(105);

int a[MAXN],num;

int dp[MAXN][MAXN]={0};

int cnt[MAXN]={0};

int dp2[2][MAXN*MAXN]={0};

int main(){

    int n,m;
    S("%d%d",&n,&m);

    FOR(i,0,m)
     dp2[0][i]=dp2[1][i]=-1;
    dp2[0][0]=dp2[1][0]=0;

    bool now=1,prev=0;

    REP(i,n)
    {
        S("%d",&num);
        REP(j,num)
         S("%d",&a[j]);

        FOR(j,0,num)
         cnt[j]=0;

        dp[0][num-1]=0;

        FORD(j,num-1,0)
         for(int k=0,l=j-1;l<num;k++,l++)
         {
          dp[k][l]=max(dp[k][l+1]+a[l+1],a[k-1]+dp[k-1][l]);
          cnt[num-j]=max(cnt[num-j],dp[k][l]);
         }

        FOR(j,1,num)
        {
         FORD(k,m,0)
         {
             if(k-j<0) break;
             if(dp2[prev][k-j]==-1) continue;
             dp2[now][k]=max(dp2[now][k],dp2[prev][k-j]+cnt[j]);
         }
        }

        FOR(k,0,m)
         dp2[now][k]=max(dp2[now][k],dp2[prev][k]);

        now=!now,prev=!prev;
    }

    P("%d",dp2[prev][m]);

}


#include <set>
#include <cstring>
#include <iostream>
#include <cstdio>
#define REP(i,n) for(int i=0; i<(int)(n); i++)

inline int getInt(){ int s; scanf("%d", &s); return s; }

using namespace std;

int dp[101][101];
int memo[100][101];
int item[100];
int nm[100];
int memo2[100][10000];

int main(){
  int n = getInt();
  int m = getInt();

  REP(i,n){
    int nn = nm[i] = getInt();

    REP(j,nn) item[j] = getInt();

    memset(dp, 0, sizeof(dp));
    REP(j,nn + 1){
      REP(left, j + 1){
        int right = nn - 1 - (j - left);
        dp[left + 1][right] = max(dp[left + 1][right], dp[left][right] + item[left]);
        memo[i][j + 1] = max(memo[i][j + 1], dp[left + 1][right]);
        if(right){
          dp[left][right - 1] = max(dp[left][right - 1], dp[left][right] + item[right]);
          memo[i][j + 1] = max(memo[i][j + 1], dp[left][right - 1]);
        }
      }
    }

    // REP(j, nn + 1) printf("%d ", memo[i][j]); puts("");
  }

  REP(i,n) REP(j,m + 1){
    REP(k,nm[i] + 1){
      if(j + k <= m){
        memo2[i + 1][j + k] = max(memo2[i + 1][j + k],
                                  memo2[i][j] + memo[i][k]);
      }else{
        break;
      }
    }
  }
  int ans = 0;
  REP(i,m+1) ans = max(ans, memo2[n][i]);

  printf("%d\n", ans);

  return 0;
}


#include <set>
#include <cstring>
#include <iostream>
#include <cstdio>
#define REP(i,n) for(int i=0; i<(int)(n); i++)

inline int getInt(){ int s; scanf("%d", &s); return s; }

using namespace std;

int dp[101][101];
int memo[101][101];
int item[100];
int nm[100];
int memo2[101][10001];

int main(){
  int n = getInt();
  int m = getInt();

  REP(i,n){
    int nn = nm[i] = getInt();

    REP(j,nn) item[j] = getInt();

    memset(dp, 0, sizeof(dp));
    REP(j,nn + 1){
      REP(left, j + 1){
        int right = nn - 1 - (j - left);
        dp[left + 1][right] = max(dp[left + 1][right], dp[left][right] + item[left]);
        memo[i][j + 1] = max(memo[i][j + 1], dp[left + 1][right]);
        if(right){
          dp[left][right - 1] = max(dp[left][right - 1], dp[left][right] + item[right]);
          memo[i][j + 1] = max(memo[i][j + 1], dp[left][right - 1]);
        }
      }
    }

    // REP(j, nn + 1) printf("%d ", memo[i][j]); puts("");
  }

  REP(i,n) REP(j,m + 1){
    REP(k,nm[i] + 1){
      if(j + k <= m){
        memo2[i + 1][j + k] = max(memo2[i + 1][j + k],
                                  memo2[i][j] + memo[i][k]);
      }else{
        break;
      }
    }
  }

  printf("%d\n", memo2[n][m]);

  return 0;
}


#include <set>
#include <cstring>
#include <iostream>
#include <cstdio>
#define REP(i,n) for(int i=0; i<(int)(n); i++)

inline int getInt(){ int s; scanf("%d", &s); return s; }

using namespace std;

int dp[101][101];
int memo[100][101];
int item[100];
int nm[100];
int memo2[100][10000];

int main(){
  int n = getInt();
  int m = getInt();

  REP(i,n){
    int nn = nm[i] = getInt();

    REP(j,nn) item[j] = getInt();

    memset(dp, 0, sizeof(dp));
    REP(j,nn + 1){
      REP(left, j + 1){
        int right = nn - 1 - (j - left);
        dp[left + 1][right] = max(dp[left + 1][right], dp[left][right] + item[left]);
        memo[i][j + 1] = max(memo[i][j + 1], dp[left + 1][right]);
        if(right){
          dp[left][right - 1] = max(dp[left][right - 1], dp[left][right] + item[right]);
          memo[i][j + 1] = max(memo[i][j + 1], dp[left][right - 1]);
        }
      }
    }

    // REP(j, nn + 1) printf("%d ", memo[i][j]); puts("");
  }

  REP(i,n) REP(j,m+1){
    REP(k,nm[i] + 1){
      if(j + k <= m){
        memo2[i + 1][j + k] = max(memo2[i + 1][j + k],
                                  memo2[i][j] + memo[i][k]);
      }else{
        break;
      }
    }
  }

  printf("%d\n", memo2[n][m]);

  return 0;
}