#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
template <typename T>
struct point {
  T x, y;
  point() {}
  point(T xx, T yy) : x(xx), y(yy) {}
  point(const point& B) : x(B.x), y(B.y) {}
  double radius() const { return sqrt(x * x + y * y); }
  double angle() const { return atan2(y, x); }
  double angle_degree() const {
    return atan2(y, x) * 180 /
           3.14159265358979323846264338327950288419716939937510;
  }
  bool operator==(const point& B) const { return x == B.x && y == B.y; }
  bool operator!=(const point& B) const { return x != B.x || y != B.y; }
  bool operator<(const point& B) const {
    return x < B.x || (x == B.x && y < B.y);
  }
  bool operator>(const point& B) const {
    return x > B.x || (x == B.x && y > B.y);
  }
  bool operator<=(const point& B) const {
    return x < B.x || (x == B.x && y <= B.y);
  }
  bool operator>=(const point& B) const {
    return x > B.x || (x == B.x && y >= B.y);
  }
  point& operator=(const point& B) {
    x = B.x;
    y = B.y;
    return *this;
  }
  point operator+(const point& B) const { return point(x + B.x, y + B.y); }
  point operator-(const point& B) const { return point(x - B.x, y - B.y); }
  point& operator+=(const point& B) {
    x += B.x;
    y += B.y;
    return *this;
  }
  point& operator-=(const point& B) {
    x -= B.x;
    y -= B.y;
    return *this;
  }
  T operator*(const point& B) const { return x * B.x + y * B.y; }
  T operator^(const point& B) const { return x * B.y - y * B.x; }
};
template <typename T>
std::ostream& operator<<(std::ostream& os, const point<T>& p) {
  return os << "(" << p.x << ", " << p.y << ")" << std::flush;
}
template <typename T>
double distance(const point<T>& A, const point<T>& B) {
  return sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y));
}
template <typename T>
double distance(T x1, T y1, T x2, T y2) {
  return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
template <typename T>
struct hash<point<T> > {
  size_t operator()(const point<T>& p) const {
    return std::hash<T>{}((std::hash<T>{}(p.x) * 19921211) ^
                          (std::hash<T>()(p.y) * 2147483647));
  }
};
template <typename T>
struct line_2p {
  point<T> pa, pb;
  line_2p(T x1, T y1, T x2, T y2) : pa(x1, y1), pb(x2, y2) {}
  T A() const { return pb.y - pa.y; }
  T B() const { return pa.x - pb.x; }
  T C() const { return pb.x * pa.y - pa.x * pb.y; }
  bool on_line(const point<T>& p) const {
    return A() * p.x + B() * p.y + C() == 0;
  }
  bool on_line_segment(const point<T>& p) const {
    if (!on_line(p)) return false;
    bool x_on = (pa.x <= p.x && p.x <= pb.x) || (pa.x >= p.x && p.x >= pb.x);
    bool y_on = (pa.y <= p.y && p.y <= pb.y) || (pa.y >= p.y && p.y >= pb.y);
    return x_on && y_on;
  }
};
template <typename T>
std::ostream& operator<<(std::ostream& os, const line_2p<T>& l) {
  return os << "line_2p{" << l.pa << ", " << l.pb << "}" << std::flush;
}
template <typename T>
bool is_parallel(const line_2p<T>& l1, const line_2p<T>& l2) {
  return l1.A() * l2.B() - l1.B() * l2.A() == 0;
}
template <typename T>
bool intersection(const line_2p<T>& l1, const line_2p<T>& l2, double& x,
                  double& y) {
  if (is_parallel(l1, l2)) return false;
  if (l1.B() == 0) {
    x = double(-l1.C()) / l1.A();
    y = double(-l2.C() - l2.A() * x) / l2.B();
    return true;
  }
  if (l2.B() == 0) {
    x = double(-l2.C()) / l2.A();
    y = double(-l1.C() - l1.A() * x) / l1.B();
    return true;
  }
  x = double(l1.B() * l2.C() - l2.B() * l1.C()) /
      double(l1.A() * l2.B() - l2.A() * l1.B());
  y = double(-x * l1.A() - l1.C()) / l1.B();
  return true;
}
const int maxn = 1e3 + 10;
int n;
unordered_map<point<long long>, set<int> > dupcnt;
vector<line_2p<long long> > lines;
int ret;
int count_points_online(int a, int b, int c, int d) {
  int dx = abs(a - c);
  int dy = abs(b - d);
  if (!dx) return dy + 1;
  if (!dy) return dx + 1;
  int g = gcd(dx, dy);
  return g + 1;
}
bool is_int(double d, double eps = 1e-9) {
  if (abs(static_cast<long long>(d) - d) <= eps) return true;
  return false;
}
int main() {
  scanf("%d\n", &n);
  for (int i = 0; i < (int)(n); ++i) {
    int a, b, c, d;
    scanf("%d %d %d %d\n", &a, &b, &c, &d);
    lines.push_back(line_2p<long long>(a, b, c, d));
    int points = count_points_online(a, b, c, d);
    ret += points;
    ;
  }
  for (int i = 0; i < (int)(n); ++i) {
    line_2p<long long>& l1 = lines[i];
    for (int j = i + 1; j < (int)(n); ++j) {
      line_2p<long long>& l2 = lines[j];
      double x, y;
      bool has_intersection = intersection(l1, l2, x, y);
      bool is_x_int = is_int(x), is_y_int = is_int(y);
      if (!has_intersection || !is_x_int || !is_y_int) continue;
      point<long long> p(x, y);
      if (!l1.on_line_segment(p) || !l2.on_line_segment(p)) continue;
      dupcnt[p].insert(i);
      dupcnt[p].insert(j);
    }
  }
  for (auto& p : dupcnt) {
    ;
    ret -= p.second.size() - 1;
  }
  printf("%d\n", ret);
  return 0;
}
