#pragma GCC optimize("Ofast", "unroll-loops") // #define TEST #define _USE_MATH_DEFINES #include using namespace std; #define ll long long vector divisor(ll k){ vector d; for (ll i = 1;i * i <= k;++i){ if (k % i == 0){ d.push_back(i); if (i * i != k) d.push_back(k / i); } } sort(d.begin(),d.end()); return d; } struct UnionFind{ vector data; /* constructor */ UnionFind(int sz){ data.assign(sz,-1); } /* merge the set to which x belongs and the set to which y belongs */ bool unite(int x,int y){ x = find(x); y = find(y); if (x == y) return false; if (data[x] > data[y]) swap(x, y); data[x] += data[y]; data[y] = x; return true; } /* find the root of k */ int find(int k){ if (data[k] < 0) return k; return data[k] = find(data[k]); } /* calculate the size of the set to which k belongs */ int size(int k){ return -data[find(k)]; } }; int main(void){ int L, R; cin >> L >> R; UnionFind uf(R - L + 1); for (int i = 0; i < R - L + 1; ++i){ int x = L + i; auto d = divisor(x); for (auto di : d){ if (di != x && L <= di && di <= R){ int idx = di - L; uf.unite(idx, i); } } } set parent; for (int i = 0; i < R - L + 1; ++i) parent.insert(uf.find(i)); cout << (parent.size() - 1) << endl; return 0; }