#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
#define int ll

#define REP(i,n) for(ll i=0;i<n;++i)
#define SORT(name) sort(name.begin(), name.end())
#define ZERO(p) memset(p, 0, sizeof(p))
#define MINUS(p) memset(p, -1, sizeof(p))
#if 1
#  define DBG(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#  define DBG(fmt, ...)
#endif

const ll LLINF = (1LL<<60);
const int INF = (1LL<<30);
const double DINF = std::numeric_limits<double>::infinity();
const int MOD = 1000000007;
#define MAX_N 100010
#define SUBMIT

ll N;
vector<ll> A;
vector<ll> fact;

static inline bool IsFact(ll val) {
    ll lb = 0;
    ll ub = fact.size();
    while(lb < ub) {
        ll mid = (lb + ub) / 2;
        if(fact[mid] == val) { return true; }
        else if(val < fact[mid]) { ub = mid; }
        else { lb = mid + 1; }
    }
    return false;
}

static inline ll bin_search1(ll val) {
    ll lb = 0;
    ll ub = A.size();
    while(lb < ub) {
        ll mid = (lb + ub) / 2;
        if(A[mid] == val) { return mid; }
        else if(val < A[mid]) { ub = mid; }
        else { lb = mid + 1; }
    }
    return -1;
}

ll solve() {
    SORT(A);
    // A を数の種類ごとにまとめる
    map<ll, ll> A2;     // 種類, その数
    map<ll, ll> A_aveil; // 種類, 利用可能数
    REP(i, N) {
        A2[A[i]]++;
        A_aveil[A[i]]++;
    }
    // A[i] が組める相手の数
    vector< pair<ll, ll> > budy_cnt(N, make_pair(0, 0));  // 相手の数, インデックス
    REP(i, N) {
        budy_cnt[i].second = i;
        for(auto& f : fact) {
            ll budy = f - A[i];
            if(bin_search1(budy) != -1) {
                budy_cnt[i].first += A2[budy];
                if(budy == A[i]) { budy_cnt[i].first--; }
            }
        }
    }
    SORT(budy_cnt);
    // 組める相手が少ないやつから組ませていく
    ll ret = 0;
    REP(i, N) {
        if(budy_cnt[i].first <= 0) { continue; }
        ll ind = budy_cnt[i].second;
        ll val = A[ind];
        if(A_aveil[val] <= 0) { continue; }
        // 組める相手を探す
        for(auto& f : fact) {
            ll budy = f - val;
            if(bin_search1(budy) != -1 && A_aveil[budy] > 0) {
                if(val == budy) {
                    if(A_aveil[val] >= 2) {
                        ret++;
                        A_aveil[val]--;
                        A_aveil[budy]--;
                        break;
                    }
                } else {
                    // ペア成立
                    ret++;
                    A_aveil[val]--;
                    A_aveil[budy]--;
                    break;
                }
            }
        }
    }
    ll cand = 0;
    A_aveil.clear();
    REP(i, N) { A_aveil[A[i]]++; }
    REP(i, N) {
        if(budy_cnt[i].first <= 0) { continue; }
        ll ind = budy_cnt[i].second;
        ll val = A[ind];
        if(A_aveil[val] <= 0) { continue; }
        // 組める相手を探す
        for(int j = fact.size()-1; j >= 0; --j) {
            ll f = fact[j];
            ll budy = f - val;
            if(bin_search1(budy) != -1 && A_aveil[budy] > 0) {
                if(val == budy) {
                    if(A_aveil[val] >= 2) {
                        cand++;
                        A_aveil[val]--;
                        A_aveil[budy]--;
                        break;
                    }
                } else {
                    // ペア成立
                    cand++;
                    A_aveil[val]--;
                    A_aveil[budy]--;
                    break;
                }
            }
        }
    }
    return max(ret, cand);
}

ll blute_force() {
    random_device r;
    mt19937 mt(r());
    vector<ll> sh;
    copy(A.begin(), A.end(), back_inserter(sh));
    ll ret = 0;
    REP(loop, 100000) {
        shuffle(sh.begin(), sh.end(), mt);
        ll cand = 0;
        for(int i = 0; i < sh.size() - 1; i += 2) {
            if(IsFact(sh[i] + sh[i+1])) { cand++; }
        }
        ret = max(ret, cand);
    }
    return ret;
}

signed main()
{
    fact.push_back(1);
    while(fact[fact.size()-1] <= 2000000000LL) {
        fact.push_back(fact[fact.size()-1] * 2);
    }
#ifdef SUBMIT
    cin >> N;
    A.assign(N, 0);
    REP(i, N) { cin >> A[i]; }
    ll ans = solve();
    //ll ans = blute_force();
    printf("%lld\n", ans);
#else
    random_device r;
    mt19937 mt(r());
    uniform_int_distribution<> dist(1, 10);
    N = 6;
    REP(loop, 1000) {
        A.assign(N, 0);
        REP(i, N) { A[i] = dist(mt); }
        ll ans = blute_force();
        ll cand = solve();
        if(ans != cand) {
            printf("N: %lld\n", N);
            printf("A: ");
            REP(i, N) { printf("%lld ", A[i]); }
            printf("\n");
            printf("ans: %lld cand: %lld\n", ans, cand);
            return 0;
        }
    }
#endif

    return 0;
}


Measured memory_bytes: 32000