Problem:
Problem H:
Fibonacci Sets
Fibonacci number
f
(
i
) appear in a variety of puzzles in nature and math, including packing problems, family trees or Pythagorean triangles. They obey the rule
f
(
i
) =
f
(
i
- 1) +
f
(
i
- 2), where we set
f
(0) = 1 =
f
(-1).
Let
V
and
d
be two certain positive integers and be
N
≡ 1001 a constant. Consider a set of
V
nodes, each node
i
having a Fibonacci label
F
[
i
] = (
f
(
i
) mod N) assigned for
i
= 1,...,
V
≤ N. If |
F
(
i
) -
F
(
j
)| <
d
, then the nodes
i
and
j
are connected.
Given
V
and
d
, how many connected subsets of nodes will you obtain?
Figure 1: There are 4 connected subsets for
V
= 20 and
d
= 100.
Input
Each data set is defined as one line with two integers as follows:
Line 1
: Number of nodes
V
and the distance
d
.
Input includes several data sets (i.e., several lines). The number of dat sets is less than or equal to 50.
Constraints
1 ≤ V ≤ 1000
1 ≤ d ≤ 150
Output
Output line contains one integer - the number of connected subsets - for each input line.
Sample Input
5 5
50 1
13 13
Output for the Sample Input
2
50
8

Submitted solutions:

code_snippet: #include <iostream>
using namespace std;

const int MAXN = 1001;

int P[MAXN], F[MAXN], V, D;
void init(int N) { // 初期化 はじめは全ての頂点はバラバラ
    for (int i=0; i<=N; ++i) P[i] = i;
}
int root(int a) { // a の root(代表元) を求める
    if (P[a] == a) return a; // a は root
    return (root(P[a])); // a の親の root を求め，a の親とする
}
void unite(int a, int b) { // a と b を同一グループにまとめる
    P[root(a)] = root(b);
}
int count() {
    int var = 0;
    for (int i=1; i<=V; i++) {
        if (root(i) == i) var++;
    }
    return var;
}
int ft_abs(int a) {
    if (a >= 0) return a;
    return -a;
}
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    F[0] = 1, F[1] = 2;
    for (int i=1; i<1001; i++) {
        F[i+1] = (F[i] + F[i-1]) % 1001; // ... F[i] に i 番目の Fibonacci 数 %1001 をあらかじめ計算, 代入しておく
    }
    while (cin >> V >> D) {
        init(V); // 木を初期化
        for (int i=1; i<=V; ++i) {
            for (int j=i+1; j<=V; ++j) {
                if (ft_abs(F[j]-F[i]) < D) { // (F[j] と F[i] の差の絶対値が D 未満だったら)
                    unite(i, j); // グループ i とグループ j を同一化;
                }
            }
        }
        cout << count() << '\n'; // i∈[1,V] に関して root(i) == i であるような数を数えて出力
    }
    return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 3200
final_rank: 20

code_snippet: #include<algorithm>
#include<bitset>
#include<cassert>
#include<cfloat>
#include<climits>
#include<cmath>
#include<deque>
#include<functional>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<string>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<vector>

using namespace std;

using lint = long long;
using P = pair<int, int>;
using LLP = pair<long long, long long>;

#define REP(i, x, n) for(int i = (x), i##_len = (int)(n) ; i < i##_len ; ++i)
#define rep(i, n) for(int i = 0, i##_len = (int)(n) ; i < i##_len ; ++i)
#define reps(i, n) for(int i = 1, i##_len = (int)(n) ; i <= i##_len ; ++i)
#define rrep(i, n) for(int i = (int)(n) - 1 ; i >= 0 ; --i)
#define rreps(i, n) for(int i = (int)(n) ; i > 0 ; --i)
#define SORT(x) sort((x).begin(), (x).end())
#define SORT_INV(x) sort((x).rbegin(), (x).rend())
#define REVERSE(x) reverse((x).begin(), (x).end())
#define TWINS(x) cout << ((x) ? "Yay!" : ":(") << '\n'
#define endl '\n'

constexpr int IINF = (1 << 30) - 1;
constexpr long long LLINF = 1LL << 61;
constexpr double EPS = 1e-10;

constexpr int dx4[] = {1, 0, -1, 0}, dy4[] = {0, 1, 0, -1};
constexpr int dx8[] = {1, 1, 0, -1, -1, -1, 0, 1}, dy8[] = {0, -1, -1, -1, 0, 1, 1, 1};

class UnionFind{
    vector<int> par;
    int groupCount;

public:
    UnionFind(int n = 0){
        init(n);
    }

    void init(int n = 0){
        par.resize(n);
        fill(par.begin(), par.end(), -1);

        groupCount = n;

        return;
    }

