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
#include <bits/stdc++.h>
using namespace std;
vector<int> prime(2000000);
void sieve() {
  prime[0] = prime[1] = 1;
  for (int i = 2; i < 2000000; i++) prime[i] = i;
  for (int i = 2; i * i < 2000000; i++) {
    if (prime[i] == i) {
      for (int j = i * i; j < 2000000; j += i) {
        if (prime[j] == j) prime[j] = i;
      }
    }
  }
}
int factors(int x) {
  int fact = 1;
  while (x > 1) {
    int p = prime[x];
    int c = 0;
    while (x % p == 0) {
      c++;
      x = x / p;
    }
    fact *= (c + 1);
  }
  return fact;
}
struct node {
  bool ch;
  long long sum;
} tree[300005 << 2];
long long arr[300005];
void build(int i, int tl, int tr) {
  if (tl == tr) {
    if (arr[tl] <= 2)
      tree[i].ch = true;
    else
      tree[i].ch = false;
    tree[i].sum = arr[tl];
    return;
  }
  int m = (tl + tr) >> 1;
  build(i + i, tl, m);
  build(i + i + 1, m + 1, tr);
  tree[i].ch = tree[i + i].ch & tree[i + i + 1].ch;
  tree[i].sum = tree[i + i].sum + tree[i + i + 1].sum;
}
void update(int i, int tl, int tr, int l, int r) {
  if (tl > tr || tl > r || tr < l) return;
  if (tree[i].ch) return;
  if (tl == tr) {
    arr[tl] = factors(arr[tl]);
    if (arr[tl] <= 2)
      tree[i].ch = true;
    else
      tree[i].ch = false;
    tree[i].sum = arr[tl];
    return;
  }
  int m = (tl + tr) >> 1;
  update(i + i, tl, m, l, r);
  update(i + i + 1, m + 1, tr, l, r);
  tree[i].ch = tree[i + i].ch & tree[i + i + 1].ch;
  tree[i].sum = tree[i + i].sum + tree[i + i + 1].sum;
}
long long query(int i, int tl, int tr, int l, int r) {
  if (tl > tr || tl > r || tr < l) return 0LL;
  if (tl >= l && tr <= r) return tree[i].sum;
  int m = (tl + tr) >> 1;
  return query(i + i, tl, m, l, r) + query(i + i + 1, m + 1, tr, l, r);
}
int main() {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  int n, q;
  cin >> n >> q;
  sieve();
  for (int i = 0; i < n; i++) cin >> arr[i];
  build(1, 0, n - 1);
  while (q--) {
    int ty, l, r;
    cin >> ty >> l >> r;
    l--, r--;
    if (ty == 1) {
      update(1, 0, n - 1, l, r);
    } else {
      cout << query(1, 0, n - 1, l, r) << endl;
    }
  }
  return 0;
}
