package main
import (
"bufio"
"io"
"os"
"strconv"
)
const MOD int64 = 998244353
const CAP int64 = 1000000000
func main() {
data, _ := io.ReadAll(os.Stdin)
pos := 0
nextInt := func() int64 {
for pos < len(data) && (data[pos] < '0' || data[pos] > '9') {
pos++
}
var v int64
for pos < len(data) && data[pos] >= '0' && data[pos] <= '9' {
v = v*10 + int64(data[pos]-'0')
pos++
}
return v
}
n := int(nextInt())
typ := make([]int, n+1)
val := make([]int64, n+1)
for i := 1; i <= n; i++ {
t := int(nextInt())
typ[i] = t
if t != 3 {
val[i] = nextInt()
}
}
pow2 := make([]int64, n+1)
pow2[0] = 1
for i := 1; i <= n; i++ {
pow2[i] = (pow2[i-1] * 2) % MOD
}
pref := make([]int64, n+1)
for i := 1; i <= n; i++ {
switch typ[i] {
case 1:
pref[i] = pref[i-1]
case 2:
s := pref[i-1] + val[i]
if s > CAP {
s = CAP
}
pref[i] = s
case 3:
s := pref[i-1] * 2
if s > CAP {
s = CAP
}
pref[i] = s
}
}
countSubsets := func(weights []int64, limit int64) int64 {
if limit < 0 {
return 0
}
var cnt int64
m := len(weights)
for i, w := range weights {
if limit >= w {
cnt += int64(1) << uint(m-i-1)
limit -= w
}
}
return cnt + 1
}
var ans int64
var suffixDamage int64
zeroRepeats := 0
weights := make([]int64, 0, 32)
for i := n; i >= 1; i-- {
if typ[i] == 1 {
limit := val[i] - 1 - suffixDamage
if limit >= 0 {
c := countSubsets(weights, limit) % MOD
ans = (ans + c*pow2[zeroRepeats]) % MOD
}
}
switch typ[i] {
case 2:
suffixDamage += val[i]
if suffixDamage > CAP {
suffixDamage = CAP
}
case 3:
t := pref[i-1]
if t == 0 {
zeroRepeats++
} else if t < CAP {
weights = append(weights, t)
}
}
}
out := bufio.NewWriterSize(os.Stdout, 1<<20)
out.WriteString(strconv.FormatInt(ans%MOD, 10))
out.Flush()
}