/*
15
63 25 66 36 39 29 93 3 188 128 191 82 179 178 168
*/
#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for(int i = (a); i < (b); ++i)
#define trav(a, x) for(auto& a : x)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define endl '\n'

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<ll> vll;

const ll mod = 1000000007;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

using State = pair<pii, bool>;

vi a;
// what cases do i have to handle?
// if the mod = 0, need to not count degenerate one
vi solve(vector<vector<vector<State>>>& prev, pii initial, bool ig) {
	vi ans;

	int whichDefault = (ig ? -1 : -2);
	bool once = false;
	while(initial != mp(-1, -1)) {
		int row = initial.first;
		int col = initial.second;
		//cout << row << " " << col << endl << flush;
		int len = sz(prev[row][col]);
		if(len + whichDefault >= 0) {
			// cout << len << " " << whichDefault << endl << flush;
			//assert(len + whichDefault < len);
			State taken = prev[row][col][len + whichDefault];
			if(taken.second) {
				ans.pb(taken.first.first + 1);
			}

			initial = taken.first;

			if(!once) {
				whichDefault = -1;
				once = true;
			}

		} else {
			// take 0
			State taken = prev[row][col][0];
			// it means that to get to the current state, we took from the previous one
			if(taken.second) {
				ans.pb(taken.first.first + 1);
			}
			initial = taken.first;
		}
	}
	reverse(all(ans));
	return ans;
}

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

	// if there exists 2 different elements = x mod 200, then obv

	int n; cin >> n;
	a.resize(n); trav(x, a) cin >> x;

	map<int,vector<int>> cnt;
	for(int i = 0; i < n; i++) {
		cnt[a[i] % 200].pb(i);
	}

	trav(p, cnt) {
		if(sz(p.second) >= 2) {
			cout << "Yes" << endl;
			cout << 1 << " " << p.second[0] + 1 << endl;
			cout << 1 << " " << p.second[1] + 1 << endl;
			return 0;
		}
	}

	// includes the dummy subsequence
	vector<vector<ll>> dp(n + 1, vector<ll>(200, 0));
	vector<vector<vector<State>>> prev(n + 1, vector<vector<State>>(200));
	dp[0][0] = 1;
	prev[0][0].pb({mp(-1,-1), false});

	for(int i = 0; i < n; i++) {
		for(int j = 0; j < 200; j++) {
			ll here = dp[i][j];
			if(here != 0) {
				// include this element
				dp[i + 1][(j + a[i]) % 200] += here;
				if(prev[i + 1][(j + a[i]) % 200].size() <= 3) {
					prev[i + 1][(j + a[i]) % 200].pb({mp(i, j), true});
				}	
				dp[i + 1][j] += here;
				if(prev[i + 1][j].size() <= 3) {
					prev[i + 1][j].pb({mp(i,j), false});
				}	
			}
		}
	}

	vi b, c;
	for(int j = 0; j <= n; j++) {
		for(int i = 0; i < 200; i++) {
			if(i == 0) {
				if(dp[j][i] >= 3) {
					cout << "Yes" << endl;
					b = solve(prev, {n, i}, false);
					c = solve(prev, {n, i}, true);
					cout << sz(b) << " "; trav(x, b) cout << x << " ";
					cout << endl;
					cout << sz(c) << " "; trav(x, c) cout << x << " ";
					cout << endl;
					return 0;
				}
			} else {
				if(dp[j][i] >= 2) {
					cout << "Yes" << endl;
					b = solve(prev, {n, i}, false);
					c = solve(prev, {n, i}, true);
					cout << sz(b) << " "; trav(x, b) cout << x << " ";
					cout << endl;
					cout << sz(c) << " "; trav(x, c) cout << x << " ";
					cout << endl;
					return 0;
				}
			}
		} 
	}
	
	cout << "No" << endl;
    return 0;
}


//in dp prefix suffix sum helps..
#include<iostream>
#include<vector>
#include<string.h>
#include<algorithm>
#include<iomanip>
#include<cmath>
#include<stack>
#include <iterator>
#include <map>
#include<list>
#include <fstream>
#include<unordered_map>
#include<set>
#include<queue>
#define int  long long
#define double long double
#define pb   push_back
#define mp   make_pair
#define pii  pair<int,int>
#define pip pair<int, pair<int, int> >
#define viv vector<vector<int> >
#define vip vector< pair<int, int> >
#define vi vector<int>
#define mii  map<int, int>
#define qu queue<int>
#define set set<int>
#define multi multiset<int>
#define stack stack<int>
#define fi first
#define se second
#define reverse(s) reverse(s.begin(), s.end())
#define sort1(v) sort(v.begin(), v.end())
#define it iterator
#define pq1 priority_queue <pii, vector<pii>, greater<pii> >
#define mem(x, y) memset(x, (int)y, sizeof(x))
#define ps(x,y) fixed<<setprecision(y)<<x
// author :: Anurag Anand.
using namespace std;
int z=  1e9+7;
//int z= 998244353;
int gcd(int a, int b){
    if(a==0)return b;
    if(b==0)return a;
    return gcd(b, a%b);
}
int power(int a,int b)
{
	int res=1;
	while(b)
	{
		if(b&1)
		{
			res=(res*a)%z;
			b--;
		}
		else
		{
			a=(a*a)%z;
			b=b>>1;
		}
	}
	return res;
}
vi sieve;
// vi seg;
// void arrange(int i, int v, int x, int lx, int rx){
// 	if(rx-lx==1){
// 		seg[x] =v;
// 		return;
// 	}
// 	int m= (lx+rx)/2;
// 	if(i<m){
// 		arrange(i, v, 2*x+1, lx, m);
// 	}
// 	else arrange(i, v, 2*x+2, m, rx);
// 	seg[x]=gcd(seg[2*x+1], seg[2*x+2]);
// }
// int calc(int l, int r, int x, int lx, int rx){
// 	    if(l>=rx||r<=lx) return 0;
// 	    if(lx>=l&&rx<=r) return seg[x];
// 	    int mid=(lx+rx)/2;
// 	    int sl= calc(l, r, 2*x+1, lx, mid), sr= calc(l, r, 2*x+2, mid, rx);
// 	    return gcd(sl, sr);
// }
int32_t main()
{
    ios_base::sync_with_stdio(false);
	cin.tie(NULL);
    cout.tie(NULL);
	vi pp;
	pp.assign(1000001, 0);
	for(int i=2;i<1000;i++){
		if(!pp[i]){
			for(int j=2*i;j<=1000000;j+=i){
				pp[j]=1;
			}
		}
	}
	for(int i=2;i<=1000000;i++) if(!pp[i]) sieve.pb(i);
	int t;
	t=1;
	//cin>>t;
	while(t--){
		int n;
		cin>>n;
		set s;
		for(int i=2;i<=sqrt(n);i++){
			int j=i;
			while(j<=n){
				j*=i;
				if(j<=n) s.insert(j);
			}
		}
		cout<<n-s.size()<<"\n";
	}
}