/********************
    Acm ID: OffensiveChild
    Author: wzh
    proverbs£ºyiroad keep straight on
    Tittle:Educational Codeforces Round 15 .01
    Time:2016.07.29
    solutions:
*********************/
#include <iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
typedef long long ll;
const int maxm=1000+5;
const int maxn=100000+5;
const int INF=0x3f3f3f3f;
const double eps=1e-8;
int num[maxn];
const int MAXN=100005;
map<int,int>mp;
int main()
{
    int n;
    scanf("%d",&n);
    long long res=0;
    for(int i=1;i<=n;i++)
    {
        int a;
        scanf("%d",&a);
        for(int j=0;j<=30;j++)
            if(mp.find((1<<j)-a)!=mp.end())
                res+=mp[(1<<j)-a];
        mp[a]++;
    }
    return 0*printf("%I64d",res);
}
/*int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        memset(num,0,sizeof(num));
        for(int i=0; i<n; i++)
        {
            scanf("%d",&num[i]);
        }
        ll ans=0;
        double res=0;
        int ares=0;
        for(int i=0; i<n; i++)
        {
            for(int j=i+1; j<n; j++)
            {
                res=log((ll)(num[i]+num[j]))/log(2);
                ares=(int)res;
                if((ll)(num[i]+num[j])==(ll)pow(2,ares))
                {
                    ans++;
                }
            }
        }
        printf("%I64d\n",ans);
    }
    return 0;
}*/


/********************
    Acm ID: OffensiveChild
    Author: wzh
    proverbs£ºyiroad keep straight on
    Tittle:Educational Codeforces Round 15 .01
    Time:2016.07.29
    solutions:
*********************/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxm=1000+5;
const int maxn=100000+5;
const int INF=0x3f3f3f3f;
const double eps=1e-8;
int num[maxn];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        memset(num,0,sizeof(num));
        for(int i=0; i<n; i++)
        {
            scanf("%d",&num[i]);
        }
        ll ans=0;
        double res=0;
        int ares=0;
        for(int i=0; i<n; i++)
        {
            for(int j=i+1; j<n; j++)
            {
                res=(double)log((ll)(num[i]+num[j]))/log(2);
                ares=(int)res;
                if((ll)(num[i]+num[j])==(ll)pow(2,ares))
                {
                    ans++;
                }
            }
        }
        printf("%I64d\n",ans);
    }
    return 0;
}


/********************
    Acm ID: OffensiveChild
    Author: wzh
    proverbs£ºyiroad keep straight on
    Tittle:Educational Codeforces Round 15 .01
    Time:2016.07.29
    solutions:
*********************/
#include <iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
typedef long long ll;
const int maxm=1000+5;
const int maxn=100000+5;
const int INF=0x3f3f3f3f;
const double eps=1e-8;
int num[maxn];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        memset(num,0,sizeof(num));
        for(int i=0; i<n; i++)
        {
            scanf("%d",&num[i]);
        }
        ll ans=0;
        double res=0;
        int ares=0;
        for(int i=0; i<n; i++)
        {
            for(int j=i+1; j<n; j++)
            {
                res=log((ll)(num[i]+num[j]))/log(2);
                ares=(int)res;
                if((ll)(num[i]+num[j])==(ll)pow(2,ares))
                {
                    ans++;
                }
            }
        }
        printf("%I64d\n",ans+1);
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

int main()
{
	 ios_base::sync_with_stdio(0);cin.tie(NULL);cout.tie(NULL);

	int  n;

	cin>>n;

	ll arr[n],sum;

	for(int i=0;i<n;i++)
	{
		cin>>arr[i];

	}
	ll cnt=0,x;

	float temp;

	for(int i=0;i<n;i++)
	{
		for(int j=i+1;j<n;j++)
		{
			sum=arr[i]+arr[j];
			temp=log2(sum);
			x=temp;

			if(x==temp)
			cnt++;

		}
	}

	cout<<cnt;

return 0;

}


#include<bits/stdc++.h>
using namespace std;

int main()
{

	long long int n,temp,index,ans=0;
	cin>>n;

	long long int arr[n];

	for(int i=0;i<n;i++)
	cin>>arr[i];

	sort(arr,arr+n);

	long long int j;

	int prev=0;

	for(int i=0;i<32;i++)
	{
		temp=pow(2,i);

		j=(upper_bound(arr,arr+n,temp)-arr);
		j--;
		if(2*arr[j]>=temp)
		{

			for(;j>=prev&&(2*arr[j]>=temp);j--)
			{
				int b=upper_bound(arr,(arr+j),(temp-arr[j]))-arr;
				{
					b--;
					while(arr[b]==(temp-arr[j]))
					{
						ans++;
						b--;

					}

				}

			}

		}

	}

    cout<<ans;

	return 0;
}


#include<bits/stdc++.h>
using namespace std;

