// {{{ y0105w49 template 21N30 // hi mom #ifndef NULL // #include #include #endif #include using namespace std; #ifdef ARST #define JO 1 #define OJ 0 #else #define JO 0 #define OJ 1 #endif #define STR(x) #x #define GCCDIAG(s) _Pragma(STR(GCC diagnostic s)) static_assert(true) #define Wsave GCCDIAG(push) #define Wpop GCCDIAG(pop) #define Wsupp(w) GCCDIAG(ignored "-W" w) #define Wpush(w) Wsave; Wsupp(w) #define typeof __typeof__ namespace gbd_ns { template struct is_iterable { template static long check(...); template static char check(int,typename T::const_iterator = C().end()); enum { value = sizeof(check(0)) == sizeof(char), neg_value = sizeof(check(0)) != sizeof(char) }; }; template struct _gbd3C; template ostream &_gbd3(ostream &os,const T &x) { return _gbd3C::call(os,x); } template<> ostream &_gbd3(ostream &os,const string &x) { return os<<'"'< ostream &_gbd3(ostream &os,char *const &x) { return os<<'"'< ostream &_gbd35(ostream &os,const T &x) { return _gbd3(os,x); // why?? } template ostream &_gbd4(ostream &os,const pair &p) { _gbd3(os<<'(',p.first); _gbd3(os<<',',p.second); return os<<')'; } template struct _gbd4_tupleC { static void call(ostream &os,const T &t) { _gbd4_tupleC::call(os,t); os<<','<(t); } }; template struct _gbd4_tupleC { static void call(ostream &os,const T &t) { os<(t); } }; template ostream &_gbd4(ostream &os,const tuple &t) { os<<'('; _gbd4_tupleC,sizeof...(Types)>::call(os,t); return os<<')'; } template<> ostream &_gbd4(ostream &os,const tuple<> &t) { (void)t; return os<<"()"; } template ostream &_gbd4(ostream &os,const T &x) { return os< struct _gbd3C { template static ostream &call(ostream &os,enable_if_t::value,const T> &V) { os<<"{"; bool ff=0; for(const auto &E:V) _gbd35(ff?os<<",":os,E), ff=1; return os<<"}"; } template static ostream &call(ostream &os,enable_if_t::neg_value,const T> &x) { return _gbd4(os,x); } }; template ostream &_gbd2(ostream &os,bool,vector::iterator nm,const T &x,Args&&... args); ostream &_gbd2(ostream &os,bool,vector::iterator) { return os; } template ostream &_gbd2(ostream &os,bool fi,vector::iterator nm,const char *x,Args&&... args) { return _gbd2(os<<(fi?"":" ")< ostream &_gbd2(ostream &os,bool fi,vector::iterator nm,const T &x,Args&&... args) { return _gbd2(_gbd3(os<<(fi?"":" ")<<*nm<<"=",x),0,nm+1,args...); } vector split(string s) { vector Z; string z=""; s+=','; int dep=0; for(char c:s) { if(c==',' && !dep) Z.push_back(z),z=""; else z+=c; if(c=='(' || c=='{' || c=='[') ++dep; if(c==')' || c=='}' || c==']') --dep; } return Z; } template ostream &_gbd1(ostream &os,const string &nm,Args&&... args) { return _gbd2(os,1,split(nm).begin(),args...); } template string _gbd1(const string &nm,Args&&... args) { ostringstream oss; _gbd2(oss,1,split(nm).begin(),args...); return oss.str(); } } bool DBG=1,EMACS=0; #define dbg(...) (JO&&DBG?gbd_ns::_gbd1(cerr<<"\033[38;5;5m"<<__FILE__<<":"<<__LINE__<<(EMACS?":note: ":": "),#__VA_ARGS__,__VA_ARGS__)<<"\033[0m"< struct _y_combinator_result { Fun _fun; template explicit _y_combinator_result(T &&fun) : _fun(forward(fun)) {} template decltype(auto) operator()(Args &&... args) { return _fun(ref(*this),forward(args)...); } }; template [[nodiscard]] decltype(auto) fix(Fun &&fun) { return _y_combinator_result>(forward(fun)); } #define nop void() #define sz(x) (int((x).size())) #define all(v) begin(v),end(v) #define sortu(v) (sort(all(v)), (v).resize(unique(all(v))-begin(v))) #define forenum(i,...) for(int i:{-1}) for(__VA_ARGS__) if(++i,0) assert(0); else #define forenumll(i,...) for(long long i:{-1}) for(__VA_ARGS__) if(++i,0) assert(0); else #define forbs(k,i,bs) for(ptrdiff_t k=0,i=(bs)._Find_first();i<(ptrdiff_t)(bs).size();i=(bs)._Find_next(i),++k) #define fordbs(k,i,bs) for(ptrdiff_t k=0,i=(bs).find_first();i<(ptrdiff_t)(bs).size();i=(bs).find_next(i),++k) #define get(x,i) get(x) template bool inb(const T &x,const T &l,const T &r) { return l<=x&&x<=r; } #define fi first #define se second #define pb push_back #define eb emplace_back template using omap=__gnu_pbds::tree,__gnu_pbds::rb_tree_tag,__gnu_pbds::tree_order_statistics_node_update>; template using oset=omap; template using rope=__gnu_cxx::rope; using dbitset=tr2::dynamic_bitset<>; const int e0=1, e1=10, e2=100, e3=1000; const int e4=10*e3, e5=100*e3, e6=1000*e3; const int e7=10*e6, e8=100*e6, e9=1000*e6; const long long e12=1LL*e3*e9, e15=1LL*e6*e9, e18=1LL*e9*e9; using ulll=__uint128_t; using lll=__int128_t; using ull=unsigned long long; using ll=long long; unsigned long long START_TIME=chrono::duration_cast(chrono::steady_clock::now().time_since_epoch()).count(); inline unsigned long long now_U_03BC_s() { return chrono::duration_cast(chrono::steady_clock::now().time_since_epoch()).count()-START_TIME; } const char *fmt_time(unsigned long long U_03BC_s=now_U_03BC_s()) { static char dur[20]; sprintf(dur,"%llu.%03llus",U_03BC_s/e6,(U_03BC_s%e6)/e3); return dur; } #define timed(cb) do { dbg("timed "#cb" ..."); unsigned long long start=now_U_03BC_s(); cb; dbg("timed "#cb" took",fmt_time(now_U_03BC_s()-start)); } while(0) int arg1; bool inp; vector args; unsigned seed=JO&&getenv("sd")?atoi(getenv("sd")):unsigned(OJ?START_TIME:START_TIME%e5); mt19937 igen(seed<<1),gen(seed<<1|1); #define irand(...) _rand(igen,__VA_ARGS__) #define rand(...) _rand(gen,__VA_ARGS__) template enable_if_t::is_integer,T> _rand(mt19937 &g,T l,T r) { return uniform_int_distribution(l,r)(g); } template enable_if_t::is_integer,T> _rand(mt19937 &g,T n) { return _rand(g,T(1),n); } [[deprecated]] int _rand(mt19937 &g) { return _rand(g,0,numeric_limits::max()); } template enable_if_t::is_iec559,T> _rand(mt19937 &g,T l,T r) { return uniform_real_distribution(l,r)(g); } bool _rand(mt19937 &g,double p) { return bernoulli_distribution(p)(g); } template T _rand(mt19937 &g,initializer_list il) { return *(il.begin()+_rand(g,0,(int)il.size()-1)); } template T _rand(mt19937 &g,double p,T a,T b) { return _rand(g,p)?a:b; } template T _rand(mt19937 &g,initializer_list il,initializer_list wt) { assert(il.size()==wt.size()); return *(il.begin()+discrete_distribution(wt)(g)); } #define random_shuffle(...) static_assert(false,"random_shuffle deprecated, use shuffle") #define ine(x,e) (inp?cin>>(x),nop:((x)=(e),nop)) #define inr(x,...) ine(x,irand(__VA_ARGS__)) #define endl '\n' string garb; void exit0() { dbg("finished (early) in",fmt_time()); exit(0); } #ifndef MAIN #define MAIN _main #endif void MAIN(); int32_t main([[maybe_unused]]int argc,[[maybe_unused]]char *argv[]) { ios_base::sync_with_stdio(0); cin.tie(0); cin.exceptions(ios_base::failbit | ios_base::badbit); arg1=0,args={argv,argv+argc}; if(sz(args)>1) { if(args[1][0]=='i') freopen((string(__FILE__).substr(0,string(__FILE__).find('.'))+"."+args[1].substr(1)+".in").c_str(),"r",stdin); else if(args[1][0]=='I') freopen(args[1].substr(1).c_str(),"r",stdin); else arg1=stoi(args[1]); } inp=!arg1; if(JO && getenv("EMACS")) EMACS=1; dbgt(arg1,seed,args); MAIN(); dbgt("gg;wp"); } using flt=double; //CARE const flt U_03B5_=(flt)1e-8; const flt U_03C4_=(flt)(2*acosl(-1)); const int inf=e9+99; const ll linf=1LL*e9*e9+99; // }}} const int P=e9+7;//998'244'353; // #define dbitset dbset struct dbset { size_t n; vector a; dbset(size_t _n) : n(_n), a((n+63)>>6) {} size_t size() const { return n; } void trim() { assert((n+63)>>6==a.size()); a.back()&=~0ULL>>(63&-n); } bool operator[](size_t i) const { return (a[i>>6]>>(i&63))&1; } int count() const { int z=0; for(ull x:a) z+=__builtin_popcountll(x); return z; } bool any() const { for(ull x:a) if(x) return 1; return 0; } size_t find_next(size_t i) const { ++i; ull x=a[i>>6]>>(i&63)<<(i&63); i>>=6; if(x) return __builtin_ctzll(x)+(i<<6); for(;++i>6]|=1ULL<<(i&63); } void reset(size_t i) { a[i>>6]&=~(1ULL<<(i&63)); } void flip(size_t i) { a[i>>6]^=1ULL<<(i&63); } friend dbset operator~(dbset a) { a.flip(); return a; } void operator|=(const dbset &o) { assert(o.n==n); for(size_t i=0;i=(ptrdiff_t)n) return reset(); for(size_t i=sz(a)-(d>>6)-1;;--i) { a[i+(d>>6)]=a[i]<<(d&63); if(!i) break; if(d&63) a[i+(d>>6)]|=a[i-1]>>(64-(d&63)); } fill(a.begin(),a.begin()+(d>>6),0); trim(); } void operator>>=(ptrdiff_t d) { if(d<0) return *this<<=-d; if(d>=(ptrdiff_t)n) return reset(); for(size_t i=(d>>6);;++i) { a[i-(d>>6)]=a[i]>>(d&63); if(i+1==a.size()) break; if(d&63) a[i-(d>>6)]|=a[i+1]<<(64-(d&63)); } fill(a.end()-(d>>6),a.end(),0); } friend dbset operator<<(dbset a,ptrdiff_t d) { a<<=d; return a; } friend dbset operator>>(dbset a,ptrdiff_t d) { a>>=d; return a; } friend ostream &operator<<(ostream &os,const dbset &a) { for(size_t i=a.n;~--i;) os<>n>>m>>k; bool fl=n>m; if(fl) swap(n,m), dbg("flippppping"); assert(1LL*n*m<=5*e6 && inb(k,0,n*m-1)); dbgt("input",n,m,k,fl); vector a(n+2,dbitset(m+2)); for(auto &bs:a) bs.set(0), bs.set(m+1); a[0].set(), a[n+1].set(); for(;k--;) { int x,y; cin>>x>>y; if(fl) swap(x,y); assert(inb(x,1,n) && inb(y,1,m) && !a[x][y]); a[x].set(y); } if(n*m lasr(n+2,0),lasc(m+2,0); int CAP=inf; forenum(x,const auto &bs:a) fordbs(_,y,bs) { if(y>lasr[x]+1) CAP=min(CAP,(int)y-lasr[x]-1); if(x>lasc[y]+1) CAP=min(CAP,(int)x-lasc[y]-1); lasr[x]=(int)y, lasc[y]=(int)x; } dbgt("early cap",CAP); assert(CAP<=min(m,n)); int Z=1; vector> aa; aa.pb({}), aa.pb(a); #define a aa[Z] dbitset tmp(m+2); for(;Z=Z;x--) { aa.back()[x]<<=1; aa.back()[x]|=a[x]; aa.back()[x+1]|=aa.back()[x]; tmp=~a[x]&aa.back()[x]; fordbs(_,y,tmp) for(int dx:{-1,1}) for(int dy:{-1,1}) { if(a[x+dx][y+dy] && a[x-dx][y] && a[x][y-dy]) { aa.pop_back(); goto die; } } } ++Z; } die:; dbgt("medium cap",Z); if(n*m da((n+2)*(m+2)); forenum(i,int &x:da) x=i; auto _rt=fix([&](auto rec,int u) -> int { return da[u]==u?u:da[u]=rec(da[u]); }); auto rt=[&](int x,int y) -> int { return _rt(x*(m+2)+y); }; auto upd=[&](int x,int y) -> void { assert(a[x][y]); ++ccs; int u=rt(x,y); for(int xx:{x-1,x,x+1}) for(int yy:{y-1,y,y+1}) if((x!=xx)^(y!=yy)) { if(!a[xx][yy]) continue; int v=rt(xx,yy); if(v!=u) da[v]=u, --ccs; } }; for(auto &v:aa) for(auto &bs:v) bs.flip(); forenum(x,const auto &bs:a) fordbs(_,y,bs) upd(x,(int)y); if(n*m0); for(;ccs>1 && Z>1;) { --Z; for(int x=Z;x<=n;x++) { tmp=a[x]&~aa[Z+1][x]; fordbs(_,y,tmp) upd(x,(int)y); } } dbgt("final",ccs,Z); if(n*m=1 && Z>=1); if(ccs>1) assert(Z==1); cout<<(ccs==1?Z:-1)<