Problem:
Score : 100 points

Problem Statement

You are given two integer arrays a_0, a_1, ..., a_{N - 1} and b_0, b_1, ..., b_{M - 1}. Calculate the array c_0, c_1, ..., c_{(N - 1) + (M - 1)}, defined by c_i = \sum_{j = 0}^i a_j b_{i - j} \bmod 998244353.

Constraints

1 \leq N, M \leq 524288

0 \leq a_i, b_i < 998244353

All values in Input are integer.

Input

Input is given from Standard Input in the following format:

N M
a_0 a_1 ... a_{N-1}
b_0 b_1 ... b_{M-1}

Output

Print the answer in the following format:

c_0 c_1 ... c_{(N - 1) + (M - 1)}

Sample Input 1

4 5
1 2 3 4
5 6 7 8 9

Sample Output 1

5 16 34 60 70 70 59 36

Sample Input 2

1 1
10000000
10000000

Sample Output 2

871938225

Solution in Ruby (2.7.1) (judge verdict: Wrong Answer)

require "fiddle/import"
module GMP
	extend Fiddle::Importer
	dlload "libgmp.so"

	MPZStruct = struct [
		"int mp_alloc",
		"int mp_size",
		"unsigned long *mp_d"]

	extern "void __gmpz_init(void *)"
	extern "void __gmpz_clear(void *)"

	extern "void __gmpz_set_ui(void *, unsigned long)"
	extern "unsigned long __gmpz_get_ui(void *)"

	extern "void __gmpz_import(void *rop, size_t count, int order, size_t size, int endian, size_t nails, void *op)"
	extern "void *__gmpz_export(void *rop, size_t *count, int order, size_t size, int endian, size_t nails, void *op)"

	extern "void __gmpz_mul(void *, void *, void *)"

	class MPZ
		attr_reader :z

		def initialize
			@z = MPZStruct.malloc
			GMP.__gmpz_init @z
		end

		def import_u64_array(array)
			s = Fiddle::Pointer[array.pack("Q*")]
			GMP.__gmpz_import @z, array.size, 1, 8, 0, 0, s
		end

		def export_u64_array(size)
			c = Fiddle::Pointer.malloc(4)
			s = GMP.__gmpz_export nil, c, 1, 8, 0, 0, @z
			n = c.to_s(4).unpack("L")[0]
			s.to_s(8 * n.to_i).unpack("Q*")
		end

		def get_u32
			GMP.__gmpz_get_ui @z
		end

		def set_u32(u32)
			GMP.__gmpz_set_ui @z, u32
		end

		def mul(a, b)
			GMP.__gmpz_mul @z, a.z, b.z
		end
	end
end

n, m = gets.split.map &:to_i
as = gets.split.flat_map { |s| [0, 0, 0, s.to_i] }
bs = gets.split.flat_map { |s| [0, 0, 0, s.to_i] }

a = GMP::MPZ.new
a.import_u64_array(as)

b = GMP::MPZ.new
b.import_u64_array(bs)

a.mul a, b

r = a.export_u64_array(n + m + 2)
puts r.each_slice(4).map { |(x, y)| ((y || 0) << 64 | x) % 998244353 }.join(" ")