#pragma GCC optimize("Ofast,fast-math,unroll-loops")
  
#include <bits/stdc++.h>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
  
//#define int ll
//#define double long double
#define endl '\n'
#define all(C) (C).begin(), (C).end()
#define rall(C) (C).rbegin(), (C).rend()
#define mp make_pair 
#define pb emplace_back
#define dbg(x) cerr << #x << " : " << x << endl
//#define PI 3.141592653589
  
using namespace std;
//using namespace __gnu_pbds;
         
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using pii = pair <int, int>;
using pll = pair <ll, ll>;
using pld = pair <ld, ld>;
 
/*
const ll MAX_MEM = 5e8;
char MEM[MAX_MEM];
ll MEM_POS = 0;
void* operator new(size_t x)
{
    auto ret = MEM + MEM_POS;
    MEM_POS += x;
    assert(MEM_POS < MAX_MEM);
    return ret;
}
void operator delete(void*)
{}
 
*/
 
template <class T>
istream& operator>> (istream &in, vector <T> &a)
{
    for (auto &i : a)
        in >> i;
    return in;
}
         
template <class T> 
ostream& operator<< (ostream &out, vector <T> a)
{
    for (auto &i : a)
        out << i << ' ';
    return out;
}
         
template <class T, class U>
istream& operator>> (istream &in, pair <T, U> &p)
{
    in >> p.first >> p.second;
    return in;
}
         
template <class T, class U>
ostream& operator<< (ostream &out, pair <T, U> p)
{
    out << p.first << " " << p.second << " ";
    return out;
}
         
inline void Start()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    //freopen("circlecover.in", "r", stdin);
    //freopen("circlecover.out", "w", stdout);
}

const int P = 1e9 + 7;
int add(int a, int b)
{
    return a + b >= P ? a + b - P : a + b;
}
int mul(int a, int b)
{
    return ll(a) * b % P;
}
int bpow(int a, int n)
{
    int res = 1;
    while (n)
    {
        if (n & 1)
            res = mul(res, a);
        a = mul(a, a);
        n >>= 1;
    }
    return res;
}
int rev(int x)
{
    return bpow(x, P - 2);
}
int divi(int a, int b)
{
    return mul(a, rev(b));
}
int sub(int a, int b)
{
    return add(a, P - b);
}
const int N = 2001;
int _dp[2 * N][2 * N];
int _d[2 * N][2 * N];
int& dp(int i, int j)
{
    return _dp[i + N][j + N];
}
int& d(int i, int j)
{
    return _d[i + N][j + N];
}
const int INF = 1e9;

signed main()
{
    Start();
    int n;
    cin >> n;
    vector <int> a(n), b(n);
    for (int i = 0; i < n; ++i)
        cin >> a[i] >> b[i];
    for (int i = 0; i < 2 * N; ++i)
        for (int j = 0; j < 2 * N; ++j)
            _dp[i][j] = 0, _d[i][j] = INF;
    for (int i = 0; i < n; ++i)
        dp(-a[i], -b[i]) = add(dp(-a[i], -b[i]), 1);
    for (int i = 1; i < 2 * N; ++i)
        for (int j = 1; j < 2 * N; ++j)
            _dp[i][j] = add(_dp[i][j], add(_dp[i - 1][j], _dp[i][j - 1]));
    int sum = 0;
    for (int i = 0; i < n; ++i)
        sum = add(sum, dp(a[i], b[i]));
    vector <int> fact(4 * N, 1), revfact(4 * N, 1);
    for (int i = 1; i < 4 * N; ++i)
        fact[i] = mul(fact[i - 1], i), revfact[i] = divi(revfact[i - 1], i);
    for (int i = 0; i < n; ++i)
        sum = sub(sum, mul(fact[a[i] + b[i] + a[i] + b[i]], mul(revfact[a[i] + a[i]], revfact[b[i] + b[i]])));
    sum = divi(sum, 2);
    cout << sum;
    

    return 0;
}



Measured memory_bytes: 126976