#include <algorithm>
#include <cassert>
#include <iostream>
#include <iterator>
#include <memory>
#include <vector>

using namespace std;

typedef vector<int>::const_iterator elements_iterator;

struct Tree {
  const unique_ptr<Tree> left;
  const int value;
  const unique_ptr<Tree> right;

  Tree(unique_ptr<Tree> left, int value, unique_ptr<Tree> right)
      : left(move(left)), value(value), right(move(right)) {}
};

vector<int> g_height_to_size = {0, 1};

unique_ptr<Tree> Build(int height_advise, elements_iterator begin,
                       elements_iterator end) {
  assert(distance(begin, end) == g_height_to_size.at(height_advise));
  if (height_advise == 0) {
    return nullptr;
  }
  if (height_advise == 1) {
    return make_unique<Tree>(nullptr, *begin, nullptr);
  }
  int left_size = g_height_to_size[height_advise - 2];
  return make_unique<Tree>(
      Build(height_advise - 2, begin, begin + left_size), *(begin + left_size),
      Build(height_advise - 1, begin + left_size + 1, end));
}

void PrintTree(const unique_ptr<Tree> &root) {
  static int counter = 0;
  auto handle_child = [&root](const unique_ptr<Tree> &child) {
    if (child) {
      cout << "  " << root->value << " -> " << child->value << ";" << endl;
      PrintTree(child);
    } else {
      cout << "  null" << counter << " [shape=point];" << endl;
      cout << "  " << root->value << " -> "
           << "null" << counter << ";" << endl;
      ++counter;
    }
  };
  if (root->left || root->right) {
    handle_child(root->left);
    handle_child(root->right);
  }
}

int main() {
  int n;
  cin >> n;

  while (g_height_to_size.back() < n) {
    g_height_to_size.push_back(g_height_to_size.back() +
                               *prev(g_height_to_size.end(), 2) + 1);
  }
  if (g_height_to_size.back() != n) {
    cerr << "Invalid N: " << n << endl;
    return 1;
  }
  vector<int> elements(n);
#if 1
  for (int i = 0; i < n; ++i) {
    elements[i] = i + 1;
  }
#else
  copy_n(istream_iterator<int>(cin), n, elements.begin());
  sort(elements.begin(), elements.end());
  if (adjacent_find(elements.begin(), elements.end()) != elements.end()) {
    cerr << "Elements must be unique" << endl;
    return 1;
  }
#endif

  cout << "digraph fib_tree { " << endl;
  PrintTree(
      Build(g_height_to_size.size() - 1, elements.begin(), elements.end()));
  cout << "}" << endl;

  return 0;
}
