#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define int long long
using namespace std;
const int N = 1e5 + 10;
inline int read(){
int x=0,f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
for(; isdigit(ch);ch=getchar()) x=(x<<3)+(x<<1)+ch-'0';
return x*f;
}
int n,m;
int a[N];
struct node{
int l,r;
int sum,mx;
}tree[N<<2];
int push_up(int p){
tree[p].sum = tree[p<<1].sum + tree[p<<1|1].sum;
tree[p].mx = max(tree[p<<1].mx , tree[p<<1|1].mx);
}
inline void build(int p,int l,int r){
tree[p].l = l , tree[p].r = r;
if(l == r){
tree[p].sum = tree[p].mx = a[l];
return;
}
int mid = l + r >> 1;
build(p<<1,l,mid); build(p<<1|1,mid+1,r);
push_up(p);
}
inline void modify(int p,int l,int r){
if(tree[p].l == tree[p].r){
tree[p].sum = sqrt(tree[p].sum);
tree[p].mx = sqrt(tree[p].mx);
return;
}
int mid = tree[p].l + tree[p].r >> 1;
if(l <= mid && tree[p<<1].mx > 1) modify(p<<1,l,mid);
if(r > mid && tree[p<<1|1].mx > 1) modify(p<<1|1,mid+1,r);
push_up(p);
}
inline int query(int p,int l,int r){
int res = 0;
if(tree[p].l >= l && tree[p].r <= r) return tree[p].sum;
int mid = tree[p].l + tree[p].r >> 1;
if(l <= mid) res += query(p<<1,l,r);
if(r > mid) res += query(p<<1|1,l,r);
return res;
}
signed main(){
int cnt = 0;
while(~scanf("%lld",&n)){
cnt++;
printf("Case #%d\n",cnt);
for(int i=1;i<=n;i++){
a[i] = read();
}
build(1,1,n);
m = read();
for(int i=1;i<=m;i++){
int opt = read() , l = read() , r = read();
if(l > r) swap(l,r);
if(opt == 0){
modify(1,l,r);
}
else{
printf("%lld\n",query(1,l,r));
}
}
printf("\n");
}
return 0;
}