#include <bits/stdc++.h>
using namespace std;
const int Mod = 998244353;
int n;
struct Vec {
  long long x, y;
  Vec(long long a = 0, long long b = 0) {
    x = a;
    y = b;
  }
} A[110];
Vec operator+(const Vec& a, const Vec& b) { return Vec(a.x + b.x, a.y + b.y); }
Vec operator-(const Vec& a, const Vec& b) { return Vec(a.x - b.x, a.y - b.y); }
long long operator*(const Vec& a, const Vec& b) {
  return a.x * b.y - a.y * b.x;
}
int dir(Vec v) {
  if (v.x >= 0 && v.y >= 0) return 0;
  if (v.x < 0 && v.y >= 0) return 1;
  if (v.x < 0 && v.y < 0) return 2;
  if (v.x >= 0 && v.y < 0) return 3;
}
bool check_left(int i, int j, int k) {
  return (A[j] - A[i]) * (A[k] - A[i]) >= 0;
}
bool check_right(int i, int j, int k) {
  return (A[j] - A[i]) * (A[k] - A[i]) < 0;
}
bool check_ok(Vec a, Vec b, Vec c) {
  long long s1 = a * b;
  long long s2 = a * c;
  if (s1 >= 0 && s2 < 0) return true;
  if (s1 < 0 && s2 > 0) return false;
  return b * c > 0;
}
bool cmp(pair<int, int> a, pair<int, int> b) {
  Vec va = A[a.second] - A[a.first];
  Vec vb = A[b.second] - A[b.first];
  if (dir(va) != dir(vb)) return dir(va) < dir(vb);
  long long cross = va * vb;
  if (cross != 0) return cross > 0;
  return a < b;
}
vector<int> e[110];
vector<int> path[110][110];
bool good[110][110];
void find_path(int u, int lst, int s) {
  path[s][u] = path[s][lst];
  path[s][u].push_back(u);
  for (int i = 0; i < e[u].size(); i++) {
    int v = e[u][i];
    if (v == lst) continue;
    find_path(v, u, s);
  }
  return;
}
void dfs(int u, int lst) {
  int pos = -1;
  for (int i = 0; i < e[u].size(); i++) {
    int v = e[u][i];
    if (v == lst)
      pos = i;
    else
      dfs(v, u);
  }
  if (pos != -1) {
    swap(e[u][pos], e[u].back());
    e[u].pop_back();
  }
  return;
}
bool check_good(int u, int v, vector<int>& vec) {
  if (vec.size() < 3) return false;
  for (int i = 0; i < vec.size(); i++)
    if (!check_left(u, v, vec[i])) return false;
  return true;
}
void init_good() {
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++) good[i][j] = check_good(i, j, path[i][j]);
  return;
}
long long dp[110];
long long value[110][110];
bool vis[110];
int calc_value(vector<int>& vec) {
  memset(vis, 0, sizeof(vis));
  for (int i = 0; i < vec.size(); i++) vis[vec[i]] = true;
  long long res = 1;
  for (int i = 0; i < vec.size(); i++) {
    int u = vec[i];
    Vec v1, v2;
    if (i > 0)
      v1 = A[vec[i - 1]] - A[u];
    else
      v1 = A[u] - A[vec[i + 1]];
    if (i + 1 < vec.size())
      v2 = A[vec[i + 1]] - A[u];
    else
      v2 = A[u] - A[vec[i - 1]];
    for (int j = 0; j < e[u].size(); j++) {
      int v = e[u][j];
      if (vis[v]) continue;
      if (check_ok(v1, A[v] - A[u], v2)) res = res * dp[v] % Mod;
    }
  }
  return res;
}
long long f[210];
int id[110][110];
int first[110][110], last[110][110];
bool ok[110][110];
bool bl[210];
vector<int> solve(int u) {
  vector<int> vec;
  vec.push_back(u);
  for (int i = 0; i < e[u].size(); i++) {
    int v = e[u][i];
    vector<int> to = solve(v);
    for (int j = 0; j < to.size(); j++) vec.push_back(to[j]);
  }
  dp[u] = 0;
  long long sum = 1;
  for (int i = 0; i < e[u].size(); i++) {
    int v = e[u][i];
    sum = sum * dp[v] % Mod;
  }
  dp[u] = (dp[u] + sum) % Mod;
  sum = 0;
  for (int i = 0; i < e[u].size(); i++) {
    long long tmp = 1;
    for (int j = 0; j < e[u].size(); j++)
      if (i != j) tmp = tmp * dp[e[u][j]] % Mod;
    int v = e[u][i];
    for (int j = 0; j < e[v].size(); j++) tmp = tmp * dp[e[v][j]] % Mod;
    sum = (sum + tmp) % Mod;
  }
  dp[u] = (dp[u] + sum) % Mod;
  int num = 0;
  memset(bl, 0, sizeof(bl));
  for (int i = 0; i < vec.size(); i++) {
    int a = vec[i];
    for (int j = 0; j < e[a].size(); j++) {
      int b = e[a][j];
      id[a][b] = ++num;
      id[b][a] = ++num;
      if (dir(A[b] - A[a]) <= 1)
        bl[id[a][b]] = 1;
      else
        bl[id[b][a]] = 1;
    }
  }
  vector<pair<int, int> > V;
  for (int i = 0; i < vec.size(); i++)
    for (int j = 0; j < vec.size(); j++) {
      int a = vec[i], b = vec[j];
      ok[a][b] = false;
      if (!check_left(a, b, u)) continue;
      if (!good[a][b]) continue;
      V.push_back(make_pair(a, b));
      int sz = path[a][b].size();
      int x = path[a][b][0], y = path[a][b][1];
      first[a][b] = id[x][y];
      x = path[a][b][sz - 1];
      y = path[a][b][sz - 2];
      last[a][b] = id[x][y];
      if (value[a][b] != -1) continue;
      ok[a][b] = 1;
      value[a][b] = calc_value(path[a][b]);
    }
  sort(V.begin(), V.end(), cmp);
  for (int s = 1; s <= num; s++) {
    if (!bl[s]) continue;
    for (int c = -1; c <= 1; c += 2) {
      memset(f, 0, sizeof(f));
      f[s] = 1;
      for (int i = 0; i < V.size(); i++) {
        int x = V[i].first;
        int y = V[i].second;
        if (c == -1 && ok[x][y]) continue;
        int fr = first[x][y];
        int to = last[x][y];
        f[to] = (f[to] + f[fr] * value[x][y]) % Mod;
      }
      f[s] = (f[s] + Mod - 1) % Mod;
      dp[u] = (dp[u] + c * f[s] + Mod) % Mod;
    }
  }
  return vec;
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) scanf("%I64d %I64d", &A[i].x, &A[i].y);
  for (int i = 1; i < n; i++) {
    int u, v;
    scanf("%d %d", &u, &v);
    e[u].push_back(v);
    e[v].push_back(u);
  }
  for (int i = 1; i <= n; i++) find_path(i, 0, i);
  dfs(1, 0);
  init_good();
  memset(value, -1, sizeof(value));
  solve(1);
  printf("%I64d\n", dp[1]);
  return 0;
}
