// Mivik 2021.4.7
#include <cstdio>
#include <cstring>
#include <iostream>

#define d isdigit(c)
#define g c=t.get();
#define L return
#define K break
#define A(c,a,b)if(c)a else b;
#define I(c,a)if(c)a;
#define Y goto E
struct MI{private:char bb[1 << 14];FILE*f;char*bs,*be;char e;bool o,l;public:MI():f(stdin),bs(0),be(0){}
#ifdef __linux__
#endif
inline char get(){if(o){o=0;L e;}
#ifdef MIVIK
char c=fgetc(f);I(c==-1,l=1)L c;
#else
I(bs==be,be=(bs=bb)+fread(bb,1,sizeof(bb),f))I(bs==be,{l=1;L-1;})L*bs++;
#endif
}inline void unget(char c){o=1;e=c;}template<class T>inline T read(){T r;*this>r;L r;}template<class T>inline MI&operator>(T&);};template<class T>struct Q{const static bool U=T(-1)>=T(0);inline void operator()(MI&t,T&r)const{r=0;char c;bool y=0;A(U,for(;;){g I(c==-1,Y)I(d,K)},for(;;){g I(c==-1,Y)A(c=='-',{g I(d,{y=1;K;})},I(d,K))})for(;;){I(c==-1,Y)A(d,r=r*10+(c^48);,K)g}t.unget(c);E:;I(y,r=-r)}};template<>struct Q<char>{};template<class T>inline MI&MI::operator>(T&t){Q<T>()(*this,t);L*this;}
#undef d
#undef g
#undef L
#undef K
#undef A
#undef I
#undef Y
template<class T>std::ostream& operator<(std::ostream&out,const T&t){return out<<t;}
#define endl ('\n')
#define P(x) cout<#x" = "<(x)<endl
#define R (cin.read<int>())

using std::cout;

#include <algorithm>
#include <cassert>
#include <vector>

MI cin;

typedef long long qe;

const int mod = 998244353;

template<typename T> inline bool gmax(T &a, const T &b) { return a < b && (a = b, true); }

inline int add(int x, int y) { return (x += y) >= mod ? x - mod : x; }
inline int sub(int x, int y) { return (x -= y) < 0 ? x + mod : x; }
inline qe ksm(qe x, int p = mod - 2) {
	qe ret = 1;
	for (; p; p >>= 1, (x *= x) %= mod)
		if (p & 1) (ret *= x) %= mod;
	return ret;
}
std::vector<int> rt, r, inv;
inline void init_ntt(int N) {
	rt.resize(1 << N); r.resize(1 << N);
	inv.resize(N + 1);
	for (int i = 0, j = 1, q = 0; i <= N; ++i, j = (q = j) << 1) {
		inv[i] = ksm(j);
		const int del = ksm(3, (mod - 1) / j);
		for (int k = 0, c = 1; k < q; ++k, c = (qe)c * del % mod) rt[q | k] = c;
	}
}
inline void ntt(int *v, int len, bool rev) {
	static int last;
	if (last != len) {
		for (int i = 1; i < len; ++i) r[i] = (r[i >> 1] >> 1) | ((i & 1)? (len >> 1): 0);
		last = len;
	}
	for (int i = 1; i < len; ++i) if (i < r[i]) std::swap(v[i], v[r[i]]);
	assert(!(len & (len - 1)));
	for (int i = 1, q = 2; i < len; i = q, q <<= 1)
	for (int j = 0; j < len; j += q)
	for (int k = 0; k < i; ++k) {
		const int x = v[j | k], y = (qe)v[i | j | k] * rt[i | k] % mod;
		v[j | k] = add(x, y);
		v[i | j | k] = sub(x, y);
	}
	if (!rev) return; std::reverse(v + 1, v + len);
	for (int i = 0, r = inv[__builtin_ctz(len)]; i < len; ++i) v[i] = (qe)v[i] * r % mod;
}
struct poly : public std::vector<int> {
#define v (*this)
	static inline int round_up(int x) { return (x & (x - 1))? (1 << (32 - __builtin_clz(x))): x; }

	poly() {}
	inline poly& ntt(int len, bool rev) { resize(round_up(len), 0); ::ntt(data(), size(), rev); return v; }
	inline poly& ntt(bool rev) { return ntt(size(), rev); }
	inline poly& imul(const poly &a, int l) {
		static poly tmp;
		if (empty() || a.empty()) return clear(), v;
		const int len = round_up(l);
		(tmp = a).ntt(len, 0); ntt(len, 0);
		for (int i = 0; i < len; ++i) v[i] = (qe)v[i] * tmp[i] % mod;
		return ntt(len, 1), resize(l), v;
	}
	inline poly& operator*=(const poly &a) { return imul(a, size() + a.size() - 1); }
#undef v
};
template<> struct Q<poly> {  };

const int $n = 200005;
const int $v = 5000005;

int n, v[$n], cnt[$v], lst[$v], pre[$n], tar[$n];
poly F;
inline void link(int x, int y) {
	static int et;
	pre[++et] = lst[x];
	lst[x] = et;
	tar[et] = y;
}
inline void print(int a, int b, int c, int d) {
	static int t[4];
	t[0] = a;
	t[1] = b;
	t[2] = c;
	t[3] = d;
	std::sort(t, t + 4);
	assert(t[0] != t[1] && t[1] != t[2] && t[2] != t[3]);
	assert(v[a] + v[b] == v[c] + v[d]);
	cout < "YES\n";
	cout < a < ' ' < b < ' ' < c < ' ' < d < endl;
}
inline void find(int a, int b, int c, int d) {
	int na, nb, nc, nd;
	na = tar[lst[a]];
	lst[a] = pre[lst[a]];
	nb = tar[lst[b]];
	lst[b] = pre[lst[b]];
	nc = tar[lst[c]];
	lst[c] = pre[lst[c]];
	nd = tar[lst[d]];
	lst[d] = pre[lst[d]];
	print(na, nb, nc, nd);
}
int main() {
	cin > n;
	int c = 0, mx = 0, t1, t2;
	for (int i = 1; i <= n; ++i) {
		const int v = ::v[i] = R;
		link(v, i);
		if (++cnt[v] == 2) {
			if (++c == 1) {
				t1 = tar[pre[lst[v]]];
				t2 = i;
			} else
				return print(t1, tar[pre[lst[v]]], t2, i), 0;
		} else if (cnt[v] == 4)
			return find(v, v, v, v), 0;
		gmax(mx, v);
	}
	for (int i = 0; i <= mx; ++i) {
		if (cnt[i] < 2) continue;
		const int w = i * 2;
		for (int j = 0; j <= w && j <= mx; ++j) {
			if (j == i || !cnt[j] || !cnt[w - j]) continue;
			return find(i, i, j, w - j), 0;
		}
	}
	init_ntt(32 - __builtin_clz(mx * 2 + 1));
	F.resize(mx + 1);
	for (int i = 0; i <= mx; ++i) F[i] = !!cnt[i];
	F.ntt(F.size() * 2 - 1, 0);
	for (int &v : F) v = (qe)v * v % mod;
	F.ntt(1);
	t1 = -1;
	for (int i = 0; i < F.size(); ++i) {
		if (F[i] < 4) continue;
		for (int j = 0; j <= i; ++j) {
			if (!lst[j] || !lst[i - j]) continue;
			if (t1 != -1)
				return find(t1, t2, j, i - j), 0;
			else {
				t1 = j;
				t2 = i - j;
			}
		}
		assert(0);
	}
	cout < "NO\n";
}