#include <utility>
#include <algorithm>
#include <string>
#include <sstream>
#include <cassert>
#include <cstring>
#include <cmath>
#include <unordered_map>
#include <vector>
#include <iterator>
#include "validate.h"

using namespace std;

class UF {
public:
    int *uf;
    int *size;

    int find(int v);
    
    void uni(int v, int w);

    UF(int n) {
        uf = new int[n];
        for(int i=0; i < n; i++) {
            uf[i] = i;
        }

        size = new int[n];
        fill_n(size, n, 1);
    }
};

int UF::find(int island) {
    int root = island;
    while (root != uf[root]) {
        uf[root] = uf[uf[root]];
        root = uf[root];
    }
    return root;
}

void UF::uni(int from, int to) {
    int root_from = find(from);
    int root_to = find(to);

    if (root_from == root_to) {
        return;
    }

    if (size[root_from] < size[root_to]) {
        uf[root_from] = root_to;
        size[root_to] += size[root_from];
    }
    else {
        uf[root_to] = root_from;
        size[root_from] += size[root_to];
    }
}


void solve() {

    // get the first line
    string line;
    assert(getline(judge_in, line));

    int n, d;
    sscanf(line.c_str(), "%d %d", &n, &d);
    judge_message("The total of islands: %d and max distance: %d\n", n, d);

    // Prints amount of islands and max distance
    cout << n << " " << d << endl;

    // initializing the union-find list of found islands
    UF uf = UF(n);
    vector<pair<int, int> > islands;

    // input handling
    for (int i=0; i < n; i++) {
        // get inputs and send to user
        int x, y;
        assert(getline(judge_in, line));
        sscanf(line.c_str(), "%d %d", &x, &y);
        cout << x << " " << y << endl;

        // find edges and union
        for (int j=0; j < islands.size(); j++) {
            pair<int, int> island2 = islands[j];
            if (d >= sqrt(
                pow(abs(island2.first - x), 2.0) +
                pow(abs(island2.second - y), 2.0))) {
                    uf.uni(i, j);
                }
        }
        islands.push_back(make_pair(x, y));
    }

    string user_answer;
    getline(author_out, user_answer);

    //There is first line
    if (user_answer.length() <= 0) {
        wrong_answer("No answer\n");
    }

    stringstream ssin(user_answer);
    std::istream_iterator<int> start = { ssin };
    std::istream_iterator<int> end;
    vector<int> user_islands(start, end);

    //Correct number of tokens
    if (user_islands.size() != n) {
        wrong_answer("Wrong count of elements in shopping list\n");
    }

    for (int i=0; i < user_islands.size(); i++) {
        int current_island = user_islands[i] - 1;
        // check if an island is withing [1 .. n]
        if (current_island < 0 || n <= current_island) {
            wrong_answer("Island %d is not one of the islands\n", current_island);
        }
    }

    int current_component_size = uf.size[uf.find(user_islands[0]-1)];
    for (int user_island: user_islands) {
        int island_size = uf.size[uf.find(user_island-1)];
        judge_message("Island %d part of group size %d\n", user_island, island_size);
        if (island_size > current_component_size) {
            wrong_answer("Island %d is part of a larger island group than those before it\n", user_island);
        }
        if (island_size < current_component_size) {
            current_component_size = island_size;
        }
    }

    return;
}

int main(int argc, char **argv) {

    init_io(argc, argv);

    solve();

    judge_message("Accepted!");

    accept();
}
