#include #include #include using namespace std; using ll = long long; using mint = atcoder::modint998244353; const int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97}; struct S{ mint val; int siz; }; struct F{ mint add; ll set; }; S op(S a, S b){ return {a.val + b.val, a.siz + b.siz}; } S e(){ return {0, 0}; } S mp(F f, S x){ if(f.set == -1){ return {x.val + x.siz * f.add, x.siz}; } return {(mint)f.set * x.siz, x.siz}; } F cm(F f, F g){ if(f.set == -1){ return {f.add + g.add, g.set}; } return {0, f.set}; } F id(){ return {0, -1}; } using segtree = atcoder::lazy_segtree; int N, Q; int main(void){ ios::sync_with_stdio(false); cin.tie(nullptr); cin >> N; vector> cnt(30, vector(N, {0, 1})); for(int i = 0;i < N;i++){ ll a; cin >> a; int id = 0; for(int p : primes){ while(a % p == 0){ a /= p; cnt[id][i].val++; } id++; } } vector seg(30); for(int i = 0;i < 25;i++){ seg[i] = segtree(cnt[i]); } cin >> Q; while(Q--){ ll t, l, r, x; cin >> t >> l >> r >> x; l--; if(t == 1){ int id = 0; for(int p : primes){ int num = 0; while(x % p == 0){ x /= p; num++; } seg[id].apply(l, r, {0, num}); id++; } }else if(t == 2){ int id = 0; for(int p : primes){ int num = 0; while(x % p == 0){ x /= p; num++; } seg[id].apply(l, r, {num, -1}); id++; } }else{ mint ans = 1; int id = 0; for(int p : primes){ if(p > x)break; ans *= seg[id].prod(l, r).val + 1; id++; } cout << ans.val() << endl; } } return 0; }