#include <bits/stdc++.h>

using namespace std;

#define LOG(...) fprintf(stderr,__VA_ARGS__)
//#define LOG(...)
#define FOR(i,a,b) for(int i=(int)(a);i<(int)(b);++i)
#define RFOR(i,a,b) for(int i=(int)(b-1);i>=(int)(a);--i)
#define REP(i,n) for(int i=0;i<(int)(n);++i)
#define RREP(i,n) for(int i=(int)(n-1);i>=0;--i)
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define SORT(c) sort(ALL(c))
#define RSORT(c) sort(RALL(c))
#define SZ(a) ((int)(a).size())
#define BIT(x, i) (((x) >> (i)) & 1)
#define SQ(x) ((x)*(x))

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef vector<char> vc;
typedef vector<vc> vvc;
typedef vector<string> vs;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

typedef pair<pii, int> P;

const int dx[] = {-1,0,1,0}, dy[] = {0,1,0,-1};

bool is_clear(vvi& field) {
    REP(y, 4) REP(x, 4) {
        if (field[y][x] != 0) {
            return false;
        }
    }
    return true;
}

int main() {
    vvi field(4, vi(4));
    REP(y, 4) REP(x, 4) cin >> field[y][x];

    set<vvi> G;

    int click = 0;
    P sentry = {{-1,-1},-1};
    vvi sentry_field(4, vi(4, -1));
    queue<vvi> action;
    G.insert(field);
    action.push(field);
    action.push(sentry_field);
    while (!action.empty()) {
        vvi field = action.front(); action.pop();
        if (is_clear(field)) break;

        if (field[0][0] == -1) {
            if (action.empty()) break;
            action.push(sentry_field);
            click++;
            if (click > 5) {
                click = -1;
                break;
            }
            continue;
        }
        queue<P> que;
        REP(y, 4) REP(x, 4) {
            if (field[y][x] == 0) continue;
            vvi fi = field;
            fi[y][x]++;
            if (fi[y][x] >= 5) {
                fi[y][x] = 0;
                REP(d, 4) que.push({{x, y}, d});
                que.push(sentry);
                while (!que.empty()) {
                    P p = que.front(); que.pop();
                    if (p.second == -1) {
                        REP(y, 4) REP(x, 4) {
                            if (fi[y][x] >= 5) {
                                fi[y][x] = 0;
                                REP(d, 4) que.push({{x, y}, d});
                            }
                        }

                        if (que.empty()) break;
                        que.push(sentry);
                        continue;
                    }
                    int dir = p.second;
                    int sx = p.first.first + dx[dir], sy = p.first.second + dy[dir];
                    if (0 <= sx && sx < 4 && 0 <= sy && sy < 4) {
                        if (fi[sy][sx] > 0) {
                            fi[sy][sx]++;
                        } else {
                            que.push({{sx, sy}, dir});
                        }
                    }
                }
            }
            if (!EXIST(G, fi)) {
                G.insert(fi);
                action.push(fi);
            }
        }
    }
    cout << click << endl;
}

Measured memory_bytes: 39112