/*
hihocoder1586 线段树(裸)
实现一个数据结构,有如下操作:
1.询问[l,r]内ai*aj的最小值(i可以等于j)
2.修改某个点ai的值
17北京网络赛的题目,现场逗比写了四颗线段树分别维护正负数的最大最小值,两百行跪。
其实没有这么复杂,选择乘积的乘数时可以选同一个数,所以如果区间最小值为正,那么答案就是它的平方。
如果区间最小值为负,那么我们需要知道区间最大值。如果此时区间最大值为正,答案即为这两数的乘积。否则,为区间最大值的平方。
这个方法就是把模板打两遍。
至于用用节点保存每个区间最大最小正负值。。。。太复杂,尤其是要考虑区间内到底有没有正数或负数时。。。
写题前尽量先估算好难易程度,不要着急上手
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <cmath>
#include <algorithm>
#include <map>
#include <set>
#define ll long long
#define fr(i,a,b) for(int i=a;i<=b;i++)
#define frr(i,a,b) for(int i=a;i>=b;i--)
#define ms(a,b) memset(a,b,sizeof(a))
#define scfd(a) scanf("%d",a)
#define scflf(a) scanf("%lf",a)
#define scfs(a) scanf("%s",a)
#define ptfd(a) printf("%d\n",a)
#define ptfs(a) printf("%s\n",a)
#define showd(a,b) printf(a"=%d\n",b)
#define showlf(a,b) printf(a"=%lf\n",b)
#define shows(a,b) printf(a"=%s\n",b)
#define mmcp(a,b) memcpy(a,b,sizeof(b))
#define pb(a) push_back(a)
using namespace std;
const int MAXN=200005;
const ll NEGINF=-999999ll;
const ll POSINF=999999ll;
ll stn_max[MAXN<<2],stn_min[MAXN<<2];
void push_up(int now){
stn_max[now]=max(stn_max[now<<1],stn_max[1+(now<<1)]);
stn_min[now]=min(stn_min[now<<1],stn_min[1+(now<<1)]);
}
void update(int now,int l,int r,int p,ll d){
if(l==r-1){
stn_max[now]=stn_min[now]=d;
}
else{
int mid=(l+r)/2;
if(p<mid)
update(now<<1,l,mid,p,d);
else
update(1+(now<<1),mid,r,p,d);
push_up(now);
}
}
ll find_max(int now,int l,int r,int tl,int tr){
if(l>=tl&&r<=tr)
return stn_max[now];
int mid=(l+r)/2;
ll ans=NEGINF;
if(tl<mid)
ans=max(ans,find_max(now<<1,l,mid,tl,tr));
if(tr>mid)
ans=max(ans,find_max(1+(now<<1),mid,r,tl,tr));
return ans;
}
ll find_min(int now,int l,int r,int tl,int tr){
if(l>=tl&&r<=tr){
return stn_min[now];
}
int mid=(l+r)/2;
ll ans=POSINF;
if(tl<mid)
ans=min(ans,find_min(now<<1,l,mid,tl,tr));
if(tr>mid)
ans=min(ans,find_min((now<<1)+1,mid,r,tl,tr));
return ans;
}
int cases,k;
void init(){
fr(i,0,MAXN-1){
stn_max[i]=NEGINF;
stn_min[i]=POSINF;
}
}
int main(){
scfd(&cases);
while(cases--){
init();
scfd(&k);
int n=1<<k;
fr(i,0,n-1){
ll t;
scanf("%lld",&t);
update(1,0,n,i,t);
}
int q;
scfd(&q);
while(q--){
int md;ll a,b;
scanf("%d%lld%lld",&md,&a,&b);
if(md==2)
update(1,0,n,(int)a,b);
else{
ll mx,mn;
mx=find_max(1,0,n,(int)a,(int)b+1);
mn=find_min(1,0,n,(int)a,(int)b+1);
if(mn>=0)
printf("%lld\n",mn*mn);
else{
if(mx>=0)
printf("%lld\n",mn*mx);
else
printf("%lld\n",mx*mx);
}
}
}
}
return 0;
}