#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#define ll long long
#define bp  __builtin_popcount
#define pb push_back
#define sz(s) (int)(s.size())

using namespace std;
using namespace __gnu_pbds;
typedef tree<int,null_type,less<int>,rb_tree_tag, tree_order_statistics_node_update> indexed_set;
const int maxn=1e6+5;
const  double EPS = 1e-14;
const int MOD = 1e9+7;

/*
ll xo,yo,z;
void extend_euclidean(ll a,ll b)
{	ll temp;
	if(b==0)
	{
		z=a;
		xo=1;
		yo=0;
	}
	else
	{
		extend_euclidean(b,a%b);
		temp=xo;
		xo=yo;
		yo=temp-(a/b)*yo;
	}
return;
}



//     O(sqrtn)

vector<ll> factorize(ll n) {
    vector<ll> res;
    for (ll i = 2; i * i <= n; ++i) {
        while (n % i == 0) {
            res.push_back(i);
            n /= i;
        }
    }
    if (n != 1) {
        res.push_back(n);
    }
    return res;
}

*************FACTORIZE IN 0(LOG(N)) PROVIDED N IS INTEGER**************

int minPrime[100000];

void modified_sieve(int n){
for (int i = 2; i * i <= n; ++i) {
    if (minPrime[i] == 0) {         //If i is prime
        for (int j = i * i; j <= n; j += i) {
            if (minPrime[j] == 0) {
                minPrime[j] = i;
            }
        }
    }
}
for (int i = 2; i <= n; ++i) {
    if (minPrime[i] == 0) {
        minPrime[i] = i;
    }
}


vector<int> factorize(int n) {
    vector<int> res;
    while (n != 1) {
        res.push_back(minPrime[n]);
        n /= minPrime[n];
    }
    return res;
}

*************************************************
bool isPrime[maxn];   o(n log(log(n)))
void sieve()
{
    memset(isPrime,true,maxn);
    isPrime[0] = false;
    isPrime[1] = false;
    for(int i = 2; i * i <= maxn ; ++i)
    {
        if(isPrime[i])
        {
            for(int j = i * 2; j <= maxn ; j += i)
                isPrime[j] = false;
        }
    }
}

ll binomialCoeff(ll n, ll k)
{
    ll res = 1;
    if(n<k)
        return 0;

    // Since C(n, k) = C(n, n-k)
    if ( k > n - k )
        k = n - k;

    // Calculate value of
    // [n * (n-1) *---* (n-k+1)] / [k * (k-1) *----* 1]
    for (ll i = 0; i < k; ++i)
    {
        res *= (n - i);
        res /= (i + 1);
    }

    return res;
}
***********************************************************
sieve with linear time complexity o(n)
void faster_sieve(int N)
{
  int lp[N+1];
  vector<int> pr;
  for (int i=2; i<=N; ++i)
   {
     if (lp[i] == 0)
     {
        lp[i] = i;
        pr.push_back (i);
     }
     for(int j=0; j<(int)pr.size() && pr[j]<=lp[i] && i*pr[j]<=N; ++j)
        lp[i * pr[j]] = pr[j];
   }
}
******************************************************************************
faster factorize
vector<long long> factorization(int N){
    while (n % 2 == 0) {
        factorization.push_back(2);
        n /= 2;
    }
    for (long long d = 3; d * d <= n; d += 2) {
        while (n % d == 0) {
            factorization.push_back(d);
            n /= d;
        }
    }
    if (n > 1)
        factorization.push_back(n);
    return factorization;
}

ll GCD(ll a,ll b){return (a)?GCD(b%a,a):b;}
ll LCM(ll a, ll b){return a*b/GCD(a,b);}
ll fastpow(ll b, ll p){if(!p)return 1;ll ret = fastpow(b, p >> 1);ret *= ret;if(p&1)ret*= b;return ret;}
*/
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
#ifndef ONLINE_JUDGE
   // freopen("in.txt", "r", stdin);
#endif
    ll n,m;
    cin >> n >> m;
	ll ans = min(n,m/2);
	m -= ans * 2;
	ans += m/4;
	cout << ans << endl;
}


Measured memory_bytes: 256