#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <stack>
#include <queue>

using namespace std;

typedef vector<int> VI;
typedef vector<VI> VVI;

VVI mat, mate;
int v;

typedef vector<int> Face;

multiset<Face> faces;

vector<bool> inface;

VI maiorciclo;
VI cicloatual;
vector<bool> incluido;
bool planar;

void auxencontra(int x){
    if(!maiorciclo.empty()) return;
    for(int i=0; i<v; ++i){
		if(!mat[x][i] || incluido[i]) continue;
		incluido[i]=true;
		cicloatual.push_back(i);
        auxencontra(i);
		incluido[i]=false;
		cicloatual.pop_back();
    }
    if(maiorciclo.empty() && cicloatual.size()==v){
        maiorciclo=cicloatual;
    }
}

vector<int> encontra_ciclo(){
	maiorciclo = VI();
	cicloatual = VI();
	incluido = vector<bool>(v, false);
	auxencontra(0);
	return maiorciclo;
}

vector<bool> fragatual;

void inicializar(){
    inface = vector<bool>(v, false);
	vector<int> ciclo = encontra_ciclo();
	Face f;
	puts("CICLO");
	for(int i=0; i<ciclo.size(); ++i){
		int a = ciclo[i];
		int b = ciclo[(i+1)%ciclo.size()];
		mate[a][b]=mate[b][a]=1;
		printf("%d ", a);
		f.push_back(a);
		inface[a]=true;
	}
	faces.insert(f); //interna
	faces.insert(f); //externa ou vice-versa

}

void insereface(int x, int y, Face f){

    faces.erase(faces.find(f));
    Face f1, f2;
    f1.push_back(y);
    f1.push_back(x);
    f2.push_back(y);
    f2.push_back(x);
    mate[x][y]=mate[y][x]=1;
    int p;
    for(p=0; p<f.size(); p++){
        if(f[p]==x) break;
    }
    puts("Isto cria 2 NOVAS FACES");

    for(int i=(p+1)%f.size(); f[i]!=y; i=(i+1)%f.size()){
        f1.push_back(f[i]);
    }

    for(int i=(p-1+f.size())%f.size(); f[i]!=y; i=(i-1+f.size())%f.size()){
        f2.push_back(f[i]);
    }

    for(int i=0; i<f1.size(); ++i) printf("%d ", f1[i]);
    puts("");
    for(int i=0; i<f2.size(); ++i) printf("%d ", f2[i]);
    puts("");

    faces.insert(f1);
    faces.insert(f2);


}


bool cordalseg(){
    Face any = Face();
    int xg, yg;
    for(int i=0; i<v; ++i){
        for(int j=i+1; j<v; ++j){
            if(!mate[i][j] && mat[i][j]){ //PARA CADA ARESTA
                int qtd=0;
                Face pri;
                int x, y;
                for(multiset<Face>::iterator f = faces.begin(); f!=faces.end(); ++f){ //PARA CADA FACE
                    Face aux = (*f);
                    bool xi=false, yi=false;
                    for(int k=0; k<aux.size(); ++k){
                        if(aux[k]==i){
                            xi=true;
                        }
                        if(aux[k]==j){
                            yi=true;
                        }
                        if(xi && yi) break;
                    }
                    if(xi && yi){
                        if(!qtd){
                            pri = aux;
                            x = i;
                            y = j;
                        }
                        qtd++;
                    }
                }
                if(qtd==0){
                    planar = false;
                    return false;
                }
                else if(qtd==1){
                    printf("Insere %d %d na face: ", x, y);
                    for(int i=0; i<pri.size(); ++i) printf("%d ", pri[i]);
                    puts("");
                    insereface(x,y,pri);
                    return true;
                }
                else if(qtd>=2){
                    puts(">=2");
                    if(any.empty()){
                        printf("! %d %d\n", x, y);
                        for(int i=0; i<pri.size(); ++i) printf(" %d", pri[i]); puts("");
                        any = pri;
                        xg=x;
                        yg=y;
                    }
                }
            }
        }
    }
    if(!any.empty()){
        printf("Insere %d %d na face: ", xg, yg);
        for(int i=0; i<any.size(); ++i) printf("%d ", any[i]); puts("");
        insereface(xg,yg,any);
        return true;
    }
    planar = true;
    return false;
}

void planarity(){
	inicializar();
    int cont = 0;
	do{
        printf("\nNa Iteracao %d existem as FACES\n", cont++);
        for(multiset<Face>::iterator f = faces.begin(); f!=faces.end(); f++){
            for(int i=0; i<(*f).size(); ++i) printf("%d ", (*f)[i]);
				puts("");
        }
	}while(cordalseg());
    puts("\nFACES FINAIS");
    for(multiset<Face>::iterator f = faces.begin(); f!=faces.end(); f++){
        for(int i=0; i<(*f).size(); ++i) printf("%d ", (*f)[i]);
            puts("");
    }
}

int main(){
	scanf("%d", &v);
	mat = VVI(v, VI(v, 0));
	mate = VVI(v, VI(v, 0));
	int a, b;
	while(scanf("%d %d", &a, &b)!=EOF){
		if(!a and !b) break;
		mat[a][b]=mat[b][a]=1;
	}
	planarity();
	if(!planar){
        printf("\nInfelizmente, nem todas as arestas puderam ser inseridas na imersao planar!\nAbaixo segue a lista das arestas que nao puderam ser colocadas:\n");
        for(int i=0; i<v; ++i){
            for(int j=i+1; j<v; ++j){
                if(mat[i][j] != mate[i][j]) printf("%d -> %d\n", i, j);
            }
        }
    }else{
        puts("\nGRAFO PLANAR");
    }
}