#include <bits/stdc++.h>
#define int long long

#define MULTITEST false

using namespace std;

struct Point {
    int x, y;

    int dist (Point & other) {
        return abs(other.x - x) + abs(other.y - y);
    }
    Point off (int dx, int dy) {
        return { x + dx, y + dy };
    }

    bool qPer () {
        return x >= 0 && y >= 0;
    }

    void show () {
        cout << x << " " << y << endl;
    }
    void show (const char *c) {
        cout << c << " " << x << " " << y << endl;
    }
};

struct Ring {
    int inner = 0; int outer = 0;
    Point center;

    bool is_in (Point & other) {
        int dl = center.dist(other);

        if ((dl & 1) != (outer & 1)) return false;

        return inner <= dl && dl <= outer;
    }
};

Ring ring_from (vector<pair<int, int>> & dists, Point p, int offset) {
    Ring res;
    res.center = p;
    res.outer = dists[offset].first;
    res.inner = dists[offset].first;

    for (int i = offset + 1; i < dists.size(); i ++) {
        res.outer += dists[i].first;
        res.inner -= dists[i].first;
    }

    if(res.inner < 0)
        res.inner = (res.outer & 1);

    return res;
}

optional<Point> find_point (int innr, int outr) {
    return {};
}

vector<pair<int, int>> find_deltas (vector<pair<int, int>> & dists, Point src, Point target, int offset) {
    if (offset + 1 == dists.size()) {
        vector<pair<int, int>> res = { { target.x - src.x, target.y - src.y } };
        return res;
    }

    Ring r_inner = ring_from(dists, src, offset + 1);
    int rad_inner = r_inner.inner;
    int rad_outer = r_inner.outer;

    // center at 0
    target.x -= src.x;
    target.y -= src.y;

    int rotated = 0;
    while (target.x  < 0 || target.y < 0) {
        swap(target.x, target.y);
        target.x *= -1;
        rotated ++;
    }

    int c1 = dists[offset].first; // px + py
    Point proj1;
    proj1.x = target.x;
    proj1.y = c1 - target.x;

    Point proj2;
    proj2.y = target.y;
    proj2.x = c1 - target.y;

    int dist1 = proj1.dist(target);
    int dist2 = proj2.dist(target);

    int outer1dist = (rad_outer - dist1) >> 1;
    int inner1dist = (rad_inner - dist1) >> 1;
    if (inner1dist < 0) inner1dist = outer1dist & 1;
    Point proj1_outer = proj1.off(outer1dist, - outer1dist);
    Point proj1_inner = proj1.off(inner1dist, - inner1dist);

    int outer2dist = (rad_outer - dist2) >> 1;
    int inner2dist = (rad_inner - dist2) >> 1;
    if (inner2dist < 0) inner2dist = outer2dist & 1;
    Point proj2_outer = proj2.off(- outer2dist, outer2dist);
    Point proj2_inner = proj2.off(- inner2dist, inner2dist);

    Point next_src = { -1, -1 };
    
    if (proj1_outer.qPer()) next_src = proj1_outer;
    if (proj2_outer.qPer()) next_src = proj2_outer;
    if (proj1_inner.qPer()) next_src = proj1_inner;
    if (proj2_inner.qPer()) next_src = proj2_inner;

    if (proj1_inner.x < 0 && proj1_outer.y < 0) {
        int del = - proj1_inner.x;
        del += del & 1;

        next_src = proj1_inner.off(del, - del);
    }
    if (proj2_outer.x < 0 && proj2_inner.y < 0) {
        int del = - proj2_outer.x;
        del += del & 1;

        next_src = proj2_outer.off(del, - del);
    }

    while (rotated < 4) {
        swap(target.x, target.y);
        target.x *= -1;
        swap(next_src.x, next_src.y);
        next_src.x *= -1;
        rotated ++;
    }

    target  .x += src.x;
    target  .y += src.y;
    next_src.x += src.x;
    next_src.y += src.y;

    vector<pair<int, int>> deltas = find_deltas(dists, next_src, target, offset + 1);

    deltas.push_back({ next_src.x - src.x, next_src.y - src.y });

    return deltas;
}

void solve () {
    int N; cin >> N;

    Point target;
    cin >> target.x >> target.y;
    
    vector<int> D(N - 1);
    for ( int i = 0; i < D.size(); i ++ )
        cin >> D[i];
    
    vector<pair<int, int>> sorted_dists;
    for ( int i = 0; i < D.size(); i ++ )
        sorted_dists.push_back({ D[i], i });
    sort(sorted_dists.rbegin(), sorted_dists.rend());

    Ring full_ring = ring_from(sorted_dists, { 0, 0 }, 0);
    if (!full_ring.is_in(target)) {
        cout << "NO\n";
        return ;
    }

    cout << "YES\n";

    vector<pair<int, int>> deltas = find_deltas(sorted_dists, { 0, 0 }, target, 0);
    
    Point curr = { 0, 0 };
    vector<int>M(D.size());
    for ( int i = 0; i < D.size(); i ++ ) {
        M[sorted_dists[i].second] = i;
    }
    cout << curr.x << " " << curr.y << "\n";
    for ( int i = 0; i < D.size(); i ++ ) {
        int di = D.size() - 1 - M[i];

        int dx = deltas[di].first;
        int dy = deltas[di].second;
        curr = curr.off(dx, dy);
        cout << curr.x << " " << curr.y << "\n";
    }
}

signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    cout.precision(30);
    
    int T = 1;
    if (MULTITEST) cin >> T;

    for (int t = 0; t < T; t ++)
        solve();
}