1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include <bits/stdc++.h>
//#include <emmintrin.h>

using namespace std;

#define FORE(it,c)  for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)
#define FOR(i,a,b)  for(int i=(a);i<(b);++i)
#define REP(i,a)    FOR(i,0,a)
#define ZERO(m)    memset(m,0,sizeof(m))
#define ALL(x)      x.begin(),x.end()
#define PB          push_back
#define S          size()
#define LL          long long
#define ULL        unsigned long long
#define LD          long double
#define MP          make_pair
#define X          first
#define Y          second
#define VC          vector
#define PII        pair <int, int>
#define VI          VC < int >
#define VPII          VC < PII >
#define VVI        VC < VI >
#define VD          VC < double >
#define VVD        VC < VD >
#define VS          VC < string >
#define DB(a)      cerr << #a << ": " << (a) << endl;

template<class T> void print(VC < T > v) {cerr << "[";if (v.S) cerr << v[0];FOR(i, 1, v.S) cerr << ", " << v[i];cerr << "]\n";}
template<class T> string i2s(T x) {ostringstream o; o << x; return o.str(); }
VS splt(string s, char c = ' ') {VS all; int p = 0, np; while (np = s.find(c, p), np >= 0) {if (np != p) all.PB(s.substr(p, np - p)); p = np + 1;} if (p < s.S) all.PB(s.substr(p)); return all;}

const int MOD = 1000000007;
const int MAXN = 1000100;
int n;
int c[MAXN];
int d[MAXN];

multiset<int> maxima;

int TV[MAXN];
int TM[MAXN];

VPII events[MAXN];

void addEvent(int p, int m, int v) {
	events[p].PB(MP(m, v));
}

int solvesq() {
	int maxPos = 0;
	int curM = 0;
	
	TV[0] = 1;
	TM[0] = 1;
	
	REP(i, n+1) {
		if (i) maxima.erase(maxima.find(d[i-1]));
		
		while (maxPos < n) {
			if (!maxima.empty() && min(*maxima.begin(), d[maxPos]) < maxPos + 1 - i) break;
			maxima.insert(d[maxPos++]);
		}
		
		for (PII p : events[i]) {
			if (p.X > 0) {
				curM = max(curM, p.X);
				TV[p.X] = (TV[p.X] + p.Y) % MOD;
				TM[p.X]++;
			} else {
				p.X = -p.X;
				TV[p.X] = (TV[p.X] - p.Y + MOD) % MOD;
				TM[p.X]--;
				while (TM[curM] == 0) curM--;
			}
		}
		
		if (i == n) break;
	
		if (i && curM == 0) continue;
		
		int mn = c[i];
		bool inside = false;
		FOR(j, i+1, maxPos+1) {
			if (j-i >= mn) {
				if (!inside) {
					addEvent(j, curM + 1, TV[curM]);
					inside = true;
				}
			} else if (inside) {
				addEvent(j, -(curM + 1), TV[curM]);
				inside = false;
			}
			
			mn = max(mn, c[j]);
		}
		
		if (inside)	addEvent(maxPos+1, -(curM + 1), TV[curM]);
		
	}
	
	if (curM == 0) {
		cout << "NIE" << endl;
	} else {
		cout << curM << ' ' << TV[curM] << endl;
	}
}

int main() {
	cin >> n;
	REP(i, n) scanf("%d%d", c+i, d+i);
	solvesq();
	return 0;
}