#include<bits/stdc++.h>

#define FOR(i,a,b) for(int i = (a);i < (b);i++)
#define RFOR(i,a,b) for(int i = (b)-1;i >= (a);i--)
#define REP(i,n) FOR(i,0,(n))
#define RREP(i,n) RFOR(i,0,(n))

using namespace std;

typedef pair<int, int> P;
#define pb push_back
#define mp make_pair
#define ft first
#define sd second
#define INF 1000000000

#define MAX_N 100
#define MAX_V (MAX_N * 20 * 2 + 1)
struct edge { int to, cap, cost, rev; };
int V;
vector<edge> G[MAX_V];
vector<edge> G2[MAX_V];
int dist[MAX_V];
int prevv[MAX_V], preve[MAX_V];
void add_edge(int from, int to, int cap, int cost) {
    G[from].push_back((edge){to, cap, cost, (int)G[to].size()});
    G[to].push_back((edge){from, 0, -cost, (int)G[from].size() - 1});
}
int min_cost_flow(int s, int t, int f) {
    int res = 0;
    while (f > 0) {
        fill(dist, dist + V, INF);
        dist[s] = 0;
        bool update = true;
        while (update) {
            update = false;
            for (int v = 0; v < V; v++) {
                if (dist[v] == INF) continue;
                for (int i = 0; i < G[v].size(); i++) {
                    edge &e = G[v][i];
                    if (e.cap > 0 && dist[e.to] > dist[v] + e.cost) {
                        dist[e.to] = dist[v] + e.cost;
                        prevv[e.to] = v;
                        preve[e.to] = i;
                        update = true;
                    }
                }
            }
        }
        if (dist[t] == INF) {
            return -1;
        }
        int d = f;
        for (int v = t; v != s; v = prevv[v]) {
            d = min(d, G[prevv[v]][preve[v]].cap);
        }
        f -= d;
        res += d * dist[t];
        for (int v = t; v != s; v = prevv[v]) {
            edge &e = G[prevv[v]][preve[v]];
            e.cap -= d;
            G[v][e.rev].cap += d;
        }
    }
    return res;
}

bool used[MAX_V]; 

int dfs(int v, int t, int f) {
    if (v == t) return f;
    used[v] = true;
    for (int i = 0; i < G[v].size(); i++) {
        edge &e = G[v][i];
        if (!used[e.to] && e.cap > 0) {
            int d = dfs(e.to, t, min(f, e.cap));
            if (d > 0) {
                e.cap -= d;
                G[e.to][e.rev].cap += d;
                return d;
            }
        }
    }
    return 0;
}
int max_flow(int s, int t) {
    int flow = 0;
    for (;;) {
        memset(used, 0, sizeof(used));
        int f = dfs(s, t, INF);
        if (f == 0) return flow;
        flow += f;
    }
}


void resetG(int ver){
  V = ver;
  REP(i,V)G[i].clear();
}

int n;
int m[MAX_N];
int x[MAX_N][20];
int y[MAX_N][20];
int c[MAX_N][20];
int g;

bool input(){
    cin >> n;
    REP(i,n - 1){
        cin >> m[i];
        REP(j,m[i])
            cin >> x[i][j] >> y[i][j] >> c[i][j];
    }
    if(n != 0)
        cin >> g;
    return n!=0;
}

int tim[MAX_V];
vector<int> soeji[MAX_N - 1][2];
int x2[20];

void solve(){
    REP(i,MAX_V)G[i].clear();
    V = 0;
    REP(i,n-1){
        soeji[i][0].clear();
        soeji[i][1].clear();
        REP(j,m[i]){
            x2[j] = x[i][j];
        }
        sort(x2,x2+m[i]);
        REP(j,m[i]){
            if(j == 0 || x2[j - 1] < x2[j]){
                soeji[i][0].pb(V);
                tim[V] = x2[j];
                if(j > 0)
                    add_edge(V-1,V,INF,0);
                V++;
            }
        }

        REP(j,m[i]){
            x2[j] = y[i][j];
        }
        sort(x2,x2+m[i]);
        REP(j,m[i]){
            if(j == 0 || x2[j - 1] < x2[j]){
                soeji[i][1].pb(V);
                tim[V] = x2[j];
                V++;
            }
        }
    }

    REP(i,n-1){
        REP(j,m[i]){
            int k = 0;
            while(tim[soeji[i][0][k++]] != x[i][j]);
            int l = 0;
            while(tim[soeji[i][1][l++]] != y[i][j]);
            add_edge(soeji[i][0][k-1],soeji[i][1][l-1],1,c[i][j]);
        }
    }

    REP(i,n-2){
        REP(j,soeji[i][1].size()){
            REP(k,soeji[i + 1][0].size()){
                if(tim[soeji[i][1][j]] <= tim[soeji[i + 1][0][k]]){
                    add_edge(soeji[i][1][j],soeji[i + 1][0][k],1,0);
                    break;
                }
            }
        }
    }
    REP(i,soeji[n - 2][1].size()){
        add_edge(soeji[n - 2][1][i],V,1,0);
    }
    V++;
    REP(i,V)G2[i] = G[i];
    int f = min(g,max_flow(0,V-1));
    REP(i,V)G[i] = G2[i];
    printf("%d %d\n",f,min_cost_flow(0,V-1,f));
}
int main(){
  cin.tie(0);
  
  while (input()){
      solve();
  }
  
  return 0;
}

Measured memory_bytes: 4424