// Original C++ solution (slower):
#pragma GCC optimize("O3")

//#pragma GCC optimize("unroll-loops,no-stack-protector")

//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>



#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)

#define endl '\n'

#define elif else if

#define ll long long int

#define ld long double

#define vec vector

#define forn(a) for(ll a=0; a<n; a++)

#define fore(a, v, n) for(ll a=v; a<n; a++)

#define all(x) x.begin(), x.end()

#define presicion(x) cout<<fixed<<setprecision(x)

#define dbg(x) cerr<<#x<<" = "<<x<<endl

#define PI 3.14159265358979323

#define sen(ang) sin((ang)*PI/180)

//cout<<flush;



using namespace std;



#define MUCHO 9999999



ll n;



struct coso {

	ll cant;

	ll cands;

};



set<pair<ll, ll>> pots;

map<ll, set<ll>> g;

map<ll, struct coso> cants;

set<pair<ll, ll>> cands;



int main() {

	IOS;

	cin >> n;

	forn (i) {

		ll n;

		cin >> n;

		cants[n].cant++;

	}



	for (auto& v : cants)

	fore (e, 1, 31) {

		ll sum = 1 << e;

		auto b = cants.find(sum - v.first);

		if (b != cants.end()) {

			v.second.cands += b->second.cant;

			g[v.first].insert(b->first);

		}

	}



	for (const auto& c : cants)

		cands.emplace(c.second.cands, c.first);



	ll count = 0;

	for (auto n = cands.begin(); n != cands.end(); n = cands.begin()) {

		ll menos_cands = MUCHO;

		ll match = 0;

		for (auto v : g[n->second])

			if (cants[v].cands < menos_cands && cants[v].cands && cants[v].cant)

				menos_cands = cants[v].cands, match = v;

		if (menos_cands == MUCHO) {

			cants.erase(n->second);

			cands.erase(n);

			continue;

		}

		ll& ncant = cants[n->second].cant;

		ll& ncand = cants[n->second].cands;

		ll& mcant = cants[match].cant;

		ll& mcand = cants[match].cands;

		ll cmatches = min(ncant, mcant);

		if (match == n->second) {

			ncant = 0;

			ncand = 0;

			count += cmatches / 2;

			cands.erase(n);

			continue;

		}

		cands.erase(make_pair(mcand, match));

		ncant -= cmatches;

		mcant -= cmatches;

		ncand -= cmatches;

		mcand -= cmatches;

		if (ncant && ncand)

			cands.insert(make_pair(ncand, n->second));

		if (mcant && mcand)

			cands.insert(make_pair(mcand, match));

		cands.erase(n);

		count += cmatches;

	}

	cout << count << endl;

	return 0;

}

// Optimized solution to the same problem (faster):
#include <cstdio>

#include <cstring>

#include <algorithm>

#include <vector>

#include <map>

#ifdef sahdsg

#define DBG(...) printf(__VA_ARGS__)

#else

#define DBG(...) (void)0

#endif // sahdsg

#define REP(r,x,y) for(register int r=(x); r<y; r++)

using namespace std;

typedef long long LL;

inline void read(int&x) {

	x=0;char ch=getchar(); while(ch<'0') ch=getchar();

	while(ch>='0') x=x*10+ch-'0',ch=getchar();

}

map<int,int> a;

int main()

{

	int n; read(n);

	REP(i,0,n) {

		int t; read(t);

		if(a.count(t)==0) a[t]=0;

		a[t]++;

	}

	int ans=0;

	for(map<int,int>::reverse_iterator it=a.rbegin(); it!=a.rend(); it++) {

		int now=it->first;

		int k=now;

		k|=k>>1;

		k|=k>>2;

		k|=k>>4;

		k|=k>>8;

		k|=k>>16;

		k++;

		k-=now;

		DBG("%d %d %d\n", k, now, a[k]);

		if(k==now) ans+=a[k]/2,it->second%=2;

		else ans+=min(it->second,a[k]),a[k]-=min(it->second,a[k]);

	}

	printf("%d\n", ans);

}

// Fastest known solution for this problem: