#include <set>
#include <map>
#include <cstdio>
#include <algorithm>
#include <queue>
#define REP(i,n) for(int i=0; i<(int)(n); i++)

#define FOR(i,c) for(__typeof((c).begin()) i=(c).begin(); i!=(c).end(); i++)

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

using namespace std;

struct Edge{
  int cap; // capacity
  int to;
  int rev; // reverse edge id

  Edge(){}
  Edge(int c, int t, int r) :
    cap(c), to(t), rev(r){}
};

struct CostEdge : public Edge{
  int cost;
  CostEdge() : Edge() {}
  CostEdge(int c, int t, int cs, int r) :
    Edge(c, t, r), cost(cs){}
};

template<class E> // Edge type
class Graph{
public:
  typedef std::vector<std::vector<E> > G;

private:
  G g;

public:
  Graph(int n) : g(G(n)) {}

  void addEdge(int from, int to, int cap){
    g[from].push_back(E(cap, to, g[to].size()));
    g[to].push_back(E(0, from, g[from].size() - 1));
  }

  void addEdge(int from, int to, int cap, int cost){
    g[from].push_back(E(cap, to, cost, g[to].size()));
    g[to].push_back(E(0, from, -cost, g[from].size() - 1));
  }

  G &getRowGraph(){
    return g;
  }
};

template<class E>
pair<int, int> minCostFlow(Graph<E> &graph, int s, int t, int f){
  typedef pair<int, int> P;
  typename Graph<E>::G &g = graph.getRowGraph();
  int n = g.size();
  int res = 0;
  vector<int> h(n, 0);
  vector<int> prevv(n);
  vector<int> preve(n);
  const int inf = 10000000;

  while(f > 0){
    priority_queue<P, vector<P>, greater<P> > que;
    vector<int> dist(n, inf);
    dist[s] = 0;
    que.push(P(0, s));

    while(!que.empty()){
      P p   = que.top(); que.pop();
      int v = p.second;
      if(dist[v] < p.first) continue;
      for(int i = 0; i < (int)g[v].size(); i++){
        E &e = g[v][i];

        if(e.cap > 0 && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]){
          dist[e.to]  = dist[v] + e.cost + h[v] - h[e.to];
          prevv[e.to] = v;
          preve[e.to] = i;
          que.push(P(dist[e.to], e.to));
        }
      }
    }
    if(dist[t] == inf){
      return make_pair(f, res);
    }

    for(int v = 0; v < n; v++) h[v] += dist[v];

    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 * h[t];

    for(int v = t; v != s; v = prevv[v]){
      E &e = g[prevv[v]][preve[v]];
      e.cap -= d;
      g[v][e.rev].cap += d;
    }
  }
  return make_pair(f, res);
}

template<class T>
class IdMaker{
public:
  std::map<T,int> _m;
  int getId(const T &v){
    if(_m.find(v) == _m.end()){
      int next = _m.size();
      return _m[v] = next;
    }
    return _m[v];
  }
};

int m[100];
int x[100][20];
int y[100][20];
int c[100][20];

int main(){
  while(int n = getInt()){
    vector<set<int> > memo(n);
    vector<map<int, int> > im(n);

    REP(i,n){
      if(i != n - 1){
        m[i] = getInt();
        REP(j,m[i]){
          x[i][j] = getInt();
          y[i][j] = getInt();
          c[i][j] = getInt();
          memo[i].insert(x[i][j]);
          memo[i + 1].insert(y[i][j]);
        }
      }
      int p = 0;
      FOR(it,memo[i])
        im[i][*it] = p++;
    }

    int cnt = 0;
    vector<int> base(n);
    vector<int> base2(n);
    REP(i,n){
      base[i] = cnt;
      base2[i] = cnt + memo[i].size();
      cnt += memo[i].size() * 2;
    }

    Graph<CostEdge> g(cnt + 2);
    const int start = cnt;
    const int end   = cnt + 1;
    const int inf   = 10000;

    g.addEdge(start, base[0], inf, 0);
    REP(i,memo[n - 1].size())
      g.addEdge(base[n - 1] + i, end, inf, 0);

    REP(i,n){
      REP(j,memo[i].size() - 1)
        g.addEdge(base[i] + j, base[i] + j + 1, inf, 0);
      REP(j,memo[i].size())
        g.addEdge(base2[i] + j, base[i] + j, 1, 0);

      if(i != n - 1){
        REP(j,m[i]){
          int xx = im[i][x[i][j]];
          int yy = im[i + 1][y[i][j]];

          // printf("%d => %d\n", xx, yy);
          g.addEdge(base[i] + xx, base2[i + 1] + yy, 1, c[i][j]);
        }
      }
    }

    int gg = getInt();
    pair<int, int> ans = minCostFlow(g, start, end, gg);

    printf("%d %d\n", gg - ans.first, ans.second);
  }
  return 0;
}

Measured memory_bytes: 0