int main()
{

	long long int n,temp,index,ans=0;
	cin>>n;

	long long int arr[n];

	for(int i=0;i<n;i++)
	cin>>arr[i];

	sort(arr,arr+n);

	long long int j;

	int prev=0;

	for(int i=0;i<32;i++)
	{
		temp=pow(2,i);

		j=(upper_bound(arr,arr+n,temp)-arr);
		j--;
		if(2*arr[j]>=temp)
		{

			for(;j>=prev&&(2*arr[j]>=temp);j--)
			{
				int b=upper_bound(arr,(arr+j),(temp-arr[j]))-arr;
				{
					b--;
					while(arr[b]==(temp-arr[j]))
					{
						if(b==j)
						continue;
						ans++;
						b--;

					}

				}

			}

		}

	}

    cout<<ans;

	return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

int main()
{
	 ios_base::sync_with_stdio(0);cin.tie(NULL);cout.tie(NULL);

	int  n;

	cin>>n;

	ll arr[n],sum;

	for(int i=0;i<n;i++)
	{
		cin>>arr[i];

	}
	ll cnt=0;
	int x;

	float temp;

	for(int i=0;i<n;i++)
	{
		for(int j=i+1;j<n;j++)
		{
			sum=arr[i]+arr[j];

			if(((sum)&(sum-1))==0)
			cnt++;

		}
	}

	cout<<cnt;

return 0;

}


#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

int main()
{
	 ios_base::sync_with_stdio(0);cin.tie(NULL);cout.tie(NULL);

	int  n;

	cin>>n;

	ll arr[n],sum;

	for(int i=0;i<n;i++)
	{
		cin>>arr[i];

	}
	ll cnt=0;
	int x;

	float temp;

	for(int i=0;i<n;i++)
	{
		for(int j=i+1;j<n;j++)
		{
			sum=arr[i]+arr[j];
			temp=log2(sum);
			x=temp;

			if(x==temp)
			cnt++;

		}
	}

	cout<<cnt;

return 0;

}


#include<bits/stdc++.h>
using namespace std;

int main()
{
	int n;
	cin>>n;
	int arr[n];

	for(int i=0;i<n;i++)
	cin>>arr[i];
	sort(arr,arr+n);

	int ans=0,ub,lb;
	long long temp;
	for(int i=1;i<n;i++)
	{

		for(int j=0;j<32;j++)
		{
			temp=pow(2,j);
			if(2*arr[i]<temp)
			break;
			else if(arr[i]>temp)
			continue;

			ub=upper_bound(arr,arr+i,temp-arr[i])-arr;
			lb=lower_bound(arr,arr+i,temp-arr[i])-arr;

			if(ub==lb);

			else
			ans+=ub-lb;

		}
	}

	cout<<ans;

}


#include<bits/stdc++.h>
using namespace std;

int main()
{
	int n;
	cin>>n;
	int arr[n];

	for(int i=0;i<n;i++)
	cin>>arr[i];
	sort(arr,arr+n);

	long long int ans=0,ub,lb;
	long long temp;
	for(int i=1;i<n;i++)
	{

		for(int j=0;j<32;j++)
		{
			temp=pow(2,j);
			if(2*arr[i]<temp)
			break;
			else if(arr[i]>temp)
			continue;

			ub=upper_bound(arr,arr+i,temp-arr[i])-arr;
			lb=lower_bound(arr,arr+i,temp-arr[i])-arr;

			if(ub==lb);

			else
			ans+=ub-lb;

		}
	}

	cout<<ans;

}


#include<bits/stdc++.h>
using namespace std;

int main()
{
	int n;
	cin>>n;
	int arr[n];

	for(int i=0;i<n;i++)
	cin>>arr[i];
	sort(arr,arr+n);

	int ans=0,k;
	long long temp;
	for(int i=1;i<n;i++)
	{

		for(int j=0;j<32;j++)
		{
			temp=pow(2,j);
			if(2*arr[i]<temp)
			break;

			k=upper_bound(arr,arr+i,temp-arr[i])-arr;

			k--;
			while(arr[k]==temp-arr[i]&&k>=0)
			{

				ans++;
				k--;
			}

		}
	}

	cout<<ans;

}


#include<bits/stdc++.h>
#include<string.h>
#define ll long long int
#define fio ios_base::sync_with_stdio(false); cin.tie(NULL);
#define MAX_LIMIT 100000
#define pb push_back
#define mod 1000000007
#define bb back
#define CHARS_TOTAL 256
#define e endl
/* For counting number of digits, directly do floor(log10(n)+1)*/
using namespace std;

int gcd(ll a, ll b)
{
    // Everything divides 0
    if (a == 0)
       return b;
    if (b == 0)
       return a;

    // base case
    if (a == b)
        return a;

    // a is greater
    if (a > b)
        return gcd(a-b, b);
    return gcd(a, b-a);
}

int largest(ll arr[], ll n)
{
    return *max_element(arr, arr+n);
}
// Function to return LCM of two numbers
 ll lcm(ll a, ll b)
 {
    return (a*b)/gcd(a, b);
 }

ll power(ll x, unsigned ll y)  //Power in O(logn)
{
    ll temp;
    if(y == 0)
        return 1;
    temp = power(x, y / 2);
    if (y % 2 == 0)
        return temp * temp;
    else
    {
        if(y > 0)
            return x * temp * temp;
        else
            return (temp * temp) / x;
    }
}
bool comp(int a, int b)
{
    return (a < b);
}
void divisors(int n)
{
    vector<ll>v;
    // Note that this loop runs till square root
    for (int i=1; i<=sqrt(n); i++)
    {
        if (n%i == 0)
        {
            // If divisors are equal, print only one
            if (n/i == i)
                v.pb(i);

            else // Otherwise print both
            v.pb(i);
            v.pb(n/i);
        }
    }
}
bool isPrime(ll n)
{
    // Corner case
    if (n <= 1)
        return false;

    // Check from 2 to n-1
    for (ll i = 2; i < n; i++)
        if (n % i == 0)
            return false;

    return true;
}

void factors(ll n)
{
    // Print the number of 2s that divide n
    vector<ll>v;
    while (n % 2 == 0)
    {
        cout << 2 << " ";
        n = n/2;
    }

    // n must be odd at this point. So we can skip
    // one element (Note i = i +2)
    for (ll i = 3; i <= sqrt(n); i = i + 2)
    {
        // While i divides n, print i and divide n
        while (n % i == 0)
        {
            v.pb(i);
            n = n/i;
        }
    }

    // This condition is to handle the case when n
    // is a prime number greater than 2
    if (n > 2)
        v.pb(n);
}
bool powertwo(ll x){
  return x&& (!(x&(x-1)));
}
bool ans(ll arr[], ll i, ll r){
	if(i>4){
        return false;
	}
	if(r==0 && i<=4){
        return true;
	}
	else{
        return ans(arr, i+1, r-arr[i]) || ans(arr, i+1, r);
	}
}

void solve(){
            ll n;
            cin>>n;
            ll i;
            ll arr[n];
            ll c=0;
            ll j,x;
            unordered_map<ll,ll>mp;
            for(i=0;i<n;i++){
                cin>>arr[i];
            }
            for(i=0;i<n;i++){
                for(j=i;j<=32;j++){
                  x=pow(2,j);
                  c=c+mp[x-arr[i]];
                }
                mp[arr[i]]++;
            }
            cout<<c<<endl;
}
int main()
{
    fio;
    solve();
}


#include<bits/stdc++.h>
#include<string.h>
#define ll long long int
#define fio ios_base::sync_with_stdio(false); cin.tie(NULL);
#define MAX_LIMIT 100000
#define pb push_back
#define mod 1000000007
#define bb back
#define CHARS_TOTAL 256
#define e endl
/* For counting number of digits, directly do floor(log10(n)+1)*/
using namespace std;

int gcd(ll a, ll b)
{
    // Everything divides 0
    if (a == 0)
       return b;
    if (b == 0)
       return a;

    // base case
    if (a == b)
        return a;

    // a is greater
    if (a > b)
        return gcd(a-b, b);
    return gcd(a, b-a);
}

int largest(ll arr[], ll n)
{
    return *max_element(arr, arr+n);
}
// Function to return LCM of two numbers
 ll lcm(ll a, ll b)
 {
    return (a*b)/gcd(a, b);
 }

ll power(ll x, unsigned ll y)  //Power in O(logn)
{
    ll temp;
    if(y == 0)
        return 1;
    temp = power(x, y / 2);
    if (y % 2 == 0)
        return temp * temp;
    else
    {
        if(y > 0)
            return x * temp * temp;
        else
            return (temp * temp) / x;
    }
}
bool comp(int a, int b)
{
    return (a < b);
}
void divisors(int n)
{
    vector<ll>v;
    // Note that this loop runs till square root
    for (int i=1; i<=sqrt(n); i++)
    {
        if (n%i == 0)
        {
            // If divisors are equal, print only one
            if (n/i == i)
                v.pb(i);

            else // Otherwise print both
            v.pb(i);
            v.pb(n/i);
        }
    }
}
bool isPrime(ll n)
{
    // Corner case
    if (n <= 1)
        return false;

    // Check from 2 to n-1
    for (ll i = 2; i < n; i++)
        if (n % i == 0)
            return false;

    return true;
}

void factors(ll n)
{
    // Print the number of 2s that divide n
    vector<ll>v;
    while (n % 2 == 0)
    {
        cout << 2 << " ";
        n = n/2;
    }

    // n must be odd at this point. So we can skip
    // one element (Note i = i +2)
    for (ll i = 3; i <= sqrt(n); i = i + 2)
    {
        // While i divides n, print i and divide n
        while (n % i == 0)
        {
            v.pb(i);
            n = n/i;
        }
    }

    // This condition is to handle the case when n
    // is a prime number greater than 2
    if (n > 2)
        v.pb(n);
}
bool powertwo(ll x){
  return x&& (!(x&(x-1)));
}
bool ans(ll arr[], ll i, ll r){
	if(i>4){
        return false;
	}
	if(r==0 && i<=4){
        return true;
	}
	else{
        return ans(arr, i+1, r-arr[i]) || ans(arr, i+1, r);
	}
}

void solve(ll a[],ll n){
            unordered_map<ll,ll> mp;
            for (ll i = 0; i < n; i++)
                mp[a[i]]++;
            sort(a, a + n, greater<ll>());
    ll c = 0;
    for (ll i = 0; i < n; i++) {

        // If element has already been paired
        if (mp[a[i]] < 1)
            continue;

        // Find the number which is greater than
        // a[i] and power of two
        ll cur = 1;
        while (cur <= a[i])
            cur <<= 1;

        // If there is a number which adds up with a[i]
        // to form a power of two
        if (mp[cur - a[i]]) {

            // Edge case when a[i] and crr - a[i] is same
            // and we have only one occurrence of a[i] then
            // it cannot be paired
            if (cur - a[i] == a[i] and mp[a[i]] == 1)
                continue;

            count++;

            // Remove already paired elements
            mp[cur - a[i]]--;
            mp[a[i]]--;
        }
    }

    // Return the count
    return count;
}
int main()
{
    fio;
    ll n;
    cin>>n;
    ll i;
    ll arr[n];
    for(i=0;i<n;i++){
        cin>>arr[i];
    }
    cout<<solve(arr,n);
}


#include<bits/stdc++.h>
#include<string.h>
#define ll long long int
#define fio ios_base::sync_with_stdio(false); cin.tie(NULL);
#define MAX_LIMIT 100000
#define pb push_back
#define mod 1000000007
#define bb back
#define CHARS_TOTAL 256
#define e endl
/* For counting number of digits, directly do floor(log10(n)+1)*/
using namespace std;

int gcd(ll a, ll b)
{
    // Everything divides 0
    if (a == 0)
       return b;
    if (b == 0)
       return a;

    // base case
    if (a == b)
        return a;

    // a is greater
    if (a > b)
        return gcd(a-b, b);
    return gcd(a, b-a);
}

int largest(ll arr[], ll n)
{
    return *max_element(arr, arr+n);
}
// Function to return LCM of two numbers
 ll lcm(ll a, ll b)
 {
    return (a*b)/gcd(a, b);
 }

ll power(ll x, unsigned ll y)  //Power in O(logn)
{
    ll temp;
    if(y == 0)
        return 1;
    temp = power(x, y / 2);
    if (y % 2 == 0)
        return temp * temp;
    else
    {
        if(y > 0)
            return x * temp * temp;
        else
            return (temp * temp) / x;
    }
}
bool comp(int a, int b)
{
    return (a < b);
}
void divisors(int n)
{
    vector<ll>v;
    // Note that this loop runs till square root
    for (int i=1; i<=sqrt(n); i++)
    {
        if (n%i == 0)
        {
            // If divisors are equal, print only one
            if (n/i == i)
                v.pb(i);

            else // Otherwise print both
            v.pb(i);
            v.pb(n/i);
        }
    }
}
bool isPrime(ll n)
{
    // Corner case
    if (n <= 1)
        return false;

    // Check from 2 to n-1
    for (ll i = 2; i < n; i++)
        if (n % i == 0)
            return false;

    return true;
}

void factors(ll n)
{
    // Print the number of 2s that divide n
    vector<ll>v;
    while (n % 2 == 0)
    {
        cout << 2 << " ";
        n = n/2;
    }

    // n must be odd at this point. So we can skip
    // one element (Note i = i +2)
    for (ll i = 3; i <= sqrt(n); i = i + 2)
    {
        // While i divides n, print i and divide n
        while (n % i == 0)
        {
            v.pb(i);
            n = n/i;
        }
    }

    // This condition is to handle the case when n
    // is a prime number greater than 2
    if (n > 2)
        v.pb(n);
}
bool powertwo(ll x){
  return x&& (!(x&(x-1)));
}
bool ans(ll arr[], ll i, ll r){
	if(i>4){
        return false;
	}
	if(r==0 && i<=4){
        return true;
	}
	else{
        return ans(arr, i+1, r-arr[i]) || ans(arr, i+1, r);
	}
}

int solve(ll a[],ll n){
            unordered_map<ll,ll> mp;
            for (ll i = 0; i < n; i++)
                mp[a[i]]++;
            sort(a, a + n, greater<ll>());
    ll count = 0;
    for (ll i = 0; i < n; i++) {

        // If element has already been paired
        if (mp[a[i]] < 1)
            continue;

        // Find the number which is greater than
        // a[i] and power of two
        ll cur = 1;
        while (cur <= a[i])
            cur <<= 1;

        // If there is a number which adds up with a[i]
        // to form a power of two
        if (mp[cur - a[i]]) {

            // Edge case when a[i] and crr - a[i] is same
            // and we have only one occurrence of a[i] then
            // it cannot be paired
            if (cur - a[i] == a[i] and mp[a[i]] == 1)
                continue;

            count++;

            // Remove already paired elements
            mp[cur - a[i]]--;
            mp[a[i]]--;
        }
    }

    // Return the count
    return count;
}
int main()
{
    fio;
    ll n;
    cin>>n;
    ll i;
    ll arr[n];
    for(i=0;i<n;i++){
        cin>>arr[i];
    }
    cout<<solve(arr,n);
}


#include<bits/stdc++.h>
#include<string.h>
#define ll long long int
#define fio ios_base::sync_with_stdio(false); cin.tie(NULL);
#define MAX_LIMIT 100000
#define pb push_back
#define mod 1000000007
#define bb back
#define CHARS_TOTAL 256
#define e endl
/* For counting number of digits, directly do floor(log10(n)+1)*/
using namespace std;

int gcd(ll a, ll b)
{
    // Everything divides 0
    if (a == 0)
       return b;
    if (b == 0)
       return a;

    // base case
    if (a == b)
        return a;

    // a is greater
    if (a > b)
        return gcd(a-b, b);
    return gcd(a, b-a);
}

int largest(ll arr[], ll n)
{
    return *max_element(arr, arr+n);
}
// Function to return LCM of two numbers
 ll lcm(ll a, ll b)
 {
    return (a*b)/gcd(a, b);
 }

ll power(ll x, unsigned ll y)  //Power in O(logn)
{
    ll temp;
    if(y == 0)
        return 1;
    temp = power(x, y / 2);
    if (y % 2 == 0)
        return temp * temp;
    else
    {
        if(y > 0)
            return x * temp * temp;
        else
            return (temp * temp) / x;
    }
}
bool comp(int a, int b)
{
    return (a < b);
}
void divisors(int n)
{
    vector<ll>v;
    // Note that this loop runs till square root
    for (int i=1; i<=sqrt(n); i++)
    {
        if (n%i == 0)
        {
            // If divisors are equal, print only one
            if (n/i == i)
                v.pb(i);

            else // Otherwise print both
            v.pb(i);
            v.pb(n/i);
        }
    }
}
bool isPrime(ll n)
{
    // Corner case
    if (n <= 1)
        return false;

    // Check from 2 to n-1
    for (ll i = 2; i < n; i++)
        if (n % i == 0)
            return false;

    return true;
}

void factors(ll n)
{
    // Print the number of 2s that divide n
    vector<ll>v;
    while (n % 2 == 0)
    {
        cout << 2 << " ";
        n = n/2;
    }

    // n must be odd at this point. So we can skip
    // one element (Note i = i +2)
    for (ll i = 3; i <= sqrt(n); i = i + 2)
    {
        // While i divides n, print i and divide n
        while (n % i == 0)
        {
            v.pb(i);
            n = n/i;
        }
    }

    // This condition is to handle the case when n
    // is a prime number greater than 2
    if (n > 2)
        v.pb(n);
}
bool powertwo(ll x){
  return x&& (!(x&(x-1)));
}
bool ans(ll arr[], ll i, ll r){
	if(i>4){
        return false;
	}
	if(r==0 && i<=4){
        return true;
	}
	else{
        return ans(arr, i+1, r-arr[i]) || ans(arr, i+1, r);
	}
}

void solve(){
            ll n;
            cin>>n;
            ll i;
            ll arr[n];
            ll c=0;
            ll j,x;
            map<ll,ll>mp;
            for(i=0;i<n;i++){
                cin>>arr[i];
            }
            for(i=0;i<n;i++){
                for(j=i;j<=32;j++){
                  x=pow(2,j);
                  c=c+mp[x-arr[i]];
                }
                mp[arr[i]]++;
            }
            cout<<c<<endl;
}
int main()
{
    fio;
    solve();
}


#include<bits/stdc++.h>
#include<string.h>
#define ll long long int
#define fio ios_base::sync_with_stdio(false); cin.tie(NULL);
#define MAX_LIMIT 100000
#define pb push_back
#define mod 1000000007
#define bb back
#define CHARS_TOTAL 256
#define e endl
/* For counting number of digits, directly do floor(log10(n)+1)*/
using namespace std;

int gcd(ll a, ll b)
{
    // Everything divides 0
    if (a == 0)
       return b;
    if (b == 0)
       return a;

    // base case
    if (a == b)
        return a;

    // a is greater
    if (a > b)
        return gcd(a-b, b);
    return gcd(a, b-a);
}

int largest(ll arr[], ll n)
{
    return *max_element(arr, arr+n);
}
// Function to return LCM of two numbers
 ll lcm(ll a, ll b)
 {
    return (a*b)/gcd(a, b);
 }

ll power(ll x, unsigned ll y)  //Power in O(logn)
{
    ll temp;
    if(y == 0)
        return 1;
    temp = power(x, y / 2);
    if (y % 2 == 0)
        return temp * temp;
    else
    {
        if(y > 0)
            return x * temp * temp;
        else
            return (temp * temp) / x;
    }
}
bool comp(int a, int b)
{
    return (a < b);
}
void divisors(int n)
{
    vector<ll>v;
    // Note that this loop runs till square root
    for (int i=1; i<=sqrt(n); i++)
    {
        if (n%i == 0)
        {
            // If divisors are equal, print only one
            if (n/i == i)
                v.pb(i);

            else // Otherwise print both
            v.pb(i);
            v.pb(n/i);
        }
    }
}
bool isPrime(ll n)
{
    // Corner case
    if (n <= 1)
        return false;

    // Check from 2 to n-1
    for (ll i = 2; i < n; i++)
        if (n % i == 0)
            return false;

    return true;
}

void factors(ll n)
{
    // Print the number of 2s that divide n
    vector<ll>v;
    while (n % 2 == 0)
    {
        cout << 2 << " ";
        n = n/2;
    }

    // n must be odd at this point. So we can skip
    // one element (Note i = i +2)
    for (ll i = 3; i <= sqrt(n); i = i + 2)
    {
        // While i divides n, print i and divide n
        while (n % i == 0)
        {
            v.pb(i);
            n = n/i;
        }
    }

    // This condition is to handle the case when n
    // is a prime number greater than 2
    if (n > 2)
        v.pb(n);
}
bool powertwo(ll x){
  return x&& (!(x&(x-1)));
}
bool ans(ll arr[], ll i, ll r){
	if(i>4){
        return false;
	}
	if(r==0 && i<=4){
        return true;
	}
	else{
        return ans(arr, i+1, r-arr[i]) || ans(arr, i+1, r);
	}
}

void solve(){
            ll n;
            cin>>n;
            ll i;
            ll arr[n];
            ll c=0;
            ll j,x;
            unordered_map<ll,ll>mp
            for(i=0;i<n;i++){
                cin>>arr[i];
            }
            for(i=0;i<n;i++){
                for(j=i;j<=32;j++){
                  x=pow(2,j);
                  c=c+mp[x-arr[i]];
                }
                mp[arr[i]]++;
            }
            cout<<c<<endl;
}
int main()
{
    fio;
    solve();
}


#include<bits/stdc++.h>
#include<string.h>
#define ll long long int
#define fio ios_base::sync_with_stdio(false); cin.tie(NULL);
#define MAX_LIMIT 100000
#define pb push_back
#define mod 1000000007
#define bb back
#define CHARS_TOTAL 256
#define e endl
/* For counting number of digits, directly do floor(log10(n)+1)*/
using namespace std;

int gcd(ll a, ll b)
{
    // Everything divides 0
    if (a == 0)
       return b;
    if (b == 0)
       return a;

    // base case
    if (a == b)
        return a;

    // a is greater
    if (a > b)
        return gcd(a-b, b);
    return gcd(a, b-a);
}

int largest(ll arr[], ll n)
{
    return *max_element(arr, arr+n);
}
// Function to return LCM of two numbers
 ll lcm(ll a, ll b)
 {
    return (a*b)/gcd(a, b);
 }

ll power(ll x, unsigned ll y)  //Power in O(logn)
{
    ll temp;
    if(y == 0)
        return 1;
    temp = power(x, y / 2);
    if (y % 2 == 0)
        return temp * temp;
    else
    {
        if(y > 0)
            return x * temp * temp;
        else
            return (temp * temp) / x;
    }
}
bool comp(int a, int b)
{
    return (a < b);
}
void divisors(int n)
{
    vector<ll>v;
    // Note that this loop runs till square root
    for (int i=1; i<=sqrt(n); i++)
    {
        if (n%i == 0)
        {
            // If divisors are equal, print only one
            if (n/i == i)
                v.pb(i);

            else // Otherwise print both
            v.pb(i);
            v.pb(n/i);
        }
    }
}
bool isPrime(ll n)
{
    // Corner case
    if (n <= 1)
        return false;

    // Check from 2 to n-1
    for (ll i = 2; i < n; i++)
        if (n % i == 0)
            return false;

    return true;
}

void factors(ll n)
{
    // Print the number of 2s that divide n
    vector<ll>v;
    while (n % 2 == 0)
    {
        cout << 2 << " ";
        n = n/2;
    }

    // n must be odd at this point. So we can skip
    // one element (Note i = i +2)
    for (ll i = 3; i <= sqrt(n); i = i + 2)
    {
        // While i divides n, print i and divide n
        while (n % i == 0)
        {
            v.pb(i);
            n = n/i;
        }
    }

    // This condition is to handle the case when n
    // is a prime number greater than 2
    if (n > 2)
        v.pb(n);
}
bool powertwo(ll x){
  return x&& (!(x&(x-1)));
}
bool ans(ll arr[], ll i, ll r){
	if(i>4){
        return false;
	}
	if(r==0 && i<=4){
        return true;
	}
	else{
        return ans(arr, i+1, r-arr[i]) || ans(arr, i+1, r);
	}
}

void solve(){
            ll n;
            cin>>n;
            ll i;
            ll arr[n];
            ll c=0;
            ll j,x;
            map<ll,ll>mp;
            for(i=0;i<n;i++){
                cin>>arr[i];
            }
            for(i=0;i<n;i++){
                for(j=1;j<=32;j++){
                  x=pow(2,j);
                  c=c+mp[x-arr[i]];
                }
                mp[arr[i]]++;
            }
            cout<<c<<endl;
}
int main()
{
    fio;
    solve();
}


#include<bits/stdc++.h>
#include<string.h>
#define ll long long int
#define fio ios_base::sync_with_stdio(false); cin.tie(NULL);
#define MAX_LIMIT 100000
#define pb push_back
#define mod 1000000007
#define bb back
#define CHARS_TOTAL 256
#define e endl
/* For counting number of digits, directly do floor(log10(n)+1)*/
using namespace std;

int gcd(ll a, ll b)
{
    // Everything divides 0
    if (a == 0)
       return b;
    if (b == 0)
       return a;

    // base case
    if (a == b)
        return a;

    // a is greater
    if (a > b)
        return gcd(a-b, b);
    return gcd(a, b-a);
}

int largest(ll arr[], ll n)
{
    return *max_element(arr, arr+n);
}
// Function to return LCM of two numbers
 ll lcm(ll a, ll b)
 {
    return (a*b)/gcd(a, b);
 }

ll power(ll x, unsigned ll y)  //Power in O(logn)
{
    ll temp;
    if(y == 0)
        return 1;
    temp = power(x, y / 2);
    if (y % 2 == 0)
        return temp * temp;
    else
    {
        if(y > 0)
            return x * temp * temp;
        else
            return (temp * temp) / x;
    }
}
bool comp(int a, int b)
{
    return (a < b);
}
void divisors(int n)
{
    vector<ll>v;
    // Note that this loop runs till square root
    for (int i=1; i<=sqrt(n); i++)
    {
        if (n%i == 0)
        {
            // If divisors are equal, print only one
            if (n/i == i)
                v.pb(i);

            else // Otherwise print both
            v.pb(i);
            v.pb(n/i);
        }
    }
}
bool isPrime(ll n)
{
    // Corner case
    if (n <= 1)
        return false;

    // Check from 2 to n-1
    for (ll i = 2; i < n; i++)
        if (n % i == 0)
            return false;

    return true;
}

void factors(ll n)
{
    // Print the number of 2s that divide n
    vector<ll>v;
    while (n % 2 == 0)
    {
        cout << 2 << " ";
        n = n/2;
    }

    // n must be odd at this point. So we can skip
    // one element (Note i = i +2)
    for (ll i = 3; i <= sqrt(n); i = i + 2)
    {
        // While i divides n, print i and divide n
        while (n % i == 0)
        {
            v.pb(i);
            n = n/i;
        }
    }

    // This condition is to handle the case when n
    // is a prime number greater than 2
    if (n > 2)
        v.pb(n);
}
bool powertwo(ll x){
  return x&& (!(x&(x-1)));
}
bool ans(ll arr[], ll i, ll r){
	if(i>4){
        return false;
	}
	if(r==0 && i<=4){
        return true;
	}
	else{
        return ans(arr, i+1, r-arr[i]) || ans(arr, i+1, r);
	}
}

void solve(){
            ll n;
            cin>>n;
            ll i;
            ll arr[n];
            for(i=0;i<n;i++){
                cin>>arr[i];
            }
            ll j,c=0;
            for(i=0;i<n;i++){
                for(j=i+1;j<=n;j++){
                    if(powertwo(arr[i]+arr[j])){
                        c++;
                    }
                }
            }
            cout<<c<<endl;
}
int main()
{
    fio;
    solve();
}


#include<bits/stdc++.h>
#include<string.h>
#define ll long long int
#define fio ios_base::sync_with_stdio(false); cin.tie(NULL);
#define MAX_LIMIT 100000
#define pb push_back
#define mod 1000000007
#define bb back
#define CHARS_TOTAL 256
#define e endl
/* For counting number of digits, directly do floor(log10(n)+1)*/
using namespace std;

int gcd(ll a, ll b)
{
    // Everything divides 0
    if (a == 0)
       return b;
    if (b == 0)
       return a;

    // base case
    if (a == b)
        return a;

    // a is greater
    if (a > b)
        return gcd(a-b, b);
    return gcd(a, b-a);
}

int largest(ll arr[], ll n)
{
    return *max_element(arr, arr+n);
}
// Function to return LCM of two numbers
 ll lcm(ll a, ll b)
 {
    return (a*b)/gcd(a, b);
 }

ll power(ll x, unsigned ll y)  //Power in O(logn)
{
    ll temp;
    if(y == 0)
        return 1;
    temp = power(x, y / 2);
    if (y % 2 == 0)
        return temp * temp;
    else
    {
        if(y > 0)
            return x * temp * temp;
        else
            return (temp * temp) / x;
    }
}
bool comp(int a, int b)
{
    return (a < b);
}
void divisors(int n)
{
    vector<ll>v;
    // Note that this loop runs till square root
    for (int i=1; i<=sqrt(n); i++)
    {
        if (n%i == 0)
        {
            // If divisors are equal, print only one
            if (n/i == i)
                v.pb(i);

            else // Otherwise print both
            v.pb(i);
            v.pb(n/i);
        }
    }
}
bool isPrime(ll n)
{
    // Corner case
    if (n <= 1)
        return false;

    // Check from 2 to n-1
    for (ll i = 2; i < n; i++)
        if (n % i == 0)
            return false;

    return true;
}

void factors(ll n)
{
    // Print the number of 2s that divide n
    vector<ll>v;
    while (n % 2 == 0)
    {
        cout << 2 << " ";
        n = n/2;
    }

    // n must be odd at this point. So we can skip
    // one element (Note i = i +2)
    for (ll i = 3; i <= sqrt(n); i = i + 2)
    {
        // While i divides n, print i and divide n
        while (n % i == 0)
        {
            v.pb(i);
            n = n/i;
        }
    }

    // This condition is to handle the case when n
    // is a prime number greater than 2
    if (n > 2)
        v.pb(n);
}
bool powertwo(ll x){
  return x&& (!(x&(x-1)));
}
bool ans(ll arr[], ll i, ll r){
	if(i>4){
        return false;
	}
	if(r==0 && i<=4){
        return true;
	}
	else{
        return ans(arr, i+1, r-arr[i]) || ans(arr, i+1, r);
	}
}

void solve(){
            unordered_map<ll,ll> mp;
            for (ll i = 0; i < n; i++)
                mp[a[i]]++;
            sort(a, a + n, greater<ll>());
    ll c = 0;
    for (ll i = 0; i < n; i++) {

        // If element has already been paired
        if (mp[a[i]] < 1)
            continue;

        // Find the number which is greater than
        // a[i] and power of two
        ll cur = 1;
        while (cur <= a[i])
            cur <<= 1;

        // If there is a number which adds up with a[i]
        // to form a power of two
        if (mp[cur - a[i]]) {

            // Edge case when a[i] and crr - a[i] is same
            // and we have only one occurrence of a[i] then
            // it cannot be paired
            if (cur - a[i] == a[i] and mp[a[i]] == 1)
                continue;

            count++;

            // Remove already paired elements
            mp[cur - a[i]]--;
            mp[a[i]]--;
        }
    }

    // Return the count
    return count;
}
int main()
{
    fio;
    ll n;
    cin>>n;
    ll i;
    ll arr[n];
    for(i=0;i<n;i++){
        cin>>arr[i];
    }
    cout<<solve(arr,n);
}


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;

long long ans;
int n, x;
cc_hash_table < int, int> used;

int main(){
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i++){
        cin >> x;
        for(int j = 0; j <= 30; j++)
            ans += used[(1LL << j) - x];
        used[x]++;
    }
    cout << ans;
}


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;

