#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod = (1LL << 32);
const int maxn = 2e5 + 10;
int a[maxn];
struct node {
int s, lcm;
}tr[maxn << 2];
int gcd(int x, int y)
{
if(x < y) swap(x,y);
if(y == 0) return x;
return gcd(y,x % y);
}
int lcm(int x, int y)
{
if (x == 0 || y == 0) return max(x, y);
return x / gcd(x, y) * y;
}
void pushup(int rt)
{
tr[rt].s = (tr[rt * 2].s + tr[rt * 2 + 1].s) % mod;
tr[rt].lcm = lcm(tr[rt * 2].lcm,tr[rt * 2 + 1].lcm);
}
void build(int rt,int l,int r)
{
if (l == r)
{
tr[rt].s = tr[rt].lcm = a[l];
return;
}
int mid = (l + r) >> 1;
build(rt * 2,l,mid);
build(rt * 2 + 1,mid + 1,r);
pushup(rt);
}
void update(int rt,int l,int r,int x,int y,int k)
{
if (l > y || r < x) return;
if (tr[rt].lcm > 0 && k % tr[rt].lcm == 0) return;
if (l == r)
{
tr[rt].s = tr[rt].lcm = gcd(tr[rt].s, k);
return;
}
int mid = (l + r) >> 1;
update(rt * 2,l,mid,x,y,k);
update(rt * 2 + 1,mid + 1,r,x,y,k);
pushup(rt);
}
int query(int rt,int l,int r,int x,int y)
{
if (r < x || l > y) return 0;
if (x <= l && r <= y) return tr[rt].s;
int mid = (l + r) >> 1;
return (query(rt * 2,l,mid,x,y) + query(rt * 2 + 1,mid + 1,r,x,y)) % mod;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n,m;
int opt,l,r,x;
cin >> n >> m;
for (int i = 1;i <= n;i++)
{
cin >> a[i];
}
build(1,1,n);
while (m--)
{
cin >> opt >> l >> r;
if (opt == 1)
{
cin >> x;
update(1,1,n,l,r,x);
}
else cout << query(1,1,n,l,r) << endl;
}
return 0;
}