#include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 20

enum Type{
	L,
	R,
};

struct Info{
	bool operator<(const struct Info &arg) const{ //距離の降順
		return dist > arg.dist;
	}
	int dist,count;
};

struct Answer{

	void set(int arg_length,int arg_table[NUM]){
		length = arg_length;
		for(int i = 0; i < length; i++){
			table[i] = arg_table[i];
		}
	}
	bool operator<(const struct Answer &arg) const{
		for(int i = 0; i < length; i++){
			if(table[i] != arg.table[i]){
				return table[i] < arg.table[i];
			}
		}
		return true;
	}

	bool operator==(const struct Answer &arg) const{

		bool FLG = true;
		for(int i = 0; i < length; i++){
			if(table[i] != arg.table[i]){
				FLG = false;
			}
		}
		return FLG;
	}

	int table[NUM],length;
};

int N;
int info_index;
Info info[(NUM*(NUM-1))/2];
map<string,bool> MAP;
map<int,int> LOC;
vector<Answer> ANS;

string make_str(int dist_array[NUM]){

	string ret;

	for(int i = 0; i < info_index; i++){
		ret.append(to_string(dist_array[i])).append("@");
	}

	return ret;
}

//0でない最初の場所を返却する関数
int get_index(int rest_num[(NUM*(NUM-1))/2]){

	for(int i = 0; i < info_index; i++){
		if(rest_num[i] > 0){
			return i;
		}
	}
	return -1; //Error
}

//index:rest_numの、非0の最小インデックス
void recursive(int dist_array[NUM],int rest_num[(NUM*(NUM-1))/2],int index,int num_decided){

	if(num_decided == N){

		//町同士の距離をstring配列化して、ANSに格納
		int work[NUM];
		Answer ans;

		for(int i = 0; i < N-1; i++){
			work[i] = dist_array[i+1]-dist_array[i];
		}
		ans.set(N-1,work);

		ANS.push_back(ans);

		return;
	}

	//今回処理する距離
	int tmp_dist = info[index].dist;
	rest_num[index]--;

	int next_dist_array[2][NUM],next_rest_num[2][(NUM*(NUM-1))/2];

	for(int i = 0; i < 2; i++){
		for(int k = 0; k < N; k++){
			next_dist_array[i][k] = dist_array[k];
		}
		for(int k = 0; k < info_index; k++){
			next_rest_num[i][k] = rest_num[k];
		}
	}

	/*★★残っている最大の距離を、左端からの距離と解釈する場合★★*/
	int tmp_pos;

	//右端から数えて、一番近い空きスペースを探す
	for(int i = N-2; i >= 0; i--){
		if(next_dist_array[L][i] == -1){
			next_dist_array[L][i] = tmp_dist;
			tmp_pos = i;
			break;
		}
	}

	int tmp_diff,tmp_loc;
	bool FLG = true;

	//既に配置されている他の距離と矛盾がないか調べる
	for(int i = 1; i < N; i++){ //★i == 0からやると、tmp_distをデクリメントしているのでfalseになってしまう★
		if(next_dist_array[L][i] == -1 || i == tmp_pos)continue;

		tmp_diff = abs(next_dist_array[L][i]-tmp_dist);

		auto at = LOC.find(tmp_diff);

		if(at == LOC.end()){ //入力にない距離なら不適
			FLG = false;
			break;
		}

		tmp_loc = LOC[tmp_diff];

		if(next_rest_num[L][tmp_loc] == 0){ //距離がもう残っていない場合は不適
			FLG = false;
			break;
		}
		next_rest_num[L][tmp_loc]--;
	}

	if(FLG){ //計算済みでないか調べる

		string tmp_str = make_str(next_dist_array[L]);

		auto ch = MAP.find(tmp_str);

		if(ch == MAP.end()){

			MAP[tmp_str] = true;
			int next_index = get_index(next_rest_num[L]);
			recursive(next_dist_array[L],next_rest_num[L],next_index,num_decided+1);
		}
	}

	/*★残っている最大の距離を、右端からの距離と解釈する場合★*/

	tmp_dist = dist_array[N-1]-tmp_dist; //★★左端からの距離にする(右端からの距離 == tmp_dist)★★

	auto a_r = LOC.find(tmp_dist);
	if(a_r == LOC.end() || rest_num[LOC[tmp_dist]] == 0)return;

	//左端から数えて、一番近い空きスペースを探す
	for(int i = 0; i < N; i++){
		if(next_dist_array[R][i] == -1){
			next_dist_array[R][i] = tmp_dist;
			tmp_pos = i;
			break;
		}
	}

	 FLG = true;

	//既に配置されている他の距離と矛盾がないか調べる
	for(int i = 0; i < N-1; i++){ //★i == N-1までやると、tmp_distをデクリメントしているのでfalseになってしまう★
		if(next_dist_array[R][i] == -1 || i == tmp_pos)continue;

		tmp_diff = abs(next_dist_array[R][i]-tmp_dist);

		auto at = LOC.find(tmp_diff);

		if(at == LOC.end()){ //入力にない距離なら不適
			FLG = false;
			break;
		}

		tmp_loc = LOC[tmp_diff];

		if(next_rest_num[R][tmp_loc] == 0){ //距離がもう残っていない場合は不適
			FLG = false;
			break;
		}
		next_rest_num[R][tmp_loc]--;
	}

	if(FLG){ //計算済みでないか調べる

		string tmp_str = make_str(next_dist_array[R]);

		auto ch = MAP.find(tmp_str);

		if(ch == MAP.end()){

			MAP[tmp_str] = true;
			int next_index = get_index(next_rest_num[R]);
			recursive(next_dist_array[R],next_rest_num[R],next_index,num_decided+1);
		}
	}
}

