#include<iostream>
long long d, p, h;
void add(long long e1, long long e2, long long to)
{
	std::cout << "+ " << e1 << " " << e2 << " " << to << std::endl;
}

void power(long long e1, long long to)
{
	std::cout << "^ " << e1 << " " << to << std::endl;
}

void multiply(long long position1, long long x, long long targetposition)
{
	x = x % p;
	if (x <= 1) x = x + p;
	long long v = x;
	v = v / 2;
	add(position1, position1, targetposition);
	while (v % 2 == 0)
	{
		add(targetposition, targetposition, targetposition);
		v = v / 2;
	}
	add(targetposition, targetposition, 4);
	if (x % 2 == 1)
		add(targetposition, position1, targetposition);
	v = v / 2;
	while (v != 0)
	{
		if (v % 2 == 1)
			add(targetposition, 4, targetposition);
		if (v / 2 != 0) add(4, 4, 4);
		v = v / 2;
	}
}

void Minus(long long e1, long long e2, long long to)
{
	multiply(e2, p - 1, to);
	add(e1, to, to);
}

long long valuepower(long long x,long long z)
{
	long long i, y = 1;
	for (i = 1; i <= z; i++)
		y = y * x;
	return (y) % p;
}

long long c(long long x, long long y)
{
	long long i, j = 1, k = 1;
	for (i = 1; i <= y; i++)
		j = j * i;
	for (i = x - y + 1; i <= x; i++)
		k = k * i;
	return (k / j) % p;
}

void become1(long long x, long long position)
{
	long long v, o;
	x = x % p;
	if (x < 0) x = x + p;
	if (x != 0)
	{
		v = 1;
		while (x != 1)
		{
			v = (v * (p / x) + v) % p;
			x = (x * (p / x) + x) % p;
		}
		v = v % p;
		multiply(position,v,40);
		multiply(40, 1, position);
	}
}

void special(long long x, long long position1, long long position2, long long target)
{
	add(x, position1, 5);
	power(5, 5);
	add(x, position2, 6);
	power(6, 6);
	if (d % 2==0)
		add(5, 6, target);
	else
		Minus(5, 6, target);
}

