给定m个长度为n的数组,要求从每一个数组中取出一个数字然后相加,这样的取法总共有n^mnm种。

问相加之后和最小的n种是多少。

输入

第一行输入两个整数m, n (1 \le m \le 100, 1 \le n \le 2000)m,n(1m100,1n2000)。

接下来m行,每行n个整数,描述每一个数组。数组中的元素非负,且不超过1万。

输出

按从小到大输出前n小的和。

样例

输入

复制
2 3
1 2 3
2 2 3

输出

复制
3 3 4


从最小和到次小和依次枚举,然后dfs找出每个和的情况。

#pragma warning(disable:4996)
#include <iostream>
#include <cstdio>
#include <numeric>
#include <cstring>
#include <vector>
#include <algorithm>
#include <functional>
#define inf 0x3f3f3f3f
int main()
{
    int m, n;
    scanf("%d%d", &m, &n);
    std::vector<std::vector<int>> array(m, std::vector<int>(n));
    int k = 0;
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            scanf("%d", &array[i][j]);
        }
        sort(array[i].begin(), array[i].begin() + n);
    }
    std::function<void(int, int, int)> dfs = [&](int arNum, int cur, int sum)->void
    {
        if (arNum >= m)
        {
            if (cur) return;
            if (k) putchar(' ');
            printf("%d", sum);
            k++;
            return;
        }
        for (int i = 0; i < n; i++)
        {
            if (k >= n || array[arNum][i] - array[arNum][0] > cur)
            {
                return;
            }
            dfs(arNum + 1, cur - array[arNum][i] + array[arNum][0], sum + array[arNum][i]);
        }
    };
    for (int i = 0; i <= 10000; i++)
    {
        if (k >= n) break;
        dfs(0, i, 0);
    }
    return 0;
}
/*
5 10
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
*/