    int root(int x){
        if(par[x] < 0){
            return x;
        }
        return par[x] = root(par[x]);
    }

    bool same(int x, int y){
        return root(x) == root(y);
    }

    int size(int x){
        return -par[root(x)];
    }

    bool unite(int x, int y){
        x = root(x);
        y = root(y);

        if(x == y){
            return false;
        }

        if(par[y] < par[x]){
            swap(x, y);
        }

        par[x] += par[y];
        par[y] = x;
        --groupCount;

        return true;
    }

    int size(void){
        return groupCount;
    }
};

template<typename T>
bool chmax(T& a, T b){
    if(a < b){
        a = b;
        return true;
    }
    return false;
}

template<typename T>
bool chmin(T& a, T b){
    if(b < a){
        a = b;
        return true;
    }
    return false;
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);

    constexpr int n = 1001;

    int fib[n + 1];
    fib[0] = 1;
    fib[1] = 2;
    REP(i, 2, n + 1){
        fib[i] = (fib[i - 1] + fib[i - 2]) % n;
    }

    int v, d;
    while(cin >> v >> d){
        UnionFind uf(v + 1);
        for(int i = 1 ; i <= v ; ++i){
            for(int j = 1 ; j <= v ; ++j){
                if(abs(fib[i] - fib[j]) < d){
                    uf.unite(i, j);
                }
            }
        }
        cout << uf.size() - 1 << endl;
    }

    cout << flush;

    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3096
final_rank: 13

code_snippet: #include <iostream>
#include <vector>
#include <unordered_set>
#include <algorithm>
#include <cassert>
using namespace std;

class DisjointSet {
private:
	const int vertex_n;
	vector<int> P;		//添え字の頂点の根
	vector< unordered_set<int> > Set;		//添え字の頂点に子として繋がっている頂点の集合
public:
	DisjointSet(int n);
	void unite(int x, int y);
	bool same(int x, int y);
	int tree_number();
};

DisjointSet::DisjointSet(int n) : vertex_n(n), P(n), Set(n) {
	for (int i = 0; i<n; ++i) {
		P[i] = i;
		Set[i].insert(i);
	}
}

void DisjointSet::unite(int x, int y) {
	if (P[x] == P[y])
		return;
	int big, small;
	if (Set[P[x]].size() >= Set[P[y]].size()) {
		big = P[x];
		small = P[y];
	}
	else {
		big = P[y];
		small = P[x];
	}
	for (auto i = Set[small].begin(); i != Set[small].end(); ++i) {
		P[*i] = big;
		Set[big].insert(*i);
	}
}

bool DisjointSet::same(int x, int y) {
	return P[x] == P[y];
}

int DisjointSet::tree_number() {
	int sum = 0;
	for (int i = 0; i < vertex_n; i++)
		if (P[i] == i)
			sum++;
	return sum;
}

const int N = 1001;
int F[1001];

int main() {
	int V, d;
	F[0] = 1; F[1] = 2;
	for (int i = 2; i < N; i++)
		F[i] = (F[i - 1] % N + F[i - 2] % N) % N;
	while (cin >> V >> d) {
		DisjointSet fs(V + 1);
		for (int i = 1; i <= V; i++)
			for (int j = i + 1; j <= V; j++) {
				if (max(F[i], F[j]) - min(F[i], F[j]) < d)
					fs.unite(i, j);
			}
		cout << fs.tree_number() - 1 << endl;
	}
}
accuracy: 1
time_ms: 10
memory_kb: 3228
final_rank: 14

code_snippet: #include <bits/stdc++.h>

#define FOR(i,a,b) for(int i= (a); i<((int)b); ++i)
#define RFOR(i,a) for(int i=(a); i >= 0; --i)
#define FOE(i,a) for(auto i : a)
#define ALL(c) (c).begin(), (c).end()
#define RALL(c) (c).rbegin(), (c).rend()
#define DUMP(x)  cerr << #x << " = " << (x) << endl;
#define SUM(x) std::accumulate(ALL(x), 0LL)
#define MIN(v) *std::min_element(v.begin(), v.end())
#define MAX(v) *std::max_element(v.begin(), v.end())
#define EXIST(v,x) (std::find(v.begin(), v.end(), x) != v.end())
#define BIT(n) (1LL<<(n))
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());

typedef long long LL;
template<typename T> using V = std::vector<T>;
template<typename T> using VV = std::vector<std::vector<T>>;
template<typename T> using VVV = std::vector<std::vector<std::vector<T>>>;