long long ans;
int n, x;
gp_hash_table < int, int> used;

int main(){
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i++){
        cin >> x;
        for(int j = 0; j <= 30; j++)
            ans += used[(1LL << j) - x];
        used[x]++;
    }
    cout << ans;
}


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;

long long ans;
int n, x;
gp_hash_table < int, int> used;

int main(){
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i++){
        cin >> x;
        for(int j = 0; j <= 30; j++){
            int y = (1LL << j) - x;
            if(used.find(y) != used.end()){
                ans += used[y];
            }
        }
        used[x]++;
    }
    cout << ans;
}


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;

long long ans;
int n, x;
cc_hash_table < int, int> used;

int main(){
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i++){
        cin >> x;
        for(int j = 0; j <= 30; j++){
            int y = (1LL << j) - x;
            if(used.find(y) != used.end()){
                ans += used[y];
            }
        }
        used[x]++;
    }
    cout << ans;
}


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;

long long ans;
int n, x;
unordered_map < int, int> used;

int main(){
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i++){
        cin >> x;
        for(int j = 0; j <= 30; j++){
            int y = (1LL << j) - x;
            if(used.find(y) != used.end()){
                ans += used[y];
            }
        }
        used[x]++;
    }
    cout << ans;
}


#include<bits/stdc++.h>
using namespace std;

long long ans;
int n, x;
map < int, int > used;

int main(){
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i++){
        cin >> x;
        for(int j = 0; j <= 30; j++)
            ans += used[(1LL << j) - x];
        used[x]++;
    }
    cout << ans;
}


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;

long long ans;
int n, x;
unordered_map < int, int> used;

int main(){
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i++){
        cin >> x;
        for(int j = 0; j <= 30; j++)
            ans += used[(1LL << j) - x];
        used[x]++;
    }
    cout << ans;
}


#include <iostream>
#include <cmath>
#include "vector"
#define all(v) ((v).begin(),(v).end())
#define sz(v) ((int)((v).size()))
using namespace std;

vector<long> a;
long checkPairs(long al, int i) {
	if (i == a.size()) return 0;
	double x = log2((al + a[i]));
	if (ceil(x)!=x) return 0 + checkPairs(al, ++i);
	return 1 + checkPairs(al, ++i);
}
int main() {

	int n,r=0;
	cin >> n;
	a.resize(n);
	for (int i = 0; i < n; i++) cin >> a[i];

	for (int i = 0; i < n - 1; i++) r = r + checkPairs(a[i], i + 1);
	cout << r;
	return 0;
}


#include <iostream>
#include <cmath>
#include "vector"
#define all(v) ((v).begin(),(v).end())
#define sz(v) ((int)((v).size()))
using namespace std;

vector<long> a;
long checkPairs(long al, int i) {
	if (i == a.size()) return 0;
	long x = al + a[i];
	if (x&(x-1)) return 0 + checkPairs(al, ++i);
	return 1 + checkPairs(al, ++i);
}
int main() {

	int n,r=0;
	cin >> n;
	a.resize(n);
	for (int i = 0; i < n; i++) cin >> a[i];

	for (int i = 0; i < n - 1; i++) r = r + checkPairs(a[i], i + 1);
	cout << r;
	return 0;
}


#include <iostream>
#include <cmath>
#include "vector"
#include "map"
#include "set"
#define all(v) ((v).begin(),(v).end())
#define sz(v) ((int)((v).size()))
using namespace std;

int main() {
	int n, r = 0;
	map<long,int> m;

	cin >> n;
	vector<long> p(32);
	long  z = 1;
	for (int i = 0; i <= 30; i++) { p[i] = z ; z *= 2 ; }

	for (int i = 0; i < n; i++) {
		long in;
		cin>>in;
	    m[in]++;
	}
	long ans = 0;
	for (auto x : m)
	{
		for (int i = 0; i <= 30; i++)
		{
			long xx = p[i] - x.first;
			if (xx < 0)
				continue;

			int f = m.count(xx);
			if (f && xx >= x.first)
			{
				if (x.first == xx)
				{
					ans += x.second*(x.second - 1) / 2;
				}
				else
				{
					ans += x.second*m[xx];
				}
			}

		}
	}

	cout << ans << endl;
}


#include <iostream>
#include <cmath>
#include "vector"
#include "map"
#include "set"
#define all(v) ((v).begin(),(v).end())
#define sz(v) ((int)((v).size()))
using namespace std;

int main() {
	long long n, r = 0;
	map<long long,int> m;

	cin >> n;
	vector<long long> p(32);
	long long z = 1;
	for (int i = 0; i <= 30; i++) { p[i] = z ; z *= 2 ; }

	for (long long i = 0; i < n; i++) {
		long long in;
		cin>>in;
	    m[in]++;
	}
	long long ans = 0;
	for (auto x : m)
	{
		for (int i = 0; i <= 30; i++)
		{
			long long xx = p[i] - x.first;
			if (xx < 0)
				continue;

			long long f = m.count(xx);
			if (f && xx >= x.first)
			{
				if (x.first == xx)
				{
					ans += x.second*(x.second - 1) / 2;
				}
				else
				{
					ans += x.second*m[xx];
				}
			}

		}
	}

	cout << ans << endl;
}


#include <iostream>
#include <cmath>
#include "vector"
#include "map"
#include "set"
#define all(v) ((v).begin(),(v).end())
#define sz(v) ((int)((v).size()))
using namespace std;

int main() {
	long long n, r = 0;
	map<long long,long long> m;

	cin >> n;
	vector<long long> p(32);
	long long z = 1;
	for (int i = 0; i <= 30; i++) { p[i] = z ; z *= 2 ; }

	for (long long i = 0; i < n; i++) {
		long long in;
		cin>>in;
	    m[in]++;
	}
	long long ans = 0;
	for (auto x : m)
	{
		for (int i = 0; i <= 30; i++)
		{
			long long xx = p[i] - x.first;
			if (xx < 0)
				continue;

			long long f = m.count(xx);
			if (f && xx >= x.first)
			{
				if (x.first == xx)
				{
					ans += x.second*(x.second - 1) / 2;
				}
				else
				{
					ans += x.second*m[xx];
				}
			}

		}
	}

	cout << ans << endl;
}


#include <iostream>
#include <cmath>
#include "vector"
#include "map"
#include "set"
#define all(v) ((v).begin(),(v).end())
#define sz(v) ((int)((v).size()))
using namespace std;

int main() {
	long long n, r = 0;
	map<long,int> m;

	cin >> n;
	vector<long long> p(32);
	long long z = 1;
	for (int i = 0; i <= 30; i++) { p[i] = z ; z *= 2 ; }

	for (int i = 0; i < n; i++) {
		long long in;
		cin>>in;
	    m[in]++;
	}
	long long ans = 0;
	for (auto x : m)
	{
		for (int i = 0; i <= 30; i++)
		{
			long long xx = p[i] - x.first;
			if (xx < 0)
				continue;

			long long f = m.count(xx);
			if (f && xx >= x.first)
			{
				if (x.first == xx)
				{
					ans += x.second*(x.second - 1) / 2;
				}
				else
				{
					ans += x.second*m[xx];
				}
			}

		}
	}

	cout << ans << endl;
}


#include <cstdio>
#include <map>

long long m,l[32],n,a[100005];
std::map<int,int> cnt;

int main() {
	scanf("%lld",&n);
	for (int i=0;i<n;i++) {
		scanf("%lld",a+i);
		cnt[a[i]]++;
	}
	l[0]=2;
	for (int i=1;i<30;i++) l[i]=l[i-1]<<1;
	for (int i=0;i<n;i++) {
		cnt[a[i]]--;
		for (int j=29;j>=0;j--) {
			if (l[j]<a[i]) break;
			m+=cnt[l[j]-a[i]];
		}
	}
	printf("%lld\n",m);
	return 0;
}


use std::io::{self, BufRead};

#[derive(Debug)]
struct Container {
    w: u32,
    h: u32,
    original_index: usize,
    chain_length: u32,
    chain_next: usize,
}

fn parse_problem<B: BufRead>(mut input: B) -> io::Result<Vec<Container>>{
    let mut buffer = String::new();
    input.read_line(&mut buffer)?;
    let nums: Vec<u32> = buffer
        .split_ascii_whitespace()
        .map(|x| x.parse().unwrap())
        .collect();
    if nums.len() != 3 {
        return Err(io::Error::new(io::ErrorKind::InvalidInput, "bad input"))
    }
    let n = nums[0];
    let mut containers = Vec::with_capacity(n as usize);
    let letter_w = nums[1];
    let letter_h = nums[2];
    containers.push(Container { w: letter_w,
                                h: letter_h,
                                original_index: 0,
                                chain_length: 0,
                                chain_next: 0 } );
    for (idx, line) in input.lines().enumerate().take(n as usize) {
        let envelope_spec: Vec<u32> = line?
            .split_ascii_whitespace()
            .map(|x| x.parse().unwrap())
            .collect();
        if envelope_spec.len() != 2 {
            return Err(io::Error::new(io::ErrorKind::InvalidInput, "bad input"))
        }
        let w = envelope_spec[0];
        let h = envelope_spec[1];
        if letter_w < w && letter_h < h {
            containers.push(Container { w: w,
                                        h: h,
                                        original_index: idx + 1,
                                        chain_length: 0,
                                        chain_next: 0 } );
        }
    }
    Ok(containers)
}

fn main() -> io::Result<()> {
    let mut containers = parse_problem(io::stdin().lock())?;
    containers.sort_unstable_by_key(|c| c.w * c.h);
    for i in (0..containers.len()).rev() {
        for j in i + 1..containers.len() {
            let (left, right) = containers.split_at_mut(i + 1);
            let first = &mut left[i];
            let second = &right[j - i - 1];
            if first.w < second.w &&
                first.h < second.h &&
                first.chain_length <= second.chain_length {
                first.chain_length = second.chain_length + 1;
                first.chain_next = j;
            }
        }
    }
    // print answer
    if containers[0].chain_next == 0 {
        println!("0");
        return Ok(())
    }
    let mut containers_idx = containers[0].chain_next;
    while containers_idx != 0 {
        print!("{} ", containers[containers_idx].original_index);
        containers_idx = containers[containers_idx].chain_next;
    }
    Ok(())
}


use std::io::{self, BufRead};

#[derive(Debug)]
struct Container {
    w: u64,
    h: u64,
    original_index: usize,
    chain_length: u32,
    chain_next: usize,
}

fn parse_problem<B: BufRead>(mut input: B) -> io::Result<Vec<Container>>{
    let mut buffer = String::new();
    input.read_line(&mut buffer)?;
    let nums: Vec<u64> = buffer
        .split_ascii_whitespace()
        .map(|x| x.parse().unwrap())
        .collect();
    if nums.len() != 3 {
        return Err(io::Error::new(io::ErrorKind::InvalidInput, "bad input"))
    }
    let n = nums[0];
    let mut containers = Vec::with_capacity(n as usize);
    let letter_w = nums[1];
    let letter_h = nums[2];
    containers.push(Container { w: letter_w,
                                h: letter_h,
                                original_index: 0,
                                chain_length: 0,
                                chain_next: 0 } );
    for (idx, line) in input.lines().enumerate().take(n as usize) {
        let envelope_spec: Vec<u64> = line?
            .split_ascii_whitespace()
            .map(|x| x.parse().unwrap())
            .collect();
        if envelope_spec.len() != 2 {
            return Err(io::Error::new(io::ErrorKind::InvalidInput, "bad input"))
        }
        let w = envelope_spec[0];
        let h = envelope_spec[1];
        if letter_w < w && letter_h < h {
            containers.push(Container { w: w,
                                        h: h,
                                        original_index: idx + 1,
                                        chain_length: 0,
                                        chain_next: 0 } );
        }
    }
    Ok(containers)
}

