#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>

using namespace std;

struct Edge{
	int to;
	int weight;
	
	Edge(int _to, int _w) : to(_to), weight(_w){}
	Edge() : to(-1), weight(-1){}
};

const int MAXN = 10;
const int INF = 0x3f3f3f3f;
int dist[MAXN];
bool isVis[MAXN];
int E, N;
vector<Edge> graph[MAXN];
vector<pair<int ,int> > dists;

struct cmp{
	bool operator() (int a, int b){
		return dist[a] > dist[b];
	}
};

void clearV(){
	for(int i = 0; i < MAXN; ++i){
		graph[i].clear();
	}
}

void init(){
	clearV();
	dists.clear();
	N = 0;
	for(int i = 0; i < E; ++i){
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		graph[a].push_back(Edge(b, c));
		graph[b].push_back(Edge(a, c));
		if(a > N) N = a;
		if(b > N) N = b;
	}
}

int dijkstra(int s){
	
	fill(isVis, isVis + MAXN, false);
	fill(dist, dist + MAXN, INF);
	dist[s] = 0;
	
	for(int i = 0; i <= N; ++i){
		
		int u = -1, MIN = INF;
		for(int j = 0; j <= N; ++j){
			if(dist[j] < MIN && isVis[j] == false){
				u = j;
				MIN = dist[j];
			}
		}
		isVis[u] = true;
		if(u == -1) break;
		
		for(int j = 0; j < graph[u].size(); ++j){
			Edge nowEdge = graph[u][j];
			if(dist[nowEdge.to] > dist[u] + nowEdge.weight){
				dist[nowEdge.to] = dist[u] + nowEdge.weight;	
			}
		}
	}
	
	int sum = 0;
	for(int i = 0; i <= N; ++i){
		if(dist[i] != INF){
			sum += dist[i];
		}
	}
	
	return sum;
}

int main(){
	while(scanf("%d", &E) && E){
		init();
		int optimum = INF;
		int index = 0;
		for(int i = 0; i <= N; ++i){
			int sum = dijkstra(i);
			if(sum < optimum){
				optimum = sum;
			}
			dists.push_back(pair<int, int>(i, sum));
		}
		
		int ans = INF;
		for(int i = 0; i <= N; ++i){
			if(dists[i].second == optimum && i < ans){
				ans = i;
			}
		}
		printf("%d %d\n", ans, optimum);
	}
}
