#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>

using namespace std;
#define int long long
#define ll long long
#define rt register int
#define reep(i,x,y) for(rt i=(x);i<(y);++i)
#define per(i,x,y) for(rt i=(x);i>=(y);--i)
#define rep(i,x,y) for(rt i=(x);i<=(y);++i)
#define travel(i,x) for(rt i=h[x];i;i=pre[i])
namespace fast_IO {
    inline char read() {
        //return getchar();
        static const int IN_LEN = 5000000;
        static char buf[IN_LEN], *s, *t;
        if (s == t) {
            t = (s = buf) + fread(buf, 1, IN_LEN, stdin);
            if (s == t) return -1;
        }
        return *s++;
    }
    template<class T>
    inline void read(T &x) {
        static bool iosig;
        static char c;
        for (iosig = false, c = read(); !isdigit(c); c = read()) {
            if (c == '-') iosig = true;
            if (c == -1) return;
        }
        for (x = 0; isdigit(c); c = read())
            x = ((x + (x << 2)) << 1) + (c ^ '0');
        if (iosig) x = -x;
    }
    const int OUT_LEN = 5000000;
    char obuf[OUT_LEN], *ooh = obuf;
    inline void print(char c) {
        if (ooh == obuf + OUT_LEN) fwrite(obuf, 1, OUT_LEN, stdout), ooh = obuf;
        *ooh++ = c;
    }
    template<class T>
    inline void print(T x) {
        static int buf[30], cnt;
        if (x == 0) {
            print('0');
        }
        else {
            if (x < 0) print('-'), x = -x;
            for (cnt = 0; x; x /= 10) buf[++cnt] = x % 10 + 48;
            while (cnt) print((char)buf[cnt--]);
        }
    }
    inline void flush() {
        fwrite(obuf, 1, ooh - obuf, stdout);
    }
}
using namespace fast_IO;
const int MAXN = 100100;
int n, m, a[MAXN], cnt;
struct node {
    int left, right, s, Max;
    node *ch[2];
}pool[MAXN * 3], *root;
inline void pushup(node *r) {
	r->s = r->ch[0]->s + r->ch[1]->s;
	r->Max = max(r->ch[0]->Max, r->ch[1]->Max);
}
inline void build(node *r, int left, int right) {
	r->left = left, r->right = right;
	if(left == right) {
		r->s = r->Max = a[left];
		return ;
	}
	node *lson = &pool[++cnt], *rson = &pool[++cnt];
	int mid = (left + right) / 2;
	r->ch[0] = lson, r->ch[1] = rson;
	build(lson, left, mid), build(rson, mid + 1, right);
	pushup(r);
}
inline void update(node *r, int pos, int x) {
	if(r->left == pos && r->left == r->right) {
		r->Max = r->s = x;
		return ;
	}
	int mid = (r->left + r->right) / 2;
	if(pos <= mid) update(r->ch[0], pos, x);
	else update(r->ch[1], pos, x);
	pushup(r);
}
inline void Mod(node *r, int left, int right, int p) {
	if(r->Max < p) return ;
	if(r->left == r->right) {
		r->s %= p; r->Max %= p;
		return ;
	}
	if(r->ch[0]->right >= right) Mod(r->ch[0], left, right, p);
	else if(r->ch[1]->left <= left) Mod(r->ch[1], left, right, p);
	else Mod(r->ch[0], left, r->ch[0]->right, p),
	     Mod(r->ch[1], r->ch[1]->left, right, p);
	pushup(r);
}
inline int query(node *r, int left, int right) {
	if(r->left == left && r->right == right) return r->s;
	if(r->ch[0]->right >= right) return query(r->ch[0], left, right);
	else if(r->ch[1]->left <= left) return query(r->ch[1], left, right);
	else return query(r->ch[0], left, r->ch[0]->right)
	          + query(r->ch[1], r->ch[1]->left, right);
}
#undef int
int main()
{
    read(n), read(m);
    for(int i = 1; i <= n; i++) read(a[i]);
	build(root = &pool[0], 1, n);
	for(int i = 1; i <= m; i++) {
		int opt, l, r, p;
		read(opt), read(l), read(r);
		if(opt == 1) print(query(root, l, r)); print('\n');
		if(opt == 2) {
			read(p);
			Mod(root, l, r, p);
		}
		if(opt == 3) update(root, l, r);
	}
	flush();
 	return 0;
}


#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>

using namespace std;
#define int long long
const int MAXN = 100100;
int n, m, a[MAXN], cnt;
struct node {
    int left, right, s, Max;
    node *ch[2];
}pool[MAXN * 3], *root;
inline void pushup(node *r) {
	r->s = r->ch[0]->s + r->ch[1]->s;
	r->Max = max(r->ch[0]->Max, r->ch[1]->Max);
}
inline void build(node *r, int left, int right) {
	r->left = left, r->right = right;
	if(left == right) {
		r->s = r->Max = a[left];
		return ;
	}
	node *lson = &pool[++cnt], *rson = &pool[++cnt];
	int mid = (left + right) / 2;
	r->ch[0] = lson, r->ch[1] = rson;
	build(lson, left, mid), build(rson, mid + 1, right);
	pushup(r);
}
inline void update(node *r, int pos, int x) {
	if(r->left == pos && r->left == r->right) {
		r->Max = r->s = x;
		return ;
	}
	int mid = (r->left + r->right) / 2;
	if(pos <= mid) update(r->ch[0], pos, x);
	else update(r->ch[1], pos, x);
	pushup(r);
}
inline void Mod(node *r, int left, int right, int p) {
	if(r->Max < p) return ;
	if(r->left == r->right) {
		r->s %= p; r->Max %= p;
		return ;
	}
	if(r->ch[0]->right >= right) Mod(r->ch[0], left, right, p);
	else if(r->ch[1]->left <= left) Mod(r->ch[1], left, right, p);
	else Mod(r->ch[0], left, r->ch[0]->right, p),
	     Mod(r->ch[1], r->ch[1]->left, right, p);
	pushup(r);
}
inline int query(node *r, int left, int right) {
	if(r->left == left && r->right == right) return r->s;
	if(r->ch[0]->right >= right) return query(r->ch[0], left, right);
	else if(r->ch[1]->left <= left) return query(r->ch[1], left, right);
	else return query(r->ch[0], left, r->ch[0]->right)
	          + query(r->ch[1], r->ch[1]->left, right);
}
#undef int
int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) scanf("%lld", &a[i]);
	build(root = &pool[0], 1, n);
	for(int i = 1; i <= m; i++) {
		int opt, l, r, p;
		scanf("%d%d%d", &opt, &l, &r);
		if(opt == 1) printf("%lld\n", query(root, l, r));
		if(opt == 2) {
			scanf("%lld", &p);
			Mod(root, l, r, p);
		}
		if(opt == 3) update(root, l, r);
	}
 	return 0;
}


#pragma GCC optimize(2)
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>

using namespace std;
#define int long long
#define ll long long
#define rt register int
#define reep(i,x,y) for(rt i=(x);i<(y);++i)
#define per(i,x,y) for(rt i=(x);i>=(y);--i)
#define rep(i,x,y) for(rt i=(x);i<=(y);++i)
#define travel(i,x) for(rt i=h[x];i;i=pre[i])
namespace fast_IO {
    inline char read() {
        //return getchar();
        static const int IN_LEN = 5000000;
        static char buf[IN_LEN], *s, *t;
        if (s == t) {
            t = (s = buf) + fread(buf, 1, IN_LEN, stdin);
            if (s == t) return -1;
        }
        return *s++;
    }
    template<class T>
    inline void read(T &x) {
        static bool iosig;
        static char c;
        for (iosig = false, c = read(); !isdigit(c); c = read()) {
            if (c == '-') iosig = true;
            if (c == -1) return;
        }
        for (x = 0; isdigit(c); c = read())
            x = ((x + (x << 2)) << 1) + (c ^ '0');
        if (iosig) x = -x;
    }
    const int OUT_LEN = 5000000;
    char obuf[OUT_LEN], *ooh = obuf;
    inline void print(char c) {
        if (ooh == obuf + OUT_LEN) fwrite(obuf, 1, OUT_LEN, stdout), ooh = obuf;
        *ooh++ = c;
    }
    template<class T>
    inline void print(T x) {
        static int buf[30], cnt;
        if (x == 0) {
            print('0');
        }
        else {
            if (x < 0) print('-'), x = -x;
            for (cnt = 0; x; x /= 10) buf[++cnt] = x % 10 + 48;
            while (cnt) print((char)buf[cnt--]);
        }
    }
    inline void flush() {
        fwrite(obuf, 1, ooh - obuf, stdout);
    }
}
using namespace fast_IO;
const int MAXN = 100100;
int n, m, a[MAXN], cnt;
struct node {
    int left, right, s, Max;
    node *ch[2];
}pool[MAXN * 3], *root;
inline void pushup(node *r) {
	r->s = r->ch[0]->s + r->ch[1]->s;
	r->Max = max(r->ch[0]->Max, r->ch[1]->Max);
}
inline void build(node *r, int left, int right) {
	r->left = left, r->right = right;
	if(left == right) {
		r->s = r->Max = a[left];
		return ;
	}
	node *lson = &pool[++cnt], *rson = &pool[++cnt];
	int mid = (left + right) / 2;
	r->ch[0] = lson, r->ch[1] = rson;
	build(lson, left, mid), build(rson, mid + 1, right);
	pushup(r);
}
inline void update(node *r, int pos, int x) {
	if(r->left == pos && r->left == r->right) {
		r->Max = r->s = x;
		return ;
	}
	int mid = (r->left + r->right) / 2;
	if(pos <= mid) update(r->ch[0], pos, x);
	else update(r->ch[1], pos, x);
	pushup(r);
}
inline void Mod(node *r, int left, int right, int p) {
	if(r->Max < p) return ;
	if(r->left == r->right) {
		r->s %= p; r->Max %= p;
		return ;
	}
	if(r->ch[0]->right >= right) Mod(r->ch[0], left, right, p);
	else if(r->ch[1]->left <= left) Mod(r->ch[1], left, right, p);
	else Mod(r->ch[0], left, r->ch[0]->right, p),
	     Mod(r->ch[1], r->ch[1]->left, right, p);
	pushup(r);
}
inline int query(node *r, int left, int right) {
	if(r->left == left && r->right == right) return r->s;
	if(r->ch[0]->right >= right) return query(r->ch[0], left, right);
	else if(r->ch[1]->left <= left) return query(r->ch[1], left, right);
	else return query(r->ch[0], left, r->ch[0]->right)
	          + query(r->ch[1], r->ch[1]->left, right);
}
#undef int
int main()
{
    read(n), read(m);
    for(int i = 1; i <= n; i++) read(a[i]);
	build(root = &pool[0], 1, n);
	for(int i = 1; i <= m; i++) {
		int opt, l, r, p;
		read(opt), read(l), read(r);
		if(opt == 1) print(query(root, l, r)); print('\n');
		if(opt == 2) {
			read(p);
			Mod(root, l, r, p);
		}
		if(opt == 3) update(root, l, r);
	}
	flush();
 	return 0;
}


#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>

using namespace std;
const int MAXN = 100100;
int n, m, a[MAXN], cnt;
struct node {
    int left, right, s, Max;
    node *ch[2];
}pool[MAXN * 3], *root;
inline void pushup(node *r) {
	r->s = r->ch[0]->s + r->ch[1]->s;
	r->Max = max(r->ch[0]->Max, r->ch[1]->Max);
}
inline void build(node *r, int left, int right) {
	r->left = left, r->right = right;
	if(left == right) {
		r->s = r->Max = a[left];
		return ;
	}
	node *lson = &pool[++cnt], *rson = &pool[++cnt];
	int mid = (left + right) / 2;
	r->ch[0] = lson, r->ch[1] = rson;
	build(lson, left, mid), build(rson, mid + 1, right);
	pushup(r);
}
inline void update(node *r, int pos, int x) {
	if(r->left == pos && r->left == r->right) {
		r->Max = r->s = x;
		return ;
	}
	int mid = (r->left + r->right) / 2;
	if(pos <= mid) update(r->ch[0], pos, x);
	else update(r->ch[1], pos, x);
	pushup(r);
}
inline void Mod(node *r, int left, int right, int p) {
	if(r->Max < p) return ;
	if(r->left == r->right) {
		r->s %= p; r->Max %= p;
		return ;
	}
	if(r->ch[0]->right >= right) Mod(r->ch[0], left, right, p);
	else if(r->ch[1]->left <= left) Mod(r->ch[1], left, right, p);
	else Mod(r->ch[0], left, r->ch[0]->right, p),
	     Mod(r->ch[1], r->ch[1]->left, right, p);
	pushup(r);
}
inline int query(node *r, int left, int right) {
	if(r->left == left && r->right == right) return r->s;
	if(r->ch[0]->right >= right) return query(r->ch[0], left, right);
	else if(r->ch[1]->left <= left) return query(r->ch[1], left, right);
	else return query(r->ch[0], left, r->ch[0]->right)
	          + query(r->ch[1], r->ch[1]->left, right);
}
int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
	build(root = &pool[0], 1, n);
	for(int i = 1; i <= m; i++) {
		int opt, l, r, p;
		scanf("%d%d%d", &opt, &l, &r);
		if(opt == 1) printf("%d\n", query(root, l, r));
		if(opt == 2) {
			scanf("%d", &p);
			Mod(root, l, r, p);
		}
		if(opt == 3) update(root, l, r);
	}
 	return 0;
}


///1085422276
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,127,sizeof(a));
#define inf 1000000007
#define mod 1000000007
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')f=-1;ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';ch=getchar();
    }return x*f;
}
//************************************************
const int maxn=100000+5;
int a[maxn],n,m,q;
struct ss{
  int  l,r;
  ll v,sum,tag;
}tr[maxn*5];
void build(int k,int s,int t)
{
    tr[k].l=s;tr[k].r=t;
    tr[k].v=0;tr[k].tag=0;tr[k].sum=0;
    if(s==t){
        tr[k].sum=a[s];
        tr[k].v=a[s];
        return ;
    }
    int mid=(s+t)>>1;
    build(k<<1,s,mid);
    build(k<<1|1,mid+1,t);
    tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
      tr[k].v=max(tr[k<<1].v,tr[k<<1|1].v);
}
ll ask(int k,int s,int t)
{
    if(tr[k].l==s&&tr[k].r==t){
        return tr[k].sum;
    }
    int mid=(tr[k].l+tr[k].r)>>1;
    ll ret=0;
    if(t<=mid)ret= ask(k<<1,s,t);
    else if(s>mid)ret= ask(k<<1|1,s,t);
    else {
        ret=(ask(k<<1,s,mid)+ask(k<<1|1,mid+1,t));
    } tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
    tr[k].v=max(tr[k<<1].v,tr[k<<1|1].v);
    return ret;
}
void modify(int k,int s,int t,ll c)
{
    if(tr[k].v<c)return ;
     if(tr[k].l==tr[k].r){
        tr[k].sum%=c;
        tr[k].v%=c;
        return ;
     }
    int mid=(tr[k].l+tr[k].r)>>1;
    if(t<=mid)modify(k<<1,s,t,c);
    else if(s>mid)modify(k<<1|1,s,t,c);
    else {
       modify(k<<1,s,mid,c);modify(k<<1|1,mid+1,t,c);
    }
     tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
     tr[k].v=max(tr[k<<1].v,tr[k<<1|1].v);
}
void update(int k,int x,int c)
{
    if(tr[k].l==x&&tr[k].r==x){
        tr[k].sum=c;
        tr[k].v=c;
        return;
    }
    int mid=(tr[k].l+tr[k].r)>>1;
    if(x<=mid)update(k<<1,x,c);
    else {
         update(k<<1|1,x,c);
    }
    tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
    tr[k].v=max(tr[k<<1].v,tr[k<<1|1].v);
}
int main(){

    n=read();m=read();
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }build(1,1,n);int x,y;ll c;
    for(int i=1;i<=m;i++){
        scanf("%d",&q);
        if(q==1){
            scanf("%d%d",&x,&y);
            printf("%I64d\n",ask(1,x,y));
        }
        else if(q==2){
            scanf("%d%d%I64d",&x,&y,&c);
            modify(1,x,y,c);
        }
        else {
            scanf("%d%d",&x,&y);
            update(1,x,y);
        }

    }
  return 0;
}


