#include<cstdio>
#include<math.h>
#include<cstring>
#include<algorithm>
using namespace std;
#define TP template<typename T>
#define TP_ template<typename T,typename ... T_>
TP void read(T &x)
{
x=0;int f=0;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())ch=='-'&&(f=1);
for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<1)+(x<<3)+(ch^48);
f&&(x=-x);
}
TP_ void read(T &x,T_&...y){read(x);read(y...);}
TP void write(T x){x<0&&(putchar('-'),x=-x);static int sta[35];int top=0;do{sta[++top]=x%10,x/=10;}while(x);while(top)putchar(sta[top--]^48);}
TP void writeln(const T x){write(x);puts("");}
TP void writesp(const T x){write(x);putchar(32);}
TP_ void writeln(const T x,T_ ...y){writesp(x);writeln(y...);}
using LL=long long;
constexpr int N=2e5+5;
constexpr int P=998244353;
struct trnode
{
int l,r,lc,rc;
LL sum,last;
}tr[N<<1];int trlen;
LL a[N];
int n,q;
#define lc tr[now].lc
#define rc tr[now].rc
void pushup(int now)
{
tr[now].sum=(tr[lc].sum+tr[rc].sum)%P;
}
void pushdown(int now)
{
if(tr[now].last)
{
tr[lc].last+=tr[now].last;
tr[rc].last+=tr[now].last;
tr[now].last=0;
}
}
void build(int l,int r)
{
int now=++trlen;
tr[now]={l,r,0,0,0,0};
if(l==r)tr[now].sum=a[l];
else
{
int mid=(r+l)>>1;
lc=trlen+1;build(l,mid);
rc=trlen+1;build(mid+1,r);
pushup(now);
}
}
void modify(int now,int l,int r,int c)
{
if(tr[now].sum==(tr[now].r-tr[now].l+1))return ;//区间全为一,不需要开方和平方
if(l<=tr[now].l&&tr[now].r<=r&&tr[now].last+c>=0)
{
tr[now].last+=c;//这个区间平方 次数加1或减一
return ;
}
if(tr[now].l==tr[now].r)//没有平方了就直接开方
{
tr[now].sum=sqrt(tr[now].sum);
return ;
}
pushdown(now);
int mid=(tr[now].r+tr[now].l)>>1;
if(l<=mid)
modify(lc,l,r,c);
if(r>=mid+1)
modify(rc,l,r,c);
pushup(now);
}
LL qpow(LL a,LL b,LL p)
{
LL ans=1%p;a%=p;
for(;b;b>>=1)
{
if(b&1)
ans=ans*a%p;
a=a*a%p;
}
return ans;
}
void calc(int now)//与上段函数同理
{
if(tr[now].sum==(tr[now].r-tr[now].l+1))return ;
if(tr[now].l==tr[now].r)
{
tr[now].sum=qpow(tr[now].sum,qpow(2,tr[now].last,P-1),P);
return ;
}
pushdown(now);
calc(lc);
calc(rc);
pushup(now);
}
int main()
{
read(n,q);
for(int i=1;i<=n;i++)
read(a[i]);
build(1,n);
while(q--)//时间复杂度瓶颈在这里的修改
{
int op,l,r;read(op,l,r);
if(op==1)
modify(1,l,r,-1);//开方
else
modify(1,l,r,1);//平方
}
calc(1);//最终计算
writeln(tr[1].sum);
return 0;
}