import java.util.Arrays;
import java.util.Scanner;

public class JavaApplication1 {

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);

        int n = input.nextInt();
        String [] arr = new String [n];

        input.nextLine();
        for(int i =0; i<n; i++)
            arr[i] = input.nextLine();

        String dig= "" ,nLine="";
        StringBuilder l=new StringBuilder();
        for(int i=0 , j=n-1; i<n && j>=0; i++ , j--){
               dig+= arr[i].charAt(i) +""+ arr[i].charAt(j);
               l= new StringBuilder(arr[i]+"");
               try{
                    l= l.deleteCharAt(l.indexOf(arr[i].charAt(i)+""));
                    l= l.deleteCharAt(l.indexOf(arr[i].charAt(j)+""));
               } catch(Exception e){}
               nLine+=l;
        }

        char [] a = dig.toCharArray();
        Arrays.sort(a);

        boolean flag = false;
        if(!dig.equals(String.valueOf(a)))
            flag=true;

        if(!flag){

                String diffDig = nLine;
                flag = false;
                a = diffDig.toCharArray();
                Arrays.sort(a);

                if(!diffDig.equals(String.valueOf(a)) ||  diffDig.charAt(0) == dig.charAt(0) )
                     flag=true;

                if(!flag)
                    System.out.println("YES");
                else
                    System.out.println("NO");
            }
            else
                 System.out.println("NO");
        }

    }


import java.util.Scanner;

public class JavaApplication1 {

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);

        int n = input.nextInt();
        String [] arr = new String [n];

        input.nextLine();
        for(int i =0; i<n; i++)
            arr[i] = input.nextLine();

        String dig="";
        for(int i=0 , j=0; i<n && j< n; i++ , j++)
            dig+=arr[i].charAt(j);

        for(int i=0 , j=n-1; i<n && j>=0; i++ , j--)
            dig+=arr[i].charAt(j);

        char cTest = dig.charAt(0);
        boolean flag = false;
        for(int i=0 ; i<n ; i++)
             if(dig.charAt(i) != cTest)
                 flag =true;

        if(!flag){

            String diffDig ="";
            for(int i=0 ; i<n ; i++)
                for(int y=0 ; y<arr[i].length() ; y++)
                     if(arr[i].charAt(y) != dig.charAt(0))
                        diffDig+= arr[i].charAt(y);

            if(diffDig.length() != 0){
                cTest = diffDig.charAt(0);
                flag = false;
                for(int i=0 ; i<diffDig.length() ; i++)
                     if(diffDig.charAt(i) != cTest)
                         flag =true;

                if(!flag)
                    System.out.println("YES");
                else
                    System.out.println("NO");
            }
            else
                 System.out.println("NO");
        }
        else
             System.out.println("NO");

    }

}


import java.util.Arrays;
import java.util.Scanner;

public class JavaApplication1 {

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);

        int n = input.nextInt();
        String [] arr = new String [n];

        input.nextLine();
        for(int i =0; i<n; i++)
            arr[i] = input.nextLine();

        String dig= "" ,nLine="";
        StringBuilder l=new StringBuilder();
        for(int i=0 , j=n-1; i<n && j>=0; i++ , j--){
               dig+= arr[i].charAt(i) +""+ arr[i].charAt(j);
               l= new StringBuilder(arr[i]+"");
               try{
                    l= l.deleteCharAt(i);
                    if(i < j)
                        l= l.deleteCharAt(j-1);
                    else if(i != j)
                        l= l.deleteCharAt(j);
               } catch(Exception e){}
               nLine+=l;
        }

        char [] a = dig.toCharArray();
        Arrays.sort(a);

        boolean flag = false;
        if(!dig.equals(String.valueOf(a)))
            flag=true;

        if(!flag){

                String diffDig = nLine;
                flag = false;
                a = diffDig.toCharArray();
                Arrays.sort(a);

                if(!diffDig.equals(String.valueOf(a)) ||  diffDig.charAt(0) == dig.charAt(0) )
                     flag=true;

                if(!flag)
                    System.out.println("YES");
                else
                    System.out.println("NO");
            }
            else
                 System.out.println("NO");
        }

    }


import java.util.Arrays;
import java.util.Scanner;

public class JavaApplication1 {

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);

        int n = input.nextInt();
        String [] arr = new String [n];

        input.nextLine();
        for(int i =0; i<n; i++)
            arr[i] = input.nextLine();

        String dig= "" , line="" ,nLine="";
        for(int i=0 , j=n-1; i<n && j>=0; i++ , j--){
               dig+= arr[i].charAt(i) +""+ arr[i].charAt(j);
               line= arr[i]+"";
               line= line.replace(arr[i].charAt(i)+"", "")+"";
               line= line.replace(arr[i].charAt(j)+"", "")+"";
               nLine+=line;
        }

        char [] a = dig.toCharArray();
        Arrays.sort(a);

        boolean flag = false;
        if(!dig.equals(String.valueOf(a)))
            flag=true;

        if(!flag){

                String diffDig = nLine;

                flag = false;
                a = diffDig.toCharArray();
                Arrays.sort(a);

                if(!diffDig.equals(String.valueOf(a)))
                     flag=true;

                if(!flag)
                    System.out.println("YES");
                else
                    System.out.println("NO");
            }
            else
                 System.out.println("NO");
        }

    }


import java.util.Scanner;

public class JavaApplication1 {

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);

        int n = input.nextInt();
        String [] arr = new String [n];

        input.nextLine();
        for(int i =0; i<n; i++)
            arr[i] = input.nextLine();

        String dig="";
        for(int i=0 , j=n-1; i<n && j>=0; i++ , j--)
            dig+=arr[i].charAt(i) +""+ arr[i].charAt(j);

        char cTest = dig.charAt(0);
        boolean flag = false;
        for(int i=0 ; i<n ; i++)
             if(dig.charAt(i) != cTest){
                 flag =true;
                 break;
             }

        if(!flag){

            String diffDig ="";
            for(int i=0 ; i<n ; i++)
                for(int y=0 ; y<arr[i].length() ; y++)
                     if(arr[i].charAt(y) != dig.charAt(0))
                        diffDig+= arr[i].charAt(y);

            if(diffDig.length() != 0){
                cTest = diffDig.charAt(0);
                flag = false;
                for(int i=0 ; i<diffDig.length() ; i++)
                     if(diffDig.charAt(i) != cTest){
                         flag =true;
                         break;
                     }

                if(!flag)
                    System.out.println("YES");
                else
                    System.out.println("NO");
            }
            else
                 System.out.println("NO");
        }
        else
             System.out.println("NO");

    }

}


import java.util.Arrays;
import java.util.Scanner;

public class JavaApplication1 {

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);

        int n = input.nextInt();
        String [] arr = new String [n];

        input.nextLine();
        for(int i =0; i<n; i++)
            arr[i] = input.nextLine();

        String dig= "";
        for(int i=0 , j=n-1; i<n && j>=0; i++ , j--)
            dig+= arr[i].charAt(i) +""+ arr[i].charAt(j);

        char [] a = dig.toCharArray();
        Arrays.sort(a);

        boolean flag = false;
        if(!dig.equals(String.valueOf(a)))
            flag=true;

        if(!flag){

            String diffDig ="";
            for(int i=0 ; i<n ; i++)
                for(int y=0 ; y<arr[i].length() ; y++)
                     if(arr[i].charAt(y) != dig.charAt(0))
                        diffDig+= arr[i].charAt(y);

            if(diffDig.length() != 0){

                flag = false;

                a = diffDig.toCharArray();
                Arrays.sort(a);
                if(!diffDig.equals(String.valueOf(a)))
                     flag=true;

                if(!flag)
                    System.out.println("YES");
                else
                    System.out.println("NO");
            }
            else
                 System.out.println("NO");
        }
        else
             System.out.println("NO");

    }

}


import java.util.Scanner;

public class ValeraAndX {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        int n = in.nextInt();
        char grid [][] = new char[n][n];
        for (int i = 0; i < n; i++)
            grid [i] = in.next().toCharArray();
        char a = grid[0][0] , b = grid[0][1];
        boolean flag = a != b;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if(i+j == n-1 || i == j)
                    flag &= grid[i][j] == a;
                else
                    flag &= grid[i][j] == b;
            }

        }
        System.out.println(flag ? "YES" : "NO");
    }

}


import java.util.Scanner;

public class ValeraAndX {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        int n = in.nextInt();
        char grid [][] = new char[n][n];
        for (int i = 0; i < n; i++)
            grid [i] = in.next().toCharArray();
        boolean flag = true;

        for (int i = 0; i < n; i++) {
                if(grid[i][0] == grid[i][n-1] )
                    flag = true;
                else{
                    flag = false;
                break;
                }
        }
        System.out.println(flag ? "YES" : "NO");
    }

}


import java.util.Scanner;

public class ValeraAndX {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        int n = in.nextInt();
        char grid [][] = new char[n][n];
        for (int i = 0; i < n; i++)
            grid [i] = in.next().toCharArray();
        boolean flag = true;
        for (int i = 0; i < n; i++) {
                if(grid[i][0] == grid[i][n-1] && grid[0][0] != grid[0][1])
                    flag = true;
                else{
                    flag = false;
                break;
                }
        }
        System.out.println(flag ? "YES" : "NO");
    }

}


import java.util.Scanner;

public class ValeraAndX {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        int n = in.nextInt();
        char grid [][] = new char[n][n];
        for (int i = 0; i < n; i++)
            grid [i] = in.next().toCharArray();
        boolean flag = true;
        for (int i = 0; i < n; i++) {
                if(grid[i][0] == grid[i][n-1] && grid[i][0] != grid[i][1])
                    flag = true;
                else{
                    flag = false;
                break;
                }
        }
        System.out.println(flag ? "YES" : "NO");
    }

}


import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.Scanner;

public class ValeraAndX {

	public static int[] getArray(int size) {
		int[] array = new int[size];
		for (int i = 0; i < size; i++) {
			array[i] = sr.nextInt();
		}
		return array;
	}

	public static char[][] getMatrix(int sizeI, int sizeJ) {
		char[][] array = new char[sizeI][sizeJ];
		for (int i = 0; i < sizeI; i++) {
			for (int j = 0; j < sizeJ; j++) {
				array[i][j] = (char) sr.nextInt();
			}
		}
		return array;
	}

	static Scanner sr = new Scanner(System.in);

	public static void main(String[] args) {

		int size = sr.nextInt();
		sr.nextLine();
		StringBuilder diagonals = new StringBuilder();
		StringBuilder others = new StringBuilder();
		String matrix[] = new String[size];
		for (int i = 0; i < matrix.length; i++) {
			matrix[i] = sr.nextLine();
		}
		for (int i = 0; i < matrix.length; i++) {
			for (int j = 0; j < matrix.length; j++) {
				if (size == i + j + 1 || i == j) {
					diagonals.append(matrix[i].charAt(j));
				} else {
					others.append(matrix[i].charAt(j));
				}
			}
		}
		System.out.println((isSame(diagonals) && isSame(others)) ? "YES" : "No");
	}

	public static boolean isSame(StringBuilder input) {
		boolean res = true;
		for (int i = 1; i < input.length(); i++) {
			if (input.charAt(i) != input.charAt(i - 1)) {
				res = false;
				break;
			}
		}
		return res;
	}
}


import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.Scanner;

public class ValeraAndX {

	public static int[] getArray(int size) {
		int[] array = new int[size];
		for (int i = 0; i < size; i++) {
			array[i] = sr.nextInt();
		}
		return array;
	}

	public static char[][] getMatrix(int sizeI, int sizeJ) {
		char[][] array = new char[sizeI][sizeJ];
		for (int i = 0; i < sizeI; i++) {
			for (int j = 0; j < sizeJ; j++) {
				array[i][j] = (char) sr.nextInt();
			}
		}
		return array;
	}

	static Scanner sr = new Scanner(System.in);

	public static void main(String[] args) {

		int size = sr.nextInt();
		sr.nextLine();
		StringBuilder diagonals = new StringBuilder();
		StringBuilder others = new StringBuilder();
		String matrix[] = new String[size];
		for (int i = 0; i < matrix.length; i++) {
			matrix[i] = sr.nextLine();
		}
		for (int i = 0; i < matrix.length; i++) {
			for (int j = 0; j < matrix.length; j++) {
				if (size == i + j + 1 || i == j) {
					diagonals.append(matrix[i].charAt(j));
				} else {
					others.append(matrix[i].charAt(j));
				}
			}
		}
		System.out.println((isSame(diagonals) && isSame(others) &&
				diagonals.charAt(0) != others.charAt(0)) ? "YES" : "NO");
	}

	public static boolean isSame(StringBuilder input) {
		boolean res = true;
		for (int i = 1; i < input.length(); i++) {
			if (input.charAt(i) != input.charAt(i - 1)) {
				res = false;
				break;
			}
		}
		return res;
	}
}


import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.Scanner;

public class ValeraAndX {

	public static int[] getArray(int size) {
		int[] array = new int[size];
		for (int i = 0; i < size; i++) {
			array[i] = sr.nextInt();
		}
		return array;
	}

	public static char[][] getMatrix(int sizeI, int sizeJ) {
		char[][] array = new char[sizeI][sizeJ];
		for (int i = 0; i < sizeI; i++) {
			for (int j = 0; j < sizeJ; j++) {
				array[i][j] = (char) sr.nextInt();
			}
		}
		return array;
	}

	static Scanner sr = new Scanner(System.in);

	public static void main(String[] args) {

		int size = sr.nextInt();
		sr.nextLine();
		StringBuilder diagonals = new StringBuilder();
		StringBuilder others = new StringBuilder();
		String matrix[] = new String[size];
		for (int i = 0; i < matrix.length; i++) {
			matrix[i] = sr.nextLine();
		}
		for (int i = 0; i < matrix.length; i++) {
			for (int j = 0; j < matrix.length; j++) {
				if (size == i + j + 1 || i == j) {
					diagonals.append(matrix[i].charAt(j));
				} else {
					others.append(matrix[i].charAt(j));
				}
			}
		}
		System.out.println((isSame(diagonals) && isSame(others)) ? "YES" : "NO");
	}

	public static boolean isSame(StringBuilder input) {
		boolean res = true;
		for (int i = 1; i < input.length(); i++) {
			if (input.charAt(i) != input.charAt(i - 1)) {
				res = false;
				break;
			}
		}
		return res;
	}
}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const ll mod = 1000000007;
const int nn = 1000001;
int b[nn], a;

int main(int argc, char* argv[])
{
    int n,m;
    scanf("%d%d", &n ,&m);
    priority_queue<int> pq;
    for (int i = 0; i < n; ++i) scanf("%d", &a),  pq.push(a);
    for (int i = 0; i < m; ++i) scanf("%d", &b[i]), b[i] = (1 << b[i]);
    sort(b, b + m, greater<int>());
    int tp = pq.top(), d = 0;
    while (d < m && b[d] > tp) ++d;
    int c = d;
    if (d < m) {
        while (c < m) {
            if (pq.size() && pq.top() >= b[c]) {
                tp = pq.top();
                pq.pop();
                tp-= b[c++];
                if (tp) pq.push(tp);
            }
            else pq.push(b[d++]);
        }
    }

    int ret = c- d;
    printf("%d", ret);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const ll mod = 1000000007;
const int nn = 1000001;
int b[nn], a;

int main(int argc, char* argv[])
{
    int n,m;
    scanf("%d%d", &n ,&m);
    priority_queue<int> pq;
    for (int i = 0; i < n; ++i) scanf("%d", &a),  pq.push(a);
    for (int i = 0; i < m; ++i) scanf("%d", &b[i]), b[i] = (1 << b[i]);
    sort(b, b + m, greater<int>());
    int tp = pq.top(), d = 0;
    while (d < m && b[d] > tp) ++d;
    int c = d;
    if (d < m) {
        while (1) {
            if (c == m || pq.empty()) break;
            tp = pq.top();
            if (tp >= b[c]) {
                pq.pop();
                tp-= b[c++];
                if (tp) pq.push(tp);
            }
            else pq.push(b[d++]);
        }
    }

    int ret = c- d;
    printf("%d", ret);
    return 0;
}


/*
u33how
*/

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

const int maxn = 1000000+1 ;
int pw[31] ;
int n , m ;

int a[maxn] ;
int ms[maxn] ;

multiset<int> mymultiset ;

int main()
{
    //freopen("input.txt","r",stdin) ;
    //ios_base::sync_with_stdio(false) ;
    //cin.tie(0) ;

    pw[0] = 1 ;
    for( int i = 1 ; i <= 30 ; i++ ) pw[i] = pw[i-1]*2 ;

    //cin >> n >> m ;
    scanf("%d %d",&n,&m) ;
    for( int i = 0 ; i < n ; i++ )
    {
        //cin >> a[i] ;
        scanf("%d",a+i) ;
        //mymultiset.insert(a[i]) ;
    }
    sort(a,a+n) ;
    /*
    for( int i = 0 ; i < n ; i++ )
    {
        cout << a[i] << " " ;
    }
    cout << endl ;
    */
    int b = 0 ;
    for( int i = 0 ; i < m ; i++ )
    {
        //cin >> b ;
        scanf("%d",&b) ;
        ms[i] = pw[b] ;
    }

    sort(ms,ms+m) ;
    /*
    for( int j = 0 ; j < m ; j++ )
    {
        cout << ms[j] << " " ;
    }
    cout << endl ;
    */

    int ans = 0 ;
    int base = 0 ;
    for( int j = 0 ; j < m && base < n ;  )
    {
        int idx = lower_bound(a+base,a+n,ms[j]) - a ;// + base ;
        //cout << "[idx] = " << idx << endl ;
        if( idx < n )
        {
            while( j < m && a[idx] >= ms[j] )
            {
                //cout << a[idx] << "," << ms[j] << endl ;

                a[idx] -= ms[j] ;
                ans++ ;
                j++ ;
                //cout << "." << endl;
            }
            base = idx+1 ;
            continue ;
        }

        break ;

    }
    //cout << ans << endl ;
    printf("%d",ans) ;

    return 0 ;

}


/*
u33how
*/

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

const int maxn = 1000000 ;
int pw[31] ;
int n , m ;

int a[maxn] ;
int ms[maxn] ;

multiset<int> mymultiset ;

int main()
{
    //freopen("input.txt","r",stdin) ;
    ios_base::sync_with_stdio(false) ;
    cin.tie(0) ;

    pw[0] = 1 ;
    for( int i = 1 ; i <= 30 ; i++ ) pw[i] = pw[i-1]*2 ;

    cin >> n >> m ;
    for( int i = 0 ; i < n ; i++ )
    {
        cin >> a[i] ;
        mymultiset.insert(a[i]) ;
    }

    int b = 0 ;
    for( int i = 0 ; i < m ; i++ )
    {
        cin >> b ;
        ms[i] = pw[b] ;
    }

    sort(ms,ms+m) ;
    int ans = 0 ;
    for( int i = 0 ; i < m ; i++ )
    {
        auto itr = mymultiset.lower_bound(ms[i]) ;
        if( itr == mymultiset.end() ) break ;

        int x = *itr ;
        mymultiset.erase(itr) ;
        x -= ms[i] ;
        ans++ ;
        if(x>0) mymultiset.insert(x) ;
    }
    cout << ans << endl ;

    return 0 ;

}


/*
u33how
*/

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

int n , m ;
int x , j , b ;

int a[31] ;
int q[31] ;

int ans ;

int main()
{
    //freopen("input.txt","r",stdin) ;
    scanf("%d %d",&n,&m) ;
    for( int i = 0 ; i < n ; i++ )
    {
        scanf("%d",&x) ;
        j = 0 ;
        while(x)
        {
            if(x&1) a[j]++ ;
            x >>= 1 ;
            j++ ;
        }
    }
    ans = 0 ;
    for( int i = 0 ; i < m ; i++ )
    {
        scanf("%d",&b) ;
        q[b]++ ;
    }
    /*
    for( int i = 10 ; i >= 0 ; i-- )
    {
        printf("%d ",a[i]) ;
    }
    printf("\n") ;

    for( int i = 10 ; i >= 0 ; i-- )
    {
        printf("%d ",q[i]) ;
    }
    printf("\n") ;
    */

    for( int i = 0 ; i < 31 ; i++ )
    {
        while( q[i] )
        {
            //
            while( a[i] && q[i] )
            {
                a[i]-- ;
                q[i]-- ;

                ans++ ;
            }
            //if q[i] == 0  continue ;
            if( q[i] > 0 )
            {
                //try
                int jmax = -1 ;
                for( int i = 0 ; i < 31 ; i++ )
                    if( a[i] > 0 ) jmax = i ;

                if( jmax > i ) // pos
                {
                    a[jmax]-- ;
                    for( int j = jmax-1 ; j > i ; j-- )
                    {
                        a[j]++ ;
                    }
                    a[i] += 2 ;
                    //continue now
                }
                else break ; //  no gain for these q[i]>0 . left them as unused
            }
        }
    }

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

}


/*
u33how
*/

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

const int maxn = 1000000 ;
int pw[31] ;
int n , m ;

int a[maxn] ;
int ms[maxn] ;

multiset<int> mymultiset ;

int main()
{
    //freopen("input.txt","r",stdin) ;
    //ios_base::sync_with_stdio(false) ;
    //cin.tie(0) ;

    pw[0] = 1 ;
    for( int i = 1 ; i <= 30 ; i++ ) pw[i] = pw[i-1]*2 ;

    //cin >> n >> m ;
    scanf("%d %d",&n,&m) ;
    for( int i = 0 ; i < n ; i++ )
    {
        //cin >> a[i] ;
        scanf("%d",a+i) ;
        mymultiset.insert(a[i]) ;
    }

    int b = 0 ;
    for( int i = 0 ; i < m ; i++ )
    {
        //cin >> b ;
        scanf("%d",&b) ;
        ms[i] = pw[b] ;
    }

    sort(ms,ms+m) ;
    int ans = 0 ;
    for( int i = 0 ; i < m ; i++ )
    {
        auto itr = mymultiset.lower_bound(ms[i]) ;
        if( itr == mymultiset.end() ) break ;

        int x = *itr ;
        mymultiset.erase(itr) ;
        x -= ms[i] ;
        ans++ ;
        if(x>0) mymultiset.insert(x) ;
    }
    //cout << ans << endl ;
    printf("%d",ans) ;

    return 0 ;

}


/*
u33how
*/

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

int n , m ;
int x , j , b ;

int a[31] ;
int q[31] ;

int ans ;

int main()
{
    //freopen("input.txt","r",stdin) ;
    scanf("%d %d",&n,&m) ;
    for( int i = 0 ; i < n ; i++ )
    {
        scanf("%d",&x) ;
        j = 0 ;
        while(x)
        {
            if(x&1) a[j]++ ;
            x >>= 1 ;
            j++ ;
        }
    }
    ans = 0 ;
    for( int i = 0 ; i < m ; i++ )
    {
        scanf("%d",&b) ;
        q[b]++ ;
    }
    /*
    for( int i = 10 ; i >= 0 ; i-- )
    {
        printf("%d ",a[i]) ;
    }
    printf("\n") ;

    for( int i = 10 ; i >= 0 ; i-- )
    {
        printf("%d ",q[i]) ;
    }
    printf("\n") ;
    */

    for( int i = 0 ; i < 31 ; i++ )
    {
        while( q[i] )
        {
            //
            while( a[i] > 0 && q[i] > 0 )
            {
                a[i]-- ;
                q[i]-- ;

                ans++ ;
            }
            //if q[i] == 0  continue ;
            if( q[i] > 0 )
            {
                //try
                int jmax1 = -1 ;
                for( int idx = 31 ; idx >= 0  ; idx-- )
                    if( a[idx] > 0 && a[idx] > q[idx] ) jmax1 = idx ;

                int jmax2 = -1 ;
                for( int idx = 31 ; idx >= 0  ; idx-- )
                    if( a[idx] > 0 && a[idx] >= q[idx] ) jmax2 = idx ;

                if( jmax1 > i ) // pos
                {
                    a[jmax1]-- ;
                    for( int j = jmax1-1 ; j > i ; j-- )
                    {
                        a[j]++ ;
                    }
                    a[i] += 2 ;
                    //continue now
                }
                else if( jmax2 > i )
                {
                    a[jmax2]-- ;
                    for( int j = jmax2-1 ; j > i ; j-- )
                    {
                        a[j]++ ;
                    }
                    a[i] += 2 ;

                }
                else break ; //  no gain for these q[i]>0 . left them as unused
            }
        }
    }

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

}


/*
u33how
*/

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

int n , m ;
int x , j , b ;

int a[31] ;
int q[31] ;

int ans ;

int main()
{
    //freopen("input.txt","r",stdin) ;
    scanf("%d %d",&n,&m) ;
    for( int i = 0 ; i < n ; i++ )
    {
        scanf("%d",&x) ;
        j = 0 ;
        while(x)
        {
            if(x&1) a[j]++ ;
            x >>= 1 ;
            j++ ;
        }
    }
    ans = 0 ;
    for( int i = 0 ; i < m ; i++ )
    {
        scanf("%d",&b) ;
        q[b]++ ;
    }

    /*
    for( int i = 10 ; i >= 0 ; i-- )
    {
        printf("%d ",a[i]) ;
    }
    printf("\n") ;

    for( int i = 10 ; i >= 0 ; i-- )
    {
        printf("%d ",q[i]) ;
    }
    printf("\n") ;
    */

    for( int i = 0 ; i < 31 ; i++ )
    {
        while( q[i] )
        {
            //
            while( a[i] > 0 && q[i] > 0 )
            {
                a[i]-- ;
                q[i]-- ;

                ans++ ;
            }
            //if q[i] == 0  continue ;
            if( q[i] > 0 )
            {
                //try
                int jmax1 = -1 ;
                for( int idx = 0 ; idx < 31  ; idx++ )
                    if( a[idx] > 0 && a[idx] > q[idx] ) jmax1 = idx ;

                int jmax2 = -1 ;
                for( int idx = 0 ; idx < 31  ; idx++ )
                    if( a[idx] > 0 && a[idx] >= q[idx] ) jmax2 = idx ;

                int jmax3 = -1 ;
                for( int idx = 0 ; idx < 31  ; idx++ )
                    if( a[idx] > 0 ) jmax3 = idx ;

                if( jmax1 > i ) // pos
                {
                    a[jmax1]-- ;
                    for( int j = jmax1-1 ; j > i ; j-- )
                    {
                        a[j]++ ;
                    }
                    a[i] += 2 ;
                    //continue now
                }
                else if( jmax2 > i )
                {
                    a[jmax2]-- ;
                    for( int j = jmax2-1 ; j > i ; j-- )
                    {
                        a[j]++ ;
                    }
                    a[i] += 2 ;

                }
                else if( jmax3 > i )
                {
                    a[jmax3]-- ;
                    for( int j = jmax3-1 ; j > i ; j-- )
                    {
                        a[j]++ ;
                    }
                    a[i] += 2 ;

                }
                else break ; //  no gain for these q[i]>0 . left them as unused
            }
        }
    }

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

}


/*
u33how
*/

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

int n , m ;
int x , j , b ;

int a[31] ;
int q[31] ;

int ans ;

int main()
{
    //freopen("input.txt","r",stdin) ;
    scanf("%d %d",&n,&m) ;
    for( int i = 0 ; i < n ; i++ )
    {
        scanf("%d",&x) ;
        j = 0 ;
        while(x)
        {
            if(x&1) a[j]++ ;
            x >>= 1 ;
            j++ ;
        }
    }
    ans = 0 ;
    for( int i = 0 ; i < m ; i++ )
    {
        scanf("%d",&b) ;
        q[b]++ ;
    }

    /*
    for( int i = 10 ; i >= 0 ; i-- )
    {
        printf("%d ",a[i]) ;
    }
    printf("\n") ;

    for( int i = 10 ; i >= 0 ; i-- )
    {
        printf("%d ",q[i]) ;
    }
    printf("\n") ;
    */

    for( int i = 0 ; i < 31 ; i++ )
    {
        while( q[i] )
        {
            //
            while( a[i] > 0 && q[i] > 0 )
            {
                a[i]-- ;
                q[i]-- ;

                ans++ ;
            }
            //if q[i] == 0  continue ;
            if( q[i] > 0 )
            {
                //try
                int jmax1 = -1 ;
                for( int idx = 0 ; idx < 31  ; idx++ )
                    if( a[idx] > 0 && a[idx] > q[idx] ) jmax1 = idx ;

                int jmax2 = -1 ;
                for( int idx = 0 ; idx < 31  ; idx++ )
                    if( a[idx] > 0 && a[idx] >= q[idx] ) jmax2 = idx ;

                if( jmax1 > i ) // pos
                {
                    a[jmax1]-- ;
                    for( int j = jmax1-1 ; j > i ; j-- )
                    {
                        a[j]++ ;
                    }
                    a[i] += 2 ;
                    //continue now
                }
                else if( jmax2 > i )
                {
                    a[jmax2]-- ;
                    for( int j = jmax2-1 ; j > i ; j-- )
                    {
                        a[j]++ ;
                    }
                    a[i] += 2 ;

                }
                else break ; //  no gain for these q[i]>0 . left them as unused
            }
        }
    }

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

}


/*
u33how
*/

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

int n , m ;
int x , j , b ;

int a[31] ;
int q[31] ;

int ans ;

int main()
{
    //freopen("input.txt","r",stdin) ;
    scanf("%d %d",&n,&m) ;
    for( int i = 0 ; i < n ; i++ )
    {
        scanf("%d",&x) ;
        j = 0 ;
        while(x)
        {
            if(x&1) a[j]++ ;
            x >>= 1 ;
            j++ ;
        }
    }
    ans = 0 ;
    for( int i = 0 ; i < m ; i++ )
    {
        scanf("%d",&b) ;
        q[b]++ ;
    }

    for( int i = 10 ; i >= 0 ; i-- )
    {
        printf("%d ",a[i]) ;
    }
    printf("\n") ;

    for( int i = 10 ; i >= 0 ; i-- )
    {
        printf("%d ",q[i]) ;
    }
    printf("\n") ;

    for( int i = 0 ; i < 31 ; i++ )
    {
        while( q[i] )
        {
            //
            while( a[i] > 0 && q[i] > 0 )
            {
                a[i]-- ;
                q[i]-- ;

                ans++ ;
            }
            //if q[i] == 0  continue ;
            if( q[i] > 0 )
            {
                //try
                int jmax1 = -1 ;
                for( int idx = 0 ; idx < 31  ; idx++ )
                    if( a[idx] > 0 && a[idx] > q[idx] ) jmax1 = idx ;

                int jmax2 = -1 ;
                for( int idx = 0 ; idx < 31  ; idx++ )
                    if( a[idx] > 0 && a[idx] >= q[idx] ) jmax2 = idx ;

                if( jmax1 > i ) // pos
                {
                    a[jmax1]-- ;
                    for( int j = jmax1-1 ; j > i ; j-- )
                    {
                        a[j]++ ;
                    }
                    a[i] += 2 ;
                    //continue now
                }
                else if( jmax2 > i )
                {
                    a[jmax2]-- ;
                    for( int j = jmax2-1 ; j > i ; j-- )
                    {
                        a[j]++ ;
                    }
                    a[i] += 2 ;

                }
                else break ; //  no gain for these q[i]>0 . left them as unused
            }
        }
    }

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

}


#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 3;

int n, m, b[N], x[31], a[N];
multiset<int> ms;

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 0; i < n; ++i) {
		scanf("%d", &a[i]);
		ms.insert(a[i]);
	}
	x[0] = 1;
	for (int i = 1; i <= 30; ++i) x[i] = x[i - 1] << 1;
	for (int i = 0; i < m; ++i) {
		scanf("%d", &b[i]);
		b[i] = x[b[i]];
	}
	int ans = 0;
	sort(b, b + m);
	for (int i = 0; i < m; ++i) {
		multiset<int>::iterator it = ms.lower_bound(b[i]);
		if (it == ms.end()) continue;
		++ans;
		int x = *it - b[i];
		ms.erase(it);
		ms.insert(x);

	}
	printf("%d", ans);
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 3;

