#include <iostream>
#include <vector>
#include <map>
#include <list>
#include <stack>

#include <set>
using namespace std;

using graph = map<int, set<int>>;

graph read_graph() {
  graph result;
  int a,b;
  while (cin >> a >> b) {
    if (a==-1)
      return result;
    result[a].insert(b);
    result[b].insert(a);
  }
  return result;
}

void print_graph(const graph &g) {
  for (auto &v : g) {
    cout << v.first << ":";
    for (auto &e : v.second) {
      cout << " " << e;
    }
    cout << endl;
  }
}

string parse_graph(const graph &g) {
  if (g.empty())
    return "";
  int index = 1;
  string result = "";
  int start = g.begin()->first;
  stack<int> to_visit;
  to_visit.push(start);
  map<int, int> opened;
  map<int, int> back_references;
  map<int, list<string>> subresults;
  map<int, set<int>> mark;
  int next_mark=1;
  
  opened[start]=1;
  while (!to_visit.empty()) {
    int current = to_visit.top();

    if(opened[current]==1) {
      cout << "opening: " << current << endl;
      const set<int> &neighbors = g.find(current)->second;
      for (auto &v:neighbors) {
        if (opened[v] < 1) {
          back_references[v] = current;
          to_visit.push(v);
          opened[v]=1;
        } else if (opened[v] == 1) {
          mark[v].insert(index);
          mark[current].insert(index++);
        }
      }
      opened[current] = 2;
    } else {
      cout << "back_ref: " << back_references[current];
      cout << "closing: " << current << endl;
      string s;
      bool x = false;
      for (auto &r: subresults[current]) if(x){
        s = "("+r+")" + s;
      } else {
        s = r;
        x=true;
      }
      for (auto &m : mark[current])
        s = to_string(m) + s;
      s = "o"+s;
      if(current==start) return s;
      subresults[back_references[current]].push_back(s);
      to_visit.pop();
    }


  }
  return result;
}

int main() {
  graph g = read_graph();
  print_graph(g);
  cout << parse_graph(g) << endl;

}
