#include <bits/stdc++.h>
    using namespace std;
    #include <ext/pb_ds/assoc_container.hpp>
    #include <ext/pb_ds/tree_policy.hpp>
    using namespace __gnu_pbds;
     
    #define fast { ios :: sync_with_stdio(false); cin.tie(0); cout.tie(0); }
    #define pb push_back
    #define ll long long
    #define ld long double
     
    #define vi vector<int>
    #define vl vector<long>
    #define vll vector<long long>
     
    #define infi INT_MAX
    #define infl LONG_LONG_MAX
    #define infd LDBL_MAX
    #define f(i,a,b) for(ll i=a;i<b;i++)
    #define fi(i,a,b) for(ll i=(b-1);i>=a;i--)
    #define F first
    #define S second
    #define G(a,b) get<a>(b)
    #define MP make_pair
    #define MT make_tuple
    #define pll pair<ll,ll> 
    #define endl "\n"
    #define ALL(v) v.begin(),v.end()
    #define nl cout<<"\n";
    #define pr(x) cout<<x;
    #define pr1(x) cout<<x<<" ";
    #define pr2(x,y) cout<<x<<" "<<y;
    #define deb printf("***************************************************************************************\n");
    #define moshi printf("moshi moshi ! \n");
    #define hi printf("hi ! \n");
    #define bye printf("bye bye ! \n");
    #define o_set(ll) tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update>
    #define number_of_set_bits  __builtin_popcountll  
     
    //template<typename T>
    //#define o_set(T) tree<T, null_type,less<T>, rb_tree_tag,tree_order_statistics_node_update>
    //member functions :
    //1. order_of_key(k) : number of elements strictly lesser than k
    //2. find_by_order(k) : k-th element in the set
     
     
    //const ll N=1e6+7;
    ll p=1e9+7;
    //ll fac[N];
     
    ll gcd(ll a, ll b) 
    { 
        if (a == 0) 
            return b; 
        return gcd(b % a, a); 
    } 
     
    inline ll ceil(ll a,ll b)
    {
      return (a+b-1)/b;
    }
     
    ll max(ll x,ll y,ll z)
    {
      return max(x,max(y,z));
    }
     
     
    ll modpro(ll x,ll y,ll z=1)
    {
      x%=p;
      y%=p;
      z%=p;
      ll res=(x*y)%p;
      res=(res*z)%p;
      return res;
    }
     
    ll modadd(ll x,ll y,ll z=0)
    {
      ll res=(x+y)%p;
      res=(res+z)%p;
      return res;
    }
     
     
    ll pow_mod_p(ll a,ll b)
    {
      a=a%p;
      ll res=1;
      while(b>0)
      {
        if(b&1) res=(res*a)%p;
        b=b>>1;
        a=(a*a)%p;
      }
      return res;
    }
     
    inline ll mod_inv(ll x)
    {
      return pow_mod_p(x,p-2);
    }
     
    /*
    ll nCr(ll x,ll y)
    {
      if(x<y) return 0;
      ll res=fac[x];
      ll den=(fac[y]*fac[x-y])%p;
      ll deni=mod_inv(den);
      res=(res*deni)%p;
      return res;
    }*/



    ll is_set(ll a,ll i)
    {
      if( ( a & ((ll)1<<i) ) == 0 ) return 0;
      else return 1;
    }  
    


    //  Comparator should follow :
    //  1: x<=y or y<=x uniquely 
    //  2: Transitivity : a<=b and b<=c implies a<=c
    //  3: Anti-Symmetry: a<=b and b<=a implies a=b
    // return 1 to put x before y in sorted order 
    inline bool comp(pll &x,pll &y)
    {
        if(x.F<y.F) return 1;
        else if(x.F==y.F)
        {
            if(x.S>y.S) return 1;
            else return 0;
        }
        return 0;
    }
     
     
    struct custom_hash {
        static uint64_t splitmix64(uint64_t x) {
            // http://xorshift.di.unimi.it/splitmix64.c
            x += 0x9e3779b97f4a7c15;
            x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
            x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
            return x ^ (x >> 31);
        }
     
        size_t operator()(uint64_t x) const {
            static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
            return splitmix64(x + FIXED_RANDOM);
        }
    };
     
    // resize : str.resize(new_size)   new size <= old size
     
    // for Vector :
    // lower_bound(starting iterator , iterator next to end , value)  :  iterator to first element greater than or equal to value
    // upper_bound(starting iterator , iterator next to end , value)  :  iterator to first element strictly greater than value
     
    // For Set :      s.lower_bound(value)
    // if no such element exists they return  vector.end() or s.end()
     
     
    // x bits : [x-1 , x-2 , .... , 1(1st bit) , 0(0th bit)] =>   leftmost 1 at 2^(x-1)    max number that can be represented : 2^(x) -1
    // 63 bits is greater than 10^18
     
    // 1<<x  :  2 ^ x  (left shift)
     
    // Min heap :  priority_queue < ll , vector<ll>, greater<ll> > q  
    // Max heap :  priority_queue < ll > q
    // Set in descending order  :   set< ll,greater <ll> >
     
     
    // While debugging : 
    // 1 : check if array size is correct  :  It may give unexpected results
    // 2 : check if you have swapped i and j at some part of program
    // 3 : for string check if you are trying to acces  index = -1 


    // Bitwise Tricks :
    // 1 : While using 1<<i  use (ll)1<<i  because in former one "1" is considered as int
    // 2 : To flip first k-bits of a number :  x xor (2^k-1)  or x ^ (((ll)1<<k)-1)  : 2^k-1 is the largest number of k bits
    // 3 : To flip k-th bit (0-based)  :  x xor (2^k)  or  x ^ ((ll)1<<k)
    // 4 : To set k-th bit (0-based)   :  x or (2^k)   or  x | ((ll)1<<k)
    // 5 : To un-set k-th bit (0-based)   :  x and ((ll)0<<k)

    
    // To prove Greedy :
    // 1 : Optimal Choice at each step 
    // 2 : Exchange Argument
    // 3 : Find a lower or upper bound on answer and then construct an answer for that bound
    // 4 : Find properties which Optimal Solution must satisfy ( This can be useful to deduce form of Optimal answer)

    // Erase one occurrence in multiset : it=s.find(element)   s.erase(it) 
    // putchar('a'+j) : to print (j+1)th character 
    // getline(cin,str) : To input string until newline
    

    void lps(string &pp,ll *lps)
    {
       ll xx=pp.length();
       //ll lps[xx]={};
       f(i,1,xx)
       {
         ll j=lps[i-1];
         while(j>0 && pp[j]!=pp[i]) j=lps[j-1];
         if(pp[i]==pp[j]) j++;
         lps[i]=j;
       }
    }






    void func()
    {
       ll n,m,x;
       cin>>n>>m>>x;

       ll cost[n+1],gain[n+1][m+1];

       f(i,1,n+1)
       {
          cin>>cost[i];

          f(j,1,m+1) cin>>gain[i][j];
       }

       ll mask=0,mx=((ll)1<<n)-1,mn=infl;
       while(mask<=mx)
       {
         ll xx=mask,temp=0;
         ll i=1,knowledge[m+1]={};
         while(xx)
         {
            if(xx&1!=0)  // choose i-th book
            {
              temp+=cost[i];
              f(j,1,m+1) knowledge[j]+=gain[i][j];
            }
            
            xx>>=1;
            i++;
         }

         bool flag=1;
         f(j,1,m+1) if(knowledge[j]<x) flag=0;
         if(flag) mn=min(mn,temp);
         mask++;
       }

       if(mn!=infl) 
       {
         pr(mn) nl
       }
       else cout<<"-1\n";
    }   
     
     
    int main() 
    {
        fast
        //#ifndef ONLINE_JUDGE
        //freopen("input.txt", "r", stdin);
        //freopen("output.txt", "w", stdout);
        //#endif // ONLINE_JUDGE
        
     
        ll ntc=1;
        //cin>>ntc;
     
        f(i,1,ntc+1)
        {
          //cout<<"Case #"<<i<<": ";
          func();
        }
     
        return 0;
    }

Measured memory_bytes: 3640