#include <cmath>
#include <iostream>
#include <vector>
using namespace std;
using ll=long long;
//用数组实现区间根号与区间求和
vector<int> arr;
//定义节点结构体
struct Node{
    int l=0,r=0;
    ll sum=0;
    int maxVal=0;
    Node()=default;
    void setSumandValue(int s,int val){
        sum=s,maxVal=val;
    }
    void setLR(int tl,int tr){
        l=tl,r=tr;
    }
};
//定义二叉树的存储数组
vector<Node> tree;
//定义更新结构
void push_up(int node){
    tree[node].sum=tree[2*node].sum+tree[2*node+1].sum;
    tree[node].maxVal=tree[2*node].maxVal>tree[2*node+1].maxVal?tree[2*node].maxVal:tree[2*node+1].maxVal;
}

void buildTree(int node){
    int l=tree[node].l;
    int r=tree[node].r;
    if(l==r){
        tree[node].setSumandValue(arr[l], arr[l]);
        return;
    }
    int mid=(l+r)/2;
    tree[2*node].setLR(l, mid);
    buildTree(2*node);
    tree[2*node+1].setLR(mid+1, r);
    buildTree(2*node+1);
    //从底向上更新sum和maxVal
    push_up(node);
}
//区间修改操作
void update(int node,int ql,int qr){
    int l=tree[node].l;
    int r=tree[node].r;
    if(ql<=l && r<=qr){
        if(tree[node].maxVal<=1) return;
        else{
            if(l==r){
                tree[node].sum=sqrt(tree[node].sum);
                tree[node].maxVal=tree[node].sum;
            }else{
                update(2*node, ql, qr);
                update(2*node+1, ql, qr);
                push_up(node);
            }
        }
    }else{
        if(tree[2*node].r>=ql){
            update(2*node, ql, qr);
        }
        if(qr>=tree[2*node+1].l){
            update(2*node+1, ql, qr);
        }
        push_up(node);
    } 
    //假设区间为【1,8】,mid=4,左区间【1,4】,右【5,8】
    //查询区间【2,6】
}
//区间查询操作
ll query(int node,int ql,int qr){
    int l=tree[node].l;
    int r=tree[node].r;
    if(ql<=l && r<=qr){
        return tree[node].sum;
    }
    ll total=0;
    if(ql<=tree[2*node].r){
        total+=query(2*node, ql, qr);
    }
    if(qr>=tree[2*node+1].l){
        total+=query(2*node+1, ql, qr);
    }
    return total;
}
int main(){
    int n,q;
    cin>>n>>q;
    arr.resize(n+1,0);
    for(int i=1;i<=n;i++){
        cin>>arr[i];
    }
    tree.resize(4*n+5);
    tree[1].setLR(1, n);
    buildTree(1);
    while(q--){
        int op,l,r;
        cin>>op>>l>>r;
        if(op==1){
            update(1, l, r);
        }else{
            cout<<query(1, l, r)<<endl;
        }
    }
    return 0;
}
// 64 位输出请用 printf("%lld")