#include <bits/stdc++.h>
using namespace std;
double fRand(double fMin, double fMax) {
  double f = (double)rand() / RAND_MAX;
  return fMin + f * (fMax - fMin);
}
template <class T>
T min(T a, T b, T c) {
  return min(a, min(b, c));
}
template <class T>
T max(T a, T b, T c) {
  return max(a, max(b, c));
}
const double PI = acos(-1.0);
struct pt {
  int x, y;
  pt operator+(pt p) { return {x + p.x, y + p.y}; }
  pt operator-(pt p) { return {x - p.x, y - p.y}; }
  int operator*(pt p) { return x * p.y - y * p.x; }
  int operator%(pt p) { return x * p.x + y * p.y; }
};
bool half(pt p) { return (p.y > 0 || (p.y == 0 && p.x < 0)); }
bool cmpPolar(pt &v, pt &w) {
  return make_tuple(half(v), 0) < make_tuple(half(w), v * w);
}
const int MAXN = 1e4 + 5;
const int MAXK = 105;
const int oo = 1e9 + 7;
int n, trace[MAXN + MAXK][MAXK][2][2], px[MAXN], py[MAXN], signX[MAXN],
    signY[MAXN];
vector<int> candR;
pt e[MAXN];
void knapsack(int a[], int sign[]) {
  int maxA = *max_element(a, a + n);
  vector<vector<int> > trace(n + 1, vector<int>(2 * maxA + 1, 0));
  trace[0][maxA] = -1;
  for (int i = (0); i <= (n - 1); ++i) {
    for (int j = (0); j <= (2 * maxA); ++j) {
      if (!trace[i][j]) continue;
      if (j >= a[i]) trace[i + 1][j - a[i]] = -1;
      if (j + a[i] <= 2 * maxA) trace[i + 1][j + a[i]] = 1;
    }
  }
  int i = n, j = maxA;
  assert(trace[i][j] != 0);
  while (i > 0) {
    sign[i - 1] = trace[i][j];
    j -= a[i - 1] * sign[i - 1];
    --i;
  }
}
int main() {
  scanf("%d", &n);
  if (n == 3) {
    puts("YES");
    puts("0 0");
    puts("1 0");
    puts("0 2");
    return 0;
  }
  for (int i = (0); i <= (MAXN + MAXK - 1); ++i)
    for (int k = (0); k <= (MAXK - 1); ++k)
      for (int rx = (0); rx <= (1); ++rx)
        for (int ry = (0); ry <= (1); ++ry) trace[i][k][rx][ry] = -1;
  trace[0][0][0][0] = 0;
  int i = 0, k = -1;
  for (int r = 1;; ++r) {
    vector<int> p;
    for (int x = (0); x <= (sqrt(r)); ++x) {
      int y2 = r - x * x, y = sqrt(y2);
      if (y * y == y2) p.push_back(x);
    }
    if ((int)p.size() == 0) continue;
    candR.push_back(r);
    for (int k = (0); k <= (MAXK - 1); ++k) {
      for (int rx = (0); rx <= (1); ++rx) {
        for (int ry = (0); ry <= (1); ++ry) {
          if (trace[i][k][rx][ry] == -1) continue;
          if (k < MAXK - 1) trace[i + 1][k + 1][rx][ry] = oo;
          for (int x : p) {
            int y = sqrt(r - x * x);
            trace[i + 1][k][(rx + x) & 1][(ry + y) & 1] = x;
          }
        }
      }
    }
    ++i;
    if (i >= n && trace[i][i - n][0][0] != -1) {
      k = i - n;
      break;
    }
  }
  int rx = 0, ry = 0;
  while (i > 0) {
    if (trace[i][k][rx][ry] == oo)
      --k;
    else {
      int x = trace[i][k][rx][ry];
      int y = sqrt(candR[i - 1] - x * x);
      px[i - k - 1] = x;
      py[i - k - 1] = y;
      rx = ((rx - x) % 2 + 2) % 2;
      ry = ((ry - y) % 2 + 2) % 2;
    }
    --i;
  }
  knapsack(px, signX);
  knapsack(py, signY);
  for (int i = (0); i <= (n - 1); ++i)
    e[i] = {px[i] * signX[i], py[i] * signY[i]};
  sort(e, e + n, cmpPolar);
  pt p = {0, 0};
  puts("YES");
  for (int i = (0); i <= (n - 1); ++i) {
    printf("%d %d\n", p.x, p.y);
    p = p + e[i];
  }
  return 0;
}
