
#include <bits/stdc++.h>

using namespace std;

#define int long long
#define nn "\n"
#define pi pair<int, int>
#define fi first
#define se second
#define lb lower_bound
#define ub upper_bound
#define eb emplace_back
#define pb push_back
#define TASK "DTTG"

#define ms(a, x) memset(a, x, sizeof(a))
#define all(a) a.begin(), a.end()
#define All(a, n) a + 1, a + 1 + n

#define LOG 19

const int INF = 1e18;
const int mod = 1e9;
const int N = 1e5 + 5;
const int MOD = 998244353;
struct Point{
    int x, y;
    bool operator == (const Point &other) const{
        return x == other.x && y == other.y;
    }
};

Point a, b, c, m, n;

int cross(Point u, Point v, Point w){
    return (v.x - u.x) * (w.y - u.y) - (v.y - u.y) * (w.x - u.x);
}

bool trenDoan(Point u, Point v, Point w){
    return cross(u, v, w) == 0
        && min(u.x, v.x) <= w.x
        && w.x <= max(u.x, v.x)
        && min(u.y, v.y) <= w.y
        && w.y <= max(u.y, v.y);
}
bool giaoNhau(Point u, Point v, Point s, Point t){
    int c1 = cross(u, v, s);
    int c2 = cross(u, v, t);
    int c3 = cross(s, t, u);
    int c4 = cross(s, t, v);
    if(c1 == 0 && trenDoan(u, v, s)) return true;
    if(c2 == 0 && trenDoan(u, v, t)) return true;
    if(c3 == 0 && trenDoan(s, t, u)) return true;
    if(c4 == 0 && trenDoan(s, t, v)) return true;
    return ((c1 > 0 && c2 < 0) || (c1 < 0 && c2 > 0))
        && ((c3 > 0 && c4 < 0) || (c3 < 0 && c4 > 0));
}

bool trongTamGiac(Point p){
    int s1 = cross(a, b, p);
    int s2 = cross(b, c, p);
    int s3 = cross(c, a, p);

    return (s1 > 0 && s2 > 0 && s3 > 0)
        || (s1 < 0 && s2 < 0 && s3 < 0);
}

bool trungCanh(Point u, Point v){
    return trenDoan(u, v, m) && trenDoan(u, v, n)
        && cross(u, v, m) == 0
        && cross(u, v, n) == 0;
}

void nhap(){
    cin >> a.x >> a.y >> b.x >> b.y >> c.x >> c.y;
    cin >> m.x >> m.y >> n.x >> n.y;
}

void solve(){
    if(trungCanh(a, b) || trungCanh(b, c) || trungCanh(c, a)){
        cout << 3 << nn;
        return;
    }
    if(trongTamGiac(m) && trongTamGiac(n)){
        cout << 4 << nn;
        return;
    }
    vector<Point> canh = {a, b, c};
    vector<Point> diem;

    for(int i = 0; i < 3; i++){
        Point u = canh[i];
        Point v = canh[(i + 1) % 3];

        if(!giaoNhau(m, n, u, v)) continue;
        if(cross(m, n, u) == 0 && cross(m, n, v) == 0){
            if(trenDoan(m, n, u)) diem.pb(u);
            if(trenDoan(m, n, v)) diem.pb(v);
            if(trenDoan(u, v, m)) diem.pb(m);
            if(trenDoan(u, v, n)) diem.pb(n);
        }
        else{
            if(cross(m, n, u) == 0 && trenDoan(m, n, u)) diem.pb(u);
            else if(cross(m, n, v) == 0 && trenDoan(m, n, v)) diem.pb(v);
            else if(cross(u, v, m) == 0 && trenDoan(u, v, m)) diem.pb(m);
            else if(cross(u, v, n) == 0 && trenDoan(u, v, n)) diem.pb(n);
            else{
                int c1 = cross(m, n, u);
                int c2 = cross(m, n, v);
                int c3 = cross(u, v, m);
                int c4 = cross(u, v, n);
                if(((c1 > 0 && c2 < 0) || (c1 < 0 && c2 > 0))
                && ((c3 > 0 && c4 < 0) || (c3 < 0 && c4 > 0))){
                    cout << 2 << nn;
                    return;
                }
            }
        }
    }
    sort(all(diem), [](Point u, Point v){
        if(u.x != v.x) return u.x < v.x;
        return u.y < v.y;
    });
    diem.erase(unique(all(diem)), diem.end());
    if(diem.size() >= 2) cout << 2 << nn;
    else if(diem.size() == 1) cout << 1 << nn;
    else cout << 0 << nn;
}

signed main(){
    if(fopen(TASK".INP", "r")){
        freopen(TASK".INP", "r", stdin);
        freopen(TASK".OUT", "w", stdout);
    }

    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    nhap();
    solve();
    return (0 ^ 0);
}
