You are given an integer $$$x$$$. Can you make $$$x$$$ by summing up some number of $$$11, 111, 1111, 11111, \ldots$$$? (You can use any number among them any number of times).For instance,   $$$33=11+11+11$$$  $$$144=111+11+11+11$$$

The first line of input contains a single integer $$$t$$$ $$$(1 \leq t \leq 10000)$$$ — the number of testcases. The first and only line of each testcase contains a single integer $$$x$$$ $$$(1 \leq x \leq 10^9)$$$ — the number you have to make.

For each testcase, you should output a single string. If you can make $$$x$$$, output "YES" (without quotes). Otherwise, output "NO". You can print each letter of "YES" and "NO" in any case (upper or lower).

NoteWays to make $$$33$$$ and $$$144$$$ were presented in the statement. It can be proved that we can't present $$$69$$$ this way.

///////////////////////////////// pre-define ////////////////////////////////////////////////////////////////////////////////
const pr = console.log;
const mi = Math.min;
const mx = Math.max;
const mxll = (...args) => args.reduce((m, e) => e > m ? e : m);
const mill = (...args) => args.reduce((m, e) => e < m ? e : m);
const sqll = (v) => { if (v < 0n) throw 'negative input'; if (v < 2n) return v; const dfs = (n, x0) => { let x1 = ((n / x0) + x0) >> 1n; if (x0 === x1 || x0 === (x1 - 1n)) return x0; return dfs(n, x1); }; return dfs(v, 1n); }; // has >> 0
const abs = Math.abs;
const fl = Math.floor;
const ce = Math.ceil;
const sq = Math.sqrt;
const lge = Math.log;
const lg10 = Math.log10;
const ll = BigInt;
const combination = (m, n) => { return factorial(m, n) / factorial(n, n); };
const factorial = (m, n) => { let num = 1n; let cnt = 0; for (let i = ll(m); i > 0; i--) { if (cnt == n) break; num *= i; cnt++; } return num; };
const gcd = (a, b) => b == 0 ? a : gcd(b, a % b);
const lcm = (a, b) => (a / gcd(a, b)) * b;
const bitCount = (n) => { n = n - ((n >> 1) & 0x55555555); n = (n & 0x33333333) + ((n >> 2) & 0x33333333); return ((n + (n >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; };
const powmod = (a, b, mod) => { let r = 1n; while (b > 0n) { if (b % 2n == 1) r = r * a % mod; b >>= 1n; a = a * a % mod; } return r; };
const amax = (a) => mx.apply(Math, a);
const amin = (a) => mi.apply(Math, a);
const sm = (a) => a.reduce(((x, y) => x + y), 0);
const aeq = (a, b) => JSON.stringify(a) == JSON.stringify(b);
const swap = (a, i, j) => [a[i], a[j]] = [a[j], a[i]];
const stin = (a) => a.sort((x, y) => x - y);
const stde = (a) => a.sort((x, y) => y - x);
const sortPart = (a, k) => { let l = a.slice(0, k); l.sort((x, y) => x - y); let r = a.slice(k); return l.concat(r); }; // sort first kth
const initialize2DArrayNew = (m, n) => { let data = []; for (let i = 0; i < m; i++) { let tmp = Array(n).fill(0); data.push(tmp); } return data; };
const stmkey_in = (m) => new Map([...m].sort((x, y) => x[0] - y[0]));
const stmkey_de = (m) => new Map([...m].sort((x, y) => y[0] - x[0]));
const stmvalue_in = (m) => new Map([...m].sort((x, y) => x[1] - y[1]));
const stmvalue_de = (m) => new Map([...m].sort((x, y) => y[1] - x[1]));
const counter = (a_or_s) => { let map = new Map(); for (const i of a_or_s) map.set(i, map.get(i) + 1 || 1); return map; };
const counter_value_in_indexA_in = (a_or_s) => { let m = new Map(); let n = a_or_s.length; for (let i = 0; i < n; i++) { if (!m.has(a_or_s[i])) m.set(a_or_s[i], []); m.get(a_or_s[i]).push(i); } return m; };
const counter_value_in_indexA_de = (a_or_s) => { let m = new Map(); let n = a_or_s.length; for (let i = 0; i < n; i++) { if (!m.has(a_or_s[i])) m.set(a_or_s[i], []); m.get(a_or_s[i]).unshift(i); } return m; };
const reverse2 = (s) => { let res = ""; for (let i = s.length - 1; i >= 0; i--) { res += s[i]; } return res; };
const isPalindrome = (s) => { let n = s.length; let i = 0; let j = n - 1; while (i < j) { if (s[i++] != s[j--]) return false; } return true; };
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 05/28/21 night

const MAX = 111111;
let dp;
const solve = (x) => {
    pr(x >= 10000 ? 'YES' : (dp[x] ? 'YES' : 'NO'));
};

const prepare = () => {
    let n = MAX + 1;
    dp = Array(n).fill(0);
    dp[0] = 1;
    for (let i = 11; i <= MAX; i = i * 10 + 1) {
        for (let j = 0; j < n - i; j++) {
            dp[i + j] |= dp[j];
        }
    }
};

const main = () => {
    const readline = require('readline');
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });
    let input = [];
    rl.on('line', (line) => {
        input.push(Number(line));
    });
    rl.on('close', () => {
        let t = input[0];
        let i = 1;
        prepare();
        while (t--) {
            solve(input[i]);
            i++;
        }
    });
};

main()

///////////////////////////////// pre-define ////////////////////////////////////////////////////////////////////////////////
const pr = console.log;
const mi = Math.min;
const mx = Math.max;
const mxll = (...args) => args.reduce((m, e) => e > m ? e : m);
const mill = (...args) => args.reduce((m, e) => e < m ? e : m);
const sqll = (v) => { if (v < 0n) throw 'negative input'; if (v < 2n) return v; const dfs = (n, x0) => { let x1 = ((n / x0) + x0) >> 1n; if (x0 === x1 || x0 === (x1 - 1n)) return x0; return dfs(n, x1); }; return dfs(v, 1n); }; // has >> 0
const abs = Math.abs;
const fl = Math.floor;
const ce = Math.ceil;
const sq = Math.sqrt;
const lge = Math.log;
const lg10 = Math.log10;
const ll = BigInt;
const combination = (m, n) => { return factorial(m, n) / factorial(n, n); };
const factorial = (m, n) => { let num = 1n; let cnt = 0; for (let i = ll(m); i > 0; i--) { if (cnt == n) break; num *= i; cnt++; } return num; };
const gcd = (a, b) => b == 0 ? a : gcd(b, a % b);
const lcm = (a, b) => (a / gcd(a, b)) * b;
const bitCount = (n) => { n = n - ((n >> 1) & 0x55555555); n = (n & 0x33333333) + ((n >> 2) & 0x33333333); return ((n + (n >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; };
const powmod = (a, b, mod) => { let r = 1n; while (b > 0n) { if (b % 2n == 1) r = r * a % mod; b >>= 1n; a = a * a % mod; } return r; };
const amax = (a) => mx.apply(Math, a);
const amin = (a) => mi.apply(Math, a);
const sm = (a) => a.reduce(((x, y) => x + y), 0);
const aeq = (a, b) => JSON.stringify(a) == JSON.stringify(b);
const swap = (a, i, j) => [a[i], a[j]] = [a[j], a[i]];
const stin = (a) => a.sort((x, y) => x - y);
const stde = (a) => a.sort((x, y) => y - x);
const sortPart = (a, k) => { let l = a.slice(0, k); l.sort((x, y) => x - y); let r = a.slice(k); return l.concat(r); }; // sort first kth
const initialize2DArrayNew = (m, n) => { let data = []; for (let i = 0; i < m; i++) { let tmp = Array(n).fill(0); data.push(tmp); } return data; };
const stmkey_in = (m) => new Map([...m].sort((x, y) => x[0] - y[0]));
const stmkey_de = (m) => new Map([...m].sort((x, y) => y[0] - x[0]));
const stmvalue_in = (m) => new Map([...m].sort((x, y) => x[1] - y[1]));
const stmvalue_de = (m) => new Map([...m].sort((x, y) => y[1] - x[1]));
const counter = (a_or_s) => { let map = new Map(); for (const i of a_or_s) map.set(i, map.get(i) + 1 || 1); return map; };
const counter_value_in_indexA_in = (a_or_s) => { let m = new Map(); let n = a_or_s.length; for (let i = 0; i < n; i++) { if (!m.has(a_or_s[i])) m.set(a_or_s[i], []); m.get(a_or_s[i]).push(i); } return m; };
const counter_value_in_indexA_de = (a_or_s) => { let m = new Map(); let n = a_or_s.length; for (let i = 0; i < n; i++) { if (!m.has(a_or_s[i])) m.set(a_or_s[i], []); m.get(a_or_s[i]).unshift(i); } return m; };
const reverse2 = (s) => { let res = ""; for (let i = s.length - 1; i >= 0; i--) { res += s[i]; } return res; };
const isPalindrome = (s) => { let n = s.length; let i = 0; let j = n - 1; while (i < j) { if (s[i++] != s[j--]) return false; } return true; };
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 05/28/21 night

const solve = (x) => {
    pr(x >= 111 * (x % 11) ? 'YES' : 'NO');
};

const main = () => {
    const readline = require('readline');
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });
    let input = [];
    rl.on('line', (line) => {
        input.push(Number(line));
    });
    rl.on('close', () => {
        let t = input[0];
        let i = 1;
        while (t--) {
            solve(input[i]);
            i++;
        }
    });
};

main()

'use strict';
// HEADER:
const print = function(arg){
  let str = arg;
  if (arguments.length>1)
    str = Array.prototype.slice.call(arguments).join(' ');
  process.stdout.write(str+'\n');
};
let IS_MULTITEST, testN, tests;
const pcalc = (testN, toPrint)=>{
  let res = CALC(testN);
  if (Array.isArray(res)){
    toPrint.push(res.join(' '));
  } else if (Number.isFinite(res) || typeof res=='string'){
    toPrint.push(res+'');
  }
  if (process.env.DEBUG && toPrint.length){
    let ans = toPrint.pop();
    print(ans);
    let expected = tests[testN-1];
    if (expected){
      if (expected==ans)
        console.log('\x1b[32m%s\x1b[0m', 'correct');
      else {
        console.log('\x1b[31m%s\x1b[0m', 'wrong, expected:', expected);
      }
    }
  }
};

const main = ()=>{
  let toPrint = [];
  L('\nSolving:');
  if (IS_MULTITEST){
    let T = +readline()
    for (testN=1; testN<=T; testN++)
      pcalc(testN, toPrint);
  } else {
    pcalc(1, toPrint);
  }
  if (toPrint.length){
    print(toPrint.join('\n'));
  }
};

const lines = [];
const rl = require('readline').createInterface({
   input: process.stdin, output: process.stdout});
rl.on('line', line=>{
  lines.push(line);
});
rl.on('close', main);
let rli = 0;
const readline = ()=>lines[rli++];
const L = process.env.DEBUG ? console.log : ()=>{};
const LT = obj=>L(`\nTest #${testN}`, obj);

const ra = ()=>readline().split(' ').map(a=>+a)
const pa = arr=>print(arr.join(' '));

tests = [
``, // Test #1
``, // Test #2
``, // Test #3
``, // Test #4
``, // Test #5
];

// SOLUTION:
IS_MULTITEST = true;

const CALC = (testN)=>{
  // READING:
  let x = +readline();
  LT({x});
  // PROCESSING:
  if (x>1500)
    return 'YES';
  for (let i11=0; i11<150; i11++){
    for (let i111=0; i111<15; i111++){
      if (11*i11+111*i111===x)
        return 'YES'

    }

  }
  return 'NO'
};

/**
*    author:  Mohamed Abo Okail
*    created: O4/O6/2O21
**/

var t = parseInt(readline());

while(t--) {
  var x = parseInt(readline())
  if(111 * (x % 11) <= x) {
      print("YES");
  }
  else {
      print("NO");
  }
}

///////////////////////////////// pre-define ////////////////////////////////////////////////////////////////////////////////
const pr = console.log;
const mi = Math.min;
const mx = Math.max;
const mxll = (...args) => args.reduce((m, e) => e > m ? e : m);
const mill = (...args) => args.reduce((m, e) => e < m ? e : m);
const sqll = (v) => { if (v < 0n) throw 'negative input'; if (v < 2n) return v; const dfs = (n, x0) => { let x1 = ((n / x0) + x0) >> 1n; if (x0 === x1 || x0 === (x1 - 1n)) return x0; return dfs(n, x1); }; return dfs(v, 1n); }; // has >> 0
const abs = Math.abs;
const fl = Math.floor;
const ce = Math.ceil;
const sq = Math.sqrt;
const lge = Math.log;
const lg10 = Math.log10;
const ll = BigInt;
const combination = (m, n) => { return factorial(m, n) / factorial(n, n); };
const factorial = (m, n) => { let num = 1n; let cnt = 0; for (let i = ll(m); i > 0; i--) { if (cnt == n) break; num *= i; cnt++; } return num; };
const gcd = (a, b) => b == 0 ? a : gcd(b, a % b);
const lcm = (a, b) => (a / gcd(a, b)) * b;
const bitCount = (n) => { n = n - ((n >> 1) & 0x55555555); n = (n & 0x33333333) + ((n >> 2) & 0x33333333); return ((n + (n >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; };
const powmod = (a, b, mod) => { let r = 1n; while (b > 0n) { if (b % 2n == 1) r = r * a % mod; b >>= 1n; a = a * a % mod; } return r; };
const amax = (a) => mx.apply(Math, a);
const amin = (a) => mi.apply(Math, a);
const sm = (a) => a.reduce(((x, y) => x + y), 0);
const aeq = (a, b) => JSON.stringify(a) == JSON.stringify(b);
const swap = (a, i, j) => [a[i], a[j]] = [a[j], a[i]];
const stin = (a) => a.sort((x, y) => x - y);
const stde = (a) => a.sort((x, y) => y - x);
const sortPart = (a, k) => { let l = a.slice(0, k); l.sort((x, y) => x - y); let r = a.slice(k); return l.concat(r); }; // sort first kth
const initialize2DArrayNew = (m, n) => { let data = []; for (let i = 0; i < m; i++) { let tmp = Array(n).fill(0); data.push(tmp); } return data; };
const stmkey_in = (m) => new Map([...m].sort((x, y) => x[0] - y[0]));
const stmkey_de = (m) => new Map([...m].sort((x, y) => y[0] - x[0]));
const stmvalue_in = (m) => new Map([...m].sort((x, y) => x[1] - y[1]));
const stmvalue_de = (m) => new Map([...m].sort((x, y) => y[1] - x[1]));
const counter = (a_or_s) => { let map = new Map(); for (const i of a_or_s) map.set(i, map.get(i) + 1 || 1); return map; };
const counter_value_in_indexA_in = (a_or_s) => { let m = new Map(); let n = a_or_s.length; for (let i = 0; i < n; i++) { if (!m.has(a_or_s[i])) m.set(a_or_s[i], []); m.get(a_or_s[i]).push(i); } return m; };
const counter_value_in_indexA_de = (a_or_s) => { let m = new Map(); let n = a_or_s.length; for (let i = 0; i < n; i++) { if (!m.has(a_or_s[i])) m.set(a_or_s[i], []); m.get(a_or_s[i]).unshift(i); } return m; };
const reverse2 = (s) => { let res = ""; for (let i = s.length - 1; i >= 0; i--) { res += s[i]; } return res; };
const isPalindrome = (s) => { let n = s.length; let i = 0; let j = n - 1; while (i < j) { if (s[i++] != s[j--]) return false; } return true; };
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 * 05/28/21 morning
 * https://codeforces.com/contest/1526/problem/A
 */

const solve = (x) => {
    if (x == 1) return pr('YES');
    if (x == 10) return pr('NO');
    while ((x + '').length > 1) {
        let max = getMax(x);
        if (max == 1) break;
        x %= max;
        // pr(x, max);
        if (x == 0) return pr('YES');
    }
    // pr(x);
    pr('NO');
};

const getMax = (x) => {
    let s = x + '';
    let n = s.length;
    let max = '1'.repeat(n - 1);
    if (x >= Number(max + '1')) {
        max += '1';
    }
    return max - '0';
};
const main = () => {
    const readline = require('readline');
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });
    let input = [];
    rl.on('line', (line) => {
        input.push(Number(line));
    });
    rl.on('close', () => {
        let t = input[0];
        let i = 1;
        while (t--) {
            solve(input[i]);
            i++;
        }
    });
};

main()

// pr(3578 % 1111)

///////////////////////////////// pre-define ////////////////////////////////////////////////////////////////////////////////
const pr = console.log;
const mi = Math.min;
const mx = Math.max;
const mxll = (...args) => args.reduce((m, e) => e > m ? e : m);
const mill = (...args) => args.reduce((m, e) => e < m ? e : m);
const sqll = (v) => { if (v < 0n) throw 'negative input'; if (v < 2n) return v; const dfs = (n, x0) => { let x1 = ((n / x0) + x0) >> 1n; if (x0 === x1 || x0 === (x1 - 1n)) return x0; return dfs(n, x1); }; return dfs(v, 1n); }; // has >> 0
const abs = Math.abs;
const fl = Math.floor;
const ce = Math.ceil;
const sq = Math.sqrt;
const lge = Math.log;
const lg10 = Math.log10;
const ll = BigInt;
const combination = (m, n) => { return factorial(m, n) / factorial(n, n); };
const factorial = (m, n) => { let num = 1n; let cnt = 0; for (let i = ll(m); i > 0; i--) { if (cnt == n) break; num *= i; cnt++; } return num; };
const gcd = (a, b) => b == 0 ? a : gcd(b, a % b);
const lcm = (a, b) => (a / gcd(a, b)) * b;
const bitCount = (n) => { n = n - ((n >> 1) & 0x55555555); n = (n & 0x33333333) + ((n >> 2) & 0x33333333); return ((n + (n >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; };
const powmod = (a, b, mod) => { let r = 1n; while (b > 0n) { if (b % 2n == 1) r = r * a % mod; b >>= 1n; a = a * a % mod; } return r; };
const amax = (a) => mx.apply(Math, a);
const amin = (a) => mi.apply(Math, a);
const sm = (a) => a.reduce(((x, y) => x + y), 0);
const aeq = (a, b) => JSON.stringify(a) == JSON.stringify(b);
const swap = (a, i, j) => [a[i], a[j]] = [a[j], a[i]];
const stin = (a) => a.sort((x, y) => x - y);
const stde = (a) => a.sort((x, y) => y - x);
const sortPart = (a, k) => { let l = a.slice(0, k); l.sort((x, y) => x - y); let r = a.slice(k); return l.concat(r); }; // sort first kth
const initialize2DArrayNew = (m, n) => { let data = []; for (let i = 0; i < m; i++) { let tmp = Array(n).fill(0); data.push(tmp); } return data; };
const stmkey_in = (m) => new Map([...m].sort((x, y) => x[0] - y[0]));
const stmkey_de = (m) => new Map([...m].sort((x, y) => y[0] - x[0]));
const stmvalue_in = (m) => new Map([...m].sort((x, y) => x[1] - y[1]));
const stmvalue_de = (m) => new Map([...m].sort((x, y) => y[1] - x[1]));
const counter = (a_or_s) => { let map = new Map(); for (const i of a_or_s) map.set(i, map.get(i) + 1 || 1); return map; };
const counter_value_in_indexA_in = (a_or_s) => { let m = new Map(); let n = a_or_s.length; for (let i = 0; i < n; i++) { if (!m.has(a_or_s[i])) m.set(a_or_s[i], []); m.get(a_or_s[i]).push(i); } return m; };
const counter_value_in_indexA_de = (a_or_s) => { let m = new Map(); let n = a_or_s.length; for (let i = 0; i < n; i++) { if (!m.has(a_or_s[i])) m.set(a_or_s[i], []); m.get(a_or_s[i]).unshift(i); } return m; };
const reverse2 = (s) => { let res = ""; for (let i = s.length - 1; i >= 0; i--) { res += s[i]; } return res; };
const isPalindrome = (s) => { let n = s.length; let i = 0; let j = n - 1; while (i < j) { if (s[i++] != s[j--]) return false; } return true; };
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 * 05/28/21 morning
 * https://codeforces.com/contest/1526/problem/A
 */

const solve = (x) => {
    while((x + '').length > 1) {
       let max = getMax(x);
       x %= max;
       if (x == 0) return pr('YES');
    }
    // pr(x);
    pr('NO');
};

const getMax = (x) => {
    let s = x + '';
    let n = s.length;
    let max = '1'.repeat(n - 1);
    if (x >= Number(max + '1')) {
        max += '1';
    }
    return max - '0';
};
const main = () => {
    const readline = require('readline');
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });
    let input = [];
    rl.on('line', (line) => {
        input.push(Number(line));
    });
    rl.on('close', () => {
        let t = input[0];
        let i = 1;
        while (t--) {
            solve(input[i]);
            i++;
        }
    });
};

main()

'use strict';
// HEADER:
const print = function(arg){
  let str = arg;
  if (arguments.length>1)
    str = Array.prototype.slice.call(arguments).join(' ');
  process.stdout.write(str+'\n');
};
let IS_MULTITEST, testN, tests;
const pcalc = (testN, toPrint)=>{
  let res = CALC(testN);
  if (Array.isArray(res)){
    toPrint.push(res.join(' '));
  } else if (Number.isFinite(res) || typeof res=='string'){
    toPrint.push(res+'');
  }
  if (process.env.DEBUG && toPrint.length){
    let ans = toPrint.pop();
    print(ans);
    let expected = tests[testN-1];
    if (expected){
      if (expected==ans)
        console.log('\x1b[32m%s\x1b[0m', 'correct');
      else {
        console.log('\x1b[31m%s\x1b[0m', 'wrong, expected:', expected);
      }
    }
  }
};

const main = ()=>{
  let toPrint = [];
  L('\nSolving:');
  if (IS_MULTITEST){
    let T = +readline()
    for (testN=1; testN<=T; testN++)
      pcalc(testN, toPrint);
  } else {
    pcalc(1, toPrint);
  }
  if (toPrint.length){
    print(toPrint.join('\n'));
  }
};

const lines = [];
const rl = require('readline').createInterface({
   input: process.stdin, output: process.stdout});
rl.on('line', line=>{
  lines.push(line);
});
rl.on('close', main);
let rli = 0;
const readline = ()=>lines[rli++];
const L = process.env.DEBUG ? console.log : ()=>{};
const LT = obj=>L(`\nTest #${testN}`, obj);

const ra = ()=>readline().split(' ').map(a=>+a)
const pa = arr=>print(arr.join(' '));

tests = [
``, // Test #1
``, // Test #2
``, // Test #3
``, // Test #4
``, // Test #5
];

// SOLUTION:
IS_MULTITEST = true;

const CALC = (testN)=>{
  // READING:
  let x = readline();
  LT({x});
  // PROCESSING:
  return x[x.length-1]===x[x.length-2] ? 'YES' : 'NO'
  if (+x<11)
    return 'NO'
  for (let i=x.length-2; i>=0; i--){
    if (x[i]>x[i+1])
      return 'NO'
  }
  return 'YES';
  let ans = 0;
  let ones = [];
  let d = 11;
  while (d<1e9){
    ones.push(d);
    d = d*10+1;
  }
  let flag = true;
  while (flag){
    for (let i=0; i<ones.length; i++){

    }

  }
  let r = ones.length-1;
  while (x>0 && r>=0){
    while (x>=ones[r]){
      x -= ones[r]
    };
    r--;
  }
  return x==0 ? 'YES' : 'NO';
};

'use strict';
// HEADER:
const print = function(arg){
  let str = arg;
  if (arguments.length>1)
    str = Array.prototype.slice.call(arguments).join(' ');
  process.stdout.write(str+'\n');
};
let IS_MULTITEST, testN, tests;
const pcalc = (testN, toPrint)=>{
  let res = CALC(testN);
  if (Array.isArray(res)){
    toPrint.push(res.join(' '));
  } else if (Number.isFinite(res) || typeof res=='string'){
    toPrint.push(res+'');
  }
  if (process.env.DEBUG && toPrint.length){
    let ans = toPrint.pop();
    print(ans);
    let expected = tests[testN-1];
    if (expected){
      if (expected==ans)
        console.log('\x1b[32m%s\x1b[0m', 'correct');
      else {
        console.log('\x1b[31m%s\x1b[0m', 'wrong, expected:', expected);
      }
    }
  }
};

const main = ()=>{
  let toPrint = [];
  L('\nSolving:');
  if (IS_MULTITEST){
    let T = +readline()
    for (testN=1; testN<=T; testN++)
      pcalc(testN, toPrint);
  } else {
    pcalc(1, toPrint);
  }
  if (toPrint.length){
    print(toPrint.join('\n'));
  }
};

const lines = [];
const rl = require('readline').createInterface({
   input: process.stdin, output: process.stdout});
rl.on('line', line=>{
  lines.push(line);
});
rl.on('close', main);
let rli = 0;
const readline = ()=>lines[rli++];
const L = process.env.DEBUG ? console.log : ()=>{};
const LT = obj=>L(`\nTest #${testN}`, obj);

const ra = ()=>readline().split(' ').map(a=>+a)
const pa = arr=>print(arr.join(' '));

tests = [
``, // Test #1
``, // Test #2
``, // Test #3
``, // Test #4
``, // Test #5
];

// SOLUTION:
IS_MULTITEST = true;

const CALC = (testN)=>{
  // READING:
  let [x] = ra();
  LT({x});
  // PROCESSING:
  let ans = 0;
  let ones = [];
  let d = 11;
  while (d<1e9){
    ones.push(d);
    d = d*10+1;
  }
  let r = ones.length-1;
  while (x>0 && r>=0){
    while (x>=ones[r]){
      x -= ones[r]
    };
    r--;
  }
  return x==0 ? 'YES' : 'NO';
};


Today the «Z» city residents enjoy a shell game competition. The residents are gathered on the main square to watch the breath-taking performance. The performer puts 3 non-transparent cups upside down in a row. Then he openly puts a small ball under one of the cups and starts to shuffle the cups around very quickly so that on the whole he makes exactly 3 shuffles. After that the spectators have exactly one attempt to guess in which cup they think the ball is and if the answer is correct they get a prize. Maybe you can try to find the ball too?

The first input line contains an integer from 1 to 3 — index of the cup which covers the ball before the shuffles. The following three lines describe the shuffles. Each description of a shuffle contains two distinct integers from 1 to 3 — indexes of the cups which the performer shuffled this time. The cups are numbered from left to right and are renumbered after each shuffle from left to right again. In other words, the cup on the left always has index 1, the one in the middle — index 2 and the one on the right — index 3.

In the first line output an integer from 1 to 3 — index of the cup which will have the ball after all the shuffles.

fs = require('fs')

/*
const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

var indicator = 0, pos = -1;

rl.on('line', (input) => {
    if (indicator == 0) {
        pos = parseInt(input);
        indicator++;
    }
    else  {
        let temp = input.split(' ').map(item => parseInt(item));
        if (pos == temp[0])
            pos = temp[1];
        else if (pos == temp[1])
            pos = temp[0];
    }

  }).on('close', function() {
    console.log(pos);
  });
  */

 fs.readFile('input.txt', 'utf8', function (err,data) {
    if (err)
      return console.log(err);

    //console.log(data);
    let cont = data.split('\n').map(item => item.trim());
    //console.log(cont);
    let pos = parseInt(cont[0]);
    for (let i = 1; i < 4; i++) {
        let temp = cont[i].split(' ').map(item => parseInt(item));
        if (temp[0]==pos)
            pos = temp[1];
        else if (temp[1]==pos)
            pos = temp[0];

    }

    fs.writeFile('output.txt', pos.toString(), function (err) {
        if (err)
        return console.log(err);
       // console.log('Hello World > helloworld.txt');
      });
  });


The crowdedness of the discotheque would never stop our friends from having fun, but a bit more spaciousness won't hurt, will it?The discotheque can be seen as an infinite xy-plane, in which there are a total of n dancers. Once someone starts moving around, they will move only inside their own movement range, which is a circular area Ci described by a center (xi, yi) and a radius ri. No two ranges' borders have more than one common point, that is for every pair (i, j) (1 ≤ i < j ≤ n) either ranges Ci and Cj are disjoint, or one of them is a subset of the other. Note that it's possible that two ranges' borders share a single common point, but no two dancers have exactly the same ranges.Tsukihi, being one of them, defines the spaciousness to be the area covered by an odd number of movement ranges of dancers who are moving. An example is shown below, with shaded regions representing the spaciousness if everyone moves at the same time.  But no one keeps moving for the whole night after all, so the whole night's time is divided into two halves — before midnight and after midnight. Every dancer moves around in one half, while sitting down with friends in the other. The spaciousness of two halves are calculated separately and their sum should, of course, be as large as possible. The following figure shows an optimal solution to the example above.  By different plans of who dances in the first half and who does in the other, different sums of spaciousness over two halves are achieved. You are to find the largest achievable value of this sum.

The first line of input contains a positive integer n (1 ≤ n ≤ 1 000) — the number of dancers. The following n lines each describes a dancer: the i-th line among them contains three space-separated integers xi, yi and ri ( - 106 ≤ xi, yi ≤ 106, 1 ≤ ri ≤ 106), describing a circular movement range centered at (xi, yi) with radius ri.

Output one decimal number — the largest achievable sum of spaciousness over two halves of the night. The output is considered correct if it has a relative or absolute error of at most 10 - 9. Formally, let your answer be a, and the jury's answer be b. Your answer is considered correct if .

NoteThe first sample corresponds to the illustrations in the legend.

// Check in cir 1 is in cir 2
function isIn(cir1, cir2) {
	var distance = Math.sqrt(Math.pow((cir1.x - cir2.x),2) + Math.pow((cir1.y - cir2.y),2));
	return (distance < cir2.r && cir1.r < cir2.r);
}

var row = readline().split(" ").map(function(x) { return parseInt(x); });

var n = row[0];
var cir = [];

for(var i = 0; i < n; i++) {
	row = readline().split(" ").map(function(x) { return parseInt(x); });
	var area = row[2]*row[2]*Math.PI;
	cir.push({"x":row[0],"y":row[1],"r":row[2],"tier":1,"area":area});
}

var maxTier = 1;
for(var i = 0; i < n; i++) {
	for(var j = 0; j < n; j++) {
		if(i != j && isIn(cir[i], cir[j])) {
			cir[i].tier++;
			if(cir[i].tier > maxTier)
				maxTier = cir[i].tier;
		}
	}
}

var result = 0;
var areaTier = [];
var count = 0;
for(var i = 1; i <= maxTier; i++) {
	areaTier[i] = 0;
	count++;
	for(var j = 0; j < n; j++) {
		if(cir[j].tier == i) {
			areaTier[i] += cir[j].area;
		}
	}
	if(count == 1 || count == 2) {
		result += areaTier[i];
	} else {
		result -= areaTier[i];
		if(count == 3)
			count = 1;
	}
}

write(result);


You are given $$$n$$$ points on the plane, the coordinates of the $$$i$$$-th point are $$$(x_i, y_i)$$$. No two points have the same coordinates.The distance between points $$$i$$$ and $$$j$$$ is defined as $$$d(i,j) = |x_i - x_j| + |y_i - y_j|$$$.For each point, you have to choose a color, represented by an integer from $$$1$$$ to $$$n$$$. For every ordered triple of different points $$$(a,b,c)$$$, the following constraints should be met:  if $$$a$$$, $$$b$$$ and $$$c$$$ have the same color, then $$$d(a,b) = d(a,c) = d(b,c)$$$;  if $$$a$$$ and $$$b$$$ have the same color, and the color of $$$c$$$ is different from the color of $$$a$$$, then $$$d(a,b) < d(a,c)$$$ and $$$d(a,b) < d(b,c)$$$. Calculate the number of different ways to choose the colors that meet these constraints.

The first line contains one integer $$$n$$$ ($$$2 \le n \le 100$$$) — the number of points. Then $$$n$$$ lines follow. The $$$i$$$-th of them contains two integers $$$x_i$$$ and $$$y_i$$$ ($$$0 \le x_i, y_i \le 10^8$$$). No two points have the same coordinates (i. e. if $$$i \ne j$$$, then either $$$x_i \ne x_j$$$ or $$$y_i \ne y_j$$$).

Print one integer — the number of ways to choose the colors for the points. Since it can be large, print it modulo $$$998244353$$$.

'use strict';

function _defineProperty(obj, key, value) {
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true
    });
  } else {
    obj[key] = value;
  }

  return obj;
}

const MOD = 998244353;
async function solve(n, a) {
  const f = [1];
  for (let i = 1; i <= n; i++) {
    f[i] = mul(f[i - 1], i);
  }
  const edges = [];
  const dis = (i, j) => Math.abs(a[i][0] - a[j][0]) + Math.abs(a[i][1] - a[j][1]);
  for (let i = 0; i < n - 1; i++) {
    for (let j = i + 1; j < n; j++) {
      const d = dis(i, j);
      edges.push([i, j, d]);
    }
  }
  edges.sort((a, b) => a[2] - b[2]);
  const st = [];
  const check = arr => {
    if (arr.length > 4) return false;
    let t = -1;
    for (let i = 0; i < arr.length; i++) {
      if (st[arr[i]]) return false;
      for (let j = i + 1; j < arr.length; j++) {
        if (st[arr[j]]) return false;
        if (t == -1) t = dis(arr[i], arr[j]);else if (t !== dis(arr[i], arr[j])) return false;
      }
    }
    return true;
  };
  const pos = [];
  for (let i = 0, j = 0; i < edges.length; i = ++j) {
    while (j + 1 < edges.length && edges[i][2] === edges[j + 1][2]) {
      j++;
    }
    const uf = new UnionFind(n);
    for (let k = i; k <= j; k++) {
      const [u, v] = edges[k];
      uf.union(u, v);
    }
    const groups = [...uf.group().values()];
    pos.push(...groups.filter(check));
    for (let k = i; k <= j; k++) {
      const [u, v] = edges[k];
      st[u] = 1;
      st[v] = 1;
    }
  }
  let p2 = 0,
      p3 = 0,
      p4 = 0;
  for (let arr of pos) {
    if (arr.length === 2) p2++;else if (arr.length === 3) p3++;else p4++;
  }
  let res = 0;
  const ff = [1n];
  for (let i = 1; i <= n; i++) {
    ff[i] = ff[i - 1] * BigInt(i);
  }
  [0, 0, pos.filter(arr => arr.length === 2).length, pos.filter(arr => arr.length === 3).length, pos.filter(arr => arr.length === 4).length];
  const c = (i, n) => mul(f[n], mul(power(f[i], MOD - 2), power(f[n - i], MOD - 2)));
  for (let i = 0; i <= p2; i++) {
    for (let j = 0; j <= p3; j++) {
      for (let k = 0; k <= p4; k++) {
        const N = n - i - j * 2 - k * 3;
        res = mod(res + mul(f[N], c(i, p2), c(j, p3), c(k, p4), c(N, n)));
      }
    }
  }
  return mod(res);
}
const mod = num => (num % MOD + MOD) % MOD;
function power(a, b) {
  let res = 1;
  while (b) {
    if (b & 1) res = mul(res, a);
    a = mul(a, a);
    b = b >> 1;
  }
  return res;
}
function mul(...args) {
  if (args.length === 1) return args[0];
  if (args.length > 2) return mul(args[0], mul(...args.slice(1)));
  const [a, b] = args;
  return ((a >> 16) * b % MOD * 65536 + (a & 65535) * b) % MOD;
}
class UnionFind {
  constructor(n) {
    _defineProperty(this, "vis", []);
    this.n = n;
    this.p = [...new Array(n).keys()];
  }
  union(i, j) {
    this.vis[i] = this.vis[j] = 1;
    const [rooti, rootj] = [this.find(i), this.find(j)];
    if (rooti === rootj) return;
    this.p[rootj] = rooti;
  }
  find(i) {
    const {
      p
    } = this;
    while (i !== p[i]) {
      p[i] = p[p[i]];
      i = p[p[i]];
    }
    return i;
  }
  group() {
    const groups = new Map();
    for (let i = 0; i < this.n; i++) {
      var _groups$get;
      if (!this.vis[i]) continue;
      const root = this.find(i);
      if (!groups.has(root)) groups.set(root, []);
      (_groups$get = groups.get(root)) === null || _groups$get === void 0 ? void 0 : _groups$get.push(i);
    }
    return groups;
  }
}

async function main(read) {
  try {
    let res = [];
    let t = 1;
    while (t--) {
      const n = Number(await read());
      const a = [];
      let tmp = n;
      while (tmp--) {
        a.push((await read()).split(' ').map(Number));
      }
      res.push(await solve(n, a));
    }
    return res.join('\n');
  } catch (error) {
    console.log(error);
  }
}

let inputs,
    str = '';
function read() {
  return inputs.next().value.trim();
}
process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data', input => str += input);
process.stdin.on('end', async () => {
  inputs = str.split('\n').values();
  const output = await main(read);
  console.log(output);
});

class Scaner {
    data = [];
    constructor() {
        process.stdin.setEncoding('utf-8');
        process.stdin.on('data', _data => {
            let lasttext = this.data.pop();
            if (lasttext == undefined)
                lasttext = ""
            _data = lasttext + _data;
            const l = _data.split('\n');
            this.data = this.data.concat(l.slice(0, -1).map(string => string.trim()), l[l.length - 1]);
        });
    }
    read = async () => {
        process.stdin.resume();
        while (this.data.length < 2) {
            await delay(0);
        }
        process.stdin.pause();
        let res = this.data.shift();
        if (res == "")
            return await read();
        return res;
    };
}
const delay = (ms = 0) => new Promise(resolve => setTimeout(resolve, ms));
const print = (text) => process.stdout.write(text);
const scaner = new Scaner()
const read = scaner.read;
//----------------------------------------------------------------
//-----------------------the-code---------------------------------
//----------------------------------------------------------------

const dn = 998244353n;
const add = (x, y) => Number((BigInt(x) + BigInt(y)) % dn);
const mul = (x, y) => Number((BigInt(x) * BigInt(y)) % dn);
class Point {
    x = 0;
    y = 0;
    constructor(a = []) {
        this.x = a[0];
        this.y = a[1];
    }
    shortest = [];
    haveGroup = false;
}
class Ans {
    p = [];
    points = [];
    constructor(n) {
        this.p[n] = [1];
        for (var j = 0; j < n; j++) {
            this.p[n][j + 1] = mul(this.p[n][j], (n - j));
        }
    }
    addPoint(a = []) {
        this.points.push(new Point(a));
    }
    calculateShortest() {
        for (let curr in this.points) {
            let distance = [];
            const p1 = this.points[curr];
            let min = Infinity;
            for (let i in this.points) {
                if (i == curr)
                    continue;
                const p2 = this.points[i];
                distance[i] = Math.abs(p1.x - p2.x) + Math.abs(p1.y - p2.y);
                if (distance[i] < min)
                    min = distance[i];
            }
            distance[curr] = min;
            p1.shortest = distance.map((e, i) => e === min ? i : "").filter(String);
        }
    }
    haveGroup(p1 = new Point()) {//n**2
        p1.haveGroup = true;
        for (let b of p1.shortest) {
            const p2 = this.points[b];
            if (p1.shortest.length != p2.shortest.length) {
                p1.haveGroup = false;
                return;
            }
            for (let c in p2.shortest)
                if (p1.shortest[c] != p2.shortest[c]) {
                    p1.haveGroup = false;
                    return;
                }
        }
    }
    solve() {
        const n = this.points.length;
        for (let a = 0; a < n; a++) {//n**3
            const p1 = this.points[a];
            if (p1.haveGroup)
                continue;
            this.haveGroup(p1);
            if (p1.haveGroup) {
                p1.shortest.forEach(b => {
                    const p2 = this.points[b];
                    p2.haveGroup = true;
                });
                this.groups.push(p1.shortest.length - 1);
            }
        }
        const ways = (ng) => this.waysToGroups(this.groups.length - 1, ng);
        let sol = 0;
        for (let i = 1; i <= n; i++) {
            sol = add(sol, mul(ways(i), this.p[n][i]));
        }
        return sol;
    }
    groups = [];
    waysToGroups_db = [];
    waysToGroups(i, pn) {
        const N = this.points.length;
        if (i == -1) {
            if (N == pn)
                return 1;
            else
                return 0;
        }
        if (this.waysToGroups_db[i] == undefined)
            this.waysToGroups_db[i] = [];
        if (this.waysToGroups_db[i][pn] != undefined)
            return this.waysToGroups_db[i][pn];
        let c1 = this.waysToGroups(i - 1, pn);
        let c2 = 0;
        if (pn < N)
            c2 = this.waysToGroups(i - 1, pn + (this.groups[i]));
        return this.waysToGroups_db[i][pn] = add(c1, c2);
    }
}
(async () => {
    let t = parseInt(await read());
    let nn = t;
    let ans = new Ans(t);
    while (t--) {
        ans.addPoint(
            (await read()).split(' ').map(Number));
    }
    ans.calculateShortest();
    console.log(ans.solve());
})().then(() => { }
)

'use strict';

function _defineProperty(obj, key, value) {
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true
    });
  } else {
    obj[key] = value;
  }

  return obj;
}

const MOD = 998244353;
async function solve(n, a) {
  const f = [1];
  for (let i = 1; i <= n; i++) {
    f[i] = mul(f[i - 1], i);
  }
  const edges = [];
  const dis = (i, j) => Math.abs(a[i][0] - a[j][0]) + Math.abs(a[i][1] - a[j][1]);
  for (let i = 0; i < n - 1; i++) {
    for (let j = i + 1; j < n; j++) {
      const d = dis(i, j);
      edges.push([i, j, d]);
    }
  }
  edges.sort((a, b) => a[2] - b[2]);
  const st = [];
  const check = arr => {
    if (arr.length > 4) return false;
    let t = -1;
    for (let i = 0; i < arr.length; i++) {
      if (st[arr[i]]) return false;
      for (let j = i + 1; j < arr.length; j++) {
        if (st[arr[j]]) return false;
        if (t == -1) t = dis(arr[i], arr[j]);else if (t !== dis(arr[i], arr[j])) return false;
      }
    }
    return true;
  };
  const pos = [];
  for (let i = 0, j = 0; i < edges.length; i = ++j) {
    while (j + 1 < edges.length && edges[i][2] === edges[j + 1][2]) {
      j++;
    }
    const uf = new UnionFind(n);
    for (let k = i; k <= j; k++) {
      const [u, v] = edges[k];
      uf.union(u, v);
    }
    const groups = [...uf.group().values()];
    pos.push(...groups.filter(check));
    for (let k = i; k <= j; k++) {
      const [u, v] = edges[k];
      st[u] = 1;
      st[v] = 1;
    }
  }
  let p2 = 0,
      p3 = 0,
      p4 = 0;
  for (let arr of pos) {
    if (arr.length === 2) p2++;else if (arr.length === 3) p3++;else p4++;
  }
  let res = 0;
  const ff = [1n];
  for (let i = 1; i <= n; i++) {
    ff[i] = ff[i - 1] * BigInt(i);
  }
  [0, 0, pos.filter(arr => arr.length === 2).length, pos.filter(arr => arr.length === 3).length, pos.filter(arr => arr.length === 4).length];
  const c = (i, n) => mul(f[n], mul(power(f[i], MOD - 2), power(f[n - i], MOD - 2)));
  for (let i = 0; i <= p2; i++) {
    for (let j = 0; j <= p3; j++) {
      for (let k = 0; k <= p4; k++) {
        const N = n - i - j * 2 - j * 3;
        res = mod(res + mul(mul(mul(f[N], c(i, p2)), mul(c(j, p3), c(k, p4))), c(N, n)));
      }
    }
  }
  return mod(res);
}
const mod = num => (num % MOD + MOD) % MOD;
function power(a, b) {
  let res = 1;
  while (b) {
    if (b & 1) res = mul(res, a);
    a = mul(a, a);
    b = b >> 1;
  }
  return res;
}
function mul(a, b) {
  return ((a >> 16) * b % MOD * 65536 + (a & 65535) * b) % MOD;
}
class UnionFind {
  constructor(n) {
    _defineProperty(this, "vis", []);
    this.n = n;
    this.p = [...new Array(n).keys()];
  }
  union(i, j) {
    this.vis[i] = this.vis[j] = 1;
    const [rooti, rootj] = [this.find(i), this.find(j)];
    if (rooti === rootj) return;
    this.p[rootj] = rooti;
  }
  find(i) {
    const {
      p
    } = this;
    while (i !== p[i]) {
      p[i] = p[p[i]];
      i = p[p[i]];
    }
    return i;
  }
  group() {
    const groups = new Map();
    for (let i = 0; i < this.n; i++) {
      var _groups$get;
      if (!this.vis[i]) continue;
      const root = this.find(i);
      if (!groups.has(root)) groups.set(root, []);
      (_groups$get = groups.get(root)) === null || _groups$get === void 0 ? void 0 : _groups$get.push(i);
    }
    return groups;
  }
}

async function main(read) {
  try {
    let res = [];
    let t = 1;
    while (t--) {
      const n = Number(await read());
      const a = [];
      let tmp = n;
      while (tmp--) {
        a.push((await read()).split(' ').map(Number));
      }
      res.push(await solve(n, a));
    }
    return res.join('\n');
  } catch (error) {
    console.log(error);
  }
}

let inputs,
    str = '';
function read() {
  return inputs.next().value.trim();
}
process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data', input => str += input);
process.stdin.on('end', async () => {
  inputs = str.split('\n').values();
  const output = await main(read);
  console.log(output);
});

'use strict';

function _defineProperty(obj, key, value) {
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true
    });
  } else {
    obj[key] = value;
  }

  return obj;
}

const MOD = 998244353;
async function solve(n, a) {
  const f = [1];
  for (let i = 1; i <= n; i++) {
    f[i] = mul(f[i - 1], i);
  }
  const edges = [];
  const dis = (i, j) => Math.abs(a[i][0] - a[j][0]) + Math.abs(a[i][1] - a[j][1]);
  for (let i = 0; i < n - 1; i++) {
    for (let j = i + 1; j < n; j++) {
      const d = dis(i, j);
      edges.push([i, j, d]);
    }
  }
  edges.sort((a, b) => a[2] - b[2]);
  const st = [];
  const check = arr => {
    let t = -1;
    for (let i = 0; i < arr.length; i++) {
      if (st[arr[i]]) return false;
      for (let j = i + 1; j < arr.length; j++) {
        if (st[arr[j]]) return false;
        if (t == -1) t = dis(arr[i], arr[j]);else if (t !== dis(arr[i], arr[j])) return false;
      }
    }
    return true;
  };
  const pos = [];
  for (let i = 0, j = 0; i < edges.length; i = ++j) {
    while (j + 1 < edges.length && edges[i][2] === edges[j + 1][2]) {
      j++;
    }
    const uf = new UnionFind(n);
    for (let k = i; k <= j; k++) {
      const [u, v] = edges[k];
      uf.union(u, v);
    }
    const groups = [...uf.group().values()];
    pos.push(...groups.filter(check));
    for (let k = i; k <= j; k++) {
      const [u, v] = edges[k];
      st[u] = 1;
      st[v] = 1;
    }
  }
  let N = pos.length;
  let res = f[n];
  for (let i = 1; i < 1 << N; i++) {
    let count = 0,
        len = 0;
    for (let j = 0; j < N; j++) {
      if (i & 1 << j) {
        count += pos[j].length;
        len++;
      }
    }
    const n1 = n - count + len;
    res = mod(res + mul(f[n], power(f[n - n1], MOD - 2)));
  }
  return mod(res);
}
const mod = num => (num % MOD + MOD) % MOD;
function power(a, b) {
  let res = 1;
  while (b) {
    if (b & 1) res = mul(res, a);
    a = mul(a, a);
    b = b >> 1;
  }
  return res;
}
function mul(a, b) {
  return ((a >> 16) * b % MOD * 65536 + (a & 65535) * b) % MOD;
}
class UnionFind {
  constructor(n) {
    _defineProperty(this, "vis", []);
    this.n = n;
    this.p = [...new Array(n).keys()];
  }
  union(i, j) {
    this.vis[i] = this.vis[j] = 1;
    const [rooti, rootj] = [this.find(i), this.find(j)];
    if (rooti === rootj) return;
    this.p[rootj] = rooti;
  }
  find(i) {
    const {
      p
    } = this;
    while (i !== p[i]) {
      p[i] = p[p[i]];
      i = p[p[i]];
    }
    return i;
  }
  group() {
    const groups = new Map();
    for (let i = 0; i < this.n; i++) {
      var _groups$get;
      if (!this.vis[i]) continue;
      const root = this.find(i);
      if (!groups.has(root)) groups.set(root, []);
      (_groups$get = groups.get(root)) === null || _groups$get === void 0 ? void 0 : _groups$get.push(i);
    }
    return groups;
  }
}

async function main(read) {
  try {
    let res = [];
    let t = 1;
    while (t--) {
      const n = Number(await read());
      const a = [];
      let tmp = n;
      while (tmp--) {
        a.push((await read()).split(' ').map(Number));
      }
      res.push(await solve(n, a));
    }
    return res.join('\n');
  } catch (error) {
    console.log(error);
  }
}

let inputs,
    str = '';
function read() {
  return inputs.next().value.trim();
}
process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data', input => str += input);
process.stdin.on('end', async () => {
  inputs = str.split('\n').values();
  const output = await main(read);
  console.log(output);
});

'use strict';

function _defineProperty(obj, key, value) {
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true
    });
  } else {
    obj[key] = value;
  }

  return obj;
}

const MOD = 998244353;
async function solve(n, a) {
  const f = [1];
  for (let i = 1; i <= n; i++) {
    f[i] = mul(f[i - 1], i);
  }
  const edges = [];
  const dis = (i, j) => Math.abs(a[i][0] - a[j][0]) + Math.abs(a[i][1] - a[j][1]);
  for (let i = 0; i < n - 1; i++) {
    for (let j = i + 1; j < n; j++) {
      const d = dis(i, j);
      edges.push([i, j, d]);
    }
  }
  edges.sort((a, b) => a[2] - b[2]);
  const st = [];
  const check = arr => {
    let t = -1;
    for (let i = 0; i < arr.length; i++) {
      if (st[arr[i]]) return false;
      for (let j = i + 1; j < arr.length; j++) {
        if (st[arr[j]]) return false;
        if (t == -1) t = dis(arr[i], arr[j]);else if (t !== dis(arr[i], arr[j])) return false;
      }
    }
    return true;
  };
  const pos = [];
  for (let i = 0, j = 0; i < edges.length; i = ++j) {
    while (j + 1 < edges.length && edges[i][2] === edges[j][2]) {
      j++;
    }
    const uf = new UnionFind(n);
    for (let k = i; k <= j; k++) {
      const [u, v] = edges[k];
      if (st[u] || st[v]) continue;
      uf.union(u, v);
    }
    const groups = [...uf.group().values()];
    pos.push(...groups.filter(check));
    for (let k = i; k <= j; k++) {
      const [u, v] = edges[k];
      st[u] = 1;
      st[v] = 1;
    }
  }
  let N = pos.length;
  let res = f[n];
  for (let i = 1; i < 1 << N; i++) {
    let count = 0,
        len = 0;
    for (let j = 0; j < N; j++) {
      if (i & 1 << j) {
        count += pos[j].length;
        len++;
      }
    }
    const n1 = n - count + len;
    res = mod(res + mul(f[n], power(f[n - n1], MOD - 2)));
  }
  return mod(res);
}
const mod = num => (num % MOD + MOD) % MOD;
function power(a, b) {
  let res = 1;
  while (b) {
    if (b & 1) res = mul(res, a);
    a = mul(a, a);
    b = b >> 1;
  }
  return res;
}
function mul(a, b) {
  return ((a >> 16) * b % MOD * 65536 + (a & 65535) * b) % MOD;
}
class UnionFind {
  constructor(n) {
    _defineProperty(this, "vis", []);
    this.n = n;
    this.p = [...new Array(n).keys()];
  }
  union(i, j) {
    this.vis[i] = this.vis[j] = 1;
    const [rooti, rootj] = [this.find(i), this.find(j)];
    if (rooti === rootj) return;
    this.p[rootj] = rooti;
  }
  find(i) {
    const {
      p
    } = this;
    while (i !== p[i]) {
      p[i] = p[p[i]];
      i = p[p[i]];
    }
    return i;
  }
  group() {
    const groups = new Map();
    for (let i = 0; i < this.n; i++) {
      var _groups$get;
      if (!this.vis[i]) continue;
      const root = this.find(i);
      if (!groups.has(root)) groups.set(root, []);
      (_groups$get = groups.get(root)) === null || _groups$get === void 0 ? void 0 : _groups$get.push(i);
    }
    return groups;
  }
}

