/*
hdu 4027 單點更新,每次更新到最底層
1、剪枝,因為每次都是減少到根号,是以小于等于1就不用再更新了
*/
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<set>
#include<queue>
using namespace std;
#define ll long long
ll tree[400005];
int cnt[400005];
int cas=1;
void pushup(int num)
{
tree[num]=tree[num*2]+tree[num*2+1];
cnt[num]=cnt[num*2]&&cnt[num*2+1];
}
void build(int L,int R,int num)
{
if(L==R)
{
scanf("%lld",&tree[num]);
if(tree[num]<=1)
cnt[num]=1;
return;
}
int mid=(L+R)/2;
build(L,mid,2*num);
build(mid+1,R,2*num+1);
pushup(num);
}
void update(int L,int R,int left,int right,int num)
{
if(left==right)
{
tree[num]=sqrt(tree[num]);
if(tree[num]<=1)
cnt[num]=1;
return;
}
int mid=(left+right)/2;
if(L<=mid&&!cnt[2*num])update(L,R,left,mid,2*num);
if(R>mid&&!cnt[2*num+1])update(L,R,mid+1,right,2*num+1);
pushup(num);
}
ll query(int L,int R,int left,int right,int num)
{
ll ans=0;
if(L<=left&&R>=right)
{
return tree[num];
}
int mid=(left+right)/2;
if(L<=mid)ans+=query(L,R,left,mid,num*2);
if(R>mid)ans+=query(L,R,mid+1,right,num*2+1);
return ans;
}
int main()
{
std::ios::sync_with_stdio(false);
int n,q,c,L,R,i;
while(~scanf("%d",&n))
{
memset(cnt,0,sizeof(cnt));
memset(tree,0,sizeof(tree));
build(1,n,1);
scanf("%d",&q);
printf("Case #%d:\n",cas++);
for(i=0;i<q;i++)
{
scanf("%d %d %d",&c,&L,&R);
if(L>R)swap(L,R);
if(c)printf("%lld\n",query(L,R,1,n,1));
else
update(L,R,1,n,1);
}
printf("\n");
}
return 0;
}