import core.stdc.stdio;
import std.typecons;
import std.typetuple;
import std.algorithm;

alias TypeTuple tie;

struct Node{
	Node* l,r,p;
	int s,v,m;
	void Update(){
		s=1;
		m=v;
		if(l !is null){
			m=min(m,l.m);
			s+=l.s;
		}
		if(r !is null){
			m=min(m,r.m);
			s+=r.s;
		}
	}
	int Pos(){
		if(p!is null&&p.l==&this) return -1;
		if(p!is null&&p.r==&this) return 1;
		return 0;
	}
	void Rotate(){
		Node* q=p,c;
		if(Pos==1){
			c=l;
			l=p;
			p.r=c;
		}else{
			c=r;
			r=p;
			p.l=c;
		}
		if(c!is null) c.p=p;
		p=p.p;
		q.p=&this;
		if(p!is null&&p.l==q) p.l=&this;
		if(p!is null&&p.r==q) p.r=&this;
		q.Update;
		Update;
	}
	void Splay(){
		while(p){
			int a=Pos*p.Pos;
			if(!a)
				Rotate;
			else if(a==1){
				p.Rotate;
				Rotate;
			}else{
				Rotate;
				Rotate;
			}
		}
	}
	Node* Idx(int i){
		int ls=l is null?0:l.s;
		if(i==ls){
			Splay();
			return &this;
		}else if(i<ls)
			return l.Idx(i);
		else
			return r.Idx(i-ls-1);
	}
}

auto Split(Node* x,bool con){
	x.Splay;
	if(con){
		Node* l=x.l;
		if(l !is null){
			l.p=null;
			x.l=null;
			x.Update;
		}
		return tuple(l,x);
	}else{
		Node* r=x.r;
		if(r !is null){
			r.p=null;
			x.r=null;
			x.Update;
		}
		return tuple(x,r);
	}
}

Node* Merge(Node* a,Node* b){
	if(a is null) return b;
	if(b is null) return a;
	b.Splay;
	while(b.l !is null) b=b.l;
	b.Splay;
	a.Splay;
	b.l=a;
	a.p=b;
	b.Update;
	return b;
}

void main(){
	int n,q;
	scanf("%d%d",&n,&q);
	Node[] ns=new Node[n];
	foreach(i;0..n){
		scanf("%d",&ns[i].v);
		if(i){
			ns[i].l=&ns[i-1];
			ns[i-1].p=&ns[i];
		}
		ns[i].Update;
	}
	Node* Idx(int i){
		ns[0].Splay;
		return ns[0].Idx(i);
	}
	foreach(_;0..q){
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		Node* t1,t2,t3,t4;
		if(x==0){
			t3=Idx(z);
			tie!(t2,t4)=Split(t3,false);
			tie!(t2,t3)=Split(t3,true);
			t2=Idx(y);
			tie!(t1,t2)=Split(t2,true);
			t1.Merge(t3).Merge(t2).Merge(t4);
		}else if(x==1){
			tie!(t2,t3)=Split(Idx(z),false);
			tie!(t1,t2)=Split(Idx(y),true);
			printf("%d\n",t2.m);
			t1.Merge(t2).Merge(t3);
		}else if(x==2){
			tie!(t2,t3)=Split(Idx(y),false);
			tie!(t1,t2)=Split(Idx(y),true);
			t2.v=z;
			t2.Update;
			t1.Merge(t2).Merge(t3);
		}
	}
}