#include<cstdio>
#define mod 19961993
#define N 100001
struct node
{
int l,r;
long long val;
}tr[2][N*4];
int n,op,opl,opr;
int prime[61],cnt;
bool v[301];
long long bit[61],ans,tmp,inv[300];
void pre()
{
inv[1]=1;
for(int i=2;i<=281;i++)
{
inv[i]=-mod/i*inv[mod%i]%mod;
if(!v[i]) prime[++cnt]=i;
for(int j=1;j<=cnt;j++)
{
if(i*prime[j]>281) break;
v[i*prime[j]]=1;
if(i%prime[j]==0) break;
}
}
bit[1]=1;
for(int i=2;i<=60;i++) bit[i]=bit[i-1]<<1;
}
struct TREE
{
void init(int k,int val)
{
tr[0][k].val=val;
tr[1][k].val=0;
for(int i=1;i<=60;i++)
if(val%prime[i]==0) tr[1][k].val+=bit[i];
}
void up(int k)
{
tr[0][k].val=tr[0][k<<1].val*tr[0][k<<1|1].val%mod;
tr[1][k].val=tr[1][k<<1].val|tr[1][k<<1|1].val;
}
void build(int k,int l,int r)
{
tr[0][k].l=l; tr[0][k].r=r;
if(l==r)
{
init(k,3);
return;
}
int mid=l+r>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
up(k);
}
void query(int k)
{
if(tr[0][k].l>=opl&&tr[0][k].r<=opr)
{
ans=ans*tr[0][k].val%mod;
tmp|=tr[1][k].val;
return;
}
int mid=tr[0][k].l+tr[0][k].r>>1;
if(opl<=mid) query(k<<1);
if(opr>mid) query(k<<1|1);
}
void solve()
{
ans=1; tmp=0;
query(1);
for(int i=1;i<=60;i++)
if(tmp&bit[i]) ans=ans*(prime[i]-1)%mod*inv[prime[i]]%mod;
ans=(ans+mod)%mod;
printf("%d\n",ans);
}
void change(int k)
{
if(tr[0][k].l==tr[0][k].r)
{
init(k,opr);
return;
}
int mid=tr[0][k].l+tr[0][k].r>>1;
if(opl<=mid) change(k<<1);
else change(k<<1|1);
up(k);
}
}Tree;
int main()
{
pre();
Tree.build(1,1,100000);
scanf("%d",&n);
while(n--)
{
scanf("%d%d%d",&op,&opl,&opr);
if(!op) Tree.solve();
else Tree.change(1);
//printf("%I64d %I64d\n",tr[0][1].val,tr[1][1].val);
}
}