fn main() -> io::Result<()> {
    let mut containers = parse_problem(io::stdin().lock())?;
    containers.sort_unstable_by_key(|c| c.w * c.h);
    for i in (0..containers.len()).rev() {
        for j in i + 1..containers.len() {
            let (left, right) = containers.split_at_mut(i + 1);
            let first = &mut left[i];
            let second = &right[j - i - 1];
            if first.w < second.w &&
                first.h < second.h &&
                first.chain_length <= second.chain_length {
                first.chain_length = second.chain_length + 1;
                first.chain_next = j;
            }
        }
    }
    // print answer
    if containers[0].chain_next == 0 {
        println!("0");
        return Ok(())
    }
    println!("{}", containers[0].chain_length);
    let mut containers_idx = containers[0].chain_next;
    while containers_idx != 0 {
        print!("{} ", containers[containers_idx].original_index);
        containers_idx = containers[containers_idx].chain_next;
    }
    Ok(())
}


use std::io::{self, BufRead};

#[derive(Debug)]
struct Container {
    w: u32,
    h: u32,
    original_index: usize,
    chain_length: u32,
    chain_next: usize,
}

fn parse_problem<B: BufRead>(mut input: B) -> io::Result<Vec<Container>>{
    let mut buffer = String::new();
    input.read_line(&mut buffer)?;
    let nums: Vec<u32> = buffer
        .split_ascii_whitespace()
        .map(|x| x.parse().unwrap())
        .collect();
    if nums.len() != 3 {
        return Err(io::Error::new(io::ErrorKind::InvalidInput, "bad input"))
    }
    let n = nums[0];
    let mut containers = Vec::with_capacity(n as usize);
    let letter_w = nums[1];
    let letter_h = nums[2];
    containers.push(Container { w: letter_w,
                                h: letter_h,
                                original_index: 0,
                                chain_length: 0,
                                chain_next: 0 } );
    for (idx, line) in input.lines().enumerate().take(n as usize) {
        let envelope_spec: Vec<u32> = line?
            .split_ascii_whitespace()
            .map(|x| x.parse().unwrap())
            .collect();
        if envelope_spec.len() != 2 {
            return Err(io::Error::new(io::ErrorKind::InvalidInput, "bad input"))
        }
        let w = envelope_spec[0];
        let h = envelope_spec[1];
        if letter_w < w && letter_h < h {
            containers.push(Container { w: w,
                                        h: h,
                                        original_index: idx + 1,
                                        chain_length: 0,
                                        chain_next: 0 } );
        }
    }
    Ok(containers)
}

fn main() -> io::Result<()> {
    let mut containers = parse_problem(io::stdin().lock())?;
    containers.sort_unstable_by_key(|c| c.w * c.h);
    for i in (0..containers.len()).rev() {
        for j in i + 1..containers.len() {
            let (left, right) = containers.split_at_mut(i + 1);
            let first = &mut left[i];
            let second = &right[j - i - 1];
            if first.w < second.w &&
                first.h < second.h &&
                first.chain_length <= second.chain_length {
                first.chain_length = second.chain_length + 1;
                first.chain_next = j;
            }
        }
    }
    // print answer
    if containers[0].chain_next == 0 {
        println!("0");
        return Ok(())
    }
    println!("{}", containers[0].chain_length);
    let mut containers_idx = containers[0].chain_next;
    while containers_idx != 0 {
        print!("{} ", containers[containers_idx].original_index);
        containers_idx = containers[containers_idx].chain_next;
    }
    Ok(())
}


use std::io::{self, Read as _};

fn main() {
    let mut input = String::new();
    io::stdin().read_to_string(&mut input).unwrap();
    let mut input = input.split_whitespace();
    macro_rules! read(
        (($($tt:tt),+)) => (($(read!($tt)),*));
        ($ty:ty) => (input.next().unwrap().parse::<$ty>().unwrap());
    );

    let (n, w, h) = read!((usize, u64, u64));
    let mut whs = (0..n)
        .map(|i| (read!(u64), read!(u64), i + 1))
        .filter(|&(wi, hi, _)| wi > w && hi > h)
        .collect::<Vec<_>>();
    whs.sort();
    let n = whs.len();
    let mut dp = (0..n).map(|i| (1, i)).collect::<Vec<_>>();
    for i in 1..n {
        for j in 0..i {
            if whs[j].0 < whs[i].0 && whs[j].1 < whs[i].1 && dp[j].0 + 1 > dp[i].0 {
                dp[i] = (dp[j].0 + 1, j)
            }
        }
    }
    let mut ys = vec![];
    let mut m = 0;
    let mut i = 0;
    for j in 0..n {
        if m < dp[j].0 {
            m = dp[j].0;
            i = j;
        }
    }
    println!("{}", m);
    while m > 0 {
        ys.push(whs[i].2);
        m -= 1;
        i = dp[i].1;
    }
    ys.reverse();
    println!(
        "{}",
        ys.iter()
            .map(|i| i.to_string())
            .collect::<Vec<_>>()
            .join(" ")
    );
}


use std::collections::BTreeSet;
use std::io;
use std::io::Stdin;
use std::str::FromStr;

fn read_line(stdin : &Stdin, line : &mut String) {
    match stdin.read_line(line) {
        Ok(_) => return,
        Err(msg) => panic!("Could not read line! Message: {}.", msg),
    }
}

fn parse_t<T : FromStr>(s : &str) -> T {
    match s.trim().parse() {
        Ok(y) => y,
        Err(_) => panic!("Could not read from string!"),
    }
}

fn read_ts<T : FromStr>(stdin : &Stdin, ts : &mut Vec<T>) {
    let mut line = String::new();
    read_line(stdin, &mut line);
    let word_iter = line.split_whitespace();
    for word in word_iter {
        let x = parse_t(word);
        ts.push(x);
    }
}

fn print_maximum_chain(envelopes : &mut Vec<(u64, u64, u64)>) {
    // Sort envelopes in descending order of (w, h).
    envelopes.sort();
    envelopes.reverse();
    let mut covering_tree : Vec<(usize, usize, usize)> = vec![];
    let mut covering_tree_roots = BTreeSet::new();
    for env_id in 0 .. envelopes.len() {
        let (w, h, _) = envelopes[env_id];
        let node_id = covering_tree.len();
        // if the covering_tree is empty.
        if covering_tree_roots.is_empty() {
            // The newly inserted node is a root.
            covering_tree.push((env_id, usize::max_value(), 1));
            covering_tree_roots.insert(node_id);
        } else {
            // Find the deepest root that covers the given envelope.
            let mut deepest_root = usize::max_value();
            let mut deepest_root_depth = 0;
            for &root in covering_tree_roots.iter() {
                let (root_env_id, _, root_depth) = covering_tree[root];
                let (root_w, root_h, _) = envelopes[root_env_id];
                if (root_w > w) && (root_h > h) {
                    if root_depth > deepest_root_depth {
                        deepest_root_depth = root_depth;
                        deepest_root = root;
                    }
                }
            }
            // If no root was found to cover the envelope.
            if deepest_root_depth == 0 {
                // The envelope is a root of a new branch.
                covering_tree_roots.insert(node_id);
                covering_tree.push((env_id, usize::max_value(), 1));
            } else {
                // The envelope is the root of an existing branch.
                covering_tree_roots.insert(node_id);
                covering_tree_roots.remove(&deepest_root);
                covering_tree.push((env_id, deepest_root, deepest_root_depth + 1));
            }
        }
    }

    // println!("{:?}", envelopes);
    // println!("{:?}", covering_tree_roots);
    // println!("{:?}", covering_tree);

    // Find the deepest root.
    let mut deepest_root = usize::max_value();
    let mut deepest_root_depth = 0;
    for &root in covering_tree_roots.iter() {
        let (_, _, root_depth) = covering_tree[root];
        if root_depth > deepest_root_depth {
            deepest_root_depth = root_depth;
            deepest_root = root;
        }
    }
    println!("{}", deepest_root_depth);
    let mut is_first = true;
    loop {
        if deepest_root == usize::max_value() {
            break;
        } else {
            let (env_id, child_id, _) = covering_tree[deepest_root];
            if is_first {
                is_first = false;
            } else {
                print!(" ");
            }
            let (_, _, i) = envelopes[env_id];
            print!("{}", i);
            deepest_root = child_id;
        }
    }
    println!();
}

fn main() {
    let stdin = io::stdin();
    let mut n_w_h = vec![];
    read_ts(&stdin, &mut n_w_h);
    let n = n_w_h[0];
    let card_width = n_w_h[1];
    let card_height = n_w_h[2];
    let mut envelopes : Vec<(u64, u64, u64)> = vec![];
    for i in 1 .. (n + 1) {
        let mut w_h = vec![];
        read_ts(&stdin, &mut w_h);
        let envelope_width = w_h[0];
        let envelope_height = w_h[1];
        if (envelope_width > card_width) && (envelope_height > card_height) {
            envelopes.push((envelope_width, envelope_height, i));
        }
    }
    // println!("n = {}, w = {}, h = {}", n, card_width, card_height);
    print_maximum_chain(&mut envelopes);
}


use std::collections::BTreeSet;
use std::io;
use std::io::Stdin;
use std::str::FromStr;

fn read_line(stdin : &Stdin, line : &mut String) {
    match stdin.read_line(line) {
        Ok(_) => return,
        Err(msg) => panic!("Could not read line! Message: {}.", msg),
    }
}

fn parse_t<T : FromStr>(s : &str) -> T {
    match s.trim().parse() {
        Ok(y) => y,
        Err(_) => panic!("Could not read from string!"),
    }
}

fn read_ts<T : FromStr>(stdin : &Stdin, ts : &mut Vec<T>) {
    let mut line = String::new();
    read_line(stdin, &mut line);
    let word_iter = line.split_whitespace();
    for word in word_iter {
        let x = parse_t(word);
        ts.push(x);
    }
}

fn print_maximum_chain(envelopes : &mut Vec<(u64, u64, u64)>) {
    // Sort envelopes in descending order of (w, h).
    envelopes.sort();
    envelopes.reverse();
    // Keep track of the chains.
    let mut covering_dag : Vec<(usize, usize, usize)> = vec![];
    let mut covering_dag_roots = BTreeSet::new();
    let mut node_id = 0;
    for env_id in 0 .. envelopes.len() {
        let (w, h, _) = envelopes[env_id];
        // if the covering dag is empty.
        if covering_dag_roots.is_empty() {
            // The newly inserted node is a root.
            covering_dag.push((env_id, usize::max_value(), 1));
            covering_dag_roots.insert(node_id);
            node_id = node_id + 1;
        } else {
            let mut roots_to_add = BTreeSet::new();
            let mut roots_to_remove = BTreeSet::new();
            let mut found_cover = false;
            // Insert the envelope into the covering dag.
            for &root in covering_dag_roots.iter() {
                let mut cursor = root;
                loop {
                    if cursor == usize::max_value() {
                        break;
                    } else {
                        let (cursor_env_id, cursor_child_id, cursor_depth) = covering_dag[cursor];
                        let (cursor_w, cursor_h, _) = envelopes[cursor_env_id];
                        // if the envelope is covered.
                        if (cursor_w > w) && (cursor_h > h) {
                            covering_dag.push((env_id, cursor, cursor_depth + 1));
                            roots_to_add.insert(node_id);
                            node_id = node_id + 1;
                            roots_to_remove.insert(cursor);
                            found_cover = true;
                            break;
                        } else {
                            cursor = cursor_child_id;
                        }
                    }
                }
            }
            for root in roots_to_remove.iter() {
                covering_dag_roots.remove(root);
            }
            for &root in roots_to_add.iter() {
                covering_dag_roots.insert(root);
            }
            // If no root was found to cover the envelope.
            if found_cover {
                // Do nothing ...
            } else {
                // The envelope is a root of a new branch.
                covering_dag_roots.insert(node_id);
                covering_dag.push((env_id, usize::max_value(), 1));
                node_id = node_id + 1;
            }
        }
    }

    // println!("{:?}", envelopes);
    // println!("{:?}", covering_tree_roots);
    // println!("{:?}", covering_tree);

    // Find the deepest root.
    let mut deepest_root = usize::max_value();
    let mut deepest_root_depth = 0;
    for &root in covering_dag_roots.iter() {
        let (_, _, root_depth) = covering_dag[root];
        if root_depth > deepest_root_depth {
            deepest_root_depth = root_depth;
            deepest_root = root;
        }
    }
    println!("{}", deepest_root_depth);
    let mut is_first = true;
    loop {
        if deepest_root == usize::max_value() {
            break;
        } else {
            let (env_id, child_id, _) = covering_dag[deepest_root];
            if is_first {
                is_first = false;
            } else {
                print!(" ");
            }
            let (_, _, i) = envelopes[env_id];
            print!("{}", i);
            deepest_root = child_id;
        }
    }
    println!();
}