template<class T> inline T ceil(T a, T b) { return (a + b - 1) / b; }
template<class T> inline void print(T x) { std::cout << x << std::endl; }
template<class T> inline void print_vec(const std::vector<T> &v) { for (int i = 0; i < v.size(); ++i) {  if (i != 0) {std::cout << " ";} std::cout << v[i];} std::cout << "\n"; }
template<class T> inline bool inside(T y, T x, T H, T W) {return 0 <= y and y < H and 0 <= x and x < W; }
template<class T> inline double euclidean_distance(T y1, T x1, T y2, T x2) { return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); }
template<class T> inline double manhattan_distance(T y1, T x1, T y2, T x2) { return abs(x1 - x2) + abs(y1 - y2); }

const int INF = 1L << 30;
const double EPS = 1e-9;
const std::string YES = "YES", Yes = "Yes", NO = "NO", No = "No";
const std::vector<int> dy4 = { 0, 1, 0, -1 }, dx4 = { 1, 0, -1, 0 };    // 4近傍（右, 下, 左, 上）
const std::vector<int> dy8 = { 0, -1, 0, 1, 1, -1, -1, 1 }, dx8 = { 1, 0, -1, 0, 1, 1, -1, -1 };

using namespace std;

void dfs(int i, const vector<vector<int>> &g, vector<bool> &used) {
    used[i] = true;
    FOE(j, g[i]) {
        if (not used[j]) {
            dfs(j, g, used);
        }
    }
}

