#include <bits/stdc++.h>
using namespace std;
template <class T>
void splitstr(const string &s, vector<T> &out) {
  istringstream in(s);
  out.clear();
  copy(istream_iterator<T>(in), istream_iterator<T>(), back_inserter(out));
}
static void redirect(int argc, const char **argv) {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  if (argc > 1) {
    static filebuf f;
    f.open(argv[1], ios::in);
    cin.rdbuf(&f);
    if (!cin) {
      cerr << "Failed to open '" << argv[1] << "'" << endl;
      exit(1);
    }
  }
  if (argc > 2) {
    static filebuf f;
    f.open(argv[2], ios::out | ios::trunc);
    cout.rdbuf(&f);
    if (!cout) {
      cerr << "Failed to open '" << argv[2] << "'" << endl;
    }
  }
  cin.exceptions(ios::failbit);
}
template <typename T>
static constexpr T gcd(T a, T b) {
  return b ? gcd(b, a % b) : a;
}
template <typename T>
static constexpr T wrap_pos(T a, T m) {
  return a < 0 ? a + m : a;
}
template <typename T>
static constexpr T sqr(T a) {
  return a * a;
}
template <typename T>
static constexpr T mod(T a, T m) {
  return wrap_pos(a % m, m);
}
template <typename T>
static constexpr T inverse2(T a, T m) {
  return a <= 1 ? a : mod((1 - inverse2(m % a, a) * m) / a, m);
}
template <typename T>
static constexpr T inverse(T a, T m) {
  return inverse2(mod(a, m), m);
}
template <typename T, typename P>
static constexpr T power(T a, P b) {
  return b == 0 ? T(1) : (b % 2) ? power(a, b - 1) * a : sqr(power(a, b / 2));
}
template <typename T, typename C, T Modulus>
class MR {
 private:
  struct tag_plus {};
  struct tag_minus {};
  struct tag_good {};
  T value;
  static_assert(std::numeric_limits<C>::max() / Modulus / Modulus > 0,
                "compute type is too small");
  static_assert(Modulus < std::numeric_limits<T>::max() / 2,
                "storage type is too small");
  static constexpr T reduce(T value, tag_plus) {
    return value >= Modulus ? value - Modulus : value;
  }
  static constexpr T reduce(T value, tag_minus) {
    return value < 0 ? value + Modulus : value;
  }
  static constexpr T reduce(T value, tag_good) { return value; }

 public:
  static constexpr T modulus = Modulus;
  constexpr MR() : value(0) {}
  constexpr MR(C value) : value(reduce(value % Modulus, tag_minus())) {}
  template <typename tag_t>
  constexpr MR(T value, tag_t tag) : value(reduce(value, tag)) {}
  MR &operator=(C value) {
    this->value = reduce(value % Modulus, tag_minus());
    return *this;
  }
  constexpr MR operator+(MR b) const { return MR(value + b.value, tag_plus()); }
  constexpr MR operator-(MR b) const {
    return MR(value - b.value, tag_minus());
  }
  constexpr MR operator*(MR b) const {
    return MR(C(value) * C(b.value) % Modulus, tag_good());
  }
  constexpr MR operator-() const { return MR(-value, tag_minus()); }
  MR &operator+=(MR b) {
    value = reduce(value + b.value, tag_plus());
    return *this;
  }
  MR &operator-=(MR b) {
    value = reduce(value - b.value, tag_minus());
    return *this;
  }
  MR &operator*=(MR b) {
    value = C(value) * C(b.value) % Modulus;
    return *this;
  }
  constexpr bool operator==(MR b) const { return value == b.value; }
  constexpr bool operator!=(MR b) const { return value != b.value; }
  constexpr T get() const { return value; }
  constexpr MR inverse() const {
    return MR(::inverse(C(value), C(Modulus)), tag_good());
  }
  constexpr MR operator/(MR b) const { return *this * b.inverse(); }
  MR &operator/=(MR b) { return *this *= b.inverse(); }
};
template <typename T, typename C, T Modulus>
static inline std::ostream &operator<<(std::ostream &o, MR<T, C, Modulus> mr) {
  return o << mr.get();
}
struct picture {
  int w;
  int d;
  int idx;
  MR<int, long long, 998244353> ans = 0;
  bool operator<(const picture &other) const {
    return tie(d, w) < tie(other.d, other.w);
  }
};
static void solve(vector<picture> &pics, const vector<int> &wsum,
                  vector<MR<int, long long, 998244353> > &ans, int A, int B,
                  const vector<MR<int, long long, 998244353> > &pdist, int d) {
  int M = ((long long)(pdist).size()) - 1;
  int W = wsum[B] - wsum[A];
  MR<int, long long, 998244353> scale0 =
      MR<int, long long, 998244353>(W).inverse();
  MR<int, long long, 998244353> prod = 0;
  for (int i = 0; i <= M; i++) {
    MR<int, long long, 998244353> scale = scale0 * (W + i * d);
    prod += scale * pdist[i];
  }
  for (int i = A; i < B; i++) ans[pics[i].idx] = prod * pics[i].w;
}
int main(int argc, const char **argv) {
  redirect(argc, argv);
  int N, M;
  cin >> N >> M;
  vector<picture> pics(N);
  for (int i = 0; i < N; i++) {
    int a;
    cin >> a;
    pics[i].d = a ? 1 : -1;
    pics[i].idx = i;
  }
  long long W = 0;
  for (int i = 0; i < N; i++) {
    cin >> pics[i].w;
    W += pics[i].w;
  }
  sort(begin(pics), end(pics));
  vector<int> wsum(N + 1);
  for (int i = 0; i < N; i++) wsum[i + 1] = wsum[i] + pics[i].w;
  int cut = 0;
  while (pics[cut].d < 0) cut++;
  int WL = wsum[cut];
  vector<MR<int, long long, 998244353> > pleft{1};
  unordered_map<int, MR<int, long long, 998244353> > inverse_cache;
  auto inversew = [&](int w) {
    auto pos = inverse_cache.find(w);
    if (pos == inverse_cache.end())
      return inverse_cache[w] = MR<int, long long, 998244353>(w).inverse();
    else
      return pos->second;
  };
  for (int i = 0; i < M; i++) {
    pleft.push_back(0);
    for (int j = ((long long)(pleft).size()) - 1; j >= 0; j--) {
      MR<int, long long, 998244353> p = 0;
      if (j > 0 && pleft[j - 1] != 0) {
        int w = W - (j - 1) + (i - j + 1);
        int wl = WL - (j - 1);
        p += pleft[j - 1] * wl * inversew(w);
      }
      if (pleft[j] != 0) {
        int w = W - j + (i - j);
        int wl = WL - j;
        p += pleft[j] * (w - wl) * inversew(w);
      }
      pleft[j] = p;
    }
  }
  vector<MR<int, long long, 998244353> > ans(N);
  solve(pics, wsum, ans, 0, cut, pleft, -1);
  reverse(begin(pleft), end(pleft));
  solve(pics, wsum, ans, cut, N, pleft, 1);
  for (int i = 0; i < N; i++) cout << ans[i] << '\n';
  return 0;
}
