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;
const int mod = 1e9 + 7;
int spf[1000001];
void sieve() {
  spf[1] = 1;
  for (int i = 2; i < 1000001; i++) spf[i] = i;
  for (int i = 4; i < 1000001; i += 2) spf[i] = 2;
  for (int i = 3; i * i < 1000001; i++) {
    if (spf[i] == i) {
      for (int j = i * i; j < 1000001; j += i)
        if (spf[j] == j) spf[j] = i;
    }
  }
}
const int N = 1e6 + 10;
long long cnt[N];
long long segtree[4 * N];
vector<long long> v;
void build(int node, int l, int r) {
  if (l == r) {
    segtree[node] = v[l];
    return;
  }
  int mid = (l + r) / 2;
  build(2 * node, l, mid);
  build(2 * node + 1, mid + 1, r);
  segtree[node] = segtree[2 * node] + segtree[2 * node + 1];
}
void update(int node, int l, int r, int pos, long long val) {
  if (l == r) {
    segtree[node] = val;
    return;
  }
  if (l > r) return;
  int mid = (l + r) / 2;
  if (pos <= mid)
    update(2 * node, l, mid, pos, val);
  else
    update(2 * node + 1, mid + 1, r, pos, val);
  segtree[node] = segtree[2 * node] + segtree[2 * node + 1];
}
long long get(int node, int l, int r, int beg, int end) {
  if (l == beg && r == end) return segtree[node];
  if (l > r || beg > end) return 0LL;
  int mid = (l + r) / 2;
  return get(2 * node, l, mid, beg, min(end, mid)) +
         get(2 * node + 1, mid + 1, r, max(beg, mid + 1), end);
}
void solve() {
  sieve();
  int n, m;
  cin >> n >> m;
  v = vector<long long>(n);
  for (auto& x : v) cin >> x;
  build(1, 0, n - 1);
  memset(cnt, 0, sizeof(cnt));
  cnt[1] = 1;
  for (int i = 2; i <= 240; i++) {
    map<int, int> M;
    int j = i;
    while (spf[j] != 1) {
      M[spf[j]]++;
      j /= spf[j];
    }
    long long pro = 1;
    for (auto p : M) {
      pro *= (p.second + 1);
    }
    cnt[i] = pro;
  }
  for (int i = 0; i < n; i++) {
    if (cnt[v[i]] != 0) continue;
    map<int, int> M;
    int j = v[i];
    while (spf[j] != 1) {
      M[spf[j]]++;
      j /= spf[j];
    }
    long long pro = 1;
    for (auto p : M) {
      pro *= (p.second + 1);
    }
    cnt[v[i]] = pro;
  }
  set<int> indices;
  for (int i = 0; i < n; i++) indices.insert(i);
  while (m--) {
    int type, l, r;
    cin >> type >> l >> r;
    l--, r--;
    int x = l;
    if (type == 1) {
      while (true) {
        auto ip = indices.lower_bound(x);
        if (ip == indices.end()) break;
        int num = *ip;
        if (num > r) break;
        int y = cnt[v[num]];
        v[num] = y;
        if (y <= 2) indices.erase(num);
        x = num + 1;
        update(1, 0, n - 1, num, y);
      }
    } else {
      cout << get(1, 0, n - 1, l, r) << '\n';
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int tests = 1;
  while (tests--) {
    solve();
  }
}
