#include <iostream>
#include <vector>

using namespace std;

template <typename T> void PrintVector(vector<T> vec){
    cout << "[";
    for (typename vector<T>::iterator it = vec.begin(); it != vec.end(); it++) {
        if (it != vec.begin())
            cout << ", ";
        cout << *it;
    }
    cout << "]" << endl;
}

// class : make combination
// set numArray that you want to make combination
// call Reset() at first
// call Next() to make combination of numArray. result is set to comArray
// return value of Next() is 0 ==> no more combination
// Print() : print comArray (current combination)
template <typename T> class Combination {
  private:
    vector<int> comParam;
  public:
    vector<T> numArray;
    vector<T> comArray;
    
    Combination() {}
    Combination(vector<T> a) { numArray = a; }
    
    int Reset() {
        int size = numArray.size();
        comParam.clear();
        for (int i = 0; i < size; i++) {
            comParam.push_back((i == 0) * size);
        }
        comArray = numArray;
        return 0;
    }
    
    int Next() {
        int size = comParam.size();
        int pos, carry;
        
        pos = size - 1;
        carry = 1;
        while (carry && (pos >= 0)) {
            comParam[pos] = comParam[pos] - carry;
	        if (comParam[pos] < 0) {
	            comParam[pos] = size - pos - 1;
	            carry = 1;
	            pos --;
	        } else {
	            carry = 0;
	        }
        }
        if (pos < 0) return 0;
        
        comArray = numArray;
        for (int i = 0; i < size; i++) {
            T tmp = comArray[i];
            comArray[i] = comArray[i + comParam[i]];
            comArray[i + comParam[i]] = tmp;
        }
        return 1;
    }
    
    void Print() {
        PrintVector<T>(comArray);
    }
};

class BilliardProblem : private Combination<int> {
  public:
    vector<int> ballArray;   // ball number list
    int ballNum;    // number of ball
    int ballSum;    // sum of all ball ( sum = n * (n - 1) + 1 )
    
    BilliardProblem(int n) {
        ballNum = n;
        ballSum = n * (n - 1) + 1;
        ballArray.clear();
        
        // make initial ball list
        int sum = 0;
        for (int i = 1; i <= n - 1; i++) {
            ballArray.push_back(i);
            sum += i;
        }
        ballArray.push_back(ballSum - sum);
    }
    
    // find next ball list
    int Next() {
        int pos;
        
        pos = ballNum - 1;
        if (pos <= 2) return 0;
        ballArray[pos-1] = ballArray[pos-1] + 1;
        ballArray[pos] = ballArray[pos] - 1;
        if (ballArray[pos-1] >= ballArray[pos]) {
            pos--;
            while (pos > 2) {
                ballArray[pos-1] = ballArray[pos-1] + 1;
                for (int i = pos; i < ballNum - 1; i++) {
                    ballArray[i] = ballArray[i-1] + 1;
                }
                int sum = 0;
                for (int i = 0; i < ballNum - 1; i++) {
                    sum += ballArray[i];
                }
                ballArray[ballNum - 1] = ballSum - sum;
                if (ballArray[ballNum - 1] > ballArray[ballNum - 2]) {
                    return 1;
                } else {
                    pos--;
                }
            }
            return 0;
        }
        return 1;
    }
    
    // check all combination of ball list
    int Check() {
        int nExist = 0;
        int count  = 0;
        
        numArray = ballArray;
        Combination::Reset();
        while (Combination::Next()) {
            // sum check
	        for (int n = 1; n <= ballSum / 2 + 1; n++) {
	            nExist = 0;
		        for (int i = 1; i <= ballNum; i++) {
		            for (int j = 0; j < ballNum; j++) {
		                int sum = 0;
		                for (int k = 0; k < i; k++) {
		                    sum += comArray[(j + k) % ballNum];
		                }
		                if (n == sum) {
		                    nExist = 1;
		                    break;
		                }
		            }
		            if (nExist == 1) break;
		        }
		        if (nExist == 0) break;
		    }
		    // combination found then print combination
		    if (nExist) {
		        Combination::Print();
		        count++;
		    }
		}
		return count;
    }
    
    // print ball list
    void Print() {
        PrintVector<int>(ballArray);
    }
};

int main(void) {
    
    BilliardProblem *ballSet;
    int     count;
    
    for (int ball = 1; ball <= 7; ball++) {
    	
        ballSet = new BilliardProblem(ball);
        
	    cout << "===============================================" << endl;
	    cout << "Check " << ball << " balls.";
	    cout << "  ( 1 - " << ballSet->ballSum << " )" << endl;
	    
	    count = 0;
	    do {
	        count += ballSet->Check();
	    } while (ballSet->Next());
	    
	    cout << count <<  " ways found, ";
	    cout << "include combination of mirror and rotation." << endl;
	    cout << "(" << count / ball / ((ball <= 2 ) ? 1 : 2);
	    cout << " ways without mirror and rotation)" << endl;
	    
	    delete ballSet;
	}
    
    return 0;
}

