#include <bits/stdc++.h>
using namespace std;
struct custom_hash {
  static uint64_t splitmix64(uint64_t x) {
    x += 0x9e3779b97f4a7c15;
    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
    x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
    return x ^ (x >> 31);
  }
  size_t operator()(uint64_t x) const {
    static const uint64_t FIXED_RANDOM =
        chrono::steady_clock::now().time_since_epoch().count();
    return splitmix64(x + FIXED_RANDOM);
  }
};
unordered_map<int, int, custom_hash> m;
int main() {
  ios::sync_with_stdio(false), cin.tie(0);
  int V, i, j, k;
  cin >> V;
  vector<pair<int, int> > nodes;
  for (int i = (0), _i = (V); i < _i; ++i) {
    cin >> j;
    nodes.push_back(pair<int, int>(j - 2, i + 1));
  }
  sort(nodes.begin(), nodes.end());
  vector<pair<int, int> > edges;
  int latch = V - 1;
  bool can = true;
  int diam = 2;
  int s = V - 1;
  for (int i = (2), _i = (V); i < _i; ++i) {
    pair<int, int> n = nodes[i];
    if (n.first == -1) {
      while (nodes[latch].first == 0) latch--;
      if (nodes[latch].first == -1) {
        can = false;
        break;
      } else {
        nodes[latch].first--;
        edges.push_back(pair<int, int>(n.second, nodes[latch].second));
      }
    } else if (i < V - 1) {
      s = min(s, i);
      diam++;
      edges.push_back(pair<int, int>(n.second, nodes[i + 1].second));
    }
  }
  if (!can)
    cout << "NO" << endl;
  else {
    edges.push_back(pair<int, int>(nodes[0].second, nodes[s].second));
    edges.push_back(pair<int, int>(nodes[1].second, nodes[V - 1].second));
    cout << "YES " << diam << endl << V - 1 << endl;
    for (pair<int, int> e : edges) {
      cout << e.first << ' ' << e.second << endl;
    }
  }
  return 0;
}
