#include <iostream>
#include <vector>
#include <queue>

using namespace std;

// Offset để dịch tọa độ từ [-1000, 1000] sang [0, 2000]
const int OFFSET = 1000;
const int GRID_SIZE = 2005;

// Mảng đánh dấu vật cản và khoảng cách
int dist[GRID_SIZE][GRID_SIZE];
bool is_blocked[GRID_SIZE][GRID_SIZE];

struct Point {
    int x, y;
};

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n;
    long long D;
    cin >> n >> D; // n <= 10^4, D <= 10^7

    // Khởi tạo trạng thái ban đầu
    for (int i = 0; i < GRID_SIZE; i++) {
        for (int j = 0; j < GRID_SIZE; j++) {
            dist[i][j] = -1;
            is_blocked[i][j] = false;
        }
    }

    // Đọc các ô bị chặn và đánh dấu
    for (int i = 0; i < n; i++) {
        int x, y;
        cin >> x >> y; // Giá trị tuyệt đối của x và y nhỏ hơn 10^3
        is_blocked[x + OFFSET][y + OFFSET] = true;
    }

    // BFS
    queue<Point> q;
    q.push({0 + OFFSET, 0 + OFFSET});
    dist[0 + OFFSET][0 + OFFSET] = 0;
    
    long long count = 0;
    int dx[] = {-1, 1, 0, 0};
    int dy[] = {0, 0, -1, 1};

    while (!q.empty()) {
        Point curr = q.front();
        q.pop();

        // Nếu khoảng cách đã đạt tới D thì không cần mở rộng thêm
        if (dist[curr.x][curr.y] >= D) continue;

        for (int i = 0; i < 4; i++) {
            int nx = curr.x + dx[i];
            int ny = curr.y + dy[i];

            // Kiểm tra biên mảng và vật cản
            if (nx >= 0 && nx < GRID_SIZE && ny >= 0 && ny < GRID_SIZE 
                && !is_blocked[nx][ny] && dist[nx][ny] == -1) {
                
                dist[nx][ny] = dist[curr.x][curr.y] + 1;
                q.push({nx, ny});
            }
        }
    }

    // Đếm số tọa độ đã đi được
    for (int i = 0; i < GRID_SIZE; i++) {
        for (int j = 0; j < GRID_SIZE; j++) {
            if (dist[i][j] != -1 && dist[i][j] <= D) {
                count++;
            }
        }
    }

    cout << count << endl;

    return 0;
}