stablegradients/pie-gem5-bysrc huggingface dataset:
// Original C++ solution (slower):
#include <cstdio>

#include <deque>

#include <iostream>

using namespace std;



int n;



signed main(void)

{

    cin >> n;

    int a;

    deque <int> b;

   for(int i=0; i<n; ++i)

    {

        cin >> a;

        int it= lower_bound(b.begin(),b.end(),a)-b.begin();

        if(!it) b.push_front(a);

        else b[it-1]=a;

    }

    cout << b.size() << "\n";

 

	return 0;

}

// Optimized solution to the same problem (faster):
#include <cstdio>

#define N 100010

using namespace std;



int n, a, t[N];



inline void ef(int a) {

	int l = 1, r = t[0];

	while (l <= r) {

		int mid = (l + r) >> 1;

		if (t[mid] < a)

			r = mid - 1;

		else

			l = mid + 1;

	}

	t[l] = a;

}



int main() {

	scanf("%d", &n);

	for (int i = 1; i <= n; ++i) {

		scanf("%d", &a);

		if (i == 1)

			t[++t[0]] = a;

		else if (a <= t[t[0]])

			t[++t[0]] = a;

		else

			ef(a);

	}

	printf("%d", t[0]);

	return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;



typedef long long ll;

typedef pair<ll,ll> P;

typedef pair<P,ll> PLL;

typedef pair<P,P> PP;

typedef vector<ll> llVEC;

typedef vector<P> PVEC;

typedef priority_queue<P,PVEC,greater<P> > PPQ;

typedef priority_queue<ll, llVEC, greater<ll> > llPQ;



#define rep(i,a,n) for(ll i = a;i < n;i++)

#define rrep(i,a,n) for(ll i = n-1; i >= a;i--)

#define index_check(i,n) if(i > n-1 || i < 0) continue;

#define LINF (ll)1e18

#define INF (int)1e9

#define fs first

#define sc second



template<typename T>

ll sz(vector<T> vec){ return (ll)vec.size(); }

ll sz(string s){ return (ll)s.size(); }



ll gcd(ll a,ll b){ return ((!b) ?a :gcd(b, a%b)); }





int main(){

    ll n;

    cin >> n;

    ll a[n] = {};

    ll memo[200000] = {};

    fill(memo,memo+200000,LINF);

    ll index = 0;



    rep(i,0,n){

        ll a;

        cin >> a;



        ll ok = index+1, ng = -1;

        while(abs(ok-ng) > 1){

            ll mid = (ok+ng)/2;

            if(memo[mid] < a) ok = mid;

            else ng = mid;

        }



        if(ok == index+1) memo[index++] = a;

        else memo[ok] = a;

    }

    

    cout << index << endl;

    return 0;

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;



typedef long long ll;

typedef pair<ll,ll> P;

typedef pair<P,ll> PLL;

typedef pair<P,P> PP;

typedef vector<ll> llVEC;

typedef vector<P> PVEC;

typedef priority_queue<P,PVEC,greater<P> > PPQ;

typedef priority_queue<ll, llVEC, greater<ll> > llPQ;



#define rep(i,a,n) for(ll i = a;i < n;i++)

#define rrep(i,a,n) for(ll i = n-1; i >= a;i--)

#define index_check(i,n) if(i > n-1 || i < 0) continue;

#define LINF (ll)1e18

#define INF (int)1e9

#define fs first

#define sc second



template<typename T>

ll sz(vector<T> vec){ return (ll)vec.size(); }

ll sz(string s){ return (ll)s.size(); }



ll gcd(ll a,ll b){ return ((!b) ?a :gcd(b, a%b)); }





int main(){

    ll n;

    cin >> n;

    ll a[n] = {};

    vector<ll> vec(n);

    ll memo = 0;



    rep(i,0,n){

        ll a;

        cin >> a;



        ll ok = memo, ng = -1;

        while(abs(ok-ng) > 1){

            ll mid = (ok+ng)/2;

            if(vec[mid] < a) ok = mid;

            else ng = mid;

        }



        if(ok == memo) vec[memo++] = a;

        else vec[ok] = a;

    }

    

    cout << memo << endl;

    return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;

using Pi = pair < int , int >;



template < typename T > 

struct BIT

{

	vector < T > dat;



	BIT (int n)

	{

		dat.assign(n + 1, 0);

	}

	

	void add(int k, T x)

	{

		k++;

		while ( k <= dat.size() ) {

			dat[k] += x;

			k += k & -k;

		}

	}



	T query(int k)

	{

		T sum = 0;

		k++;

		while ( k > 0 ) {

			sum += dat[k];

			k -= k & -k;

		}

		return ( sum );

	}



	int lower_bound(T x)

	{

		int l, r;

		l = -1, r = dat.size();

		while ( l + 1 < r ) {

			int m = (l + r) / 2;

			if ( query(m) >= x ) r = m;

			else l = m;

		}

		return ( r );

	}

};



int main()

{

	int N;

	int A[100005];

	Pi dat[100005];



	map < Pi , int > idx;

	cin >> N;



	for ( int i = 0; i < N; i++ ) {

		cin >> A[i];

		dat[i] = Pi(A[i], -i);

	}

	sort(dat, dat + N);

	

	for ( int i = 0; i < N; i++ ) {

		idx[dat[i]] = i;

	}

	

	BIT < int > tree(N);	

	int ans = 0;

	for ( int i = 0; i < N; i++ ) {

		int pos = idx[Pi(A[i], -i)];

		int value = tree.query(pos);

		

		if ( value == 0 ) {

			ans++;

		} else {

			tree.add(tree.lower_bound(value), -1);

		}

		tree.add(pos, 1);

	}



	cout << ans << endl;



	return ( 0 );

}


// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;



int main()

{

	int N;

	deque < int > d;



	cin >> N;

	for ( int i = 0; i < N; i++ ) {

		int A, p;

		cin >> A;

		p = lower_bound(begin(d), end(d), A) - begin(d);

		if ( p == 0 ) d.push_front(A);

		else d[p - 1] = A;

	}



	cout << d.size() << endl;



	return ( 0 );

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;

/* typedef */

typedef long long ll;

typedef pair<int, int> pii;

/* constant */

const int INF = 1 << 30;

const ll LINF = 1LL << 50;

const int NIL = -1;

const int MAX = 100005;

const int mod = 1000000007;

const double pi = 3.141592653589;

/* global variables */

/* function */

/* main */

int main(){

    int N;

    cin >> N;

    vector<int> A(MAX), L(MAX, -1), D;

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

    L[0] = A[0];

    D.push_back(INF);

    int length = 1;

    for (int i = 1; i < N; i++) {

        if (L[length - 1] < A[i]) L[length++] = A[i];

        else {

            int ind = lower_bound(L.begin(), L.begin() + length, A[i]) - L.begin();

            int d = L[ind];

            L[ind] = A[i];

            if (d == -1) { continue; }

            auto itr = lower_bound(D.begin(), D.end(), d);

            if (itr == D.begin()) {

                D.insert(D.begin(), {d});

            }

            else *(itr - 1) = d;

        }

    }

    int ans = 1;

    if (D[0] != INF) ans += D.size() - 1;

    cout << ans << '\n';

}


// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;

/* typedef */

typedef long long ll;

typedef pair<int, int> pii;

/* constant */

const int INF = 1 << 30;

const ll LINF = 1LL << 50;

const int NIL = -1;

const int MAX = 10000;

const int mod = 1000000007;

const double pi = 3.141592653589;

/* global variables */

/* function */

/* main */

int main(){

    int N;

    cin >> N;

    vector<int> a(N);

    for (int i = 0; i < N; i++) cin >> a[i];

    vector<int> L(N + 1);

    L[0] = a[N-1];

    int length = 1;

    for (int i = N-2; i >= 0; i--) {

        if (L[length - 1] <= a[i]) L[length++] = a[i];

        else {

            *upper_bound(L.begin(), L.begin() + length, a[i]) = a[i];

        }

    }

    cout << length << '\n';

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;



const int maxn=2e5+5;

int a[maxn];

bool vis[maxn];



int main()

{

    int n;

    while(cin>>n){

        memset(vis, 0, sizeof(vis));

        multiset<int> LIS;

        for(int i=0;i<n;i++){

            cin>>a[i];

        }

        LIS.emplace(a[0]);

        for(int i=1;i<n;i++){

            if(a[i]<=*LIS.begin()){

                LIS.emplace(a[i]);

            }

            else{

                auto it = LIS.lower_bound(a[i]);

                if(it!=LIS.begin()) it--;

                LIS.erase(it);

                LIS.emplace(a[i]);

            }

        }

        cout<<LIS.size()<<endl;

    }

    return 0;

}


// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;



int main()

{

    int n;

    while(cin>>n){

        multiset<int> LIS;

        int temp;

        cin>>temp;

        LIS.insert(temp);

        for(int i=1;i<n;i++){

            cin>>temp;

            if(temp<=*LIS.begin()){

                LIS.insert(temp);

            }

            else{

                auto p = LIS.lower_bound(temp);

                if(p!=LIS.begin()) p--;

                LIS.erase(p);

                LIS.insert(temp);

            }

        }

        cout<<LIS.size()<<endl;

    }

    return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>



using namespace std;



const int N=100000+5;

const int inf=10000000;



int dis[N];

int f[N];

int dp[N];

int q[N];

int n;

int a[N];



int main()

{

	int i=1;

	cin>>n;

	int j;

	for(i=1;i<=n;++i)cin>>dis[i];

	for(i=0;i<N;++i)f[i]=inf; 

	i=1;

	for(j=1;j<=n;++j)

	{

		f[upper_bound(f+1,f+i+2,dis[j])-f]=dis[j];

		if(f[i+1]!=inf)i++;

	}

	int ans=0;

	reverse(dis+1,dis+1+n);

	memset(q,0x3f,sizeof(q));

	for(i=1;i<=n;++i)

	{

		dp[i]=upper_bound(q+1,q+n,dis[i])-q;

		q[dp[i]]=dis[i];

		ans=max(ans,dp[i]);

	}

	cout<<ans<<endl;

	return 0;

}


// Optimized solution to the same problem (faster):
#include<cstdio>

#include<set>

using namespace std;

const int MAXN=100005;

int n,a[MAXN],ans;

multiset<int>low;

int main()

{

    scanf("%d",&n);

    for (int i=1;i<=n;++i) scanf("%d",&a[i]);

    for (int i=1;i<=n;++i)

    {

        set<int>::iterator sec=low.upper_bound(-a[i]);

        if(sec!=low.end())

        {

            low.erase(sec);

            low.insert(-a[i]);

        } else {

            low.insert(-a[i]);

            ++ans;

        }

    }

    printf("%d",ans);

    return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>



using namespace std;



const int N=100000+5;

const int inf=10000000;



int dis[N];

int f[N];

int dp[N];

int q[N];

int n;

int a[N];



int main()

{

	int i=1;

	cin>>n;

	int j;

	for(i=1;i<=n;++i)cin>>dis[i];

	int ans=0;

	reverse(dis+1,dis+1+n);

	memset(q,0x3f,sizeof(q));

	for(i=1;i<=n;++i)

	{

		dp[i]=upper_bound(q+1,q+n,dis[i])-q;

		q[dp[i]]=dis[i];

		ans=max(ans,dp[i]);

	}

	cout<<ans<<endl;

	return 0;

}


// Optimized solution to the same problem (faster):
#include<cstdio>

#include<set>

using namespace std;

const int MAXN=100005;

int n,a[MAXN],ans;

multiset<int>low;

int main()

{

    scanf("%d",&n);

    for (int i=1;i<=n;++i) scanf("%d",&a[i]);

    for (int i=1;i<=n;++i)

    {

        set<int>::iterator sec=low.upper_bound(-a[i]);

        if(sec!=low.end())

        {

            low.erase(sec);

            low.insert(-a[i]);

        } else {

            low.insert(-a[i]);

            ++ans;

        }

    }

    printf("%d",ans);

    return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;



#define ll long long

#define ull unsigned long long

#define vii vector<int>

#define pii pair<int,int>

#define pll pair<long long,long long>

#define pdd pair<double,double>

#define pldld pair<long long double, long long double>

#define ff first

#define ss second

#define pb push_back

#define read freopen("alu.txt","r",stdin);

#define write freopen("vorta.txt","w",stdout);

#define fastio ios::sync_with_stdio(false); cin.tie(NULL);

#define PI 2*acos(0.0)

#define DEBUG(x) cerr << #x << " = " << x << endl



const int MAX = 3e5 + 5, MOD = 1e9 + 7, MAXLG = log2(MAX)+1;

const ll inf = 1e18 + 5;



int arr[MAX];

int mx = 0;

void compress(int n){

    vii v;

    for(int i=0;i<n;i++) v.pb(arr[i]);

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

    v.erase(unique(v.begin(),v.end()),v.end());

    for(int i=0;i<n;i++){

        int zipped=lower_bound(v.begin(),v.end(),arr[i])-v.begin()+1;

        arr[i]=zipped;

        mx=max(mx,zipped);

    }

}



int bit[MAX];

void update(int pos, int val){

    while(pos <= mx){

        bit[pos] = max(bit[pos], val);

        pos += (pos & (-pos));

    }

}



int get(int pos){

    int ret = 0;

    while(pos > 0){

        ret = max(ret, bit[pos]);

        pos -= (pos & (-pos));

    }

    return ret;

}



int col[MAX];

int main(){



    fastio;

    int n;

    cin>>n;

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

    compress(n);



    for(int i=n-1; i>=0; i--){

        int g = get(arr[i]);

        col[i] = g + 1;

        update(arr[i], g + 1);

//        cout<<g<<" "<<col[i]<<" "<<get(arr[i])<<"\n";

    }



    int ans = 0;

    for(int i=0; i<n; i++){

//        cout<<col[i]<<" ";

        ans = max(ans, col[i]);

    }

//    cout<<"\n";

    cout<<ans<<"\n";



}


// Optimized solution to the same problem (faster):
#include<cstdio>

#include<set>

using namespace std;

const int MAXN=100005;

int n,a[MAXN],ans;

multiset<int>low;

int main()

{

    scanf("%d",&n);

    for (int i=1;i<=n;++i) scanf("%d",&a[i]);

    for (int i=1;i<=n;++i)

    {

        set<int>::iterator sec=low.upper_bound(-a[i]);

        if(sec!=low.end())

        {

            low.erase(sec);

            low.insert(-a[i]);

        } else {

            low.insert(-a[i]);

            ++ans;

        }

    }

    printf("%d",ans);

    return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int main() {

    ios_base::sync_with_stdio(false);

    cin.tie(0);

    cout.tie(0);

    multiset<int> ms;

    int n;

    cin >> n;

    for (int i = 0; i < n; i++) {

        int x;

        cin >> x;

        ms.insert(-x);

        int tmp = x - 1;

        auto it = ms.find(-tmp);

        if (it != ms.end()) {

            ms.erase(it);

            continue;

        }

        it = ms.upper_bound(-tmp);

        if (it != ms.end()) ms.erase(it);

    }

    cout << ms.size();

    return 0;

}

// Optimized solution to the same problem (faster):
#include<cstdio>

#include<set>

using namespace std;

const int MAXN=100005;

int n,a[MAXN],ans;

multiset<int>low;

int main()

{

    scanf("%d",&n);

    for (int i=1;i<=n;++i) scanf("%d",&a[i]);

    for (int i=1;i<=n;++i)

    {

        set<int>::iterator sec=low.upper_bound(-a[i]);

        if(sec!=low.end())

        {

            low.erase(sec);

            low.insert(-a[i]);

        } else {

            low.insert(-a[i]);

            ++ans;

        }

    }

    printf("%d",ans);

    return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;

#define LL long long

#define sigma_size 30

#define max_size (int)(1e5+10)

#define MAX (int)(1e5+7)



int N;

int a[max_size];

const int INF = 1e9+7;

int main ()

{

	ios::sync_with_stdio(0);

	cin >> N ;

	vector <int> v;

	v.push_back(0);

	for ( int i = 1 ; i <= N ; i++ )

		cin >> a[i];

	for ( int i = 1 ; i <= N ; i++ )

	{

		if ( v.size() == 1 )

		{

			v.push_back(a[i]);

			continue;

		}

		int left = 1 , right = (int)v.size();

		while ( left < right )

		{

			int mid = left + right >> 1;

			if ( v[mid] < a[i] )

				right = mid;

			else left = mid+1;

		}

		if ( left == (int)v.size() )

			v.push_back(a[i]);

		else v[left] = a[i];

	}

	cout << v.size()-1 << endl;

}

// Optimized solution to the same problem (faster):
#include<cstdio>

#include<set>

using namespace std;

const int MAXN=100005;

int n,a[MAXN],ans;

multiset<int>low;

int main()

{

    scanf("%d",&n);

    for (int i=1;i<=n;++i) scanf("%d",&a[i]);

    for (int i=1;i<=n;++i)

    {

        set<int>::iterator sec=low.upper_bound(-a[i]);

        if(sec!=low.end())

        {

            low.erase(sec);

            low.insert(-a[i]);

        } else {

            low.insert(-a[i]);

            ++ans;

        }

    }

    printf("%d",ans);

    return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;

const int maxn = 100000 + 10;

const int INF = 0x3f3f3f3f;



int n,a[maxn],q[maxn],f[maxn],res;

int main() {

	scanf("%d",&n);

	for (int i = 1; i <= n; i++) {

		scanf("%d",&a[i]);

	}

	memset(q,0x3f,sizeof(q));

	q[0] = -INF;

	for (int i = 1; i <= n; i++) {

		f[i] = upper_bound(q + 1, q + n, -a[i]) - q;

		q[f[i]] = -a[i];

		res = max(res,f[i]);

	}

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

	return 0;

}

// Optimized solution to the same problem (faster):
#include <iostream>

#include<bits/stdc++.h>

using namespace std;

int num[100009]={0},a[100009]={0},f=0;

int main()

{

    int n,i,mi;

    scanf("%d",&n);

    for(i=1;i<=n;i++){

        int n1;

        scanf("%d",&n1);

        num[i]=n1;

    }

    a[1]=num[1];

    f++;

    mi=a[1];

    for(i=2;i<=n;i++){

        if(num[i]<=mi){

            mi=num[i];

            a[++f]=num[i];

        }

        else{

                for(int j=1;j<=f;j++){

                    if(a[j]<num[i]){

                        a[j]=num[i];

                        if(j==f)

                            mi=num[i];

                            break;

                    }

                }

        }

        //printf("%d  %d\n",mi,f);



    }

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



    return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <algorithm>

#include <bitset>

#include <cmath>

#include <cstdio>

#include <cstring>

#include <ctime>

#include <deque>

#include <fstream>

#include <iomanip>

#include <iostream>

#include <map>

#include <queue>

#include <random>

#include <set>

#include <stack>

#include <string>

#include <unordered_map>

#include <unordered_set>

#include <vector>

#define ll long long

#define ull unsigned long long

using namespace std;

void io() {

    ios::sync_with_stdio(false);

    cin.tie(nullptr);

    cout.tie(nullptr);

}



const int MAXN = 1e5 + 5;

const ll INF = 0x3f3f3f3f3f3f3f3f;

const ll MOD = 1e9 + 7;



int n;

int a[MAXN];

int t[MAXN];

int len;



int main() {

    io();

    memset(t, -1, sizeof(t));

    cin >> n;

    for (int i = 0; i < n; i++) {

        cin >> a[i];

    }

    for (int i = 0; i < n; i++) {

        int p = upper_bound(t, t + len, a[i], greater<int>()) - t;

        t[p] = a[i];

        if (p == len) {

            len++;

        }

    }

    cout << len;

}


// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

using namespace std;

const int maxn=1e5+5;

typedef long long ll;

const int inf =2e9;

int N,top=0;

int st[maxn];

int main(){

    cin>>N;

    st[top]=-inf;

    for(int i=1;i<=N;i++){

        int x;

        cin>>x;

        x=-x;

        if(x>=st[top])st[++top]=x;

        else{

            int l=1,r=top;

            while(l<=r){

                int mid=(l+r)/2;

                if(x>=st[mid])l=mid+1;

                else r=mid-1;

            }

            st[l]=x;

        }

    }

    cout<<top<<endl;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

#define INF 1e9

#define llINF 1e18

#define MOD 1000000007

#define pb push_back

#define mp make_pair 

#define F first

#define S second

#define ll long long

#define ull unsigned long long

#define vi vector<ll>

#define vvi vector<vi>

#define DBG_N(hoge) cerr<<" "<<(hoge)<<endl;

#define DBG cerr<<"!"<<endl;

#define BITLE(n) (1LL<<((ll)n))

#define BITCNT(n) (__builtin_popcountll(n))

#define SUBS(s,f,t) ((s).substr((f)-1,(t)-(f)+1))

#define ALL(a) (a).begin(),(a).end()

using namespace std;

ll cnt=0;

vi A(222222);

ll lis(int n){

  vi dp(222222,llINF);

  ll now=0;

  for(int i=0;i<n;i++){

    ll po=(upper_bound(ALL(dp),A[i])-dp.begin());

    dp[po]=A[i];

  }

  return lower_bound(ALL(dp),llINF)-dp.begin();

}



int main(){

  cin.tie(0);

  ios::sync_with_stdio(false);

  ll n;cin>>n;

  //int hoge[n+10]={};

  A.resize(n);

  for(int i=0;i<n;i++){

    cin>>A[i];

  }

  reverse(ALL(A));

  cout<<lis(n)<<endl;

  return 0;

}


// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

#define INF 1e9

#define llINF 1e18

#define MOD 1000000007

#define pb push_back

#define mp make_pair 

#define F first

#define S second

#define ll long long

#define vi vector<ll>

#define vvi vector<vi>

#define BITLE(n) (1LL<<((ll)n))

#define SHIFT_LEFT(n) (1LL<<((ll)n))

#define SUBS(s,f,t) ((s).substr((f),(t)-(f)))

#define ALL(a) (a).begin(),(a).end()

using namespace std;

ll lis(vi A){

  ll n = A.size();

  vi dp(n,llINF);

  for(int i=0;i<n;i++){

    *upper_bound(ALL(dp),A[i]) = A[i];

  }

  return (lower_bound(ALL(dp),llINF)-dp.begin());

}

int main(){

  cin.tie(0);

  ios::sync_with_stdio(false);

  ll n;cin>>n;

  vi A(n);

  for(auto &a:A)cin>>a;

  reverse(ALL(A));

  cout<<lis(A)<<endl;

  return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
//### In The Name Of GOD ###



#include <bits/stdc++.h>



using namespace std;



typedef long long ll ;



const int MOD = 1000000007;

const int INF = 30 * 1000 + 20;

const int MAXN = 2600;

const int MLOG = 18;

const int NMAX = 60;



#define int ll

#define pb push_back

#define pp pop_back

#define X first

#define Y second

#define IO ios_base::sync_with_stdio(false);

#define sz(a) (int)(a.size())

#define ct(x) const_cast<const int&>(x)



vector<int> primes;



bool prime(int x){

	for(int a : primes){

		if(x%a==0){

			return false;

		}

	}

	return true;

}



int32_t main(){

	primes.pb(2);

	for(int i = 3;i < MAXN;i++){

		if(prime(i)){

			primes.pb(i);

		}

	}

	int n;

	cin >> n;

	int ans = 1;

	int kk[primes.size()]={};



	for(int i = 1; i <= n ; i++){

		int a = i;

		for(int j=0;j<sz(primes);j++){

			while(a % primes[j]==0){

				a/=primes[j];

				kk[j]++;

			}

		}

	}	

	for(int i=0;i<sz(primes);i++){

//		if(kk[i] > 0)

//			cout << primes[i] << ' ' << kk[i] << endl;

		ans *= kk[i] + 1;

		ans %= MOD;

	}

	cout << ans;

}

// Optimized solution to the same problem (faster):
#include <iostream>



using namespace std;



const int M = 1e9+7,N = 1e3+1;



int freq[N];



int main()

{

    int n;long div=1;

    scanf("%d",&n);

    for(int i=2;i<=n;i++)

    {

        int x=i;

        for(int j=2;j*j<=x;j++)

        {

            while(x%j==0)

            {

            	x/=j;

                freq[j]++;

            }

        }

        if(x!=1)

          freq[x]++;

    }

    for(int i=2;i<=n;i++){

        div*=(freq[i]+1);

        div%=M;

    }

    printf("%ld\n",div);

    return 0;

}

// Fastest known solution for this problem: