#include <bits/stdc++.h>
using ll = long long int;
using vi = std::vector<int>;
using vvi = std::vector<vi>;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using pi = std::pair<int, int>;
using vpi = std::vector<pi>;
template <typename T>
void mk_unique(T& l) {
  if (!std::is_sorted((l).begin(), (l).end()))
    std::sort((l).begin(), (l).end());
  auto it = std::unique(l.begin(), l.end());
  auto d = std::distance(l.begin(), it);
  l.resize(d);
}
template <typename T>
T& smax(T& l, const T& r) {
  if (l < r) l = r;
  return l;
}
template <typename T>
T& smin(T& l, const T& r) {
  if (l > r) l = r;
  return l;
}
constexpr int MOD = 998244353;
namespace io {
class input_reader {
  void throw_error() {
    throw std::runtime_error("No more inputs while reading number");
  }
  template <typename T>
  inline void readIntegerValue(T& f) {
    bool positive = true;
    f = 0;
    char c;
    if (!in.get(c)) throw_error();
    while (c < '0' || c > '9') {
      if (c == '-') positive = false;
      if (!in.get(c)) throw_error();
    }
    while (c >= '0' && c <= '9') {
      f = (f << 3) + (f << 1) + (c & 15);
      if (!in.get(c)) break;
    }
    if (!positive) f *= -1;
  }

 public:
  std::istream& in;
  explicit input_reader(std::istream& in) : in(in) {}
  inline void read(int& f) { readIntegerValue(f); }
  inline void read(short& f) { readIntegerValue(f); }
  inline void read(long int& f) { readIntegerValue(f); }
  inline void read(long long int& f) { readIntegerValue(f); }
  inline void read(unsigned int& f) { readIntegerValue(f); }
  inline void read(unsigned short& f) { readIntegerValue(f); }
  inline void read(unsigned long int& f) { readIntegerValue(f); }
  inline void read(unsigned long long int& f) { readIntegerValue(f); }
  template <typename T>
  inline void read(std::vector<T>& f) {
    for (auto& i : f) read(i);
  }
  template <typename T, int N>
  inline void read(std::array<T, N>& res) {
    for (auto& i : res) read(i);
  }
  template <typename T1, typename T2>
  inline void read(std::pair<T1, T2>& p) {
    in.read(p.first, p.second);
  }
  template <typename T>
  inline void read(T& f) {
    in >> f;
  }
  template <typename T, typename... Args>
  inline void read(T& t, Args&... args) {
    read(t), read(args...);
  }
  template <typename T>
  inline void readArray(int n, T* res) {
    while (n--) read(*(res++));
  }
  template <typename T>
  inline input_reader& operator>>(T& t) {
    return read(t), *this;
  }
};
}  // namespace io
namespace io {
class output_writer {
  std::ostream& out;
  template <typename T>
  inline void printIntegerHelper(T x) {
    if (x >= 10) printIntegerHelper(x / 10);
    out.put(x % 10 + 48);
  }
  template <typename T>
  inline void printInteger(T x) {
    if (x < 0) out.put('-'), x = -x;
    printIntegerHelper(x);
  }
  template <typename T>
  inline void printArray(T& ar) {
    bool first = true;
    for (auto& t : ar) print((first) ? first = false, "" : " ", t);
  }