int n, m, b[N], x[31], a[N];
multiset<int> ms;

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(NULL); cout.tie(NULL);
	cin >> n >> m;
	for (int i = 0; i < n; ++i) {
		cin >> a[i];
		ms.insert(a[i]);
	}
	x[0] = 1;
	for (int i = 1; i <= 30; ++i) x[i] = x[i - 1] << 1;
	for (int i = 0; i < m; ++i) {
		cin >> b[i];
		b[i] = x[b[i]];
	}
	int ans = 0;
	sort(b, b + m);
	for (int i = 0; i < m; ++i) {
		multiset<int>::iterator it = ms.lower_bound(b[i]);
		if (it == ms.end()) continue;
		++ans;
		int x = *it - b[i];
		ms.erase(it);
		ms.insert(x);

	}
	cout << ans;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 3;

int n, m, b[N], a[33], ans = 0;

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 0; i < n; ++i) {
		int x; scanf("%d", &x);
		int cnt = 0;
		while (x) {
			a[cnt] += (x & 1);
			x >>= 1;
			++cnt;
		}
	}

	for (int i = 0; i < m; ++i) scanf("%d", &b[i]);
	sort(b, b + m);
	for (int i = 0; i < m; ++i) {
		for (int j = b[i]; j <= 32; ++j) {
			if (a[j] > 0) {
				if (j == b[i]) a[j]--;
				else {
					a[j]--;
					for (int k = 0; k < j; ++k) ++a[k];
				}
				++ans;
				break;
			}
		}
	}
	printf("%d", ans);
	return 0;
}


#include <cstdio>
#include <algorithm>
using namespace std;

inline void read (int& s) {
	s = 0;
	static char c = getchar ();
	while (c < '0' || c > '9') c = getchar ();
	while (c >= '0' && c <= '9') s = (s << 3) + (s << 1) + (c ^ 48), c = getchar ();
	return ;
}

const int N = 1000003;
int n, m, a[N], b[N];

int main () {
	read (n), read (m);
	register int i, j; for (i = 1; i <= n; ++i) read (a[i]);
	sort (a + 1, a + n + 1);
	for (i = 1; i <= m; ++i) read (b[i]), b[i] = 1 << b[i];
	sort (b + 1, b + m + 1);
	j = 1;
	for (i = 1; i <= m; ++i) {
		while (j <= n && a[j] < b[i]) ++j;
		if (j > n) break;
		a[j] -= b[i];
	}
	printf ("%d\n", i - 1);
	return 0;
}


#include <cstdio>
#include <algorithm>
using namespace std;

inline void read (int& s) {
	s = 0;
	static char c = getchar ();
	while (c < '0' || c > '9') c = getchar ();
	while (c >= '0' && c <= '9') s = (s << 3) + (s << 1) + (c ^ 48), c = getchar ();
	return ;
}

const int N = 1000003;
int n, m, a[31], b[31], ans;

int main () {
	read (n), read (m);
	int i, x;
	for (i = 1; i <= n; ++i) {
		read (x);
		int now = 0;
		while (x) {
			if (x & 1) ++a[now];
			++now, x >>= 1;
		}
	}
	for (i = 1; i <= m; ++i) {
		read (x);
		++b[x];
	}
	for (i = 0; i < 31; ++i) {
		while (a[i] < b[i]) {
			int f = 1;
			for (register int j = i + 1; j < 31; ++j) {
				if (!a[j]) continue;
				for (register int k = i + 1; k < j; ++k) ++a[k];
				--a[j], a[i] += 2;
				f = 0; break;
			}
			if (f) break;
		}
		ans += min (a[i], b[i]);
	}
	printf ("%d\n", ans);
	return 0;
}


#include <cstdio>
#include <algorithm>
using namespace std;

inline void read (int& s) {
	s = 0;
	static char c = getchar ();
	while (c < '0' || c > '9') c = getchar ();
	while (c >= '0' && c <= '9') s = (s << 3) + (s << 1) + (c ^ 48), c = getchar ();
	return ;
}

const int N = 1000003;
int n, m, a[31], b[31], ans;

int main () {
	read (n), read (m);
	int i, x;
	for (i = 1; i <= n; ++i) {
		read (x);
		int now = 0;
		while (x) {
			if (x & 1) ++a[now];
			++now, x >>= 1;
		}
	}
	for (i = 1; i <= m; ++i) {
		read (x);
		++b[x];
	}
	for (i = 0; i < 31; ++i) {
		while (a[i] < b[i]) {
			int f = 1;
			for (register int j = i + 1; j < 31; ++j) {
				if (!a[i]) continue;
				for (register int k = i + 1; k < j; ++k) ++a[k];
				--a[j], a[i] += 2;
				f = 0; break;
			}
			if (f) break;
		}
		ans += min (a[i], b[i]);
	}
	printf ("%d\n", ans);
	return 0;
}


#include <cstdio>
#include <algorithm>
using namespace std;

inline void read (int& s) {
	s = 0;
	static char c = getchar ();
	while (c < '0' || c > '9') c = getchar ();
	while (c >= '0' && c <= '9') s = (s << 3) + (s << 1) + (c ^ 48), c = getchar ();
	return ;
}

const int N = 1000003;
int n, m, a[31], b[31], ans;

int main () {
	read (n), read (m);
	int i, x;
	for (i = 1; i <= n; ++i) {
		read (x);
		int now = 0;
		while (x) {
			if (x & 1) ++a[now];
			++now, x >>= 1;
		}
	}
	for (i = 1; i <= m; ++i) {
		read (x);
		++b[x];
	}
	for (i = 0; i < 31; ++i) {
		while (a[i] < b[i]) {
			int f = 1;
			for (register int j = i + 1; j < 31; ++j) {
				if (!a[i]) continue;
				for (register int k = i + 1; k < j; ++k) ++a[i];
				--a[j], a[i] += 2;
				f = 0; break;
			}
			if (f) break;
		}
		ans += min (a[i], b[i]);
	}
	printf ("%d\n", ans);
	return 0;
}


#include <iostream>
#include <cstdio>
#include<list>
#include<iomanip>
#include<cmath>
#include<queue>
#include <functional>
#include<stdio.h>
#include<assert.h>
#include<stack>
#include<sstream>
#include <cstdlib>
#include<map>
#include<algorithm>
#include<iostream>
#include<set>
#include<utility>
#include<memory.h>
#include<string>
#include<vector>
#include<numeric>
using namespace std;
#define ll  long long
#define pb push_back
#define sz(v)               ((int)((v).size()))
#define all(x)          (x).begin(),(x).end()
#define REP(i, v)       for(int i=0;i<sz(v);i++)
typedef pair<int,int> pii;
#define ios std::ios_base::sync_with_stdio(false);
using namespace std;
const int maxn = 1000*1000 + 5;
int cap[31];
int b[maxn];
int n,m;
int tmp[31];
int cap_copy[31];
bool can(int ind) {
	memset(tmp,0,sizeof(tmp));
	for(int j = ind ; j >= 0; --j) tmp[b[j]]++;
	for(int i = 0 ; i < 31; ++i) cap_copy[i] = cap[i];
	for(int k = 30 ; k >= 0 ; --k) {
		if(cap_copy[k] < tmp[k])
			return 0;
		cap_copy[k] -= tmp[k];
		if(k > 0)
		cap_copy[k - 1] += 2 * cap_copy[k];
	}
	return 1;
}
int main() {

	scanf("%d %d",&n,&m);
	for(int i = 0 ; i < n ; ++i) {
		int x = 0;
		scanf("%d",&x);
		for(int j = 30 ; j >= 0 ; --j) {
			if(x & (1 << j)) cap[j]++;
		}
	}
	for(int i = 0 ; i < m ; ++i) {
		int x;
		scanf("%d",&x);
		b[i] = x;
	}
	sort(b,b + m);
	int lo = 0,hi = m - 1;
	int ans = -1;
	while(lo <= hi) {
		int mid = lo + (hi - lo) / 2;
		if(can(mid))
			ans = mid, lo = mid + 1;
		else hi = mid - 1;
	}
	ans++;
	cout << ans << "\n";

}


#include <iostream>
#include <cstdio>
#include<list>
#include<iomanip>
#include<cmath>
#include<queue>
#include <functional>
#include<stdio.h>
#include<assert.h>
#include<stack>
#include<sstream>
#include <cstdlib>
#include<map>
#include<algorithm>
#include<iostream>
#include<set>
#include<utility>
#include<memory.h>
#include<string>
#include<vector>
#include<numeric>
using namespace std;
#define ll  long long
#define pb push_back
#define sz(v)               ((int)((v).size()))
#define all(x)          (x).begin(),(x).end()
#define REP(i, v)       for(int i=0;i<sz(v);i++)
typedef pair<int,int> pii;
#define ios std::ios_base::sync_with_stdio(false);
using namespace std;

const int maxn = 1000005;
int cap[maxn];
int b[maxn];
int n,m;
int main() {
	scanf("%d %d",&n,&m);
	for(int i = 0 ; i < n ; ++i)
		scanf("%d",&cap[i]);
	for(int i = 0 ; i < m ; ++i) {
		int x;
		scanf("%d",&x);
		int res = 1;
		while(x--) res <<= 1;
		b[i] = res;
	}
	sort(cap, cap + n);
	sort(b, b + m);
	int ptr = 0;
	int ans = 0;
	for(int i = 0 ; i < m ; ++i) {
		while(ptr < n && cap[ptr] < b[i]) ptr++;
		if(ptr == n)
			break;
		cap[ptr] -= b[i];
		ans++;
	}
	printf("%d\n",ans);
}