void func(){

	MAP.clear();
	LOC.clear();
	ANS.clear();
	info_index = 0;

	int tmp;
	bool FLG;

	//距離の入力
	for(int i = 0; i < (N*(N-1))/2; i++){

		scanf("%d",&tmp);

		FLG = false;

		//既に登場した距離か調べる
		for(int k = 0;k < info_index; k++){
			if(info[k].dist == tmp){
				info[k].count++;
				FLG = true;
				break;
			}
		}

		if(FLG)continue;

		info[info_index].dist = tmp;
		info[info_index].count = 1;
		info_index++;
	}

	for(int i = 0; i < info_index; i++){ //数字の位置を記録
		LOC[info[i].dist] = i;
	}

	if(info[0].count != 1){ //最長距離が1つでないならreturn
		//printf("not 1\n");
		printf("-----\n");
		return;
	}

	int first_dist_array[NUM]; //左端の町からの相対距離配列
	int first_rest_num[(NUM*(NUM-1))/2]; //距離の使用数の残数配列<★infoの並びに対応★>

	first_dist_array[0] = 0;
	for(int i = 1; i <= N-2; i++)first_dist_array[i] = -1;
	first_dist_array[N-1] = info[0].dist;

	first_rest_num[0] = 0;
	for(int i = 1; i < info_index; i++)first_rest_num[i] = info[i].count;

	recursive(first_dist_array,first_rest_num,1,2);

	if(ANS.size() > 0){
		sort(ANS.begin(),ANS.end());
		ANS.erase(unique(ANS.begin(),ANS.end()),ANS.end());
	}

	for(int i = 0; i < ANS.size(); i++){
		printf("%d",ANS[i].table[0]);
		for(int k = 1; k < N-1; k++){
			printf(" %d",ANS[i].table[k]);
		}
		printf("\n");
	}

	printf("-----\n");
}

int main(){

	while(true){
		scanf("%d",&N);
		if(N == 0)break;

		func();
	}

	return 0;
}