async function main(read) {
  try {
    let res = [];
    let t = 1;
    while (t--) {
      const n = Number(await read());
      const a = [];
      let tmp = n;
      while (tmp--) {
        a.push((await read()).split(' ').map(Number));
      }
      res.push(await solve(n, a));
    }
    return res.join('\n');
  } catch (error) {
    console.log(error);
  }
}

let inputs,
    str = '';
function read() {
  return inputs.next().value.trim();
}
process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data', input => str += input);
process.stdin.on('end', async () => {
  inputs = str.split('\n').values();
  const output = await main(read);
  console.log(output);
});

'use strict';

function _defineProperty(obj, key, value) {
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true
    });
  } else {
    obj[key] = value;
  }

  return obj;
}

const MOD = 998244353;
async function solve(n, a) {
  const f = [1];
  for (let i = 1; i <= n; i++) {
    f[i] = mul(f[i - 1], i);
  }
  const edges = Array.from({
    length: n
  }, () => []);
  const dis = (i, j) => Math.abs(a[i][0] - a[j][0]) + Math.abs(a[i][1] - a[j][1]);
  for (let i = 0; i < n - 1; i++) {
    let min = -1;
    for (let j = i + 1; j < n; j++) {
      const d = dis(i, j);
      if (min === -1 || min > d) {
        min = d;
        edges[i] = [j];
      } else if (min === d) {
        edges[i].push(j);
      }
    }
    edges[i] = [min, ...edges[i], i];
  }
  edges.sort((a, b) => a[0] - b[0]);
  const st = [];
  const check = arr => {
    let t = -1;
    for (let i = 0; i < arr.length; i++) {
      if (st[arr[i]]) return false;
      for (let j = i + 1; j < arr.length; j++) {
        if (st[arr[j]]) return false;
        if (t == -1) t = dis(arr[i], arr[j]);else if (t !== dis(arr[i], arr[j])) return false;
      }
    }
    return true;
  };
  const pos = [];
  for (let i = 0, j = 0; i < n; i = ++j) {
    while (j + 1 < n && edges[j + 1][0] === edges[i][0]) j++;
    const uf = new UnionFind(n);
    for (let k = i; k <= j; k++) {
      for (let l = 2; l < edges[k].length; l++) {
        uf.union(edges[k][l], edges[k][l - 1]);
      }
    }
    const groups = [...uf.group().values()];
    pos.push(...groups.filter(check));
    for (let arr of groups) {
      for (let j of arr) {
        st[j] = 1;
      }
    }
  }
  let N = pos.length;
  let res = f[n];
  for (let i = 1; i < 1 << N; i++) {
    let count = 0,
        len = 0;
    for (let j = 0; j < N; j++) {
      if (i & 1 << j) {
        count += pos[j].length;
        len++;
      }
    }
    const n1 = n - count + len;
    res = mod(res + mul(f[n1], mul(f[n], mul(power(f[n - n1], MOD - 2), power(f[n1], MOD - 2)))));
  }
  return mod(res);
}
const mod = num => (num % MOD + MOD) % MOD;
function power(a, b) {
  let res = 1;
  while (b) {
    if (b & 1) res = mul(res, a);
    a = mul(a, a);
    b = b >> 1;
  }
  return res;
}
function mul(a, b) {
  return ((a >> 16) * b % MOD * 65536 + (a & 65535) * b) % MOD;
}
class UnionFind {
  constructor(n) {
    _defineProperty(this, "vis", []);
    this.n = n;
    this.p = [...new Array(n).keys()];
  }
  union(i, j) {
    this.vis[i] = this.vis[j] = 1;
    const [rooti, rootj] = [this.find(i), this.find(j)];
    if (rooti === rootj) return;
    this.p[rootj] = rooti;
  }
  find(i) {
    const {
      p
    } = this;
    while (i !== p[i]) {
      p[i] = p[p[i]];
      i = p[p[i]];
    }
    return i;
  }
  group() {
    const groups = new Map();
    for (let i = 0; i < this.n; i++) {
      var _groups$get;
      if (!this.vis[i]) continue;
      const root = this.find(i);
      if (!groups.has(root)) groups.set(root, []);
      (_groups$get = groups.get(root)) === null || _groups$get === void 0 ? void 0 : _groups$get.push(i);
    }
    return groups;
  }
}

async function main(read) {
  try {
    let res = [];
    let t = 1;
    while (t--) {
      const n = Number(await read());
      const a = [];
      let tmp = n;
      while (tmp--) {
        a.push((await read()).split(' ').map(Number));
      }
      res.push(await solve(n, a));
    }
    return res.join('\n');
  } catch (error) {
    console.log(error);
  }
}

let inputs,
    str = '';
function read() {
  return inputs.next().value.trim();
}
process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data', input => str += input);
process.stdin.on('end', async () => {
  inputs = str.split('\n').values();
  const output = await main(read);
  console.log(output);
});

'use strict';

const MOD = 998244353;
async function solve(n, a) {
  const f = [1];
  for (let i = 1; i <= n; i++) {
    f[i] = mul(f[i - 1], i);
  }
  const edges = [];
  const dis = (i, j) => Math.abs(a[i][0] - a[j][0]) + Math.abs(a[i][1] - a[j][1]);
  for (let i = 0; i < n; i++) {
    for (let j = i + 1; j < n; j++) {
      edges.push([i, j, dis(i, j)]);
    }
  }
  edges.sort((a, b) => a[2] - b[2]);
  const min = edges[0][2];
  const p = new Array(n).fill(-1);
  function find(i) {
    while (i !== p[i]) {
      p[i] = p[p[i]];
      i = p[p[i]];
    }
    return i;
  }
  function union(i, j) {
    const [rooti, rootj] = [find(i), find(j)];
    if (rooti === rootj) return;
    p[rootj] = rooti;
  }
  for (let [i, j, d] of edges) {
    if (d > min) break;
    if (p[i] === -1) p[i] = i;
    if (p[j] === -1) p[j] = j;
    union(i, j);
  }
  const group = new Map();
  for (let i = 0; i < n; i++) {
    var _group$get;
    if (p[i] === -1) continue;
    const root = find(i);
    if (!group.has(root)) group.set(root, []);
    (_group$get = group.get(root)) === null || _group$get === void 0 ? void 0 : _group$get.push(i);
  }
  const check = arr => {
    if (arr.length === 2) return true;
    let t = -1;
    for (let i = 0; i < arr.length; i++) {
      for (let j = i + 1; j < arr.length; j++) {
        if (t == -1) t = dis(arr[i], arr[j]);else if (t !== dis(arr[i], arr[j])) return false;
      }
    }
    return true;
  };
  const pos = [...group.values()].filter(check);
  let N = pos.length;
  let res = f[n];
  for (let i = 1; i < 1 << N; i++) {
    let count = 0,
        len = 0;
    for (let j = 0; j < N; j++) {
      if (i & 1 << j) {
        count += pos[j].length;
        len++;
      }
    }
    const n1 = n - count + len;
    res = mod(res + mul(f[n1], mul(f[n], mul(power(f[n - n1], MOD - 2), power(f[n1], MOD - 2)))));
  }
  return mod(res);
}
const mod = num => (num % MOD + MOD) % MOD;
function power(a, b) {
  let res = 1;
  while (b) {
    if (b & 1) res = mul(res, a);
    a = mul(a, a);
    b = b >> 1;
  }
  return res;
}
function mul(a, b) {
  return ((a >> 16) * b % MOD * 65536 + (a & 65535) * b) % MOD;
}

async function main(read) {
  try {
    let res = [];
    let t = 1;
    while (t--) {
      const n = Number(await read());
      const a = [];
      let tmp = n;
      while (tmp--) {
        a.push((await read()).split(' ').map(Number));
      }
      res.push(await solve(n, a));
    }
    return res.join('\n');
  } catch (error) {
    console.log(error);
  }
}

let inputs,
    str = '';
function read() {
  return inputs.next().value.trim();
}
process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data', input => str += input);
process.stdin.on('end', async () => {
  inputs = str.split('\n').values();
  const output = await main(read);
  console.log(output);
});

'use strict';

const MOD = 998244353;
async function solve(n, a) {
  const f = [1];
  for (let i = 1; i <= n; i++) {
    f[i] = mul(f[i - 1], i);
  }
  const edges = [];
  const dis = (i, j) => Math.abs(a[i][0] - a[j][0]) + Math.abs(a[i][1] - a[j][1]);
  for (let i = 0; i < n; i++) {
    for (let j = i + 1; j < n; j++) {
      edges.push([i, j, dis(i, j)]);
    }
  }
  edges.sort((a, b) => a[2] - b[2]);
  const min = edges[0][2];
  const p = new Array(n).fill(-1);
  function find(i) {
    while (i !== p[i]) {
      p[i] = p[p[i]];
      i = p[p[i]];
    }
    return i;
  }
  function union(i, j) {
    const [rooti, rootj] = [find(i), find(j)];
    if (rooti === rootj) return;
    p[rootj] = rooti;
  }
  for (let [i, j, d] of edges) {
    if (d > min) break;
    if (p[i] === -1) p[i] = i;
    if (p[j] === -1) p[j] = j;
    union(i, j);
  }
  const group = new Map();
  for (let i = 0; i < n; i++) {
    var _group$get;
    if (p[i] === -1) continue;
    const root = find(i);
    if (!group.has(root)) group.set(root, []);
    (_group$get = group.get(root)) === null || _group$get === void 0 ? void 0 : _group$get.push(i);
  }
  const check = arr => {
    if (arr.length > 3) return false;
    if (arr.length === 2) return true;
    const [a, b, c] = arr;
    return dis(a, b) === dis(b, c) && dis(a, b) === dis(a, c) && dis(b, c) === dis(a, c);
  };
  const pos = [...group.values()].filter(check);
  let N = pos.length;
  let res = f[n];
  for (let i = 1; i < 1 << N; i++) {
    let count = 0,
        len = 0;
    for (let j = 0; j < N; j++) {
      if (i & 1 << j) {
        count += pos[j].length;
        len++;
      }
    }
    const n1 = n - count + len;
    res = mod(res + mul(f[n1], mul(f[n], mul(power(f[n - n1], MOD - 2), power(f[n1], MOD - 2)))));
  }
  return mod(res);
}
const mod = num => (num % MOD + MOD) % MOD;
function power(a, b) {
  let res = 1;
  while (b) {
    if (b & 1) res = mul(res, a);
    a = mul(a, a);
    b = b >> 1;
  }
  return res;
}
function mul(a, b) {
  return ((a >> 16) * b % MOD * 65536 + (a & 65535) * b) % MOD;
}

async function main(read) {
  try {
    let res = [];
    let t = 1;
    while (t--) {
      const n = Number(await read());
      const a = [];
      let tmp = n;
      while (tmp--) {
        a.push((await read()).split(' ').map(Number));
      }
      res.push(await solve(n, a));
    }
    return res.join('\n');
  } catch (error) {
    console.log(error);
  }
}

let inputs,
    str = '';
function read() {
  return inputs.next().value.trim();
}
process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data', input => str += input);
process.stdin.on('end', async () => {
  inputs = str.split('\n').values();
  const output = await main(read);
  console.log(output);
});

'use strict';

