#include<iostream>
#include<vector>
#include<string>
#include<algorithm>	
#include<map>
#include<set>
#include<utility>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<cstdio>
#include<sstream>
#include<iomanip>
#include<assert.h>
#include<typeinfo>
#define loop(i,a,b) for(int i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define pb push_back
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
using namespace std;
//kaewasuretyuui
typedef long long ll;
//#define int ll
typedef int Def;
typedef pair<Def,Def> pii;
typedef vector<Def> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef vector<string> vs;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef pair<Def,pii> pip;
typedef vector<pip>vip;
//#define mt make_tuple
//typedef tuple<pii,int,int> tp;
//typedef vector<tp> vt;
template<typename A,typename B>bool cmin(A &a,const B &b){return a>b?(a=b,true):false;}
template<typename A,typename B>bool cmax(A &a,const B &b){return a<b?(a=b,true):false;}
//template<class C>constexpr int size(const C &c){return (int)c.size();}
//template<class T,size_t N> constexpr int size(const T (&xs)[N])noexcept{return (int)N;}
const double PI=acos(-1);
const double EPS=1e-7;
Def inf = sizeof(Def) == sizeof(long long) ? 2e18 : 1e9;
int dx[]={0,1,0,-1};
int dy[]={1,0,-1,0};
struct edge{
	int to,cap,cost,rev;
};
typedef vector<edge> ve;
typedef vector<ve> vve;
class MCF{	//Minimum Cost Flow
	public:
	int n;
	vve G;
	vi h,dist,prev,pree;
	MCF(int size){
		n=size;
		G=vve(n);
		h=dist=prev=pree=vi(n);
	}
	void add_edge(int s,int t,int ca,int co){
		edge e={t,ca,co,G[t].size()};
		G[s].pb(e);
		edge ee={s,0,-co,G[s].size()-1};
		G[t].pb(ee);
	}
	pii mcf(int s,int t,int f){
		int out=0;
		h=vi(n);
		while(f>0){			
			priority_queue<pii,vector<pii> >q;
			dist=vi(n,inf);
			dist[s]=0;
			q.push(pii(0,s));
			while(!q.empty()){
				pii p=q.top();q.pop();
				int v=p.second;
				if(dist[v]<-p.first)continue;
				rep(i,G[v].size()){
					edge &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];
						prev[e.to]=v;
						pree[e.to]=i;
						q.push(pii(-dist[e.to],e.to));
					}
				}
			}
			if(dist[t]==inf)return {f,out};
			rep(i,n)h[i]+=dist[i];
			int d=f;
			for(int v=t;v!=s;v=prev[v])d=min(d,G[prev[v]][pree[v]].cap);
			f-=d;
			out+=d*h[t];
			for(int v=t;v!=s;v=prev[v]){
				edge &e=G[prev[v]][pree[v]];
				e.cap-=d;
				G[v][e.rev].cap+=d;
			}
		}
		return {0,out};	
	}
};
int main(){
	int n;
	while(cin>>n,n){
		MCF mcf(10010);
		int s=0,t=10009;
		int sum=0;
		vvi pre(1,vi(3));
		pre[0][1]=-1;
		map<int,int>prem;
		prem[-1]=1;
		rep(q,n-1){
			int c=0;
			int m;cin>>m;
			vvi in(m,vi(3));
			rep(i,m)rep(j,3)cin>>in[i][j];
			map<int,int>ma;
			rep(j,m)if(ma[in[j][1]]==0){
				c++;
				ma[in[j][1]]=c;
			}
			int nex=sum+pre.size();
			rep(i,pre.size())rep(j,m){
				if(pre[i][1]<=in[j][0]){
//					cout<<sum+prem[pre[i][1]]-1<<" "<<nex+ma[in[j][1]]-1<<" "<<in[j][2]<<endl;
					mcf.add_edge(sum+prem[pre[i][1]]-1,nex+ma[in[j][1]]-1,1,in[j][2]);
				}
			}
			sum+=pre.size();
			prem=ma;
			pre=in;
			rep(i,c){mcf.add_edge(sum+i,sum+c+i,1,0);}
			sum+=c;
		}
		rep(i,prem.size()){mcf.add_edge(sum+i,t,1,0);}
		int g;cin>>g;
		pii out=mcf.mcf(s,t,g);
		if(out.first==g)cout<<"0 0"<<endl;
		else cout<<g-out.first<<" "<<out.second<<endl;
	}
}

Measured memory_bytes: 5156