///1085422276
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,127,sizeof(a));
#define inf 1000000007
#define mod 1000000007
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')f=-1;ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';ch=getchar();
    }return x*f;
}
//************************************************
const int maxn=100000+5;
int a[maxn],n,m,q;
struct ss{
  int  l,r;
  ll v,sum,tag;
}tr[maxn*5];
void build(int k,int s,int t)
{
    tr[k].l=s;tr[k].r=t;
    tr[k].v=0;tr[k].tag=0;tr[k].sum=0;
    if(s==t){
        tr[k].sum=a[s];
        tr[k].v=a[s];
        return ;
    }
    int mid=(s+t)>>1;
    build(k<<1,s,mid);
    build(k<<1|1,mid+1,t);
    tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
      tr[k].v=max(tr[k<<1].v,tr[k<<1|1].v);
}
ll ask(int k,int s,int t)
{
    if(tr[k].l==s&&tr[k].r==t){
        return tr[k].sum;
    }
    int mid=(tr[k].l+tr[k].r)>>1;
    ll ret=0;
    if(t<=mid)ret= ask(k<<1,s,t);
    else if(s>mid)ret= ask(k<<1|1,s,t);
    else {
        ret=(ask(k<<1,s,mid)+ask(k<<1|1,mid+1,t));
    } tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
    return ret;
}
void modify(int k,int s,int t,ll c)
{
    if(tr[k].v<c)return ;
     if(tr[k].l==tr[k].r){
        tr[k].sum%=c;
        return ;
     }
    int mid=(tr[k].l+tr[k].r)>>1;
    if(t<=mid)modify(k<<1,s,t,c);
    else if(s>mid)modify(k<<1|1,s,t,c);
    else {
       modify(k<<1,s,mid,c);modify(k<<1|1,mid+1,t,c);
    }
     tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
}
void update(int k,int x,int c)
{
    if(tr[k].l==x&&tr[k].r==x){
        tr[k].sum=c;
        return;
    }
    int mid=(tr[k].l+tr[k].r)>>1;
    if(x<=mid)update(k<<1,x,c);
    else {
         update(k<<1|1,x,c);
    }
    tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
}
int main(){

    n=read();m=read();
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }build(1,1,n);int x,y;ll c;
    for(int i=1;i<=m;i++){
        scanf("%d",&q);
        if(q==1){
            scanf("%d%d",&x,&y);
            printf("%I64d\n",ask(1,x,y));
        }
        else if(q==2){
            scanf("%d%d%I64d",&x,&y,&c);
            modify(1,x,y,c);
        }
        else {
            scanf("%d%d",&x,&y);
            update(1,x,y);
        }

    }
  return 0;
}


///1085422276
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,127,sizeof(a));
#define inf 1000000007
#define mod 1000000007
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')f=-1;ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';ch=getchar();
    }return x*f;
}
//************************************************
const int maxn=100000+5;
int a[maxn],n,m,q;
struct ss{
  int  l,r;
  ll v,sum,tag;
}tr[maxn*5];
void pushdown(int k)
{
    if(tr[k].l==tr[k].r){
    tr[k].sum%=tr[k].tag;
    tr[k].tag=0;
        return ;
    }
    if(tr[k<<1].tag!=0) tr[k<<1].tag=min(tr[k<<1].tag, tr[k].tag);
        else
    tr[k<<1].tag=tr[k].tag;
   if(tr[k<<1|1].tag!=0) tr[k<<1|1].tag=min(tr[k<<1|1].tag, tr[k].tag);
        else
    tr[k<<1|1].tag=tr[k].tag;

    tr[k<<1].sum%=tr[k].tag;
    tr[k<<1|1].sum%=tr[k].tag;
    tr[k].tag=0;
}
void build(int k,int s,int t)
{
    tr[k].l=s;tr[k].r=t;
    tr[k].v=0;tr[k].tag=0;tr[k].sum=0;
    if(s==t){
        tr[k].sum=a[s];
        return ;
    }
    int mid=(s+t)>>1;
    build(k<<1,s,mid);
    build(k<<1|1,mid+1,t);
    tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
}
ll ask(int k,int s,int t)
{
   // if(tr[k].tag)pushdown(k);
    if(tr[k].l==s&&tr[k].r==t){
        return tr[k].sum;
    }
    int mid=(tr[k].l+tr[k].r)>>1;
    ll ret=0;
    if(t<=mid)ret= ask(k<<1,s,t);
    else if(s>mid)ret= ask(k<<1|1,s,t);
    else {
        ret=(ask(k<<1,s,mid)+ask(k<<1|1,mid+1,t));
    } tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
    return ret;
}
void modify(int k,int s,int t,ll c)
{
    // if(tr[k].tag)pushdown(k);
     if(tr[k].l==tr[k].r){
     //   tr[k].tag=c;
        tr[k].sum%=c;
        return ;
     }
    int mid=(tr[k].l+tr[k].r)>>1;
    if(t<=mid)modify(k<<1,s,t,c);
    else if(s>mid)modify(k<<1|1,s,t,c);
    else {
       modify(k<<1,s,mid,c);modify(k<<1|1,mid+1,t,c);
    }
     tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
}
void update(int k,int x,int c)
{
    //if(tr[k].tag)pushdown(k);
    if(tr[k].l==x&&tr[k].r==x){
        tr[k].sum=c;
        return;
    }
    int mid=(tr[k].l+tr[k].r)>>1;
    if(x<=mid)update(k<<1,x,c);
    else {
         update(k<<1|1,x,c);
    }
    tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
}
int main(){

    n=read();m=read();
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }build(1,1,n);int x,y;ll c;
    for(int i=1;i<=m;i++){
        scanf("%d",&q);
        if(q==1){
            scanf("%d%d",&x,&y);
            printf("%I64d\n",ask(1,x,y));
        }
        else if(q==2){
            scanf("%d%d%I64d",&x,&y,&c);
            modify(1,x,y,c);
        }
        else {
            scanf("%d%d",&x,&y);
            update(1,x,y);
        }

    }
  return 0;
}


///1085422276
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,127,sizeof(a));
#define inf 1000000007
#define mod 1000000007
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')f=-1;ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';ch=getchar();
    }return x*f;
}
//************************************************
const int maxn=100000+5;
int a[maxn],n,m,q;
struct ss{
  int  l,r;
  ll v,sum,tag;
}tr[maxn*5];
void build(int k,int s,int t)
{
    tr[k].l=s;tr[k].r=t;
    tr[k].v=0;tr[k].tag=0;tr[k].sum=0;
    if(s==t){
        tr[k].sum=a[s];
        tr[k].v=a[s];
        return ;
    }
    int mid=(s+t)>>1;
    build(k<<1,s,mid);
    build(k<<1|1,mid+1,t);
    tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
      tr[k].v=max(tr[k<<1].v,tr[k<<1|1].v);
}
ll ask(int k,int s,int t)
{
    if(tr[k].l==s&&tr[k].r==t){
        return tr[k].sum;
    }
    int mid=(tr[k].l+tr[k].r)>>1;
    ll ret=0;
    if(t<=mid)ret= ask(k<<1,s,t);
    else if(s>mid)ret= ask(k<<1|1,s,t);
    else {
        ret=(ask(k<<1,s,mid)+ask(k<<1|1,mid+1,t));
    } tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
    tr[k].v=max(tr[k<<1].v,tr[k<<1|1].v);
    return ret;
}
void modify(int k,int s,int t,int c)
{
    if(tr[k].v<c)return ;
     if(tr[k].l==tr[k].r){
        tr[k].sum%=c;
        tr[k].v%=c;
        return ;
     }
    int mid=(tr[k].l+tr[k].r)>>1;
    if(t<=mid)modify(k<<1,s,t,c);
    else if(s>mid)modify(k<<1|1,s,t,c);
    else {
       modify(k<<1,s,mid,c);modify(k<<1|1,mid+1,t,c);
    }
     tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
     tr[k].v=max(tr[k<<1].v,tr[k<<1|1].v);
}
void update(int k,int x,int c)
{
    if(tr[k].l==x&&tr[k].r==x){
        tr[k].sum=c;
        tr[k].v=c;
        return;
    }
    int mid=(tr[k].l+tr[k].r)>>1;
    if(x<=mid)update(k<<1,x,c);
    else {
         update(k<<1|1,x,c);
    }
    tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
    tr[k].v=max(tr[k<<1].v,tr[k<<1|1].v);
}
int main(){

    n=read();m=read();
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }build(1,1,n);int x,y;ll c;
    for(int i=1;i<=m;i++){
        scanf("%d",&q);
        if(q==1){
            scanf("%d%d",&x,&y);
            printf("%d\n",ask(1,x,y));
        }
        else if(q==2){
            scanf("%d%d%d",&x,&y,&c);
            modify(1,x,y,c);
        }
        else {
            scanf("%d%d",&x,&y);
            update(1,x,y);
        }

    }
  return 0;
}


///1085422276
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,127,sizeof(a));
#define inf 1000000007
#define mod 1000000007
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')f=-1;ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';ch=getchar();
    }return x*f;
}
//************************************************
const int maxn=100000+5;
int a[maxn],n,m,q;
struct ss{
  int  l,r;
  ll v,sum,tag;
}tr[maxn*5];
void build(int k,int s,int t)
{
    tr[k].l=s;tr[k].r=t;
    tr[k].v=0;tr[k].tag=0;tr[k].sum=0;
    if(s==t){
        tr[k].sum=a[s];
        tr[k].v=a[s];
        return ;
    }
    int mid=(s+t)>>1;
    build(k<<1,s,mid);
    build(k<<1|1,mid+1,t);
    tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
      tr[k].v=max(tr[k<<1].v,tr[k<<1|1].v);
}
ll ask(int k,int s,int t)
{
    if(tr[k].l==s&&tr[k].r==t){
        return tr[k].sum;
    }
    int mid=(tr[k].l+tr[k].r)>>1;
    ll ret=0;
    if(t<=mid)ret= ask(k<<1,s,t);
    else if(s>mid)ret= ask(k<<1|1,s,t);
    else {
        ret=(ask(k<<1,s,mid)+ask(k<<1|1,mid+1,t));
    } tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
    tr[k].v=max(tr[k<<1].v,tr[k<<1|1].v);
    return ret;
}
void modify(int k,int s,int t,ll c)
{
    if(tr[k].v<c)return ;
     if(tr[k].l==tr[k].r){
        tr[k].sum%=c;
        tr[k].v%=c;
        return ;
     }
    int mid=(tr[k].l+tr[k].r)>>1;
    if(t<=mid)modify(k<<1,s,t,c);
    else if(s>mid)modify(k<<1|1,s,t,c);
    else {
       modify(k<<1,s,mid,c);modify(k<<1|1,mid+1,t,c);
    }
     tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
     tr[k].v=max(tr[k<<1].v,tr[k<<1|1].v);
}
void update(int k,int x,int c)
{
    if(tr[k].l==x&&tr[k].r==x){
        tr[k].sum=c;
        tr[k].v=c;
        return;
    }
    int mid=(tr[k].l+tr[k].r)>>1;
    if(x<=mid)update(k<<1,x,c);
    else {
         update(k<<1|1,x,c);
    }
    tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
    tr[k].v=max(tr[k<<1].v,tr[k<<1|1].v);
}
int main(){

    n=read();m=read();
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }build(1,1,n);int x,y;ll c;
    for(int i=1;i<=m;i++){
        scanf("%d",&q);
        if(q==1){
            scanf("%d%d",&x,&y);
            printf("%I64d\n",ask(1,x,y));
        }
        else if(q==2){
            scanf("%d%d%d",&x,&y,&c);
            modify(1,x,y,c);
        }
        else {
            scanf("%d%d",&x,&y);
            update(1,x,y);
        }

    }
  return 0;
}


#include <bits/stdc++.h>
#define fr(i,a,b) for (int i = (a); i < (b); ++i)
#define st first
#define nd second
#define dbg(x) cout << #x << " " << x << endl
using namespace std;

const double eps = 1e-7;
const int inf = 0x3f3f3f3f;
typedef pair<int,int> ii;
typedef long long ll;
typedef vector<int> vi;

const int N = 100005;
int maxi[4*N], a[N], n;
ll tree[4*N];

void apply(int no, int L, int R, int i, int j, int x) {
    int nl = no<<1, nr = nl+1, mid = (L+R)>>1;
    if (maxi[no] < x) return;
    if (i > R || j < L) return;
    if (L == R) {
        a[L] %= x;
        tree[no] = maxi[no] = a[L];
        return;
    }
    apply(nl, L, mid, i, j, x);
    apply(nr, mid+1, R, i, j, x);
    maxi[no] = max(maxi[nl], maxi[nr]);
    tree[no] = tree[nl] + tree[nr];
}

void apply(int l, int r, int x) {
    apply(1,0,n-1,l,r,x);
}

void update(int no, int L, int R, int k, int x) {
    int nl = no<<1, nr = nl+1, mid = (L+R)>>1;
    if (L == R) {
        tree[no] = maxi[no] = a[L] = x;
        return;
    }
    if (k <= mid) update(nl, L, mid, k, x);
    else update(nr, mid+1, R, k, x);
    maxi[no] = max(maxi[nl], maxi[nr]);
    tree[no] = tree[nl] + tree[nr];
}

void update(int k, int x) { update(1,0,n-1,k,x); }

ll sum(int no, int L, int R, int i, int j) {
    int nl = no<<1, nr = nl+1, mid = (L+R)>>1;
    if (i > R || j < L) return 0;
    if (i <= L && R <= j) return tree[no];
    ll a = sum(nl, L, mid, i, j);
    ll b = sum(nr, mid+1, R, i, j);
    return a + b;
}

ll sum(int l, int r) { return sum(1,0,n-1,l,r); }

void build(int no, int L, int R) {
    if (L == R) {
        tree[no] = maxi[no] = a[L];
        return;
    }
    int nl = no<<1, nr = nl+1, mid = (L+R)>>1;
    build(nl,L,mid);
    build(nr,mid+1,R);
    tree[no] = tree[nl] + tree[nr];
    maxi[no] = max(maxi[nl], maxi[nr]);
}

