#include using namespace std; using ll = long long; using ld = long double; using db = double; using str = string; // yay python! using pi = pair; using pl = pair; using pd = pair; using vi = vector; using vb = vector; using vl = vector; using vd = vector; using vs = vector; using vpi = vector; using vpl = vector; using vpd = vector; #define tcT template using V = vector; tcT, size_t SZ> using AR = array; tcT> using PR = pair; // pairs #define mp make_pair #define f first #define s second // vectors #define sz(x) (int)(x).size() #define all(x) begin(x), end(x) #define rall(x) (x).rbegin(), (x).rend() #define sor(x) sort(all(x)) #define rsz resize #define ins insert #define ft front() #define bk back() #define pf push_front #define pb push_back #define eb emplace_back #define lb lower_bound #define ub upper_bound // loops #define FOR(i,a,b) for (int i = (a); i < (b); ++i) #define F0R(i,a) FOR(i,0,a) #define ROF(i,a,b) for (int i = (b)-1; i >= (a); --i) #define R0F(i,a) ROF(i,0,a) #define trav(a,x) for (auto& a: x) const int MOD = 1e9+7; // 998244353; const int mxN = 5e3 + 5; const int mxD = 2e5 + 5; ll add(ll f, ll s){ f += s; if(f >= MOD) f %= MOD; if(f < 0) f += MOD; return f; } // add f to s and make sure it's in range ll mul(ll f, ll s){ f *= s; if(f >= MOD) f %= MOD; return f;} // multiply f and s and make sure it's in range ll pw(ll x, ll y) { ll ans = 1, ml = x; while(y) { if(y & 1) ans = mul(ans, ml); ml = mul(ml, ml); y >>= 1; } return ans; } // number x to a power y ll inv(ll x) { return pw(x, MOD - 2); } struct pnt { int x, y; pnt(int _x, int _y) { x = _x; y = _y; } bool operator<(pnt other) const { return x < other.x || (x == other.x && y < other.y); } }; int n, m, k; pl T2[mxN]; ll fac[mxD], inve[mxD]; ll way(int x, int y, int x1, int y1) { int dis1 = abs(x1 - x); int dis2 = abs(y1 - y); //ps(dis1, dis2, T[dis1][dis2]); return mul(fac[dis1 + dis2], mul(inve[dis1], inve[dis2])); //return T[dis1][dis2]; } int main() { ifstream fin("connectem.in"); ofstream fout("connectem.out"); int t; fin >> t; fac[0] = 1; inve[0] = inv(fac[0]); for(int i = 1; i < mxD; i++) { fac[i] = mul(fac[i - 1], i); inve[i] = inv(fac[i]); } //cout << way(1, 1, 5, 5); while(t--) { fin >> n >> m >> k; int x, y; vector v; for(int i = 0; i < k; i++) { fin >> x >> y; v.pb(pnt(x, y)); } sort(all(v)); pl ans = mp(0, 0); for(int i = 0; i < k; i++) { T2[i] = mp(1, way(1, 1, v[i].x, v[i].y)); for(int j = 0; j < i; j++) { if(v[j].y <= v[i].y) { pl temp = mp(T2[j].f + 1, mul(T2[j].s, way(v[j].x, v[j].y, v[i].x, v[i].y))); //ps(temp.f, temp.s); if(T2[i].f == temp.f) { T2[i].s = add(T2[i].s, temp.s); } else if(T2[i].f < temp.f) { T2[i] = temp; } } } //ps(T2[i].s); ans = max(ans, T2[i]); } //ps(ans.s); fout << ans.f << " " << ans.s << "\n"; } fin.close(); fout.close(); return 0; // you should actually read the stuff at the bottom } /* stuff you should look for * int overflow, array bounds * special cases (n=1?) * do smth instead of nothing and stay organized * WRITE STUFF DOWN * DON'T GET STUCK ON ONE APPROACH */