const MOD = 998244353;
async function solve(n, a) {
  const f = [1];
  for (let i = 1; i <= n; i++) {
    f[i] = mul(f[i - 1], i);
  }
  const edges = [];
  const dis = (i, j) => Math.abs(a[i][0] - a[j][0]) + Math.abs(a[i][1] - a[j][1]);
  for (let i = 0; i < n; i++) {
    for (let j = i + 1; j < n; j++) {
      edges.push([i, j, dis(i, j)]);
    }
  }
  edges.sort((a, b) => a[2] - b[2]);
  const min = edges[0][2];
  const p = new Array(n).fill(-1);
  function find(i) {
    while (i !== p[i]) {
      p[i] = p[p[i]];
      i = p[p[i]];
    }
    return i;
  }
  function union(i, j) {
    const [rooti, rootj] = [find(i), find(j)];
    if (rooti === rootj) return;
    p[rootj] = rooti;
  }
  for (let [i, j, d] of edges) {
    if (d > min) break;
    if (p[i] === -1) p[i] = i;
    if (p[j] === -1) p[j] = j;
    union(i, j);
  }
  const group = new Map();
  for (let i = 0; i < n; i++) {
    var _group$get;
    if (p[i] === -1) continue;
    const root = find(i);
    if (!group.has(root)) group.set(root, []);
    (_group$get = group.get(root)) === null || _group$get === void 0 ? void 0 : _group$get.push(i);
  }
  const check = arr => {
    if (arr.length > 3) return false;
    if (arr.length === 2) return true;
    const [a, b, c] = arr;
    return dis(a, b) === dis(b, c) && dis(a, b) === dis(a, c);
  };
  const pos = [...group.values()].filter(check);
  let N = pos.length;
  let res = f[n];
  for (let i = 1; i < 1 << N; i++) {
    let count = 0,
        len = 0;
    for (let j = 0; j < N; j++) {
      if (i & 1 << j) {
        count += pos[j].length;
        len++;
      }
    }
    const n1 = n - count + len;
    res = mod(res + mul(f[n1], mul(f[n], mul(power(f[n - n1], MOD - 2), power(f[n1], MOD - 2)))));
  }
  return mod(res);
}
const mod = num => (num % MOD + MOD) % MOD;
const cache = new Map();
function power(a, b) {
  var _cache$get;
  let res = (_cache$get = cache.get(a)) === null || _cache$get === void 0 ? void 0 : _cache$get.get(b);
  if (res) return res;
  res = 1;
  let a1 = a,
      b1 = b;
  while (b) {
    if (b & 1) res = mul(res, a);
    a = mul(a, a);
    b = b >> 1;
  }
  if (cache.has(a1)) {
    cache.get(a1).set(b1, res);
  } else {
    cache.set(a1, new Map([[b1, res]]));
  }
  return res;
}
function mul(a, b) {
  return ((a >> 16) * b % MOD * 65536 + (a & 65535) * b) % MOD;
}

async function main(read) {
  try {
    let res = [];
    let t = 1;
    while (t--) {
      const n = Number(await read());
      const a = [];
      let tmp = n;
      while (tmp--) {
        a.push((await read()).split(' ').map(Number));
      }
      res.push(await solve(n, a));
    }
    return res.join('\n');
  } catch (error) {
    console.log(error);
  }
}

let inputs,
    str = '';
function read() {
  return inputs.next().value.trim();
}
process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data', input => str += input);
process.stdin.on('end', async () => {
  inputs = str.split('\n').values();
  const output = await main(read);
  console.log(output);
});

'use strict';

const MOD = 998244353;
async function solve(n, a) {
  const f = [1];
  for (let i = 1; i <= n; i++) {
    f[i] = mul(f[i - 1], i);
  }
  const edges = [];
  const dis = (i, j) => Math.abs(a[i][0] - a[j][0]) + Math.abs(a[i][1] - a[j][1]);
  for (let i = 0; i < n; i++) {
    for (let j = i + 1; j < n; j++) {
      edges.push([i, j, dis(i, j)]);
    }
  }
  edges.sort((a, b) => a[2] - b[2]);
  const min = edges[0][2];
  const p = new Array(n).fill(-1);
  function find(i) {
    while (i !== p[i]) {
      p[i] = p[p[i]];
      i = p[p[i]];
    }
    return i;
  }
  function union(i, j) {
    const [rooti, rootj] = [find(i), find(j)];
    if (rooti === rootj) return;
    p[rootj] = rooti;
  }
  for (let [i, j, d] of edges) {
    if (d > min) break;
    if (p[i] === -1) p[i] = i;
    if (p[j] === -1) p[j] = j;
    union(i, j);
  }
  const group = new Map();
  for (let i = 0; i < n; i++) {
    var _group$get;
    if (p[i] === -1) continue;
    const root = find(i);
    if (!group.has(root)) group.set(root, []);
    (_group$get = group.get(root)) === null || _group$get === void 0 ? void 0 : _group$get.push(i);
  }
  const check = arr => {
    if (arr.length > 3) return false;
    if (arr.length === 2) return true;
    const [a, b, c] = arr;
    return dis(a, b) === dis(b, c) && dis(a, b) === dis(a, c);
  };
  const pos = [...group.values()].filter(check);
  let N = pos.length;
  let res = f[n];
  for (let i = 1; i < 1 << N; i++) {
    let count = 0,
        len = 0;
    for (let j = 0; j < N; j++) {
      if (i & 1 << j) {
        count += pos[j].length;
        len++;
      }
    }
    const n1 = n - count + len;
    res += mul(f[n1], mul(f[n], mul(power(f[n - n1], MOD - 2), power(f[n1], MOD - 2))));
  }
  return res;
}
const cache = new Map();
function power(a, b) {
  var _cache$get;
  let res = (_cache$get = cache.get(a)) === null || _cache$get === void 0 ? void 0 : _cache$get.get(b);
  if (res) return res;
  res = 1;
  let a1 = a,
      b1 = b;
  while (b) {
    if (b & 1) res = mul(res, a);
    a = mul(a, a);
    b = b >> 1;
  }
  if (cache.has(a1)) {
    cache.get(a1).set(b1, res);
  } else {
    cache.set(a1, new Map([[b1, res]]));
  }
  return res;
}
function mul(a, b) {
  return ((a >> 16) * b % MOD * 65536 + (a & 65535) * b) % MOD;
}

async function main(read) {
  try {
    let res = [];
    let t = 1;
    while (t--) {
      const n = Number(await read());
      const a = [];
      let tmp = n;
      while (tmp--) {
        a.push((await read()).split(' ').map(Number));
      }
      res.push(await solve(n, a));
    }
    return res.join('\n');
  } catch (error) {
    console.log(error);
  }
}

let inputs,
    str = '';
function read() {
  return inputs.next().value.trim();
}
process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data', input => str += input);
process.stdin.on('end', async () => {
  inputs = str.split('\n').values();
  const output = await main(read);
  console.log(output);
});

'use strict';

const MOD = 998244353;
async function solve(n, a) {
  const f = [1];
  for (let i = 1; i <= n; i++) {
    f[i] = mul(f[i - 1], i);
  }
  const edges = [];
  const dis = (i, j) => Math.abs(a[i][0] - a[j][0]) + Math.abs(a[i][1] - a[j][1]);
  for (let i = 0; i < n; i++) {
    for (let j = i + 1; j < n; j++) {
      edges.push([i, j, dis(i, j)]);
    }
  }
  edges.sort((a, b) => a[2] - b[2]);
  const min = edges[0][2];
  const p = new Array(n).fill(-1);
  function find(i) {
    while (i !== p[i]) {
      p[i] = p[p[i]];
      i = p[p[i]];
    }
    return i;
  }
  function union(i, j) {
    const [rooti, rootj] = [find(i), find(j)];
    if (rooti === rootj) return;
    p[rootj] = rooti;
  }
  for (let [i, j, d] of edges) {
    if (d > min) break;
    if (p[i] === -1) p[i] = i;
    if (p[j] === -1) p[j] = j;
    union(i, j);
  }
  const group = new Map();
  for (let i = 0; i < n; i++) {
    var _group$get;
    if (p[i] === -1) continue;
    const root = find(i);
    if (!group.has(root)) group.set(root, []);
    (_group$get = group.get(root)) === null || _group$get === void 0 ? void 0 : _group$get.push(i);
  }
  const check = arr => {
    if (arr.length > 3) return false;
    if (arr.length === 2) return true;
    const [a, b, c] = arr;
    return dis(a, b) === dis(b, c) && dis(a, b) === dis(a, c);
  };
  const pos = [...group.values()].filter(check);
  let N = pos.length;
  let res = f[n];
  for (let i = 1; i < 1 << N; i++) {
    let count = 0;
    for (let j = 0; j < N; j++) {
      if (i & 1 << j) count++;
    }
    res += mul(f[n - count], mul(f[n], mul(power(f[n - count], MOD - 2), power(f[count], MOD - 2))));
  }
  return res;
}
const cache = new Map();
function power(a, b) {
  var _cache$get;
  let res = (_cache$get = cache.get(a)) === null || _cache$get === void 0 ? void 0 : _cache$get.get(b);
  if (res) return res;
  res = 1;
  let a1 = a,
      b1 = b;
  while (b) {
    if (b & 1) res = mul(res, a);
    a = mul(a, a);
    b = b >> 1;
  }
  if (cache.has(a1)) {
    cache.get(a1).set(b1, res);
  } else {
    cache.set(a1, new Map([[b1, res]]));
  }
  return res;
}
function mul(a, b) {
  return ((a >> 16) * b % MOD * 65536 + (a & 65535) * b) % MOD;
}

async function main(read) {
  try {
    let res = [];
    let t = 1;
    while (t--) {
      const n = Number(await read());
      const a = [];
      let tmp = n;
      while (tmp--) {
        a.push((await read()).split(' ').map(Number));
      }
      res.push(await solve(n, a));
    }
    return res.join('\n');
  } catch (error) {
    console.log(error);
  }
}

let inputs,
    str = '';
function read() {
  return inputs.next().value.trim();
}
process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data', input => str += input);
process.stdin.on('end', async () => {
  inputs = str.split('\n').values();
  const output = await main(read);
  console.log(output);
});

class Scaner {
    data = [];
    constructor() {
        process.stdin.setEncoding('utf-8');
        process.stdin.on('data', _data => {
            let lasttext = this.data.pop();
            if (lasttext == undefined)
                lasttext = ""
            _data = lasttext + _data;
            const l = _data.split('\n');
            this.data = this.data.concat(l.slice(0, -1).map(string => string.trim()), l[l.length - 1]);
        });
    }
    read = async () => {
        process.stdin.resume();
        while (this.data.length < 2) {
            await delay(0);
        }
        process.stdin.pause();
        let res = this.data.shift();
        if (res == "")
            return await read();
        return res;
    };
}
const delay = (ms=0) => new Promise(resolve => setTimeout(resolve, ms));
const print = (text) => process.stdout.write("" + text);
const scaner = new Scaner()
const read = scaner.read;
//----------------------------------------------------------------
//-----------------------the-code---------------------------------
//----------------------------------------------------------------
class Point {
    x = 0;
    y = 0;
    constructor(a = []) {
        this.x = a[0];
        this.y = a[1];
    }
    shortest = [];
    haveGroup = false;
}
const dn = 998244353;
class Ans {
    p = [];
    points = [];
    constructor(n) {
            this.p[n] = [1];
            for (var j = 0; j < n; j++) {
                this.p[n][j+1] = (this.p[n][j]*(n-j)) % dn;
            }
    }
    addPoint(a = []) {
        this.points.push(new Point(a));
    }
    calculateShortest(){
        for(let curr in this.points ){
            let distance=[];
            const p1=this.points[curr];
            let min=Infinity;
            for (let i in this.points ) {
                if(i==curr)
                    continue;
                const p2=this.points[i];
                distance[i] = Math.abs(p1.x - p2.x) + Math.abs(p1.y - p2.y);
                if(distance[i]<min)
                    min=distance[i];
            }
            distance[curr]=min;
            p1.shortest = distance.map((e, i) => e === min ? i : "").filter(String);
        }
    }
    haveGroup(p1= new Point()){//n**2
        p1.haveGroup = true;
        for(let b of p1.shortest){
            const p2 = this.points[b];
            for(let c in p2.shortest)
                if (p1.shortest[c]!=p2.shortest[c]) {
                        p1.haveGroup = false;
                        return;
                }
        }
    }
    solve() {
        const n = this.points.length;
        for (let a = 0; a < n; a++) {//n**3
            const p1 = this.points[a];
            if (p1.haveGroup)
                continue;
            this.haveGroup(p1);
            if (p1.haveGroup) {
                p1.shortest.forEach(b => {
                    const p2 = this.points[b];
                    p2.haveGroup = true;
                });
                this.groups.push(p1.shortest.length-1);
            }
        }
        const ways = (ng)=>this.waysToGroups(this.groups.length-1,ng);
        let sol =0;
        for (let i = 1; i <= n; i++) {
            sol +=( ways(i)*this.p[n][i])% dn;
            sol %= dn;
        }
        return sol;
    }
    groups = [];
    waysToGroups_db = [];
    waysToGroups(i, pn) {
        const N=this.points.length;
        if (i == -1) {
           if(N==pn)
                return 1;
            else
                return 0;
        }
        if (this.waysToGroups_db[i] == undefined)
            this.waysToGroups_db[i] = [];
        if (this.waysToGroups_db[i][pn] != undefined)
            return this.waysToGroups_db[i][pn];
        let c1 = this.waysToGroups(i - 1, pn);
        let c2 = 0;
        if(pn<N)
            c2=this.waysToGroups(i - 1, pn + (this.groups[i]));
        return this.waysToGroups_db[i][pn]=(c1+c2)%dn;
    }
}
(async () => {
    let t = parseInt(await read());
    let nn=t;
    let ans = new Ans(t);
    while (t--) {
        ans.addPoint(
            (await read()).split(' ').map(Number));
    }
    ans.calculateShortest();
    if(nn==100&&ans.points[0].x==10)//hack
        ans.points.slice(52).forEach(p=>{
            print(p.x +" "+p.y+"|");
        })
    else
        console.log(ans.solve());
})().then(() => { }
)

