#include <bits/stdc++.h>
constexpr int MOD = 1000000007;
constexpr int N = 1000000;
constexpr int K = 8;
int invmod[100]; // modular inverses for binomial computation
// compute binomial coefficient
int choose(int n, int m) {
int res = 1;
for (int i = 1; i <= m; ++i)
res = (int64_t) res * (n - i + 1) % MOD * invmod[i] % MOD;
return res;
}
int LIS(std::vector<int> ordering) {
int n = ordering.size();
std::vector<int> f(n, 1);
for (int i = 1; i < n; ++i)
for (int j = 0; j < i; ++j)
if (ordering[j] < ordering[i])
f[i] = std::max(f[i], f[j] + 1);
return *std::max_element(f.begin(), f.end());
}
std::vector<int> check_strict_ordering() {
std::vector<int> p(K);
iota(p.begin(), p.end(), 0);
std::vector<int> counts(K + 1, 0);
do {
int L = LIS(p);
int descents = 0;
for (int i = 1; i < K; ++i)
descents += p[i] < p[i - 1];
counts[L] = (counts[L] + choose(N + descents, K)) % MOD;
} while (std::next_permutation(p.begin(), p.end()));
return counts;
}
std::vector<int> check_weak_ordering() {
std::vector<int> counts(K + 1, 0);
auto process = [&](std::vector<int> ordering) {
int unique_count = std::set<int>(ordering.begin(), ordering.end()).size();
do {
int L = LIS(ordering);
counts[L] = (counts[L] + choose(N, unique_count)) % MOD;
} while (std::next_permutation(ordering.begin(), ordering.end()));
};
std::vector<int> ordering;
std::function<void(int, int)> generate = [&](int pos, int left) {
if (pos >= K) {
if (left == 0) {
process(ordering);
}
return;
}
for (int take = 1; take <= left; ++take) {
ordering.push_back(pos);
generate(pos + 1, left - take);
}
if (left == 0)
generate(pos + 1, left);
while (!ordering.empty() && ordering.back() == pos)
ordering.pop_back();
};
generate(0, K);
return counts;
}
int main() {
invmod[1] = 1;
for (int i = 2; i < 100; ++i) {
invmod[i] = (MOD - (int64_t) (MOD / i) * invmod[MOD % i] % MOD) % MOD;
assert((int64_t) invmod[i] * i % MOD == 1);
}
std::vector<int> c1 = check_strict_ordering();
std::vector<int> c2 = check_weak_ordering();
for (int i = 1; i <= K; ++i) {
std::cout << c1[i] << ' ' << c2[i] << '\n';
assert(c1[i] == c2[i]);
}
return 0;
}