#include <algorithm>
#include <numeric>
#include <limits>
#include <iostream>
#include <vector>

using array_type = std::vector<int>;

array_type input(std::string info, int n) {
    array_type result(n);
    std::cout << info;
    for ( ; n--; )
        std::cin >> result[n];
    return result;
}

int score(const std::vector<array_type>& arrays, const array_type& weights) {
    return std::inner_product( std::begin( arrays ), std::end( arrays ) - 1, std::begin( arrays ) + 1, 0, std::plus<int>{},
        [&](auto& a, auto& b) {
            return std::inner_product( std::begin( a ), std::end( a ), std::begin( b ), 0, std::plus<int>{},
                [&](auto& x, auto& y) {
                    return ( x == y ) * weights[&x - &a.front()];
                } );
        } );
}

int main()
{
    std::cout << "Arraylänge: ";
    int l = 0;
    std::cin >> l;
    array_type weights = input( "Gewichte: ", l );
    std::cout << "Anzahl Arrays: ";
    int n = 0;
    std::cin >> n;
    std::vector<array_type> arrays;
    for ( int i = 0; i != n; ++i ) {
        arrays.push_back( input( "Array " + std::to_string( i ) + ": ", l ) );
    }
    std::sort( begin( arrays ), end( arrays ) );
    int best_score = std::numeric_limits<int>::min();
    std::vector<array_type> best;
    do {
        if ( score( arrays, weights ) > best_score ) {
            best_score = score( arrays, weights );
            best = arrays;
        }
    } while ( next_permutation( std::begin( arrays ), std::end( arrays ) ) );
    std::cout << "\nBeste Punkte: " << best_score << '\n';
    for ( auto& a : arrays ) {
    	std::cout << "( ";
        for ( auto& x : a ) {
            std::cout << x << ' ';
        }
        std::cout << ")\n";
    }
    std::cout << std::endl;
}