#include <iostream>
#include <cstdio>
#include<list>
#include<iomanip>
#include<cmath>
#include<queue>
#include <functional>
#include<stdio.h>
#include<assert.h>
#include<stack>
#include<sstream>
#include <cstdlib>
#include<map>
#include<algorithm>
#include<iostream>
#include<set>
#include<utility>
#include<memory.h>
#include<string>
#include<vector>
#include<numeric>
using namespace std;
#define ll  long long
#define pb push_back
#define sz(v)               ((int)((v).size()))
#define all(x)          (x).begin(),(x).end()
#define REP(i, v)       for(int i=0;i<sz(v);i++)
typedef pair<int,int> pii;
#define ios std::ios_base::sync_with_stdio(false);
using namespace std;
const int maxn = 1000*1000 + 5;
int cap[31];
int b[maxn];
int n,m;
int tmp[31];
ll cap_copy[31];
bool can(int ind) {
	memset(tmp,0,sizeof(tmp));
	for(int j = ind ; j >= 0; --j) tmp[b[j]]++;
	for(int i = 0 ; i < 31; ++i) cap_copy[i] = cap[i];
	for(int k = 30 ; k >= 0 ; --k) {
		if(cap_copy[k] < tmp[k])
			return 0;
		cap_copy[k] -= tmp[k];
		if(k > 0)
		cap_copy[k - 1] += 2LL * cap_copy[k];
	}
	return 1;
}
int main() {

	scanf("%d %d",&n,&m);
	for(int i = 0 ; i < n ; ++i) {
		int x = 0;
		scanf("%d",&x);
		for(int j = 30 ; j >= 0 ; --j) {
			if(x & (1 << j)) cap[j]++;
		}
	}
	for(int i = 0 ; i < m ; ++i) {
		int x;
		scanf("%d",&x);
		b[i] = x;
	}
	sort(b,b + m);
	int lo = 0,hi = m - 1;
	int ans = -1;
	while(lo <= hi) {
		int mid = lo + (hi - lo) / 2;
		if(can(mid))
			ans = mid, lo = mid + 1;
		else hi = mid - 1;
	}
	ans++;
	cout << ans << "\n";

}


#include<bits/stdc++.h>
using namespace std;
int a[40],b[40];
int main()
{
	int n,m,x,sum=0;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&x);
		int k=0;
		while(x)
		{
			a[k++]+=x&1;
			x/=2;
		}
	}
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&x);
		b[x]++;
	}
	while(1)
	{
		int i=0;
		while(i<32&&!b[i])
			i++;
		if(i==32)
			break;
		b[i]--;
		while(i<32&&!a[i])
		{
			a[i]++;
			i++;
		}
		if(i==32)
			break;
		a[i]--;
		sum++;
	}
	printf("%d\n",sum);
	return 0;
}


// In the name of God

#include <bits/stdc++.h>

#define For(i,x,y) for(__typeof(y)i=(x)-((x)>(y));i!=(y)-((x)>(y));i+=1-2*((x)>(y)))
#define _ ios::sync_with_stdio(0);cin.tie(0);
#define sz(x) (((int)x.size()))
#define rep(i,n) For(i,0,n)
#define mp make_pair
#define ss second
#define ff first

const int Maxn = 1e6 + 7;
const int inf = 1e9 + 7;

typedef long double dd;
typedef long long ll;
using namespace std;

int b[Maxn], m, n, x, a[35];

int main() {
    cin >> n >> m;
    rep(i,n) {
        int x, j = 0; scanf("%d", &x);
        while(x) {
             if (x & 1)
                a[j]++;
            j++ ,x /= 2;
        }
    }
    rep(i,m) scanf("%d", &b[i]);
    sort(b, b + m);
    for (int i = 0; i < m; i++) {
        x = b[i];
        while (x < 33 && !a[x])
            a[x++] = 1;
        if (x == 33) {
            printf("%d",i);
            return 0;
        }
        a[x]--;
    }
    printf("%d", m);
}

/*int main() { _
    int n, m;
    cin >> n >> m;
    rep(i, n) scanf("%d", &a[i]);
    rep(i, m) scanf("%d", &b[i]);
    sort(a, a+n);
    sort(b, b+m);

    int s = 0, e = m+1;
    while ( (e - s) > 1) {
        int mid = (s+e)/2;
        int f[Maxn];
        rep(i, n) f[i] = a[i];
        int i = 0, flag = true;
        for(int j = 0; j < mid; j++){
            while ( f[i] < (1<<b[j]) && i < n)
                i++;
            if (i == n)
                flag = false;
            f[i] -= (1<<b[j]);
        }
        if (flag)
            s = mid;
        else
            e = mid;
        //cerr << mid << ' ' << flag << endl;
    }
    cout << s << endl;
}*/


// In the name of God

#include <bits/stdc++.h>

#define For(i,x,y) for(__typeof(y)i=(x)-((x)>(y));i!=(y)-((x)>(y));i+=1-2*((x)>(y)))
#define _ ios::sync_with_stdio(0);cin.tie(0);
#define sz(x) (((int)x.size()))
#define rep(i,n) For(i,0,n)
#define mp make_pair
#define ss second
#define ff first

const int Maxn = 1e6 + 7;
const int inf = 1e9 + 7;

typedef long double dd;
typedef long long ll;
using namespace std;

int a[Maxn], b[Maxn];

int main() {
    int n, m;
    cin >> n >> m;
    rep(i, n) scanf("%d", &a[i]);
    rep(i, m) scanf("%d", &b[i]);
    sort(a, a+n);
    sort(b, b+m);

    int s = 0, e = m+1;
    while ( (e - s) > 1) {
        int mid = (s+e)/2;
        int f[Maxn];
        rep(i, n) f[i] = a[i];
        int i = 0, flag = true;
        for(int j = 0; j < mid; j++){
            while ( f[i] < (1<<b[j]) && i < n)
                i++;
            if (i == n)
                flag = false;
            f[i] -= (1<<b[j]);
        }
        if (flag)
            s = mid;
        else
            e = mid;
        //cerr << mid << ' ' << flag << endl;
    }
    cout << s << endl;
}


// In the name of God

#include <bits/stdc++.h>

#define For(i,x,y) for(__typeof(y)i=(x)-((x)>(y));i!=(y)-((x)>(y));i+=1-2*((x)>(y)))
#define _ ios::sync_with_stdio(0);cin.tie(0);
#define sz(x) (((int)x.size()))
#define rep(i,n) For(i,0,n)
#define mp make_pair
#define ss second
#define ff first

const int Maxn = 1e6 + 7;
const int inf = 1e9 + 7;

typedef long double dd;
typedef long long ll;
using namespace std;

int a[Maxn], b[Maxn];

int main() { _
    int n, m;
    cin >> n >> m;
    rep(i, n) cin >> a[i];
    rep(i, m) cin >> b[i];
    sort(a, a+n);
    sort(b, b+m);

    int s = 0, e = m+1;
    while ( (e - s) > 1) {
        int mid = (s+e)/2;
        int f[Maxn];
        rep(i, n) f[i] = a[i];
        int i = 0, flag = true;
        for(int j = 0; j < mid; j++){
            while ( f[i] < (1<<b[j]) && i < n)
                i++;
            if (i == n)
                flag = false;
            f[i] -= (1<<b[j]);
        }
        if (flag)
            s = mid;
        else
            e = mid;
        //cerr << mid << ' ' << flag << endl;
    }
    cout << s << endl;
}


// In the name of God

#include <bits/stdc++.h>

#define For(i,x,y) for(__typeof(y)i=(x)-((x)>(y));i!=(y)-((x)>(y));i+=1-2*((x)>(y)))
#define _ ios::sync_with_stdio(0);cin.tie(0);
#define sz(x) (((int)x.size()))
#define rep(i,n) For(i,0,n)
#define mp make_pair
#define ss second
#define ff first

const int Maxn = 1e6 + 7;
const int inf = 1e9 + 7;

typedef long double dd;
typedef long long ll;
using namespace std;

int b[Maxn], m, n, x, a[35];

int main() {
    cin >> n >> m;
    rep(i,n) {
        int x, j = 0; scanf("%d", &x);
        while(x) {
             if (x & 1)
                a[j]++;
            j++ ,x /= 2;
        }
    }
    rep(i,m) cin >> b[i];
    sort(b, b + m);
    for (int i = 0; i < m; i++) {
        x = b[i];
        while (x < 33 && !a[x])
            a[x++] = 1;
        if (x == 33) {
            printf("%d",i);
            return 0;
        }
        a[x]--;
    }
    printf("%d", m);
}

/*int main() { _
    int n, m;
    cin >> n >> m;
    rep(i, n) scanf("%d", &a[i]);
    rep(i, m) scanf("%d", &b[i]);
    sort(a, a+n);
    sort(b, b+m);

    int s = 0, e = m+1;
    while ( (e - s) > 1) {
        int mid = (s+e)/2;
        int f[Maxn];
        rep(i, n) f[i] = a[i];
        int i = 0, flag = true;
        for(int j = 0; j < mid; j++){
            while ( f[i] < (1<<b[j]) && i < n)
                i++;
            if (i == n)
                flag = false;
            f[i] -= (1<<b[j]);
        }
        if (flag)
            s = mid;
        else
            e = mid;
        //cerr << mid << ' ' << flag << endl;
    }
    cout << s << endl;
}*/


#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<functional>

using namespace std;

const int MAXN = 1e6 + 10;
const int LOG = 30 + 1;

int n, m, vec[MAXN], cnt[LOG + 2];
priority_queue<int, vector<int>, greater<int>> st;

int main(){
	scanf("%d %d", &n, &m);
	while (n--){
		int x;	scanf("%d", &x);
		for (int i = LOG - 1; i >= 0; i--)
			if ((x >> i) & 1)	cnt[i]++;
	}
	for (int i = 0; i < m; i++)
		scanf("%d", &vec[i]);
	sort(vec, vec + m);
	int ans = 0;
	for (int i = 0; i < m; i++){
		for (int j = vec[i]; j < LOG; j++)
			if (cnt[j]){
				ans++;
				cnt[j]--;
				for (int w = vec[i]; w < j; w++)
					cnt[w]++;
				break;
			}
	}
	printf("%d\n", ans);
	return	0;
}


#include<cstdio>
#include<algorithm>
#include<queue>

using namespace std;

const int MAXN = 1e6 + 10;

int n, m, vec[MAXN];
priority_queue<int> st;

int main(){
	scanf("%d %d", &n, &m);
	while (n--){int x;	scanf("%d", &x);	st.push(x);}
	for (int i = 0; i < m; i++)
		scanf("%d", &vec[i]), vec[i] = 1<<vec[i];
	sort(vec, vec + m);
	int ans = 0;
	for (int i = 0; i < m; i++){
		while (st.size() && st.top() < vec[i])	st.pop();
		if (st.size()){
			ans++;
			int temp = st.top();
			st.pop();
			st.push(temp - vec[i]);
		}
	}
	printf("%d\n", ans);
	return	0;
}


#include<cstdio>
#include<iostream>
#include<algorithm>
#include<set>

using namespace std;

const int MAXN = 1e6 + 10;

int vec[MAXN];

int main(){
	int n, m;	scanf("%d %d", &n, &m);
	multiset<int>	st;
	while (n--){int x;	scanf("%d", &x);	st.insert(x);}
	int tm = m;
	while (m--)	scanf("%d", &vec[m]);
	sort(vec, vec + tm);
	int ans = 0;
	for (int i = 0; i < tm; i++){auto it = st.lower_bound(1 << vec[i]);	if (it != st.end()){ans++; int temp = *it;	st.erase(it);	st.insert(temp - (1 << vec[i]));}}
	printf("%d\n", ans);
	return	0;
}


#include<cstdio>
#include<iostream>
#include<algorithm>
#include<set>

using namespace std;

const int MAXN = 1e6 + 10;

int n, m, vec[MAXN];
multiset<int>	st;

int main(){
	scanf("%d %d", &n, &m);
	while (n--){int x;	scanf("%d", &x);	st.insert(x);}
	for (int i = 0; i < m; i++)
		scanf("%d", &vec[i]), vec[i] = 1<<vec[i];
	sort(vec, vec + m);
	int ans = 0;
	for (int i = 0; i < m; i++){auto it = st.lower_bound(vec[i]);	if (it != st.end()){ans++; int temp = *it;	st.erase(it);	st.insert(temp - (vec[i]));}}
	printf("%d\n", ans);
	return	0;
}


#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<functional>

using namespace std;

const int MAXN = 1e6 + 10;

int n, m, vec[MAXN];
priority_queue<int, vector<int>, greater<int>> st;

int main(){
	scanf("%d %d", &n, &m);
	while (n--){int x;	scanf("%d", &x);	st.push(x);}
	for (int i = 0; i < m; i++)
		scanf("%d", &vec[i]), vec[i] = 1<<vec[i];
	sort(vec, vec + m);
	int ans = 0;
	for (int i = 0; i < m; i++){
		while (st.size() && st.top() < vec[i])	st.pop();
		if (st.size()){
			ans++;
			int temp = st.top();
			st.pop();
			st.push(temp - vec[i]);
		}
	}
	printf("%d\n", ans);
	return	0;
}


#include<iostream>
#include<algorithm>
#include<vector>
#include<set>

using namespace std;

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n, m;	cin >> n >> m;
	multiset<int>	st;
	while (n--){int x;	cin >> x;	st.insert(x);}
	vector<int>	vec(m);
	int tm = m;
	while (m--)	cin >> vec[m];
	sort(vec.begin(), vec.end());
	int ans = 0;
	for (int i = 0; i < tm; i++){auto it = st.lower_bound(1 << vec[i]);	if (it != st.end()){ans++; int temp = *it;	st.erase(it);	st.insert(temp - (1 << vec[i]));}}
	cout << ans << endl;
	return	0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int  ,int > pii;

const ll maxn =4e5;
const ld SADAT = 7.84e-17;
const ll INF = 1e9;
const ll mod = 1e9+7;
const ld PI = 4 * atan((ld) 1);

#define pb(x) push_back(x);
#define endl '\n'
#define dokme(x) cout << x ;  return(0);
#define migmig ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define file_init freopen("input.txt", "r+", stdin); freopen("output.txt", "w+", stdout);
#define random_init mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
#define ms(x , y) memset(x , y , sizeof x);
#define sa(x) x.begin() , x.end()
#define prnt(x)  for(int i = 0 ; i < x.size() ; i ++) cout << x[i] << ' ';
ll pw(ll a, ll b) {
    return (!b ? 1 : (b & 1 ? a * pw(a * a % mod, b / 2) % mod : pw(a * a % mod, b / 2) % mod));
}

ll n , m , ans = 0;
vector <ll> sz;
vector <ll> b;
int c[50];

bool ibit(ll x , int i){
    return((x & (1 << i)));
}

void prc(ll x){
    for (int i = 0 ; i < 40 ; i ++){
        if(ibit(x , i)){
            c[i]++;
        }
    }
}