int main() {
    cin.tie(0);
	ios::sync_with_stdio(false);

	vector<int> fib(1100);
	fib[0] = 1;
	fib[1] = 2;
	FOR(i, 2, fib.size()) {
	    fib[i] = (fib[i - 1] + fib[i - 2]) % 1001;
	}

	int V, D;
    while (cin >> V >> D) {

        vector<vector<int>> g(V + 1);
        FOR(i, 1, V + 1) {
            FOR(j, 1, V + 1) {
                if (abs(fib[i] - fib[j]) < D) {
                    g[i].emplace_back(j);
                    g[j].emplace_back(i);
                }
            }
        }

        int ans = 0;
        vector<bool> used(V, false);
        FOR(i, 1, V + 1) {
            if (used[i]) {
                continue;
            }
            ans++;
            dfs(i, g, used);
        }
        print(ans);

    }

	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 6772
final_rank: 19

code_snippet: #include <iostream>
#include <vector>
#include <cstdlib>
#include <utility>
#include <algorithm>

using namespace std;

const int N = 1001;
vector<int> F, djset, szset;
//vector<pair<int, pair<int, int>>> G;

int root(int v)
{
    int r = djset[v];
    while (r != djset[r]) r = djset[r];
    djset[v] = r;
    return r;
}

bool same(int v1, int v2)
{
    return (root(v1) == root(v2));
}

void unite(int v1, int v2)
{
    int r[2] = {root(v1), root(v2)};
    if (szset[r[1]] > szset[r[0]]) swap(r[0], r[1]);
    djset[r[1]] = r[0];
    szset[r[0]] += szset[r[1]];
    szset[r[1]] = 0;
}

int main(void)
{
    int V, D;
    F.resize(N);
    F[0] = 2;
    F[1] = 3;
    for (int i = 2; i < N; i++) F[i] = (F[i - 1] + F[i - 2]) % N;
    while (cin >> V >> D)
    {
        djset.resize(V);
        szset.resize(V, 1);
        for (int i = 0; i < V; i++) djset[i] = i;
        for (int i = 0; i < V; i++)
        {
            for (int j = 0; j < V; j++)
            {
                if (abs(F[i] - F[j]) >= D || same(i, j)) continue;
                unite(i, j);
            }
        }
        int ans = 0;
        for (auto i : szset) if (i) ans++;
        cout << ans << endl;
        djset.clear();
        szset.clear();
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3040
final_rank: 12

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <functional>
#include <numeric>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <utility>
#include <sstream>
#include <complex>
#include <fstream>
#include <bitset>

using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;
typedef vector<ll> V;
typedef complex<double> Point;

#define PI acos(-1.0)
#define EPS 1e-10
const ll INF = 1e9 + 7;
const ll MOD = 1e9 + 7;

#define FOR(i,a,b) for(long long i=(a);i<(b);i++)
#define REP(i,N) for(long long i=0;i<(N);i++)
#define ALL(s) (s).begin(),(s).end()
#define EQ(a,b) (abs((a)-(b))<EPS)
#define EQV(a,b) ( EQ((a).real(), (b).real()) && EQ((a).imag(), (b).imag()) )
#define fi first
#define se second

const int N = 1001;
int v, d;
int f[100100];

struct UnionFind{
	int par[201000];
	int rank[201000];

	void init(int n){
		for (int i = 0; i < 201000; i++){
			par[i] = i;
			rank[i] = 1;
		}
	}

	int find(int x){
		if (par[x] == x) return x;
		return par[x] = find(par[x]);
	}

	void unite(int x, int y){
		x = find(x);
		y = find(y);
		if (x == y)return;
		if (rank[x] < rank[y]){
			par[x] = y;
		}
		else{
			par[y] = x;
			if (rank[y] == rank[x])rank[x]++;
		}
	}

	bool same(int x, int y){
		return find(x) == find(y);
	}
};

UnionFind uf;

int main(){
	f[0] = 1, f[1] = 2;
	FOR(i,2, 10000){
		f[i] = f[i - 1] + f[i - 2];
		f[i] %= N;
	}
	while (cin >> v >> d){
		set<int> si;
		uf.init(v);
		REP(i, v){
			REP(j, v){
				if (abs(f[i + 1] - f[j + 1]) < d)uf.unite(i + 1, j + 1);
			}
		}
		REP(i, v){
			si.insert(uf.find(i + 1));
		}
		cout << si.size() << endl;
	}
}
accuracy: 1
time_ms: 20
memory_kb: 4620
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std ;

#define pb(n) push_back(n)
#define fi first
#define se second
#define all(r) begin(r),end(r)
#define vmax(ary) *max_element(all(ary))
#define vmin(ary) *min_element(all(ary))
#define debug(x) cout<<#x<<": "<<x<<endl
#define fcout(n) cout<<fixed<<setprecision((n))
#define scout(n) cout<<setw(n)
#define vary(type,name,size,init) vector< type> name(size,init)
#define vvl(v,w,h,init) vector<vector<ll>> v(w,vector<ll>(h,init))
#define mp(a,b) make_pair(a,b)

#define rep(i,n) for(int i = 0; i < (int)(n);++i)
#define REP(i,a,b) for(int i = (a);i < (int)(b);++i)
#define repi(it,array) for(auto it = array.begin(),end = array.end(); it != end;++it)
#define repa(n,array) for(auto &n :(array))

using ll = long long;
using pii = pair<int,int> ;
using pll = pair<ll,ll> ;

const int mod = 1000000007;
constexpr ll inf = ((1<<30)-1)*2+1 ;
constexpr double PI = acos(-1.0) ;
double eps = 1e-10 ;
const int dy[] = {-1,0,1,0,1,-1,1,-1};
const int dx[] = {0,-1,0,1,1,-1,-1,1};
const int N = 1001;

vector<int> g[N+4];
ll v,d;
void add_edge(int from,int to){
  g[from].push_back(to);
  g[to].push_back(from);
}
vector<ll> f(N+4,0);

void dfs(int k,int c){
  if(f[k] == c) return ;
  f[k] = c;
  for(auto &&e : g[k]){
    dfs(e,c);
  }
}

int solve(){
  int res = 0;
  f = vector<ll>(N+4,0);
  REP(i,2,v+2){
    if(f[i] == 0){
      ++res;
      dfs(i,res);
    }
  }
  return res;
}

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  int fib[N+4];
  fib[0] = 1,fib[1] = 1;
  REP(i,2,N+4){
    fib[i] = (fib[i-1] + fib[i-2]) % N;
  }
  while(cin >> v >> d){
    rep(i,N+4){
      g[i].clear();
    }
    REP(i,2,v+2){
      REP(j,i+1,v+2){
        if(abs(fib[i] - fib[j]) < d){
          add_edge(i,j);
        }
      }
    }
    cout << solve()<< endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 5060
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;

#define int long long
typedef vector<int>vint;
typedef pair<int,int>pint;
typedef vector<pint>vpint;
#define rep(i,n) for(int i=0;i<(n);i++)
#define reps(i,f,n) for(int i=(f);i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define each(it,v) for(__typeof((v).begin()) it=(v).begin();it!=(v).end();it++)
#define pb push_back
#define fi first
#define se second
template<typename A,typename B>inline void chmin(A &a,B b){if(a>b)a=b;}
template<typename A,typename B>inline void chmax(A &a,B b){if(a<b)a=b;}

struct UF{
    vector<int>par,sz;
    void init(int n){
        par.resize(n);
        sz.resize(n);
        for(int i=0;i<n;i++){
            par[i]=i;
            sz[i]=1;
        }
    }
    int find(int x){
        return x==par[x]?x:par[x]=find(par[x]);
    }
    void unite(int x,int y){
        x=find(x);y=find(y);
        if(x==y)return;
        sz[x]+=sz[y];
        par[y]=x;
    }
    bool same(int x,int y){
        return find(x)==find(y);
    }
    int size(int x){
        return sz[find(x)];
    }
};

signed main(){
    int V,d;
    while(cin>>V>>d){
        int a=1,b=1;
        UF uf;uf.init(V);
        int F[1000];
        rep(i,V){
            F[i]=(a+b)%1001;

            b=a;a=F[i];
        }
        rep(i,V)rep(j,V)if(abs(F[i]-F[j])<d)uf.unite(i,j);
        int ans=0;
        rep(i,V)if(uf.find(i)==i)ans++;
        cout<<ans<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 2984
final_rank: 11

code_snippet: #include <bits/stdc++.h>

using namespace std;

struct UnionFind{
  vector<int> data;
  UnionFind(int n)
  {
    data.assign(n, -1);
  }
  int find(int k)
  {
    if(data[k] < 0) return k;
    return data[k] = find(data[k]);
  }
  void unite(int x, int y)
  {
    x = find(x), y = find(y);
    if(x == y) return;
    if(x > y) swap(x, y);
    data[x] += data[y];
    data[y] = x;
  }
  int size(int k)
  {
    return -data[find(k)];
  }
};

int memo[1010];

int fib(int v)
{
  if(v <= 0) return 1;
  if(~memo[v]) return memo[v];
  return memo[v] = (fib(v-1) + fib(v-2)) % 1001;
}

int main()
{
  int V, d;
  int F[1010];
  memset(memo, -1, sizeof(memo));
  for(int i = 0; i < 1000; i++) F[i] = fib(i+1);
  while(cin >> V >> d){
    UnionFind uf(V);
    for(int i = 0; i < V; i++){
      for(int j = i+1; j < V; j++){
	if(abs(F[i] - F[j]) < d) uf.unite(i, j);
      }
    }
    int cnt = 0;
    for(int i = 0; i < V; i++){
      if(uf.data[i] < 0) cnt++;
    }
    cout << cnt << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1208
final_rank: 1

code_snippet: #include <bits/stdc++.h>
#define N 1001
using namespace std;
int V,d;
int used[1010];
int f[1010]={2,3};

void dfs(int pos){
  if(used[pos])return;
  used[pos]=1;
  for(int i=0;i<V;i++)if(abs(f[pos]-f[i])<d) dfs(i);
}


int main(){

  for(int i=2;i<1010;i++) f[i]=(f[i-2]+f[i-1])%N;
  
  while(cin>>V>>d){
    memset(used,0,sizeof(used));
    int ans=0;
    for(int i=0;i<V;i++) if(!used[i])ans++,dfs(i);
    cout <<ans<<endl;
  }

  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 1196
final_rank: 4

code_snippet: #include<iostream>
#include<set>
using namespace std;

int nlist[1010];

int abs(int a){
  return ((a > 0) ?(a) : (-(a)));
}

int parent(int i){
  if(nlist[i] == i) return i;
  return (nlist[i]=parent(nlist[i]));
}

int main(){
  int v,d;
  int fib[1010];
  fib[0]=fib[1]=1;
  for(int i=2;i<1010;i++){
    fib[i] = (fib[i-1]+fib[i-2])%1001;
  }
  while(cin>>v>>d){
    set<int> s;
    for(int i=0;i<v;i++) nlist[i]=i;
    for(int i=0;i<v;i++){
      for(int j=i+1;j<v;j++){
	if(abs(fib[i+2]-fib[j+2]) < d){
	  nlist[parent(j)] = parent(nlist[i]);
	}      
      }
    }
    for(int i=0;i<v;i++) s.insert(parent(i));
    cout<<s.size()<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 1204
final_rank: 5

code_snippet: #include <iostream>
#include <vector>
#include <cstdlib>
using namespace std;

const int N = 1001;
int F[1001];
int V, d;

vector<int> Alist[1001];

int f(int n)
{
  if (n == -1) return 1;
  else if (n == 0) return 1;
  else if (n <= 1000) return F[n];
  else return -1;
}

void dfs(int v, bool *visited)
{
  visited[v] = true;
  for (int i=0;i<Alist[v].size();i++)
  {
    int w = Alist[v][i];
    if (!visited[w]) dfs(w, visited);
  }
  return;
}


int num_components()
{
  bool visited[1001];
  int n = 0;
  for (int i=1;i<=V;i++) visited[i]=false;
  for (int v=1;v<=V;v++)
  {
    if (!visited[v])
    {
      dfs(v, visited);
      n++;
    }
  }
  return n;
}

int main()
{
  while (cin >> V >> d)
  {
    for (int i=1;i<=V;i++)
      F[i] = ((f(i-1) % N)+ (f(i-2) % N)) % N;

    for (int i=1;i<=V;i++) Alist[i].clear();
    for (int i=1;i<=V;i++)
    {
      for (int j=i+1;j<=V;j++)
      {
        if (abs(f(i)-f(j)) < d)
        {
          Alist[i].push_back(j);
          Alist[j].push_back(i);
        }
      }
    } // Graph created
    int res = num_components();
    cout << res << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3192
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define for_(i,a,b) for(int i=(a);i<(b);++i)

int V, d;
vector< vector< int > > adj;
vector< bool > vis;
vector< int > F;

void dfs(int v) {
	vis[v] = true;
	for (int u : adj[v]) if (!vis[u]) dfs(u);
}

int main() {
	vector< int > F(1001);
	F[0] = 1; F[1] = 2;
	
	for_(i,2,1001) F[i] = (F[i - 1] + F[i - 2]) % 1001;
	
	while (cin >> V >> d) {
		adj.assign(V + 1, vector< int >());
		
		for_(u,1,V+1) for_(v,u+1,V+1) {
			if (abs(F[u] - F[v]) < d) {
				adj[u].push_back(v);
				adj[v].push_back(u);
			}
		}
		
		vis.assign(V + 1, false);
		
		int ans = 0;
		
		for_(v,1,V+1) {
			if (vis[v]) continue;
			dfs(v);
			++ans;
		}
		
		cout << ans << endl;
	}
}
accuracy: 1
time_ms: 10
memory_kb: 4976
final_rank: 17

code_snippet: #include <iostream>
#include <cstdlib>
#include <cmath>

using namespace std;

long long  F[1001];

int P[10010];
void init(int N){
    for(int i=0;i<=N;i++)
        P[i] = i;
}

int root(int a){
    if(P[a]==a)
        return a;
    return(P[a] = root(P[a]));
}

bool is_same_set(int a, int b){
    return root(a) == root(b);
}

void unit(int a, int b){
    P[root(a)] = root(b);
}

int main(){
    F[0] = 1; F[1]=2;
    for(int i=2;i<=1000;i++){
        F[i] = F[i-1]+F[i-2];
        F[i] %= 1001;
    }
    int V,d;
    while(cin >> V >> d){
        int count=0;
        init(V);
        for(int i=1;i<=V;i++){
            for(int j=i+1; j<=V;j++){
                if(abs(F[j]-F[i])<d){
                    unit(i,j);
                }
            }
        }
        for(int i=1;i<=V;i++){
            if(root(i)==i)
                count++;
        }
        cout << count << endl;
    }
}
accuracy: 1
time_ms: 20
memory_kb: 1180
final_rank: 3

code_snippet: #include <iostream>
#include <algorithm>
#include <string>
#include <stack>
#include <cstdlib>
#include <queue>
#include <vector>
#include <set>
#include <stdio.h>
#include <cstdio>
using namespace std;
int p[1005];
int root(int a) {
	if (p[a] == a) return a;
	return (p[a] = root(p[a]));
}
void unite(int a,int b){
	p[root(a)] = root(b);
}
void same(int a ,int b){
	if (root(a) == root(b)) cout << "1" <<endl;
	else cout << "0" << endl;
}
bool rcheck(int a){
	if (root(a) == a) return 1;
	else return 0;
}
long long int F[1005];
int main() {
	int V,D;
	F[0]=1, F[1] =2;
	for (int i = 2;i< 1005;i++ ){
		F[i] = F[i-1]%1001 + F[i-2]%1001; 
		F[i] = F[i]%1001;
	}
	while ( cin >> V >> D) {
		int cou = 0;
		for (int i = 0; i < 1001; i++){
		p[i] = i;
		}
		for (int i=1;i <= V;i++) {
			for (int j=i+1;j <= V;j++ ){
				if (F[j] - F[i] < D && F[j] - F[i] > - D )
					unite(i,j);
			}

			}
		for (int i = 1;i <= V;i++){
			if (rcheck(i) == 1) {
				cou += 1;
			}
		}
		cout << cou <<  endl;
}
	}
accuracy: 1
time_ms: 30
memory_kb: 1172
final_rank: 8

code_snippet: #include <iostream>
#include <vector>
#include <math.h>
#include <stdio.h>
#include <algorithm>
#include <string>
#include <map>
#include <queue>
#include <memory.h>
using namespace std;

int par[1000];
int Rank[1000];

void init(int n) {
  for(int i = 0; i < n; i++) {
    par[i] = i;
    Rank[i] = 0;
  }
}

int find(int x) {
  if(par[x] == x) {
    return x;
  }
  return par[x] = find(par[x]);
}

void unite(int x, int y) {
  x = find(x);
  y = find(y);
  if(x == y) return;

  if(Rank[x] < Rank[y]) {
    par[x] = y;
  } else {
    par[y] = x;
    if(Rank[x] == Rank[y]) Rank[x]++;
  }
}

bool same(int x, int y) {
  return find(x) == find(y);
}

int main() {
  int V,d;
  long long fib[1000];
  fib[0] = 2L;
  fib[1] = 3L;
  for(int i = 2; i < 1000; i++) {
    fib[i] = (fib[i-1] + fib[i-2]) % 1001;
  }
  while(cin >> V >> d) {
    init(V);
    for(int i = 0; i < V; i++) {
      for(int j = 0; j < V; j++) {
        if(abs(fib[i] - fib[j]) < d) {
          unite(i,j);
        }
      }
    }
    int count = 0;
    for(int i = 0; i < V; i++) {
      if(find(i) == i) count++;
    }
    printf("%d\n",count);

  }



}
accuracy: 1
time_ms: 30
memory_kb: 1160
final_rank: 7

code_snippet: #include<iostream>
#include<vector>
#include<cmath>
#include<algorithm>
#define loop(i,a,b) for(int i=a;i<b;i++)
#define rep(i,a) loop(i,0,a)
#define N 1001
using namespace std;

int main(){
	int V,d;
	while(cin>>V){
		cin>>d;
		int rank[V+1],parent[V+1],label[V+1];
		label[0]=1;
		label[1]=2;
		rep(i,V+1){
			rank[i]=1;
			parent[i]=i;
			if(i>=2)label[i]=(label[i-1]+label[i-2])%N;
		}
		loop(i,1,V+1){
			loop(j,1,V+1){
				if(abs(label[i]-label[j])<d){
					int now1=i,now2=j;
					while(parent[now1]!=now1){
						now1=parent[now1];
					}
					while(parent[now2]!=now2){
						now2=parent[now2];
					}
					if(rank[now1]>rank[now2]){
						parent[now2]=now1;
					}else if(rank[now1]<rank[now2]){
						parent[now1]=now2;
					}else{
						parent[now2]=now1;
						rank[now1]++;
					}
				}
			}
		}
		int cnt=0;
		loop(i,1,V+1){
			if(parent[i]==i)cnt++;
		}
		cout<<cnt<<endl;
	}
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 1172
final_rank: 2

code_snippet: #include<iostream>
#include<cmath>
#include<vector>
#include<string>
typedef unsigned long long ull;
#define rep(i,a) for(int i=0;i<a;i++)
#define loop(i,a,b) for(int i=a;i<b;i++)
using namespace std;
const double eps = 1e-10;
const double pi = acos(-1);
const double inf = (int)1e8;

const int MAX_N = 1001;
int f[MAX_N+1] = {2,3};

struct Union_Find{
  vector<int> par,rank;
  
  void init(int n){
    par.resize(n); rank.resize(n);
    for(int i = 0 ; i < n ; i ++){
      par[i] = i;
      rank[i] = 0;
    }
  }
  
  int find(int s){
    if(par[s] == s)return s;
    return par[s] = find(par[s]);
  }

  void unite(int x,int y){
    int a = find(x),  b = find(y);
    if(a==b)return ;
    if(rank[a] < rank[b]) par[a] = b;
    else{
      par[a] = b;
      if(rank[a] == rank[b]){
	rank[b]++;
      }
    }
  }
  bool same(int x,int y){
    return find(x)==find(y);
  }

  bool size(int x,int y){
    return par.size();
  }
};

void fib_init(){
  loop(i,2,MAX_N+1){
    f[i] = (f[i-1] + f[i-2])%MAX_N;
  }
}

void solve(){
  fib_init();
  
  int V,D;
  while(cin>>V>>D){
    Union_Find uf;
    uf.init(V);
    int memo[MAX_N+1] = {0};
    rep(i,V){
      loop(j,i+1,V){
	if(abs(f[i]-f[j])<D){
	  uf.unite(i,j);
	}
      }
    }
    int ans = 0;
    rep(i,V){
      int root = uf.find(i);
      if(memo[root]==0){
	memo[root]=1;
	ans ++;
      }
    }
    cout<<ans<<endl;
    
  }
}

int main(void){
  solve();
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 1208
final_rank: 6

code_snippet: #ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>

//#ifdef __GXX_EXPERIMENTAL_CXX0X__
#include <ccomplex>
#include <cfenv>
#include <cinttypes>
#include <cstdbool>
#include <cstdint>
#include <ctgmath>
#include <cwchar>
#include <cwctype>
//#endif

#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>

#include <array>
//#include <atomic>
#include <chrono>
//#include <condition_variable>
#include <forward_list>
//#include <future>
#include <initializer_list>
//#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <system_error>
//#include <thread>
#include <tuple>
#include <typeindex>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>


using namespace std;

template<typename T>
class UF
{
public:
	UF ()
	{
		count = 0;
	}

	void push ( T a )
	{
		M[a] = count;
		V.push_back ( count );
		rank.push_back ( 0 );
		count++;
	}

	void unite ( T a , T b )
	{
		long long int x = find ( M[a] );
		long long int y = find ( M[b] );
		if( x == y )return;
		if( rank[x] < rank[y] )
		{
			V[x] = y;
		} else
		{
			V[y] = x;
			if( rank[x] == rank[y] )rank[x]++;
		}
	}
	void merge ( T a , T b )
	{
		unite ( a , b );
	}
	bool same ( T a , T b )
	{
		return find ( M[a] ) == find ( M[b] );
	}
	long long int group ()
	{
		set<long long int>S;
		for( long long int i = 0; i < V.size (); i++ )
		{
			S.insert ( find ( V[i] ) );
		}
		return S.size ();
	}

private:
	vector<long long int> V , rank;
	map < T , long long int>M;
	long long int count;

	long long int find ( long long int x )
	{
		if( V[x] == x )return x;
		else return V[x] = find ( V[x] );
	}
};

int main ()
{
	int V , d;
	int data[1001] = {};
	data[0] = 2;
	data[1] = 3;
	for( size_t i = 2; i < 1001; i++ )
	{
		data[i] = data[i - 1] + data[i - 2];
		data[i] %= 1001;
	}

	while( cin >> V >> d )
	{
		UF<int> uf;
		for( size_t i = 0; i < V; i++ )
		{
			uf.push ( i );
		}
		for( size_t i = 0; i < V; i++ )
		{
			for( size_t j = i + 1; j < V; j++ )
			{
				if( abs ( data[i] - data[j] ) < d )
				{
					uf.merge ( i , j );
				}
			}
		}
		cout << uf.group () << endl;
	}
}
accuracy: 1
time_ms: 30
memory_kb: 1304
final_rank: 9

code_snippet: #ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>

//#ifdef __GXX_EXPERIMENTAL_CXX0X__
#include <ccomplex>
#include <cfenv>
#include <cinttypes>
#include <cstdbool>
#include <cstdint>
#include <ctgmath>
#include <cwchar>
#include <cwctype>
//#endif

#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>

#include <array>
//#include <atomic>
#include <chrono>
//#include <condition_variable>
#include <forward_list>
//#include <future>
#include <initializer_list>
//#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <system_error>
//#include <thread>
#include <tuple>
#include <typeindex>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>


using namespace std;

template<typename T>
class UF
{
public:
	UF ()
	{
		count = 0;
	}
	void push ( T a )
	{
		M[a] = count;
		V.push_back ( count );
		rank.push_back ( 0 );
		count++;
	}

	void unite ( T a , T b )
	{
		long long int x = find ( M[a] );
		long long int y = find ( M[b] );
		if( x == y )return;
		if( rank[x] < rank[y] )
		{
			V[x] = y;
		} else
		{
			V[y] = x;
			if( rank[x] == rank[y] )rank[x]++;
		}
	}
	void merge ( T a , T b )
	{
		unite ( a , b );
	}
	bool same ( T a , T b )
	{
		return find ( M[a] ) == find ( M[b] );
	}
	long long int group ()
	{
		set < long long int > S;
		for( long long int i = 0; i < V.size (); i++ )
		{
			S.insert ( find ( V[i] ) );
		}
		return S.size ();
	}

private:
	vector<long long int>V , rank;
	map < T , long long int>M;
	long long int count;

	long long int find ( long long int x )
	{
		if( V[x] == x )return x;
		else return V[x] = find ( V[x] );
	}
};

int main ()
{
	int V , d;
	int data[1001] = {};
	data[0] = 2;
	data[1] = 3;
	for( size_t i = 2; i < 1001; i++ )
	{
		data[i] = data[i - 1] + data[i - 2];
		data[i] %= 1001;
	}

	while( cin >> V >> d )
	{
		UF<int>* uf = new UF < int > ;
		set<int>S;
		for( size_t i = 0; i < V; i++ )
		{
			( *uf ).push ( i );
		}
		for( size_t i = 0; i < V; i++ )
		{
			for( size_t j = i + 1; j < V; j++ )
			{
				if( abs ( data[i] - data[j] ) < d )
				{
					( *uf ).merge ( i , j );
				}
			}
		}
		cout << ( *uf ).group () << endl;
		delete uf;
	}
}
accuracy: 1
time_ms: 30
memory_kb: 1304
final_rank: 9