#include<iostream>
#include<bitset>
using namespace std;
#define lowbit(x) (x &(-x))
typedef long long ll;
const int MAXN=5e5+9;
const int N=2e7+9;
int phi[N+1],prime[N+1],cnt;
template<typename T>inline void read(T &x){
x=0;T f=1;char ch=getchar();
while(ch<48||ch>57){if(ch=='-'){f=-1;}ch=getchar();}
while(ch>=48&&ch<=57){x=x*10+ch-48;ch=getchar();}
x*=f;
}
template<typename T>inline void write(T x) {
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+48);
}
bitset<N+1> v;
void eular(){
phi[1]=1;
for(int i=2;i<=N;i++){
if(!v[i]) prime[++cnt]=i,phi[i]=i-1;
for(int j=1;prime[j]<=N/i;j++){
v[i*prime[j]]=1;
if(i%prime[j]==0){
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
else{
phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
}
}
int n,m;
ll qmi(ll a,ll b,ll p){
ll res=1;
int tag=0;
while(b){
if(b&1) {
res=res*a;
if(res>=p) res%=p,tag=1;
}
if(a>=p) tag=1,a%=p;
a=a*a;
if(a>=p) tag=1,a%=p;
b>>=1;
}
return res+(tag?p:0);
}
int a[MAXN];
ll arr[MAXN];
void modify(int pos,int d){
for(int i=pos;i<=n;i+=lowbit(i)){
arr[i]+=d;
}
}
ll query(int pos){
ll res=0;
for(int i=pos;i;i-=lowbit(i)) res+=arr[i];
return res;
}
inline ll solve(int id,int r,ll p)
{
if ( p == 1 ) return 1;
if ( id > r ) return 1;
ll cur = query(id) + a[id],y = solve(id + 1,r,phi[p]);
return qmi(cur,y,p);
}
int main(){
eular();
read(n),read(m);
for(int i=1;i<=n;i++){
read(a[i]);
}
int op,l,r,p;
while(m--){
read(op),read(l),read(r),read(p);
if(op==1) modify(l,p),modify(r+1,-p);
else {
write(solve(l,r,p)%p);
puts("");
}
}
return 0;
}
68行为什么 if ( p == 1 ) return 1; 就能AC
不应该是return 0吗?