int main(){
    migmig
    ms(c , 0);
    cin >> n >> m;
    for (ll i =0;  i < n ; i ++){
        ll inp;
        cin >> inp;
        sz.pb(inp);
        prc(inp);
    }
    ll cnt = 0;
    for (ll i =0;  i < m ; i ++){
        int inp;
        cin >> inp;
        b.pb(inp);
    }
    sort(sa(b));
    for (int i = 0;  i< m ; i ++){
        for (int j = b[i] ; j <= 30 ; j++){
            if(c[j]){
                ans++;
                c[j]--;
                for (int k = b[i] ; k < j ; k ++){
                    c[k] ++;
                }
                break;
            }
        }
    }
    cout << ans;
    return(0);
}

//When we hit our lowest point, we are open to the greatest change.
//If I try, I fail. If I don't try, I'm NEVER GOING TO GET IT.
//Sometimes, life is like this dark tunnel. You can't always see the light at the end of the tunnel. But if you just keep moving... you will come to a better place.
//It is important to draw wisdom from diffrent places. If you take it from only one place it becomes rigid and stale.


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int  ,int > pii;

const ll maxn =4e5;
const ld SADAT = 7.84e-17;
const ll INF = 1e9;
const ll mod = 1e9+7;
const ld PI = 4 * atan((ld) 1);

#define pb(x) push_back(x);
#define endl '\n'
#define dokme(x) cout << x ;  return(0);
#define migmig ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define file_init freopen("input.txt", "r+", stdin); freopen("output.txt", "w+", stdout);
#define random_init mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
#define ms(x , y) memset(x , y , sizeof x);
#define sa(x) x.begin() , x.end()
#define prnt(x)  for(int i = 0 ; i < x.size() ; i ++) cout << x[i] << ' ';
ll pw(ll a, ll b) {
    return (!b ? 1 : (b & 1 ? a * pw(a * a % mod, b / 2) % mod : pw(a * a % mod, b / 2) % mod));
}

int n , m , ans = 0;
vector <int> sz;
vector <int> b;
int c[50];

bool ibit(int x , int i){
    return((x & (1 << i)));
}

void prc(int x){
    for (int i = 0 ; i < 32 ; i ++){
        if(ibit(x , i)){
            c[i]++;
        }
    }
}

int main(){
    migmig
    ms(c , 0);
    cin >> n >> m;
    for (int i =0;  i < n ; i ++){
        int inp;
        cin >> inp;
        sz.pb(inp);
        prc(inp);
    }
    int cnt = 0;
    for (int i =0;  i < m ; i ++){
        int inp;
        cin >> inp;
        b.pb(inp);
    }
    sort(sa(b));
    for (int i = 0;  i< m ; i ++){
        for (int j = b[i] ; j <= 30 ; j++){
            if(c[j]){
                ans++;
                c[j]--;
                for (int k = b[i] ; k < j ; k ++){
                    c[k] ++;
                }
                break;
            }
        }
    }
    cout << ans;
    return(0);
}

//When we hit our lowest point, we are open to the greatest change.
//If I try, I fail. If I don't try, I'm NEVER GOING TO GET IT.
//Sometimes, life is like this dark tunnel. You can't always see the light at the end of the tunnel. But if you just keep moving... you will come to a better place.
//It is important to draw wisdom from diffrent places. If you take it from only one place it becomes rigid and stale.


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int  ,int > pii;

const ll maxn =4e5;
const ld SADAT = 7.84e-17;
const ll INF = 1e9;
const ll mod = 1e9+7;
const ld PI = 4 * atan((ld) 1);

#define pb(x) push_back(x);
#define endl '\n'
#define dokme(x) cout << x ;  return(0);
#define migmig ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define file_init freopen("input.txt", "r+", stdin); freopen("output.txt", "w+", stdout);
#define random_init mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
#define ms(x , y) memset(x , y , sizeof x);
#define sa(x) x.begin() , x.end()
#define prnt(x)  for(int i = 0 ; i < x.size() ; i ++) cout << x[i] << ' ';
ll pw(ll a, ll b) {
    return (!b ? 1 : (b & 1 ? a * pw(a * a % mod, b / 2) % mod : pw(a * a % mod, b / 2) % mod));
}

ll n , m , ans = 0;
vector <ll> sz;
vector <ll> b;
int c[50];

bool ibit(ll x , int i){
    return((x & (1 << i)));
}

void prc(ll x){
    for (int i = 0 ; i < 32 ; i ++){
        if(ibit(x , i)){
            c[i]++;
        }
    }
}

int main(){
    migmig
    ms(c , 0);
    cin >> n >> m;
    for (ll i =0;  i < n ; i ++){
        ll inp;
        cin >> inp;
        sz.pb(inp);
        prc(inp);
    }
    ll cnt = 0;
    for (ll i =0;  i < m ; i ++){
        int inp;
        cin >> inp;
        b.pb(inp);
    }
    sort(sa(b));
    for (int i = 0;  i< m ; i ++){
        for (int j = b[i] ; j <= 30 ; j++){
            if(c[j]){
                ans++;
                c[j]--;
                for (int k = b[i] ; k < j ; k ++){
                    c[k] ++;
                }
                break;
            }
        }
    }
    cout << ans;
    return(0);
}

//When we hit our lowest point, we are open to the greatest change.
//If I try, I fail. If I don't try, I'm NEVER GOING TO GET IT.
//Sometimes, life is like this dark tunnel. You can't always see the light at the end of the tunnel. But if you just keep moving... you will come to a better place.
//It is important to draw wisdom from diffrent places. If you take it from only one place it becomes rigid and stale.


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

int main(){
int n=0,m=0,ans=0,odd=0;
long long freq[40]={0};
long long power[40]={0};
for(long long i=0,j=1;i<33;i++,j*=2)power[i]=j;
vector<long long>a;
scanf("%d%d",&n,&m);
while(n--){
int x=0;
scanf("%d",&x);
a.push_back(x);
odd+=(x%2);
}
sort(a.begin(),a.end());
while(m--){
int x=0;
scanf("%d",&x);
freq[x]++;
}
if(odd&&freq[0]){
    for(int i=0;i<(int)a.size();i++)
    if(a[i]%2)ans+=(freq[0]>0),freq[0]-=(freq[0]>0),a[i]--;
}
else if(!odd&&freq[0]){
    for(int i=0;i<(int)a.size();i++)
    if(freq[0]>2&&a[i]>2)a[i]-=2,freq[0]-=2,ans+=2;
    }
else if(odd&&!freq[0])
    for(int i=0;i<(int)a.size();i++)
    if(a[i]%2)a[i]--;

for(int i=0;i<(int)a.size();i++)
    for(int j=0;j<31;j++)
if(a[i]>=power[j]){
    long long s=min(a[i]/power[j],freq[j]);
    a[i]-=(s*power[j]);
    freq[j]-=s;
    ans+=s;
}
printf("%d",ans);

    return 0;
}


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

int main(){
int n=0,m=0,ans=0;
map<int,int>mp;
vector<int>b;
vector<int>a;
for(int i=0,j=1;i<33;i++,j*=2)b.push_back(j);
scanf("%d%d",&n,&m);
while(n--){
int x=0;
scanf("%d",&x);
mp[x]++;
}
while(m--){
int x=0;
scanf("%d",&x);
x=b[x];
a.push_back(x);
}
sort(a.begin(),a.end());
for(int i=0;i<(int)a.size();i++){

auto it=mp.lower_bound(a[i]);
if(it==mp.end())break;
ans++;
int ele=it->first;
int freq=it->second;
freq--;
if(!freq)mp.erase(ele);

}

printf("%d",ans);
    return 0;
}


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

int main(){
long long n=0,m=0,ans=0;
map<long long,long long>mp;
vector<long long>b;
vector<long long>a;
for(long long i=0,j=1;i<33;i++,j*=2)b.push_back(j);
scanf("%I64d%I64d",&n,&m);
while(n--){
long long x=0;
scanf("%I64d",&x);
mp[x]++;
}
while(m--){
long long x=0;
scanf("%I64d",&x);
x=b[x];
a.push_back(x);
}
sort(a.begin(),a.end());
for(int i=0;i<(int)a.size();i++){

auto it=mp.lower_bound(a[i]);
if(it==mp.end())break;
ans++;
long long ele=it->first;
long long freq=it->second;
freq--;
if(!freq)mp.erase(ele);

}

printf("%I64d",ans);
    return 0;
}


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

int main(){
int n=0,m=0,ans=0,odd=0;
long long freq[40]={0};
long long power[40]={0};
for(long long i=0,j=1;i<33;i++,j*=2)power[i]=j;
vector<long long>a;
cin>>n>>m;
while(n--){
int x=0;
cin>>x;
a.push_back(x);
odd+=(x%2);
}
sort(a.begin(),a.end());
while(m--){
int x=0;
cin>>x;
freq[x]++;
}
if(odd&&freq[0]){
    for(int i=0;i<(int)a.size();i++)
    if(a[i]%2)ans+=(freq[0]>0),freq[0]-=(freq[0]>0),a[i]--;
}
else if(!odd&&freq[0]){
    for(int i=0;i<(int)a.size();i++)
    if(freq[0]>2&&a[i]>2)a[i]-=2,freq[0]-=2,ans+=2;
    }
else if(odd&&!freq[0])
    for(int i=0;i<(int)a.size();i++)
    if(a[i]%2)a[i]--;

for(int i=0;i<(int)a.size();i++)
    for(int j=0;j<31;j++)
if(a[i]>=power[j]){
    int s=min(a[i]/power[j],freq[j]);
    a[i]-=(s*power[j]);
    freq[j]-=s;
    ans+=s;
}
cout<<ans;

    return 0;
}


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

int main(){
int n=0,m=0,ans=0;
map<int,int>mp;
vector<int>b;
for(int i=0,j=1;i<33;i++,j*=2)b.push_back(j);
cin>>n>>m;
while(n--){
int x=0;
cin>>x;
mp[x]++;
}
while(m--){
int x=0;
cin>>x;
x=b[x];
auto it=mp.lower_bound(x);
if(it==mp.end())continue;
ans++;
int ele=it->first;
int freq=it->second;
freq--;
if(!freq)mp.erase(ele);

}
cout<<ans;
    return 0;
}


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

int main(){
int n=0,m=0,ans=0;
map<long long,long long>mp;
vector<long long>b;
vector<long long>a;
for(long long i=0,j=1;i<33;i++,j*=2)b.push_back(j);
scanf("%d%d",&n,&m);
while(n--){
long long x=0;
scanf("%I64d",&x);
mp[x]++;
}
while(m--){
long long x=0;
scanf("%I64d",&x);
x=b[x];
a.push_back(x);
}
sort(a.begin(),a.end());
for(int i=0;i<(int)a.size();i++){

auto it=mp.lower_bound(a[i]);
if(it==mp.end())break;
ans++;
long long ele=it->first;
long long freq=it->second;
freq--;
if(!freq)mp.erase(ele);

}

printf("%d",ans);
    return 0;
}


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

