// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;



using ll = long long;

using ull = unsigned long long;

using ld = long double;



#define MOD 1000000007



#define rep(i, n) for(ll (i) = 0LL;(i) < (ll)(n);(i)++)

#define rep2(i, s, e) for(ll (i) = (ll)(s);(i) < (ll)(e);(i)++)

#define repi(i, n) for(ll (i) = 0LL;(i) <= (ll)(n);(i)++)

#define repi2(i, s, e) for(ll (i) = (ll)(s);(i) <= (ll)(e);(i)++)

#define per(i, n) for(ll (i) = (ll)(n) - 1LL;(i) >= 0LL;(i)--)

#define per2(i, s, e) for(ll (i) = (ll)(s) - 1LL;(i) >= (ll)(e);(i)--)

#define peri(i, n) for(ll (i) = (ll)(n);(i) >= 0LL;(i)--)

#define peri2(i, s, e) for(ll (i) = (ll)(s);(i) >= (ll)(e);(i)--)

#define iter(i, it) for(auto &(i): (it))



template<typename T, typename U> ostream& operator<<(ostream &s, const pair<T, U> m) {

    cout << "(" << m.first << ", " << m.second << ")";

    return s;

}

template<typename T, typename U> ostream& operator<<(ostream &s, const map<T, U> m) {

    ll c = 0;

    cout << "{ ";

    iter(i, m) cout << i << (c++ == m.size() - 1 ? " " : ", ");

    cout << "}";

    return s;

}

template<typename T> ostream& operator<<(ostream &s, const vector<T> &v) {

    cout << "{ ";

    rep(i, v.size()) cout << v[i] << (i == v.size() - 1 ? " " : ", ");

    cout << "}";

    return s;

}

template<typename T> ostream& operator<<(ostream &s, const list<T> &v) {

    ll c = 0;

    cout << "{ ";

    iter(i, v) cout << i << (c++ == v.size() - 1 ? " " : ", ");

    cout << "}";

    return s;

}



int main(void) {

    bool flag2 = false;

    ll N, M, X;

    ll mini = LONG_LONG_MAX;

    vector<pair<ll, vector<ll>>> C;

    cin >> N >> M >> X;

    rep(i, N) {

        ll c;

        vector<ll> A;

        cin >> c;

        A.resize(M);

        rep(i, M) cin >> A[i];

        C.emplace_back(c, A);

    }

    rep(i, 1LL << N) {

        ll money = 0;

        bool flag = true;

        vector<ll> rikai(M);

        rep(j, N) {

            if(i & (1LL << j)) {

                money += C[j].first;

                rep(k, M) {

                    rikai[k] += C[j].second[k];

                }

            }

        }

        iter(j, rikai) {

            if(j < X) flag = false;

        }

        if(flag) {

            flag2 = true;

            mini = min(mini, money);

        }

    }

    if(flag2) cout << mini << endl;

    else cout << -1 << endl;

    return 0;

}


// Optimized solution to the same problem (faster):
#include<stdio.h>

#include<limits.h>



int main(void) {

    int i, j, k;

    int wholeFlag = 0;

    int N, M, X;

    int mini = INT_MAX;

    int C[100000];

    int A[100000][12];

    scanf("%d %d %d", &N, &M, &X);

    for(i = 0;i < N;i++) {

        scanf("%d", &C[i]);

        for(j = 0;j < M;j++) scanf("%d", &A[i][j]);

    }

    for(i = 0;i < 1LL << N;i++) {

        int money = 0;

        int flag = 1;

        int rikai[12] = {};

        for(j = 0;j < N;j++) {

            if(i & (1LL << j)) {

                money += C[j];

                for(k = 0;k < M;k++) rikai[k] += A[j][k];

            }

        }

        for(j = 0;j < M;j++) {

            if(rikai[j] < X) flag = 0;

        }

        if(flag) {

            wholeFlag = 1;

            mini = mini < money ? mini : money;

        }

    }

    if(wholeFlag) printf("%d\n", mini);

    else puts("-1");

    return 0;

}


// Fastest known solution for this problem: