// tennis3.cpp
// Solution for the TENNIS problem of BOI 2002
// Ahto Truu
// Tested with GCC 2.95.2/MinGW32, GCC 3.0.4/DJDEV

// This is the middle version, using a faster sorting algorithm

#include <fstream>
#include <algorithm>
using namespace std;

const char iname[] = "TENNIS.IN"; // input file name
const char oname[] = "TENNIS.OUT"; // output file name
const char pos[] = "SOLUTION"; // "positive" answer
const char neg[] = "NO SOLUTION"; // "negative" answer
const int maxn = 1000;  // max allowed number of players

struct player { // this is the data we keep on each player
    int num; // sequence number of the player
    int gam; // number of games still available
};

// compares two players by number of games
bool before(player a, player b)
{
    return a.gam > b.gam;
}

// global data
int n; // the number of players
player p[maxn]; //player data
bool g[maxn][maxn]; // "game matrix", g[i][j] iff players i and j play

int main()
{
    // load the input data
    ifstream fin(iname);
    fin >> n;
    for (int i = 0; i < n; ++i)
        fin >> p[i].gam;
    fin.close();

    // assign the sequence numbers to players
    for (int i = 0; i < n; ++i)
        p[i].num = i; // 0-based, need to adjust for output

    // fill the matrix in a greedy way
    // on each step, the player with highest number of available games
    // is set to play with the players with the second, third, etc
    bool ok = true; // assume we'll find a solution
    while (true) {
        // sort the players in descending order of number of games
        sort(p, p + n, before);
        // no more games to match, we're done
        if (p[0].gam == 0)
            break;
        // match the first player with the following ones
        int i = 1;
        while (p[0].gam > 0 && p[i].gam > 0) {
            g[p[0].num][p[i].num] = g[p[i].num][p[0].num] = true;
            --p[0].gam; --p[i].gam;
            ++i;
        }
        // some games were left for first player, we have a problem
        if (p[0].gam > 0) {
            ok = false;
            break;
        }
    }

    // output the answer
    ofstream fout(oname);
    if (ok) {
        fout << pos << endl;
        for (int i = 0; i < n; ++i) {
            bool spc = false;
            for (int j = 0; j < n; ++j)
                if (g[i][j]) {
                    if (spc)
                        fout << ' ';
                    fout << j + 1; // adjust 0-based values
                    spc = true;
                }
            fout << endl;
        }
    } else
        fout << neg << endl;
    fout.close();

    // that's all, folks :)
    return 0;
}
