    /**
     * Author: Sergey Kopeliovich (Burunduk30@gmail.com)
     */

    #include <bits/stdc++.h>

    using namespace std;

    #define forn(i, n) for (int i = 0; i < (int)(n); i++)

    typedef long long ll;

    template <const int maxLen, const int ALPHA_SIZE>
    struct SuffixTree {
      static const int maxV = 1 + maxLen * 2;
      struct edge {
        int st, len, next;
        edge() { }
        edge( int st, int len, int next ) : st(st), len(len), next(next) { }
      };

      int *s, n, vn, root, suf[maxV], dep[maxV], size[maxV];
      edge e[maxV][ALPHA_SIZE];

      int newV( int d, bool end ) {
        assert(vn < maxV);
        dep[vn] = d, size[vn] = end, suf[vn] = 0;
        memset(e[vn], 0, sizeof(e[0]));
        return vn++;
      }

      int split( int v, int c, int i ) {
        edge a = e[v][c];
        int u = newV(dep[v] + i, 0);
        e[v][c] = edge(a.st, i, u);
        e[u][s[a.st + i]] = edge(a.st + i, a.len - i, a.next);
        return u;
      }

      void create( int u, int c, int i ) {
        e[u][c] = edge(i, n - i, newV(dep[u] + (n - i), 1));
      }

      SuffixTree( int n, int *s ) : s(s), n(n) {
        vn = 0;
        root = newV(0, 0);

        int v = 0, cur_c = 0, cur_i = 0;
        forn(i, n) {
          if (cur_i && cur_i == e[v][cur_c].len)
            v = e[v][cur_c].next, cur_i = 0;

          int c = s[i], last = -1;
          int *t = s + e[v][cur_c].st;
          while (cur_i && t[cur_i] != c) {
            int w = suf[v], u = split(v, cur_c, cur_i);
            create(u, c, i);
            if (last != -1)
              suf[last] = u;
            last = u;
            if (!v)
              t++, cur_i--;
            edge a;
            while (cur_i && (a = e[w][cur_c = *t]).len <= cur_i)
              cur_i -= a.len, w = a.next, t += a.len;
            v = w;
            if (!cur_i)
              suf[last] = v;
          }
          if (cur_i) {
            cur_i++;
          } else {
            cur_i = 1, cur_c = c;
            while (e[v][c].len < cur_i) {
              create(v, c, i);
              if (v)
                v = suf[v];
              else
                cur_i = 0;
            }
          }
        }
      }

      vector<edge> ss;
      void out( int v, int res_v ) {
        if (v == res_v) {
          for (auto x : ss)
            forn(i, x.len)
              if (s[x.st + i] != 0)
                printf("%d ", s[x.st + i]);
        }
        forn(i, ALPHA_SIZE)
          if (e[v][i].len)  {
            ss.push_back(e[v][i]);
            out(e[v][i].next, res_v);
            ss.pop_back();
          }
      }
      void out( int res_v ) {
        out(root, res_v);
      }
    };

    typedef SuffixTree<int(1e5), 11> ST;

    int main() {
      const int n = 10;
      int a[n] = {};
      ST *tree = new ST(n, a);
    }