#include #include using namespace std; #define rep(i,a,b) for(int i=a;i=b;i--) #define fore(i,a) for(auto& i:a) #define ff first #define ss second #define all(a) begin(a),end(a) #define allr(a) rbegin(a),rend(a) #define pb push_back using ll =long long; using pii=pair; using pll=pair; using vi=vector; using vll=vector; template inline bool chmin(T& a,T b){return a>b?a=b,1:0;} template inline bool chmax(T& a,T b){return a::max()/2; const ll INFL=numeric_limits::max()/2; #define lb(c, x) distance((c).begin(), lower_bound(all(c), (x))) #define ub(c, x) distance((c).begin(), upper_bound(all(c), (x))) long long modpow(long long a, long long n, long long mod) { a%=mod; assert(a!=0||n!=0); if(a==0)return 0; long long res = 1; while (n > 0) { if (n & 1) res = res * a % mod; a = a * a % mod; n >>= 1; } return res; } template struct SegmentTree{ private: int n; vector data; const F f; T ti; public: SegmentTree()=default; SegmentTree(int n,F f,T ti):n(n),f(f),ti(ti),data(n<<1,ti){} SegmentTree(vector v,F f,T ti):n(v.size()),f(f),ti(ti),data(n<<1,ti){ for(int i=0;i=1;i--)data[i]=f(data[i<<1],data[i<<1|1]); } void update(int k,const T& val){ k+=n; data[k]=val; for(k>>=1;k>=1;k>>=1){ data[k]=f(data[k<<1],data[k<<1|1]); } } const T operator[](const int &k){return data[k+n];} void apply(int k,const T& val){ update(k,f(data[k+n],val)); } const T prod(int l,int r){ l+=n;r+=n; T vl=ti,vr=ti; for(;l>=1,r>>=1){ if(l&1)vl=f(vl,data[l++]); if(r&1)vr=f(data[--r],vr); } return f(vl,vr); } }; template SegmentTree get_SegmentTree(int n,F f,T ti){return SegmentTree(n,f,ti);} template SegmentTree get_SegmentTree(vector v,F f,T ti){return SegmentTree(v,f,ti);} void solve(){ } int main(){ cin.tie(0)->sync_with_stdio(0); int n;ll p;cin>>n>>p; //atcoder::fenwick_tree seg(n+1); auto seg=get_SegmentTree(n+1,[&p](ll a,ll b){return (a+b)%p;},0ll); vector> list(n+1); vector par(n+1);//par[i]:=iがどこに属するか vector w(n+1); vector dp(n+1);//(dp[i]+1)*w[i]をセグ木に入れる rep(i,1,n+1){ for(int j=i;j<=n;j+=i){ list[j].pb(i); } w[i]=1; par[i]=i; } rep(i,2,n+1){ fore(d,list[i]){ ll pre=par[d]; par[d]=i; w[pre]--; w[i]++; seg.update(pre,(dp[pre]+1)*w[pre]%p); } ll S=seg.prod(0,i); ll inv=modpow(i-list[i].size(),p-2,p); dp[i]=inv*((S+list[i].size())%p)%p; seg.update(i,(dp[i]+1)*w[i]%p); } cout<