int main() {
    int m; scanf("%d %d", &n, &m);
    fr(i,0,n) scanf("%d", &a[i]);
    build(1,0,n-1);
    while (m--) {
        int t; scanf("%d", &t);
        if (t == 1) {
            int l, r; scanf("%d %d", &l, &r); --l; --r;
            cout << sum(l,r) << endl;
        } else if (t == 2) {
            int l, r, x; scanf("%d %d %d", &l, &r, &x); --l; --r;
            apply(l,r,x);
        } else {
            int k, x; scanf("%d %d", &k, &x); --k;
            update(k,x);
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define fr(i,a,b) for (int i = (a); i < (b); ++i)
#define st first
#define nd second
#define dbg(x) cout << #x << " " << x << endl
using namespace std;

const double eps = 1e-7;
const int inf = 0x3f3f3f3f;
typedef pair<int,int> ii;
typedef long long ll;
typedef vector<int> vi;

const int N = 100005;
int tree[4*N], a[N], n;
vi lazy[4*N];

void apply(int no, int L, int R, int i, int j, int x) {
    int nl = no<<1, nr = nl+1, mid = (L+R)>>1;
    if (lazy[no].size()) {
        if (L != R) {
            fr(i,0,lazy[no].size()) {
                //tree[no] %= lazy[no][i];
                if (lazy[nl].empty() || lazy[nl][lazy[nl].size()-1] > lazy[no][i])
                    lazy[nl].push_back(lazy[no][i]);
                if (lazy[nr].empty() || lazy[nr][lazy[nr].size()-1] > lazy[no][i])
                    lazy[nr].push_back(lazy[no][i]);
            }
        } else fr(i,0,lazy[no].size()) tree[no] %= lazy[no][i];
        lazy[no].clear();
    }
    if (i > R || j < L) return;
    if (i <= L && R <= j) {
        if (L != R) {
            if (lazy[nl].empty() || lazy[nl][lazy[nl].size()-1] > x)
                lazy[nl].push_back(x);
            if (lazy[nr].empty() || lazy[nr][lazy[nr].size()-1] > x)
                lazy[nr].push_back(x);
        } else tree[no] %= x;
        if (L == R) return;
    }
    apply(nl, L, mid, i, j, x);
    apply(nr, mid+1, R, i, j, x);
    tree[no] = tree[nl] + tree[nr];
}

void apply(int l, int r, int x) {
    apply(1,0,n-1,l,r,x);
}

void update(int no, int L, int R, int k, int x) {
    int nl = no<<1, nr = nl+1, mid = (L+R)>>1;
    if (lazy[no].size()) {
        if (L != R) {
            fr(i,0,lazy[no].size()) {
                //tree[no] %= lazy[no][i];
                if (lazy[nl].empty() || lazy[nl][lazy[nl].size()-1] > lazy[no][i])
                    lazy[nl].push_back(lazy[no][i]);
                if (lazy[nr].empty() || lazy[nr][lazy[nr].size()-1] > lazy[no][i])
                    lazy[nr].push_back(lazy[no][i]);
            }
        } else fr(i,0,lazy[no].size()) tree[no] %= lazy[no][i];
        lazy[no].clear();
    }
    if (k < L || k > R) return;
    if (L == R) {
        tree[no] = a[L]; lazy[no].clear();
        return;
    }
    update(nl, L, mid, k, x);
    update(nr, mid+1, R, k, x);
    tree[no] = tree[nl] + tree[nr];
}

void update(int k, int x) { update(1,0,n-1,k,x); }

ll sum(int no, int L, int R, int i, int j) {
    int nl = no<<1, nr = nl+1, mid = (L+R)>>1;
    if (lazy[no].size()) {
        if (L != R) {
            fr(i,0,lazy[no].size()) {
                //tree[no] %= lazy[no][i];
                if (lazy[nl].empty() || lazy[nl][lazy[nl].size()-1] > lazy[no][i])
                    lazy[nl].push_back(lazy[no][i]);
                if (lazy[nr].empty() || lazy[nr][lazy[nr].size()-1] > lazy[no][i])
                    lazy[nr].push_back(lazy[no][i]);
            }
        } else fr(i,0,lazy[no].size()) tree[no] %= lazy[no][i];
        lazy[no].clear();
    }
    if (i > R || j < L) return 0;
    if (i <= L && R <= j) return tree[no];
    ll a = sum(nl, L, mid, i, j);
    ll b = sum(nr, mid+1, R, i, j);
    return a + b;
}

ll sum(int l, int r) { return sum(1,0,n-1,l,r); }

void build(int no, int L, int R) {
    if (L == R) {
        tree[no] = a[L]; return;
    }
    int nl = no<<1, nr = nl+1, mid = (L+R)>>1;
    build(nl,L,mid);
    build(nr,mid+1,R);
    tree[no] = tree[nl] + tree[nr];
}

int main() {
    int m; scanf("%d %d", &n, &m);
    fr(i,0,n) scanf("%d", &a[i]);
    build(1,0,n-1);
    while (m--) {
        int t; scanf("%d", &t);
        if (t == 1) {
            int l, r; scanf("%d %d", &l, &r); --l; --r;
            cout << sum(l,r) << endl;
        } else if (t == 2) {
            int l, r, x; scanf("%d %d %d", &l, &r, &x); --l; --r;
            apply(l,r,x);
        } else {
            int k, x; scanf("%d %d", &k, &x); --k;
            a[k] = x;
            update(k,x);
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define fr(i,a,b) for (int i = (a); i < (b); ++i)
#define st first
#define nd second
#define dbg(x) cout << #x << " " << x << endl
using namespace std;

const double eps = 1e-7;
const int inf = 0x3f3f3f3f;
typedef pair<int,int> ii;
typedef long long ll;
typedef vector<int> vi;

const int N = 100005;
int maxi[4*N], a[N], n;
ll tree[4*N];

void apply(int no, int L, int R, int i, int j, int x) {
    int nl = no<<1, nr = nl+1, mid = (L+R)>>1;
    if (maxi[no] < x) return;
    if (L == R) {
        a[L] %= x;
        tree[no] = maxi[no] = a[L];
        return;
    }
    if (i > R || j < L) return;
    apply(nl, L, mid, i, j, x);
    apply(nr, mid+1, R, i, j, x);
    maxi[no] = max(maxi[nl], maxi[nr]);
    tree[no] = tree[nl] + tree[nr];
}

void apply(int l, int r, int x) {
    apply(1,0,n-1,l,r,x);
}

void update(int no, int L, int R, int k, int x) {
    int nl = no<<1, nr = nl+1, mid = (L+R)>>1;
    if (L == R) {
        tree[no] = maxi[no] = a[L] = x;
        return;
    }
    if (k <= mid) update(nl, L, mid, k, x);
    else update(nr, mid+1, R, k, x);
    maxi[no] = max(maxi[nl], maxi[nr]);
    tree[no] = tree[nl] + tree[nr];
}

void update(int k, int x) { update(1,0,n-1,k,x); }

ll sum(int no, int L, int R, int i, int j) {
    int nl = no<<1, nr = nl+1, mid = (L+R)>>1;
    if (i > R || j < L) return 0;
    if (i <= L && R <= j) return tree[no];
    ll a = sum(nl, L, mid, i, j);
    ll b = sum(nr, mid+1, R, i, j);
    return a + b;
}

ll sum(int l, int r) { return sum(1,0,n-1,l,r); }

void build(int no, int L, int R) {
    if (L == R) {
        tree[no] = maxi[no] = a[L];
        return;
    }
    int nl = no<<1, nr = nl+1, mid = (L+R)>>1;
    build(nl,L,mid);
    build(nr,mid+1,R);
    tree[no] = tree[nl] + tree[nr];
    maxi[no] = max(maxi[nl], maxi[nr]);
}

int main() {
    int m; scanf("%d %d", &n, &m);
    fr(i,0,n) scanf("%d", &a[i]);
    build(1,0,n-1);
    while (m--) {
        int t; scanf("%d", &t);
        if (t == 1) {
            int l, r; scanf("%d %d", &l, &r); --l; --r;
            cout << sum(l,r) << endl;
        } else if (t == 2) {
            int l, r, x; scanf("%d %d %d", &l, &r, &x); --l; --r;
            apply(l,r,x);
        } else {
            int k, x; scanf("%d %d", &k, &x); --k;
            update(k,x);
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define fr(i,a,b) for (int i = (a); i < (b); ++i)
#define st first
#define nd second
#define dbg(x) cout << #x << " " << x << endl
using namespace std;

const double eps = 1e-7;
const int inf = 0x3f3f3f3f;
typedef pair<int,int> ii;
typedef long long ll;
typedef vector<int> vi;

const int N = 100005;
int maxi[4*N], a[N], n;
ll tree[4*N];

void apply(int no, int L, int R, int i, int j, int x) {
    int nl = no<<1, nr = nl+1, mid = (L+R)>>1;
    if (maxi[no] < x) return;
    if (L == R) {
        a[L] %= x;
        maxi[no] = tree[no] = a[L];
        return;
    }
    if (i > R || j < L) return;
    apply(nl, L, mid, i, j, x);
    apply(nr, mid+1, R, i, j, x);
    maxi[no] = max(maxi[nl], maxi[nr]);
    tree[no] = tree[nl] + tree[nr];
}

void apply(int l, int r, int x) {
    apply(1,0,n-1,l,r,x);
}

void update(int no, int L, int R, int k, int x) {
    int nl = no<<1, nr = nl+1, mid = (L+R)>>1;
    if (L == R) {
        maxi[no] = tree[no] = a[L] = x;
        return;
    }
    if (k <= mid) update(nl, L, mid, k, x);
    else update(nr, mid+1, R, k, x);
    maxi[no] = max(maxi[nl], maxi[nr]);
    tree[no] = tree[nl] + tree[nr];
}

void update(int k, int x) { update(1,0,n-1,k,x); }

ll sum(int no, int L, int R, int i, int j) {
    int nl = no<<1, nr = nl+1, mid = (L+R)>>1;
    if (i > R || j < L) return 0;
    if (i <= L && R <= j) return tree[no];
    ll a = sum(nl, L, mid, i, j);
    ll b = sum(nr, mid+1, R, i, j);
    return a + b;
}

ll sum(int l, int r) { return sum(1,0,n-1,l,r); }

void build(int no, int L, int R) {
    if (L == R) {
        tree[no] = maxi[no] = a[L];
        return;
    }
    int nl = no<<1, nr = nl+1, mid = (L+R)>>1;
    build(nl,L,mid);
    build(nr,mid+1,R);
    tree[no] = tree[nl] + tree[nr];
    maxi[no] = max(maxi[nl], maxi[nr]);
}

int main() {
    int m; scanf("%d %d", &n, &m);
    fr(i,0,n) scanf("%d", &a[i]);
    build(1,0,n-1);
    while (m--) {
        int t; scanf("%d", &t);
        if (t == 1) {
            int l, r; scanf("%d %d", &l, &r); --l; --r;
            cout << sum(l,r) << endl;
        } else if (t == 2) {
            int l, r, x; scanf("%d %d %d", &l, &r, &x); --l; --r;
            apply(l,r,x);
        } else {
            int k, x; scanf("%d %d", &k, &x); --k;
            update(k,x);
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define fr(i,a,b) for (int i = (a); i < (b); ++i)
#define st first
#define nd second
#define dbg(x) cout << #x << " " << x << endl
using namespace std;

const double eps = 1e-7;
const int inf = 0x3f3f3f3f;
typedef pair<int,int> ii;
typedef long long ll;
typedef vector<int> vi;

const int N = 100005;
int maxi[4*N], a[N], n;
ll tree[4*N];

void apply(int no, int L, int R, int i, int j, int x) {
    int nl = no<<1, nr = nl+1, mid = (L+R)>>1;
    if (L > R) return;
    if (maxi[no] < x) return;
    if (L == R) {
        a[L] %= x;
        maxi[no] = tree[no] = a[L];
        return;
    }
    if (i > R || j < L) return;
    apply(nl, L, mid, i, j, x);
    apply(nr, mid+1, R, i, j, x);
    maxi[no] = max(maxi[nl], maxi[nr]);
    tree[no] = tree[nl] + tree[nr];
}

void apply(int l, int r, int x) {
    apply(1,0,n-1,l,r,x);
}

void update(int no, int L, int R, int k, int x) {
    int nl = no<<1, nr = nl+1, mid = (L+R)>>1;
    if (L == R) {
        maxi[no] = tree[no] = a[L] = x;
        return;
    }
    if (k <= mid) update(nl, L, mid, k, x);
    else update(nr, mid+1, R, k, x);
    maxi[no] = max(maxi[nl], maxi[nr]);
    tree[no] = tree[nl] + tree[nr];
}

void update(int k, int x) { update(1,0,n-1,k,x); }

ll sum(int no, int L, int R, int i, int j) {
    int nl = no<<1, nr = nl+1, mid = (L+R)>>1;
    if (i > R || j < L) return 0;
    if (i <= L && R <= j) return tree[no];
    ll a = sum(nl, L, mid, i, j);
    ll b = sum(nr, mid+1, R, i, j);
    return a + b;
}

ll sum(int l, int r) { return sum(1,0,n-1,l,r); }

void build(int no, int L, int R) {
    if (L == R) {
        tree[no] = maxi[no] = a[L];
        return;
    }
    int nl = no<<1, nr = nl+1, mid = (L+R)>>1;
    build(nl,L,mid);
    build(nr,mid+1,R);
    tree[no] = tree[nl] + tree[nr];
    maxi[no] = max(maxi[nl], maxi[nr]);
}

int main() {
    int m; scanf("%d %d", &n, &m);
    fr(i,0,n) scanf("%d", &a[i]);
    build(1,0,n-1);
    while (m--) {
        int t; scanf("%d", &t);
        if (t == 1) {
            int l, r; scanf("%d %d", &l, &r); --l; --r;
            cout << sum(l,r) << endl;
        } else if (t == 2) {
            int l, r, x; scanf("%d %d %d", &l, &r, &x); --l; --r;
            apply(l,r,x);
        } else {
            int k, x; scanf("%d %d", &k, &x); --k;
            update(k,x);
        }
    }
    return 0;
}


#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int N=510000;
typedef struct seg{
   int l,r,lx,rx,mx,sum;
  }seg ;
seg a[N*5];
int n,m,l,r,t,tot;

int build(int l,int r)
  {  int mid=(l+r)>>1;
     int x=++tot;
     a[x].lx=l; a[x].rx=r;
     if (l==r) return x;
     a[x].l=build(l,mid);
     a[x].r=build(mid+1,r);
     return x;}

int up(int x)
  { a[x].sum=a[a[x].l].sum+a[a[x].r].sum;
    a[x].mx=max(a[a[x].l].mx,a[a[x].r].mx);}

int modify(int p,int t)
 {a[p].sum=a[p].mx=t;}

int add(int x,int p,int t)
 { if (a[x].lx==a[x].rx) return modify(x,t);
   int mid=(a[x].lx+a[x].rx)>>1;
   if (mid>=p) add(a[x].l,p,t);
   else add(a[x].r,p,t);
   up(x);}

int addx(int x,int l,int r,int t)
  {  if (a[x].mx<t) return 0;
     if (a[x].lx==a[x].rx) return modify(x,a[x].mx%t);
     int mid=(l+r)>>1;
     if (mid>=l) addx(a[x].l,l,r,t);
     if (mid+1<=r) addx(a[x].r,l,r,t);
     up(x);}

int sum(int x,int l,int r)
 { if (a[x].lx>=l&&a[x].rx<=r) return a[x].sum;
   int mid=(a[x].lx+a[x].rx)>>1; int ans=0;
   if (mid>=l) ans+=sum(a[x].l,l,r);
   if (mid+1<=r) ans+=sum(a[x].r,l,r);
   return ans;
  }

int main()
 {  //freopen("1.in","r",stdin);
    scanf("%d%d",&n,&m);
    build(1,n);
    for (int i=1;i<=n;i++)
      { scanf("%d",&t);
        add(1,i,t);}
    int sy;
    while (m--)
      {  scanf("%d%d%d",&sy,&l,&r);
         if (sy==1) printf("%d\n",sum(1,l,r));
         if (sy==2) scanf("%d",&t),addx(1,l,r,t);
         if (sy==3) add(1,l,r);
         }
     }


#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=510000;
typedef long long ll;
typedef struct seg{
   int l,r,lx,rx; ll mx,sum;
  }seg ;
seg a[N*5];
int n,m,l,r,t,tot;

int build(int l,int r)
  {  int mid=(l+r)>>1;
     int x=++tot;
     a[x].lx=l; a[x].rx=r;
     if (l==r) return x;
     a[x].l=build(l,mid);
     a[x].r=build(mid+1,r);
     return x;}

int up(int x)
  { a[x].sum=a[a[x].l].sum+a[a[x].r].sum;
    a[x].mx=max(a[a[x].l].mx,a[a[x].r].mx);}

int modify(int p,int t) {a[p].sum=t; a[p].mx=t; return 0;}

int add(int x,int p,int t)
 { if (a[x].lx==a[x].rx) return modify(x,t);
   int mid=(a[x].lx+a[x].rx)>>1;
   if (mid>=p) add(a[x].l,p,t);
   else add(a[x].r,p,t);
   up(x);}

int addx(int x,int l,int r,int t)
  {  if (a[x].mx<t) return 0;
     if (a[x].lx==a[x].rx) return modify(x,a[x].mx%t);
     int mid=(a[x].lx+a[x].rx)>>1;
     if (l>mid) addx(a[x].r,l,r,t);
     else
     if (r<=mid) addx(a[x].l,l,r,t);
     else addx(a[x].l,l,mid,t),addx(a[x].r,mid+1,r,t);
     up(x);}

ll sum(int x,int l,int r)
 { if (a[x].lx>=l&&a[x].rx<=r) return a[x].sum;
   int mid=(a[x].lx+a[x].rx)>>1; ll ans=0;
   if (mid>=l)   ans+=sum(a[x].l,l,r);
   if (mid+1<=r) ans+=sum(a[x].r,l,r);
   return ans;}

int main()
 {  //freopen("1.in","r",stdin);
    scanf("%d%d",&n,&m);
    build(1,n);
    for (int i=1;i<=n;i++)
    {scanf("%d",&t);
     add(1,i,t);}
    int sy;
    while (m--)
      { scanf("%d%d%d",&sy,&l,&r);
        if (sy==1) printf("%I64d\n",sum(1,l,r));
        if (sy==2) scanf("%d",&t),addx(1,l,r,t);
        if (sy==3) add(1,l,r);
      }
  }


#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=510000;
typedef long long ll;
int a[N];
int n,m,l,r,t,tot;
int sum(int l,int r)
  {  long long ans=0;
     for (int i=l;i<=r;i++)
      ans+=a[i]; return ans;}

int addx(int l,int r,int t)
   { for (int i=l;i<=r;i++)
      a[i]=a[i]%t;}

int add(int l,int r)
   { a[l]=r;}

int main()
 {  //freopen("1.in","r",stdin);
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++)
    {scanf("%I64d",&a[i]);}
    int sy;
    while (m--)
      { scanf("%d%d%d",&sy,&l,&r);
        if (sy==1) printf("%d\n",sum(l,r));
        if (sy==2) scanf("%d",&t),addx(l,r,t);
        if (sy==3) add(l,r);
      }
  }


#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=510000;
typedef long long ll;
typedef struct seg{
   int l,r,lx,rx,ll mx,sum;
  }seg ;
seg a[N*5];
int n,m,l,r,t,tot;

int build(int l,int r)
  {  int mid=(l+r)>>1;
     int x=++tot;
     a[x].lx=l; a[x].rx=r;
     if (l==r) return x;
     a[x].l=build(l,mid);
     a[x].r=build(mid+1,r);
     return x;}

int up(int x)
  { a[x].sum=a[a[x].l].sum+a[a[x].r].sum;
    a[x].mx=max(a[a[x].l].mx,a[a[x].r].mx);}

int modify(int p,int t) {a[p].sum=t; a[p].mx=t; return 0;}

int add(int x,int p,int t)
 { if (a[x].lx==a[x].rx) return modify(x,t);
   int mid=(a[x].lx+a[x].rx)>>1;
   if (mid>=p) add(a[x].l,p,t);
   else add(a[x].r,p,t);
   up(x);}

int addx(int x,int l,int r,int t)
  {  if (a[x].mx<t) return 0;
     if (a[x].lx==a[x].rx) return modify(x,a[x].mx%t);
     int mid=(a[x].lx+a[x].rx)>>1;
     if (mid>=l) addx(a[x].l,l,r,t);
     if (mid+1<=r) addx(a[x].r,l,r,t);
     up(x);}

ll sum(int x,int l,int r)
 { if (a[x].lx>=l&&a[x].rx<=r) return a[x].sum;
   int mid=(a[x].lx+a[x].rx)>>1; ll ans=0;
   if (mid>=l) ans+=sum(a[x].l,l,r);
   if (mid+1<=r) ans+=sum(a[x].r,l,r);
   return ans;}

int main()
 {  //freopen("1.in","r",stdin);
    scanf("%d%d",&n,&m);
    build(1,n);
    for (int i=1;i<=n;i++)
    {scanf("%d",&t);
     add(1,i,t);}
    int sy;
    while (m--)
      {  scanf("%d%d%d",&sy,&l,&r);
         if (sy==1) printf("%d\n",sum(1,l,r));
         if (sy==2) scanf("%d",&t),addx(1,l,r,t);
         if (sy==3) add(1,l,r);
      }
  }


#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=510000;
typedef long long ll;
ll a[N];
int n,m,l,r,t,tot;
int sum(int l,int r)
  {  long long ans=0;
     for (int i=l;i<=r;i++)
      ans+=a[i]; return ans;}

int addx(int l,int r,int t)
   { for (int i=l;i<=r;i++)
      a[i]=a[i]%t;}

int add(int l,int r)
   { a[l]=r;}

int main()
 {  //freopen("1.in","r",stdin);
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++)
    {scanf("%I64d",&a[i]);}
    int sy;
    while (m--)
      { scanf("%d%d%d",&sy,&l,&r);
        if (sy==1) printf("%I64d\n",sum(l,r));
        if (sy==2) scanf("%d",&t),addx(l,r,t);
        if (sy==3) add(l,r);
      }
  }


#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=510000;
typedef long long ll;
typedef struct seg{
   int l,r,lx,rx,mx; ll sum;
  }seg ;
seg a[N*5];
int n,m,l,r,t,tot;

int build(int l,int r)
  {  int mid=(l+r)>>1;
     int x=++tot;
     a[x].lx=l; a[x].rx=r;
     if (l==r) return x;
     a[x].l=build(l,mid);
     a[x].r=build(mid+1,r);
     return x;}

int up(int x)
  { a[x].sum=a[a[x].l].sum+a[a[x].r].sum;
    a[x].mx=max(a[a[x].l].mx,a[a[x].r].mx);}

int modify(int p,int t) {a[p].sum=a[p].mx=t;}

int add(int x,int p,int t)
 { if (a[x].lx==a[x].rx) return modify(x,t);
   int mid=(a[x].lx+a[x].rx)>>1;
   if (mid>=p) add(a[x].l,p,t);
   else add(a[x].r,p,t);
   up(x);}

int addx(int x,int l,int r,int t)
  {  if (a[x].mx<t) return 0;
     if (a[x].lx==a[x].rx) return modify(x,a[x].mx%t);
     int mid=(a[x].lx+a[x].rx)>>1;
     if (mid>=l) addx(a[x].l,l,r,t);
     if (mid+1<=r) addx(a[x].r,l,r,t);
     up(x);}

ll sum(int x,int l,int r)
 { if (a[x].lx>=l&&a[x].rx<=r) return a[x].sum;
   int mid=(a[x].lx+a[x].rx)>>1; ll ans=0;
   if (mid>=l) ans+=sum(a[x].l,l,r);
   if (mid+1<=r) ans+=sum(a[x].r,l,r);
   return ans;
  }

int main()
 {  //freopen("1.in","r",stdin);
    scanf("%d%d",&n,&m);
    build(1,n);
    for (int i=1;i<=n;i++)
    {scanf("%d",&t);
     add(1,i,t);}
    int sy;
    while (m--)
      {  scanf("%d%d%d",&sy,&l,&r);
         if (sy==1) printf("%d\n",sum(1,l,r));
         if (sy==2) scanf("%d",&t),addx(1,l,r,t);
         if (sy==3) add(1,l,r);
         }
     }


#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=510000;
typedef long long ll;
ll a[N];
int n,m,l,r,t,tot;
ll sum(int l,int r)
  {  long long ans=0;
     for (int i=l;i<=r;i++)
      ans+=a[i]; return ans;}

int addx(int l,int r,int t)
   { for (int i=l;i<=r;i++)
      a[i]=a[i]%t;}

int add(int l,int r)
   { a[l]=r;}

int main()
 {  //freopen("1.in","r",stdin);
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++)
    {scanf("%I64d",&a[i]);}
    int sy;
    while (m--)
      { scanf("%d%d%d",&sy,&l,&r);
        if (sy==1) printf("%I64d\n",sum(l,r));
        if (sy==2) scanf("%d",&t),addx(l,r,t);
        if (sy==3) add(l,r);
      }
  }


#include<stdio.h>
#include<algorithm>
#include<set>
using namespace std;
int c[110000];
int SQ=300;
long long bag[500];
set<pair<int,int> >S[500];
pair<int,int>tmp[1000];
long long query(int a,int b){
    long long ret=0;
    int L=a/SQ+1;
    int R=b/SQ;
    for(int i=L;i<R;i++){
        ret+=bag[i];
    }
    if(L>=R){
        for(int i=a;i<=b;i++)ret+=c[i];
    }else{
        for(int i=a;i<L*SQ;i++)ret+=c[i];
        for(int i=R*SQ;i<=b;i++)ret+=c[i];
    }
    return ret;
}
void update(int a,int b){
    S[a/SQ].erase(make_pair(c[a],a));
    bag[a/SQ]-=c[a];
    c[a]=b;
    bag[a/SQ]+=b;
    S[a/SQ].insert(make_pair(c[a],b));
}
void updmod(int a,int b,int f){
    int L=a/SQ+1;
    int R=b/SQ;
    for(int i=L;i<R;i++){
        int n=0;
        for(set<pair<int,int> >::iterator it=S[i].lower_bound(make_pair(f,0));it!=S[i].end();it++){
            tmp[n++]=(*it);
        }
        for(int j=0;j<n;j++)update(tmp[i].second,tmp[i].first%f);
    }
    if(L>=R){
        for(int i=a;i<=b;i++)update(i,c[i]%f);
    }else{
        for(int i=a;i<L*SQ;i++)update(i,c[i]%f);
        for(int i=(R-1)*SQ;i<=b;i++)update(i,c[i]%f);
    }
}
int main(){
    int a,b;
    scanf("%d%d",&a,&b);
    for(int i=0;i<a;i++)scanf("%d",c+i);
    for(int i=0;i<a;i++){
        S[i/SQ].insert(make_pair(c[i],i));
        bag[i/SQ]+=c[i];
    }
    while(b--){
        int p;
        scanf("%d",&p);
        if(p==1){
            int l,r;scanf("%d%d",&l,&r);
            l--;r--;
            printf("%I64d\n",query(l,r));
        }else if(p==2){
            int l,r,x;scanf("%d%d%d",&l,&r,&x);
            l--;r--;
            updmod(l,r,x);
        }else{
            int k,x;
            scanf("%d%d",&k,&x);
            k--;
            update(k,x);
        }
    }
}


#include<stdio.h>
#include<algorithm>
#include<set>
using namespace std;
int c[110000];
int SQ=300;
long long bag[500];
set<pair<int,int> >S[500];
pair<int,int>tmp[1000];
long long query(int a,int b){
    long long ret=0;
    int L=a/SQ+1;
    int R=b/SQ;
    for(int i=L;i<R;i++){
        ret+=bag[i];
    }
    if(L>=R){
        for(int i=a;i<=b;i++)ret+=c[i];
    }else{
        for(int i=a;i<L*SQ;i++)ret+=c[i];
        for(int i=R*SQ;i<=b;i++)ret+=c[i];
    }
    return ret;
}
void update(int a,int b){
    S[a/SQ].erase(make_pair(c[a],a));
    bag[a/SQ]-=c[a];
    c[a]=b;
    bag[a/SQ]+=b;
    S[a/SQ].insert(make_pair(c[a],b));
}
void updmod(int a,int b,int f){
    int L=a/SQ+1;
    int R=b/SQ;
    for(int i=L;i<R;i++){
        int n=0;
        for(set<pair<int,int> >::iterator it=S[i].lower_bound(make_pair(f,0));it!=S[i].end();it++){
            tmp[n++]=(*it);
        }
        for(int j=0;j<n;j++)update(tmp[i].second,tmp[i].first%f);
    }
    if(L>=R){
        for(int i=a;i<=b;i++)update(i,c[i]%f);
    }else{
        for(int i=a;i<L*SQ;i++)update(i,c[i]%f);
        for(int i=R*SQ;i<=b;i++)update(i,c[i]%f);
    }
}
int main(){
    int a,b;
    scanf("%d%d",&a,&b);
    for(int i=0;i<a;i++)scanf("%d",c+i);
    for(int i=0;i<a;i++){
        S[i/SQ].insert(make_pair(c[i],i));
        bag[i/SQ]+=c[i];
    }
    while(b--){
        int p;
        scanf("%d",&p);
        if(p==1){
            int l,r;scanf("%d%d",&l,&r);
            l--;r--;
            printf("%I64d\n",query(l,r));
        }else if(p==2){
            int l,r,x;scanf("%d%d%d",&l,&r,&x);
            l--;r--;
            updmod(l,r,x);
        }else{
            int k,x;
            scanf("%d%d",&k,&x);
            k--;
            update(k,x);
        }
    }
}


#include<stdio.h>
#include<algorithm>
#include<set>
using namespace std;
int c[110000];
set<pair<int,int> >S[262144];
long long seg[262144];
pair<int,int>tmp[262144];
int sz;
long long query(int a,int b,int c,int d,int e){
    if(d<a||b<c)return 0;
    if(c<=a&&b<=d)return seg[e];
    return query(a,(a+b)/2,c,d,e*2)+query((a+b)/2+1,b,c,d,e*2+1);
}
void update(int a,int b){
    int at=a+sz;
    while(at){
        S[at].erase(make_pair(seg[a+sz],a));
        at/=2;
    }
    at=a+sz;
    seg[at]=b;
    at/=2;
    while(at){
        seg[at]=seg[at*2]+seg[at*2+1];
        at/=2;
    }
    at=a+sz;
    while(at){
        S[at].insert(make_pair(seg[a+sz],a));
        at/=2;
    }
}
void updmod(int a,int b,int c,int d,int e,int f){
    if(d<a||b<c)return;
    if(c<=a&&b<=d){
        int n=0;
        for(set<pair<int,int> >::iterator it=S[e].lower_bound(make_pair(f,0));it!=S[e].end();it++){
            tmp[n++]=(*it);
        }
        for(int i=0;i<n;i++){
            update(tmp[i].second,tmp[i].first%f);
        }
        return;
    }
    updmod(a,(a+b)/2,c,d,e*2,f);
    updmod((a+b)/2+1,b,c,d,e*2+1,f);
}
int main(){
    int a,b;
    scanf("%d%d",&a,&b);
    for(int i=0;i<a;i++)scanf("%d",c+i);
    sz=131072;
    for(int i=0;i<a;i++){
        seg[sz+i]=c[i];
        S[sz+i].insert(make_pair(c[i],i));
    }
    for(int i=sz-1;i>0;i--){
        seg[i]=seg[i*2]+seg[i*2+1];
        for(set<pair<int,int> >::iterator j=S[i*2].begin();j!=S[i*2].end();j++){
            S[i].insert(*j);
        }
        for(set<pair<int,int> >::iterator j=S[i*2+1].begin();j!=S[i*2+1].end();j++){
            S[i].insert(*j);
        }
    }
    while(b--){
        int p;
        scanf("%d",&p);
        if(p==1){
            int l,r;scanf("%d%d",&l,&r);
            l--;r--;
            printf("%I64d\n",query(0,sz-1,l,r,1));
        }else if(p==2){
            int l,r,x;scanf("%d%d%d",&l,&r,&x);
            l--;r--;
            updmod(0,sz-1,l,r,1,x);
        }else{
            int k,x;
            scanf("%d%d",&k,&x);
            k--;
            update(k,x);
        }
    }
}


#include<stdio.h>
#include<algorithm>
#include<set>
using namespace std;
int c[110000];
int SQ=200;
long long bag[700];
set<pair<int,int> >S[700];
pair<int,int>tmp[1000];
long long query(int a,int b){
    long long ret=0;
    int L=a/SQ+1;
    int R=b/SQ;
    for(int i=L;i<R;i++){
        ret+=bag[i];
    }
    if(L>=R){
        for(int i=a;i<=b;i++)ret+=c[i];
    }else{
        for(int i=a;i<L*SQ;i++)ret+=c[i];
        for(int i=R*SQ;i<=b;i++)ret+=c[i];
    }
    return ret;
}
void update(int a,int b){
    S[a/SQ].erase(make_pair(c[a],a));
    bag[a/SQ]-=c[a];
    c[a]=b;
    bag[a/SQ]+=b;
    S[a/SQ].insert(make_pair(c[a],a));
}
void updmod(int a,int b,int f){
    int L=a/SQ+1;
    int R=b/SQ;
    for(int i=L;i<R;i++){
        int n=0;
        for(set<pair<int,int> >::iterator it=S[i].lower_bound(make_pair(f,0));it!=S[i].end();it++){
            tmp[n++]=(*it);
        }
        for(int j=0;j<n;j++)update(tmp[j].second,tmp[j].first%f);
    }
    if(L>=R){
        for(int i=a;i<=b;i++)if(c[i]>=f)update(i,c[i]%f);
    }else{
        for(int i=a;i<L*SQ;i++)if(c[i]>=f)update(i,c[i]%f);
        for(int i=R*SQ;i<=b;i++)if(c[i]>=f)update(i,c[i]%f);
    }
}
int main(){
    int a,b;
    scanf("%d%d",&a,&b);
    for(int i=0;i<a;i++)scanf("%d",c+i);
    for(int i=0;i<a;i++){
        S[i/SQ].insert(make_pair(c[i],i));
        bag[i/SQ]+=c[i];
    }
    while(b--){
        int p;
        scanf("%d",&p);
        if(p==1){
            int l,r;scanf("%d%d",&l,&r);
            l--;r--;
            printf("%I64d\n",query(l,r));
        }else if(p==2){
            int l,r,x;scanf("%d%d%d",&l,&r,&x);
            l--;r--;
            updmod(l,r,x);
        }else{
            int k,x;
            scanf("%d%d",&k,&x);
            k--;
            update(k,x);
        }
    }
}


#include<stdio.h>
#include<algorithm>
#include<set>
using namespace std;
int c[110000];
int SQ=300;
long long bag[500];
set<pair<int,int> >S[500];
pair<int,int>tmp[1000];
long long query(int a,int b){
    long long ret=0;
    int L=a/SQ+1;
    int R=b/SQ;
    for(int i=L;i<R;i++){
        ret+=bag[i];
    }
    if(L>=R){
        for(int i=a;i<=b;i++)ret+=c[i];
    }else{
        for(int i=a;i<L*SQ;i++)ret+=c[i];
        for(int i=R*SQ;i<=b;i++)ret+=c[i];
    }
    return ret;
}
void update(int a,int b){
    S[a/SQ].erase(make_pair(c[a],a));
    bag[a/SQ]-=c[a];
    c[a]=b;
    bag[a/SQ]+=b;
    S[a/SQ].insert(make_pair(c[a],a));
}
void updmod(int a,int b,int f){
    int L=a/SQ+1;
    int R=b/SQ;
    for(int i=L;i<R;i++){
        int n=0;
        for(set<pair<int,int> >::iterator it=S[i].lower_bound(make_pair(f,0));it!=S[i].end();it++){
            tmp[n++]=(*it);
        }
        for(int j=0;j<n;j++)update(tmp[i].second,tmp[i].first%f);
    }
    if(L>=R){
        for(int i=a;i<=b;i++)update(i,c[i]%f);
    }else{
        for(int i=a;i<L*SQ;i++)update(i,c[i]%f);
        for(int i=R*SQ;i<=b;i++)update(i,c[i]%f);
    }
}
int main(){
    int a,b;
    scanf("%d%d",&a,&b);
    for(int i=0;i<a;i++)scanf("%d",c+i);
    for(int i=0;i<a;i++){
        S[i/SQ].insert(make_pair(c[i],i));
        bag[i/SQ]+=c[i];
    }
    while(b--){
        int p;
        scanf("%d",&p);
        if(p==1){
            int l,r;scanf("%d%d",&l,&r);
            l--;r--;
            printf("%I64d\n",query(l,r));
        }else if(p==2){
            int l,r,x;scanf("%d%d%d",&l,&r,&x);
            l--;r--;
            updmod(l,r,x);
        }else{
            int k,x;
            scanf("%d%d",&k,&x);
            k--;
            update(k,x);
        }
    }
}


#include<stdio.h>
#include<algorithm>
#include<set>
using namespace std;
int c[110000];
int SQ=300;
long long bag[500];
set<pair<int,int> >S[500];
pair<int,int>tmp[1000];
long long query(int a,int b){
    long long ret=0;
    int L=a/SQ+1;
    int R=b/SQ;
    for(int i=L;i<R;i++){
        ret+=bag[i];
    }
    if(L>=R){
        for(int i=a;i<=b;i++)ret+=c[i];
    }else{
        for(int i=a;i<L*SQ;i++)ret+=c[i];
        for(int i=R*SQ;i<=b;i++)ret+=c[i];
    }
    return ret;
}
void update(int a,int b){
    S[a/SQ].erase(make_pair(c[a],a));
    bag[a/SQ]-=c[a];
    c[a]=b;
    bag[a/SQ]+=b;
    S[a/SQ].insert(make_pair(c[a],a));
}
void updmod(int a,int b,int f){
    int L=a/SQ+1;
    int R=b/SQ;
    for(int i=L;i<R;i++){
        int n=0;
        for(set<pair<int,int> >::iterator it=S[i].lower_bound(make_pair(f,0));it!=S[i].end();it++){
            tmp[n++]=(*it);
        }
        for(int j=0;j<n;j++)update(tmp[j].second,tmp[j].first%f);
    }
    if(L>=R){
        for(int i=a;i<=b;i++)update(i,c[i]%f);
    }else{
        for(int i=a;i<L*SQ;i++)update(i,c[i]%f);
        for(int i=R*SQ;i<=b;i++)update(i,c[i]%f);
    }
}
int main(){
    int a,b;
    scanf("%d%d",&a,&b);
    for(int i=0;i<a;i++)scanf("%d",c+i);
    for(int i=0;i<a;i++){
        S[i/SQ].insert(make_pair(c[i],i));
        bag[i/SQ]+=c[i];
    }
    while(b--){
        int p;
        scanf("%d",&p);
        if(p==1){
            int l,r;scanf("%d%d",&l,&r);
            l--;r--;
            printf("%I64d\n",query(l,r));
        }else if(p==2){
            int l,r,x;scanf("%d%d%d",&l,&r,&x);
            l--;r--;
            updmod(l,r,x);
        }else{
            int k,x;
            scanf("%d%d",&k,&x);
            k--;
            update(k,x);
        }
    }
}


#include <iostream>
#include <algorithm>
//#include <map>

typedef std::pair<int, int> pii;
typedef long long ll;

const int MAX = 400010;
int n;
//ranges are [low, high), pairs store <low, high>
//std::map<pii, ll> sum;
//std::map<pii, ll> max;
ll sum[MAX];
ll max[MAX];

//mod range [a, b) by x
//void mod(pii p, int a, int b, int x) {
void mod(pii p, int index, int a, int b, int x) {
	//std::cout << "[" << p.first << ", " << p.second << ") " << index << '\n';
	//if(max[p] < x) {
	if(max[index] < x) {
		return;
	}
	if(p.second - p.first < 2) {
		//sum[p] = sum[p] % x;
		//max[p] = max[p] % x;
		sum[index] %= x;
		max[index] %= x;
		return;
	}
	int mid = (p.first + p.second) / 2;
	pii left(p.first, mid);
	pii right(mid, p.second);
	int leftindex = index * 2;
	int rightindex = index * 2 + 1;
	if(a < mid) {
		//mod(left, a, b, x);
		mod(left, leftindex, a, b, x);
	}
	if(b > mid) {
		//mod(right, a, b, x);
		mod(right, rightindex, a, b, x);
	}
	//sum[p] = sum[left] + sum[right];
	//max[p] = std::max(max[left], max[right]);
	sum[index] = sum[leftindex] + sum[rightindex];
	max[index] = std::max(max[leftindex], max[rightindex]);
}

//change value at i to x
//void change(pii p, int i, int x) {
void change(pii p, int index, int i, int x) {
	if(p.second - p.first < 2) {
		//sum[p] = x;
		//max[p] = x;
		sum[index] = x;
		max[index] = x;
		return;
	}
	int mid = (p.first + p.second) / 2;
	pii left(p.first, mid);
	pii right(mid, p.second);
	int leftindex = index * 2;
	int rightindex = index * 2 + 1;
	if(i < mid) {
		//change(left, i, x);
		change(left, leftindex, i, x);
	} else {
		//change(right, i, x);
		change(right, rightindex, i, x);
	}
	//sum[p] = sum[left] + sum[right];
	//max[p] = std::max(max[left], max[right]);
	sum[index] = sum[leftindex] + sum[rightindex];
	max[index] = std::max(max[leftindex], max[rightindex]);
}

//sum [a, b)
//ll get_sum(pii p, int a, int b) {
ll get_sum(pii p, int index, int a, int b) {
	if(p.second - p.first < 2) {
		//return sum[p];
		return sum[index];
	}
	if(a <= p.first && a >= p.second) {
		//return sum[p];
		return sum[index];
	}
	int mid = (p.first + p.second) / 2;
	pii left(p.first, mid);
	pii right(mid, p.second);
	int leftindex = index * 2;
	int rightindex = index * 2 + 1;
	ll ret = 0;
	if(a < mid) {
		//ret += get_sum(left, a, b);
		ret += get_sum(left, leftindex, a, b);
	}
	if(b > mid) {
		//ret += get_sum(right, a, b);
		ret += get_sum(right, rightindex, a, b);
	}
	return ret;
}
/*
inline void print() {
	pii p(0, n);
	for(int k = 0; k < n; ++k) {
		std::cout << get_sum(p, 1, k, k + 1) << ' ';
	}
	std::cout << '\n';
}
*/
int main() {
	int m;
	std::cin >> n >> m;
	pii p(0, n);
	for(int k = 0; k < n; ++k) {
		int x;
		std::cin >> x;
		//change(p, k, x);
		change(p, 1, k, x);
	}
	//print();
	for(int k = 0; k < m; ++k) {
		int t;
		//scanf("%d", &t);
		std::cin >> t;
		if(t == 1) {
			//type 1: sum
			int a, b;
			std::cin >> a >> b;
			//printf("%I64d\n", get_sum(p, a - 1, b));
			std::cout << get_sum(p, 1, a - 1, b) << '\n';
		} else if(t == 2) {
			//type 2: mod
			int a, b, x;
			std::cin >> a >> b >> x;
			//mod(p, a - 1, b, x);
			mod(p, 1, a - 1, b, x);
		} else {
			//type 3: set
			int i, x;
			std::cin >> i >> x;
			//change(p, i - 1, x);
			change(p, 1, i - 1, x);
		}
		//print();
	}
	return 0;
}


#include <iostream>
#include <algorithm>
//#include <map>

typedef long long ll;

const int MAX = 400010;
int n;
//ranges are [low, high), pairs store <low, high>
//std::map<pii, ll> sum;
//std::map<pii, ll> max;
ll sum[MAX];
ll max[MAX];

//mod range [a, b) by x
//void mod(pii p, int a, int b, int x) {
void mod(int l, int r, int index, int a, int b, int x) {
	if(max[index] < x) {
		return;
	}
	if(r - l < 2) {
		sum[index] %= x;
		max[index] %= x;
		return;
	}
	int mid = (l + r) / 2;
	int leftindex = index * 2;
	int rightindex = index * 2 + 1;
	if(a < mid) {
		mod(l, mid, leftindex, a, b, x);
	}
	if(b > mid) {
		mod(mid, r, rightindex, a, b, x);
	}
	sum[index] = sum[leftindex] + sum[rightindex];
	max[index] = std::max(max[leftindex], max[rightindex]);
}

//change value at i to x
void change(int l, int r, int index, int i, int x) {
	if(r - l < 2) {
		sum[index] = x;
		max[index] = x;
		return;
	}
	int mid = (l + r) / 2;
	int leftindex = index * 2;
	int rightindex = index * 2 + 1;
	if(i < mid) {
		change(l, mid, leftindex, i, x);
	} else {
		change(mid, r, rightindex, i, x);
	}
	sum[index] = sum[leftindex] + sum[rightindex];
	max[index] = std::max(max[leftindex], max[rightindex]);
}

//sum [a, b)
ll get_sum(int l, int r, int index, int a, int b) {
	if(r - l < 2) {
		return sum[index];
	}
	if(a <= l && a >= r) {
		return sum[index];
	}
	int mid = (l + r) / 2;
	int leftindex = index * 2;
	int rightindex = index * 2 + 1;
	ll ret = 0;
	if(a < mid) {
		ret += get_sum(l, mid, leftindex, a, b);
	}
	if(b > mid) {
		ret += get_sum(mid, r, rightindex, a, b);
	}
	return ret;
}

int main() {
	int m;
	std::cin >> n >> m;
	for(int k = 0; k < n; ++k) {
		int x;
		std::cin >> x;
		change(0, n, 1, k, x);
	}
	for(int k = 0; k < m; ++k) {
		int t;
		//scanf("%d", &t);
		std::cin >> t;
		if(t == 1) {
			//type 1: sum
			int a, b;
			std::cin >> a >> b;
			//printf("%I64d\n", get_sum(p, a - 1, b));
			std::cout << get_sum(0, n, 1, a - 1, b) << '\n';
		} else if(t == 2) {
			//type 2: mod
			int a, b, x;
			std::cin >> a >> b >> x;
			//mod(p, a - 1, b, x);
			mod(0, n, 1, a - 1, b, x);
		} else {
			//type 3: set
			int i, x;
			std::cin >> i >> x;
			//change(p, i - 1, x);
			change(0, n, 1, i - 1, x);
		}
		//print();
	}
	return 0;
}


#include <cstdio>
#include <algorithm>

typedef long long ll;

const int MAX = 400010;
int n;
//ranges are [low, high), pairs store <low, high>
ll sum[MAX];
ll max[MAX];

//mod range [a, b) by x
void mod(int l, int r, int index, int a, int b, int x) {
	if(max[index] < x) {
		return;
	}
	if(r - l < 2) {
		sum[index] %= x;
		max[index] %= x;
		return;
	}
	int mid = (l + r) / 2;
	int leftindex = index * 2;
	int rightindex = index * 2 + 1;
	if(a < mid) {
		mod(l, mid, leftindex, a, b, x);
	}
	if(b > mid) {
		mod(mid, r, rightindex, a, b, x);
	}
	sum[index] = sum[leftindex] + sum[rightindex];
	max[index] = std::max(max[leftindex], max[rightindex]);
}

//change value at i to x
void change(int l, int r, int index, int i, int x) {
	if(r - l < 2) {
		sum[index] = x;
		max[index] = x;
		return;
	}
	int mid = (l + r) / 2;
	int leftindex = index * 2;
	int rightindex = index * 2 + 1;
	if(i < mid) {
		change(l, mid, leftindex, i, x);
	} else {
		change(mid, r, rightindex, i, x);
	}
	sum[index] = sum[leftindex] + sum[rightindex];
	max[index] = std::max(max[leftindex], max[rightindex]);
}

//sum [a, b)
ll get_sum(int l, int r, int index, int a, int b) {
	if(b <= l || a >= r) {
		return 0;
	}
	if(a <= l && b >= r) {
		return sum[index];
	}
	int mid = (l + r) / 2;
	int leftindex = index * 2;
	int rightindex = index * 2 + 1;
	ll ret = 0;
	return get_sum(l, mid, leftindex, a, b) + get_sum(mid, r, rightindex, a, b);
}

int main() {
	int m;
	scanf("%d%d", &n, &m);
	for(int k = 0; k < n; ++k) {
		int x;
		scanf("%d", &x);
		change(0, n, 1, k, x);
	}
	for(int k = 0; k < m; ++k) {
		int t;
		scanf("%d", &t);
		if(t == 1) {
			//type 1: sum
			int a, b;
			scanf("%d%d", &a, &b);
			printf("%I64d\n", get_sum(0, n, 1, a - 1, b));
		} else if(t == 2) {
			//type 2: mod
			int a, b, x;
			scanf("%d%d%d", &a, &b, &x);
			mod(0, n, 1, a - 1, b, x);
		} else {
			//type 3: set
			int i, x;
			scanf("%d%d", &i, &x);
			change(0, n, 1, i - 1, x);
		}
	}
	return 0;
}


#include <cstdio>
#include <algorithm>
#include <map>

typedef std::pair<int, int> pii;
typedef long long ll;

const int MAX = 400010;
int n;
//ranges are [low, high), pairs store <low, high>
//std::map<pii, ll> sum;
//std::map<pii, ll> max;
ll sum[MAX];
ll max[MAX];

//mod range [a, b) by x
//void mod(pii p, int a, int b, int x) {
void mod(pii p, int index, int a, int b, int x) {
	//if(max[p] < x) {
	if(max[index] < x) {
		return;
	}
	if(p.second - p.first < 2) {
		//sum[p] = sum[p] % x;
		//max[p] = max[p] % x;
		sum[index] = sum[index] % x;
		max[index] = max[index] % x;
	}
	int mid = (p.first + p.second) / 2;
	pii left(p.first, mid);
	pii right(mid, p.second);
	int leftindex = index * 2;
	int rightindex = index * 2 + 1;
	if(a < mid) {
		//mod(left, a, b, x);
		mod(left, leftindex, a, b, x);
	}
	if(b > mid) {
		//mod(right, a, b, x);
		mod(right, rightindex, a, b, x);
	}
	//sum[p] = sum[left] + sum[right];
	//max[p] = std::max(max[left], max[right]);
	sum[index] = sum[leftindex] + sum[rightindex];
	max[index] = std::max(max[leftindex], max[rightindex]);
}

//change value at i to x
//void change(pii p, int i, int x) {
void change(pii p, int index, int i, int x) {
	if(p.second - p.first < 2) {
		//sum[p] = x;
		//max[p] = x;
		sum[index] = x;
		max[index] = x;
		return;
	}
	int mid = (p.first + p.second) / 2;
	pii left(p.first, mid);
	pii right(mid, p.second);
	int leftindex = index * 2;
	int rightindex = index * 2 + 1;
	if(i < mid) {
		//change(left, i, x);
		change(left, leftindex, i, x);
	} else {
		//change(right, i, x);
		change(right, rightindex, i, x);
	}
	//sum[p] = sum[left] + sum[right];
	//max[p] = std::max(max[left], max[right]);
	sum[index] = sum[leftindex] + sum[rightindex];
	max[index] = std::max(max[leftindex], max[rightindex]);
}

//sum [a, b)
//ll get_sum(pii p, int a, int b) {
ll get_sum(pii p, int index, int a, int b) {
	if(p.second - p.first < 2) {
		//return sum[p];
		return sum[index];
	}
	if(a <= p.first && a >= p.second) {
		//return sum[p];
		return sum[index];
	}
	int mid = (p.first + p.second) / 2;
	pii left(p.first, mid);
	pii right(mid, p.second);
	int leftindex = index * 2;
	int rightindex = index * 2 + 1;
	ll ret = 0;
	if(a < mid) {
		//ret += get_sum(left, a, b);
		ret += get_sum(left, leftindex, a, b);
	}
	if(b > mid) {
		//ret += get_sum(right, a, b);
		ret += get_sum(right, rightindex, a, b);
	}
	return ret;
}

int main() {
	int m;
	scanf("%d%d", &n, &m);
	pii p(0, n);
	for(int k = 0; k < n; ++k) {
		int x;
		scanf("%d", &x);
		//change(p, k, x);
		change(p, 1, k, x);
	}
	for(int k = 0; k < m; ++k) {
		int t;
		scanf("%d", &t);
		if(t == 1) {
			//type 1: sum
			int a, b;
			scanf("%d%d", &a, &b);
			//printf("%I64d\n", get_sum(p, a - 1, b));
			printf("%I64d\n", get_sum(p, 1, a - 1, b));
		} else if(t == 2) {
			//type 2: mod
			int a, b, x;
			scanf("%d%d%d", &a, &b, &x);
			//mod(p, a - 1, b, x);
			mod(p, 1, a - 1, b, x);
		} else {
			//type 3: set
			int i, x;
			scanf("%d%d", &i, &x);
			//change(p, i - 1, x);
			change(p, 1, i - 1, x);
		}
	}
	return 0;
}


#include <cstdio>
#include <algorithm>
#include <map>

typedef std::pair<int, int> pii;
typedef long long ll;

//ranges are [low, high), pairs store <low, high>
std::map<pii, ll> sum;
std::map<pii, ll> max;
int n;

//mod range [a, b) by x
void mod(pii p, int a, int b, int x) {
	if(max[p] < x) {
		return;
	}
	if(p.second - p.first < 2) {
		sum[p] = sum[p] % x;
		max[p] = max[p] % x;
	}
	int mid = (p.first + p.second) / 2;
	pii left(p.first, mid);
	pii right(mid, p.second);
	if(a < mid) {
		mod(left, a, b, x);
	}
	if(b > mid) {
		mod(right, a, b, x);
	}
	sum[p] = sum[left] + sum[right];
	max[p] = std::max(max[left], max[right]);
}

//change value at i to x
void change(pii p, int i, int x) {
	if(p.second - p.first < 2) {
		sum[p] = x;
		max[p] = x;
		return;
	}
	int mid = (p.first + p.second) / 2;
	pii left(p.first, mid);
	pii right(mid, p.second);
	if(i < mid) {
		change(left, i, x);
	} else {
		change(right, i, x);
	}
	sum[p] = sum[left] + sum[right];
	max[p] = std::max(max[left], max[right]);
}

//sum [a, b)
ll get_sum(pii p, int a, int b) {
	if(p.second - p.first < 2) {
		return sum[p];
	}
	if(a <= p.first && a >= p.second) {
		return sum[p];
	}
	int mid = (p.first + p.second) / 2;
	pii left(p.first, mid);
	pii right(mid, p.second);
	ll ret = 0;
	if(a < mid) {
		ret += get_sum(left, a, b);
	}
	if(b > mid) {
		ret += get_sum(right, a, b);
	}
	return ret;
}

int main() {
	int m;
	scanf("%d%d", &n, &m);
	pii p(0, n);
	for(int k = 0; k < n; ++k) {
		int x;
		scanf("%d", &x);
		change(p, k, x);
	}
	for(int k = 0; k < m; ++k) {
		int t;
		scanf("%d", &t);
		if(t == 1) {
			//type 1: sum
			int a, b;
			scanf("%d%d", &a, &b);
			printf("%I64d\n", get_sum(p, a - 1, b));
		} else if(t == 2) {
			//type 2: mod
			int a, b, x;
			scanf("%d%d%d", &a, &b, &x);
			mod(p, a - 1, b, x);
		} else {
			//type 3: set
			int i, x;
			scanf("%d%d", &i, &x);
			change(p, i - 1, x);
		}
	}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <map>

typedef std::pair<int, int> pii;

//ranges are [low, high), pairs store <low, high>
std::map<pii, int> sum;
std::map<pii, int> max;
int n;

//mod range [a, b) by x
void mod(pii p, int a, int b, int x) {
	if(max[p] < x) {
		return;
	}
	if(p.second - p.first < 2) {
		sum[p] = sum[p] % x;
		max[p] = max[p] % x;
	}
	int mid = (p.first + p.second) / 2;
	pii left(p.first, mid);
	pii right(mid, p.second);
	if(a < mid) {
		mod(left, a, b, x);
	}
	if(b > mid) {
		mod(right, a, b, x);
	}
	sum[p] = sum[left] + sum[right];
	max[p] = std::max(max[left], max[right]);
}

//change value at i to x
void change(pii p, int i, int x) {
	if(p.second - p.first < 2) {
		sum[p] = x;
		max[p] = x;
		return;
	}
	int mid = (p.first + p.second) / 2;
	pii left(p.first, mid);
	pii right(mid, p.second);
	if(i < mid) {
		change(left, i, x);
	} else {
		change(right, i, x);
	}
	sum[p] = sum[left] + sum[right];
	max[p] = std::max(max[left], max[right]);
}

//sum [a, b)
long long get_sum(pii p, int a, int b) {
	if(p.second - p.first < 2) {
		return sum[p];
	}
	int mid = (p.first + p.second) / 2;
	pii left(p.first, mid);
	pii right(mid, p.second);
	long long ret = 0;
	if(a < mid) {
		ret += get_sum(left, a, b);
	}
	if(b > mid) {
		ret += get_sum(right, a, b);
	}
	return ret;
}

int main() {
	int m;
	std::cin >> n >> m;
	pii p(0, n);
	for(int k = 0; k < n; ++k) {
		int x;
		std::cin >> x;
		change(p, k, x);
	}
	for(int k = 0; k < m; ++k) {
		int t;
		std::cin >> t;
		if(t == 1) {
			//type 1: sum
			int a, b;
			std::cin >> a >> b;
			std::cout << get_sum(p, a - 1, b) << '\n';
		} else if(t == 2) {
			//type 2: mod
			int a, b, x;
			std::cin >> a >> b >> x;
			mod(p, a - 1, b, x);
		} else {
			//type 3: set
			int i, x;
			std::cin >> i >> x;
			change(p, i - 1, x);
		}
	}
	return 0;
}


#include <cstdio>
#include <algorithm>
#include <map>

typedef std::pair<int, int> pii;

//ranges are [low, high), pairs store <low, high>
std::map<pii, int> sum;
std::map<pii, int> max;
int n;

//mod range [a, b) by x
void mod(pii p, int a, int b, int x) {
	if(max[p] < x) {
		return;
	}
	if(p.second - p.first < 2) {
		sum[p] = sum[p] % x;
		max[p] = max[p] % x;
	}
	int mid = (p.first + p.second) / 2;
	pii left(p.first, mid);
	pii right(mid, p.second);
	if(a < mid) {
		mod(left, a, b, x);
	}
	if(b > mid) {
		mod(right, a, b, x);
	}
	sum[p] = sum[left] + sum[right];
	max[p] = std::max(max[left], max[right]);
}

//change value at i to x
void change(pii p, int i, int x) {
	if(p.second - p.first < 2) {
		sum[p] = x;
		max[p] = x;
		return;
	}
	int mid = (p.first + p.second) / 2;
	pii left(p.first, mid);
	pii right(mid, p.second);
	if(i < mid) {
		change(left, i, x);
	} else {
		change(right, i, x);
	}
	sum[p] = sum[left] + sum[right];
	max[p] = std::max(max[left], max[right]);
}

//sum [a, b)
long long get_sum(pii p, int a, int b) {
	if(p.second - p.first < 2) {
		return sum[p];
	}
	int mid = (p.first + p.second) / 2;
	pii left(p.first, mid);
	pii right(mid, p.second);
	long long ret = 0;
	if(a < mid) {
		ret += get_sum(left, a, b);
	}
	if(b > mid) {
		ret += get_sum(right, a, b);
	}
	return ret;
}

int main() {
	int m;
	scanf("%d%d", &n, &m);
	pii p(0, n);
	for(int k = 0; k < n; ++k) {
		int x;
		scanf("%d", &x);
		change(p, k, x);
	}
	for(int k = 0; k < m; ++k) {
		int t;
		scanf("%d", &t);
		if(t == 1) {
			//type 1: sum
			int a, b;
			scanf("%d%d", &a, &b);
			printf("%I64d\n", get_sum(p, a - 1, b));
		} else if(t == 2) {
			//type 2: mod
			int a, b, x;
			scanf("%d%d%d", &a, &b, &x);
			mod(p, a - 1, b, x);
		} else {
			//type 3: set
			int i, x;
			scanf("%d%d", &i, &x);
			change(p, i - 1, x);
		}
	}
	return 0;
}


#include <cstdio>
#include <algorithm>

typedef long long ll;

const int MAX = 400010;
int n;
//ranges are [low, high), pairs store <low, high>
ll sum[MAX];
ll max[MAX];

//mod range [a, b) by x
void mod(int l, int r, int index, int a, int b, int x) {
	if(max[index] < x) {
		return;
	}
	if(r - l < 2) {
		sum[index] %= x;
		max[index] %= x;
		return;
	}
	int mid = (l + r) / 2;
	int leftindex = index * 2;
	int rightindex = index * 2 + 1;
	if(a < mid) {
		mod(l, mid, leftindex, a, b, x);
	}
	if(b > mid) {
		mod(mid, r, rightindex, a, b, x);
	}
	sum[index] = sum[leftindex] + sum[rightindex];
	max[index] = std::max(max[leftindex], max[rightindex]);
}

//change value at i to x
void change(int l, int r, int index, int i, int x) {
	if(r - l < 2) {
		sum[index] = x;
		max[index] = x;
		return;
	}
	int mid = (l + r) / 2;
	int leftindex = index * 2;
	int rightindex = index * 2 + 1;
	if(i < mid) {
		change(l, mid, leftindex, i, x);
	} else {
		change(mid, r, rightindex, i, x);
	}
	sum[index] = sum[leftindex] + sum[rightindex];
	max[index] = std::max(max[leftindex], max[rightindex]);
}

//sum [a, b)
ll get_sum(int l, int r, int index, int a, int b) {
	if(r - l < 2) {
		return sum[index];
	}
	if(a <= l && a >= r) {
		return sum[index];
	}
	int mid = (l + r) / 2;
	int leftindex = index * 2;
	int rightindex = index * 2 + 1;
	ll ret = 0;
	if(a < mid) {
		ret += get_sum(l, mid, leftindex, a, b);
	}
	if(b > mid) {
		ret += get_sum(mid, r, rightindex, a, b);
	}
	return ret;
}

int main() {
	int m;
	scanf("%d%d", &n, &m);
	for(int k = 0; k < n; ++k) {
		int x;
		scanf("%d", &x);
		change(0, n, 1, k, x);
	}
	for(int k = 0; k < m; ++k) {
		int t;
		scanf("%d", &t);
		if(t == 1) {
			//type 1: sum
			int a, b;
			scanf("%d%d", &a, &b);
			printf("%I64d\n", get_sum(0, n, 1, a - 1, b));
		} else if(t == 2) {
			//type 2: mod
			int a, b, x;
			scanf("%d%d%d", &a, &b, &x);
			mod(0, n, 1, a - 1, b, x);
		} else {
			//type 3: set
			int i, x;
			scanf("%d%d", &i, &x);
			change(0, n, 1, i - 1, x);
		}
	}
	return 0;
}


#include <iostream>
#include <algorithm>
//#include <map>

typedef std::pair<int, int> pii;
typedef long long ll;

const int MAX = 400010;
int n;
//ranges are [low, high), pairs store <low, high>
//std::map<pii, ll> sum;
//std::map<pii, ll> max;
ll sum[MAX];
ll max[MAX];

//mod range [a, b) by x
//void mod(pii p, int a, int b, int x) {
void mod(pii p, int index, int a, int b, int x) {
	//std::cout << "[" << p.first << ", " << p.second << ") " << index << '\n';
	//if(max[p] < x) {
	if(max[index] < x) {
		return;
	}
	if(p.second - p.first < 2) {
		//sum[p] = sum[p] % x;
		//max[p] = max[p] % x;
		sum[index] %= x;
		max[index] %= x;
		return;
	}
	int mid = (p.first + p.second) / 2;
	pii left(p.first, mid);
	pii right(mid, p.second);
	int leftindex = index * 2;
	int rightindex = index * 2 + 1;
	if(a < mid) {
		//mod(left, a, b, x);
		mod(left, leftindex, a, b, x);
	}
	if(b >= mid) {
		//mod(right, a, b, x);
		mod(right, rightindex, a, b, x);
	}
	//sum[p] = sum[left] + sum[right];
	//max[p] = std::max(max[left], max[right]);
	sum[index] = sum[leftindex] + sum[rightindex];
	max[index] = std::max(max[leftindex], max[rightindex]);
}

//change value at i to x
//void change(pii p, int i, int x) {
void change(pii p, int index, int i, int x) {
	if(p.second - p.first < 2) {
		//sum[p] = x;
		//max[p] = x;
		sum[index] = x;
		max[index] = x;
		return;
	}
	int mid = (p.first + p.second) / 2;
	pii left(p.first, mid);
	pii right(mid, p.second);
	int leftindex = index * 2;
	int rightindex = index * 2 + 1;
	if(i < mid) {
		//change(left, i, x);
		change(left, leftindex, i, x);
	} else {
		//change(right, i, x);
		change(right, rightindex, i, x);
	}
	//sum[p] = sum[left] + sum[right];
	//max[p] = std::max(max[left], max[right]);
	sum[index] = sum[leftindex] + sum[rightindex];
	max[index] = std::max(max[leftindex], max[rightindex]);
}

//sum [a, b)
//ll get_sum(pii p, int a, int b) {
ll get_sum(pii p, int index, int a, int b) {
	if(p.second - p.first < 2) {
		//return sum[p];
		return sum[index];
	}
	if(a <= p.first && a >= p.second) {
		//return sum[p];
		return sum[index];
	}
	int mid = (p.first + p.second) / 2;
	pii left(p.first, mid);
	pii right(mid, p.second);
	int leftindex = index * 2;
	int rightindex = index * 2 + 1;
	ll ret = 0;
	if(a < mid) {
		//ret += get_sum(left, a, b);
		ret += get_sum(left, leftindex, a, b);
	}
	if(b > mid) {
		//ret += get_sum(right, a, b);
		ret += get_sum(right, rightindex, a, b);
	}
	return ret;
}
/*
inline void print() {
	pii p(0, n);
	for(int k = 0; k < n; ++k) {
		std::cout << get_sum(p, 1, k, k + 1) << ' ';
	}
	std::cout << '\n';
}
*/
int main() {
	int m;
	std::cin >> n >> m;
	pii p(0, n);
	for(int k = 0; k < n; ++k) {
		int x;
		std::cin >> x;
		//change(p, k, x);
		change(p, 1, k, x);
	}
	//print();
	for(int k = 0; k < m; ++k) {
		int t;
		scanf("%d", &t);
		if(t == 1) {
			//type 1: sum
			int a, b;
			std::cin >> a >> b;
			//printf("%I64d\n", get_sum(p, a - 1, b));
			std::cout << get_sum(p, 1, a - 1, b) << '\n';
		} else if(t == 2) {
			//type 2: mod
			int a, b, x;
			std::cin >> a >> b >> x;
			//mod(p, a - 1, b, x);
			mod(p, 1, a - 1, b, x);
		} else {
			//type 3: set
			int i, x;
			std::cin >> i >> x;
			//change(p, i - 1, x);
			change(p, 1, i - 1, x);
		}
		//print();
	}
	return 0;
}


#include <iostream>
#include <algorithm>
//#include <map>

typedef std::pair<int, int> pii;
typedef long long ll;

const int MAX = 400010;
int n;
//ranges are [low, high), pairs store <low, high>
//std::map<pii, ll> sum;
//std::map<pii, ll> max;
ll sum[MAX];
ll max[MAX];

//mod range [a, b) by x
//void mod(pii p, int a, int b, int x) {
void mod(pii p, int index, int a, int b, int x) {
	//std::cout << "[" << p.first << ", " << p.second << ") " << index << '\n';
	//if(max[p] < x) {
	if(max[index] < x) {
		return;
	}
	if(p.second - p.first < 2) {
		//sum[p] = sum[p] % x;
		//max[p] = max[p] % x;
		sum[index] %= x;
		max[index] %= x;
		return;
	}
	int mid = (p.first + p.second) / 2;
	pii left(p.first, mid);
	pii right(mid, p.second);
	int leftindex = index * 2;
	int rightindex = index * 2 + 1;
	if(a < mid) {
		//mod(left, a, b, x);
		mod(left, leftindex, a, b, x);
	}
	if(b >= mid) {
		//mod(right, a, b, x);
		mod(right, rightindex, a, b, x);
	}
	//sum[p] = sum[left] + sum[right];
	//max[p] = std::max(max[left], max[right]);
	sum[index] = sum[leftindex] + sum[rightindex];
	max[index] = std::max(max[leftindex], max[rightindex]);
}

//change value at i to x
//void change(pii p, int i, int x) {
void change(pii p, int index, int i, int x) {
	if(p.second - p.first < 2) {
		//sum[p] = x;
		//max[p] = x;
		sum[index] = x;
		max[index] = x;
		return;
	}
	int mid = (p.first + p.second) / 2;
	pii left(p.first, mid);
	pii right(mid, p.second);
	int leftindex = index * 2;
	int rightindex = index * 2 + 1;
	if(i < mid) {
		//change(left, i, x);
		change(left, leftindex, i, x);
	} else {
		//change(right, i, x);
		change(right, rightindex, i, x);
	}
	//sum[p] = sum[left] + sum[right];
	//max[p] = std::max(max[left], max[right]);
	sum[index] = sum[leftindex] + sum[rightindex];
	max[index] = std::max(max[leftindex], max[rightindex]);
}

//sum [a, b)
//ll get_sum(pii p, int a, int b) {
ll get_sum(pii p, int index, int a, int b) {
	if(p.second - p.first < 2) {
		//return sum[p];
		return sum[index];
	}
	if(a <= p.first && a >= p.second) {
		//return sum[p];
		return sum[index];
	}
	int mid = (p.first + p.second) / 2;
	pii left(p.first, mid);
	pii right(mid, p.second);
	int leftindex = index * 2;
	int rightindex = index * 2 + 1;
	ll ret = 0;
	if(a < mid) {
		//ret += get_sum(left, a, b);
		ret += get_sum(left, leftindex, a, b);
	}
	if(b > mid) {
		//ret += get_sum(right, a, b);
		ret += get_sum(right, rightindex, a, b);
	}
	return ret;
}
/*
inline void print() {
	pii p(0, n);
	for(int k = 0; k < n; ++k) {
		std::cout << get_sum(p, 1, k, k + 1) << ' ';
	}
	std::cout << '\n';
}
*/
int main() {
	int m;
	std::cin >> n >> m;
	pii p(0, n);
	for(int k = 0; k < n; ++k) {
		int x;
		std::cin >> x;
		//change(p, k, x);
		change(p, 1, k, x);
	}
	//print();
	for(int k = 0; k < m; ++k) {
		int t;
		//scanf("%d", &t);
		std::cin >> t;
		if(t == 1) {
			//type 1: sum
			int a, b;
			std::cin >> a >> b;
			//printf("%I64d\n", get_sum(p, a - 1, b));
			std::cout << get_sum(p, 1, a - 1, b) << '\n';
		} else if(t == 2) {
			//type 2: mod
			int a, b, x;
			std::cin >> a >> b >> x;
			//mod(p, a - 1, b, x);
			mod(p, 1, a - 1, b, x);
		} else {
			//type 3: set
			int i, x;
			std::cin >> i >> x;
			//change(p, i - 1, x);
			change(p, 1, i - 1, x);
		}
		//print();
	}
	return 0;
}


#include <iostream>
#include <cstdio>
using namespace std;
#define int long long
int n, m;
int a[100005];
struct Segment{
	int sum;
	bool lazy;
	int mx;
}t[400005];

#define ls(x) x << 1
#define rs(x) x<<1|1
#define sum(x) t[x].sum
#define lazy(x) t[x].lazy
#define mx(x) t[x].mx

inline void pushup(int o){
	sum(o) = sum(ls(o)) + sum(rs(o));
	lazy(o) = lazy(ls(o)) & lazy(rs(o));
	mx(o) = max(mx(ls(o)), mx(rs(o)));
}

void build(int l, int r, int o)
{
	if (l == r){
		sum(o) = a[l];
		//lazy(o) = ((a[l] == 0) | (a[l] == 1));
		if (a[l] == 0 or a[l] == 1) lazy(o) = 1;
		mx(o) = a[l];
		return ;
	}
	int mid = l + r >> 1;
	build (l, mid, ls(o));
	build (mid + 1, r, rs(o));
	pushup(o);
}

void change(int pos, int li, int ri, int o, int tt)
{
	if (li == ri){
		sum(o) = tt;
		mx(o) = tt;
		if (tt == 0 or tt == 1) lazy(o) = 1;
		//lazy(o) = ((tt == 0) | (tt == 1));
		return ;
	}
	int mid = li + ri >> 1;
	if (mid >= pos) change(pos, li, mid, ls(o), tt);
	else change(pos, mid + 1, ri, rs(o), tt);
	pushup(o);
}

int query(int l, int r, int o, int li, int ri)
{
	if (li >= l and ri <= r){
		return sum(o);
	}
	int mid = li + ri >> 1;
	int res = 0;
	if (mid >= l) res += query(l, r, ls(o), li, mid);
	if (mid < r) res += query(l, r, rs(o), mid + 1, ri);
	return res;
}

void mod(int l, int r, int o, int li, int ri, int MOD)
{
	if (lazy(o)) return ;
	if (mx(o) < MOD) return ;
	if (li == ri) {
		sum(o) = sum(o) % MOD;
		lazy(o) = ((sum(o) == 0) | (sum(o) == 1));
		return ;
	}
	int mid = li + ri >> 1;
	if (mid >= l) mod(l, r, ls(o), li, mid, MOD);
	if (mid < r) mod(l, r, rs(o), mid + 1, ri, MOD);
	pushup(o);
}

signed main()
{
	scanf("%lld%lld", &n, &m);
	for (register int i = 1 ;i <= n ; i ++) scanf("%lld", &a[i]);
	build(1, n, 1);
	while(m--)
	{
		int opt;
		scanf("%lld", &opt);
		if (opt == 1)
		{
			int x, y;scanf("%lld%lld", &x, &y);
			printf("%lld\n", query(x, y, 1, 1, n));
		}
		else if (opt == 2)
		{
			int x, y, z;scanf("%lld%lld%lld", &x, &y, &z);
			mod(x, y, 1, 1, n, z);
		}
		else
		{
			int x, y;scanf("%lld%lld", &x, &y);
			change(x, 1, n, 1, y);
		}
	}
	return 0;
}


#include <iostream>
#include <cstdio>
using namespace std;
#define int long long
int n, m;
int a[100005];
bool ywysb, ywydsb;
bool ywysbsbsbsb;
struct Segment{
	int sum;
	int mx;
}t[400005];

#define ls(x) x << 1
#define rs(x) x<<1|1
#define sum(x) t[x].sum
#define mx(x) t[x].mx

inline void pushup(int o){
	sum(o) = sum(ls(o)) + sum(rs(o));
	mx(o) = max(mx(ls(o)), mx(rs(o)));
}

void build(int l, int r, int o)
{
	if (l == r){
		sum(o) = a[l];
		mx(o) = a[l];
		return ;
	}
	int mid = l + r >> 1;
	build (l, mid, ls(o));
	build (mid + 1, r, rs(o));
	pushup(o);
}

void change(int pos, int li, int ri, int o, int tt)
{
	if (li == ri){
		sum(o) = tt;
		mx(o) = tt;
		return ;
	}
	int mid = li + ri >> 1;
	if (mid >= pos) change(pos, li, mid, ls(o), tt);
	else change(pos, mid + 1, ri, rs(o), tt);
	pushup(o);
}

int query(int l, int r, int o, int li, int ri)
{
	if (li >= l and ri <= r){
		return sum(o);
	}
	int mid = li + ri >> 1;
	int res = 0;
	if (mid >= l) res += query(l, r, ls(o), li, mid);
	if (mid < r) res += query(l, r, rs(o), mid + 1, ri);
	return res;
}

void mod(int l, int r, int o, int li, int ri, int MOD)
{
	if (mx(o) < MOD) return ;
	if (li == ri) {
		sum(o) = sum(o) % MOD;
		mx(o) = sum(o);
		return ;
	}
	int mid = li + ri >> 1;
	if (mid >= l) mod(l, r, ls(o), li, mid, MOD);
	if (mid < r) mod(l, r, rs(o), mid + 1, ri, MOD);
	pushup(o);
}

signed main()
{
	scanf("%lld%lld", &n, &m);
	for (register int i = 1 ;i <= n ; i ++) scanf("%lld", &a[i]);
	build(1, n, 1);
	while(m--)
	{
		int opt;
		scanf("%lld", &opt);
		if (opt == 1)
		{
			int x, y;scanf("%lld%lld", &x, &y);
			printf("%lld\n", query(x, y, 1, 1, n));
		}
		else if (opt == 2)
		{
			int x, y, z;scanf("%lld%lld%lld", &x, &y, &z);
			mod(x, y, 1, 1, n, z);
		}
		else
		{
			int x, y;scanf("%lld%lld", &x, &y);
			change(x, 1, n, 1, y);
		}
	}
	return 0;
}


#include <iostream>
#include <cstdio>
using namespace std;

int n, m;
int a[100005];
struct Segment{
	int sum;
	bool lazy;
}t[400005];

#define ls(x) x << 1
#define rs(x) x<<1|1
#define sum(x) t[x].sum
#define lazy(x) t[x].lazy

inline void pushup(int o){
	sum(o) = sum(ls(o)) + sum(rs(o));
	lazy(o) = lazy(ls(o)) & lazy(rs(o));
}

void build(int l, int r, int o)
{
	if (l == r){
		sum(o) = a[l];
		//lazy(o) = ((a[l] == 0) | (a[l] == 1));
		if (a[l] == 0 or a[l] == 1) lazy(o) = 1;
		return ;
	}
	int mid = l + r >> 1;
	build (l, mid, ls(o));
	build (mid + 1, r, rs(o));
	pushup(o);
}

void change(int pos, int li, int ri, int o, int tt)
{
	if (li == ri){
		sum(o) = tt;
		if (tt == 0 or tt == 1) lazy(o) = 1;
		//lazy(o) = ((tt == 0) | (tt == 1));
		return ;
	}
	int mid = li + ri >> 1;
	if (mid >= pos) change(pos, li, mid, ls(o), tt);
	else change(pos, mid + 1, ri, rs(o), tt);
	pushup(o);
}

int query(int l, int r, int o, int li, int ri)
{
	if (li >= l and ri <= r){
		return sum(o);
	}
	int mid = li + ri >> 1;
	int res = 0;
	if (mid >= l) res += query(l, r, ls(o), li, mid);
	if (mid < r) res += query(l, r, rs(o), mid + 1, ri);
	return res;
}

void mod(int l, int r, int o, int li, int ri, int MOD)
{
	if (lazy(o)) return ;
	if (li == ri) {
		sum(o) = sum(o) % MOD;
		lazy(o) = ((sum(o) == 0) | (sum(o) == 1));
		return ;
	}
	int mid = li + ri >> 1;
	if (mid >= l) mod(l, r, ls(o), li, mid, MOD);
	if (mid < r) mod(l, r, rs(o), mid + 1, ri, MOD);
	pushup(o);
}

int main()
{
	scanf("%d%d", &n, &m);
	for (register int i = 1 ;i <= n ; i ++) scanf("%d", &a[i]);
	build(1, n, 1);
	while(m--)
	{
		int opt;
		scanf("%d", &opt);
		if (opt == 1)
		{
			int x, y;scanf("%d%d", &x, &y);
			printf("%d\n", query(x, y, 1, 1, n));
		}
		else if (opt == 2)
		{
			int x, y, z;scanf("%d%d%d", &x, &y, &z);
			mod(x, y, 1, 1, n, z);
		}
		else
		{
			int x, y;scanf("%d%d", &x, &y);
			change(x, 1, n, 1, y);
		}
	}
	return 0;
}


#include <iostream>
#include <cstdio>
using namespace std;
#define int long long
int n, m;
int a[100005];
struct Segment{
	int sum;
	bool lazy;
	int mx;
}t[400005];

#define ls(x) x << 1
#define rs(x) x<<1|1
#define sum(x) t[x].sum
#define lazy(x) t[x].lazy
#define mx(x) t[x].mx

inline void pushup(int o){
	sum(o) = sum(ls(o)) + sum(rs(o));
	lazy(o) = lazy(ls(o)) & lazy(rs(o));
	mx(o) = max(mx(ls(o)), mx(rs(o)));
}

void build(int l, int r, int o)
{
	if (l == r){
		sum(o) = a[l];
		//lazy(o) = ((a[l] == 0) | (a[l] == 1));
		if (a[l] == 0 or a[l] == 1) lazy(o) = 1;
		mx(o) = a[l];
		return ;
	}
	int mid = l + r >> 1;
	build (l, mid, ls(o));
	build (mid + 1, r, rs(o));
	pushup(o);
}

void change(int pos, int li, int ri, int o, int tt)
{
	if (li == ri){
		sum(o) = tt;
		mx(o) = tt;
		if (tt == 0 or tt == 1) lazy(o) = 1;
		//lazy(o) = ((tt == 0) | (tt == 1));
		return ;
	}
	int mid = li + ri >> 1;
	if (mid >= pos) change(pos, li, mid, ls(o), tt);
	else change(pos, mid + 1, ri, rs(o), tt);
	pushup(o);
}

int query(int l, int r, int o, int li, int ri)
{
	if (li >= l and ri <= r){
		return sum(o);
	}
	int mid = li + ri >> 1;
	int res = 0;
	if (mid >= l) res += query(l, r, ls(o), li, mid);
	if (mid < r) res += query(l, r, rs(o), mid + 1, ri);
	return res;
}

void mod(int l, int r, int o, int li, int ri, int MOD)
{
//	if (lazy(o)) return ;
	if (mx(o) < MOD) return ;
	if (li == ri) {
		sum(o) = sum(o) % MOD;
		if (sum(o) == 0 or sum(o) == 1) lazy(o) = 1;
		//lazy(o) = ((sum(o) == 0) | (sum(o) == 1));
		mx(o) = sum(o);
		return ;
	}
	int mid = li + ri >> 1;
	if (mid >= l) mod(l, r, ls(o), li, mid, MOD);
	if (mid < r) mod(l, r, rs(o), mid + 1, ri, MOD);
	pushup(o);
}

signed main()
{
	scanf("%lld%lld", &n, &m);
	for (register int i = 1 ;i <= n ; i ++) scanf("%lld", &a[i]);
	build(1, n, 1);
	while(m--)
	{
		int opt;
		scanf("%lld", &opt);
		if (opt == 1)
		{
			int x, y;scanf("%lld%lld", &x, &y);
			printf("%lld\n", query(x, y, 1, 1, n));
		}
		else if (opt == 2)
		{
			int x, y, z;scanf("%lld%lld%lld", &x, &y, &z);
			mod(x, y, 1, 1, n, z);
		}
		else
		{
			int x, y;scanf("%lld%lld", &x, &y);
			change(x, 1, n, 1, y);
		}
	}
	return 0;
}


#include <iostream>
#include <cstdio>
using namespace std;
#define int long long
int n, m;
int a[100005];
struct Segment{
	int sum;
	bool lazy;
}t[400005];

#define ls(x) x << 1
#define rs(x) x<<1|1
#define sum(x) t[x].sum
#define lazy(x) t[x].lazy

inline void pushup(int o){
	sum(o) = sum(ls(o)) + sum(rs(o));
	lazy(o) = lazy(ls(o)) & lazy(rs(o));
}

void build(int l, int r, int o)
{
	if (l == r){
		sum(o) = a[l];
		//lazy(o) = ((a[l] == 0) | (a[l] == 1));
		if (a[l] == 0 or a[l] == 1) lazy(o) = 1;
		return ;
	}
	int mid = l + r >> 1;
	build (l, mid, ls(o));
	build (mid + 1, r, rs(o));
	pushup(o);
}

void change(int pos, int li, int ri, int o, int tt)
{
	if (li == ri){
		sum(o) = tt;
		if (tt == 0 or tt == 1) lazy(o) = 1;
		//lazy(o) = ((tt == 0) | (tt == 1));
		return ;
	}
	int mid = li + ri >> 1;
	if (mid >= pos) change(pos, li, mid, ls(o), tt);
	else change(pos, mid + 1, ri, rs(o), tt);
	pushup(o);
}

int query(int l, int r, int o, int li, int ri)
{
	if (li >= l and ri <= r){
		return sum(o);
	}
	int mid = li + ri >> 1;
	int res = 0;
	if (mid >= l) res += query(l, r, ls(o), li, mid);
	if (mid < r) res += query(l, r, rs(o), mid + 1, ri);
	return res;
}

void mod(int l, int r, int o, int li, int ri, int MOD)
{
	if (lazy(o)) return ;
	if (li == ri) {
		sum(o) = sum(o) % MOD;
		lazy(o) = ((sum(o) == 0) | (sum(o) == 1));
		return ;
	}
	int mid = li + ri >> 1;
	if (mid >= l) mod(l, r, ls(o), li, mid, MOD);
	if (mid < r) mod(l, r, rs(o), mid + 1, ri, MOD);
	pushup(o);
}

signed main()
{
	scanf("%lld%lld", &n, &m);
	for (register int i = 1 ;i <= n ; i ++) scanf("%lld", &a[i]);
	build(1, n, 1);
	while(m--)
	{
		int opt;
		scanf("%lld", &opt);
		if (opt == 1)
		{
			int x, y;scanf("%lld%lld", &x, &y);
			printf("%lld\n", query(x, y, 1, 1, n));
		}
		else if (opt == 2)
		{
			int x, y, z;scanf("%lld%lld%lld", &x, &y, &z);
			mod(x, y, 1, 1, n, z);
		}
		else
		{
			int x, y;scanf("%lld%lld", &x, &y);
			change(x, 1, n, 1, y);
		}
	}
	return 0;
}


#include <iostream>
#include <cstdio>
using namespace std;
#define int long long
int n, m;
int a[100005];
struct Segment{
	int sum;
	bool lazy;
	int mx;
}t[400005];

#define ls(x) x << 1
#define rs(x) x<<1|1
#define sum(x) t[x].sum
#define lazy(x) t[x].lazy
#define mx(x) t[x].mx

inline void pushup(int o){
	sum(o) = sum(ls(o)) + sum(rs(o));
	lazy(o) = lazy(ls(o)) & lazy(rs(o));
	mx(o) = max(mx(ls(o)), mx(rs(o)));
}

void build(int l, int r, int o)
{
	if (l == r){
		sum(o) = a[l];
		//lazy(o) = ((a[l] == 0) | (a[l] == 1));
		if (a[l] == 0 or a[l] == 1) lazy(o) = 1;
		mx(o) = a[l];
		return ;
	}
	int mid = l + r >> 1;
	build (l, mid, ls(o));
	build (mid + 1, r, rs(o));
	pushup(o);
}

void change(int pos, int li, int ri, int o, int tt)
{
	if (li == ri){
		sum(o) = tt;
		mx(o) = tt;
		if (tt == 0 or tt == 1) lazy(o) = 1;
		//lazy(o) = ((tt == 0) | (tt == 1));
		return ;
	}
	int mid = li + ri >> 1;
	if (mid >= pos) change(pos, li, mid, ls(o), tt);
	else change(pos, mid + 1, ri, rs(o), tt);
	pushup(o);
}

int query(int l, int r, int o, int li, int ri)
{
	if (li >= l and ri <= r){
		return sum(o);
	}
	int mid = li + ri >> 1;
	int res = 0;
	if (mid >= l) res += query(l, r, ls(o), li, mid);
	if (mid < r) res += query(l, r, rs(o), mid + 1, ri);
	return res;
}

void mod(int l, int r, int o, int li, int ri, int MOD)
{
	if (lazy(o)) return ;
	if (mx(o) < MOD) return ;
	if (li == ri) {
		sum(o) = sum(o) % MOD;
		if (sum(o) == 0 or sum(o) == 1) lazy(o) = 1;
		//lazy(o) = ((sum(o) == 0) | (sum(o) == 1));
		mx(o) = sum(o);
		return ;
	}
	int mid = li + ri >> 1;
	if (mid >= l) mod(l, r, ls(o), li, mid, MOD);
	if (mid < r) mod(l, r, rs(o), mid + 1, ri, MOD);
	pushup(o);
}

signed main()
{
	scanf("%lld%lld", &n, &m);
	for (register int i = 1 ;i <= n ; i ++) scanf("%lld", &a[i]);
	build(1, n, 1);
	while(m--)
	{
		int opt;
		scanf("%lld", &opt);
		if (opt == 1)
		{
			int x, y;scanf("%lld%lld", &x, &y);
			printf("%lld\n", query(x, y, 1, 1, n));
		}
		else if (opt == 2)
		{
			int x, y, z;scanf("%lld%lld%lld", &x, &y, &z);
			mod(x, y, 1, 1, n, z);
		}
		else
		{
			int x, y;scanf("%lld%lld", &x, &y);
			change(x, 1, n, 1, y);
		}
	}
	return 0;
}


#include<cstdio>
#include<algorithm>
#define MAXN 100010
using namespace std;
struct Tree
{
	int l,r;
	long long sum,viv;
}tree[MAXN*3];
int N,Q,A[MAXN];
void Pushup(int o)
{
	tree[o].sum=tree[o<<1].sum+tree[o<<1|1].sum;
	tree[o].viv=max(tree[o<<1].viv,tree[o<<1|1].viv);
}
void build(int o,int l,int r)
{
	tree[o].l=l,tree[o].r=r;
	if(l==r)
	{
		tree[o].viv=tree[o].sum=A[l];
		return;
	}
	int mid=(l+r)>>1;
	build(o<<1,l,mid);
	build(o<<1|1,mid+1,r);
	Pushup(o);
}
void changepoint(int o,int chp,int x)
{
	int L=tree[o].l,R=tree[o].r;
	if(chp<L || R<chp)return;
	if(L == R && chp == L)
	{
		tree[o].viv=tree[o].sum=x;
		return;
	}
	int mid=(L+R)>>1;
	if(chp<=mid) changepoint(o<<1,chp,x);
	else changepoint(o<<1|1,chp,x);
	Pushup(o);
}
void modulo(int o,int l,int r,int x)
{
	if(tree[o].viv<x)return;
	int L=tree[o].l,R=tree[o].r;
	if(r<L || R<l)return;
	if(L==R && l<=L && R<=r)
	{
		tree[o].sum%=x;
		return;
	}
	int mid=(L+R)>>1;
	if(r<=mid)modulo(o<<1,l,r,x);
	else if(mid<l) modulo(o<<1|1,l,r,x);
	else
	{
		modulo(o<<1,l,mid,x);
		modulo(o<<1|1,mid+1,r,x);
	}
	Pushup(o);
}
long long getsum(int o,int l,int r)
{
	int L=tree[o].l,R=tree[o].r;
	if(r<L || R<l)return 0;
	if(L==l && R==r)return tree[o].sum;
	int mid=(L+R)>>1;
	if(r<=mid)return getsum(o<<1,l,r);
	if(mid<l) return getsum(o<<1|1,l,r);
	return (long long)(getsum(o<<1,l,mid)+getsum(o<<1|1,mid+1,r));
}
int main()
{
	scanf("%d%d",&N,&Q);
	for(int i=1;i<=N;i++)scanf("%d",&A[i]);
	build(1,1,N);
	while(Q--)
	{
		int type;
		scanf("%d",&type);
		if(3 == type)
		{
			int k,x;
			scanf("%d%d",&k,&x);
			changepoint(1,k,x);
		}
		else if(2 == type)
		{
			int l,r,x;
			scanf("%d%d%d",&l,&r,&x);
			modulo(1,l,r,x);
		}
		else if(1 == type)
		{
			int l,r;
			scanf("%d%d",&l,&r);
			printf("%I64d\n",getsum(1,l,r));
		}
	}
	return 0;
}


#include<cstdio>
#include<algorithm>
#define MAXN 100010
using namespace std;
struct Tree
{
	int l,r;
	long long sum,viv;
}tree[MAXN*3];
int N,Q,A[MAXN];
void Pushup(int o)
{
	tree[o].sum=tree[o<<1].sum+tree[o<<1|1].sum;
	tree[o].viv=max(tree[o<<1].viv,tree[o<<1|1].viv);
}
void build(int o,int l,int r)
{
	tree[o].l=l,tree[o].r=r;
	if(l==r)
	{
		tree[o].viv=tree[o].sum=A[l];
		return;
	}
	int mid=(l+r)>>1;
	build(o<<1,l,mid);
	build(o<<1|1,mid+1,r);
	Pushup(o);
}
void changepoint(int o,int chp,int x)
{
	int L=tree[o].l,R=tree[o].r;
	if(chp<L || R<chp)return;
	if(L == R && chp == L)
	{
		tree[o].sum=x;
		return;
	}
	int mid=(L+R)>>1;
	if(chp<=mid) changepoint(o<<1,chp,x);
	else changepoint(o<<1|1,chp,x);
	Pushup(o);
}
void modulo(int o,int l,int r,int x)
{
	if(tree[o].viv<x)return;
	int L=tree[o].l,R=tree[o].r;
	if(r<L || R<l)return;
	if(L==R && l<=L && R<=r)
	{
		tree[o].sum%=x;
		return;
	}
	int mid=(L+R)>>1;
	if(r<=mid)modulo(o<<1,l,r,x);
	else if(mid<l) modulo(o<<1|1,l,r,x);
	else
	{
		modulo(o<<1,l,mid,x);
		modulo(o<<1|1,mid+1,r,x);
	}
	Pushup(o);
}
long long getsum(int o,int l,int r)
{
	int L=tree[o].l,R=tree[o].r;
	if(r<L || R<l)return 0;
	if(L==l && R==r)return tree[o].sum;
	int mid=(L+R)>>1;
	if(r<=mid)return getsum(o<<1,l,r);
	if(mid<l) return getsum(o<<1|1,l,r);
	return (long long)(getsum(o<<1,l,mid)+getsum(o<<1|1,mid+1,r));
}
int main()
{
	scanf("%d%d",&N,&Q);
	for(int i=1;i<=N;i++)scanf("%d",&A[i]);
	build(1,1,N);
	while(Q--)
	{
		int type;
		scanf("%d",&type);
		if(3 == type)
		{
			int k,x;
			scanf("%d%d",&k,&x);
			changepoint(1,k,x);
		}
		else if(2 == type)
		{
			int l,r,x;
			scanf("%d%d%d",&l,&r,&x);
			modulo(1,l,r,x);
		}
		else if(1 == type)
		{
			int l,r;
			scanf("%d%d",&l,&r);
			printf("%I64d\n",getsum(1,l,r));
		}
	}
	return 0;
}


#include<cstdio>
#include<algorithm>
#define MAXN 100010
using namespace std;
struct Tree
{
	int l,r;
	long long sum,viv;
}tree[MAXN*3];
int N,Q,A[MAXN];
void Pushup(int o)
{
	tree[o].sum=tree[o<<1].sum+tree[o<<1|1].sum;
	tree[o].viv=max(tree[o<<1].viv,tree[o<<1|1].viv);
}
void build(int o,int l,int r)
{
	tree[o].l=l,tree[o].r=r;
	if(l==r)
	{
		tree[o].viv=tree[o].sum=A[l];
		return;
	}
	int mid=(l+r)>>1;
	build(o<<1,l,mid);
	build(o<<1|1,mid+1,r);
	Pushup(o);
}
void changepoint(int o,int chp,int x)
{
	int L=tree[o].l,R=tree[o].r;
	if(chp<L || R<chp)return;
	if(L == R && chp == L)
	{
		tree[o].viv=tree[o].sum=x;
		return;
	}
	int mid=(L+R)>>1;
	if(chp<=mid) changepoint(o<<1,chp,x);
	else changepoint(o<<1|1,chp,x);
	Pushup(o);
}
void modulo(int o,int l,int r,int x)
{
	if(tree[o].viv<x)return;
	int L=tree[o].l,R=tree[o].r;
	if(r<L || R<l)return;
	if(L==R && l<=L && R<=r)
	{
		tree[o].viv%=x;
		tree[o].sum%=x;
		return;
	}
	int mid=(L+R)>>1;
	if(r<=mid)modulo(o<<1,l,r,x);
	else if(mid<l) modulo(o<<1|1,l,r,x);
	else
	{
		modulo(o<<1,l,mid,x);
		modulo(o<<1|1,mid+1,r,x);
	}
	Pushup(o);
}
long long getsum(int o,int l,int r)
{
	int L=tree[o].l,R=tree[o].r;
	if(r<L || R<l)return 0;
	if(L==l && R==r)return tree[o].sum;
	int mid=(L+R)>>1;
	if(r<=mid)return getsum(o<<1,l,r);
	if(mid<l) return getsum(o<<1|1,l,r);
	return (long long)(getsum(o<<1,l,mid)+getsum(o<<1|1,mid+1,r));
}
int main()
{
	scanf("%d%d",&N,&Q);
	for(int i=1;i<=N;i++)scanf("%d",&A[i]);
	build(1,1,N);
	while(Q--)
	{
		int type;
		scanf("%d",&type);
		if(3 == type)
		{
			int k,x;
			scanf("%d%d",&k,&x);
			changepoint(1,k,x);
		}
		else if(2 == type)
		{
			int l,r,x;
			scanf("%d%d%d",&l,&r,&x);
			modulo(1,l,r,x);
		}
		else if(1 == type)
		{
			int l,r;
			scanf("%d%d",&l,&r);
			printf("%I64d\n",getsum(1,l,r));
		}
	}
	return 0;
}