思路:枚举第一个碰到的被攻击的点
#include <bits/stdc++.h>
using namespace std;
typedef int lint;
typedef long long LL;
const int maxn = 10000005;
const int maxm = 3005;
const int mod = 998244353;
typedef unsigned long long ll;
const ll oo=mod;
ll frac[maxn], carf[maxn];
ll inv(ll x){
if (x==1) return 1;
else return (oo-oo/x)*inv(oo%x)%oo;
}
void init(){
frac[0]=1;
for (int i=1;i<=10000001;i++)
frac[i]=frac[i-1]*i%oo;
carf[10000001]=inv(frac[10000001]);
for (int i=10000001;i>=1;i--)
carf[i-1]=carf[i]*i%oo;
}
ll C(int n, int m){
if (m>n ) return 0;
else return frac[n]*carf[n-m]%oo*carf[m]%oo;
}
struct point{
lint t,p;
point( lint tt = 0,lint pp = 0 ){
t = tt;p = pp;
}
bool operator < ( const point&b )const{
if( p == b.p ) return t < b.t;
return t < b.t;
}
};
vector<point> ve;
LL g[maxn],S[maxn],f[maxm];
int main(){
init();
//cout << C( 0,0 ) << endl;
lint L,d,m,t,p;
scanf("%d%d%d",&L,&d,&m);
for( lint i = 1;i <= m;i++ ){
scanf("%d%d",&t,&p);
ve.push_back( point( t,p ) );
}
sort( ve.begin(),ve.end() );
g[0] = 1;
S[0] = 1;
for( int i = 1;i <= d-1;i++ ) g[i] = 0,S[i] = S[i-1];
for( int i = d;i <= L;i++ ){
g[i] = S[i-d];
S[i] = (S[i-1]+g[i])%mod;
}
for( lint i = 0; i< ve.size();i++ ){
if( ve[i].p-(LL)( d-1 )*ve[i].t-1 >= 0 )f[i] = C( ve[i].p-(LL)( d-1 )*ve[i].t-1,ve[i].t-1 );
for( lint j = 0;j < i;j++ ){
if( ve[i].p > ve[j].p && ve[i].t > ve[j].t ) {
if( ve[i].p-ve[j].p-(LL)(d-1)* (ve[i].t-ve[j].t) -1 >= 0 )f[i] = (f[i] - f[j] * C( ve[i].p-ve[j].p-(LL)(d-1)* (ve[i].t-ve[j].t) -1 ,ve[i].t-ve[j].t-1 )%mod + mod)%mod;
}
}
}
LL ans = g[L];
for( lint i = 0;i < ve.size();i++ ){
ans = (ans + mod - f[i]*g[ L-ve[i].p ]%mod )%mod ;
}
cout << ans << endl;
return 0;
}