Problem: Let D(x) be the number of positive divisors of a positive integer x. For example, D(2) = 2 (2 is divisible by 1 and 2), D(6) = 4 (6 is divisible by 1, 2, 3 and 6).

You are given an array a of n integers. You have to process two types of queries:

  1. REPLACE l r — for every <image> replace ai with D(ai); 
  2. SUM l r — calculate <image>. 



Print the answer for each SUM query.

Input

The first line contains two integers n and m (1 ≤ n, m ≤ 3·105) — the number of elements in the array and the number of queries to process, respectively.

The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 106) — the elements of the array.

Then m lines follow, each containing 3 integers ti, li, ri denoting i-th query. If ti = 1, then i-th query is REPLACE li ri, otherwise it's SUM li ri (1 ≤ ti ≤ 2, 1 ≤ li ≤ ri ≤ n).

There is at least one SUM query.

Output

For each SUM query print the answer to it.

Example

Input

7 6
6 4 1 10 3 2 4
2 1 7
2 4 5
1 3 5
2 4 4
1 5 7
2 1 7


Output

30
13
4
22

Solution (in JAVA):

Solution:
import java.util.*;
import java.io.*;

public class Main {
	public static void main(String args[]) {new Main().run();}

	FastReader in = new FastReader();
	PrintWriter out = new PrintWriter(System.out);
	void run(){
		work();
		out.flush();
	}
	long mod=998244353;
	long gcd(long a,long b) {
		return b==0?a:gcd(b,a%b);
	}
	int[] dp;
	void work() {
		dp=new int[1000001];
		for(int i=1;i<=1000000;i++) {
			for(int j=i;j<=1000000;j+=i) {
				dp[j]++;
			}
		}
		int n=in.nextInt(),m=in.nextInt();
		int[] A=new int[n];
		for(int i=0;i<n;i++)A[i]=in.nextInt();
		Node root=new Node();
		for(int i=0;i<n;i++) {
			insert(root,A[i],i,0,n-1);
		}
		for(int i=0;i<m;i++) {
			int type=in.nextInt();
			if(type==1) {
				update(root,in.nextInt()-1,in.nextInt()-1,0,n-1);
			}else {
				out.println(query(root,in.nextInt()-1,in.nextInt()-1,0,n-1));
			}
		}
	}
	
	private long query(Node node, int s, int e, int l, int r) {
		if(l>=s&&r<=e) {
			return node.sum;
		}
		Node lnode=getLnode(node);
		Node rnode=getRnode(node);
		long ret=0;
		int m=(l+r)/2;
		if(m>=s) {
			ret+=query(lnode,s,e,l,m);
		}
		if(m<e) {
			ret+=query(rnode,s,e,m+1,r);
		}
		return ret;
	}
	
	private void update(Node node,int s, int e,int l,int r) {
		if(l==r) {
			node.sum=dp[(int)node.sum];
			if(dp[(int)node.sum]==node.sum)node.cnt--;
			return;
		}
		Node lnode=getLnode(node);
		Node rnode=getRnode(node);
		int m=(l+r)/2;
		if(m>=s&&lnode.cnt>0) {
			update(lnode,s,e,l,m);
		}
		if(m<e&&rnode.cnt>0) {
			update(rnode,s,e,m+1,r);
		}
		node.sum=lnode.sum+rnode.sum;
		node.cnt=lnode.cnt+rnode.cnt;
	}
	
	private void insert(Node node, long v,int idx, int l, int r) {
		if(l==r) {
			node.sum=v;
			if(dp[(int)v]!=v)node.cnt++;
			return;
		}
		int m=(l+r)/2;
		Node lnode=getLnode(node);
		Node rnode=getRnode(node);
		if(idx<=m) {
			insert(lnode,v,idx,l,m);
		}else {
			insert(rnode,v,idx,m+1,r);
		}
		node.cnt=lnode.cnt+rnode.cnt;
		node.sum=lnode.sum+rnode.sum;
	}
	
	private Node getRnode(Node node) {
		if(node.rnode==null) node.rnode=new Node();
		return node.rnode;
	}
	
	private Node getLnode(Node node) {
		if(node.lnode==null) node.lnode=new Node();
		return node.lnode;
	}
	
	class Node{
		Node lnode,rnode;
		int cnt;
		long sum;
	}
}	



class FastReader
{
	BufferedReader br;
	StringTokenizer st;

	public FastReader()
	{
		br=new BufferedReader(new InputStreamReader(System.in));
	}

	public String next() 
	{
		if(st==null || !st.hasMoreElements())
		{
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return st.nextToken();
	}

	public int nextInt() 
	{
		return Integer.parseInt(next());
	}

	public long nextLong()
	{
		return Long.parseLong(next());
	}
}