int main(){
int n=0,m=0,ans=0;
map<int,int>mp;
vector<int>b;
for(int i=0,j=1;i<33;i++,j*=2)b.push_back(j);
scanf("%d%d",&n,&m);
while(n--){
int x=0;
scanf("%d",&x);
mp[x]++;
}
while(m--){
int x=0;
scanf("%d",&x);
x=b[x];
auto it=mp.lower_bound(x);
if(it==mp.end())continue;
ans++;
int ele=it->first;
int freq=it->second;
freq--;
if(!freq)mp.erase(ele);

}
printf("%d",ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
int arr[1000000+9]={0};
int main(){
int n=0,m=0,ans=0;
map<int,int>mp;
cin>>n>>m;
while(n--){
int x=0;
cin>>x;
mp[x]++;
}
while(m--){
int x=1,y=0;
cin>>y;
while(y--)x*=2;

auto it=mp.lower_bound(x);
if(it==mp.end())continue;
ans++;
int ele=it->first;
int freq=it->second;
freq--;
if(!freq)mp.erase(ele);

}
cout<<ans;
    return 0;
}


#include <bits/stdc++.h>
//#define int long long
#define hash hashhash
#define X first
#define Y second
#define endl "\n"
#define Mp make_pair
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline long long lin(){long long x ; scanf("%lld",&x) ; return x ;}
inline string get(){char ch[2000010] ; scanf("%s",ch) ; return ch;}
inline void read(int *a , int n ) { for (int i = 0 ; i < n ; i ++) a[i] = in() ; }
template <class blank> inline void out(blank x) {cout << x << endl ; exit(0) ;}
template <class blank> inline void smin(blank &a , blank b) {a = min(a , b) ;}
template <class blank> inline void smax(blank &a , blank b) {a = max(a , b) ; }
typedef pair<int , int > pii;
typedef long double ld;
typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pii> vii;
const int maxn  = 1e6  + 10;
const int maxm = 1e6 + 10;
const int maxlg = 21;
const int base = 29;
const int mod = 1e9 + 7;
const ll inf = 2e18 + 10;
const int SQ = 317;
int b[maxn],res,a[maxn];
int32_t main()
{
    multiset<int> st;
    int n = in() , m = in();
    read(a,n);
    vi vc;
    for (int i = 0 ; i < n ; i ++)
    {
        for (int j = 0 ; j < 30 ; j ++)
        {
            if (a[i] >> j & 1)
                vc.push_back(1 << j);
        }
    }
    sort(vc.begin(),vc.end());
    read(b,m);
    sort(b,b+m);
    int cur = 0;
    for (int i = 0 ; i < m ; i ++)
    {
        while(cur < vc.size() && vc[cur] <  (1 << b[i])) cur ++;
        if (cur < vc.size())
        {
            res ++;
            vc[cur] -= 1 << b[i];
        }
    }
    cout << res << endl;

}


#include <bits/stdc++.h>
#define int long long
#define hash hashhash
#define X first
#define Y second
#define endl "\n"
#define Mp make_pair
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline long long lin(){long long x ; scanf("%lld",&x) ; return x ;}
inline string get(){char ch[2000010] ; scanf("%s",ch) ; return ch;}
inline void read(int *a , int n ) { for (int i = 0 ; i < n ; i ++) a[i] = in() ; }
template <class blank> inline void out(blank x) {cout << x << endl ; exit(0) ;}
template <class blank> inline void smin(blank &a , blank b) {a = min(a , b) ;}
template <class blank> inline void smax(blank &a , blank b) {a = max(a , b) ; }
typedef pair<int , int > pii;
typedef long double ld;
typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pii> vii;
const int maxn  = 1e6  + 10;
const int maxm = 1e6 + 10;
const int maxlg = 21;
const int base = 29;
const int mod = 1e9 + 7;
const ll inf = 2e18 + 10;
const int SQ = 317;
int b[maxn],res;

int32_t main()
{
    multiset<int> st;
    int n = in() , m = in();
    for (int i = 0 ; i < n ; i ++) st.insert(in());
    read(b,m);
    sort(b,b+m);
    for (int i = 0 ; i < m ; i ++)
    {
        b[i] = (1 << b[i]);
        set<int>::iterator low = st.lower_bound(b[i]);
        if (low == st.end()) break;
        int val = *low;
        st.erase(st.find(val));
        st.insert(val-b[i]);
        res ++;
    }
    cout << res << endl;

}


#include <bits/stdc++.h>
//#define int long long
#define hash hashhash
#define X first
#define Y second
#define endl "\n"
#define Mp make_pair
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline long long lin(){long long x ; scanf("%lld",&x) ; return x ;}
inline string get(){char ch[2000010] ; scanf("%s",ch) ; return ch;}
inline void read(int *a , int n ) { for (int i = 0 ; i < n ; i ++) a[i] = in() ; }
template <class blank> inline void out(blank x) {cout << x << endl ; exit(0) ;}
template <class blank> inline void smin(blank &a , blank b) {a = min(a , b) ;}
template <class blank> inline void smax(blank &a , blank b) {a = max(a , b) ; }
typedef pair<int , int > pii;
typedef long double ld;
typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pii> vii;
const int maxn  = 1e6  + 10;
const int maxm = 1e6 + 10;
const int maxlg = 21;
const int base = 29;
const int mod = 1e9 + 7;
const ll inf = 2e18 + 10;
const int SQ = 317;
int b[maxn],res,a[maxn];
int32_t main()
{
    multiset<int> st;
    int n = in() , m = in();
    read(a,n);
    sort(a,a+n);
    read(b,m);
    sort(b,b+m);
    int cur = 0;
    for (int i = 0 ; i < m ; i ++)
    {
        while(cur < n && a[cur] < (1 << b[i])) cur ++;
        if (cur < n)
        {
            res ++;
            a[cur] -= 1 << b[i];
        }
    }
    cout << res << endl;

}


#include <bits/stdc++.h>
//#define int long long
#define hash hashhash
#define X first
#define Y second
#define endl "\n"
#define Mp make_pair
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline long long lin(){long long x ; scanf("%lld",&x) ; return x ;}
inline string get(){char ch[2000010] ; scanf("%s",ch) ; return ch;}
inline void read(int *a , int n ) { for (int i = 0 ; i < n ; i ++) a[i] = in() ; }
template <class blank> inline void out(blank x) {cout << x << endl ; exit(0) ;}
template <class blank> inline void smin(blank &a , blank b) {a = min(a , b) ;}
template <class blank> inline void smax(blank &a , blank b) {a = max(a , b) ; }
typedef pair<int , int > pii;
typedef long double ld;
typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pii> vii;
const int maxn  = 1e6  + 10;
const int maxm = 1e6 + 10;
const int maxlg = 21;
const int base = 29;
const int mod = 1e9 + 7;
const ll inf = 2e18 + 10;
const int SQ = 317;
int b[maxn],res,a[maxn];
int vc[maxn*20];
int t;
int32_t main()
{
    int n = in() , m = in();
    read(a,n);
    for (int i = 0 ; i < n ; i ++)
    {
        for (int j = 0 ; j < 30 ; j ++)
        {
            if (a[i] >> j & 1)
                vc[t ++] = 1 << j;
        }
    }
    sort(vc,vc+t);
    read(b,m);
    sort(b,b+m);
    int cur = 0;
    for (int i = 0 ; i < m ; i ++)
    {
        while(cur < t && vc[cur] < (1 << b[i])) cur ++;
        if (cur < t)
        {
            res ++;
            vc[cur] -= 1 << b[i];
        }else break;
    }
    cout << res << endl;

}


#include <bits/stdc++.h>
//#define int long long
#define hash hashhash
#define X first
#define Y second
#define endl "\n"
#define Mp make_pair
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline long long lin(){long long x ; scanf("%lld",&x) ; return x ;}
inline string get(){char ch[2000010] ; scanf("%s",ch) ; return ch;}
inline void read(int *a , int n ) { for (int i = 0 ; i < n ; i ++) a[i] = in() ; }
template <class blank> inline void out(blank x) {cout << x << endl ; exit(0) ;}
template <class blank> inline void smin(blank &a , blank b) {a = min(a , b) ;}
template <class blank> inline void smax(blank &a , blank b) {a = max(a , b) ; }
typedef pair<int , int > pii;
typedef long double ld;
typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pii> vii;
const int maxn  = 1e6  + 10;
const int maxm = 1e6 + 10;
const int maxlg = 21;
const int base = 29;
const int mod = 1e9 + 7;
const ll inf = 2e18 + 10;
const int SQ = 317;
int b[maxn],res;

int32_t main()
{
    multiset<int> st;
    int n = in() , m = in();
    for (int i = 0 ; i < n ; i ++) st.insert(in());
    read(b,m);
    sort(b,b+m);
    for (int i = 0 ; i < m ; i ++)
    {
        b[i] = (1 << b[i]);
        set<int>::iterator low = st.lower_bound(b[i]);
        if (low == st.end()) break;
        int val = *low;
        st.erase(st.find(val));
        st.insert(val-b[i]);
        res ++;
    }
    cout << res << endl;

}


#include <bits/stdc++.h>
//#define int long long
#define hash hashhash
#define X first
#define Y second
#define endl "\n"
#define Mp make_pair
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline long long lin(){long long x ; scanf("%lld",&x) ; return x ;}
inline string get(){char ch[2000010] ; scanf("%s",ch) ; return ch;}
inline void read(int *a , int n ) { for (int i = 0 ; i < n ; i ++) a[i] = in() ; }
template <class blank> inline void out(blank x) {cout << x << endl ; exit(0) ;}
template <class blank> inline void smin(blank &a , blank b) {a = min(a , b) ;}
template <class blank> inline void smax(blank &a , blank b) {a = max(a , b) ; }
typedef pair<int , int > pii;
typedef long double ld;
typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pii> vii;
const int maxn  = 1e6  + 10;
const int maxm = 1e6 + 10;
const int maxlg = 21;
const int base = 29;
const int mod = 1e9 + 7;
const ll inf = 2e18 + 10;
const int SQ = 317;
int b[maxn],res,a[maxn];
int32_t main()
{
    multiset<int> st;
    int n = in() , m = in();
    read(a,n);
    read(b,m);
    sort(b,b+m);
    int cur = 0;
    for (int i = 0 ; i < m ; i ++)
    {
        while(cur < n && a[cur] < (1 << b[i])) cur ++;
        if (cur < n)
        {
            res ++;
            a[cur] -= 1 << b[i];
        }
    }
    cout << res << endl;

}


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

int frc[50];

void add(int n);
bool rem(int n);

int v[1000010];

int main()
{
	int n, m, c;

	scanf("%d%d", &n, &m);

	while (n--) {
		scanf("%d", &c);
		add(c);
	}

	for (int i(0); i < m; i++)
		scanf("%d", &v[i]);

	sort(v, v + m);

	int ans(0);

	for (int i(0); i < m; i++) {
		if (rem(v[i]))
			ans++;
		else
			break;
	}

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

	return 0;
}

bool rem(int n)
{
	if (n > 30)
		return false;
	if (frc[n]) {
		frc[n]--;
		return true;
	}
	frc[n] = 1;
	return rem(n + 1);
}

void add(int n)
{
	for (int i(0); n; i++, n >>= 1)
		if (n & 1)
			frc[i]++;
}


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

int frc[50];

void add(int n);
bool rem(int n);

int main()
{
	vector <int> v;
	int n, m, c;
	ios_base :: sync_with_stdio(0);
	cin.tie(0);

	cin >> n >> m;
	while (n--) {
		cin >> c;
		add(c);
	}

	while (m--) {
		cin >> c;
		v.push_back(c);
	}

	sort(v.begin(), v.end());

	int ans(0);

	for (auto i : v) {
		if (rem(i))
			ans++;
	}

	cout << ans;

	return 0;
}

bool rem(int n)
{
	if (n > 40)
		return false;
	if (frc[n]) {
		frc[n]--;
		return true;
	}
	frc[n] = 1;
	return rem(n + 1);
}

void add(int n)
{
	for (int i(0); n; i++)
		if (n & (1 << i))
			frc[i]++, n ^= (1 << i);
}


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

int frc[50];

void add(int n);
bool rem(int n);

int main()
{
	vector <int> v;
	int n, m, c;
	ios_base :: sync_with_stdio(0);
	cin.tie(0);

	cin >> n >> m;
	while (n--) {
		cin >> c;
		add(c);
	}

	v.resize(m);

	for (int i(0); i < m; i++)
		cin >> v[i];

	sort(v.begin(), v.end());

	int ans(0);

	for (auto i : v) {
		if (rem(i))
			ans++;
		else
			break;
	}

	cout << ans;

	return 0;
}

bool rem(int n)
{
	if (n > 30)
		return false;
	if (frc[n]) {
		frc[n]--;
		return true;
	}
	frc[n] = 1;
	return rem(n + 1);
}

void add(int n)
{
	for (int i(0); n && i <= 31; i++)
		if (n & (1 << i))
			frc[i]++, n ^= (1 << i);
}


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

int frc[50];

void add(int n);
bool rem(int n);

int main()
{
	vector <int> v;
	int n, m, c;
	ios_base :: sync_with_stdio(0);
	cin.tie(0);

	cin >> n >> m;
	while (n--) {
		cin >> c;
		add(c);
	}

	while (m--) {
		cin >> c;
		v.push_back(c);
	}

	sort(v.begin(), v.end());

	int ans(0);

	for (auto i : v) {
		if (rem(i))
			ans++;
		else
			break;
	}

	cout << ans;

	return 0;
}

bool rem(int n)
{
	if (n > 40)
		return false;
	if (frc[n]) {
		frc[n]--;
		return true;
	}
	frc[n] = 1;
	return rem(n + 1);
}

void add(int n)
{
	for (int i(0); n; i++)
		if (n & (1 << i))
			frc[i]++, n ^= (1 << i);
}


#include <bits/stdc++.h>
using namespace std;
#define M 41
#define Max 1000010
#define ll long long
ll s[M];
ll b[M];
ll a[M];
ll n,m;

int jin(ll k) {
	ll jie = 0,now = 0;
	for(ll i = k+1; i<M; i++) {
		if(a[i]) {
			jie = 1;
			now = i;
			break;
		}
	}
	if(!jie)
		return 0;
	ll tt = b[k] / s[now - k];
	if(tt == 0 ) {
		for(ll i = k +1 ; i < now; i++)
			a[i] += 1;
		a[k] += 2;
		a[now] -= 1;
		return 1;
	}
	ll pp = min(tt,a[now]);
	a[now] -= pp;
	a[k] += pp*s[now - k];
	return 1;
}
int main() {
	for(int i = 0; i<M; i++)
		s[i] = ((ll)1<<i);

	scanf("%lld%lld",&n,&m);
    ll k;
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	for(ll i = 0; i < n; i++) {
		scanf("%lld",&k);
		for(ll j = 0; j<M && k>=s[j]; j++)
			if(k&s[j])
				a[j]++;
	}
	for(ll i = 0; i<m; i++) {
		scanf("%lld",&k);
		b[k] ++;
	}
	ll ans = 0;
	int flag = 1;
	for(ll i = 0; i<M; i++) {
		while(b[i]) {
			ll tt = min(a[i],b[i]);
			a[i] -= tt;
			b[i] -= tt;
			ans += tt;
			if(b[i]) {
				if(!jin(i)) {
					flag = 0;
					break;
				}
			} else break;
		}
		if(!flag)
			break;
	}
	printf ("%lld\n",ans);

	return 0;
}


//in the name of Allah
//#isart
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int lg = 32, N = 1e6 + 10;
int cnt[lg + 10], cnt2[lg + 10], a[N];

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n, m;
	cin >> n >> m;
	for(int i = 0; i < n; i ++){
		int a, num = 0;
		cin >> a;
		while(a != 0){
			cnt[num] += a % 2;
			a /= 2;
			num ++;
		}
	}
	for(int i = 0; i < m; i ++){
		int b;
		cin >> b;
		cnt2[b] ++;
	}
	int cur = 0, cnn = 0, ans = 0;
	for(int i = 0; i < lg; i ++){
		for(int j = i; j < lg; j ++){
			if(cnt2[i] == 0)
				break;
			int last = cnt2[i];
			cnt2[i] = max(0ll, cnt2[i] - cnt[j] * (1ll << (j - i)));
			cnt[j] = max(0ll, cnt[j] - (last - cnt2[i]) / (1ll << (j - i)));
			int rem = (last - cnt2[i]) % (1ll << (j - i));
			if(rem == 0)
				continue;
			cnt[j] --;
			ll val = (1ll << j) - rem * (1ll << i);
			for(int x = 0; x < lg; x ++)
				if((1ll << x) & val)
					cnt[x] ++;

		}
		ans += cnt2[i];
	}
	cout << m - ans;
	return 0;
}


//in the name of Allah
//#isart
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int lg = 32, N = 1e6 + 10;
ll cnt[lg], cnt2[lg];

int main(){
	int n, m;
	cin >> n >> m;
	for(int i = 0; i < n; i ++){
		int a;
		cin >> a;
		for(int j = 0; j < lg; j ++)
			if(a & (1ll << j))
				cnt[j] ++;
	}
	for(int i = 0; i < m; i ++){
		int b;
		cin >> b;
		cnt2[b] ++;
	}
	int cur = 0, ans = 0;
	for(int i = 0; i < lg; i ++){
		cur = max(cur, i);
		int last = cnt2[i];
		while(cnt2[i] and cnt[cur]){
			int val = cnt2[i];
			cnt2[i] -= cnt[cur] * (cur - i + 1);
			int md = 0;
			if(val % (cur - i + 1) != 0)
				md = 1;
			cnt[cur] -= (val / (cur - i + 1) + md);
			cnt2[i] = max(0ll, cnt2[i]);
			cnt[cur] = max(0ll, cnt[cur]);
			if(cnt[cur] == 0)
				cur ++;
		}
		ans += last - cnt2[i];
	}
	cout << ans;
	return 0;
}


//in the name of Allah
//#isart
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int lg = 32, N = 1e6 + 10;
int cnt[lg + 10], cnt2[lg + 10];

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n, m;
	cin >> n >> m;
	for(int i = 0; i < n; i ++){
		int a;
		cin >> a;
		for(int j = 0; j < lg; j ++)
			if(a & (1ll << j))
				cnt[j] ++;
	}
	for(int i = 0; i < m; i ++){
		int b;
		cin >> b;
		cnt2[b] ++;
	}
	int cur = 0, cnn = 0, ans = 0;
	for(int i = 0; i < lg; i ++){
		cur = max(cur, i);
		int last = cnt2[i];
		while(cnt2[i] and cnt[cur] and cur < lg){
			int val = cnt2[i];
			cnt2[i] -= cnt[cur] * (cur - i + 1);
			int md = 0;
			if(val % (cur - i + 1) != 0)
				md = 1;
			cnt[cur] -= (val / (cur - i + 1) + md);
			cnt2[i] = max(0, cnt2[i]);
			cnt[cur] = max(0, cnt[cur]);
			if(cnt[cur] == 0)
				cur ++;
			cnn ++;
			if(cnn > 1e7){
				cout << "WRONG";
				return 0;
			}
		}
		ans += last - cnt2[i];
	}
	cout << ans;
	return 0;
}