fn main() {
    let stdin = io::stdin();
    let mut n_w_h = vec![];
    read_ts(&stdin, &mut n_w_h);
    let n = n_w_h[0];
    let card_width = n_w_h[1];
    let card_height = n_w_h[2];
    let mut envelopes : Vec<(u64, u64, u64)> = vec![];
    for i in 1 .. (n + 1) {
        let mut w_h = vec![];
        read_ts(&stdin, &mut w_h);
        let envelope_width = w_h[0];
        let envelope_height = w_h[1];
        if (envelope_width > card_width) && (envelope_height > card_height) {
            envelopes.push((envelope_width, envelope_height, i));
        }
    }
    // println!("n = {}, w = {}, h = {}", n, card_width, card_height);
    print_maximum_chain(&mut envelopes);
}


use std::collections::BTreeSet;
use std::io;
use std::io::Stdin;
use std::str::FromStr;

fn read_line(stdin : &Stdin, line : &mut String) {
    match stdin.read_line(line) {
        Ok(_) => return,
        Err(msg) => panic!("Could not read line! Message: {}.", msg),
    }
}

fn parse_t<T : FromStr>(s : &str) -> T {
    match s.trim().parse() {
        Ok(y) => y,
        Err(_) => panic!("Could not read from string!"),
    }
}

fn read_ts<T : FromStr>(stdin : &Stdin, ts : &mut Vec<T>) {
    let mut line = String::new();
    read_line(stdin, &mut line);
    let word_iter = line.split_whitespace();
    for word in word_iter {
        let x = parse_t(word);
        ts.push(x);
    }
}

fn print_maximum_chain(envelopes : &mut Vec<(usize, usize, usize)>, print_debug : bool) {
    if print_debug {
        println!("Sorting envelopes! - {}", envelopes.len());
    }
    // Sort envelopes in descending order of (w, h).
    envelopes.sort();
    envelopes.reverse();
    // Keep track of the chains.
    let mut covering_dag : Vec<(usize, usize, usize)> = vec![];
    let mut covering_dag_roots = BTreeSet::new();
    let mut node_id = 0;
    let mut counter = 0;
    for env_id in 0 .. envelopes.len() {
        counter = counter + 1;
        let (w, h, _) = envelopes[env_id];
        // if the covering dag is empty.
        if covering_dag_roots.is_empty() {
            // The newly inserted node is a root.
            covering_dag.push((env_id, usize::max_value(), 1));
            covering_dag_roots.insert(node_id);
            node_id = node_id + 1;
        } else {
            let mut covering_nodes = vec![];
            let mut found_cover = false;
            // Insert the envelope into the covering dag.
            for &root in covering_dag_roots.iter() {
                let mut cursor = root;
                loop {
                    if cursor == usize::max_value() {
                        break;
                    } else {
                        let (cursor_env_id, cursor_child_id, _) = covering_dag[cursor];
                        let (cursor_w, cursor_h, _) = envelopes[cursor_env_id];
                        // if the envelope is covered.
                        if (cursor_w > w) && (cursor_h > h) {
                            covering_nodes.push(cursor);
                            found_cover = true;
                            break;
                        } else {
                            cursor = cursor_child_id;
                        }
                    }
                }
            }
            // If nodes were found to cover the envelope.
            if found_cover {
                // Add root to the deepest node.
                let mut deepest_node = usize::max_value();
                let mut deepest_node_depth = 0;
                for cursor in covering_nodes {
                    let (_, _, cursor_depth) = covering_dag[cursor];
                    if cursor_depth > deepest_node_depth {
                        deepest_node_depth = cursor_depth;
                        deepest_node = cursor;
                    }
                }
                covering_dag_roots.insert(node_id);
                covering_dag.push((env_id, deepest_node, deepest_node_depth + 1));
                node_id = node_id + 1;
            } else {
                // If no node was found to cover the envelope.
                // The envelope is a root of a new branch.
                covering_dag_roots.insert(node_id);
                covering_dag.push((env_id, usize::max_value(), 1));
                node_id = node_id + 1;
            }
        }
        if print_debug && (counter == 10) {
            println!("Processing envelopes! - {} - {}", covering_dag_roots.len(), covering_dag.len());
            counter = 0;
        }
    }

    if print_debug {
        println!("Processed envelopes! - {} - {}", covering_dag_roots.len(), covering_dag.len());
    }

    // println!("{:?}", envelopes);
    // println!("{:?}", covering_tree_roots);
    // println!("{:?}", covering_tree);

    // Find the deepest root.
    let mut deepest_root = usize::max_value();
    let mut deepest_root_depth = 0;
    for &root in covering_dag_roots.iter() {
        let (_, _, root_depth) = covering_dag[root];
        if root_depth > deepest_root_depth {
            deepest_root_depth = root_depth;
            deepest_root = root;
        }
    }
    println!("{}", deepest_root_depth);
    let mut is_first = true;
    loop {
        if deepest_root == usize::max_value() {
            break;
        } else {
            let (env_id, child_id, _) = covering_dag[deepest_root];
            if is_first {
                is_first = false;
            } else {
                print!(" ");
            }
            let (_, _, i) = envelopes[env_id];
            print!("{}", i);
            deepest_root = child_id;
        }
    }
    println!();
}

fn main() {
    let stdin = io::stdin();
    let mut n_w_h = vec![];
    read_ts(&stdin, &mut n_w_h);
    let n = n_w_h[0];
    let card_width = n_w_h[1];
    let card_height = n_w_h[2];
    let mut envelopes : Vec<(usize, usize, usize)> = vec![];
    for i in 1 .. (n + 1) {
        let mut w_h = vec![];
        read_ts(&stdin, &mut w_h);
        let envelope_width = w_h[0];
        let envelope_height = w_h[1];
        if (envelope_width > card_width) && (envelope_height > card_height) {
            envelopes.push((envelope_width, envelope_height, i));
        }
    }
    // println!("n = {}, w = {}, h = {}", n, card_width, card_height);
    let print_debug = (n == 483) && (card_width == 103232) && (card_height == 75323);
    // let print_debug = true;
    print_maximum_chain(&mut envelopes, print_debug);
}


use std::collections::BTreeSet;
use std::io;
use std::io::Stdin;
use std::str::FromStr;

fn read_line(stdin : &Stdin, line : &mut String) {
    match stdin.read_line(line) {
        Ok(_) => return,
        Err(msg) => panic!("Could not read line! Message: {}.", msg),
    }
}

fn parse_t<T : FromStr>(s : &str) -> T {
    match s.trim().parse() {
        Ok(y) => y,
        Err(_) => panic!("Could not read from string!"),
    }
}

fn read_ts<T : FromStr>(stdin : &Stdin, ts : &mut Vec<T>) {
    let mut line = String::new();
    read_line(stdin, &mut line);
    let word_iter = line.split_whitespace();
    for word in word_iter {
        let x = parse_t(word);
        ts.push(x);
    }
}

fn print_maximum_chain(envelopes : &mut Vec<(usize, usize, usize)>, print_debug : bool) {
    if print_debug {
        println!("Sorting envelopes! - {}", envelopes.len());
    }
    // Sort envelopes in descending order of (w, h).
    envelopes.sort();
    envelopes.reverse();
    // Keep track of the chains.
    let mut covering_dag : Vec<(usize, usize, usize)> = vec![];
    let mut covering_dag_roots = BTreeSet::new();
    let mut node_id = 0;
    for env_id in 0 .. envelopes.len() {
        let (w, h, _) = envelopes[env_id];
        // if the covering dag is empty.
        if covering_dag_roots.is_empty() {
            // The newly inserted node is a root.
            covering_dag.push((env_id, usize::max_value(), 1));
            covering_dag_roots.insert(node_id);
            node_id = node_id + 1;
        } else {
            let mut roots_to_add = BTreeSet::new();
            let mut roots_to_remove = BTreeSet::new();
            let mut found_cover = false;
            // Insert the envelope into the covering dag.
            for &root in covering_dag_roots.iter() {
                let mut cursor = root;
                loop {
                    if cursor == usize::max_value() {
                        break;
                    } else {
                        let (cursor_env_id, cursor_child_id, cursor_depth) = covering_dag[cursor];
                        let (cursor_w, cursor_h, _) = envelopes[cursor_env_id];
                        // if the envelope is covered.
                        if (cursor_w > w) && (cursor_h > h) {
                            covering_dag.push((env_id, cursor, cursor_depth + 1));
                            roots_to_add.insert(node_id);
                            node_id = node_id + 1;
                            roots_to_remove.insert(cursor);
                            found_cover = true;
                            break;
                        } else {
                            cursor = cursor_child_id;
                        }
                    }
                }
            }
            for root in roots_to_remove.iter() {
                covering_dag_roots.remove(root);
            }
            for &root in roots_to_add.iter() {
                covering_dag_roots.insert(root);
            }
            // If no root was found to cover the envelope.
            if found_cover {
                // Do nothing ...
            } else {
                // The envelope is a root of a new branch.
                covering_dag_roots.insert(node_id);
                covering_dag.push((env_id, usize::max_value(), 1));
                node_id = node_id + 1;
            }
        }
        if print_debug {
            println!("Processed envelopes! - {} - {}", covering_dag_roots.len(), covering_dag.len());
        }
    }

    if print_debug {
        println!("Processed envelopes! - {} - {}", covering_dag_roots.len(), covering_dag.len());
    }

    // println!("{:?}", envelopes);
    // println!("{:?}", covering_tree_roots);
    // println!("{:?}", covering_tree);

    // Find the deepest root.
    let mut deepest_root = usize::max_value();
    let mut deepest_root_depth = 0;
    for &root in covering_dag_roots.iter() {
        let (_, _, root_depth) = covering_dag[root];
        if root_depth > deepest_root_depth {
            deepest_root_depth = root_depth;
            deepest_root = root;
        }
    }
    println!("{}", deepest_root_depth);
    let mut is_first = true;
    loop {
        if deepest_root == usize::max_value() {
            break;
        } else {
            let (env_id, child_id, _) = covering_dag[deepest_root];
            if is_first {
                is_first = false;
            } else {
                print!(" ");
            }
            let (_, _, i) = envelopes[env_id];
            print!("{}", i);
            deepest_root = child_id;
        }
    }
    println!();
}

fn main() {
    let stdin = io::stdin();
    let mut n_w_h = vec![];
    read_ts(&stdin, &mut n_w_h);
    let n = n_w_h[0];
    let card_width = n_w_h[1];
    let card_height = n_w_h[2];
    let mut envelopes : Vec<(usize, usize, usize)> = vec![];
    for i in 1 .. (n + 1) {
        let mut w_h = vec![];
        read_ts(&stdin, &mut w_h);
        let envelope_width = w_h[0];
        let envelope_height = w_h[1];
        if (envelope_width > card_width) && (envelope_height > card_height) {
            envelopes.push((envelope_width, envelope_height, i));
        }
    }
    // println!("n = {}, w = {}, h = {}", n, card_width, card_height);
    let print_debug = (n == 483) && (card_width == 103232) && (card_height == 75323);
    print_maximum_chain(&mut envelopes, print_debug);
}


