#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const long long INFF = 0x3f3f3f3f3f3f3f3fll;
const long long M = 1e9 + 7;
const long long maxn = 1e6 + 107;
const double pi = acos(-1.0);
const double eps = 0.0000000001;
long long gcd(long long a, long long b) { return b ? gcd(b, a % b) : a; }
template <typename T>
inline void pr2(T x, int k = 64) {
  long long i;
  for (i = 0; i < k; i++) fprintf(stderr, "%d", (x >> i) & 1);
  putchar(' ');
}
template <typename T>
inline void add_(T &A, int B, long long MOD = M) {
  A += B;
  (A >= MOD) && (A -= MOD);
}
template <typename T>
inline void mul_(T &A, long long B, long long MOD = M) {
  A = (A * B) % MOD;
}
template <typename T>
inline void mod_(T &A, long long MOD = M) {
  A %= MOD;
  A += MOD;
  A %= MOD;
}
template <typename T>
inline void max_(T &A, T B) {
  (A < B) && (A = B);
}
template <typename T>
inline void min_(T &A, T B) {
  (A > B) && (A = B);
}
template <typename T>
inline T abs(T a) {
  return a > 0 ? a : -a;
}
template <typename T>
inline T powMM(T a, T b) {
  T ret = 1;
  for (; b; b >>= 1ll, a = (long long)a * a % M)
    if (b & 1) ret = (long long)ret * a % M;
  return ret;
}
int startTime;
void startTimer() { startTime = clock(); }
void printTimer() {
  fprintf(stderr, "/--- Time: %ld milliseconds ---/\n", clock() - startTime);
}
int n;
int A[maxn];
struct node {
  int x, y, z;
  node(int _x, int _y, int _z) : x(_x), y(_y), z(_z) {}
};
vector<node> ans, mor;
vector<int> changes, tmp;
int pre[maxn], vis[maxn];
queue<int> Q;
bool calc(int val, int len) {
  int i;
  tmp.push_back((1 << 0) | (1 << 1) | (1 << 2));
  tmp.push_back((1 << 0) | (1 << 2) | (1 << 4));
  tmp.push_back((1 << 0) | (1 << 3) | (1 << 6));
  tmp.push_back((1 << 0) | (1 << 4) | (1 << 8));
  tmp.push_back((1 << 0) | (1 << 5) | (1 << 10));
  tmp.push_back((1 << 0) | (1 << 6) | (1 << 12));
  tmp.push_back((1 << 0) | (1 << 7) | (1 << 14));
  tmp.push_back((1 << 0) | (1 << 8) | (1 << 16));
  for (i = 0; i < 15; i++)
    for (int v : tmp)
      if ((v << i) < (1 << len)) changes.push_back(v << i);
  Q.push(0);
  vis[0] = 1;
  while (Q.size()) {
    int x = Q.front();
    Q.pop();
    for (int trans : changes)
      if (!vis[x ^ trans]) {
        pre[x ^ trans] = x;
        vis[x ^ trans] = 1;
        Q.push(x ^ trans);
      }
  }
  if (vis[val]) {
    for (int x = val; x; x = pre[x]) {
      int nowtrans = x ^ pre[x];
      tmp.clear();
      for (i = 0; i < len; i++)
        if ((nowtrans >> i) & 1) tmp.push_back(i);
      mor.push_back(node(tmp[0], tmp[1], tmp[2]));
    }
    return 1;
  }
  return 0;
}
bool rev;
inline int g(int x) {
  if (rev)
    return n - x + 1;
  else
    return x;
}
void _flip(int x, int y, int z) {
  x = g(x);
  y = g(y);
  z = g(z);
  ans.push_back(node(x, y, z));
  A[x] ^= 1;
  A[y] ^= 1;
  A[z] ^= 1;
}
int l, r;
inline void reverse() {
  int tmp = l;
  l = n - r + 1;
  r = n - tmp + 1;
  rev ^= 1;
}
int main() {
  int i;
  scanf("%d", &n);
  for (i = 1; i <= n; i++) scanf("%d", &A[i]);
  l = 1, r = n;
  while (l + 16 <= r) {
    if (A[g(l)] && A[g(l + 1)] && A[g(l + 2)]) {
      _flip(l, l + 1, l + 2);
      l += 3;
    } else if (A[g(l)] && A[g(l + 2)]) {
      _flip(l, l + 2, l + 4);
      l += 3;
    } else if (A[g(l)] && A[g(l + 1)]) {
      if (A[g(r)] && A[g(r - 1)] && !A[g(r - 2)]) {
        if ((l + r) & 1) {
          _flip(l, (l + r - 1) / 2, r - 1);
          _flip(l + 1, (l + 1 + r) / 2, r);
        } else {
          _flip(l, (l + r) / 2, r);
          _flip(l + 1, (l + r) / 2, r - 1);
        }
        l += 3;
        r -= 3;
      } else
        reverse();
    } else if (A[g(l)]) {
      _flip(l, l + 3, l + 6);
      l += 3;
    } else {
      l++;
    }
  }
  int val = 0;
  for (i = l; i <= r; i++) val |= A[g(i)] << (i - l);
  if (calc(val, r - l + 1)) {
    puts("YES");
    for (node x : mor) _flip(x.x + l, x.y + l, x.z + l);
    printf("%d\n", (int)ans.size());
    for (node x : ans) printf("%d %d %d\n", x.x, x.y, x.z);
  } else {
    puts("NO");
  }
}