//in the name of Allah
//#isart
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int lg = 32, N = 1e6 + 10;
int cnt[lg + 10], cnt2[lg + 10];

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n, m;
	cin >> n >> m;
	for(int i = 0; i < n; i ++){
		int a;
		cin >> a;
		for(int j = 0; j < lg; j ++)
			if(a & (1ll << j))
				cnt[j] ++;
	}
	for(int i = 0; i < m; i ++){
		int b;
		cin >> b;
		cnt2[b] ++;
	}
	int cur = 0, ans = 0;
	for(int i = 0; i < lg; i ++){
		cur = max(cur, i);
		int last = cnt2[i];
		while(cnt2[i] and cnt[cur] and cur < lg){
			int val = cnt2[i];
			cnt2[i] -= cnt[cur] * (cur - i + 1);
			int md = 0;
			if(val % (cur - i + 1) != 0)
				md = 1;
			cnt[cur] -= (val / (cur - i + 1) + md);
			cnt2[i] = max(0ll, cnt2[i]);
			cnt[cur] = max(0ll, cnt[cur]);
			if(cnt[cur] == 0)
				cur ++;
		}
		ans += last - cnt2[i];
	}
	cout << ans;
	return 0;
}


//in the name of Allah
//#isart
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int lg = 32, N = 1e6 + 10;
int cnt[lg + 10], cnt2[lg + 10];

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n, m;
	cin >> n >> m;
	for(int i = 0; i < n; i ++){
		int a;
		cin >> a;
		for(int j = 0; j < lg; j ++)
			if(a & (1ll << j))
				cnt[j] ++;
	}
	for(int i = 0; i < m; i ++){
		int b;
		cin >> b;
		cnt2[b] ++;
	}
	int cur = 0, cnn = 0, ans = 0;
	for(int i = 0; i < lg; i ++){
		for(int j = i; j < lg; j ++){
			if(cnt2[i] == 0)
				break;
			int last = cnt2[i];
			cnt2[i] = max(0ll, cnt2[i] - cnt[j] * (1ll << (j - i)));
			cnt[j] = max(0ll, cnt[j] - (last - cnt2[i]) / (1ll << (j - i)));
			int rem = (last - cnt2[i]) % (1ll << (j - i));
			if(rem == 0)
				continue;
			cnt[j] --;
			ll val = (1ll << j) - rem * (1ll << i);
			for(int x = 0; x < lg; x ++)
				if((1ll << x) & val)
					cnt[x] ++;

		}
		ans += cnt2[i];
	}
	cout << m - ans;
	return 0;
}


//in the name of Allah
//#isart
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int lg = 32, N = 1e6 + 10;
int cnt[lg + 10], cnt2[lg + 10], a[N];

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n, m;
	cin >> n >> m;
	for(int i = 0; i < n; i ++)
		cin >> a[i];
	for(int i = 0; i < n; i ++)
		for(int j = 0; j < lg; j ++)
			if(a[i] & (1 << j))
				cnt[j] ++;
	for(int i = 0; i < m; i ++){
		int b;
		cin >> b;
		cnt2[b] ++;
	}
	int cur = 0, cnn = 0, ans = 0;
	for(int i = 0; i < lg; i ++){
		for(int j = i; j < lg; j ++){
			if(cnt2[i] == 0)
				break;
			int last = cnt2[i];
			cnt2[i] = max(0ll, cnt2[i] - cnt[j] * (1ll << (j - i)));
			cnt[j] = max(0ll, cnt[j] - (last - cnt2[i]) / (1ll << (j - i)));
			int rem = (last - cnt2[i]) % (1ll << (j - i));
			if(rem == 0)
				continue;
			cnt[j] --;
			ll val = (1ll << j) - rem * (1ll << i);
			for(int x = 0; x < lg; x ++)
				if((1ll << x) & val)
					cnt[x] ++;

		}
		ans += cnt2[i];
	}
	cout << m - ans;
	return 0;
}


//in the name of Allah
//#isart
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int lg = 32, N = 1e6 + 10;
int cnt[lg + 10], cnt2[lg + 10];

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n, m;
	cin >> n >> m;
	for(int i = 0; i < n; i ++){
		int a;
		cin >> a;
		for(int j = 0; j < lg; j ++)
			if(a & (1ll << j))
				cnt[j] ++;
	}
	for(int i = 0; i < m; i ++){
		int b;
		cin >> b;
		cnt2[b] ++;
	}
	int cur = 0, ans = 0;
	for(int i = 0; i < lg; i ++){
		cur = max(cur, i);
		int last = cnt2[i];
		while(cnt2[i] and cnt[cur] and cur < lg){
			int val = cnt2[i];
			cnt2[i] -= cnt[cur] * (cur - i + 1);
			int md = 0;
			if(val % (cur - i + 1) != 0)
				md = 1;
			cnt[cur] -= (val / (cur - i + 1) + md);
			cnt2[i] = max(0, cnt2[i]);
			cnt[cur] = max(0, cnt[cur]);
			if(cnt[cur] == 0)
				cur ++;
		}
		ans += last - cnt2[i];
	}
	cout << ans;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
using PP = std::pair<int, int>;

#define MAX_N 1000000
#define MAX_M 1000000

int N = 5;
int M = 3;
int A[MAX_N] = {8, 4, 3, 2, 2}; // left memory
int B[MAX_M] = {3, 2, 2}; // data to be allocated.
// answer is count of data to be able to allocated.

int slot[32];
int data_slot[32];
int solve_ljw(){
    for (int i = 0; i < 32; i++){
        slot[i] = 0;
        data_slot[i] = 0;
    }
    for (int i = 0; i < N; i++){
        int mem = A[i];
        int cnt = 0;
        while(mem > 0){
            int empty = mem & 1;
            if (empty > 0){
                slot[cnt]++;
            }
            mem = mem >> 1;
            cnt++;
        }
    }
    for (int i = 0; i < M; i++){
        data_slot[B[i]]++;
    }
    int ans = 0;
    for (int i = 0; i < 32; i++){
        int j = 0;
        while(data_slot[i] != 0){
            data_slot[i]--;
            j = i;
            while(j < 32 && slot[j] == 0){
                slot[j++]++;
            }
            if (j == 32) break;
            slot[j]--;
            ans++;
        }
        if (j == 32) break;
    }
    return ans;
}

int main(){

    cin >> N >> M;
    for (int i = 0; i < N; i++){
        cin >> A[i];
    }
    for (int i = 0; i < M; i++){
        cin >> B[i];
    }

    printf("%d\n", solve_ljw());
}


#include <bits/stdc++.h>
using namespace std;
using PP = std::pair<int, int>;

#define MAX_N 1000000
#define MAX_M 1000000

int N = 5;
int M = 3;
int A[MAX_N] = {8, 4, 3, 2, 2}; // left memory
int B[MAX_M] = {3, 2, 2}; // data to be allocated.
// answer is count of data to be able to allocated.

int slot[32];
int data_slot[32];
int solve_ljw(){
    for (int i = 0; i < 32; i++){
        slot[i] = 0;
        data_slot[i] = 0;
    }
    for (int i = 0; i < N; i++){
        int mem = A[i];
        int cnt = 0;
        while(mem > 0){
            int empty = mem & 1;
            if (empty > 0){
                slot[cnt]++;
            }
            mem = mem >> 1;
            cnt++;
        }
    }
    for (int i = 0; i < M; i++){
        data_slot[B[i]]++;
    }
    int ans = 0;
    for (int i = 0; i < 32; i++){
        int j = 0;
        while(data_slot[i] != 0){
            data_slot[i]--;
            j = i;
            while(j < 32 && slot[j] == 0){
                slot[j++]++;
            }
            if (j == 32) break;
            slot[j]--;
            ans++;
        }
        if (j == 32) break;
    }
    return ans;
}

int main(){
    scanf("%d %d", &N, &M);
    for (int i = 0; i < N; i++){
        scanf("%d", &A[i]);
    }
    for (int i = 0; i < M; i++){
        scanf("%d", &B[i]);
    }

    printf("%d\n", solve_ljw());
}


#include <bits/stdc++.h>
using namespace std;
using PP = std::pair<int, int>;

#define MAX_N 1000000
#define MAX_M 1000000

int N = 5;
int M = 3;
int A[MAX_N] = {8, 4, 3, 2, 2}; // left memory
int B[MAX_N] = {3, 2, 2}; // data to be allocated.
// answer is count of data to be able to allocated.

int slot[32];
int solve_ljw(){
    for (int i = 0; i < 32; i++){
        slot[i] = 0;
    }
    for (int i = 0; i < N; i++){
        int mem = A[i];
        int cnt = 0;
        while(mem > 0){
            int empty = mem & 1;
            if (empty > 0){
                slot[cnt]++;
            }
            mem = mem >> 1;
            cnt++;
        }
    }
    int ans = 0;
    for (int i = 0; i < M; i++){
        if (slot[B[i]] > 0){
            slot[B[i]]--;
            ans++;
        }
    }
    return ans;
}

int main(){
    cin >> N >> M;
    for (int i = 0; i < N; i++){
        cin >> A[i];
    }
    for (int i = 0; i < M; i++){
        cin >> B[i];
    }
    printf("%d\n", solve_ljw());
}


#include <bits/stdc++.h>
#define MAXN 1001000
#define pii pair<int, int>
#define pb push_back
typedef long long ll;

using namespace std;

int n, m, A[MAXN], b[MAXN], a[MAXN], f[40], F[40];

bool check(int x){
	for(int i = 0; i < 40; i++){
		a[i] = F[i];
	}
	for(int i = 0; i < 33; i++)
		f[i] = 0;
	for(int i = 0; i < x; i++){
		f[b[i]]++;
	}
	for(int i = 0; i < 32; i++){
		int t = min(a[i], f[i]);
		a[i] -= t;
		f[i] -= t;
		f[i + 1] += (1 + f[i]) / 2;
		f[i] = 0;
	}
	for(int i = 0; i < 33; i++){
		if(f[i] > 0) return false;
	}
	return true;
}

int main(){
    #ifndef ONLINE_JUDGE
		freopen("input.txt", "r", stdin);
	#endif
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
    cin >> n >> m;
    for(int i = 0; i < n; i++) cin >> A[i];
    for(int i = 0; i < m; i++) cin >> b[i];
    for(int i = 0; i < n; i++){
    	for(int j = 0; j < 33; j++){
    		if(A[i] & (1 << j)) F[j]++;
    	}
    }
    sort(b, b + m);
    int l = 0, r = m;
	while(l < r){
		int mid = (l + r) / 2;
		if(check(mid)) l = mid + 1;
		else r = mid;
	}
	//cout << check(3);
	if(check(l)) cout << l;
	else cout << l - 1;
}


#include <bits/stdc++.h>
#define MAXN 1001000
#define pii pair<int, int>
#define pb push_back
typedef long long ll;

using namespace std;

int n, m, a[MAXN], b[MAXN];

bool check(int x){
	multiset<int> s;
	for(int i = 0; i < n; i++) s.insert(a[i]);
	for(int i = x - 1; i >= 0; i--){
		int t = *--s.end();
		//cout << b[i];
		if(t < b[i]) return false;
		s.erase(--s.end());
		t -= b[i];
		s.insert(t);
	}
	return true;
}

int main(){
    #ifndef ONLINE_JUDGE
		freopen("input.txt", "r", stdin);
	#endif
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
    cin >> n >> m;
    for(int i = 0; i < n; i++) cin >> a[i];
    for(int i = 0; i < m; i++) cin >> b[i];
    sort(b, b + m);
    for(int i = 0; i < m; i++) b[i] = (1 << b[i]);
    int l = 0, r = m;
	while(l < r){
		int mid = (l + r) / 2;
		if(check(mid)) l = mid + 1;
		else mid = r;
	}
	if(check(l)) cout << l;
	else cout << l - 1;
}


#include <bits/stdc++.h>
#define MAXN 1001000
#define pii pair<int, int>
#define pb push_back
typedef long long ll;

using namespace std;

int n, m, A[MAXN], b[MAXN], a[MAXN], f[40];

