1 #include<cstdio>
2 #include<iostream>
3 #include<cmath>
4 #include<cstring>
5 #include<algorithm>
6 using namespace std;
7 char ch;
8 bool ok;
9 void read(int &x){
10 for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
11 for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
12 if (ok) x=-x;
13 }
14 const int maxn=150005;
15 int n,m,v,op,a,b,anc[maxn],bel[maxn];
16 int find(int x){return anc[x]==x?x:anc[x]=find(anc[x]);}
17 int find_(int x){return bel[x]==x?x:bel[x]=find_(bel[x]);}
18 struct lct{
19 int son[maxn][2],fa[maxn],val[maxn],tot[maxn],sum[maxn],rev[maxn];
20 int wh[maxn];
21 void reverse(int x){
22 if (x){
23 rev[x]^=1;
24 if (wh[x]!=2) wh[x]^=1;
25 }
26 }
27 void pushdown(int x){if (rev[x]) swap(son[x][0],son[x][1]),reverse(son[x][0]),reverse(son[x][1]),rev[x]=0;}
28 void relax(int x){if (wh[x]!=2) relax(fa[x]); pushdown(x);}
29 void update(int x){
30 sum[x]=tot[x];
31 /*if (son[x][0])*/ sum[x]+=sum[son[x][0]];
32 /*if (son[x][1])*/ sum[x]+=sum[son[x][1]];
33 }
34 void rotate(int x){
35 int y=fa[x],z=fa[y],d=wh[x],dd=wh[y];
36 fa[son[x][d^1]]=y,son[y][d]=son[x][d^1],wh[son[x][d^1]]=d,fa[x]=fa[y];
37 if (dd!=2) son[z][dd]=x;
38 fa[y]=x,son[x][d^1]=y,update(y),update(x),wh[y]=d^1,wh[x]=dd;
39 }
40 void splay(int x){
41 relax(x);
42 while (wh[x]!=2){
43 if (wh[fa[x]]==2) rotate(x);
44 else if (wh[x]==wh[fa[x]]) rotate(fa[x]),rotate(x);
45 else rotate(x),rotate(x);
46 }
47 }
48 void access(int x){
49 for (int p=0;x;fa[x]=find(fa[x]),x=fa[x]){
50 splay(x);
51 if (son[x][1]) wh[son[x][1]]=2;
52 if (p) wh[p]=1;
53 son[x][1]=p,update(p=x);
54 }
55 }
56 void make_root(int x){access(x),splay(x),reverse(x);}
57 void link(int x,int y){make_root(x),fa[x]=y;}
58 int query(int x,int y){
59 x=find(x),y=find(y);
60 make_root(x),access(y),splay(y);
61 return sum[y];
62 }
63 void merge(int x,int y){
64 anc[x]=y,pushdown(x);
65 if (x!=y) tot[y]+=tot[x];
66 if (son[x][0]) merge(son[x][0],y);
67 if (son[x][1]) merge(son[x][1],y);
68 }
69 void build(int x,int y){
70 x=find(x),y=find(y);
71 int tx=find_(x),ty=find_(y);
72 if (tx==ty) make_root(x),access(y),splay(y),merge(y,y);
73 else link(x,y),bel[tx]=ty;
74 }
75 void modify(int x,int v){
76 int y=find(x);
77 make_root(y),tot[y]-=val[x],val[x]=v,tot[y]+=val[x],update(y);
78 }
79 }T;
80 int main(){
81 read(n),read(m);
82 for (int i=1;i<=n;i++) anc[i]=i;
83 for (int i=1;i<=n;i++) bel[i]=i;
84 for (int i=1;i<=n;i++) read(v),T.wh[i]=2,T.modify(i,v);
85 for (int i=1;i<=m;i++){
86 read(op),read(a),read(b);
87 if (op==1) T.build(a,b);
88 else if (op==2) T.modify(a,b);
89 else if (op==3){
90 if (find_(a)==find_(b)) printf("%d\n",T.query(a,b));
91 else puts("-1");
92 }
93 }
94 return 0;
95 }