use std::collections::BTreeSet;
use std::io;
use std::io::Stdin;
use std::str::FromStr;

fn read_line(stdin : &Stdin, line : &mut String) {
    match stdin.read_line(line) {
        Ok(_) => return,
        Err(msg) => panic!("Could not read line! Message: {}.", msg),
    }
}

fn parse_t<T : FromStr>(s : &str) -> T {
    match s.trim().parse() {
        Ok(y) => y,
        Err(_) => panic!("Could not read from string!"),
    }
}

fn read_ts<T : FromStr>(stdin : &Stdin, ts : &mut Vec<T>) {
    let mut line = String::new();
    read_line(stdin, &mut line);
    let word_iter = line.split_whitespace();
    for word in word_iter {
        let x = parse_t(word);
        ts.push(x);
    }
}

fn print_maximum_chain(envelopes : &mut Vec<(usize, usize, usize)>) {
    // Sort envelopes in descending order of (w, h).
    envelopes.sort();
    envelopes.reverse();
    // Keep track of the chains.
    let mut covering_dag : Vec<(usize, usize, usize)> = vec![];
    let mut covering_dag_roots = BTreeSet::new();
    let mut node_id = 0;
    for env_id in 0 .. envelopes.len() {
        let (w, h, _) = envelopes[env_id];
        // if the covering dag is empty.
        if covering_dag_roots.is_empty() {
            // The newly inserted node is a root.
            covering_dag.push((env_id, usize::max_value(), 1));
            covering_dag_roots.insert(node_id);
            node_id = node_id + 1;
        } else {
            let mut covering_nodes = vec![];
            let mut found_cover = false;
            // Insert the envelope into the covering dag.
            for &root in covering_dag_roots.iter() {
                let mut cursor = root;
                loop {
                    if cursor == usize::max_value() {
                        break;
                    } else {
                        let (cursor_env_id, cursor_child_id, _) = covering_dag[cursor];
                        let (cursor_w, cursor_h, _) = envelopes[cursor_env_id];
                        // if the envelope is covered.
                        if (cursor_w > w) && (cursor_h > h) {
                            covering_nodes.push(cursor);
                            found_cover = true;
                            break;
                        } else {
                            cursor = cursor_child_id;
                        }
                    }
                }
            }
            // If nodes were found to cover the envelope.
            if found_cover {
                // Add root to the deepest node.
                let mut deepest_node = usize::max_value();
                let mut deepest_node_depth = 0;
                for cursor in covering_nodes {
                    let (_, _, cursor_depth) = covering_dag[cursor];
                    if cursor_depth > deepest_node_depth {
                        deepest_node_depth = cursor_depth;
                        deepest_node = cursor;
                    }
                }
                covering_dag_roots.insert(node_id);
                covering_dag.push((env_id, deepest_node, deepest_node_depth + 1));
                node_id = node_id + 1;
                covering_dag_roots.remove(&deepest_node);
            } else {
                // If no node was found to cover the envelope.
                // The envelope is a root of a new branch.
                covering_dag_roots.insert(node_id);
                covering_dag.push((env_id, usize::max_value(), 1));
                node_id = node_id + 1;
            }
        }
    }
    // Find the deepest root.
    let mut deepest_root = usize::max_value();
    let mut deepest_root_depth = 0;
    for &root in covering_dag_roots.iter() {
        let (_, _, root_depth) = covering_dag[root];
        if root_depth > deepest_root_depth {
            deepest_root_depth = root_depth;
            deepest_root = root;
        }
    }
    println!("{}", deepest_root_depth);
    let mut is_first = true;
    loop {
        if deepest_root == usize::max_value() {
            break;
        } else {
            let (env_id, child_id, _) = covering_dag[deepest_root];
            if is_first {
                is_first = false;
            } else {
                print!(" ");
            }
            let (_, _, i) = envelopes[env_id];
            print!("{}", i);
            deepest_root = child_id;
        }
    }
    println!();
}

fn main() {
    let stdin = io::stdin();
    let mut n_w_h = vec![];
    read_ts(&stdin, &mut n_w_h);
    let n = n_w_h[0];
    let card_width = n_w_h[1];
    let card_height = n_w_h[2];
    let mut envelopes : Vec<(usize, usize, usize)> = vec![];
    for i in 1 .. (n + 1) {
        let mut w_h = vec![];
        read_ts(&stdin, &mut w_h);
        let envelope_width = w_h[0];
        let envelope_height = w_h[1];
        if (envelope_width > card_width) && (envelope_height > card_height) {
            envelopes.push((envelope_width, envelope_height, i));
        }
    }
    print_maximum_chain(&mut envelopes);
}


use std::collections::BTreeSet;
use std::io;
use std::io::Stdin;
use std::str::FromStr;

fn read_line(stdin : &Stdin, line : &mut String) {
    match stdin.read_line(line) {
        Ok(_) => return,
        Err(msg) => panic!("Could not read line! Message: {}.", msg),
    }
}

fn parse_t<T : FromStr>(s : &str) -> T {
    match s.trim().parse() {
        Ok(y) => y,
        Err(_) => panic!("Could not read from string!"),
    }
}

fn read_ts<T : FromStr>(stdin : &Stdin, ts : &mut Vec<T>) {
    let mut line = String::new();
    read_line(stdin, &mut line);
    let word_iter = line.split_whitespace();
    for word in word_iter {
        let x = parse_t(word);
        ts.push(x);
    }
}

fn print_maximum_chain(envelopes : &mut Vec<(usize, usize, usize)>, print_debug : bool) {
    if print_debug {
        println!("Sorting envelopes! - {}", envelopes.len());
    }
    // Sort envelopes in descending order of (w, h).
    envelopes.sort();
    envelopes.reverse();
    // Keep track of the chains.
    let mut covering_dag : Vec<(usize, usize, usize)> = vec![];
    let mut covering_dag_roots = BTreeSet::new();
    let mut node_id = 0;
    let mut counter = 0;
    for env_id in 0 .. envelopes.len() {
        counter = counter + 1;
        let (w, h, _) = envelopes[env_id];
        // if the covering dag is empty.
        if covering_dag_roots.is_empty() {
            // The newly inserted node is a root.
            covering_dag.push((env_id, usize::max_value(), 1));
            covering_dag_roots.insert(node_id);
            node_id = node_id + 1;
        } else {
            let mut covering_nodes = vec![];
            let mut found_cover = false;
            // Insert the envelope into the covering dag.
            for &root in covering_dag_roots.iter() {
                let mut cursor = root;
                loop {
                    if cursor == usize::max_value() {
                        break;
                    } else {
                        let (cursor_env_id, cursor_child_id, _) = covering_dag[cursor];
                        let (cursor_w, cursor_h, _) = envelopes[cursor_env_id];
                        // if the envelope is covered.
                        if (cursor_w > w) && (cursor_h > h) {
                            covering_nodes.push(cursor);
                            found_cover = true;
                            break;
                        } else {
                            cursor = cursor_child_id;
                        }
                    }
                }
            }
            // If nodes were found to cover the envelope.
            if found_cover {
                // Add root to the deepest node.
                let mut deepest_node = usize::max_value();
                let mut deepest_node_depth = 0;
                for cursor in covering_nodes {
                    let (_, _, cursor_depth) = covering_dag[cursor];
                    if cursor_depth > deepest_node_depth {
                        deepest_node_depth = cursor_depth;
                        deepest_node = cursor;
                    }
                }
                covering_dag_roots.insert(node_id);
                covering_dag.push((env_id, deepest_node, deepest_node_depth + 1));
                node_id = node_id + 1;
            } else {
                // If no node was found to cover the envelope.
                // The envelope is a root of a new branch.
                covering_dag_roots.insert(node_id);
                covering_dag.push((env_id, usize::max_value(), 1));
                node_id = node_id + 1;
            }
        }
        if print_debug && (counter == 10) {
            println!("Processing envelopes! - {} - {}", covering_dag_roots.len(), covering_dag.len());
            counter = 0;
        }
    }

    if print_debug {
        println!("Processed envelopes! - {} - {}", covering_dag_roots.len(), covering_dag.len());
    }

    // println!("{:?}", envelopes);
    // println!("{:?}", covering_tree_roots);
    // println!("{:?}", covering_tree);

    // Find the deepest root.
    let mut deepest_root = usize::max_value();
    let mut deepest_root_depth = 0;
    for &root in covering_dag_roots.iter() {
        let (_, _, root_depth) = covering_dag[root];
        if root_depth > deepest_root_depth {
            deepest_root_depth = root_depth;
            deepest_root = root;
        }
    }
    println!("{}", deepest_root_depth);
    let mut is_first = true;
    loop {
        if deepest_root == usize::max_value() {
            break;
        } else {
            let (env_id, child_id, _) = covering_dag[deepest_root];
            if is_first {
                is_first = false;
            } else {
                print!(" ");
            }
            let (_, _, i) = envelopes[env_id];
            print!("{}", i);
            deepest_root = child_id;
        }
    }
    println!();
}

fn main() {
    let stdin = io::stdin();
    let mut n_w_h = vec![];
    read_ts(&stdin, &mut n_w_h);
    let n = n_w_h[0];
    let card_width = n_w_h[1];
    let card_height = n_w_h[2];
    let mut envelopes : Vec<(usize, usize, usize)> = vec![];
    for i in 1 .. (n + 1) {
        let mut w_h = vec![];
        read_ts(&stdin, &mut w_h);
        let envelope_width = w_h[0];
        let envelope_height = w_h[1];
        if (envelope_width > card_width) && (envelope_height > card_height) {
            envelopes.push((envelope_width, envelope_height, i));
        }
    }
    // println!("n = {}, w = {}, h = {}", n, card_width, card_height);
    // let print_debug = (n == 483) && (card_width == 103232) && (card_height == 75323);
    let print_debug = false;
    print_maximum_chain(&mut envelopes, print_debug);
}


use std::collections::BTreeSet;
use std::io;
use std::io::Stdin;
use std::str::FromStr;

fn read_line(stdin : &Stdin, line : &mut String) {
    match stdin.read_line(line) {
        Ok(_) => return,
        Err(msg) => panic!("Could not read line! Message: {}.", msg),
    }
}

fn parse_t<T : FromStr>(s : &str) -> T {
    match s.trim().parse() {
        Ok(y) => y,
        Err(_) => panic!("Could not read from string!"),
    }
}

fn read_ts<T : FromStr>(stdin : &Stdin, ts : &mut Vec<T>) {
    let mut line = String::new();
    read_line(stdin, &mut line);
    let word_iter = line.split_whitespace();
    for word in word_iter {
        let x = parse_t(word);
        ts.push(x);
    }
}