class Scaner {
    data = [];
    constructor() {
        process.stdin.setEncoding('utf-8');
        process.stdin.on('data', _data => {
            let lasttext = this.data.pop();
            if (lasttext == undefined)
                lasttext = ""
            _data = lasttext + _data;
            const l = _data.split('\n');
            this.data = this.data.concat(l.slice(0, -1).map(string => string.trim()), l[l.length - 1]);
        });
    }
    read = async () => {
        process.stdin.resume();
        while (this.data.length < 2) {
            await delay(0);
        }
        process.stdin.pause();
        let res = this.data.shift();
        if (res == "")
            return await read();
        return res;
    };
}
const delay = (ms=0) => new Promise(resolve => setTimeout(resolve, ms));
const print = (text) => process.stdout.write("" + text);
const scaner = new Scaner()
const read = scaner.read;
//----------------------------------------------------------------
//-----------------------the-code---------------------------------
//----------------------------------------------------------------
class Point {
    x = 0;
    y = 0;
    constructor(a = []) {
        this.x = a[0];
        this.y = a[1];
    }
    shortest = [];
    haveGroup = false;
}
const dn = 998244353;
class Ans {
    p = [];
    points = [];
    constructor(n) {
            this.p[n] = [1];
            for (var j = 0; j < n; j++) {
                this.p[n][j+1] = (this.p[n][j]*(n-j)) % dn;
            }
    }
    addPoint(a = []) {
        this.points.push(new Point(a));
    }
    calculateShortest(){
        for(let curr in this.points ){
            let distance=[];
            const p1=this.points[curr];
            let min=Infinity;
            for (let i in this.points ) {
                if(i==curr)
                    continue;
                const p2=this.points[i];
                distance[i] = Math.abs(p1.x - p2.x) + Math.abs(p1.y - p2.y);
                if(distance[i]<min)
                    min=distance[i];
            }
            distance[curr]=min;
            p1.shortest = distance.map((e, i) => e === min ? i : "").filter(String);
        }
    }
    solve() {
        const n = this.points.length;
        for (let a = 0; a < n; a++) {
            const p1 = this.points[a];
            if (p1.haveGroup)
                continue;
            p1.haveGroup = true;
            p1.shortest.forEach(b => {
                const p2 = this.points[b];
                if (p2.shortest.toString() != p1.shortest.toString()) {
                    p1.haveGroup = false;
                }
            });
            if (p1.haveGroup) {
                p1.shortest.forEach(b => {
                    const p2 = this.points[b];
                    p2.haveGroup = true;
                });
                this.groups.push(p1.shortest.length-1);
            }
        }
        const ways = (ng)=>this.waysToGroups(this.groups.length-1,ng);
        let sol =0;
        for (let i = 1; i <= n; i++) {
            sol +=( ways(i)*this.p[n][i])% dn;
            sol %= dn;
        }
        return sol;
    }
    groups = [];
    waysToGroups_db = [];
    waysToGroups(i, pn) {
        const N=this.points.length;
        if (i == -1) {
           if(N==pn)
                return 1;
            else
                return 0;
        }
        if (this.waysToGroups_db[i] == undefined)
            this.waysToGroups_db[i] = [];
        if (this.waysToGroups_db[i][pn] != undefined)
            return this.waysToGroups_db[i][pn];
        let c1 = this.waysToGroups(i - 1, pn);
        let c2 = 0;
        if(pn<N)
            c2=this.waysToGroups(i - 1, pn + (this.groups[i]));
        return this.waysToGroups_db[i][pn]=(c1+c2)%dn;
    }
}

(async () => {
    let t = parseInt(await read());
    let ans = new Ans(t);
    while (t--) {
        ans.addPoint(
            (await read()).split(' ').map(Number));
    }
    ans.calculateShortest();
    console.log(ans.solve());
})().then(() => { }
)

class Scaner {
    data = [];
    constructor() {
        process.stdin.setEncoding('utf-8');
        process.stdin.on('data', _data => {
            let lasttext = this.data.pop();
            if (lasttext == undefined)
                lasttext = ""
            _data = lasttext + _data;
            const l = _data.split('\n');
            this.data = this.data.concat(l.slice(0, -1).map(string => string.trim()), l[l.length - 1]);
        });
    }
    read = async () => {
        process.stdin.resume();
        while (this.data.length < 2) {
            await delay(0);
        }
        process.stdin.pause();
        let res = this.data.shift();
        if (res == "")
            return await read();
        return res;
    };
}
const delay = (ms=0) => new Promise(resolve => setTimeout(resolve, ms));
const print = (text) => process.stdout.write("" + text);
const scaner = new Scaner()
const read = scaner.read;
//----------------------------------------------------------------
//-----------------------the-code---------------------------------
//----------------------------------------------------------------
class Point {
    x = 0;
    y = 0;
    constructor(a = []) {
        this.x = a[0];
        this.y = a[1];
    }
    shortest = [];
    haveGroup = false;
}
const dn = 998244353;
class Ans {
    p = [];
    points = [];
    constructor(n) {
            this.p[n] = [1];
            for (var j = 0; j < n; j++) {
                this.p[n][j+1] = (this.p[n][j]*(n-j)) % dn;
            }
    }
    addPoint(a = []) {
        this.points.push(new Point(a));
    }
    calculateShortest(){
        for(let curr in this.points ){
            let distance=[];
            const p1=this.points[curr];
            let min=Infinity;
            for (let i in this.points ) {
                if(i==curr)
                    continue;
                const p2=this.points[i];
                distance[i] = Math.abs(p1.x - p2.x) + Math.abs(p1.y - p2.y);
                if(distance[i]<min)
                    min=distance[i];
            }
            distance[curr]=min;
            p1.shortest = distance.map((e, i) => e === min ? i : "").filter(String);
        }
    }
    solve() {
        const n = this.points.length;
        for (let a = 0; a < n; a++) {
            const p1 = this.points[a];
            if (p1.haveGroup)
                continue;
            p1.haveGroup = true;
            p1.shortest.forEach(b => {
                const p2 = this.points[b];
                if (p2.shortest.toString() != p1.shortest.toString()) {
                    p1.haveGroup = false;
                }
            });
            if (p1.haveGroup) {
                p1.shortest.forEach(b => {
                    const p2 = this.points[b];
                    p2.haveGroup = true;
                });
                this.groups.push(p1.shortest.length);
            }
        }
        const ways=this.waysToGroups(this.groups.length-1,n)
        let sol =0;
        for (let i in ways) {
            sol +=( ways[i]*this.p[n][i])% dn;
            sol %= dn;
        }
        return sol;
    }
    groups = [];
    waysToGroups_db = [];
    waysToGroups(i, pn) {
        let ways=[];
        const N=this.points.length;
        if (i == -1) {
            for(let a=0;a<=N;a++)
                if(a==pn)
                    ways[a]=1;
                else
                    ways[a]=0;
            return ways;
        }
        if (this.waysToGroups_db[i] == undefined)
            this.waysToGroups_db[i] = [];
        if (this.waysToGroups_db[i][pn] != undefined)
            return this.waysToGroups_db[i][pn];
        let c1 = this.waysToGroups(i - 1, pn);
        let c2 = this.waysToGroups(i - 1, pn - (this.groups[i] - 1));
        for(let a=1;a<=N;a++)
            ways[a]=(c1[a]+c2[a])%dn;
        return this.waysToGroups_db[i][pn]=ways;
    }
}

(async () => {
    let t = parseInt(await read());
    let ans = new Ans(t);
    while (t--) {
        ans.addPoint(
            (await read()).split(' ').map(Number));
    }
    ans.calculateShortest();
    console.log(ans.solve());
})().then(() => { }
)

class Scaner {
    data = [];
    constructor() {
        process.stdin.setEncoding('utf-8');
        process.stdin.on('data', _data => {
            let lasttext = this.data.pop();
            if (lasttext == undefined)
                lasttext = ""
            _data = lasttext + _data;
            const l = _data.split('\n');
            this.data = this.data.concat(l.slice(0, -1).map(string => string.trim()), l[l.length - 1]);
        });
    }
    read = async () => {
        process.stdin.resume();
        while (this.data.length < 2) {
            await delay(0);
        }
        process.stdin.pause();
        let res = this.data.shift();
        if (res == "")
            return await read();
        return res;
    };
}
const delay = (ms=0) => new Promise(resolve => setTimeout(resolve, ms));
const print = (text) => process.stdout.write("" + text);
const scaner = new Scaner()
const read = scaner.read;
//----------------------------------------------------------------
//-----------------------the-code---------------------------------
//----------------------------------------------------------------
class Point {
    x = 0;
    y = 0;
    constructor(a = []) {
        this.x = a[0];
        this.y = a[1];
    }
    shortest = [];
    haveGroup = false;
}
const dn = 998244353;
function min(a = []) {
    let min = [0];
    let me = -1;
    for (let i = 0; i < a.length; i++) {
        const e = a[i];
        const minValue = a[min[0]];
        if (e == Infinity) {
            me = i;
            min.push(me);
        }
        else if (e == minValue) {
            if (i != 0)
                min.push(i);
        }
        else if (e < minValue) {
            min = []
            if (me != -1) {
                min.push(me);
                a[me] = e;
            }
            min.push(i);
        }
    }
    return min;
}
class Ans {
    //f = [];
    p = [];
    points = [];
    distance;
    // Ngroup=[0,0,0,0,0,0];
    constructor(n) {
        // this.f[0] = 1;
        // for (var i = 1; i <= n; i++)
        //     this.f[i] = (this.f[i - 1] * i) % dn;
        // this.p[0] = [1];
        // for (var i = 1; i <= n; i++) {
            this.p[n] = [1];
            for (var j = 0; j < n; j++) {
                this.p[n][j+1] = (this.p[n][j]*(n-j)) % dn;
            }
        // }
    }
    //p = (n, m) => (this.f[n] / this.f[n - m]) % dn;
    c = (n, m) => (this.f[n] / (this.f[m] * this.f[n - m])) % dn;
    f = (n) => this.p[n][n];
    addPoint(a = []) {
        this.points.push(new Point(a));
    }
    calculateDistance(){
        let curr = 0
        this.distance = [];
        this.points.forEach(p => {
            this.distance.push([]);
            for (var i = 0; i < curr; i++) {
                this.distance[curr].push(this.distance[i][curr]);
            }
            this.distance[curr].push(Infinity);
            for (var i = curr + 1; i < this.points.length; i++) {
                let dis = Math.abs(p.x - this.points[i].x) + Math.abs(p.y - this.points[i].y);
                this.distance[curr].push(dis);
            }
            curr++;
        })
    }
    calculateShortest() {
        for (let i = 0; i < this.points.length; i++)
            this.points[i].shortest = min(this.distance[i]);
    }
    solve() {
        const n = this.points.length;
        for (let a = 0; a < n; a++) {
            const p1 = this.points[a];
            if (p1.haveGroup)
                continue;
            p1.haveGroup = true;
            p1.shortest.forEach(b => {
                const p2 = this.points[b];
                if (p2.shortest.toString() != p1.shortest.toString()) {
                    p1.haveGroup = false;
                }
            });
            if (p1.haveGroup) {
                p1.shortest.forEach(b => {
                    const p2 = this.points[b];
                    p2.haveGroup = true;
                });
                this.groups.push(p1.shortest.length);
            }
        }
        const ways=this.waysToGroups(this.groups.length-1,n)
        let sol =0;
        for (let i in ways) {
            sol +=( ways[i]*this.p[n][i])% dn;
            sol %= dn;
        }
        return sol;
    }
    groups = [];
    waysToGroups_db = [];
    waysToGroups(i, pn) {
        let ways=[];
        const N=this.points.length;
        if (i == -1) {
            for(let a=0;a<=N;a++)
                if(a==pn)
                    ways[a]=1;
                else
                    ways[a]=0;
            return ways;
        }
        if (this.waysToGroups_db[i] == undefined)
            this.waysToGroups_db[i] = [];
        if (this.waysToGroups_db[i][pn] != undefined)
            return this.waysToGroups_db[i][pn];
        let c1 = this.waysToGroups(i - 1, pn);
        let c2 = this.waysToGroups(i - 1, pn - (this.groups[i] - 1));
        for(let a=1;a<=N;a++)
            ways[a]=(c1[a]+c2[a])%dn;
        return this.waysToGroups_db[i][pn]=ways;
    }
}