void getsquare()
{
	if (d == 2)
	{
		power(1, 7);
		power(2, 8);
		add(7, 8, 7);
		power(3, 8);
		h = 1;
		multiply(7, p - 1, 9);
		add(8, 9, 8);
		multiply(8, (p + 1) / 2, 9);
	}
	else if (d == 3)
	{
		multiply(10, -1, 11);
		special(1, 10, 11, 12);
		special(2, 10, 11, 13);
		add(12, 13, 7);
		special(3, 10, 11, 12);
		multiply(10, -4, 11);
		add(7, 11, 7);
		multiply(10, -2, 11);
		add(12, 11, 8);
		h = 6;
		multiply(7, p - 1, 9);
		add(8, 9, 8);
		multiply(8, (p + 1) / 2, 9);
	}
	else
	{
		long long t = (d - 1) / 2, i, j;
		for (i = 11; i <= 9 + t; i++)
			add(10, i - 1, i);
		multiply(10, -t, 14 + t);
		for (i = 13 + t; i >= 15; i--)
			add(i + 1, 10, i);
		for (i = 1; i <= t; i++)
		{
			special(2, 9 + i, 14 + i, 19);
			special(1, 9 + i, 14 + i, 20 + i);
			add(19, 20 + i, 20 + i);
			special(3, 9 + i, 14 + i, 30 + i);
			multiply(20 + i, - 1, 40 + i);
			add(40 + i, 30 + i, 20 + i);
		}
		if (d % 2 == 0)
		{
			power(1, 20);
			power(2, 19);
			add(20, 19, 20);
			multiply(20, -1, 19);
			power(3, 30);
			add(19, 30, 20);
			for (i = 1; i <= t; i++)
			{
				multiply(20, -2, 30);
				add(30, 20 + i, 20 + i);
			}
		}
		for (i = 1; i <= t; i++)
		{
			power(9 + i, 30);
			add(30, 20 + i, 20 + i);
			add(30, 20 + i, 20 + i);
		}
		if (t == 1)
		{
			h = 12;
			multiply(21, (p + 1) / 2, 9);
		}
		if (t == 2)
		{
			multiply(21, -valuepower(2, d - 4), 31);
			add(31, 22, 31);
			h = valuepower(2, d - 1)*c(d, 2) - valuepower(2, d - 3)*c(d, 2);
			multiply(31, (p + 1) / 2, 9);
		}
		if (t == 3)
		{
			long long u = valuepower(2, d - 6);
			long long v = valuepower(3, d - 6);
			multiply(21, -u, 31);
			add(31, 22, 22);
			multiply(21, -v, 31);
			add(31, 23, 23);
			long long a1 = valuepower(2, d - 4), a2 = valuepower(2, d - 2), a3 = valuepower(3, d - 4), a4 = valuepower(3, d - 2);
			multiply(22, a3 - v, 31);
			multiply(23, u - a1, 32);
			add(31, 32, 22);
			multiply(22, (p + 1) / 2, 9);
			h = 2 * ((a2 - u)*(a3 - v) + (a4 - v)*(u - a1))*c(d, 2);
		}
		if (t == 4)
		{
			long long a[10][10];
			for (i = 1; i <= 4; i++)
				for (j = 1; j <= 4; j++)
					a[j][i] = valuepower(j, d - 2 * i);
			for (i = 2; i <= 4; i++)
			{
				multiply(21, -a[i][4], 30);
				add(30, 20 + i, 20 + i);
			}
			for (i = 2; i <= 4; i++)
				for (j = 1; j <= 3; j++)
					a[i][j] = a[i][j] - a[i][4];
			for (i = 3; i <= 4; i++)
			{
				multiply(22, a[i][3], 30);
				multiply(20 + i, -a[2][3], 31);
				add(30, 31, 20 + i);
				for (j = 1; j <= 2; j++)
					a[i][j] = a[2][j] * a[i][3] - a[2][3] * a[i][j];
			}
			multiply(23, a[4][2], 30);
			multiply(24, -a[3][2], 31);
			add(30, 31, 24);
			a[4][1] = a[3][1] * a[4][2] - a[3][2] * a[4][1];
			h = a[4][1] * 2 * c(d, 2);
			multiply(24, (p + 1) / 2, 9);
		}
	}
}
int main()
{
	using namespace std;
	cin >> d >> p;
	add(1, 2, 3);
	long long i;
	getsquare();
	become1(h, 9);
	cout << "f " << 9 << endl;
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
const int MAXN = 100 + 10;

int d, p;
void print_add(int a, int b, int c) {
  printf("+ %d %d %d\n", a, b, c);
}
void print_pwr(int a, int b) {
  printf("^ %d %d\n", a, b);
}
int x = 1, y = 2, one = 3, mone = 4, cur = 4;
int choose[MAXN][MAXN];
int print_mul(int x, int y) { // a[x] * y
  int ans = ++cur;
  print_add(ans, mone, ans);
  for (; y; y >>= 1, print_add(x, x, x)) {
    if (y & 1) print_add(ans, x, ans);
  }
  return ans;
}
int work(int a, int b, int c) {
  int ans = ++cur;
  print_add(ans, mone, ans);
  if (a) print_add(x, ans, ans);
  if (b) print_add(y, ans, ans);
  for (int i = 1; i <= c; i++) print_add(ans, one, ans);
  print_pwr(ans, ans);
  return ans;
}
int pwr(int x, int y) {
  int ans = 1;
  for (; y; y >>= 1, x = 1ll * x * x % p) {
    if (y & 1) ans = 1ll * ans * x % p;
  }
  return ans;
}
int main() {
  scanf("%d%d", &d, &p);

  choose[0][0] = 1;
  for (int i = 1; i <= d; i++) {
    choose[i][0] = choose[i][i] = 1;
    for (int j = 1; j < i; j++) {
      choose[i][j] = choose[i - 1][j] + choose[i - 1][j - 1];
    }
  }

  int ans = ++cur;

  mone = print_mul(++cur, p - 3);
  print_add(ans, mone, ans);
  //fprintf(stderr, "%d --\n", mone);
  for (int i = 0; i <= 1; i++) {
    for (int j = 0; j <= 1; j++) {
      for (int k = 0; k <= d - 2; k++) {
        int pos = work(i, j, k);
        int t = choose[d - 2][k];
        if ((d - (i + j + k)) & 1) {
          t = p - t;
        }
        int o = print_mul(pos, t);
        print_add(ans, o, ans);
        //fprintf(stderr, "%d %d %d %d %d %d--\n", i, j, k, pos, t, o);
      }
    }
  }

  int fact = 1;
  for (int i = 1; i <= d; i++) fact = fact * i % p;
  fact = pwr(fact, p - 2);
  printf("f %d\n", print_mul(ans, fact));

}


#include<iostream>
#include<vector>
#include<sstream>
#include<algorithm>
#include<numeric>
#include<cstdlib>
#include<cmath>
#include<complex>
#include<set>
#include<map>
#include<queue>
#include<cassert>

using namespace std;

#define rep(i,n) for(int i=0;i<n;i++)
#define rp(i,c) rep(i,(c).size())
#define fr(i,c) for(__typeof((c).begin()) i=(c).begin();i!=(c).end();i++)
#define pb push_back
#define mp make_pair
#define all(c) (c).begin(),(c).end()
#define dbg(x) cerr<<#x<<" = "<<(x)<<endl

typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int,int> pi;
typedef long long ll;

const int inf=1<<28;
const double INF=1e12,EPS=1e-9;

void run()
{
	int l,r; cin>>l>>r;
	string a,b; char s[20];
	sprintf(s,"%d",l); a=s;
	sprintf(s,"%d",r); b=s;

	int m=5,nine=9;
	rep(i,b.size()-1)m*=10, nine*=10,nine+=9;

	if(m-1<=r){
		cout<<(m-1ll)*(nine-m+1)<<endl; return;
	}
	cout<<(nine-r)*ll(r)<<endl;
}

int main()
{
	//int cs=3;rep(i,cs)
	run();
}


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

   int l,r,t;
   long long re;

   int main()
   {
    cin >> l >> r;
    t=9;
    while (t<r) t=t*10+9;
    re=1LL*r*(t-r);
    re=max(re,1LL*l*(t-l));
    t/=2;
    if (r>=t) re=max(re,t*(t+1));
    cout << re << endl;
    return 0;
   }


g`"#include <algorithm>
#include <iostream>
using namespace std;
int dec_bits( long long num ){
	int b = 0;
	for(; num; num /= 10, b++ );
	return b;
}
long long dec_pow( int pow ){
	long long val = 1;
	for(; pow; pow --, val *= 10 );
	return val;
}
long long weight( long long num ){
	return ( ( ( dec_pow( dec_bits( num ) )-1 )-num) * num );
}
int main(){
	long long l, r, mid;
	cin >> l >> r;
	mid = (dec_pow( dec_bits( r ) )-1)/2;
	if( l < mid && mid < r ){
		cout << weight( mid ) << endl;
	}else{
		cout << max( weight(l), weight(r) ) << endl;
	}
	return 0;
}
/****** PCCA -Wed Aug 03 02:50:15 GMT 2011 *******/


#include<iostream>
#include<string>
using namespace std;

long long  ref(string a)
{
	long long r = 0 ;

	for(int i = 0 ; i < a.size() ; ++i )
	{
		r *= 10;
		r += (long long)(9 - (a[i]-'0'));

	}
//	cout<<r<<' '<<a<<endl;

	return r* (long long )atoi(a.c_str());

}

int main()
{

	string l,r,mmid;
	int ll,rr,mid=0;

	cin>>l>>r;

	ll = atoi(l.c_str());
	rr = atoi(r.c_str());

	for(int i = 0 ; i < r.size() ; ++i )
	{
		mid *= 10 ;
		mid += 9;

		mmid.push_back('9');
	}
	mmid[0]  = '4';

	mid /= 2;

//	cout<<mmid<<' '<<mid<<endl;

	if(  l.size() < r.size() )
	{
		if( rr < mid)
			cout<<ref(r)<<endl;
		else	cout<<ref(mmid)<<endl;
	}
	else
	{
		if( rr < mid )
		{
			cout<<ref(r)<<endl;
		}
		else if( ll > mid )
		{
			cout<<ref(l)<<endl;
		}
		else
		{
			cout<<ref(mmid)<<endl;
		}
	}

}


#include <bits/stdc++.h>
using namespace std
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
#define mp make_pair

ull INF;
ull MOD;
ull add(ull x, ull y) {
	x += y;
	if (x >= MOD) return x - MOD;
	return x;
}
ull sub(ull x, ull y) {
	if (x < y) x += MOD;
	return x - y;
}
ull mult(ull x, ull y) {
	return (x * y) % MOD;
}

const int N = 222;
ull C[N][N];
int d;
ull a[N];
ull b[N][N];
ull dp[N][N];

ull solve(int n) {
	for (int i = 0; i <= min(n - 1, d); i++)
		for (int j = 0; j < n; j++)
			dp[i][j] = 0;
	dp[0][n - 1] = 1 % MOD;
	for (int i = 0; i < min(n - 1, d); i++)
		for (int x = 0; x < n; x++) {
			dp[i][x] %= MOD;
			if (dp[i][x] == 0) continue;
			for (int y = 1; y <= x; y++) {
				dp[i + 1][x - y] += dp[i][x] * ((a[y] * C[x - 1][y - 1]) % MOD) % MOD;
			}
		}
	ull res = 0;
	for (int i = 0; i <= min(n - 1, d); i++) {
		b[n][i] = dp[i][0] % MOD;
		res += dp[i][0] % MOD;
	}
	return res % MOD;
}

int main()
{
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int n;
	scanf("%d%d%llu", &n, &d, &MOD);
	if (n == 1) {
		throw;
		printf("0\n");
		return 0;
	}
	if (n == 2) {
		ull ans = 4;
		printf("%llu\n", ans % MOD);
		return 0;
	}
	if (d == 1) {
		printf("0\n");
		return 0;
	}

	d--;
	for (int i = 0; i < N; i++)
		C[i][0] = C[i][i] = 1 % MOD;
	for (int i = 1; i < N; i++)
		for (int j = 1; j < i; j++)
			C[i][j] = add(C[i - 1][j - 1], C[i - 1][j]);
	a[0] = 1 % MOD;
	for (int i = 1; i < n; i++)
		a[i] = solve(i);
	d++;
	a[n] = solve(n);

	ull ans = sub(a[n], b[n][1]);
	ans = add(ans, ans);

	for (int x = 1; x < n - 1; x++) {
		ull sum = 0;
		for (int i = 2; i <= d - 2; i++)
			sum = add(sum, b[n - x][i]);
		for (int i = 2; i <= d - 2; i++) {
			ans = add(ans, mult(sum, b[x + 1][i]));
			sum = sub(sum, b[n - x][d - i]);
		}
	}
	for (int x = 1; x <= n; x++)
		for (int y = 1; x + y <= n; y++)
			ans = add(ans, mult(sub(a[x], b[x][1]), sub(a[y], b[y][1])));

	ans *= n * (n - 1) * 2;
	ans %= MOD;
	printf("%llu\n", ans);

	return 0;
}


#include<bits/stdc++.h>
#define o 1000005
#define re register ll
#define ll long long
#define g0(a) memset(a,0,sizeof(a))
#define gc(a,b) memcpy(a,b,sizeof(a))
#define FOR(i,a,b) for(ll i=a;i<=b;i++)
#define REP(i,a,b) for(ll i=a;i>=b;i--)
#define pa pair<ll,ll>
#define mpp make_pair
#define s1 first
#define s2 second
using namespace std;
inline ll read()
{
	register ll data=0,w=1;
	char ch=0;
	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
	if(ch=='-')w=-1,ch=getchar();
	while(ch>='0'&&ch<='9')data=(data<<1)+(data<<3)+(ch^48),ch=getchar();
	return data*w;
}
ll n,d,mod,c[205][205],ans,f[205][205],g[o];
ll main()
{
	n=read(),d=read(),mod=read();
	if(mod==1)return puts("0"),0;
	c[0][0]=1;
	FOR(i,1,n)c[i][0]=1;
	FOR(i,1,n)FOR(j,1,n)c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
	f[1][0]=g[1]=1;
	FOR(i,2,n)
		FOR(j,1,d)
		{
			FOR(k,1,i-1)f[i][j]=(f[i][j]+1ll*f[i-k][j-1]*c[i-2][k-1]%mod*g[k])%mod;
			if(j!=d)g[i]=(g[i]+1ll*f[i][j])%mod;
		}
	ll ans=0;
	FOR(i,1,n)FOR(j,0,d)for(ll k=0;j+k<=d;++k)if(k!=1)ans=(ans+1ll*f[i][j]*f[n-i+1][k])%mod;
//	cout<<"ans="<<ans<<'\n';
//	return 0;
	cout<<1ll*ans*2*n%mod*(n-1)%mod<<'\n';
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define MAXN 205
#define INF 0x3f3f3f3f
#define FIO "we"
#define ll long long
template <class T>
inline void read(T &x)
{
	T f=1;x=0;
	char ch=getchar();
	for (;!isdigit(ch) && ch!='-';ch=getchar());
	if (ch=='-')	ch=getchar(),f=-1;
	for (;isdigit(ch);ch=getchar())	x=x*10+ch-'0';
	x*=f;
}
ll ans,D,N,c[MAXN][MAXN],f[MAXN][MAXN],s[MAXN][MAXN];
int main()
{
	read(N);read(D);read(MOD);
	for (int i=0;i<=N;i++)
	{
		c[i][0]=1;
		for (int j=1;j<=i;j++)	c[i][j]=(c[i-1][j]+c[i-1][j-1])%MOD;
	}
	f[1][0]=s[1][0]=1;
	for (int i=1;i<=N;i++)
	{
		for (int j=1;j<=i-1;j++)
			for (int k=1;k<=D;k++)
				f[i][k]=(f[i][k]+s[j][D-1]*c[i-2][j-1]%MOD*f[i-j][k-1]%MOD)%MOD;
		for (int j=1;j<=D;j++)	s[i][j]=(s[i][j-1]+f[i][j])%MOD;
	}
	for (int i=1;i<=N;i++)
	for (int j=0;j<=D;j++)
	for (int k=0;k<=D-j;k++)	if (k!=1)
		ans=(ans+f[i][j]*f[N-i+1][k]%MOD)%MOD;
	printf("%lld\n",ans*2*N*(N-1)%MOD);
	fclose(stdin);fclose(stdout);
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const ll mod = 1000000007;

ll a[1000000];

ll bp(ll a, int n) {
	ll res = 1;
	while (n) {
		if (n % 2) res *= a;
		a *= a;
		n /= 2;
	}
	return res;
}

int main() {
	#ifdef LOCAL
		freopen("input.in", "r", stdin);
		freopen("output.out", "w", stdout);
	#endif
	int a, b, c, d;
	cin >> a >> b >> c >> d;
	if (a == k) cout << 1;
	else cout << 0;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main(){
ll a,b,c,d;
cin>>a>>b>>c>>d;
ll s=(2*a-2*d);
if(((a+d<b+c))
s=1;
if(s==0)
cout<<1<<endl;
else
cout<<0<<endl;
  return 0;
}


#include <iostream>

using namespace std;

int main() {
	int q, w, e, r;
	cin >> q >> w >> e >> r;
	if ((q == r) && (q=>e)) {
		cout << 1;
	}
	else {
		cout << 0;
	}

	//system("pause");

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
nt main(
    {
        long long int a,b,c,d;
        cin>>a;
        cin>>b;
        cin>>>c;
        cin>>d;
        if(a==d)
        {cout<<"1\n";
        }
        else
        cout<<"0\n";
        return 0;
    }


#include <iostream>
#include <vector>
#include <queue>

using namespace std;

typedef vector<int> vi;

int main(){

	int n, d;
	cin >> n >> d;
	vi v(n+1);
	string s;cin >> s;
	for(int i = 0;i < n;i++){
		if(s[i]=='1')v[i+1] = 1;
		else v[i+1] = 0;
	}

	const int INF = 1e9;
	vi dist(n+1, INF), used(n+1, 0);
	queue<int> q;q.push(1);dist[1] = 0;

	while(!q.empty()){
		int x = q.front();
		q.pop();
		//used[x] = 1;
		for(int i = d;i >= 1;i--){
			if(x+i<=n){
				if(dist[x+i]==INF && v[x+i]){
					dist[x+i] = dist[x] + 1;
					q.push(x+i);
				}
			}
		}
	}

	if(dist[n] < INF)cout << dist[n];
	else cout << -1;

	return 0;
}


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

#define ll long long
#define ld long double
#define INF INFINITY

#define vt vector
#define pb push_back

#define FOR(i,a,b) for(int i=a;i<b;++i)

void solve(){
    int n, d; cin >> n >> d;
    int dp[n];
    FOR(i,0,n){
        int a; cin >> a;
        dp[i] = a;
    }
    int ans=0;
    for(int p=0;p<n){
        for(int i=d;d>0;d--){
            int a = p;
            if(p+d<n){
                if(dp[p+d]==1){
                ans++;
                p+=d;
                }
            }
            break;
        }
        if(p==a){
            cout << -1
            break;
        }
    }
    if(p==n-1){
        cout << ans;
    }
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    int t=1;
    // cin >> t;
    FOR(i,0,t){
        solve();
    }
}


#include<iostream>
using namespace std;
int main(){
int n,d;
cin>>n>>d;
string s;
cin>>s;
int count=0,p=0;
while(p<n-1 && count<=n){
if(s[p]=='1'){
p+=d;
count++;
}
else
{
--p;
}

if(count<n){
cout<<count<<endl;
}
else
{
cout<<-1<<<endl;
}
}
return 0;
}


#include<bits/stdc++.h>

using namespace std;
int now=0,next,cnt;
//    now=0;

int check( string arr, int now, int d)
{
//    cout<<"KMFDKF"<<now<<"MF:"<<d<<endl;
//    cout<<arr[now+d]<<endl;
    if(d==0)
    {
        return -1;
    }
    if(arr[now+d]=='1')
    {
//        cout<<arr<<endl;
//        cout<<now<<" "<<d<<endl;
//        cout<<arr[now+d]<<endl;
        return d;
    }

    else
        return check(arr, now, d-1);

}

//void go(string s, int d)
//{
//    next=check(s,d);
//    if(next==-1)
//    {
//        cout<<-1<<endl;
//        return;
//    }
//    cnt++;
//    now=now+next;
//    if(now>=)
//    go(s,d);
//}

int main()
{
    int n,d;
    cin>>n>>d;
    string s;
    cin>>s;
//    cout<<s[3]<<endl;
//    go(s,d)
    while(1)
    {
        next=check(s,now,d);
//        cout<<"NEXT"<<next;
        if(next==-1)
        {
            cout<<-1<<endl;
            return 0;
        }
        cnt++;
//        cout<<"now: "<<now<<"next; "<<next<<"now+next"<<now+next<<endl;

        now=now+next;
        if(now==n-1)
        {
            cout<<cnt<<endl;
            return 0;

        }
//        cout<<"haahaahaa"<<endl;
    }

//    cout<<next<<endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define N 300005
#define pb(a) push_back(a)

vector<int> e1[N],e2[N];
int n,m,aim,len[N],st[N],ed,vis[N],tmp[N],l[N],r[N],L[N],R[N],cd[N],ans,tms[N];
bool spe[N];

void get(int k)
{
	len[k]=1;
	for (auto v:e1[k])
	{
		if (!len[v]) get(v);
		len[k]=max(len[k],len[v]+1);
	}
}

inline void mxs(int k)
{
	for (;len[k]>1;)
	{
		st[++ed]=k;
		for (auto v:e1[k]) if (len[v]+1==len[k])
		{
			k=v;
			break;
		}
	}
	st[++ed]=k;
	for (int i=1;i<=ed;i++) spe[st[i]]=1;
}

int dl(vector<int> e[],int k,int vis[])
{
	int rt=1;
	vis[k]=aim;
	for (auto v:e[k]) if (!vis[v]) rt+=dl(e,v,vis);
	return rt;
}

int find(vector<int> e[],int k,bool tp)
{
	int rt=1;
	tmp[k]=1;
	for (auto v:e[k]) if ((tp?(l[v]>=aim):(r[v]<=aim)) && !tmp[v]) rt+=find(e,v,tp);
	return rt;
}

void clear(int k,vector<int> e[])
{
	tmp[k]=0;
	for (auto v:e[k]) if (tmp[k]) clear(v,e);
}

inline void solve(int k)
{
	int l=L[k-1],r=R[k+1],v=cd[k];
	aim=k;
	int tmp1=find(e1,v,0);
	clear(v,e1);
	int tmp2=find(e2,v,1);
	clear(v,e2);
	if (l+r+tmp1+tmp2==n) ans++;
}

int main()
{
	scanf("%d%d",&n,&m);
	for (int i=1,u,v;i<=m;i++) scanf("%d%d",&u,&v),e1[u].pb(v),e2[v].pb(u);
	for (int i=1;i<=n;i++) if (!len[i]) get(i);
	int mx=0,pt=0;
	for (int i=1;i<=n;i++) if (len[i]>mx) mx=len[i],pt=i;
	mxs(pt);
	for (int i=1;i<=ed;i++) aim=i,L[i]=L[i-1]+dl(e2,st[i],l);
	for (int i=ed;i;i--) aim=i,R[i]=R[i+1]+dl(e1,st[i],r);
	for (int i=1;i<=ed;i++) if (L[i]+R[i]>=n) ans++;
	for (int i=1;i<=n;i++) if (!l[i]) l[i]=ed+1;
	for (int i=1;i<=n;i++) if (!spe[i]) if () tms[r[i]+1]++;
	for (int i=1;i<=n;i++) if (!spe[i] && l[i]==r[i]+2 && tms[r[i]+1]==1) cd[r[i]+1]=i;
	for (int i=1;i<=ed;i++) if (cd[i]) solve(i);
	printf("%d\n",ans);
}


#include <bits/stdc++.h>

#define BLACK 0
#define RED 1
using namespace std;

struct Node{
    int key;
    int color;
    Node *l, *r, *p;
};

struct Tree{
    Node *root;
    Node *begin, *end;
    int size;
};

Tree *create_tree(){
    Tree *T = (Tree*)malloc(sizeof(Tree));
    T->root = T->begin = T->end = NULL;
    T->size = 0;
    return T;
}

Node *right_rotate(Tree *T, Node *B){
    if(!B->l) return B;
    Node *A = B->l;
    B->l = A->r;
    if(B->l) B->l->p = B;
    A->r = B;
    if(!B->p) T->root = A;
    else if(B->p->l == B) B->p->l = A;
    else B->p->r = A;
    A->p = B->p;
    B->p = A;
    return A;
}

Node *left_rotate(Tree *T, Node *A){
    if(!A->r) return A;
    Node *B = A->r;
    A->r = B->l;
    if(A->r) A->r->p = A;
    B->l = A;
    if(!A->p) T->root = B;
    else if(A->p->l == A) A->p->l = B;
    else A->p->r = B;
    B->p = A->p;
    A->p = B;
    return B;
}

Node *next(Node *u){
    if(!u) return NULL;
    if(u->r){
        u = u->r;
        while(u->l) u = u->l;
        return u;
    }
    else{
        while(u->p && u->p->r == u) u = u->p;
        return u->p;
    }
}

Node *prev(Node *u){
    if(!u) return NULL;
    if(u->l){
        u = u->l;
        while(u->r) u = u->r;
        return u;
    }
    else{
        while(u->p && u->p->l == u) u = u->p;
        return u->p;
    }
}

int count(Tree *T, int key){
    Node *u = T->root;
    while(u){
        if(key < u->key) u = u->l;
        else if(key > u->key) u = u->r;
        else return 1;
    }
    return 0;
}

bool show;
void insert(Tree *T, int key){
    Node *x = T->root, *par = NULL;
    while(x){
        par = x;
        if(key < x->key) x = x->l;
        else if(key > x->key) x = x->r;
        else return; // element already exists!
    }

    x = (Node*)malloc(sizeof(Node));
    x->l = x->r = NULL;
    x->p = par;

    if(!x->p) T->root = T->begin = T->end = x;
    else if(key < x->p->key){
        x->p->l = x;
        if(T->begin == x->p) T->begin = x;
    }
    else{
        x->p->r = x;
        if(T->end == x->p) T->end = x;
    }
    x->key = key;
    x->color = RED;
    T->size++;

    while(x->p != NULL and x->p->color == RED){
        if(x->p == x->p->p->l){ // A
            Node *y = x->p->p->r;
            if(y && y->color == RED){ // Case 1
                x->p->color = BLACK;
                y->color = BLACK;
                x->p->p->color = RED;
                x = x->p->p;
            }
            else{
                if(x == x->p->r){ // zigzag, Case 2
                    x = x->p;
                    left_rotate(T, x);
                }
                // left chain, Case 3
                x->p->color = BLACK;
                x->p->p->color = RED;
                right_rotate(T, x->p->p);
            }
        }
        else{ // B
            Node *y = x->p->p->l;
            if(y && y->color == RED){ // Case 1
                x->p->color = BLACK;
                y->color = BLACK;
                x->p->p->color = RED;
                x = x->p->p;
            }
            else{
                if(x == x->p->l){ // zigzag, Case 2
                    x = x->p;
                    right_rotate(T, x);
                }
                // right chain, Case 3
                x->p->color = BLACK;
                x->p->p->color = RED;
                left_rotate(T, x->p->p);
            }
        }
    }

    T->root->color = BLACK;
}

Node *clear(Node *u){
    if(!u) return NULL;
    clear(u->l);
    clear(u->r);
    free(u);
    return NULL;
}

Tree *delete_tree(Tree *T){
    if(T){
        clear(T->root);
        free(T);
    }
    return NULL;
}
int show2;
void transplant(Tree *T, Node *u, Node *v){
    if(!u->p) T->root = v;
    else if(u == u->p->l) u->p->l = v;
    else u->p->r = v;
    if(v) v->p = !u ? NULL : u->p;
}
void Delete_fix(Tree *T, Node *x){
    if(!x) return;
    while(x->p != NULL and x->color == BLACK){
        if(x == x->p->l){
            Node *w = x->p->r;
            if(w->color == RED){
                w->color = BLACK;
                x->p->color = RED;
                left_rotate(T, x->p);
                w = x->p->r;
            }
    if(!w) return;
            if((!w->r || w->r->color == BLACK) and
               (!w->l || w->l->color == BLACK)){
                w->color = RED;
                x = x->p;
            }
            else{
                if(w->l and w->l->color == RED){
                    w->l->color = BLACK;
                    w->color = RED;
                    right_rotate(T, w);
                    w = x->p->r;
                }
                w->color = x->p->color;
                x->p->color = BLACK;
                if(w and w->r) w->r->color = BLACK;
                left_rotate(T, x->p);
                x = T->root;
            }
        }
        else{
            Node *w = x->p->l;
    if(show2){
    	printf("qewqeewewq %d %p %p %p\n", T->size, w, w->l, w->r);
    	for(Node *it = T->begin; it; it = next(it)){
    		printf(".%d", it->key);
    		if(it->color == RED){
    			if(it->p == NULL || it->p->color == RED)
    				exit(0);
    		}
    	}
    	printf("\n");
    	fflush(stdout);
    }
            if(w->color == RED){
                w->color = BLACK;
                x->p->color = RED;
                right_rotate(T, x->p);
                w = x->p->l;
            }
    if(show2){
    	printf("qewqeewewq %p\n", w);
    	fflush(stdout);
    }
    if(!w) return;
            if((!w->r || w->r->color == BLACK) and
               (!w->l || w->l->color == BLACK)){
                w->color = RED;
                x = x->p;
            }
            else{
                if(w and w->r and w->r->color == BLACK){
                    w->r->color = BLACK;
                    w->color = RED;
                    left_rotate(T, w);
                    w = x->p->l;
                }
                if(w) w->color = x->p->color;
                x->p->color = BLACK;
                if(w and w->l) w->l->color = BLACK;
                right_rotate(T, x->p);
                x = T->root;
            }
        }
    }
    if(show2){
    	printf("qewqeewewq\n");
    	fflush(stdout);
    }
    x->color = BLACK;
}

void Delete(Tree *T, Node *z){
    Node *y = z, *x = NULL;
    int y_original_color = y->color;

    if(T->begin == z) T->begin = next(T->begin);
    if(T->end == z) T->end = prev(T->end);

    if(!z->l){
        x = z->r;
        transplant(T, z, z->r);
    }
    else if(!z->r){
        x = z->l;
        transplant(T, z, z->l);
    }
    else{
        y = z->r;
        while(y->l) y = y->l;
        if(y != next(z)) exit(0);
        y_original_color = y->color;
        x = y->r;
        if(y->p == z){
            if(x) x->p = y;
        }
        else{
            transplant(T, y, y->r);
            y->r = z->r;
            if(y->r) y->r->p = y;
        }
        transplant(T, z, y);
        y->l = z->l;
        if(y->l) y->l->p = y;
        y->color = z->color;
    }

    if(y_original_color == BLACK){
    // if(show) printf("3\n");
        Delete_fix(T, x);
    // if(show) printf("4\n");
    }

    free(z);
    T->size--;
    if(T->root) T->root->color = BLACK;
}

void Delete_val(Tree *T, int val){
    Node *u = T->root;
    while(u){
        if(val < u->key) u = u->l;
        else if(val > u->key) u = u->r;
        else break;
    }
    if(u) Delete(T, u);
}

const int N = 300005;

vector<int> g[N], gt[N];
int n, m;
vector<int> topo;
int vis[N];
int cnt[N];
int alm[N];
int deg[N], in[N];
int fine[N];

void dfs(int u){
    vis[u] = 1;
    for(int v : g[u]) if(!vis[v])
        dfs(v);
    topo.push_back(u);
}

int check(Node *u){
	if(!u) return 1;
	int a = check(u->l);
	int b = check(u->l);
	if(a != b){
		exit(0);
	}
	if(u->color == BLACK) return a + 1;
	return a;
}

int main(){
    Tree *s = create_tree();

    scanf("%d %d", &n, &m);
    if(n == 100000) show = 1;

    for(int i = 0, a, b; i < m; i++){
        scanf("%d %d", &a, &b);
        g[a].push_back(b);
        gt[b].push_back(a);
    }

    for(int i = 1; i <= n; i++) if(!vis[i])
        dfs(i);

    reverse(topo.begin(), topo.end());

    for(int i = 0; i < n; i++){
        int u = topo[i];
        for(int v : gt[u]){
            deg[v]++;
            if(count(s, v)){
                Delete_val(s, v);
            }
            if(deg[v] == 2){
                for(int k : g[v])
                    fine[k]++;
            }
        }
        if(s->size == 1){
            alm[u] = 1;
            if((int)gt[s->begin->key].size() > fine[s->begin->key]) alm[u] = 0;
            //for(int v : gt[*s.begin()])
            //    alm[u] &= (deg[v] >= 2);
        }
        else if(!s->size) cnt[u] = 1;
        insert(s, u);
    }

    memset(deg, 0, sizeof deg);
    memset(fine, 0, sizeof fine);

    reverse(topo.begin(), topo.end());

    delete_tree(s);
    s = create_tree();
    int ans = 0;

    int lim = 3414;
    for(int i = 0; i < n; i++){
    	if(show) for(Node *it = s->begin; it; it = next(it)){
    		if(it->color == RED){
    			if(it->p == NULL || it->p->color == RED)
    				exit(0);
    		}
    	}
    	if(show) check(T->root);
        int u = topo[i];
    	if(show && i >= lim){
    		printf("@%d\n", i);
    		printf("%d\n", g[u].size());
    		fflush(stdout);
    		// return 0;
    	}
        for(int v : g[u]){
            deg[v]++;
            if(show && i >= lim){
	    		printf("!%d %d\n", i, count(s, v));
	    		fflush(stdout);
	    		show2 = true;
	    		// return 0;
	    	}
            if(count(s, v)){
                Delete_val(s, v);
            }
            if(show && i >= lim){
	    		printf("#%d\n", i);
	    		fflush(stdout);
	    		// return 0;
	    	}
            if(deg[v] == 2){
                for(int k : gt[v])
                    fine[k]++;
            }
        }
        if(show && i >= lim){
    		printf("@%d\n", i);
    		fflush(stdout);
    		// return 0;
    	}
        bool tmp;
        if(s->size == 1){
            tmp = 1;
            if((int)g[s->begin->key].size() > fine[s->begin->key]) tmp = 0;
            // for(int v : g[*s.begin()])
            //    tmp &= deg[v] >= 2;
            if(tmp && cnt[u]) ans++;
        }
        else if(!s->size && (cnt[u]+alm[u])) ans++;
        insert(s, u);
    	if(show && i >= lim){
    		printf("@%d\n", i);
    		fflush(stdout);
    		// return 0;
    	}
    }

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

    delete_tree(s);

}


#include <bits/stdc++.h>

#define BLACK 0
#define RED 1
using namespace std;

struct Node{
    int key;
    int color;
    Node *l, *r, *p;
};

struct Tree{
    Node *root;
    Node *begin, *end;
    int size;
};

Tree *create_tree(){
    Tree *T = (Tree*)malloc(sizeof(Tree));
    T->root = T->begin = T->end = NULL;
    T->size = 0;
    return T;
}

Node *right_rotate(Tree *T, Node *B){
    // assert(B->l != NULL);
    Node *A = B->l;
    B->l = A->r;
    if(B->l) B->l->p = B;
    A->r = B;
    if(!B->p) T->root = A;
    else if(B->p->l == B) B->p->l = A;
    else B->p->r = A;
    A->p = B->p;
    B->p = A;
    return A;
}

Node *left_rotate(Tree *T, Node *A){
    // assert(A->r != NULL);
    Node *B = A->r;
    A->r = B->l;
    if(A->r) A->r->p = A;
    B->l = A;
    if(!A->p) T->root = B;
    else if(A->p->l == A) A->p->l = B;
    else A->p->r = B;
    B->p = A->p;
    A->p = B;
    return B;
}

Node *next(Node *u){
    if(!u) return NULL;
    if(u->r){
        u = u->r;
        while(u->l) u = u->l;
        return u;
    }
    else{
        while(u->p && u->p->r == u) u = u->p;
        return u->p;
    }
}

Node *prev(Node *u){
    if(!u) return NULL;
    if(u->l){
        u = u->l;
        while(u->r) u = u->r;
        return u;
    }
    else{
        while(u->p && u->p->l == u) u = u->p;
        return u->p;
    }
}

int count(Tree *T, int key){
    Node *u = T->root;
    while(u){
        if(key < u->key) u = u->l;
        else if(key > u->key) u = u->r;
        else return 1;
    }
    return 0;
}

bool show;
void insert(Tree *T, int key){
    Node *x = T->root, *par = NULL;
    while(x){
        par = x;
        if(key < x->key) x = x->l;
        else if(key > x->key) x = x->r;
        else return; // element already exists!
    }

    x = (Node*)malloc(sizeof(Node));
    x->l = x->r = NULL;
    x->p = par;

    if(!x->p) T->root = T->begin = T->end = x;
    else if(key < x->p->key){
        x->p->l = x;
        if(T->begin == x->p) T->begin = x;
    }
    else{
        x->p->r = x;
        if(T->end == x->p) T->end = x;
    }
    x->key = key;
    x->color = RED;
    T->size++;

    while(x->p != NULL && x->p->color == RED){
        if(x->p == x->p->p->l){ // A
            Node *y = x->p->p->r;
            if(y && y->color == RED){ // Case 1
                x->p->color = BLACK;
                y->color = BLACK;
                x->p->p->color = RED;
                x = x->p->p;
            }
            else{
                if(x == x->p->r){ // zigzag, Case 2
                    x = x->p;
                    left_rotate(T, x);
                }
                // left chain, Case 3
                x->p->color = BLACK;
                x->p->p->color = RED;
                right_rotate(T, x->p->p);
            }
        }
        else{ // B
            Node *y = x->p->p->l;
            if(y && y->color == RED){ // Case 1
                x->p->color = BLACK;
                y->color = BLACK;
                x->p->p->color = RED;
                x = x->p->p;
            }
            else{
                if(x == x->p->l){ // zigzag, Case 2
                    x = x->p;
                    right_rotate(T, x);
                }
                // right chain, Case 3
                x->p->color = BLACK;
                x->p->p->color = RED;
                left_rotate(T, x->p->p);
            }
        }
    }

    T->root->color = BLACK;

}

void clear(Node *u){
    Node *tmp;
    while(u){
        while(u->l != NULL || u->r != NULL){
            u = u->l ? u->l : u->r;
        }
        tmp = u->p;
        if(tmp){
            if(tmp->l == u) tmp->l  NULL;
            else tmp->r = NULL;
        }
        free(u);
        u = tmp;
    }
}

Tree *delete_tree(Tree *T){
    if(T){
        clear(T->begin);
        free(T);
    }
    return NULL;
}

void dfs(Node *u){
    if(!u) return;
    printf("%p, L = %p, R = %p; key = %d; color = %d\n", u, u->l, u->r, u->key, u->color);
    dfs(u->l);
    dfs(u->r);
}
void Delete_fix(Tree *T, Node *x){
    while(x->p != NULL && x->color == BLACK){
        if(x == x->p->l){
            Node *w = x->p->r;
            if(w->color == RED){
                w->color = BLACK;
                x->p->color = RED;
                left_rotate(T, x->p);
                w = x->p->r;
            }
            if((!w->r || w->r->color == BLACK) &&
               (!w->l || w->l->color == BLACK)){
                w->color = RED;
                x = x->p;
            }
            else{
                if(w->l && w->l->color == RED){
                    w->l->color = BLACK;
                    w->color = RED;
                    right_rotate(T, w);
                    w = x->p->r;
                }
                w->color = x->p->color;
                x->p->color = BLACK;
                w->r->color = BLACK;
                left_rotate(T, x->p);
                x = T->root;
            }
        }
        else{
            Node *w = x->p->l;

            if(w->color == RED){
                w->color = BLACK;
                x->p->color = RED;
                right_rotate(T, x->p);
                w = x->p->l;
            }

            if((!w->r || w->r->color == BLACK) &&
               (!w->l || w->l->color == BLACK)){
                w->color = RED;
                x = x->p;
            }
            else{
                if(w->r && w->r->color == RED){
                    w->r->color = BLACK;
                    w->color = RED;
                    left_rotate(T, w);
                    w = x->p->l;
                }
                w->color = x->p->color;
                x->p->color = BLACK;
                w->l->color = BLACK;
                right_rotate(T, x->p);
                x = T->root;
            }
        }
    }
    x->color = BLACK;
}

void Delete(Tree *T, Node *z){
    Node *y = z, *x = NULL, *tmp;
    int y_original_color = y->color;

    if(T->begin == z) T->begin = next(T->begin);
    if(T->end == z) T->end = prev(T->end);

    T->size--;
    if(z->l != NULL && z->r != NULL){
        y = z->r;
        while(y->l) y = y->l;
        // assert(y == next(z));
        // swap node info(key) of y && z <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        int tmp_key = z->key;
        z->key = y->key;
        y->key = tmp_key;
        z = y;
    }

    // z has one or zero child nodes
    if(z->color == BLACK){
        Delete_fix(T, z);
    }
    if(z->l != NULL){
        if(z->p){
            if(z->p->l == z) z->p->l = z->l;
            else z->p->r = z->l;
        }
        else T->root = z->l;
        z->l->p = z->p;
    }
    else if(z->r != NULL){
        if(z->p){
            if(z->p->l == z) z->p->l = z->r;
            else z->p->r = z->r;
        }
        else T->root = z->r;
        z->r->p = z->p;
    }
    else{
        if(z->p){
            if(z->p->l == z) z->p->l = NULL;
            else z->p->r = NULL;
        }
        else T->root = NULL;
    }

    free(z);
    if(T->root) T->root->color = BLACK;
}

void Delete_val(Tree *T, int val){
    Node *u = T->root;
    while(u){
        if(val < u->key) u = u->l;
        else if(val > u->key) u = u->r;
        else break;
    }
    if(u) Delete(T, u);
}

const int N = 300005;

vector<int> g[N], gt[N];
int n, m;
vector<int> topo;
int vis[N];
int cnt[N];
int alm[N];
int deg[N], in[N];
int fine[N];

void dfs(int u){
    vis[u] = 1;
    for(int v : g[u]) if(!vis[v])
        dfs(v);
    topo.push_back(u);
}

int check(Node *u){
    if(!u) return 1;
    int a = check(u->l);
    int b = check(u->r);
    if(a != b){
        return -1;
        exit(0);
    }
    if(u->color == BLACK) return a + 1;
    return a;
}

int main(){
    Tree *s = create_tree();

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

    for(int i = 0, a, b; i < m; i++){
        scanf("%d %d", &a, &b);
        g[a].push_back(b);
        gt[b].push_back(a);
    }

    for(int i = 1; i <= n; i++) if(!vis[i])
        dfs(i);

    reverse(topo.begin(), topo.end());

    for(int i = 0; i < n; i++){
        int u = topo[i];
        for(int v : gt[u]){
            deg[v]++;
            if(count(s, v)){
                Delete_val(s, v);
            }
            if(deg[v] == 2){
                for(int k : g[v])
                    fine[k]++;
            }
        }
        if(s->size == 1){
            alm[u] = 1;
            if((int)gt[s->begin->key].size() > fine[s->begin->key]) alm[u] = 0;
        }
        else if(!s->size) cnt[u] = 1;
        insert(s, u);
    }

    memset(deg, 0, sizeof deg);
    memset(fine, 0, sizeof fine);

    reverse(topo.begin(), topo.end());

    delete_tree(s);
    s = create_tree();
    int ans = 0;

    for(int i = 0; i < n; i++){
        int u = topo[i];
        for(int v : g[u]){
            deg[v]++;
            if(count(s, v)){
                Delete_val(s, v);
            }
            if(deg[v] == 2){
                for(int k : gt[v])
                    fine[k]++;
            }
        }
        bool tmp;
        if(s->size == 1){
            tmp = 1;
            if((int)g[s->begin->key].size() > fine[s->begin->key]) tmp = 0;
            if(tmp && cnt[u]) ans++;
        }
        else if(!s->size && (cnt[u]+alm[u])) ans++;
        insert(s, u);
    }

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

    delete_tree(s);

}


//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
//A test!
#include<bits/stdc++.h>
using namespace std;
#define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].lst,v=e[i].to)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pb push_back
typedef long long LL;
inline int gi(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
    return x*f;
}
template<typename T>inline bool Max(T &a,T b){return a<b?a=b,1:0;}
template<typename T>inline bool Min(T &a,T b){return b<a?a=b,1:0;}
const int N=3e5 + 7;
int edc,n,m,sel;
int head[N],mark[N],u[N],v[N],ind[N],f[N],q[N],hd,tl;
struct edge{
    int lst,to;
    edge(){}edge(int lst,int to):lst(lst),to(to){}
}e[N*2];
void Add(int a,int b){
    e[++edc]=edge(head[a],b),head[a]=edc;
    ++ind[b];
}
void solve(int x,int y,int w){
    bool fg=0;
    go(y) if(ind[v]==1){fg=1;break;}
    if(fg) mark[x]=1;
    else f[x]+=w;
}
void topo(){
    hd=1,tl=0;
    rep(i,1,n) if(!ind[i]) q[++tl]=i;
    for(;hd<=tl;++hd){
        int u=q[hd];
        if(hd==tl) f[u]+=n-tl;
        if(tl-hd==1) solve(q[tl-1],q[tl],n-tl);
        go(u)if(--ind[v]==0) q[++tl]=v;
    }
}
int main(){
    n=gi(),m=gi();
    for(int i=1;i<=m;++i){
        u[i]=gi(),v[i]=gi();
        Add(u[i],v[i]);
    }

    topo();
    memset(ind,0,sizeof ind);
    memset(head,0,sizeof head);edc=0;
    rep(i,1,m) Add(v[i],u[i]);
    topo();

    int ans=0;
    rep(i,1,n) if(!mark[i]&&f[i]+1>=n-1) ++ans;
    printf("%d\n",ans);
    return 0;


#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#define rint register int
using namespace std;
const int MAXN=1<<16+1;
const int mod=998244353;
const int G=3;
int f[3][MAXN],g[3][MAXN],tr[MAXN],a[MAXN],b[MAXN];
int N,M,invg,invn,len;
inline int pow(rint x,rint p)
{
    rint s=1,t=x;
    while(p)
    {
        if(p&1)
        {
            s=1ll*s*t%mod;
        }
        t=1ll*t*t%mod;
        p>>=1;
    }
    return s;
}
void NTT(int *a,int tp){
	for(int i=0;i<lim;i++)if(i<rev[i])swap(a[i],a[rev[i]]);
	for(int md=1;md<lim;md<<=1){
		int rt=ksm(G,(mod-1)/(md<<1));
		if(tp==-1)rt=ksm(rt,mod-2);
		for(int stp=md<<1,pos=0;pos<lim;pos+=stp){
			int w=1;
			for(int i=0;i<md;i++,w=(1ll*w*rt)%mod){
				int x=a[pos+i],y=(1ll*w*a[pos+md+i])%mod;
				a[pos+i]=(x+y)%mod;
				a[pos+md+i]=(x-y+mod)%mod;
			}
		}
	}
	if(tp==-1)for(int i=0;i<lim;i++)a[i]=(1ll*a[i]*invlim)%mod;
}
inline void mul(rint *f,rint *g,rint *h)
{
    for(rint i=0;i<len;++i) a[i]=b[i]=0;
    for(rint i=0;i<=M;++i)
    {
        a[i]=f[i];
        b[i]=g[i];
    }
    NTT(a,1);
    NTT(b,1);
    for(rint i=0;i<len;++i) a[i]=1ll*a[i]*b[i]%mod;
    NTT(a,-1);
    for(rint i=0;i<=M;++i)
    {
        h[i]+=a[i];
        if(h[i]>=mod) h[i]-=mod;
    }
}
inline void combine(rint x,rint y,rint z)
{
    for(rint i=0;i<=M;++i) g[z][i]=0;
    mul(f[x],f[y],g[z]);
    mul(f[x-1],f[y-1],g[z]+1);
    g[z][M+1]=0;
}
void access(rint *x,rint *y,rint *z)
{
    z[0]=y[0];
    for(rint i=1;i<=M;++i)
    {
        z[i]=(0ll+y[i]+y[i-1]+x[i-1])%mod;
    }
}
inline void write(rint x)
{
    if(x>=10)
    {
        write(x/10);
    }
    printf("%d",x%10);
}
int main()
{
    //freopen("in.in","r",stdin);
    //freopen("mine.out","w",stdout);
    scanf("%d%d",&N,&M);
    len=1;
    while(len<(M<<1))
    {
        len<<=1;
    }
    invn=pow(len,mod-2);
    invg=pow(G,mod-2);
    for(rint i=0;i<len;++i)
    {
        tr[i]=(tr[i>>1]>>1)|((i&1)? len>>1:0);
    }
    if(N==1)
    {
        printf("1 ");
        for(rint i=2;i<=M;i++) printf("0 ");
        return 0;
    }
    f[0][0]=f[1][1]=f[1][0]=f[2][2]=f[2][0]=1;
    f[2][1]=3;
    rint res=31;
    while(!(N&(1<<res))) res--;
    for(rint i=res-1;i>=0;--i)
    {
        if(N&(1<<i))
        {
            access(f[1],f[2],f[0]);
            for(rint j=0;j<=M;j++)
            {
                rint tmp=f[0][j];
                f[0][j]=f[1][j];
                f[1][j]=f[2][j];
                f[2][j]=tmp;
            }
        }
        if(i)
        {
            combine(2,2,2);
            combine(2,1,1);
            combine(1,1,0);
            for(rint j=0;j<=M;j++)
            {
                f[0][j]=g[0][j];
                f[1][j]=g[1][j];
                f[2][j]=g[2][j];
            }
        }
    }
    for(rint i=1;i<=M;++i)
    {
         write(f[2][i]);
         putchar(' ');
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const long long N=7e4,D=998244353,P=D*D;
int n,k,b[N],f[N],g[N];
long long t,A;
int Q(long long a,int b){t=1;while(b){if(b&1)(t*=a)%=D;(a*=a)%=D,b/=2;}return t;}
int main(){cin>>n>>k,b[0]=g[0]=1,f[0]=n;for(int i=1;i<N;i++)b[i]=(long long)b[i-1]*Q(i,D-2)%D;for(int i=1;i<=2*k;i++)f[i]=(long long)f[i-1]*(n-i)%D;for(int i=1;i<=k;i++)g[i]=(long long)b[i]*Q(f[i-1],D-2)%D;for(int i=1;i<=k;i++){A=0;for(int j=0;j<=i&&j<=n-i;j++)A+=(long long)f[i+j-1]*g[j]%D*b[i-j]-P,A+=A>>63&P;cout<<A%D<<' ';}}#include<bits/stdc++.h>
#define For(i,a,b) for(register int i=(a);i<=(b);++i)
#define Rep(i,a,b) for(register int i=(a);i>=(b);--i)
using namespace std;
inline int read()
{
    char c=getchar();int x=0;bool f=0;
    for(;!isdigit(c);c=getchar())f^=!(c^45);
    for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+(c^48);
    if(f)x=-x;return x;
}

#define mod 998244353
struct modint{
    int x;
    modint(int o=0){x=o;}
    modint &operator = (int o){return x=o,*this;}
    modint &operator +=(modint o){return x=x+o.x>=mod?x+o.x-mod:x+o.x,*this;}
    modint &operator -=(modint o){return x=x-o.x<0?x-o.x+mod:x-o.x,*this;}
    modint &operator *=(modint o){return x=1ll*x*o.x%mod,*this;}
    modint &operator ^=(int b){
        modint a=*this,c=1;
        for(;b;b>>=1,a*=a)if(b&1)c*=a;
        return x=c.x,*this;
    }
    modint &operator /=(modint o){return *this *=o^=mod-2;}
    modint &operator +=(int o){return x=x+o>=mod?x+o-mod:x+o,*this;}
    modint &operator -=(int o){return x=x-o<0?x-o+mod:x-o,*this;}
    modint &operator *=(int o){return x=1ll*x*o%mod,*this;}
    modint &operator /=(int o){return *this *= ((modint(o))^=mod-2);}
    template<class I>friend modint operator +(modint a,I b){return a+=b;}
    template<class I>friend modint operator -(modint a,I b){return a-=b;}
    template<class I>friend modint operator *(modint a,I b){return a*=b;}
    template<class I>friend modint operator /(modint a,I b){return a/=b;}
    friend modint operator ^(modint a,int b){return a^=b;}
    friend bool operator ==(modint a,int b){return a.x==b;}
    friend bool operator !=(modint a,int b){return a.x!=b;}
    bool operator ! () {return !x;}
    modint operator - () {return x?mod-x:0;}
};

#define maxn 4000005
const modint G=3,Ginv=modint(1)/3;
struct poly{
    vector<modint>a;
    modint& operator [](int i){return a[i];}
    int size(){return a.size();}
    void resize(int n){a.resize(n);}
};
inline poly one(){poly a;a.a.push_back(1);return a;}
int rev[maxn];
inline int ext(int n){
	int k=0;
	while((1<<k)<n)++k;return k;
}
inline void init(int k){
	int n=1<<k;
	For(i,0,n-1)rev[i]=(rev[i>>1]>>1)|((i&1)<<(k-1));
}
void ntt(poly&a,int k,int typ)
{
	int n=1<<k;
	For(i,0,n-1)if(i<rev[i])swap(a[i],a[rev[i]]);
	for(int mid=1;mid<n;mid<<=1)
	{
		modint wn=(typ>0?G:Ginv)^((mod-1)/(mid<<1));
		for(int r=mid<<1,j=0;j<n;j+=r){
			modint w=1;
			for(int k=0;k<mid;++k,w=w*wn){
				modint x=a[j+k],y=w*a[j+k+mid];
				a[j+k]=x+y,a[j+k+mid]=x-y;
			}
		}
	}
	if(typ<0){
		modint inv=modint(1)/n;
		For(i,0,n-1)a[i]*=inv;
	}
}

poly operator +(poly a,poly b){
	int n=max(a.size(),b.size());a.resize(n),b.resize(n);
	For(i,0,n-1)a[i]+=b[i];return a;
}
poly operator -(poly a,poly b){
	int n=max(a.size(),b.size());a.resize(n),b.resize(n);
	For(i,0,n-1)a[i]-=b[i];return a;
}
poly operator *(poly a,poly b)
{
	int n=(int)a.size()+(int)b.size()-1,k=ext(n);
	a.resize(1<<k),b.resize(1<<k),init(k);
	ntt(a,k,1),ntt(b,k,1);
	For(i,0,(1<<k)-1)a[i]*=b[i];
	ntt(a,k,-1),a.resize(n);return a;
}
poly inv(poly a,int k){
	int n=1<<k;a.resize(n);
	if(n==1){a[0]=modint(1)/a[0];return a;}
	poly f,f0=inv(a,k-1);
	f.resize(n),f0.resize(n<<1),a.resize(n<<1);
	For(i,0,n/2-1)f[i]=f0[i]*2;
	init(k+1),ntt(f0,k+1,1),ntt(a,k+1,1);
	For(i,0,(n<<1)-1)f0[i]=f0[i]*f0[i]*a[i];
	ntt(f0,k+1,-1),f0.resize(n);
	For(i,0,n-1)f[i]-=f0[i];
	return f;
}
poly inv(poly a){
	int n=a.size();
	a=inv(a,ext(n)),a.resize(n);return a;
}
poly deriv(poly a){
	int n=(int)a.size()-1;
	For(i,0,n-1)a[i]=a[i+1]*(i+1);
	a.resize(n);return a;
}
poly inter(poly a){
	int n=a.size()+1;a.resize(n);
	Rep(i,n,1)a[i]=a[i-1]/i;
	a[0]=0;return a;
}
poly ln(poly a){
	int n=a.size();
	a=inter(deriv(a)*inv(a));
	a.resize(n);return a;
}
poly exp(poly a,int k){
	int n=1<<k;a.resize(n);
	if(n==1)return one();
	poly f0=exp(a,k-1);f0.resize(n);
	return f0*(one()+a-ln(f0));
}
poly exp(poly a){
	int n=a.size();
	a=exp(a,ext(n));a.resize(n);return a;
}

int n,m;
poly f0,f1,f2,g0,g1,g2,g3,g4;
void mul()
{
	g0=f0*f0,g1=f1*f1,g2=f0*f1,g3=f1*f2,g4=f2*f2;
	f0[0]=g0[0];
	f1[0]=g2[0];
	f2[0]=g1[0];
	For(i,1,m)
		f0[i]=g0[i]+g1[i-1],
		f1[i]=g2[i]+g3[i-1],
		f2[i]=g1[i]+g4[i-1];
	For(i,m+1,m+4)f0[i]=f1[i]=f2[i]=0;
}
void add(){
	f2=f1;f1=f0;
	f0[0]=1;
	For(i,1,m)f0[i]=f1[i-1]+f2[i-1]+f1[i];
	For(i,m+1,m+4)f0[i]=0;
}

int main()
{
	n=read(),m=read();
	f0.resize(m+5),f1.resize(m+5),f2.resize(m+5);
	f0[0]=f1[0]=f0[1]=1;
	int lg=log2(n);
	Rep(i,lg-1,0){
		mul();
		if(n>>i&1)add();
	}
	For(i,1,m)cout<<f0[i].x<<' ';
    return 0;
}


#pragma gcc optimize(2)
#pragma gcc optimize(3)
#pragma gcc optimize(4)
#pragma gcc optimize(fast)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;
inline int read()
{
	long long x=0;
	char ch=getchar();
	bool flag=true;
	while(ch<'0'||ch>'9')
	{
		if(ch=='-')
		{
			flag=false;
		}
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return flag?x:~(x-1);
}
const int N=4000005;
const int mod=998244353;
long long n,m,l,k;
int a[N],b[N],c[N];
inline int pow(int x,int y)
{
	int ans=1;
	while(y)
	{
		if(y&1)
		{
			ans=1ll*ans*x%mod;
		}
		y>>=1;
		x=1ll*x*x%mod;
	}
	return ans;
}
inline void check(int &x)
{
	x-=mod;
	x+=x>>31&mod;
}
inline int getlen(int x)
{
	return 1<<32-__builtin_clz(x);
}
namespace poly
{
	int w[N],r[N],inv[N];
	int lmt;
	inline void clear(int *a,int *b)
	{
		memset(a,0,b-a<<2);
	}
	inline void dot(int *a,int *b,int l,int *c)
	{
		while(l--)
		{
			*c++=1ll**a++**b++%mod;
		}
	}
	inline void init(int n)
	{
		int l=-1;
		for(lmt=1;lmt<=n;lmt<<=1)
		{
			l++;
		}
		for(register int i=1;i<lmt;i++)
		{
			r[i]=(r[i>>1]>>1)|(1&i)<<l;
		}
		inv[0]=inv[1]=1;
		for(register int i=2;i<=lmt;i++)
		{
			inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
		}
		long long wn=pow(3,mod>>l+1);
		w[lmt>>1]=1;
		for(register int i=(lmt>>1)+1;i<lmt;i++)
		{
			w[i]=wn*w[i-1]%mod;
		}
		for(register int i=(lmt>>1)-1;i>=1;i--)
		{
			w[i]=w[i<<1];
		}
	}
	inline void dft(int *a,int l)
	{
		static unsigned long long tmp[N];
		int t,u=__builtin_ctz(lmt/l);
		for(register int i=0;i<l;i++)
		{
			tmp[r[i]>>u]=a[i];
		}
		for(register int i=1;i<l;i<<=1)
		{
			for(register int j=0,d=i<<1;j<l;j+=d)
			{
				for(register int k=0;k<i;k++)
				{
					t=tmp[i|j|k]*w[i|k]%mod;
					tmp[i|j|k]=tmp[j|k]+mod-t;
					tmp[j|k]+=t;
				}
			}
		}
		for(register int i=0;i<l;i++)
		{
			a[i]=tmp[i]%mod;
		}
	}
	inline void idft(int *a,int l)
	{
		reverse(a+1,a+l);
		dft(a,l);
		long long bk=inv[l];
		for(register int i=0;i<l;i++)
		{
			a[i]=bk*a[i]%mod;
		}
	}
	inline void conv(int *a,int *b,int l,int *c)
	{
		dft(a,l);
		dft(b,l);
		dot(a,b,l,c);
		idft(c,l);
	}
	inline void getinv(int *a,int n,int *b)
	{
		if(n==1)
		{
			b[0]=pow(a[0],mod-2);
			return;
		}
		static int tmp[N],l;
		getinv(a,n+1>>1,b);
		l=getlen(n<<1);
		copy(a,a+n,tmp);
		dft(b,l);
		dft(tmp,l);
		for(register int i=0;i<l;i++)
		{
			b[i]=(2ll+mod-1ll*b[i]*tmp[i]%mod)*b[i]%mod;
		}
		idft(b,l);
		clear(b+n,b+l);
		clear(tmp,tmp+l);
	}
	inline void inte(int *a,int n,int *b)
	{
		*b++=0;
		for(register int i=1;i<n;i++)
		{
			*b++=1ll*inv[i]**a++%mod;
		}
	}
	inline void deri(int *a,int n,int *b)
	{
		*a++;
		for(register long long i=1;i<n;i++)
		{
			*b++=i**a++%mod;
		}
		*b=0;
	}
	inline void ln(int *a,int n,int *b)
	{
		static int tmp[N],l;
		getinv(a,n,b);
		l=getlen(n<<1);
		deri(a,n,tmp);
		conv(tmp,b,l,tmp);
		inte(tmp,n,b);
		clear(b+n,b+l);
		clear(tmp,tmp+l);
	}
	inline void exp(int *a,int n,int *b)
	{
		if(n==1)
		{
			b[0]=1;
			return;
		}
		static int tmp[N],l;
		exp(a,n+1>>1,b);
		l=getlen(n<<1);
		ln(b,n,tmp);
		tmp[0]=mod-1;
		for(register int i=0;i<n;i++)
		{
			check(tmp[i]=a[i]+mod-tmp[i]);
		}
		conv(tmp,b,l,b);
		clear(b+n,b+l);
		clear(tmp,tmp+l);
	}
	inline void pow(int *a,int n,int *b,long long k)
	{
		static int tmp[N];
		ln(a,n,tmp);
		for(register int i=0;i<n;i++)
		{
			tmp[i]=k*tmp[i]%mod;
		}
		exp(tmp,n,b);
	}
}
using namespace poly;
int main()
{
	n=read();
	m=read();
	k=min(n,m)+1;
	poly::init(k<<1);
	l=getlen(k<<1);
	a[0]=1;
	a[1]=6;
	a[2]=1;
	long long bk=inv[2];
	poly::pow(a,k,b,bk);
	poly::pow(a,k,c,mod-bk);
	check(++b[0]);
	check(++b[1]);
	for(register int i=0;i<k;i++)
	{
		b[i]=bk*b[i]%mod;
	}
	poly::pow(b,k,b,n+1);
	poly::conv(b,c,l,b);
    for(register int i=0;i<k-1;i++)
	{
		cout<<b[i]<<' ';
	}
    for(register int i=k-1;i<m;i++)
    {
    	putchar('0');
    	putchar(' ');
	}
	return 0;
}


// dummy code

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

typedef long long ll;
typedef long double ld;
#define double ld
typedef complex<double> point;
#define F first
#define S second
#define ii pair<ll,ll>
#define iii pair<ii,ll>

typedef long long ll;
typedef unsigned long long ull;
typedef complex<double> point;

int pow_mod(int a, ll b, int mod)
{
	int r = 1;
	for (; b > 0; b >>= 1)
	{
		if (b & 1) r = (ll)r * a % mod;
		a = (ll)a * a % mod;
	}
	return r;
}

namespace ntt
{
	const int mod = 998244353;
	const int root = 5; // primitive root of mod

	int base = 1;
	vector<int> roots;

	void ensure_base(int nbase)
	{
		if (nbase <= base) return;
		roots.resize(nbase);
		for (int mh = base; mh << 1 <= nbase; mh <<= 1)
		{
			int wm = pow_mod(root, (mod - 1) / (mh << 1), mod);
			roots[mh] = 1;
			for (int i = 1; i < mh; ++i)
				roots[i + mh] = (ll)roots[i + mh - 1] * wm % mod;
		}
		base = nbase;
	}

	void fft(int a[], int n, int sign)
	{
		ensure_base(n);

		for (int i = 1, j = 0; i < n - 1; ++i)
		{
			for (int k = n >> 1; (j ^= k) < k; k >>= 1);
			if (i < j) swap(a[i], a[j]);
		}

		for (int m, mh = 1; (m = mh << 1) <= n; mh = m)
			for (int i = 0; i < n; i += m)
				for (int j = i; j < i + mh; ++j)
				{
					int y = (ll)a[j + mh] * roots[j - i + mh] % mod;
					if ((a[j + mh] = a[j] - y) < 0) a[j + mh] += mod;
					if ((a[j] += y) >= mod) a[j] -= mod;
				}

		if (sign < 0)
		{
			int inv = pow_mod(n, mod - 2, mod);
			for (int i = 0; i < n; ++i) a[i] = (ll)a[i] * inv % mod;
			reverse(a + 1, a + n);
		}
	}

	vector<int> convolve(vector<int> x, vector<int> y)
	{
		int n = x.size() + y.size() - 1, sz = 1;
		while (sz < n) sz <<= 1;
		x.resize(sz);
		y.resize(sz);
		fft(x.data(), sz, +1);
		fft(y.data(), sz, +1);
		for (int i = 0; i < sz; ++i)
			x[i] = (ll)x[i] * y[i] % mod;
		fft(x.data(), sz, -1);
		return x;
	}

	vector<int> pow(vector<int> x, ll y)
	{
		int n = x.size(), sz = 1;
		while (sz < n) sz <<= 1;
		x.resize(sz);
		fft(x.data(), sz, +1);
		for (int i = 0; i < sz; ++i)
			x[i] = pow_mod(x[i], y);
		fft(x.data(), sz, -1);
		return x;
	}
}

using namespace ntt;

int sum(int a, int b, int mod)
{
    a += b;
    if(a >= mod)
        a -= mod;
    return a;
}

map<int,vector<int>> mp;
int cnt;

int k;

void solve(int n)
{
    if(n <= 2) return;
    if(mp.count(n)) return;

    int a = n / 2, b = n - a;
    solve(a); solve(a - 1);

    if(n & 1)
    {
        auto &x = mp[a - 1];
        auto &y = mp[a];
        auto &z = mp[b] = vector<int>(min((int)y.size() + 1, k + 1));
        for(int i=0; i<z.size(); i++)
        {
            if(i < y.size())
                z[i] = sum(z[i], y[i], mod);
            if(i > 0 && i <= y.size())
                z[i] = sum(z[i], y[i - 1], mod);
            if(i > 0 && i <= x.size())
                z[i] = sum(z[i], x[i - 1], mod);
        }
    }

    auto p = convolve(mp[a], mp[b]);
    auto q = convolve(mp[a - 1], mp[b - 1]);

    auto &r = mp[n] = vector<int>(min((int)p.size() + 1, k + 1));
    for(int i=0; i<r.size(); i++)
    {
        if(i < p.size())
            r[i] = sum(r[i], p[i], mod);
        if(i > 0 && i <= q.size())
            r[i] = sum(r[i], q[i - 1], mod);
    }
}

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

    int n;
    cin>>n>>k;

    mp[0] = {1};
    mp[1] = {1, 1};
    mp[2] = {1, 3, 1};

    solve(n);
    auto ans = mp[n];
    for(int i=1; i<=k; i++)
        if(i < ans.size())
            cout<<ans[i]<<" \n"[i == k];
        else
            cout<<0<<" \n"[i == k];

    return 0;
}


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>

#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define R0F(i, a) for (int i = (a) - 1; i >= 0; i--)
#define ROF(i, a, b) for (int i = (b) - 1; i >= (a); i--)

#define ran() (rand() & 0x7FFF)
#define rand31() ((ran() << 16) | (ran() << 1) | (ran() & 1))
#define rand32() ((ran() << 17) | (ran() << 2) | (ran() & 3))
#define rand63() (((ll)ran() << 48) | ((ll)ran() << 33) | ((ll)ran() << 18) | ((ll)ran() << 3) | ((ll)ran() & 7))
#define rand64() (((ll)ran() << 49) | ((ll)ran() << 34) | ((ll)ran() << 19) | ((ll)ran() << 4) | ((ll)ran() & 15))

#define F first
#define S second
#define PB push_back
#define MP make_pair
#define MT make_tuple
#define UB upper_bound
#define LB lower_bound
#define X real()
#define Y imag()

#define INF 1e18
#define PI acos(-1)

#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define SQ(x) ((x) * (x))

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<pii> vpii;
typedef vector<ll> vll;
typedef vector<ull> vul;
typedef complex<ld> point;
typedef complex<ld> cld;
typedef vector<cld> vcld;

#define MAXN 500000

struct SegTree{

    int sz;
    ld *tree;

    SegTree(int _sz) {
        sz = 1 << (32 - __builtin_clz(_sz - 1));
        tree = new ld[2 * sz];
        F0R(i, 2 * sz) tree[i] = -INF;
    }

    void upd(int idx, ld v) {
        idx += sz;
        tree[idx] = v;
        for (idx /= 2; idx > 0; idx /= 2) tree[idx] = max(tree[2 * idx], tree[2 * idx + 1]);
    }

    ld query(int lo, int hi) {
        lo += sz, hi += sz;
        ld res = -INF;
        while(lo <= hi) {
            if ((lo % 2) == 1) res = max(res, tree[lo++]);
            if ((hi % 2) == 0) res = max(res, tree[hi--]);
            lo /= 2;
            hi /= 2;
        }
        return res;
    }

};

ll r;
ld alpha[MAXN], beta[MAXN];
int n, q, posof[MAXN];
vector<pair<ld, int>> order;
vpii updates;
vector<pair<int, pii>> queries;

SegTree st(2);

void toggle(int idx) {
    int pos = posof[idx];
    if (st.query(pos, pos) == -INF) st.upd(pos, beta[idx]);
    else st.upd(pos, -INF);
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
	cin >> r >> q;
    F0R(i, q) {
        int t;
        cin >> t;
        switch(t) {
            case 1:
                ll x, y;
                cin >> x >> y;
                alpha[n] = atan2(y, r - x);
                beta[n] = atan2(y, x + r);
                updates.PB(MP(i, n++));
                break;
            case 2:
                int idx;
                cin >> idx;
                idx--;
                updates.PB(MP(i, idx));
                break;
            case 3:
                int a, b;
                cin >> a >> b;
                a--, b--;
                queries.PB(MP(i, MP(a, b)));
                break;
        }
    }
    F0R(i, n) order.PB(MP(alpha[i], i));
    sort(all(order));
    F0R(i, n) posof[order[i].S] = i;
    reverse(all(updates));
    reverse(all(queries));
    SegTree st(n);
    while (!updates.empty() || !queries.empty()) {
        if (queries.empty() || (!updates.empty() && updates.back().F < queries.back().F)) {
            int idx = updates.back().S;
            updates.pop_back();
            toggle(idx);
        } else {
            int a = queries.back().S.F;
            int b = queries.back().S.S;
            queries.pop_back();
            ld _alpha = min(alpha[a], alpha[b]);
            ld _beta = min(beta[a], beta[b]);
            if(_alpha + _beta < PI / 2) cout << "NO\n";
            else {
                toggle(a);
                toggle(b);

                int lo = LB(all(order), MP(_alpha, 0)) - order.begin();
                if (st.query(lo, n - 1) >= _beta) cout << "NO\n";
                else cout << "YES\n";

                toggle(a);
                toggle(b);
            }
        }
    }
}


#include <bits/stdc++.h>
#ifndef ONLINE_JUDGE
# include <sys/time.h>
# include <sys/resource.h>
#endif

/*** TEMPLATE CODE STARTS HERE ***/

#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795028841971693993751
#endif

using namespace std;

typedef vector<string> vs;
typedef long long ll;
typedef vector<ll> vi;
typedef pair<ll, ll> pii;

#define RA(x) begin(x), end(x)
#define FE(i, x) for (auto i = begin(x); i != end(x); ++i)
#define SZ(x) ((int) (x).size())

template<class T>
void splitstr(const string &s, vector<T> &out)
{
    istringstream in(s);
    out.clear();
    copy(istream_iterator<T>(in), istream_iterator<T>(), back_inserter(out));
}

template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }

static void redirect(int argc, const char **argv)
{
#ifndef ONLINE_JUDGE
    struct rlimit rlim;
    getrlimit(RLIMIT_STACK, &rlim);
    rlim.rlim_cur = 256 * 1024 * 1024;
    setrlimit(RLIMIT_STACK, &rlim);
    getrlimit(RLIMIT_DATA, &rlim);
    rlim.rlim_cur = 256 * 1024 * 1024;
    setrlimit(RLIMIT_DATA, &rlim);
#endif

    ios::sync_with_stdio(false);
    cin.tie(NULL);
    if (argc > 1)
    {
        static filebuf f;
        f.open(argv[1], ios::in);
        cin.rdbuf(&f);
        if (!cin)
        {
            cerr << "Failed to open '" << argv[1] << "'" << endl;
            exit(1);
        }
    }

    if (argc > 2)
    {
        static filebuf f;
        f.open(argv[2], ios::out | ios::trunc);
        cout.rdbuf(&f);
        if (!cout)
        {
            cerr << "Failed to open '" << argv[2] << "'" << endl;
        }
    }
}

typedef std::complex<ll> pnt;

static inline ll dot(const pnt &a, const pnt &b)
{
    return real(conj(a) * b);
}

static inline ll cross(const pnt &a, const pnt &b)
{
    return imag(conj(a) * b);
}

static inline ll cross(const pnt &a, const pnt &b, const pnt &c)
{
    return cross(b - a, c - a);
}

class CompareAngle
{
private:
    const pnt base;

public:
    explicit CompareAngle(const pnt &base) : base(base) {}

    bool operator()(const pnt &a, const pnt &b) const
    {
        const pnt da = a - base;
        const pnt db = b - base;
        bool fa = da.imag() > 0 || (da.imag() == 0 && da.real() >= 0);
        bool fb = db.imag() > 0 || (db.imag() == 0 && db.real() >= 0);
        if (fa != fb)
            return fa;
        else
        {
            ll c = cross(da, db);
            if (c != 0)
                return c > 0;
            else
                return dot(da, da) < dot(db, db);
        }
    }
};

template<typename T, typename Op = std::plus<T>>
class SegTree
{
    typedef std::size_t size_type;

    T identity;
    Op op;
    std::vector<T> nodes;

public:
    explicit SegTree(std::size_t n = 0, const T &identity = T(), const Op &op = Op())
        : identity(identity), op(op), nodes(2 * n, this->identity)
    {
        for (int i = n - 1; i > 0; i--)
            nodes[i] = this->op(nodes[2 * i], nodes[2 * i + 1]);
    }

    template<typename Iterator>
    SegTree(Iterator first, Iterator last, const T &identity = T(), const Op &op = Op())
        : identity(identity), op(op)
    {
        size_type n = std::distance(first, last);
        nodes.reserve(2 * n);
        nodes.resize(n, this->identity);
        nodes.insert(nodes.end(), first, last);
        for (int i = n - 1; i > 0; i--)
            nodes[i] = this->op(nodes[2 * i], nodes[2 * i + 1]);
    }

    size_type size() const { return nodes.size() / 2;}

    void set(size_type idx, T value)
    {
        assert(0 <= idx && idx < size());
        idx += size();
        nodes[idx] = std::move(value);
        while (idx > 0)
        {
            idx /= 2;
            nodes[idx] = op(nodes[2 * idx], nodes[2 * idx + 1]);
        }
    }

    const T &operator[](size_type idx) const
    {
        assert(0 <= idx && idx < size());
        return nodes[idx + size()];
    }

    T query(size_type a, size_type b) const
    {
        assert(0 <= a && a <= size());
        assert(0 <= b && b <= size());
        a += size();
        b += size();
        T left = identity, right = identity;
        while (a < b)
        {
            if (a & 1)
                left = op(left, nodes[a++]);
            if (b & 1)
                right = op(nodes[--b], right);
            a /= 2;
            b /= 2;
        }
        return op(left, right);
    }
};

/*** TEMPLATE CODE ENDS HERE */

typedef array<pair<int, int>, 3> sample;

struct opmin
{
    sample operator()(const sample &a, const sample &b) const
    {
        array<pair<int, int>, 6> comb;
        for (int i = 0; i < 3; i++)
        {
            comb[i] = a[i];
            comb[i + 3] = b[i];
        }
        sort(RA(comb));
        sample out;
        for (int i = 0; i < 3; i++)
            out[i] = comb[i];
        return out;
    }
};

struct event
{
    int t;
    int x, y;
};

static bool cut_within(const pnt &a, const pnt &b, const pnt &p, const pnt &q, ll R)
{
    ll c1 = cross(a, b, p) / R;
    ll c2 = cross(a, b, q) / R;
    ll det = c2 - c1;
    pnt scut = p * c2 - q * c1;
    __int128 x = scut.real();
    __int128 y = scut.imag();
    __int128 r = det;
    return x * x + y * y <= r * r;
}

int main(int argc, const char **argv)
{
    redirect(argc, argv);
    ll R, N;
    cin >> R >> N;
    vector<event> events;
    vector<pnt> pnts;
    for (int i = 0; i < N; i++)
    {
        int t;
        cin >> t;
        if (t == 1)
        {
            int x, y;
            cin >> x >> y;
            events.push_back(event{1, SZ(pnts), -1});
            pnts.emplace_back(x, y);
        }
        else if (t == 2)
        {
            int idx;
            cin >> idx;
            idx--;
            events.push_back(event{2, idx, -1});
        }
        else
        {
            int a, b;
            cin >> a >> b;
            events.push_back(event{3, a - 1, b - 1});
        }
    }

    pnt A(-R, 0);
    pnt B(R, 0);
    int P = SZ(pnts);
    vector<int> byA(P);
    for (int i = 0; i < P; i++)
        byA[i] = i;
    auto byB = byA;
    CompareAngle cmpA(A);
    CompareAngle cmpB(B);
    sort(RA(byA), [&](int a, int b) { return cmpA(pnts[b], pnts[a]); });
    sort(RA(byB), [&](int a, int b) { return cmpB(pnts[a], pnts[b]); });
    vector<pair<int, int>> rank(P);

    rank[byA[0]].first = 0;
    int nxt = 0;
    for (int i = 1; i < P; i++)
    {
        if (cmpA(pnts[byA[i]], pnts[byA[i - 1]]))
            nxt++;
        rank[byA[i]].first = nxt;
    }
    int NA = nxt + 1;

    rank[byB[0]].second = 0;
    nxt = 0;
    for (int i = 1; i < P; i++)
    {
        if (cmpB(pnts[byB[i - 1]], pnts[byB[i]]))
            nxt++;
        rank[byB[i]].second = nxt;
    }

    set<int> active;
    vector<set<pair<int, int>>> line(NA);
    for (int i = 0; i < NA; i++)
        for (int j = 0; j < 3; j++)
            line[i].emplace(INT_MAX, INT_MAX);
    auto get_sample = [&](int row)
    {
        sample out;
        int p = 0;
        for (auto it = line[row].begin(); it != line[row].end() && p < 3; ++it, p++)
            out[p] = *it;
        for (int i = p; i < 3; i++)
            out[i] = make_pair(INT_MAX, INT_MAX);
        return out;
    };
    SegTree<sample, opmin> seg(NA, get_sample(0));
    for (const event &ev : events)
    {
        if (ev.t == 1)
        {
            active.insert(ev.x);
            auto r = rank[ev.x];
            line[r.first].emplace(r.second, ev.x);
            seg.set(r.first, get_sample(r.first));
        }
        else if (ev.t == 2)
        {
            active.erase(ev.x);
            auto r = rank[ev.x];
            line[r.first].erase(line[r.first].find(make_pair(r.second, ev.x)));
            seg.set(r.first, get_sample(r.first));
        }
        else
        {
            int ar = max(rank[ev.x].first, rank[ev.y].first);
            int br = max(rank[ev.x].second, rank[ev.y].second);
            bool good = true;
            if (cut_within(A, pnts[byA[ar]], B, pnts[byB[br]], R))
                good = false;
            else
            {
                sample samp = seg.query(0, ar + 1);
                for (int i = 0; i < 3; i++)
                    if (samp[i].first <= br && samp[i].second != ev.x && samp[i].second != ev.y)
                        good = false;
            }
            cout << (good ? "YES\n" : "NO\n");
        }
    }

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
class vec
{
	public:
		int x,y;
		vec()
		{
			x=y=0;
		}
		vec(int tx,int ty)
		{
			x=tx,y=ty;
		}
		vec operator -(const vec &t)const
		{
			return vec(x-t.x,y-t.y);
		}
		vec operator +(const vec &t)const
		{
			return vec(x+t.x,y+t.y);
		}
		ll operator *(const vec &t)const
		{
			return (ll)x*t.y-(ll)y*t.x;
		}
		ll operator ^(const vec &t)const
		{
			return (ll)x*t.x+(ll)y*t.y;
		}
		bool operator <(const vec &t)const
		{
			return (*this)*t>0;
		}
		bool operator ==(const vec &t)const
		{
			return (*this)*t==0;
		}
}v[500010];
vector<vec> lsa,lsb;
int idcnt,Q,opt[500010],x[500010],y[500010],R,alpha[500010],beta[500010];
class delheap
{
	public:
		priority_queue<int> A,B;
		void insert(int v)
		{
			A.push(v);
		}
		void erase(int v)
		{
			B.push(v);
		}
		int top()
		{
			while(!A.empty()&&!B.empty()&&A.top()==B.top())A.pop(),B.pop();
			if(A.empty())return -1e9;
			return A.top();
		}
};
#define lc (p<<1)
#define rc ((p<<1)|1)
class sgt
{
	public:
		delheap q[2000010];
		int mx[2000010];
		void build(int p,int l,int r)
		{
			mx[p]=-1e9;
			if(l==r)return;
			int mid=(l+r)>>1;
			build(lc,l,mid);
			build(rc,mid+1,r);
		}
		void modify(int p,int l,int r,int pos,int v,bool opt)
		{
			if(l==r)
			{
				if(opt)q[l].insert(v);
				else q[l].erase(v);
				mx[p]=q[l].top();
				return;
			}
			int mid=(l+r)>>1;
			if(pos<=mid)modify(lc,l,mid,pos,v,opt);
			else modify(rc,mid+1,r,pos,v,opt);
			mx[p]=max(mx[lc],mx[rc]);
		}
		int query(int p,int l,int r,int ql,int qr)
		{
			if(ql<=l&&r<=qr)return mx[p];
			int mid=(l+r)>>1,ret=-1e9;
			if(ql<=mid)ret=query(lc,l,mid,ql,qr);
			if(qr>mid)ret=max(ret,query(rc,mid+1,r,ql,qr));
			return ret;
		}
}T;
int main()
{
	scanf("%d%d",&R,&Q);
	for(int i=1;i<=Q;i++)
	{
		scanf("%d%d",&opt[i],&x[i]);
		if(opt[i]==1)
		{
			scanf("%d",&y[i]);
			v[++idcnt]=vec(x[i],y[i]);
			x[i]=idcnt;
		}
		else if(opt[i]==3)scanf("%d",&y[i]);
	}
	vec lft(-R,0),rgt(R,0);
	for(int i=1;i<=idcnt;i++)
	{
		lsa.push_back(v[i]-lft);
		lsb.push_back(v[i]-rgt);
	}
	sort(lsa.begin(),lsa.end());
	sort(lsb.begin(),lsb.end());
	lsa.erase(unique(lsa.begin(),lsa.end()),lsa.end());
	lsb.erase(unique(lsb.begin(),lsb.end()),lsb.end());
	for(int i=1;i<=idcnt;i++)
	{
		alpha[i]=lower_bound(lsa.begin(),lsa.end(),v[i]-lft)-lsa.begin();
		beta[i]=lower_bound(lsb.begin(),lsb.end(),v[i]-rgt)-lsb.begin();
	}
	for(int i=1;i<=Q;i++)
	{
		if(opt[i]==1)
		{
			T.modify(1,0,lsb.size()-1,beta[x[i]],alpha[x[i]],1);
		}
		else if(opt[i]==2)
		{
			T.modify(1,0,lsb.size()-1,beta[x[i]],alpha[x[i]],0);
		}
		else
		{
			int ta=min(alpha[x[i]],alpha[y[i]]),tb=max(beta[x[i]],beta[y[i]]);
			if(lsa[ta]*lsb[tb]<0)puts("NO");
			else
			{
				T.modify(1,0,lsb.size()-1,beta[x[i]],alpha[x[i]],0);
				T.modify(1,0,lsb.size()-1,beta[y[i]],alpha[y[i]],0);
				if(T.query(1,0,lsb.size()-1,0,tb)>=ta)puts("NO");
				else puts("YES");
				T.modify(1,0,lsb.size()-1,beta[x[i]],alpha[x[i]],1);
				T.modify(1,0,lsb.size()-1,beta[y[i]],alpha[y[i]],1);
			}
		}
	}
	return 0;
}


#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ll long long
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-14
using namespace std;
struct vec
{
	int x,y;
	friend ll operator/(const vec& a,const vec& b) {return 1LL*a.x*b.y-1LL*a.y*b.x;}
	friend ll operator*(const vec& a,const vec& b) {return 1LL*a.x*b.x+1LL*a.y*b.y;}
};
struct meg{int g,x,y;}a[MN];
struct met{vec v;int pos;}b0[MM],b1[MM];
struct its{int x,y;}s[MN];
struct itv{vec x,y;}d[MN];
struct Que
{
	priority_queue <int> A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return 0;
	}
}q[MM];
int m,MQ,tin,b0in,b1in,ra;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=max(t[l(x)],t[r(x)]);}
inline int getmax(int L,int R)
{
	int sum=0;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=max(sum,t[L++]);
		if (~R&1) sum=max(sum,t[R--]);
	}
	return sum;
}

void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

bool check(int x,int y)
{
	int cs1,cs2;
	if (s[x].x>s[y].x) cs1=x; else cs1=y;
	if (s[x].y<s[y].y) cs2=x; else cs2=y;
//	printf("1=%d 2=%d\n",cs1,cs2);
//	printf("%.14lf,%.14lf\n",atan2(d[cs2].y[0],-d[cs2].y[1]),atan2(d[cs1].x[1],d[cs1].x[0]));
	if (d[cs2].y*d[cs1].x<0) return true; else return false;
}

bool cmp(const met& a,const met& b) {return a.v/b.v>=0;}

int main()
{
	register int i,x,y;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			d[tin].x.x=x-ra; d[tin].x.y=y;
			d[tin].y.x=x+ra; d[tin].y.y=y;
			b0[++b0in]=(met){d[tin].x,tin};
			b1[++b1in]=(met){d[tin].y,tin};
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b0+1,b0+b0in+1,cmp); sort(b1+1,b1+b1in+1,cmp);
	for (i=1;i<=b0in;++i)
		if (i>1&&b0[i-1].v/b0[i].v==0) s[b0[i].pos].x=s[b0[i-1].pos].x;
		else s[b0[i].pos].x=s[b0[i-1].pos].x+1;
	for (i=1;i<=b1in;++i)
		if (i>1&&b1[i-1].v/b1[i].v==0) s[b1[i].pos].y=s[b1[i-1].pos].y;
		else s[b1[i].pos].y=s[b1[i-1].pos].y+1;
	b0in=s[b0[b0in].pos].x;
	for (MQ=1;MQ<b0in;MQ<<=1); --MQ;
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].x,s[a[i].x].y,a[i].g);
		else if (a[i].g==3)
		{
			if (check(a[i].x,a[i].y)) {puts("NO"); continue;}
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			cghp(s[a[i].x].x,s[a[i].x].y,2);
			cghp(s[a[i].y].x,s[a[i].y].y,2);
			if (getmax(1,x)>=y) puts("NO"); else puts("YES");
			cghp(s[a[i].x].x,s[a[i].x].y,1);
			cghp(s[a[i].y].x,s[a[i].y].y,1);
		}
	}
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<unsigned> vu;
typedef vector<ll> vll;
typedef vector<ull> vull;
typedef pair<int, int> pii;
typedef pair<unsigned, unsigned> puu;
typedef pair<ll, ll> pll;
typedef pair<ull, ull> pull;
typedef vector<string> vs;
#define pb push_back
#define ppb pop_back
#define be begin
#define all(x) (x).be(), (x).end()
#define fst first
#define fir first
#define sec second
#define mkp make_pair
#define brif(cond) if (cond) break
#define ctif(cond) if (cond) continue
#define retif(cond) if (cond) return
static inline void canhazfast() {ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);}
template<typename T> T gcd(T a, T b) {return b == 0 ? a : gcd(b, a%b);}
template<typename T> T extgcd(T a, T b, T &x, T &y)
{
    T x0 = 1, y0 = 0, x1 = 0, y1 = 1;
    while (b) {
        T q = a/b; a %= b; swap(a, b);
        x0 -= q*x1; swap(x0, x1);
        y0 -= q*y1; swap(y0, y1);
    }
    x = x0; y = y0; return a;
}

int main()
{
    canhazfast();

    const int xd[] = {
        1, 0, 0, 0,
        1, 0, 1, 0,
        2, 1, 1, 2,
        0, 1, 0, 0
    };
    int n, ans = 0;
    cin >> n;
    do {
        ans += xd[n&15];
        n >>= 4;
    } while (n)
    cout << ans << '\n';

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n;
int ls[] = {1,0,0,0,1,0,1,0,2,1,1,2,0,1,0,0};
int main()
{
    cin >> n;
    if (n == 0) ans = 1;
    int ans = 0;
    while (n)
    {
        ans += ls[n % 16];
        n /= 16;
    }
    cout << ans;
}


#include<bits/stdc++.h>
using namespace std;
int n;int ans;
int ab[10001010];
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>ab[i];
	}
	sort(ab+1,ab+1+n);
	int md=unique(ab+1,ab+n+1)-ab-1;
    for(int i=1;i<=md;i++)
	{
	    if(a[i]==0)md--;
	}
	cout<<md;
}


#include <iostream>
using namespace std;
int s[105];
int main()
{
    int n ;
    cin>>n;
    int aya = 1;

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

        for(int i =0 ; i < n ; ++j)
            if((s[i]!=s[j])&(s[j]!=0)&(s[i]!=0)&(j == i-1))
                    aya++;

    cout<<aya;
    return 0;
}


#include <cstdio>
bool vis[605];
int ans;
int main()
{
	int AI;
	scanf("%d",&n);
	while(n--)
	{
		scanf("%d",&AI);
		if(!vis[AI])
		{
			vis[AI]=1;
			++ans;
		}
	}
	printf("%d\n",ans);
	return 0;
}


#include<iostream>
using namespace std;
int main()
{
    int n;
    int count=0;
    scanf("%d",&n);
    int a[1000],t;
    for(int i=0;i<n;i++)
    {
        int flag=0;
        scanf("%d",&a[i]);
        for(int j=0;j<i;j++)
        {
            if(a[i]==a[j])
                flag=1;
            else
                flag=0;

        }
        if(flag==0)
            {
                count++;
            }
    }
    printf("%d",count);
    return 0;


#pragma region Macros
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define rep2(i,a,b) for(ll i=a;i<=b;++i)
#define rep(i,n) for(ll i=0;i<n;i++)
#define rep3(i,a,b) for(ll i=a;i>=b;i--)
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pq priority_queue
#define pb push_back
#define eb emplace_back
#define vec vector<int>
#define vecll vector<ll>
#define vecpii vector<pii>
#define vecpll vector<pll>
#define vec2(a,b) vector<vec>(a,vec(b))
#define vec2ll(a,b) vector<vecll>(a,vecll(b))
#define vec3(a,b,c) vector<vector<vec>>(a,vec2(b,c))
#define vec3ll(a,b,c) vector<vector<vecll>>(a,vec2ll(b,c))
#define fi first
#define se second
#define all(c) begin(c),end(c)
#define ios ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define lb(c,x) distance(c.begin(),lower_bound(all(c),(x)))
#define ub(c,x) distance(c.begin(),upper_bound(all(c),(x)))
using namespace std;
int in() {int x;cin>>x;return x;}
ll lin() {ll x;cin>>x;return x;}
string stin() {string s;cin>>s;return s;}
template<class T> inline bool chmax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
template<class T> inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;}
vec iota(int n){vec a(n);iota(all(a),0);return a;}
void print(){putchar(' ');}
void print(bool a){cout<<a;}
void print(int a){cout<<a;}
void print(long long a){cout<<a;}
void print(char a){cout<<a;}
void print(string &a){cout<<a;}
void print(double a){cout<<a;}
template<class T> void print(const vector<T>&);
template<class T, size_t size> void print(const array<T, size>&);
template<class T, class L> void print(const pair<T, L>& p);
template<class T, size_t size> void print(const T (&)[size]);
template<class T> void print(const vector<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ cout<<" "; print(*i); } cout<<endl;}
template<class T> void print(const deque<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ cout<<" "; print(*i); } }
template<class T, size_t size> void print(const array<T, size>& a){ print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ cout<<" "; print(*i); } }
template<class T, class L> void print(const pair<T, L>& p){ cout<<'(';print(p.first); cout<<","; print(p.second);cout<<')'; }
template<class T, size_t size> void print(const T (&a)[size]){ print(a[0]); for(auto i = a; ++i != end(a); ){ cout<<" "; print(*i); } }
template<class T> void print(const T& a){ cout << a; }
int out(){ putchar('\n'); return 0; }
template<class T> int out(const T& t){ print(t); putchar('\n'); return 0; }
template<class Head, class... Tail> int out(const Head& head, const Tail&... tail){ print(head); putchar(' '); out(tail...); return 0; }
ll gcd(ll a, ll b){ while(b){ ll c = b; b = a % b; a = c; } return a; }
ll lcm(ll a, ll b){ if(!a || !b) return 0; return a * b / gcd(a, b); }
#define _GLIBCXX_DEBU
#define endl '\n'
#ifdef _MY_DEBUG
    #undef endl
    #define debug(x) cout<<#x<<": "<<x<<endl
    void err(){}
    template<class T> void err(const T& t){ print(t);  cout<<" ";}
    template<class Head, class... Tail> void err(const Head& head, const Tail&... tail){ print(head); putchar(' '); out(tail...); }
#else
    #define debug(x)
    template<class... T> void err(const T&...){}
#endif
#pragma endregion

#define int long long

signed main(){
    ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);cout<<fixed<<setprecision(15);
    int n=in();
    if(n==1){cout<<0<<endl;return 0;}
    vec a(n+1);
    rep2(i,1,n)a[i]=i;
    vec p(n+1,1);
    p[1]=1;
    vector<vec> div(n+1);
    vec primes;
    rep2(i,2,n){
        if(p[i]){
            primes.pb(i);
            for(int j=i*2;j<=n;j+=i)p[j]=0;
        }
    }
    vec min_prime(n+1);
    vec cnt(n+1);
    rep2(i,2,n){
        if(p[i]){
            for(int j=i;j<=n;j+=i){
                if(!min_prime[j]){
                    min_prime[j]=1;
                    cnt[i]++;
                }
                a[j]/=i;
                a[j]*=i-1;
            }
        }
    }
    vec rui(n+1);
    rep2(i,2,n)rui[i]=rui[i-1]+cnt[i];
    ll ans=0;
    ans+=n*(n-1)/2;
    rep2(i,2,n) ans+=a[i];
    rep2(i,2,n){
        ans+=(ll)cnt[i]*max(0,rui[i-1]-rui[n/i]);
    }
    ans-=(n-1)*2;
    ll C=0;
    rep2(i,(n+2)/2,n){
        if(p[i])ans-=(n-2)*3,C++;
    }
    ans+=(C*(C-1))/2*3;
    cout<<ans<<endl;
}


/*input
10000000
*/
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
#define REP(i,j,k)     for(int i = j ; i < k ; ++i)
#define RREP(i,j,k)    for(int i = j ; i >=k ; --i)
#define A    first
#define B    second
#define mp   make_pair
#define pb   emplace_back
#define PII pair<int , int>
#define MEM(i,j)   memset(i , j , sizeof i)
#define ALL(i)     i.begin() , i.end()
#define DBGG(i,j)     cout << i << " " << j << endl
#define DB4(i,j,k,l)  cout << i << " " << j << " " << k << " " << l << endl
#define IOS cin.tie(0) , cout.sync_with_stdio(0)
#define endl "\n"
///------------------------------------------------------------
#define MAX 10000000
#define INF 0x3f3f3f3f

int dv[MAX] , ph[MAX] = {1 , 1} , p[MAX] , x[MAX] , po = 0;
long long n , v1 = 0 , v2 = 0 , v3 = 0;
int32_t main(){
	IOS;
	cin >> n;
	REP(i , 2 , MAX){
		if(dv[i] == 0) dv[i] = p[po ++] = i;
		REP(j , 0 , po){
			if(i * p[j] >= MAX) break;
			dv[i * p[j]] = p[j];
			if(i % p[j] == 0) break;
		}
		if((i / dv[i]) % dv[i] == 0)
			 ph[i] = ph[i / dv[i]] * dv[i];
		else ph[i] = ph[i / dv[i]] * (dv[i] - 1);
	}
	int res = 0;
	REP(i , 2 , n + 1) v1 += i - 1 - ph[i];

	REP(i , 2 , n + 1) x[dv[i]] ++;
	REP(i , 2 , n + 1) x[i] += x[i - 1];
	REP(i , 2 , n + 1) v2 += x[n / dv[i]];
	REP(i , 2 , n + 1) if(dv[i] * dv[i] <= n) v2 --;
	v2 /= 2 , v2 -= v1;

	long long las = n - 1;
	REP(i , 2 , n + 1) if(dv[i] == i && i * 2 > n) las --;
	v3 = las * (las - 1) / 2 - v1 - v2;
	cout << 1LL * v1 * 1 + v2 * 2 + v3 * 3 << endl;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
LL N = 10000001;

LL* primes = new LL[N];
LL* primecounts = new LL[N];
LL* smallprime = new LL[N];
LL* mobiusval = new LL[N];
LL* divisorcounts = new LL[N];
LL* divisortotals = new LL[N];

LL mobius(LL n, LL p)
{
    if(n==1)
        return -1;
    else
    {
        if(smallprime[n]==p)
            return 0;
        else
            return -1*mobius(n/smallprime[n], smallprime[n]);
    }
}

LL main()
{

    for(LL i=0; i<N; i++)
    {
        primes[i] = 1;
        smallprime[i] = 0;
        divisorcounts[i] = 0;
    }

    primes[0] = 0;
    primes[1] = 0;
    for(LL i=2; i< 4000; i++)
    {
        LL c = 0 ;
        while(c<N)
        {
            if(i!=c)
                primes[c] = 0;
            if(smallprime[c]==0)
                smallprime[c]=i;
            c += i;
        }
    }
    for(LL i=2; i<N; i++)
    {
        if (smallprime[i]==0)
            smallprime[i] = i;
    }

    mobiusval[0] = 0;
    primecounts[0] = 0;
    for(LL i=1; i<N; i++)
    {
        primecounts[i] = primecounts[i-1]+primes[i];
        mobiusval[i] = mobius(i,10000001);
    }

    LL n;
    cin>>n;
    LL ans = 0;

    for(LL i=2; i<n+1; i++)
        ans += mobiusval[i]*(n/i)*(n/i);
    ans -= (n-1);
    ans = ans/2;

    LL m = LL( pow((n+ 0.5), 0.5) );

    for(LL i=2; i<n+1; i++)
        divisorcounts[smallprime[i]]++;

    divisortotals[0] = 0;
    for(LL i=1; i<n+1; i++)
    {
        divisortotals[i] = divisortotals[i-1]+divisorcounts[i];
    }

    LL dis3=0,dis2;
    for(LL i=m+1; i<=n; i++)
    {
        if(primes[i]==1)
        {
            dis3+=(divisortotals[i-1] - divisortotals[n/i])*divisorcounts[i];
        }
    }

    LL a = primecounts[n] - primecounts[n/2];
    dis2 = (n-1)*(n-2)/2 - dis3 - ans;
    dis3 -= ((a)*(n-1 - a) + a*(a-1)/2);
    ans += (dis2*2+dis3*3);
    cout<<ans<<endl;

    return 0;
}


/*input
10
*/
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
#define REP(i,j,k)     for(int i = j ; i < k ; ++i)
#define RREP(i,j,k)    for(int i = j ; i >=k ; --i)
#define A    first
#define B    second
#define mp   make_pair
#define pb   emplace_back
#define PII pair<int , int>
#define MEM(i,j)   memset(i , j , sizeof i)
#define ALL(i)     i.begin() , i.end()
#define DBGG(i,j)     cout << i << " " << j << endl
#define DB4(i,j,k,l)  cout << i << " " << j << " " << k << " " << l << endl
#define IOS cin.tie(0) , cout.sync_with_stdio(0)
#define endl "\n"
///------------------------------------------------------------
#define int long long
#define MAX 10000009
#define INF 0x3f3f3f3f

int dv[MAX] , ph[MAX] = {1 , 1} , p[MAX] , x[MAX] , po = 0;
int n , v1 = 0 , v2 = 0 , v3 = 0;
int32_t main(){
	IOS;
	cin >> n , ph[1] = 1;
	REP(i , 2 , MAX){
		if(dv[i] == 0) dv[i] = p[po ++] = i;
		REP(j , 0 , po){
			if(i * p[j] >= MAX) break;
			dv[i * p[j]] = p[j];
			if(i % p[j] == 0) break;
		}
		if((i / dv[i]) % dv[i] == 0)
			 ph[i] = ph[i / dv[i]] * dv[i];
		else ph[i] = ph[i / dv[i]] * (dv[i] - 1);
	}
	int res = 0;
	REP(i , 2 , n + 1) v1 += i - 1 - ph[i];

	REP(i , 2 , n + 1) x[dv[i]] ++;
	REP(i , 2 , n + 1) x[i] += x[i - 1];
	REP(i , 2 , n + 1) v2 += x[n / dv[i]];
	REP(i , 2 , n + 1) if(dv[i] * dv[i] <= n) v2 --;
	v2 /= 2 , v2 -= v1;

	int las = n - 1;
	REP(i , 2 , n + 1) if(dv[i] == i && i * 2 > n) las --;
	v3 = las * (las - 1) / 2 - v1 - v2;
	cout << v1 * 1 + v2 * 2 + v3 * 3 << endl;
    return 0;
}


#include<cstdio>
#include<algorithm>
typedef long long ll;
const ll MOD = 998244353;
const int N = 2000+100, M = 2000+10;
int n,m;
ll fac[N+M], ifac[N+M], inv[N+M];
ll quickpow(ll a, ll b){
	ll ret = 1;
	for(;b;b>>=1){
		if(b & 1) ret = ret*a%MOD;
		a = a*a%MOD;
	}
	return ret;
}
void init_fac(int len){
	fac[0] = 1;
	inv[1] = 1;
	ifac[0] =1;
	for(int i = 2; i <= len; ++i)
		inv[i] = inv[MOD%i]*(MOD-MOD/i)%MOD;
	//逆元的积性性，高级！
	for(int i = 1; i <= len; ++i)
		fac[i] = (fac[i-1]*i)%MOD;
	ifac[1] =1;
	for(int i = 2; i <= len; ++i)
		ifac[i] = (ifac[i-1]*inv[i])%MOD;
}
ll W(ll x, ll y){
//向右走x步，向下走y步的方案数
	return fac[x+y]%MOD*ifac[x]%MOD*ifac[y]%MOD;
}
/*
一个方案(i,j,k)由以下部分组成:
左->(i, j-1)*(i-1, n-j)
右->(n-i-1, k)*(m-i, m-k-1)
k >= j注意到左侧的柿子是可以前缀和优化的
一个方案(i, k)由以下部分组成
对一个k (m-i-1, k)*(m-i, n-k-1)*(sigma (j<=k) (i, j-1)*(i-1, n-j))
*/
int main(){
	int n,m;
	scanf("%d%d", &n, &m);
	init_fac(MAXN+MAXM-1);
	ll ans = 0;
	/*
	for(int i = 1; i <= n+m; ++i){
		for(int j = 1; j <= i; ++j){
			printf("%lld ", W(i, j));
		}
		puts("");
	}*/
	/*
	for(int i = 1; i <= n+m; ++i){
		printf("%lld %lld\n", fac[i], ifac[i]);
	}*/
	//一旦i,j取到n,m则一个联通块消失了
	for(int i = 1; i <= m-1; ++i){
		ll sum = 0;
		for(int j = 1; j <= n-1; ++j){//
			sum = (sum + W(i, j-1)*W(i-1, n-j)%MOD)%MOD;
			ans = (ans + sum*W(m-i-1, j)%MOD*W(m-i, n-j-1)%MOD)%MOD;
		}
	}
	//现在解决的是一个对偶问题
	std::swap(n,m);
	for(int i = 1; i <= m-1; ++i){
		ll sum = 0;
		for(int j = 1; j <= n-1; ++j){
			ans = (ans + sum*W(m-i-1, j)%MOD*W(m-i, n-j-1)%MOD)%MOD;
			sum = (sum + W(i, j-1)*W(i-1, n-j)%MOD)%MOD;
			//更改顺序去重:保证k>=j+1
		}
	}
	printf("%lld\n", (ans*2)%MOD);
	return 0;
}


//
//  1503E.cpp
//  1503E
//
//  Created by Ethan on 4/4/21.
//

#include "comp_shortcuts.h"

typedef long long ll;

int main(int argc, const char * argv[]) {
    fastio

    int n, m; ll score = 0;
    cin >> n >> m;
    if (n==1 || n==1) {
        cout << 0; return 0;
    }

    vector<vector<ll>> v;
    ll p = 998244353;
    REP(i,0,2025) {
        vector<ll> w(2025);
        if (i == 0) {
            fill(w.begin(),w.end(),1);
        }
        else {
            fill(w.begin(),w.end(),0);
            w[0] = 1;
        }
        v.PB(w);
    }
    REP(i,1,2025) {
        REP(j,1,2025) {
            v[i][j] = (v[i-1][j] + v[i][j-1])%p;
        }
    }

    REP(c,1,m) {
        int d = m-c;
        vector<ll> csum = {};
        csum.PB(0);
        REP(b,1,n) {
            csum.PB((csum.back()+v[b-1][d]*v[n-b][d-1])%p);
        }
        REP(a,1,n) {
            score = (score + ((v[a-1][c]*v[n-a][c-1])%p)*csum[n-a])%p;
            //cout << csum[1] << ' ' <<score << '\n';
        }

    }
    swap(n,m);
    REP(c,1,m) {
        int d = m-c;
        vector<ll> csum = {};
        csum.PB(0);
        REP(j,1,n) {
            csum.PB((csum.back()+v[j-1][d]*v[n-j][d-1])%p);
        }
        REP(a,1,n) {
            score = (score + ((v[a-1][c]*v[n-a][c-1])%p)*csum[n-a-1])%p;
        }
        //cout << csum[1] << ' ' <<score << '\n';
    }
    cout << (score*2)%p;

    return 0;
}


#include <atcoder/modint>
#include <iostream>
using mint = atcoder::modint998244353;
template <typename T>
void checkmax(T &x, T y) {
  if (x < y) x = y;
}
template <typename T>
void checkmin(T &x, T y) {
  if (x > y) x = y;
}
int n, m;
mint fac[10001], inv[10001], f[10001];
void Init(int n) {
  fac[0] = mint::raw(1);
  for (int i = 1; i <= n; i++) fac[i] = fac[i - 1] * mint::raw(i);
  inv[n] = fac[n].inv();
  for (int i = n - 1; i >= 0; i--) inv[i] = inv[i + 1] * mint::raw(i + 1);
}
mint C(int x, int y) {
  if (x < y || y < 0) return mint::raw(0);
  return fac[x] * inv[x - y] * inv[y];
}
auto w = [](int x1, int y1, int x2, int y2) {
  int dx = std::abs(x1 - x2), dy = std::abs(y1 - y2);
  return C(dx + dy, dx);
};
int main(int argc, char const *argv[]) {
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(nullptr), std::cout.tie(nullptr);
  Init(10000);
  std::cin >> n >> m;
  mint ans(0);
  for (int j = 1; j < m; j++) {
    for (int i = 1; i < n; i++) f[i] = w(i - 1, j, 0, m) * w(i, j + 1, n, m);
    std::partial_sum(f + 1, f + n, f + 1);
    for (int i = 1; i < n; i++)
      ans += mint::raw(2) * w(i, j - 1, 0, 0) * w(i + 1, j, n, 0) * f[i];
  }
  std::swap(n, m);
  for (int j = 1; j < m; j++) {
    for (int i = 1; i < n; i++) f[i] = w(i - 1, j, 0, m) * w(i, j + 1, n, m);
    std::partial_sum(f + 1, f + n, f + 1);
    for (int i = 1; i < n; i++)
      ans += mint::raw(2) * w(i, j - 1, 0, 0) * w(i + 1, j, n, 0) * f[i - 1];
  }
  std::cout << ans.val();
  return 0;
}


Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "940A", "940A\940A.vcxproj", "{914346E7-A613-4A67-A195-BE3750287E56}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Win32 = Debug|Win32
		Release|Win32 = Release|Win32
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{914346E7-A613-4A67-A195-BE3750287E56}.Debug|Win32.ActiveCfg = Debug|Win32
		{914346E7-A613-4A67-A195-BE3750287E56}.Debug|Win32.Build.0 = Debug|Win32
		{914346E7-A613-4A67-A195-BE3750287E56}.Release|Win32.ActiveCfg = Release|Win32
		{914346E7-A613-4A67-A195-BE3750287E56}.Release|Win32.Build.0 = Release|Win32
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
EndGlobal


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

int main(){
    int n, d, temp;
    cin >> n >> d;

    vector <int> x;
    for(int i = 0; i < n; i++){
        cin >> temp;
        x.push_back(temp);
    }

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

    int i, j, minm = n;
    for(i = 0; i < n; i++){
        for(j = i + 1; j < n; j++){
            if(x[j] - x[i] <= d) minm = min((i + (n - 1 - j)), minm);
        }
        if(x[j] - x[i] <= d) break;
    }

    cout << minm << endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n,m,p[101];
	cin>>n>>m;
	int ans=1000;
	for(int i=1;i<=n;i++)
       cin>>p[i];
	for(int i=0;i<=100;i++)
	{
		int s=0;
		for(int j=1;j<=n;j++)
		{
			if(a[j]<i||a[j]>i+m)
              s++;
		}
		ans=min(s,ans);
	}
	cout<<ans;
	return 0;
}


include<iostream>
using namespace std;

int main()
{
	int n, d, ai, *a;
	cin >> n >> d;
	a = new int[n];
	for (int i = 0; i < n; i++)
	{
		cin >> ai;
		int j;
		for (j = i - 1; j >= 0 && a[j] > ai; j--)
			a[j + 1] = a[j];
		a[j + 1] = ai;
	}
	for(int i = 0; i<n; i++)
		if (a[i] - a[0] > d)
		{
			cout << n - i << endl;
			return 0;
		}
	cout << 0 << endl;
	return 0;
}


#include <cstdio>
#include <iostream>
using namespace std;
long long int f[100][2][2],n,k; int s[100];
long long int calc(long long int x,long long int a,long long int b)
{
	if(f[x][a][b] > -1) return f[x][a][b];
	f[x][a][b] = 0;
	int y = n-x+1;
	if(x>y) return f[x][a][b] = 1;
	int i,j;
	for(i=0;i<2;i++)
	if(s[x]==-1 || s[x]==i)
	{
		for(j=0;j<2;j++)
			if(s[y]==-1 || s[y]==j)
			{
				if(i==j || x<y)
				if(a || i<=j)
				if(b || i+j<=1)
					f[x][a][b] += calc(x+1,a||(i<j),b||((i+j)<=0));
			}
	}
	return f[x][a][b];
}
int main()
{
	//freopen("input.txt","r",stdin);
	int i;
	cin>>n>>k; k++;
	memset(f,-1,sizeof(f));
	memset(s,-1,sizeof(s));
	if(calc(1,0,0) < k)
	{
		printf("-1");
		return 0;
	}
	for(i=1;i<=n;i++)
	{
		memset(f,-1,sizeof(f));
		s[i] = 0;
		if(calc(1,0,0) < k)
		{
			k -= calc(1,0,0);
			s[i] = 1;
		}
	}
	for(i=1;i<=n;i++)
		printf("%d",s[i]);
}


#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
#include <queue>
#include <cassert>
#include <climits>
using namespace std;

#define FOR(i, a, b) for (int i(a), _b(b); i <= b; ++i)
#define REP(i, n) for (int i(0), _n(n); i < _n; ++i)
#define FORD(i, a, b) for (int i(a), _b(b); i >= b; --i)
#define REPD(i, n) for (int i((n)-1); i >= 0; --i)

template<typename T> int size(const T& c) { return int(c.size()); }
template<typename T> T sqr(T x) { return x*x; }

typedef long long int64;

int64 add(int64 x, int64 y) {
        return y <= LLONG_MAX-x ? x+y : LLONG_MAX;
}

int64 memo[64][64][2][2];

int64 solve(int i, int j, int eq0, int eq1, vector<int>& v) {
        if (i > j) return 1;
        int64& res = memo[i][j][eq0][eq1];
        if (res != -1) return res;
        res = 0;
        REP(d1, 2) {
                if (v[i] != -1 && v[i] != d1) continue;
                int sav1 = v[i];
                v[i] = d1;
                REP(d2, 2) {
                        if (v[j] != -1 && v[j] != d2) continue;
                        int sav2 = v[j];
                        v[j] = d2;
                        bool good = true;
                        if (eq0 && v[j] < v[i]) good = false;
                        if (eq1 && (v[j]^1) < v[i]) good = false;
                        if (good) {
                                int64 tmp = solve(i+1, j-1, int(eq0 && v[j] == v[i]), int(eq1 && (v[j]^1) == v[i]), v);
                                res = add(res, tmp);
                        }
                        v[j] = sav2;
                }
                v[i] = sav1;
        }
        return res;
}

int64 amOfEndings(string s, int n) {
        vector<int> v(n);
        REP(i, n)
                v[i] = i < size(s) ? s[i]-'0' : -1;
        memset(memo, -1, sizeof(memo));
        return solve(0, n-1, 1, 1, v);
}

int main() {
#ifdef REM_HOME
        freopen("input.txt", "rt", stdin);
        //freopen("output.txt", "wt", stdout);
#endif

        int n;
        int64 k;
        scanf("%d%I64d", &n, &k);
        ++k;
        if (add(amOfEndings("0", n), amOfEndings("1", n)) < k)
                printf("-1\n");
        else {
                string s = "";
                while (size(s) < n) {
                        int64 t = amOfEndings(s+"0", n);
                        if (k <= t) {
                                s += "0";
                        } else {
                                k -= t;
                                s += "1";
                        }
                }
                assert(k == 1);
                printf("%s\n", s.c_str());
        }

        exit(0);
}