fn print_maximum_chain(envelopes : &mut Vec<(usize, usize, usize)>, print_debug : bool) {
    if print_debug {
        println!("Sorting envelopes! - {}", envelopes.len());
    }
    // Sort envelopes in descending order of (w, h).
    envelopes.sort();
    envelopes.reverse();
    // Keep track of the chains.
    let mut covering_dag : Vec<(usize, usize, usize)> = vec![];
    let mut covering_dag_roots = BTreeSet::new();
    let mut node_id = 0;
    for env_id in 0 .. envelopes.len() {
        let (w, h, _) = envelopes[env_id];
        // if the covering dag is empty.
        if covering_dag_roots.is_empty() {
            // The newly inserted node is a root.
            covering_dag.push((env_id, usize::max_value(), 1));
            covering_dag_roots.insert(node_id);
            node_id = node_id + 1;
        } else {
            let mut roots_to_add = BTreeSet::new();
            let mut roots_to_remove = BTreeSet::new();
            let mut found_cover = false;
            // Insert the envelope into the covering dag.
            for &root in covering_dag_roots.iter() {
                let mut cursor = root;
                loop {
                    if cursor == usize::max_value() {
                        break;
                    } else {
                        let (cursor_env_id, cursor_child_id, cursor_depth) = covering_dag[cursor];
                        let (cursor_w, cursor_h, _) = envelopes[cursor_env_id];
                        // if the envelope is covered.
                        if (cursor_w > w) && (cursor_h > h) {
                            covering_dag.push((env_id, cursor, cursor_depth + 1));
                            roots_to_add.insert(node_id);
                            node_id = node_id + 1;
                            roots_to_remove.insert(cursor);
                            found_cover = true;
                            break;
                        } else {
                            cursor = cursor_child_id;
                        }
                    }
                }
            }
            for root in roots_to_remove.iter() {
                covering_dag_roots.remove(root);
            }
            for &root in roots_to_add.iter() {
                covering_dag_roots.insert(root);
            }
            // If no root was found to cover the envelope.
            if found_cover {
                // Do nothing ...
            } else {
                // The envelope is a root of a new branch.
                covering_dag_roots.insert(node_id);
                covering_dag.push((env_id, usize::max_value(), 1));
                node_id = node_id + 1;
            }
        }
    }

    if print_debug {
        println!("Processed envelopes! - {} - {}", covering_dag_roots.len(), covering_dag.len());
    }

    // println!("{:?}", envelopes);
    // println!("{:?}", covering_tree_roots);
    // println!("{:?}", covering_tree);

    // Find the deepest root.
    let mut deepest_root = usize::max_value();
    let mut deepest_root_depth = 0;
    for &root in covering_dag_roots.iter() {
        let (_, _, root_depth) = covering_dag[root];
        if root_depth > deepest_root_depth {
            deepest_root_depth = root_depth;
            deepest_root = root;
        }
    }
    println!("{}", deepest_root_depth);
    let mut is_first = true;
    loop {
        if deepest_root == usize::max_value() {
            break;
        } else {
            let (env_id, child_id, _) = covering_dag[deepest_root];
            if is_first {
                is_first = false;
            } else {
                print!(" ");
            }
            let (_, _, i) = envelopes[env_id];
            print!("{}", i);
            deepest_root = child_id;
        }
    }
    println!();
}

fn main() {
    let stdin = io::stdin();
    let mut n_w_h = vec![];
    read_ts(&stdin, &mut n_w_h);
    let n = n_w_h[0];
    let card_width = n_w_h[1];
    let card_height = n_w_h[2];
    let mut envelopes : Vec<(usize, usize, usize)> = vec![];
    for i in 1 .. (n + 1) {
        let mut w_h = vec![];
        read_ts(&stdin, &mut w_h);
        let envelope_width = w_h[0];
        let envelope_height = w_h[1];
        if (envelope_width > card_width) && (envelope_height > card_height) {
            envelopes.push((envelope_width, envelope_height, i));
        }
    }
    // println!("n = {}, w = {}, h = {}", n, card_width, card_height);
    let print_debug = (n == 483) && (card_width == 103232) && (card_height == 75323);
    print_maximum_chain(&mut envelopes, print_debug);
}


use std::collections::BTreeSet;
use std::io;
use std::io::Stdin;
use std::str::FromStr;

fn read_line(stdin : &Stdin, line : &mut String) {
    match stdin.read_line(line) {
        Ok(_) => return,
        Err(msg) => panic!("Could not read line! Message: {}.", msg),
    }
}

fn parse_t<T : FromStr>(s : &str) -> T {
    match s.trim().parse() {
        Ok(y) => y,
        Err(_) => panic!("Could not read from string!"),
    }
}

fn read_ts<T : FromStr>(stdin : &Stdin, ts : &mut Vec<T>) {
    let mut line = String::new();
    read_line(stdin, &mut line);
    let word_iter = line.split_whitespace();
    for word in word_iter {
        let x = parse_t(word);
        ts.push(x);
    }
}

fn print_maximum_chain(envelopes : &mut Vec<(usize, usize, usize)>) {
    // Sort envelopes in descending order of (w, h).
    envelopes.sort();
    envelopes.reverse();
    // Keep track of the chains.
    let mut covering_dag : Vec<(usize, usize, usize)> = vec![];
    let mut covering_dag_roots = BTreeSet::new();
    let mut node_id = 0;
    for env_id in 0 .. envelopes.len() {
        let (w, h, _) = envelopes[env_id];
        // if the covering dag is empty.
        if covering_dag_roots.is_empty() {
            // The newly inserted node is a root.
            covering_dag.push((env_id, usize::max_value(), 1));
            covering_dag_roots.insert(node_id);
            node_id = node_id + 1;
        } else {
            let mut roots_to_add = BTreeSet::new();
            let mut roots_to_remove = BTreeSet::new();
            let mut found_cover = false;
            // Insert the envelope into the covering dag.
            for &root in covering_dag_roots.iter() {
                let mut cursor = root;
                loop {
                    if cursor == usize::max_value() {
                        break;
                    } else {
                        let (cursor_env_id, cursor_child_id, cursor_depth) = covering_dag[cursor];
                        let (cursor_w, cursor_h, _) = envelopes[cursor_env_id];
                        // if the envelope is covered.
                        if (cursor_w > w) && (cursor_h > h) {
                            covering_dag.push((env_id, cursor, cursor_depth + 1));
                            roots_to_add.insert(node_id);
                            node_id = node_id + 1;
                            roots_to_remove.insert(cursor);
                            found_cover = true;
                            break;
                        } else {
                            cursor = cursor_child_id;
                        }
                    }
                }
            }
            for root in roots_to_remove.iter() {
                covering_dag_roots.remove(root);
            }
            for &root in roots_to_add.iter() {
                covering_dag_roots.insert(root);
            }
            // If no root was found to cover the envelope.
            if found_cover {
                // Do nothing ...
            } else {
                // The envelope is a root of a new branch.
                covering_dag_roots.insert(node_id);
                covering_dag.push((env_id, usize::max_value(), 1));
                node_id = node_id + 1;
            }
        }
    }

    // println!("{:?}", envelopes);
    // println!("{:?}", covering_tree_roots);
    // println!("{:?}", covering_tree);

    // Find the deepest root.
    let mut deepest_root = usize::max_value();
    let mut deepest_root_depth = 0;
    for &root in covering_dag_roots.iter() {
        let (_, _, root_depth) = covering_dag[root];
        if root_depth > deepest_root_depth {
            deepest_root_depth = root_depth;
            deepest_root = root;
        }
    }
    println!("{}", deepest_root_depth);
    let mut is_first = true;
    loop {
        if deepest_root == usize::max_value() {
            break;
        } else {
            let (env_id, child_id, _) = covering_dag[deepest_root];
            if is_first {
                is_first = false;
            } else {
                print!(" ");
            }
            let (_, _, i) = envelopes[env_id];
            print!("{}", i);
            deepest_root = child_id;
        }
    }
    println!();
}

fn main() {
    let stdin = io::stdin();
    let mut n_w_h = vec![];
    read_ts(&stdin, &mut n_w_h);
    let n = n_w_h[0];
    let card_width = n_w_h[1];
    let card_height = n_w_h[2];
    let mut envelopes : Vec<(usize, usize, usize)> = vec![];
    for i in 1 .. (n + 1) {
        let mut w_h = vec![];
        read_ts(&stdin, &mut w_h);
        let envelope_width = w_h[0];
        let envelope_height = w_h[1];
        if (envelope_width > card_width) && (envelope_height > card_height) {
            envelopes.push((envelope_width, envelope_height, i));
        }
    }
    // println!("n = {}, w = {}, h = {}", n, card_width, card_height);
    print_maximum_chain(&mut envelopes);
}


use std::collections::BTreeSet;
use std::io;
use std::io::Stdin;
use std::str::FromStr;

fn read_line(stdin : &Stdin, line : &mut String) {
    match stdin.read_line(line) {
        Ok(_) => return,
        Err(msg) => panic!("Could not read line! Message: {}.", msg),
    }
}

fn parse_t<T : FromStr>(s : &str) -> T {
    match s.trim().parse() {
        Ok(y) => y,
        Err(_) => panic!("Could not read from string!"),
    }
}

fn read_ts<T : FromStr>(stdin : &Stdin, ts : &mut Vec<T>) {
    let mut line = String::new();
    read_line(stdin, &mut line);
    let word_iter = line.split_whitespace();
    for word in word_iter {
        let x = parse_t(word);
        ts.push(x);
    }
}

fn print_maximum_chain(envelopes : &mut Vec<(usize, usize, usize)>, print_debug : bool) {
    // Sort envelopes in descending order of (w, h).
    envelopes.sort();
    envelopes.reverse();
    // Keep track of the chains.
    let mut covering_dag : Vec<(usize, usize, usize)> = vec![];
    let mut covering_dag_roots = BTreeSet::new();
    let mut node_id = 0;
    for env_id in 0 .. envelopes.len() {
        let (w, h, _) = envelopes[env_id];
        // if the covering dag is empty.
        if covering_dag_roots.is_empty() {
            // The newly inserted node is a root.
            covering_dag.push((env_id, usize::max_value(), 1));
            covering_dag_roots.insert(node_id);
            node_id = node_id + 1;
        } else {
            let mut roots_to_add = BTreeSet::new();
            let mut roots_to_remove = BTreeSet::new();
            let mut found_cover = false;
            // Insert the envelope into the covering dag.
            for &root in covering_dag_roots.iter() {
                let mut cursor = root;
                loop {
                    if cursor == usize::max_value() {
                        break;
                    } else {
                        let (cursor_env_id, cursor_child_id, cursor_depth) = covering_dag[cursor];
                        let (cursor_w, cursor_h, _) = envelopes[cursor_env_id];
                        // if the envelope is covered.
                        if (cursor_w > w) && (cursor_h > h) {
                            covering_dag.push((env_id, cursor, cursor_depth + 1));
                            roots_to_add.insert(node_id);
                            node_id = node_id + 1;
                            roots_to_remove.insert(cursor);
                            found_cover = true;
                            break;
                        } else {
                            cursor = cursor_child_id;
                        }
                    }
                }
            }
            for root in roots_to_remove.iter() {
                covering_dag_roots.remove(root);
            }
            for &root in roots_to_add.iter() {
                covering_dag_roots.insert(root);
            }
            // If no root was found to cover the envelope.
            if found_cover {
                // Do nothing ...
            } else {
                // The envelope is a root of a new branch.
                covering_dag_roots.insert(node_id);
                covering_dag.push((env_id, usize::max_value(), 1));
                node_id = node_id + 1;
            }
        }
    }

    if print_debug {
        println!("Processed envelopes! - {} - {}", covering_dag_roots.len(), covering_dag.len());
    }

    // println!("{:?}", envelopes);
    // println!("{:?}", covering_tree_roots);
    // println!("{:?}", covering_tree);

    // Find the deepest root.
    let mut deepest_root = usize::max_value();
    let mut deepest_root_depth = 0;
    for &root in covering_dag_roots.iter() {
        let (_, _, root_depth) = covering_dag[root];
        if root_depth > deepest_root_depth {
            deepest_root_depth = root_depth;
            deepest_root = root;
        }
    }
    println!("{}", deepest_root_depth);
    let mut is_first = true;
    loop {
        if deepest_root == usize::max_value() {
            break;
        } else {
            let (env_id, child_id, _) = covering_dag[deepest_root];
            if is_first {
                is_first = false;
            } else {
                print!(" ");
            }
            let (_, _, i) = envelopes[env_id];
            print!("{}", i);
            deepest_root = child_id;
        }
    }
    println!();
}

fn main() {
    let stdin = io::stdin();
    let mut n_w_h = vec![];
    read_ts(&stdin, &mut n_w_h);
    let n = n_w_h[0];
    let card_width = n_w_h[1];
    let card_height = n_w_h[2];
    let mut envelopes : Vec<(usize, usize, usize)> = vec![];
    for i in 1 .. (n + 1) {
        let mut w_h = vec![];
        read_ts(&stdin, &mut w_h);
        let envelope_width = w_h[0];
        let envelope_height = w_h[1];
        if (envelope_width > card_width) && (envelope_height > card_height) {
            envelopes.push((envelope_width, envelope_height, i));
        }
    }
    // println!("n = {}, w = {}, h = {}", n, card_width, card_height);
    let print_debug = (n == 483) && (card_width == 103232) && (card_height == 75323);
    print_maximum_chain(&mut envelopes, print_debug);
}