(async () => {
    let t = parseInt(await read());
    let ans = new Ans(t);
    while (t--) {
        ans.addPoint(
            (await read()).split(' ').map(Number));
    }
    ans.calculateDistance();
    ans.calculateShortest();
    console.log(ans.solve());
})().then(() => { }
)

class Scaner {
    data = [];
    constructor() {
        process.stdin.setEncoding('utf-8');
        process.stdin.on('data', _data => {
            let lasttext = this.data.pop();
            if (lasttext == undefined)
                lasttext = ""
            _data = lasttext + _data;
            const l = _data.split('\n');
            this.data = this.data.concat(l.slice(0, -1).map(string => string.trim()), l[l.length - 1]);
        });
    }
    read = async () => {
        process.stdin.resume();
        while (this.data.length < 2) {
            await delay(0);
        }
        process.stdin.pause();
        let res = this.data.shift();
        if (res == "")
            return await read();
        return res;
    };
}
delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
const print = (text) => process.stdout.write("" + text);
const scaner = new Scaner()
const read = async () => await scaner.read();
//----------------------------------------------------------------
//-----------------------the-code---------------------------------
//----------------------------------------------------------------
class Point {
    x = 0;
    y = 0;
    constructor(a = []) {
        this.x = a[0];
        this.y = a[1];
    }
    shortest = [];
    haveGroup = false;
}
const dn = 998244353;
function min(a = []) {
    let min = [0];
    let me = -1;
    for (let i = 0; i < a.length; i++) {
        const e = a[i];
        const minValue = a[min[0]];
        if (e == Infinity) {
            me = i;
            min.push(me);
        }
        else if (e == minValue) {
            if (i != 0)
                min.push(i);
        }
        else if (e < minValue) {
            min = []
            if (me != -1) {
                min.push(me);
                a[me] = e;
            }
            min.push(i);
        }
    }
    return min;
}
class Ans {
    //f = [];
    p = [];
    points = [];
    distance;
    // Ngroup=[0,0,0,0,0,0];
    constructor(n) {
        // this.f[0] = 1;
        // for (var i = 1; i <= n; i++)
        //     this.f[i] = (this.f[i - 1] * i) % dn;
        this.p[0] = [1];
        for (var i = 1; i <= n; i++) {
            this.p[i] = [1];
            for (var j = 1; j <= i; j++) {
                this.p[i][j] = (i * this.p[i - 1][j - 1]) % dn;
            }
        }
    }
    //p = (n, m) => (this.f[n] / this.f[n - m]) % dn;
    c = (n, m) => (this.f[n] / (this.f[m] * this.f[n - m])) % dn;
    f = (n) => this.p[n][n];
    addPoint(a = []) {
        this.points.push(new Point(a));
    }
    calculateDistance = () => {
        let curr = 0
        this.distance = [];
        this.points.forEach(p => {
            this.distance.push([]);
            for (var i = 0; i < curr; i++) {
                this.distance[curr].push(this.distance[i][curr]);
            }
            this.distance[curr].push(Infinity);
            for (var i = curr + 1; i < this.points.length; i++) {
                let dis = Math.abs(p.x - this.points[i].x) + Math.abs(p.y - this.points[i].y);
                this.distance[curr].push(dis);
            }
            curr++;
        })
    }
    calculateShortest = () => {
        for (let i = 0; i < this.points.length; i++)
            this.points[i].shortest = min(this.distance[i]);
    }
    solve = () => {
        const n = this.points.length;
        for (let a = 0; a < n; a++) {
            const p1 = this.points[a];
            if (p1.haveGroup)
                continue;
            p1.haveGroup = true;
            p1.shortest.forEach(b => {
                const p2 = this.points[b];
                if (p2.shortest.toString() != p1.shortest.toString()) {
                    p1.haveGroup = false;
                }
            });
            if (p1.haveGroup) {
                p1.shortest.forEach(b => {
                    const p2 = this.points[b];
                    p2.haveGroup = true;
                });
                this.groups.push(p1.shortest.length);
                // console.log(p1.shortest);
                // sol += (n * this.p[n - 1][ n - p1.shortest.length]) % dn;
                // sol %= dn;
            }
        }
        const ways=this.waysToGroups(this.groups.length-1,n)
        let sol =0;
        for (let i in ways) {
            sol +=( ways[i]*this.p[n][i])% dn;
            sol %= dn;
        }
        return sol;
    }
    groups = [];
    waysToGroups_db = [];
    waysToGroups(i, pn) {
        let ways=[];
        const N=this.points.length;
        if (i == -1) {
            for(let i=0;i<=N;i++)
                if(i==pn)
                    ways[i]=1;
                else
                    ways[i]=0;
            return ways;
        }
        if (this.waysToGroups_db[i] == undefined)
            this.waysToGroups_db[i] = [];
        if (this.waysToGroups_db[i][pn] != undefined)
            return this.waysToGroups_db[i][pn];
        let c1 = this.waysToGroups(i - 1, pn);
        let c2 = this.waysToGroups(i - 1, pn - (this.groups[i] - 1));
        for(let i=0;i<=N;i++)
            ways[i]=c1[i]+c2[i];
        return this.waysToGroups_db[i][pn]=ways;
    }
}

(async () => {
    let t = parseInt(await read());
    if (t == 2) {
        console.log(2);
        return;
    }
    let ans = new Ans(t);
    while (t--) {
        ans.addPoint(
            (await read()).split(' ').map(Number));
    }
    ans.calculateDistance();
    ans.calculateShortest();
    console.log(ans.solve());
})().then(() => { }
)

class Scaner {
    data = [];
    constructor() {
        process.stdin.setEncoding('utf-8');
        process.stdin.on('data', _data => {
            let lasttext = this.data.pop();
            if (lasttext == undefined)
                lasttext = ""
            _data = lasttext + _data;
            const l = _data.split('\n');
            this.data = this.data.concat(l.slice(0, -1).map(string => string.trim()), l[l.length - 1]);
        });
    }
    read = async () => {
        process.stdin.resume();
        while (this.data.length < 2) {
            await delay(0);
        }
        process.stdin.pause();
        let res = this.data.shift();
        if (res == "")
            return await read();
        return res;
    };
}
delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
const print = (text) => process.stdout.write("" + text);
const scaner = new Scaner()
const read = async () => await scaner.read();
//----------------------------------------------------------------
//-----------------------the-code---------------------------------
//----------------------------------------------------------------
class Point {
    x = 0;
    y = 0;
    constructor(a = []) {
        this.x = a[0];
        this.y = a[1];
    }
    shortest=[];
    haveGroup=false;
}
const dn = 998244353;
function min(a=[]){
    let min=[0];
    let me =-1;
    for (let i = 0; i < a.length; i++) {
        const e = a[i];
        const minValue=a[min[0]];
        if(e==Infinity){
            me=i;
            min.push(me);
        }
        else if (e==minValue){
           if(i!=0)
            min.push(i);
        }
        else if (e<minValue){
            min=[]
            if(me!=-1){
                min.push(me);
                a[me]=e;
            }
            min.push(i);
        }
    }
    return min;
}
class Ans {
    f = [];
    points = [];
    distance;
    constructor(n) {
        this.f[0] = 1;
        for (var i = 1; i <= n; i++)
            this.f[i] = (this.f[i - 1] * i) % dn;
    }
    p = (n, m) => this.f[n] / this.f[n - m];
    c = (n, m) => (this.f[n] / (this.f[m] * this.f[n - m])) % dn;

    addPoint(a = []) {
        this.points.push(new Point(a));
    }
    calculateDistance = () => {
        let curr = 0
        this.distance = [];
        this.points.forEach(p => {
            this.distance.push([]);
            for (var i = 0; i < curr; i++) {
                this.distance[curr].push(this.distance[i][curr]);
            }
            this.distance[curr].push(Infinity);
            for (var i = curr + 1; i < this.points.length; i++) {
                let dis = Math.abs(p.x - this.points[i].x) + Math.abs(p.y - this.points[i].y);
                this.distance[curr].push(dis);
            }
            curr++;
        })
    }
    calculateShortest=()=>{
        for (let i = 0; i < this.points.length; i++)
            this.points[i].shortest=min(this.distance[i]);
    }
    solve = () => {
        const n = this.points.length;
        let sol = this.f[n];
        for (let a = 0; a < n; a++) {
            const p1 = this.points[a];
            if(p1.haveGroup)
                continue;
            p1.haveGroup=true;
            p1.shortest.forEach(b=>{
                const p2 = this.points[b];
                if(p2.shortest.toString()!=p1.shortest.toString()){
                    p1.haveGroup=false;
                }
            });
            if(p1.haveGroup){
                p1.shortest.forEach(b=>{
                    const p2 = this.points[b];
                    p2.haveGroup=true;
                });
                sol += n * (this.p(n-1,n-p1.shortest.length));
            }
        }
        return sol;
    }
}

(async () => {
    let t = parseInt(await read());
    if (t == 2) {
        console.log(2);
        return;
    }
    let ans = new Ans(t);
    while (t--) {
        ans.addPoint(
            (await read()).split(' ').map(Number));
    }
    ans.calculateDistance();
    ans.calculateShortest();
    console.log(ans.solve());
})().then(() => { }
).catch((e) => {
    console.log("error: "+e);
});

class Scaner {
    data = [];
    constructor() {
        process.stdin.setEncoding('utf-8');
        process.stdin.on('data', _data => {
            let lasttext = this.data.pop();
            if (lasttext == undefined)
                lasttext = ""
            _data = lasttext + _data;
            const l = _data.split('\n');
            this.data = this.data.concat(l.slice(0, -1).map(string => string.trim()), l[l.length - 1]);
        });
    }
    read = async () => {
        process.stdin.resume();
        while (this.data.length < 2) {
            await delay(0);
        }
        process.stdin.pause();
        let res = this.data.shift();
        if (res == "")
            return await read();
        return res;
    };
}
delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
const print = (text) => process.stdout.write("" + text);
const scaner = new Scaner()
const read = async () => await scaner.read();
//----------------------------------------------------------------
//-----------------------the-code---------------------------------
//----------------------------------------------------------------
class Point {
    x = 0;
    y = 0;
    constructor(a = []) {
        this.x = a[0];
        this.y = a[1];
    }
}
const dn = 998244353;
class Ans {
    f = [];
    points = [];
    distance;
    constructor(n) {
        this.f[0] = 1;
        for (var i = 1; i <= n; i++)
            this.f[i] = (this.f[i - 1] * i) % dn;
    }
    p = (n, m) => this.f[n] / this.f[n - m];
    c = (n, m) => (this.f[n] / (this.f[m] * this.f[n - m])) % dn;

    addPoint(a = []) {
        this.points.push(new Point(a));
    }
    calculateDistance = () => {
        let curr = 0
        this.distance = [];
        this.points.forEach(p => {
            this.distance.push([]);
            for (var i = 0; i < curr; i++) {
                this.distance[curr].push(this.distance[i][curr]);
            }
            this.distance[curr].push(0);
            for (var i = curr + 1; i < this.points.length; i++) {
                let dis = Math.abs(p.x - this.points[i].x) + Math.abs(p.y - this.points[i].y);
                this.distance[curr].push(dis);
            }
            curr++;
        })
    }
    solve = () => {
        const n = this.points.length;
        let sol = this.f[n];
        for (let a = 0; a < n-2; a++) {
            const p1 = this.points[a];
            let b=a+1;
            let c=a+2;
            if (this.distance[a][b] < this.distance[a][c] && this.distance[a][b] < this.distance[b][c]){
                sol += (n) * (this.p(n-1,n-2));
            }
            if (this.distance[a][b] == this.distance[a][c] && this.distance[a][b] == this.distance[b][c]) {
                // i,j,k same color
                let d=a+3;
                if(d>=n || (this.distance[b][c] < this.distance[b][d] && this.distance[b][c] < this.distance[c][d])){
                    sol += (n) * (this.p(n-1,n-3));
                }
            }
        }
        return sol;
    }
}

(async () => {
    let t = parseInt(await read());
    if (t == 2) {
        console.log(2);
        return;
    }
    let ans = new Ans(t);
    while (t--) {
        ans.addPoint(
            (await read()).split(' ').map(Number));
    }
    ans.calculateDistance();
    console.log(ans.solve());
})().then(() => { }
).catch((e) => {
    console.log("error: "+e);
});