#include <time.h>

#include <stdlib.h>
#include <cstdint>
#include <cassert>
#include <algorithm>
#include <functional>
#include <iostream>
#include <limits>
#include <cstdint>
#include <cassert>
#include <algorithm>
#include <functional>
#include <iostream>
#include <limits>
#include <vector>
#include <map>
#include <set>
#include <iomanip>
#include <numeric>
#include <cmath>
#include <bitset>
#include <iterator>
#include <deque>
#include <string>
using namespace std;
const int64_t INF=10000000000000000;


#include <cstdint>
#include <cassert>
#include <algorithm>
#include <functional>
#include <iostream>
#include <limits>

class SegmentTree_min {
public:
	SegmentTree_min(int64_t size,const int64_t *d);
	SegmentTree_min(const SegmentTree_min& t);
	SegmentTree_min& operator=(const SegmentTree_min& t);
	pair<int64_t,int64_t> calcmin(const int64_t a,const int64_t b) const;//[a,b]の間の最小値 戻り値のpairは、(最小値、その最小値のindex)
	void change(const int64_t address,const int64_t value);
	virtual ~SegmentTree_min();
private:
	int64_t max_depth;
	pair<int64_t,int64_t> calcmin(const int64_t a,const int64_t b,const int64_t ptr,const int64_t range_min,const int64_t range_max) const;
	//calcminからよばれる内部処理 [a,b]について、配列番号ptrのものを探索 配列番号ptrが指す範囲は、[range_min,range_max]
	int64_t size;
	int64_t *data;
	int64_t *min_index;//最小値を与える元データのindexを保持
};
SegmentTree_min::SegmentTree_min(int64_t dsize,const int64_t *d) {

	// TODO 自動生成されたコンストラクター・スタブ
	for(int i=63;i>=0;i--){
		if((uint64_t)dsize>((uint64_t)1<<i)){
			max_depth = i+1;
			break;
		}
	}
	this->size = ((uint64_t)1<<(max_depth));
	data = new int64_t[2*size-1];
	min_index = new int64_t[2*size-1];
	for(int64_t i=0;i<dsize;i++){
		data[size-1+i]=d[i];
		min_index[size-1+i]=i;
	}
	for(int64_t i=dsize;i<size;i++){
		data[size-1+i]=std::numeric_limits<int64_t>::max();
		min_index[size-1+i]=i;
	}
	for(int64_t i=size-2;i>=0;i--){
		if(data[2*i+1]<=data[2*i+2]){
			data[i]=data[2*i+1];
			min_index[i]=min_index[2*i+1];
		}else{
			data[i]=data[2*i+2];
			min_index[i]=min_index[2*i+2];
		}
	}
}
SegmentTree_min::SegmentTree_min(const SegmentTree_min& t){
	if(&t==this){
		max_depth = 1;
		size = 1;
		data = new int64_t[1];
		min_index = new int64_t[1];
		data[0]=0;
		min_index[0]=0;
	}else{
		max_depth = t.max_depth;
		size = t.size;
		data = new int64_t[2*size-1];
		min_index = new int64_t[2*size-1];
		for(int64_t i=0;i<(2*size-1);i++){
			data[i]=t.data[i];
			min_index[i]=t.min_index[i];
		}

	}
}
SegmentTree_min& SegmentTree_min::operator=(const SegmentTree_min& t){
	if(&t!=this){
		delete[] data;
		delete min_index;
		max_depth = t.max_depth;
		size = t.size;
		data = new int64_t[2*size-1];
		min_index = new int64_t[2*size-1];
		for(int64_t i=0;i<(2*size-1);i++){
			data[i]=t.data[i];
			min_index[i]=t.min_index[i];
		}
	}
	return *this;
}
pair<int64_t,int64_t> SegmentTree_min::calcmin(const int64_t a,const int64_t b) const{
	return calcmin(a,b,0,0,size-1);
}
pair<int64_t,int64_t> SegmentTree_min::calcmin(const int64_t a,const int64_t b,const int64_t ptr,const int64_t range_min,const int64_t range_max) const{
	if(a<=range_min&&b>=range_max){
		return make_pair(data[ptr],min_index[ptr]);
	}else{
		int64_t border = (range_max+range_min-1)/2;
		if(b<=border){
			return calcmin(a,b,2*ptr+1,range_min,border);
		}else if(a>=border+1){
			return calcmin(a,b,2*ptr+2,border+1,range_max);
		}else{
			pair<int64_t,int64_t> left_retval = calcmin(a,border,ptr*2+1,range_min,border);
			pair<int64_t,int64_t> right_retval = calcmin(border+1,b,ptr*2+2,border+1,range_max);
			if(left_retval.first<=right_retval.first){
				return left_retval;
			}else{
				return right_retval;
			}
		}
	}
}
void SegmentTree_min::change(const int64_t address,const int64_t value){
	data[address + size -1]=value;
	int64_t i=address+size-1;
	do{
		i=(i-1)/2;
		if(data[2*i+1]<=data[2*i+2]){
			data[i]=data[2*i+1];
			min_index[i]=min_index[2*i+1];
		}else{
			data[i]=data[2*i+2];
			min_index[i]=min_index[2*i+2];
		}
	}while(i!=0);
}
SegmentTree_min::~SegmentTree_min() {
	// TODO Auto-generated destructor stub
	delete[] data;
	delete min_index;
}
struct Robot{
	int64_t position;
	int64_t move;
	int64_t alpha;
	int64_t beta;
};

int operator < (const Robot &left,const Robot &right){
	return left.position<right.position;
}
int main(){
	int64_t n;
	cin>>n;
	vector<Robot> robots;
	for(int64_t i1=0;i1<n;i1++){
		Robot *temp = new Robot;
		cin>>(temp->position);
		cin>>(temp->move);
		temp->alpha=0;
		temp->beta=0;
		robots.push_back(*temp);
	}
	sort(robots.begin(),robots.end());

	int64_t *data=new int64_t[n];
	for(int64_t i1=0;i1<n;i1++){
		data[i1]=-(robots[i1].position+robots[i1].move);
	}
	SegmentTree_min after_move(n,data);

	for(int64_t i1=n-1;i1>=0;i1--){
		//calculate alpha
		if(i1==n-1){
			robots[i1].alpha=1;
		}else{
			robots[i1].alpha=(robots[i1+1].alpha+robots[i1+1].beta)%998244353;
		}
		//calculate beta
		if(robots[i1].position+robots[i1].move>robots[n-1].position){
			robots[i1].beta=1;
		}else{
			if(robots[i1].position+robots[i1].move<=robots[i1+1].position){
				robots[i1].beta=(robots[i1+1].alpha+robots[i1+1].beta)%998244353;
			}else{
				Robot comp;
				comp.position=robots[i1].position+robots[i1].move;
				int64_t top_index = distance(robots.begin(),std::lower_bound(robots.begin(),robots.end(),comp))-1;
				robots[i1].beta=robots[after_move.calcmin(i1+1,top_index).second].beta;
			}
		}
	}
	cout<<(robots[0].alpha+robots[0].beta)%998244353<<endl;


}


Measured memory_bytes: 27496