 public:
  explicit output_writer(std::ostream& out) : out(out) {}
  inline void flush() { out.flush(); }
  inline void print() {}
  inline void print(char x) { out.put(x); }
  inline void print(short x) { printInteger(x); }
  inline void print(int x) { printInteger(x); }
  inline void print(long int x) { printInteger(x); }
  inline void print(long long int x) { printInteger(x); }
  inline void print(unsigned short x) { printInteger(x); }
  inline void print(unsigned int x) { printInteger(x); }
  inline void print(unsigned long int x) { printInteger(x); }
  inline void print(unsigned long long int x) { printInteger(x); }
  template <typename T1>
  inline void print(const T1& t1) {
    out << t1;
  }
  template <typename T1>
  inline void print(const std::vector<T1>& t1) {
    printArray(t1);
  }
  template <typename T1, int N>
  inline void print(const std::array<T1, N>& t1) {
    printArray(t1);
  }
  template <typename T1, int N, int M>
  inline void print(const std::array<std::array<T1, M>, N>& t1) {
    for (auto& t : t1) println(t);
  }
  template <typename T1>
  inline void print(const std::vector<std::vector<T1>>& t1) {
    bool first = true;
    for (auto& t : t1) print((first) ? first = false, "" : "\n", t);
  }
  template <typename T, typename... Args>
  inline void print(const T& t, Args... args) {
    print(t), print(args...);
  }
  template <typename... Args>
  inline void println(Args... args) {
    print(args...), print('\n');
  }
  template <typename T>
  output_writer& operator<<(const T& t) {
    return print(t), *this;
  }
};
}  // namespace io
inline ll pow_mod(ll a, ll b, const ll MOD) {
  ll res = 1;
  for (ll i = 1; b; b ^= b & i, i <<= 1, a = (a * a) % MOD)
    if (b & i) res = (res * a) % MOD;
  return res;
}
inline ll mod_inv(const ll a, const ll MOD) { return pow_mod(a, MOD - 2, MOD); }
template <typename T>
inline T gcd(T a, T b) {
  T t;
  while (a != 0) t = a, a = b % a, b = t;
  return b;
}
template <typename T>
T lcm(const T& a, const T& b) {
  assert(a != 0 && b != 0);
  return a / gcd(a, b) * b;
}
namespace math {
template <class T>
int gMOD(T v) {
  v %= MOD;
  if (v < 0) v += MOD;
  return (int)v;
};
class mod_int {
  using mi = mod_int;
  int v;

 public:
  mod_int(int v) : v(gMOD(v)) {}
  mod_int(unsigned int v) : v(gMOD(v)) {}
  mod_int(long long int v) : v(gMOD(v)) {}
  mod_int(unsigned long long int v) : v(gMOD(v)) {}
  mod_int(long int v) : v(gMOD(v)) {}
  mod_int(unsigned long int v) : v(gMOD(v)) {}
  mod_int() = default;
  mod_int(const mi& o) = default;
  mod_int(mi&& o) = default;
  inline mi& operator=(const mi& o) = default;
  inline mi& operator=(mi&& o) = default;
  inline mi& operator++() {
    if (v == MOD - 1)
      v = 0;
    else
      v++;
    return *this;
  }
  inline mi& operator--() {
    if (v == 0)
      v = MOD - 1;
    else
      v--;
    return *this;
  }
  inline mi operator++(int) {
    mi t = *this;
    ++(*this);
    return t;
  }
  inline mi operator--(int) {
    mi t = *this;
    --(*this);
    return t;
  }
  inline bool friend operator==(const mi& lhs, const mi& rhs) {
    return lhs.v == rhs.v;
  }
  inline bool friend operator!=(const mi& lhs, const mi& rhs) {
    return lhs.v != rhs.v;
  }
  template <typename T>
  inline bool friend operator==(const mi& lhs, const T& rhs) {
    return lhs == mi(rhs);
  }
  template <typename T>
  inline bool friend operator!=(const mi& lhs, const T& rhs) {
    return lhs != mi(rhs);
  }
  inline mi friend operator-(const mi& lhs, const mi& rhs) {
    mi res;
    res.v = lhs.v - rhs.v;
    if (res.v < 0) res.v += MOD;
    return res;
  }
  inline mi friend operator+(const mi& lhs, const mi& rhs) {
    mi res;
    res.v = lhs.v + rhs.v - MOD;
    if (res.v < 0) res.v += MOD;
    return res;
  }
  inline mi friend operator*(const mi& lhs, const mi& rhs) {
    return {((((long long int)lhs.v) * rhs.v))};
  }
  inline mi friend operator/(const mi& lhs, const mi& rhs) {
    return lhs * rhs.inv();
  }
  template <typename T>
  inline mi friend operator-(const mi& lhs, const T& rhs) {
    return lhs - mi(rhs);
  }
  template <typename T>
  inline mi friend operator+(const mi& lhs, const T& rhs) {
    return lhs + mi(rhs);
  }
  template <typename T>
  inline mi friend operator*(const mi& lhs, const T& rhs) {
    return lhs * mi(rhs);
  }
  template <typename T>
  inline mi friend operator/(const mi& lhs, const T& rhs) {
    return lhs / mi(rhs);
  }
  template <typename T>
  inline mi& operator-=(const T& rhs) {
    return *this = *this - rhs;
  }
  template <typename T>
  inline mi& operator+=(const T& rhs) {
    return *this = *this + rhs;
  }
  template <typename T>
  inline mi& operator*=(const T& rhs) {
    return *this = *this * rhs;
  }
  template <typename T>
  inline mi& operator/=(const T& rhs) {
    return *this = *this / rhs;
  }
  inline mi inv() const { return pow(MOD - 2); }
  inline mi pow(long long int pw) const {
    mi res, val;
    res.v = 1, val.v = v;
    while (pw) {
      if (pw & 1) res *= val;
      val *= val;
      pw >>= 1;
    }
    return res;
  }
  inline operator int() const { return v; }
  inline friend std::istream& operator>>(std::istream& in, mi& rhs) {
    long long int v;
    in >> v;
    rhs = {v};
    return in;
  }
  inline friend std::ostream& operator<<(std::ostream& out, mi& rhs) {
    out << rhs.v;
    return out;
  }
};
}  // namespace math
namespace math {
mod_int factorial(unsigned int n) {
  static std::vector<mod_int> mem;
  static mod_int last;
  if (mem.empty()) last = {1}, mem.push_back(last);
  while (!(n < mem.size())) mem.push_back(mem.back() * last++);
  return mem[n];
}
mod_int n_choose_k(int n, int k) {
  mod_int res = factorial(n);
  mod_int res2 = (factorial(k) * factorial(n - k));
  return res / res2;
}
}  // namespace math
template <typename P, typename CMP = std::less<P>, int B = 2>
class priority_queue_with_changes {
  using K = int;
  const CMP cmp = CMP();

 public:
  priority_queue_with_changes(int n) : index(n), pq(1) { assert(B > 1); }
  struct state {
    K key;
    P priority;
  };

 private:
  std::vector<int> index;
  std::vector<state> pq;
  inline bool compare_indices(int i, int j) const {
    return cmp(pq[i].priority, pq[j].priority);
  }
  void heap_up(int i) {
    const auto pme = pq[i];
    while (i >> B != 0) {
      __builtin_prefetch(&(*pq.begin()) + (i >> (B * 4)));
      const auto pnxt = pq[i >> B];
      if (cmp(pnxt.priority, pme.priority)) {
        pq[i] = pnxt, index[pnxt.key] = i;
        i >>= B;
      } else
        break;
    }
    pq[i] = pme, index[pme.key] = i;
  }
  void heap_down(unsigned int i) {
    const auto pme = pq[i];
    const size_t len = pq.size();
    while ((i << B) < len) {
      __builtin_prefetch(&(*pq.begin()) + (((size_t)i) << (4 * B)));
      auto p = pq[i << B];
      int inxt = i << B;
      for (size_t j = 1; j < 1 << B && (i << B) + j < len; j++) {
        auto p1 = pq[(i << B) + j];
        if (cmp(p.priority, p1.priority)) p = p1, inxt = (i << B) + j;
      }
      if (cmp(pme.priority, p.priority)) {
        pq[i] = p, index[p.key] = i, i = inxt;
      } else
        break;
    }
    pq[i] = pme, index[pme.key] = i;
  }

 public:
  bool was_poped(K key) const { return index[key] < 0; }
  void push(K key, P priority) {
    int& i = index[key];
    if (i > 0) {
      P before = pq[i].priority;
      pq[i].priority = priority;
      if (cmp(before, priority))
        heap_up(i);
      else
        heap_down(i);
    } else {
      i = pq.size();
      pq.push_back({key, priority});
      heap_up(i);
    }
  }

 private:
  size_t get_index_of_max() const {
    size_t res = 1;
    for (size_t i = 2; i < (1 << B) && i < pq.size(); ++i)
      if (cmp(pq[res].priority, pq[i].priority)) res = i;
    return res;
  }

 public:
  const state& top() const {
    assert(!this->empty());
    return pq[get_index_of_max()];
  }
  void pop() {
    assert(!this->empty());
    int i = get_index_of_max();
    K key = pq[i].key;
    index[key] = -1;
    if (i == pq.size() - 1)
      pq.pop_back();
    else {
      pq[i] = pq.back(), index[pq[i].key] = i, pq.pop_back();
      heap_down(i);
    }
  }
  class changable_entry {
    priority_queue_with_changes& pq;
    K k;

   public:
    changable_entry(priority_queue_with_changes& pq_, K k_) : pq(pq_), k(k_) {}
    operator P() {
      assert(pq.index[k] > 0);
      return pq.pq[pq.index[k]].priority;
    }
    changable_entry& operator=(P p_) {
      pq.push(k, p_);
      return *this;
    }
  };
  int count(K k) const { return index[k] > 0; }
  changable_entry operator[](const K& k) { return changable_entry(*this, k); }
  bool empty() const { return pq.size() == 1; }
};
using mi = math::mod_int;
using vmi = std::vector<mi>;
using vvmi = std::vector<std::vector<mi>>;
using namespace std;
class E1ChioriAndDollPickingEasyVersion {
  class Solver {
   public:
    io::input_reader in;
    io::output_writer out;
    Solver(std::istream& in, std::ostream& out) : in(in), out(out) {}
    vll find_basis(vll& a) {
      vll B;
      int i = a.size() - 1;
      while (i >= 0) {
        if (a[i] != 0) {
          for (auto& j : B) j = smin(j, j ^ a[i]);
          B.push_back(a[i]);
          for (int j = 0; j < i; j++) smin(a[j], a[j] ^ a[i]);
        }
        i--;
      }
      return B;
    }
    void solve() {
      int n, m;
      in >> n >> m;
      vll a(n);
      in >> a;
      vll b = find_basis(a);
      vmi ans(m + 1);
      if (b.size() <= 20) {
        ll up_to_now = 0;
        function<void(int)> dfs = [&](int i) {
          if (i == b.size())
            ans[__builtin_popcountll(up_to_now)]++;
          else
            dfs(i + 1), up_to_now ^= b[i], dfs(i + 1), up_to_now ^= b[i];
        };
        dfs(0);
      } else {
        int m_rel = b.size(), m_unrel = m - b.size();
        for (auto i : b) {
          int highest_bit = 0;
          while (i >> (highest_bit + 1)) highest_bit++;
          for (auto& j : b)
            j = ((j >> (highest_bit + 1)) << highest_bit) |
                (((1ll << highest_bit) - 1) & j);
        }
        vvmi dp(m_rel + 1, vmi(1 << m_unrel));
        dp[0][0] = 1;
        vvmi dp1 = dp;
        for (int i = 0; i < m_rel; i++) {
          for (int j = (1); j <= (i + 1); ++j) {
            for (int mask = 0; mask < 1 << m_unrel; mask++) {
              dp1[j][mask] = dp[j][mask] + dp[j - 1][mask ^ b[i]];
            }
          }
          swap(dp, dp1);
        }
        for (int i = 0; i < m_rel + 1; i++) {
          for (int mask = 0; mask < 1 << m_unrel; mask++) {
            ans[i + __builtin_popcount(mask)] += dp[i][mask];
          }
        }
      }
      mi p = mi(2).pow(n - b.size());
      for (auto& i : ans) i *= p;
      out.println(ans);
    }
  };

 public:
  void solve(std::istream& in, std::ostream& out) { Solver(in, out).solve(); }
};
int main() {
  std::ios_base::sync_with_stdio(false), cin.tie(0);
  E1ChioriAndDollPickingEasyVersion solver;
  std::istream& in(std::cin);
  std::ostream& out(std::cout);
  solver.solve(in, out);
  return 0;
}