bool check(int x){
	for(int i = 0; i < n; i++){
		a[i] = A[i];
	}
	for(int i = 0; i < 33; i++)
		f[i] = 0;
	for(int i = 0; i < x; i++){
		f[b[i]]++;
	}
	for(int i = 0; i < 33; i++){
		for(int j = 0; j < n; j++){
			if(f[i] == 0) break;
			if(a[j] & (1 << i)){
				f[i]--;
				a[j] -= (1 << i);
			}
		}
		f[i + 1] += f[i] / 2;
		f[i] %= 2;
	}
	for(int i = 32; i >= 0; i--){
		if(f[i] > 0){
			for(int j = 0; j < n; j++){
				if(f[i] == 0) break;
				int t = a[j] / (1 << i);
				f[i] -= t;
				a[j] -= t * (1 << i);
				if(f[i] == 0) break;
			}
		}
		if(f[i] > 0) return false;
	}
	return true;
}

int main(){
    #ifndef ONLINE_JUDGE
		freopen("input.txt", "r", stdin);
	#endif
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
    cin >> n >> m;
    for(int i = 0; i < n; i++) cin >> A[i];
    for(int i = 0; i < m; i++) cin >> b[i];
    sort(b, b + m);
    int l = 0, r = m;
	while(l < r){
		int mid = (l + r) / 2;
		if(check(mid)) l = mid + 1;
		else r = mid;
	}
	if(check(l)) cout << l;
	else cout << l - 1;
}


#include <bits/stdc++.h>
#define MAXN 1001000
#define pii pair<int, int>
#define pb push_back
typedef long long ll;

using namespace std;

int n, m, A[MAXN], b[MAXN], a[MAXN], f[40], F[40];

bool check(int x){
	for(int i = 0; i < 40; i++){
		a[i] = F[i];
	}
	for(int i = 0; i < 33; i++)
		f[i] = 0;
	for(int i = 0; i < x; i++){
		f[b[i]]++;
	}
	for(int i = 0; i < 32; i++){
		int t = min(a[i], f[i]);
		a[i] -= t;
		f[i] -= t;
		f[i + 1] += (1 + f[i]) / 2;
		f[i] = 0;
	}
	for(int i = 0; i < 33; i++){
		if(f[i] > 0) return false;
	}
	return true;
}

int main(){
    #ifndef ONLINE_JUDGE
		freopen("input.txt", "r", stdin);
	#endif
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
    cin >> n >> m;
    for(int i = 0; i < n; i++) cin >> A[i];
    for(int i = 0; i < m; i++) cin >> b[i];
    for(int i = 0; i < n; i++){
    	for(int j = 0; j < 33; j++){
    		if(A[i] & 1) F[j]++;
    		A[i] = A[i] >> 1;
    	}
    }
    sort(b, b + m);
    int l = 0, r = m;
	while(l < r){
		int mid = (l + r) / 2;
		if(check(mid)) l = mid + 1;
		else r = mid;
	}
	//cout << check(3);
	if(check(l)) cout << l;
	else cout << l - 1;
}


#include <bits/stdc++.h>
#define MAXN 1001000
#define pii pair<int, int>
#define pb push_back
typedef long long ll;

using namespace std;

int n, m, A[MAXN], b[MAXN], a[MAXN], f[MAXN];

bool check(int x){
	for(int i = 0; i < n; i++){
		a[i] = A[i];
	}
	for(int i = 0; i < 33; i++)
		f[i] = 0;
	for(int i = 0; i < x; i++){
		f[b[i]]++;
	}
	for(int i = 0; i < 33; i++){
		for(int j = 0; j < n; j++){
			if(a[j] & (1 << i) and f[i] > 0){
				f[i]--;
				a[j] ^= (1 << i);
			}
		}
		f[i + 1] += f[i] / 2;
		f[i] %= 2;
	}
	for(int i = 32; i >= 0; i--){
		if(f[i] > 0){
			for(int j = 0; j < n; j++){
				while(f[i] > 0 and a[j] >= (1 << i)){
					j -= (1 << i);
					f[i]--;
				}
			}
		}
		if(f[i] > 0) return false;
	}
	return true;
}

int main(){
    #ifndef ONLINE_JUDGE
		freopen("input.txt", "r", stdin);
	#endif
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
    cin >> n >> m;
    for(int i = 0; i < n; i++) cin >> A[i];
    for(int i = 0; i < m; i++) cin >> b[i];
    sort(b, b + m);
    int l = 0, r = m;
	while(l < r){
		int mid = (l + r) / 2;
		if(check(mid)) l = mid + 1;
		else mid = r;
	}
	if(check(l)) cout << l;
	else cout << l - 1;
}


#include <bits/stdc++.h>
#define MAXN 1001000
#define pii pair<int, int>
#define pb push_back
typedef long long ll;

using namespace std;

int n, m, A[MAXN], b[MAXN], a[MAXN], f[MAXN];

bool check(int x){
	for(int i = 0; i < n; i++){
		a[i] = A[i];
	}
	for(int i = 0; i < 33; i++)
		f[i] = 0;
	for(int i = 0; i < x; i++){
		f[b[i]]++;
	}
	for(int i = 0; i < 33; i++){
		for(int j = 0; j < n; j++){
			if(f[i] == 0) break;
			if(a[j] & (1 << i)){
				f[i]--;
				a[j] ^= (1 << i);
			}
		}
		f[i + 1] += f[i] / 2;
		f[i] %= 2;
	}
	for(int i = 32; i >= 0; i--){
		if(f[i] > 0){
			for(int j = 0; j < n; j++){
				while(f[i] > 0 and a[j] >= (1 << i)){
					j -= (1 << i);
					f[i]--;
				}
				if(f[i] == 0) break;
			}
		}
		if(f[i] > 0) return false;
	}
	return true;
}

int main(){
    #ifndef ONLINE_JUDGE
		freopen("input.txt", "r", stdin);
	#endif
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
    cin >> n >> m;
    for(int i = 0; i < n; i++) cin >> A[i];
    for(int i = 0; i < m; i++) cin >> b[i];
    sort(b, b + m);
    int l = 0, r = m;
	while(l < r){
		int mid = (l + r) / 2;
		if(check(mid)) l = mid + 1;
		else r = mid;
	}
	if(check(l)) cout << l;
	else cout << l - 1;
}


#include <bits/stdc++.h>
#define MAXN 1001000
#define pii pair<int, int>
#define pb push_back
typedef long long ll;

using namespace std;

int n, m, A[MAXN], b[MAXN], a[MAXN], f[MAXN];

bool check(int x){
	for(int i = 0; i < n; i++){
		a[i] = A[i];
	}
	for(int i = 0; i < 33; i++)
		f[i] = 0;
	for(int i = 0; i < x; i++){
		f[b[i]]++;
	}
	for(int i = 0; i < 33; i++){
		for(int j = 0; j < n; j++){
			if(a[j] & (1 << i) and f[i] > 0){
				f[i]--;
				a[j] ^= (1 << i);
			}
		}
		f[i + 1] += f[i] / 2;
		f[i] %= 2;
	}
	for(int i = 32; i >= 0; i--){
		if(f[i] > 0){
			for(int j = 0; j < n; j++){
				while(f[i] > 0 and a[j] >= (1 << i)){
					j -= (1 << i);
					f[i]--;
				}
			}
		}
		if(f[i] > 0) return false;
	}
	return true;
}

int main(){
    #ifndef ONLINE_JUDGE
		freopen("input.txt", "r", stdin);
	#endif
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
    cin >> n >> m;
    for(int i = 0; i < n; i++) cin >> A[i];
    for(int i = 0; i < m; i++) cin >> b[i];
    sort(b, b + m);
    int l = 0, r = m;
	while(l < r){
		int mid = (l + r) / 2;
		if(check(mid)) l = mid + 1;
		else r = mid;
	}
	if(check(l)) cout << l;
	else cout << l - 1;
}


#include <bits/stdc++.h>
#define MAXN 1001000
#define pii pair<int, int>
#define pb push_back
typedef long long ll;

using namespace std;

int n, m, A[40], b[MAXN], a[MAXN], f[40], F[40];

bool check(int x){
	for(int i = 0; i < 40; i++){
		a[i] = F[i];
	}
	for(int i = 0; i < 33; i++)
		f[i] = 0;
	for(int i = 0; i < x; i++){
		f[b[i]]++;
	}
	for(int i = 0; i < 32; i++){
		int t = min(a[i], f[i]);
		a[i] -= t;
		f[i] -= t;
		f[i + 1] += (1 + f[i]) / 2;
		f[i] = 0;
	}
	for(int i = 0; i < 33; i++){
		if(f[i] > 0) return false;
	}
	return true;
}

int main(){
    #ifndef ONLINE_JUDGE
		freopen("input.txt", "r", stdin);
	#endif
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
    cin >> n >> m;
    for(int i = 0; i < n; i++) cin >> A[i];
    for(int i = 0; i < m; i++) cin >> b[i];
    for(int i = 0; i < n; i++){
    	for(int j = 0; j < 33; j++){
    		if(A[i] & (1 << j)) F[j]++;
    	}
    }
    sort(b, b + m);
    int l = 0, r = m;
	while(l < r){
		int mid = (l + r) / 2;
		if(check(mid)) l = mid + 1;
		else r = mid;
	}
	//cout << check(3);
	if(check(l)) cout << l;
	else cout << l - 1;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef double db;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define rep(i,l,r) for(int i=(l);i<(r);++i)
#define per(i,l,r) for(int i=(r)-1;i>=(l);--i)
#define dd(x) cout << #x << " = " << x << ", "
#define de(x) cout << #x << " = " << x << endl
//-------
const int N = 1e6 + 7;
const int M = 30;
int n, m, c[2][M];
int main() {
        scanf("%d%d", &n, &m);
        rep(i, 0, n) {
                int ai; scanf("%d", &ai);
                rep(j, 0, M) if (ai >> j & 1) ++c[0][j];
        }
        rep(i, 0, m) {
                int bi; scanf("%d", &bi);
                ++c[1][bi];
        }
        per(i, 0, M) {
                while (c[0][i] > 0) {
                        int v = 1 << i;
                        per(j, 0, i) if (c[0][j] < c[1][j]) {
                                int x = min(v >> j, c[1][j] - c[0][j]);
                                c[0][j] += x, v -= x << j;
                        }
                        if (v >> i) break;
                        --c[0][i];
                }
        }
        int ans = 0;
        rep(i, 0, M) ans += min(c[0][i], c[1][i]);
        printf("%d\n", ans);
        return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef double db;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define rep(i,l,r) for(int i=(l);i<(r);++i)
#define per(i,l,r) for(int i=(r)-1;i>=(l);--i)
#define dd(x) cout << #x << " = " << x << ", "
#define de(x) cout << #x << " = " << x << endl
//-------
const int N = 1e6 + 7;
int n, m, b[N];
priority_queue<int> Q;
int main() {
        scanf("%d%d", &n, &m);
        rep(i, 0, n) {
                int ai; scanf("%d", &ai);
                Q.push(-ai);
        }
        rep(i, 0, m) scanf("%d", b + i);
        sort(b, b + m);
        int ans = 0;
        rep(i, 0, m) {
                while (!Q.empty() && -Q.top() < (1 << b[i])) Q.pop();
                if (Q.empty()) break;
                int ai = -Q.top(); Q.pop();
                ++ans, Q.push(-(ai - (1 << b[i])));
        }
        printf("%d\n", ans);
        return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef double db;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define rep(i,l,r) for(int i=(l);i<(r);++i)
#define per(i,l,r) for(int i=(r)-1;i>=(l);--i)
#define dd(x) cout << #x << " = " << x << ", "
#define de(x) cout << #x << " = " << x << endl
//-------
const int N = 1e6 + 7;
const int M = 30;
int n, m, c[2][M];
int main() {
        scanf("%d%d", &n, &m);
        rep(i, 0, n) {
                int ai; scanf("%d", &ai);
                rep(j, 0, M) if (ai >> j & 1) ++c[0][j];
        }
        rep(i, 0, m) {
                int bi; scanf("%d", &bi);
                ++c[1][bi];
        }
        int ans = 0;
        per(i, 0, M) {
                int v = 0;
                rep(j, 0, i) v = max(v, c[1][j] - c[0][j]);
                v = min(v, c[0][i]);
                c[0][i] -= v;
                rep(j, 0, i) c[0][j] += v;
                ans += min(c[0][i], c[1][i]);
        }
        printf("%d\n", ans);
        return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef double db;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define rep(i,l,r) for(int i=(l);i<(r);++i)
#define per(i,l,r) for(int i=(r)-1;i>=(l);--i)
#define dd(x) cout << #x << " = " << x << ", "
#define de(x) cout << #x << " = " << x << endl
//-------
const int N = 1e6 + 7;
const int M = 30;
int n, m, a[M], b[N];
int main() {
        scanf("%d%d", &n, &m);
        rep(i, 0, n) {
                int x; scanf("%d", &x);
                rep(j, 0, M) if (x >> j & 1)
                        ++a[j];
        }
        rep(i, 0, m) scanf("%d", b + i);
        sort(b, b + m);
        int ans = 0;
        rep(i, 0, m) {
                rep(j, b[i], M) if (a[j] > 0) {
                        ++ans, --a[j];
                        int v = (1 << j) - (1 << b[i]);
                        rep(k, 0, j) if (v >> k & 1)
                                ++a[k];
                        break;
                }
        }
        printf("%d", ans);
        return 0;
}


#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define ll long long
#define F first
#define S second
#define P pair
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define V vector
#define RE return
#define ALL(a) a.begin(),a.end()
#define MP make_pair
#define PB push_back
#define PF push_front
#define FILL(a,b) memset(a,b,sizeof(a))
using namespace std;
int a[40],b[1000005];
int main(){
	ios::sync_with_stdio(0);
    cin.tie(0);
	int n,m,x;
	cin>>n>>m;
	FOR(i,1,n){
		cin>>x;
		int t=1;
		FOR(j,0,29){
			if(x&t)a[j]++;
			t*=2;
		}
	}
	FOR(i,1,m){
		cin>>b[i];
	}
	sort(b+1,b+m+1);
	FOR(i,1,m){
		bool f=0;
		FOR(j,b[i],29){
			if(a[j]){
				a[j]--;
				for(int k=b[i];k<j;k++)a[k]++;
				f=1;break;
			}
		}
		if(!f){
			cout<<i-1;RE 0;
		}
	}
	cout<<m;
	RE 0;
}