#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;
}