jiahuimbzuai/CoQuIR huggingface dataset:
//  [c]
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define rep(i,N) for(int i=0;i<(int)N;i++)
#pragma GCC optimize("O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
static inline char GET(void)
{
  static char buf[1<<15],*s1=buf,*s2=buf;
  return s1==s2&&(s2=(s1=buf)+fread(buf,1,1<<15,stdin),s1==s2)?EOF:*s1++;
}
static inline void PUT(char c)
{
  static char buf[1<<15],*ptr=buf;
  if(ptr==buf+strlen(buf)||c==0){fwrite(buf,1,ptr-buf,stdout),ptr=buf;}*ptr++=c;
}
static inline int IN(void)
{
  int x=0,f=0,c=GET();while(c<48||c>57){f^=c==45,c=GET();}
  while(c>47&&c<58){x=x*10+c-48,c=GET();}return f?-x:x;
}
static inline void OUT(int a)
{
  if(a<0)PUT('-'),a=-a;
  int d[40],i=0;do{d[i++]=a%10;}while(a/=10);
  while(i--){PUT(d[i]+48);}PUT('\n');
}
static inline int Max(int x,int y){return x>y?x:y;}
int main(void)
{
  int H=IN(),W=IN(),M=IN(),row[H],col[W],bombY[M],bombX[M],
      idh=0,idw=0,hmax=0,wmax=0,obj=0;
  memset(row,0,sizeof(row));memset(col,0,sizeof(col));
  rep(i,M)
  {
    bombY[i]=IN()-1,bombX[i]=IN()-1;
    row[bombY[i]]++;col[bombX[i]]++;
    hmax=Max(hmax,row[bombY[i]]);wmax=Max(wmax,col[bombX[i]]);
  }
  rep(i,H){if(hmax==row[i]){idh++;}}rep(j,W){if(wmax==col[j]){idw++;}}
  rep(i,M){obj+=(row[bombY[i]]==hmax&&col[bombX[i]]==wmax);}
  return OUT(hmax+wmax-(1l*obj==1l*idh*idw)),0;
}
//  [c]
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define rep(i,N) for(int i=0;i<(int)N;i++)
#pragma GCC optimize("O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
static inline char GET(void)
{
  static char buf[1<<22],*s1=buf,*s2=buf;
  return s1==s2&&(s2=(s1=buf)+fread(buf,1,1<<22,stdin),s1==s2)?EOF:*s1++;
}
static inline void PUT(char c)
{
  static char buf[1<<15],*ptr=buf;
  if(ptr==buf+strlen(buf)||c==0){fwrite(buf,1,ptr-buf,stdout),ptr=buf;}*ptr++=c;
}
static inline int IN(void)
{
  int x=0,f=0,c=GET();while(c<48||c>57){f^=c==45,c=GET();}
  while(c>47&&c<58){x=x*10+c-48,c=GET();}return f?-x:x;
}
static inline void OUT(int a)
{
  if(a<0)PUT('-'),a=-a;
  int d[40],i=0;do{d[i++]=a%10;}while(a/=10);
  while(i--){PUT(d[i]+48);}PUT('\n');
}
static inline int Max(int x,int y){return x>y?x:y;}
int main(void)
{
  int H=IN(),W=IN(),M=IN(),row[H],col[W],bombY[M],bombX[M],
      idh=0,idw=0,hmax=0,wmax=0,obj=0;
  memset(row,0,sizeof(row));memset(col,0,sizeof(col));
  rep(i,M)
  {
    bombY[i]=IN()-1,bombX[i]=IN()-1;
    row[bombY[i]]++;col[bombX[i]]++;
    hmax=Max(hmax,row[bombY[i]]);wmax=Max(wmax,col[bombX[i]]);
  }
  rep(i,H){if(hmax==row[i]){idh++;}}rep(j,W){if(wmax==col[j]){idw++;}}
  rep(i,M){obj+=(row[bombY[i]]==hmax&&col[bombX[i]]==wmax);}
  return OUT(hmax+wmax-(1l*obj==1l*idh*idw)),0;
}
//  [c]
#include <ctype.h>
#include <float.h>
#include <inttypes.h>
#include <limits.h>
#include <signal.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <math.h>
#ifdef __cplusplus
#include <bits/stdc++.h>
#endif
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")

#define getchar getchar_unlocked
#define putchar putchar_unlocked
int32_t nextint(void){ char c=getchar(); while(c!='-'&&(c<'0'||'9'<c)) c=getchar(); bool s=false; if(c=='-'){s=true;c=getchar();} uint32_t x=0; while('0'<=c && c<='9'){ x=x*10+c-'0'; c=getchar(); } return s?-x:x; }
int64_t nextlong(void){ char c=getchar(); while(c!='-'&&(c<'0'||'9'<c)) c=getchar(); int s=0; if(c=='-'){s=1;c=getchar();} uint64_t x=0; while('0'<=c && c<='9'){ x=x*10+c-'0'; c=getchar(); } return s?-x:x; }
uint32_t nextstr(char *s){ char c=getchar(); while(c==' '||c=='\n') c=getchar(); uint32_t len=0; while(c!=' '&&c!='\n'){ *s++=c; len++; c=getchar(); } *s='\0'; return len; }
void rsorta_d32(void *base, const int count, const int size, const int index){
	typedef int32_t rsort_t;
	rsort_t (*a)[size] = (rsort_t(*)[size])base;
	rsort_t (*b)[size] = (rsort_t(*)[size])malloc(count*size*sizeof(rsort_t));
	int c[0x100];
	for(int k=0; k<4; k++){
		memset(c, 0, sizeof(c)); for(int i=0; i<count; i++){ c[(a[i][index]>>(k<<3))&0xFF]++; } for(int i=1; i<0x100; i++) c[i]+=c[i-1]; for(int i=count-1; i>=0; i--){ int to=--c[(a[i][index]>>(k<<3))&0xFF]; for(int j=0; j<size; j++){ b[to][j]=a[i][j]; } }{rsort_t(*t)[size]=a; a=b; b=t;}
	}
	free(b);
}

int a[300000][2];
int cx[300000], cy[300000];
int main(void){
	int h=nextint();
	int w=nextint();
	int n=nextint();
	for(int i=0; i<n; i++){
		a[i][0]=nextint()-1;
		a[i][1]=nextint()-1;
		cx[a[i][0]]++;
		cy[a[i][1]]++;
	}
	int bxm=0, bym=0;
	int bx=0, by=0;
	for(int x=0; x<h; x++){
		if(cx[x]>bxm){
			bxm=cx[x];
			bx=1;
		}else if(cx[x]==bxm){
			bx++;
		}
	}
	for(int y=0; y<w; y++){
		if(cy[y]>bym){
			bym=cy[y];
			by=1;
		}else if(cy[y]==bym){
			by++;
		}
	}
	if(bx*by>n){
		int ans=bxm+bym;
		printf("%d\n", ans);
	}else{
		int s=0;
		for(int i=0; i<n; i++){
			if(cx[a[i][0]]==bxm && cy[a[i][1]]==bym){
				s++;
			}
		}
		if(s==bx*by){
			int ans=bxm+bym-1;
			printf("%d\n", ans);
		}else{
			int ans=bxm+bym;
			printf("%d\n", ans);
		}
	}
}
//  [c]
#include <stdio.h>
#include <stdlib.h>

typedef struct{
    int row;
    int target;
}pair;//個数と行列番号保持
typedef struct{
    int ver;
    int hor;
}hoge;//座標保持
int compare(const void *a,const void *b){
    pair x=*(pair *)a,y=*(pair *)b;
    int p=x.target,q=y.target;
    if(p<q)return 1;
    return -1;
}
int compint(const void *a,const void *b){
    if(*(const int *)a> *(const int *)b)return 1;
    if(*(const int *)a== *(const int *)b)return 0;
    return -1;
}
int main()
{   int h,w,m;
    scanf("%d%d%d",&h,&w,&m);
    hoge a[m];
    pair x[h],y[w];         //XとY方向で各行・列にあるターゲットの個数と行列番号を保持する。
    for(int i=0;i<w;i++){
        x[i].row=i;
        x[i].target=0;
    }
    for(int i=0;i<h;i++){
        y[i].row=i;
        y[i].target=0;
    }
    int arr1[h],arr2[w];
    for(int i=0;i<m;i++){
        int tmpx,tmpy;
        scanf("%d%d",&tmpy,&tmpx);
        tmpx--;
        tmpy--;
        a[i].hor=tmpx;
        a[i].ver=tmpy;
        x[tmpy].target++;
        y[tmpx].target++;
    }
    /*for(int i=0;i<w;i++){
        printf("%d ",x[i].target);
    }
    printf("\n");
    for(int i=0;i<h;i++){
        printf("%d ",y[i].target);
    }
     */
    qsort(x,h,sizeof(pair),compare);    //行列にあるターゲットの個数が多い順にソート
    qsort(y,w,sizeof(pair),compare);
    /* for(int i=0;i<h;i++){
        printf("%d x=%d ",y[i].target,y[i].row);
    }
    printf("\n");
    for(int i=0;i<w;i++){
        printf("%d y=%d ",x[i].target,x[i].row);
    }
    */
    int i=0;
    arr1[0]=x[0].row;
    while(x[i].target==x[i+1].target&&i<h){
        i++;
        arr1[i]=x[i].row;
    }
    qsort(arr1,i,sizeof(int),compint);
    int xmax=i+1;
    i=0;
    arr2[0]=y[0].row;
    while(y[i].target==y[i+1].target&&i<w){
        i++;
        arr2[i]=y[i].row;
    }
    int ymax=i+1;
    qsort(arr2,i,sizeof(int),compint);
    /*
    for(int j=0;j<xmax;j++){
        printf("%d",arr1[j]);
    }
    printf("\n");
    for(int j=0;j<ymax;j++){
        printf("%d\n",arr2[j]);
    }
    */
    int flag=0;
    for(i=0;i<m;i++){
        //printf("\nx=%d y=%d",a[i].hor,a[i].ver);
        if((bsearch(&a[i].ver,arr1,xmax,sizeof(int),compint)!=NULL)&&(bsearch(&a[i].hor,arr2,ymax,sizeof(int) , compint)!=NULL)){
            flag++;
        }
    }
    int ans=x[0].target+y[0].target;
    if(flag==xmax*ymax)ans--;
    printf("%d",ans);

    return 0;
}
//  [c]
#include <stdio.h>
#include <stdlib.h>

typedef struct{
    int row;
    int target;
}pair;//個数と行列番号保持
typedef struct{
    int ver;
    int hor;
}hoge;//座標保持
int compare(const void *a,const void *b){
    pair x=*(pair *)a,y=*(pair *)b;
    int p=x.target,q=y.target;
    if(p<q)return 1;
    return -1;
}
int compint(const void *a,const void *b){
    if(*(const int *)a> *(const int *)b)return 1;
    if(*(const int *)a== *(const int *)b)return 0;
    return -1;
}
int main()
{   int h,w,m;
    scanf("%d%d%d",&h,&w,&m);
    hoge a[m];
    pair x[h],y[w];         //XとY方向で各行・列にあるターゲットの個数と行列番号を保持する。
    for(int i=0;i<w;i++){
        x[i].row=i;
        x[i].target=0;
    }
    for(int i=0;i<h;i++){
        y[i].row=i;
        y[i].target=0;
    }
    int arr1[h],arr2[w];
    for(int i=0;i<m;i++){
        int tmpx,tmpy;
        scanf("%d%d",&tmpy,&tmpx);
        tmpx--;
        tmpy--;
        a[i].hor=tmpx;
        a[i].ver=tmpy;
        x[tmpy].target++;
        y[tmpx].target++;
    }
    /*for(int i=0;i<w;i++){
        printf("%d ",x[i].target);
    }
    printf("\n");
    for(int i=0;i<h;i++){
        printf("%d ",y[i].target);
    }
     */
    qsort(x,h,sizeof(pair),compare);    //行列にあるターゲットの個数が多い順にソート
    qsort(y,w,sizeof(pair),compare);
    /* for(int i=0;i<h;i++){
        printf("%d x=%d ",y[i].target,y[i].row);
    }
    printf("\n");
    for(int i=0;i<w;i++){
        printf("%d y=%d ",x[i].target,x[i].row);
    }
    */
    int i=0;
    arr1[0]=x[0].row;
    while(x[i].target==x[i+1].target&&i<h){
        i++;
        arr1[i]=x[i].row;
    }
    qsort(arr1,i,sizeof(int),compint);
    int xmax=i+1;
    i=0;
    arr2[0]=y[0].row;
    while(y[i].target==y[i+1].target&&i<w){
        i++;
        arr2[i]=y[i].row;
    }
    int ymax=i+1;
    qsort(arr2,i,sizeof(int),compint);
    /*
    for(int j=0;j<xmax;j++){
        printf("%d",arr1[j]);
    }
    printf("\n");
    for(int j=0;j<ymax;j++){
        printf("%d\n",arr2[j]);
    }
    */
    int flag=0;
    for(i=0;i<m;i++){
        //printf("\nx=%d y=%d",a[i].hor,a[i].ver);
        if((bsearch(&a[i].ver,arr1,xmax,sizeof(int),compint)!=NULL)&&(bsearch(&a[i].hor,arr2,ymax ,sizeof(int) , compint)!=NULL)){
            flag++;
        }
    }
    int ans=x[0].target+y[0].target;
    if(flag==xmax*ymax)ans--;
    printf("%d",ans);

    return 0;
}
//  [javascript]
function main(input = "") {
    const lines = input.split("\n");
    const header = lines[0].split(" ").map((v) => (Number(v)));
    const H = header[0], W = header[1], M = header[2];

    let arrH = new Int32Array(H);
    let arrW = new Int32Array(W);
    let grid = new Set();
    for (let i = 0; i < M; i++) {
        let arr = lines[i + 1].split(" ");
        let h = arr[0] - 1, w = arr[1] - 1;
        arrH[h]++;
        arrW[w]++;
        grid.add(h * W + w);
    }

    let maxH = arrH[0];
    let idsH = [0];
    for (let i = 0; i < H; i++) {
        let v = arrH[i];
        if (maxH < v) {
            maxH = v;
            idsH = [i]
        } else if (maxH === v) {
            idsH.push(i);
        }
    }

    let maxW = arrW[0];
    let idsW = [0];
    for (let i = 0; i < W; i++) {
        let v = arrW[i];
        if (maxW < v) {
            maxW = v;
            idsW = [i]
        } else if (maxW === v) {
            idsW.push(i);
        }
    }

    for (let h = 0; h < idsH.length; h++) {
        let idh = idsH[h];
        for (let w = 0; w < idsW.length; w++) {
            let idw = idsW[w];
            if (!grid.has(idh * W + idw)) {
                return maxH + maxW;
            }
        }
    }

    return maxH + maxW - 1;
}

//******************************
exports.main = main;

function Main(input) {
    console.log(main(input.trim()));
}

if (process.argv[2] !== "test") {
    Main(require("fs").readFileSync("/dev/stdin", "utf8"));
}
//  [javascript]
"use strict";
var input=require("fs").readFileSync("/dev/stdin","utf8");
var cin=input.split(/ |\n/),cid=0;
function next(){return +cin[cid++];}
function nextstr(){return cin[cid++];}
function nextbig(){return BigInt(cin[cid++]);}
function nexts(n,a){return a?cin.slice(cid,cid+=n):cin.slice(cid,cid+=n).map(a=>+a);}
function nextm(h,w,a){var r=[],i=0;if(a)for(;i<h;i++)r.push(cin.slice(cid,cid+=w));else for(;i<h;i++)r.push(cin.slice(cid,cid+=w).map(a=>+a));return r;}
function xArray(v){var a=arguments,l=a.length,r="Array(a["+--l+"]).fill().map(x=>{return "+v+";})";while(--l)r="Array(a["+l+"]).fill().map(x=>"+r+")";return eval(r);}

var myOut = main();
if(myOut !== undefined)console.log(String(myOut));

function main(){
  var [h,w,m] = nexts(3);
  var y = xArray(0,h), x = xArray(0,w);
  var set = xArray("new Set()",h);
  for(var i = 0; i < m; i++){
    var u = next()-1, v = next()-1;
    set[u].add(v);
    y[u]++, x[v]++;
  }
  var mx = 0, xid = [], yx = 0, yid = [];
  for(var i = 0; i < h; i++){
    if(yx < y[i])yx = y[i], yid = [i];
    else if(yx === y[i])yid.push(i);
  }
  for(var i = 0; i < w; i++){
    if(mx < x[i])mx = x[i], xid = [i];
    else if(mx === x[i])xid.push(i);
  }
  for(var i = 0; i < yid.length; i++)for(var j = 0; j < xid.length; j++){
    var yy = yid[i], xx = xid[j];
    if(!set[yy].has(xx))return mx+yx;
  }
  return mx+yx-1;
}
//  [javascript]
const main = (input) => {
  input = input.trim().split('\n')
  const [h, w, m] = input[0].split(' ').map(Number)

  const hs = new Array(h+1).fill(0)
  const ws = new Array(w+1).fill(0)
  const bomb = new Map()

  for (let i=1; i<=m; i++) {
    const [hi, wi] = input[i].split(' ').map(Number)
    hs[hi-1]++
    ws[wi-1]++
    bomb.set(`${hi-1}:${wi-1}`, true)
  }

  let hmx = 0
  let wmx = 0

  let topH = []
  let topW = []

  for (let i=0; i<Math.max(hs.length, ws.length); i++) {
    if (hs[i] && hs[i] > hmx) {
      hmx = hs[i]
      topH = [[i, hs[i]]]
    } else if (hs[i] && hs[i] === hmx) {
      topH.push([i, hs[i]])
    }

    if (ws[i] && ws[i] > wmx) {
      wmx = ws[i]
      topW = [[i, ws[i]]]
    } else if (ws[i] && ws[i] === wmx) {
      topW.push([i, ws[i]])
    }
  }

  // const hs = {}
  // const ws = {}
  //
  // const bomb = new Map()
  //
  // for (let i=1; i<=m; i++) {
  //   const [hi, wi] = input[i].split(' ').map(Number)
  //   hs[hi-1] = ~~hs[hi-1] + 1
  //   ws[wi-1] = ~~ws[wi-1] + 1
  //   bomb.set(`${hi-1}:${wi-1}`, true)
  // }

  // const ascH = [...Object.entries(hs)].sort((a, b) => b[1] - a[1])
  // const ascW = [...Object.entries(ws)].sort((a, b) => b[1] - a[1])
  //
  // const topH = [ascH.shift()]
  // const topW = [ascW.shift()]
  // while (ascH[0] && topH[0][1] === ascH[0][1]) topH.push(ascH.shift())
  // while (ascW[0] && topW[0][1] === ascW[0][1]) topW.push(ascW.shift())

  for (let x=0; x<topH.length; x++) {
    for (let y=0; y<topW.length; y++) {
      if (!bomb.has(`${topH[x][0]}:${topW[y][0]}`)) return console.log(hmx + wmx)
    }
  }

  return console.log(hmx + wmx - 1)
  // return console.log(topH[0][1] + topW[0][1] - 1)
}

process.env.MYTEST ? test() : main(require('fs').readFileSync('/dev/stdin', 'utf8'))
//  [javascript]
(async () => {
    let input = '';
    for await (const chunk of process.stdin) input += chunk;
    const lines = input.split(/\n/);
    const [h, w, m] = lines[0].split(/\s/).map(v => +v);
    const targets = lines.slice(1, m + 1).map(line => line.split(/\s/).map(v => v - 1));

    let targetCount = [new Array(h).fill(0), new Array(w).fill(0)];
    let targetMap = new Array(h).fill([]).map(x => new Array(w).fill(false));
    for (const target of targets) {
        targetCount[0][target[0]]++;
        targetCount[1][target[1]]++;
        targetMap[target[0]][target[1]] = true;
    }

    let yMaxs = [];
    let yMax = 0;
    for (let i = 0; i < h; i++) {
        if(targetCount[1][i] < yMax) continue;
        if(targetCount[1][i] == yMax){
            yMaxs.push(i);
        }else{
            yMax = targetCount[1][i];
            yMaxs = [i];
        }
    }
    let allCross = 1;
    let xMax = 0;
    for (let i = 0; i < h; i++) {
        if(targetCount[0][i] < xMax) continue;
        if(targetCount[0][i] > xMax){
            xMax = targetCount[0][i];
            allCross = 1;
        }
        for (let j = 0; j < yMaxs.length; j++) {
            if(!targetMap[i][yMaxs[j]]){
                allCross = 0;
                break;
            }
        }
    }
    console.log(yMax + xMax - allCross);
})();
//  [javascript]
(async () => {
    let input = '';
    for await (const chunk of process.stdin) input += chunk;
    const lines = input.split(/\n/);
    const [h, w, m] = lines[0].split(/\s/).map(v => +v);
    const targets = lines.slice(1, m + 1).map(line => line.split(/\s/).map(v => v - 1));

    let targetCount = [new Array(h).fill(0), new Array(w).fill(0)];
    let targetMap = new Array(h).fill([]).map(x => new Array(w).fill(false));
    for (const target of targets) {
        targetCount[0][target[0]]++;
        targetCount[1][target[1]]++;
        targetMap[target[0]][target[1]] = true;
    }
    const xMax = targetCount[0].slice().sort((a, b) => b - a);
    const yMax = targetCount[1].slice().sort((a, b) => b - a);

    let yMaxs = [];
    for (let i = 0; i < h; i++) {
        if(targetCount[1][i] == yMax[0]){
            yMaxs.push(i);
        }
    }
    let allCross = 1;
    for (let i = 0; i < h && allCross; i++) {
        if(targetCount[0][i] == xMax[0]){
            for (let j = 0; j < yMaxs.length; j++) {
                if(!targetMap[i][yMaxs[j]]){
                    allCross = 0;
                    break;
                }
            }
        }
    }
    console.log(yMax[0] + xMax[0] - allCross);
})();
//  [javascript]
let input = require('fs').readFileSync('/dev/stdin', 'utf8')
// let input = require('fs').readFileSync('./sample_e.txt', 'utf8')
.split(/\n| /)
.slice(0,-1)
.map(item => parseInt(item))

const [height, width, ..._targets] = input
const targets = []

for(let i=1; i<_targets.length; i+=2){
    targets.push([_targets[i], _targets[i+1]])
}

let hlist = new Array(height).fill(0)
let wlist = new Array(width).fill(0)

for(let i=0; i<targets.length; i++){
    hlist[targets[i][0]-1]++
    wlist[targets[i][1]-1]++
}


const hmax = Math.max(...hlist)
const hindexes = []
for (let i=0; i<height; i++) {
    if(hlist[i] === hmax) hindexes.push(i)
}

const wmax = Math.max(...wlist)
const windexes = []
for (let i=0; i<width; i++) {
    if(wlist[i] === wmax) windexes.push(i)
}

for( hitem of hindexes ){
    for( witem of windexes ){
        if(!targets.some(item => item[0]===hitem+1 && item[1]===witem+1)){
            console.log(hmax + wmax)
            return
        }
    }
}

console.log(hmax + wmax - 1)
//  [go]
package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

func configure(scanner *bufio.Scanner) {
	scanner.Split(bufio.ScanWords)
	scanner.Buffer(make([]byte, 1000005), 1000005)
}
func getNextString(scanner *bufio.Scanner) string {
	scanned := scanner.Scan()
	if !scanned {
		panic("scan failed")
	}
	return scanner.Text()
}
func getNextInt(scanner *bufio.Scanner) int {
	i, _ := strconv.Atoi(getNextString(scanner))
	return i
}
func getNextInt64(scanner *bufio.Scanner) int64 {
	i, _ := strconv.ParseInt(getNextString(scanner), 10, 64)
	return i
}
func getNextFloat64(scanner *bufio.Scanner) float64 {
	i, _ := strconv.ParseFloat(getNextString(scanner), 64)
	return i
}
func main() {
	fp := os.Stdin
	wfp := os.Stdout
	extra := 0
	if os.Getenv("I") == "IronMan" {
		fp, _ = os.Open(os.Getenv("END_GAME"))
		extra = 100
	}
	scanner := bufio.NewScanner(fp)
	configure(scanner)
	writer := bufio.NewWriter(wfp)
	defer func() {
		r := recover()
		if r != nil {
			fmt.Fprintln(writer, r)
		}
		writer.Flush()
	}()
	solve(scanner, writer)
	for i := 0; i < extra; i++ {
		fmt.Fprintln(writer, "-----------------------------------")
		solve(scanner, writer)
	}
}
func solve(scanner *bufio.Scanner, writer *bufio.Writer) {
	h := getNextInt(scanner)
	w := getNextInt(scanner)
	m := getNextInt(scanner)
	hh := make([]int, m)
	ww := make([]int, m)
	sh := make([]int, h+1)
	sw := make([]int, w+1)
	hw := make([][]int, h)
	for i := 0; i < m; i++ {
		hh[i] = getNextInt(scanner) - 1
		ww[i] = getNextInt(scanner) - 1
		sh[hh[i]]++
		sw[ww[i]]++
		hw[hh[i]] = append(hw[hh[i]], ww[i])
	}
	mh := 0
	mhc := 0
	mw := 0
	mwc := 0
	for i := 0; i < h; i++ {
		if mh < sh[i] {
			mh = sh[i]
		}
	}
	for i := 0; i < w; i++ {
		if mw < sw[i] {
			mw = sw[i]
		}
	}
	for i := 0; i < h; i++ {
		if mh == sh[i] {
			mhc++
		}
	}
	for i := 0; i < w; i++ {
		if mw == sw[i] {
			mwc++
		}
	}
	for i := 0; i < h; i++ {
		if sh[i] < mh {
			continue
		}
		c := mwc
		for _, tw := range hw[i] {
			if sw[tw] == mw {
				c--
			}
		}
		if c > 0 {
			fmt.Fprintln(writer, mw+mh)
			return
		}
	}
	fmt.Fprintln(writer, mw+mh-1)
}
//  [go]
package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

func main() {
	h, w, m := readI(), readI(), readI()
	counth, countw := make([]int, h), make([]int, w)
	type pos struct {
		h, w int
	}
	target := make(map[pos]bool)
	for i := 0; i < m; i++ {
		tmph, tmpw := readI()-1, readI()-1
		target[pos{tmph, tmpw}] = true
		counth[tmph]++
		countw[tmpw]++
	}

	max := 0
	maxh, maxw := make([]int, 0), make([]int, 0)
	for i := 0; i < h; i++ {
		if max < counth[i] {
			max = counth[i]
			maxh = []int{i}
		} else if max == counth[i] {
			maxh = append(maxh, i)
		}
	}
	max = 0
	for i := 0; i < w; i++ {
		if max < countw[i] {
			max = countw[i]
			maxw = []int{i}
		} else if max == countw[i] {
			maxw = append(maxw, i)
		}
	}

	for i := 0; i < len(maxh); i++ {
		for j := 0; j < len(maxw); j++ {
			if target[pos{maxh[i], maxw[j]}] == false {
				fmt.Println(counth[maxh[0]] + countw[maxw[0]])
				return
			}
		}
	}
	fmt.Println(counth[maxh[0]] + countw[maxw[0]] - 1)
}

/*-----------Utils-----------*/

var sc = bufio.NewScanner(os.Stdin)

func init() {
	if len(os.Args) >= 2 {
		if os.Args[1] == "debug" {
			debug()
		}
	}
	const maxBuf = 200100
	var buf []byte = make([]byte, maxBuf)
	sc.Split(bufio.ScanWords)
	sc.Buffer(buf, maxBuf)
}

func debug() {
	testFile, err := os.Open("./test/sample-3.in")
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error : There is no testfile.")
		os.Exit(1)
	}
	sc = bufio.NewScanner(testFile)
}

func readS() string {
	sc.Scan()
	return sc.Text()
}

func readSs(a int) []string {
	b := make([]string, a)
	for i := 0; i < a; i++ {
		b[i] = readS()
	}
	return b
}

func readI() int {
	sc.Scan()
	r, _ := strconv.Atoi(sc.Text())
	return r
}

func readIs(a int) []int {
	b := make([]int, a)
	for i := 0; i < a; i++ {
		b[i] = readI()
	}
	return b
}

func readF() float64 {
	sc.Scan()
	r, _ := strconv.ParseFloat(sc.Text(), 64)
	return r
}

func readFs(a int) []float64 {
	b := make([]float64, a)
	for i := 0; i < a; i++ {
		b[i] = readF()
	}
	return b
}
//  [go]
package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

const (
	initialBufSize = 100000
	maxBufSize     = 10000000
)

var (
	sc = bufio.NewScanner(os.Stdin)
	wt = bufio.NewWriter(os.Stdout)
)

func next() string {
	sc.Scan()
	return sc.Text()
}

func nextInt() int {
	i, _ := strconv.Atoi(next())
	return i
}

func puts(a ...interface{}) {
	fmt.Fprintln(wt, a...)
}

func max(nums ...int) int {
	ret := nums[0]
	for _, v := range nums {
		if v > ret {
			ret = v
		}
	}
	return ret
}

type Point struct {
	h, w int
}

func main() {
	sc.Split(bufio.ScanWords)
	sc.Buffer(make([]byte, initialBufSize), maxBufSize)
	defer wt.Flush()

	h, w, m := nextInt(), nextInt(), nextInt()

	sh, sw := make([]int, h), make([]int, w)
	set := map[Point]bool{}
	for i := 0; i < m; i++ {
		hi, wi := nextInt()-1, nextInt()-1
		sh[hi]++
		sw[wi]++
		set[Point{hi, wi}] = true
	}

	// 行，列ごとの最大の爆破数
	shmax, swmax := max(sh...), max(sw...)
	// 爆破対象に選ぶとshmax/swmaxだけ爆破できるような爆弾の座標
	hmax, wmax := make([]int, 0), make([]int, 0)
	for p := range set {
		if shmax == sh[p.h] {
			hmax = append(hmax, p.h)
		}
		if swmax == sw[p.w] {
			wmax = append(wmax, p.w)
		}
	}

	ans := shmax + swmax
	for i := range hmax {
		for j := range wmax {
			// 爆破数を最大化でき，爆弾と重ならないマスが存在すればOK
			if !set[Point{hmax[i], wmax[j]}] {
				puts(ans)
				return
			}
		}
	}
	// 爆弾と重なるマスしかない場合
	puts(ans - 1)
}
//  [go]
package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var sc = bufio.NewScanner(os.Stdin)

func nextInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

func nextFloat64() float64 {
	sc.Scan()
	i, e := strconv.ParseFloat(sc.Text(), 64)
	if e != nil {
		panic(e)
	}
	return i
}

func nextString() string {
	sc.Scan()
	return sc.Text()
}

func abs(x int) int {
	if x < 0 {
		return -1 * x
	} else {
		return x
	}
}

func max(x map[int]int) int {
	ans := 0
	for _, v := range x {
		if ans < v {
			ans = v
		}
	}
	return ans
}

func main() {
	sc.Split(bufio.ScanWords)
	sc.Buffer(nil, 10000000000)

	_, _, m := nextInt(), nextInt(), nextInt()

	hs := make([]int, m)
	ws := make([]int, m)

	hsum := make(map[int]int)
	wsum := make(map[int]int)

	bomb := make(map[int]map[int]bool)

	for i := 0; i < m; i++ {
		hs[i], ws[i] = nextInt()-1, nextInt()-1

		if _, ok := bomb[hs[i]]; ok {
			bomb[hs[i]][ws[i]] = true
		} else {
			bomb[hs[i]] = make(map[int]bool)
			bomb[hs[i]][ws[i]] = true
		}

		hsum[hs[i]] += 1
		wsum[ws[i]] += 1
	}

	hmax := max(hsum)
	wmax := max(wsum)

	checkh := []int{}
	checkw := []int{}

	for i := 0; i < m; i++ {
		if _, ok := hsum[i]; ok {
			if hsum[i] == hmax {
				checkh = append(checkh, i)
			}
		}
		if _, ok := wsum[i]; ok {
			if wsum[i] == wmax {
				checkw = append(checkw, i)
			}
		}
	}

	ans := hmax + wmax - 1
	for _, ch := range checkh {
		if _, ok := bomb[ch]; !ok {
			continue
		}
		for _, cw := range checkw {
			if _, ok := bomb[ch][cw]; !ok {
				ans = hmax + wmax
				fmt.Println(ans)
				return
			}
		}
	}

	fmt.Println(ans)
}
//  [go]
package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var sc = bufio.NewScanner(os.Stdin)

func nextInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

func nextFloat64() float64 {
	sc.Scan()
	i, e := strconv.ParseFloat(sc.Text(), 64)
	if e != nil {
		panic(e)
	}
	return i
}

func nextString() string {
	sc.Scan()
	return sc.Text()
}

func abs(x int) int {
	if x < 0 {
		return -1 * x
	} else {
		return x
	}
}

func max(x map[int]int) int {
	ans := 0
	for _, v := range x {
		if ans < v {
			ans = v
		}
	}
	return ans
}

func main() {
	sc.Split(bufio.ScanWords)
	sc.Buffer(nil, 10000000000)

	h, w, m := nextInt(), nextInt(), nextInt()

	hs := make([]int, m)
	ws := make([]int, m)

	hsum := make(map[int]int, h)
	wsum := make(map[int]int, w)

	bomb := make(map[int]map[int]bool)

	for i := 0; i < m; i++ {
		hs[i], ws[i] = nextInt()-1, nextInt()-1

		if _, ok := bomb[hs[i]]; ok {
			bomb[hs[i]][ws[i]] = true
		} else {
			bomb[hs[i]] = make(map[int]bool)
			bomb[hs[i]][ws[i]] = true
		}

		hsum[hs[i]] += 1
		wsum[ws[i]] += 1
	}

	hmax := max(hsum)
	wmax := max(wsum)

	checkh := []int{}
	checkw := []int{}

	for i := 0; i < m; i++ {
		if hsum[i] == hmax {
			checkh = append(checkh, i)
		}
		if wsum[i] == wmax {
			checkw = append(checkw, i)
		}
	}

	ans := hmax + wmax - 1
	for _, ch := range checkh {
		if _, ok := bomb[ch]; !ok {
			continue
		}
		for _, cw := range checkw {
			if _, ok := bomb[ch][cw]; !ok {
				ans = hmax + wmax
				fmt.Println(ans)
				return
			}
		}
	}

	fmt.Println(ans)
}
//  [ruby]
(H, W, M), *HWs = readlines.map{_1.split.map(&:to_i)}

ht, wt = Array.new(H + 1, 0), Array.new(W + 1, 0)
HWs.each{|h, w| ht[h] += 1; wt[w] += 1}
hm, wm = ht.max, wt.max
hn, wn = ht.count(hm), wt.count(wm)
puts hm + wm - (hn*wn > HWs.count{ht[_1] == hm && wt[_2] == wm} ? 0 : 1)
//  [ruby]
H,W,M = gets.split.map(&:to_i)
m = $<.map{|ln| ln.split.map{|_|_.to_i-1} }

hx,hh = 0,[0]*H
wx,ww = 0,[0]*W
m.each{|h,w|
	hx = hh[h] if hx < hh[h]+=1
	wx = ww[w] if wx < ww[w]+=1
}

hxn = hh.count(hx)
wxn = ww.count(wx)
mxn = m.count{|h,w| hh[h]==hx && ww[w]==wx }

p hx+wx-(mxn==hxn*wxn ? 1 : 0)
//  [ruby]
# reference
# https://atcoder.jp/contests/abc176/submissions/16207205
# https://atcoder.jp/contests/abc176/submissions/16157397
# https://qiita.com/QUANON/items/ca06f3068c87b3a21e18

H, W, M = gets.strip.split.map(&:to_i)

m = []
M.times do
  m.push(gets.strip.split.map { |_| _.to_i - 1 })
end

hx, hh = 0, [0] * H
wx, ww = 0, [0] * W

m.each { |h, w|
  hx = hh[h] if hx < hh[h] += 1
  wx = ww[w] if wx < ww[w] += 1
}

hm_count = hh.count(hx)
wm_count = ww.count(wx)

if hm_count * wm_count > m.count{|h,w| hh[h] == hx && ww[w] == wx}
  p hx + wx
else
  p hx + wx - 1
end
//  [ruby]
H, W, M = gets.chomp.split(" ").map(&:to_i)
G = Array.new(H).map{Array.new(W, 0)}
R = Array.new(H, 0)
C = Array.new(W, 0)
B = Array.new(M).map{
  r, c = gets.chomp.split(" ").map(&:to_i)
  R[r-1] += 1
  C[c-1] += 1
  G[r-1][c-1] = -1
}

r_m, c_m = R.max, C.max
r_i = R.map.with_index{|r, i| r==r_m ? i : nil}.compact
c_i = C.map.with_index{|c, i| c==c_m ? i : nil}.compact

puts r_i.product(c_i).any?{|r, c| G[r][c] == 0} ? r_m+c_m : r_m+c_m-1
//  [ruby]
h, w, m = gets.chomp.split(" ").map{|i|i.to_i}

boms = Array.new(h) { Array.new(w,0) }
m.times do
	bom_h, bom_w = gets.chomp.split(" ").map{|i|i.to_i-1}
  	boms[bom_h][bom_w] = 1
end

arr = []
h.times do |i|
	w.times do |j|
    
    	w_boms = boms[i].count(1)
      	h_boms = boms.transpose[j].count(1)
      	if boms[i][j] == 1
      		bom_counter = w_boms + h_boms -1
          	arr.push(bom_counter)
        else
          	bom_counter = w_boms + h_boms
          	arr.push(bom_counter)
        end
    end
end

puts arr.max
//  [ruby]
h, w, m = gets.split.map(&:to_i)

p h, w, m
//  [rust]
#[allow(non_snake_case)]
fn main() {
    proconio::input! {
        W: usize,
        H: usize,
        M: usize,
        B: [(usize, usize); M],
    }

    let mut xmax = 0;
    let mut ymax = 0;
    let mut xs = vec![0; W + 1];
    let mut ys = vec![0; H + 1];

    for b in &B {
        xs[b.0] += 1;
        ys[b.1] += 1;
        xmax = xmax.max(xs[b.0]);
        ymax = ymax.max(ys[b.1]);
    }

    let xn = xs.iter().fold(0, |a, &n| a + if n == xmax { 1 } else { 0 });
    let yn = ys.iter().fold(0, |a, &n| a + if n == ymax { 1 } else { 0 });
    let bn = B.iter().fold(0, |a, b| a + if xs[b.0] == xmax && ys[b.1] == ymax { 1 } else { 0 });

    println!("{}", xmax + ymax - (if xn * yn == bn { 1 } else { 0 }));
}
//  [rust]
use proconio::{input, marker::Usize1};

fn main() {
    input! {
        h: usize,
        w: usize,
        b: [(Usize1, Usize1)]
    }

    let mut row = vec![0; h];
    let mut col = vec![0; w];

    for &(i, j) in &b {
        row[i] += 1;
        col[j] += 1;
    }

    let mr = *row.iter().max().unwrap();
    let mc = *col.iter().max().unwrap();

    let cr = row.iter().filter(|&&c| c == mr).count();
    let cc = col.iter().filter(|&&c| c == mc).count();
    let bc = b
        .iter()
        .filter(|&&(i, j)| row[i] == mr && col[j] == mc)
        .count();

    let ans = if bc < cr * cc { mr + mc } else { mr + mc - 1 };
    println!("{}", ans);
}
//  [rust]
fn main() {
    proconio::input! {
        h: usize,
        w: usize,
        m: usize,
        b: [(usize, usize); m]
    };
    let mut cnt_h = vec![0; h+1];
    let mut cnt_w = vec![0; w+1];
    for &p in &b {
        cnt_h[p.0] += 1;
        cnt_w[p.1] += 1;
    }
    let max_h = *cnt_h.iter().max().unwrap();
    let max_w = *cnt_w.iter().max().unwrap();
    let overlap = cnt_h.iter().fold(0, |a, &x| a + if x == max_h { 1 } else { 0 }) * cnt_w.iter().fold(0, |a, &x| a + if x == max_w { 1 } else { 0 });
    let cover = b.iter().fold(0, |a, &(x, y)| a + if cnt_h[x] == max_h && cnt_w[y] == max_w { 1 } else { 0 });
    println!("{}", max_h + max_w - if cover == overlap { 1 } else { 0 });
}
//  [rust]
use std::io::*;
use std::str::*;

fn read<T: FromStr>(s: &mut StdinLock) -> T {
    let s = s.by_ref().bytes().map(|c| c.unwrap() as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect::<String>();
    s.parse::<T>().ok().unwrap()
}


struct TargetMap 
{
	height: i32,
	width:  i32,
	hsum : Vec::<i32>,
	wsum : Vec::<i32>,
	pt: Vec::<(i32,i32)>,
	hmax: i32,
	wmax: i32,
}

impl TargetMap {


	fn read(&mut self, s : &mut StdinLock) {
		self.height = read::<i32>(s);
		self.width = read::<i32>(s);
		self.hsum = vec![0; self.width as usize];
		self.wsum = vec![0; self.height as usize];
		self.pt = Vec::<(i32,i32)>::new();
		let m =  read::<usize>(s);
	
		for _i in 0..m {
			let ph =  read::<i32>(s)-1;
			let pw =  read::<i32>(s)-1;
			self.hsum[pw as usize] += 1;
			if self.hsum[pw as usize] > self.hmax {
				self.hmax = self.hsum[pw as usize];
			}
			self.wsum[ph as usize] += 1;
			if self.wsum[ph as usize] > self.wmax {
				self.wmax = self.wsum[ph as usize];
			}
			self.pt.push((ph,pw));
		
		}
		self.pt.sort();
	}

	fn solve(&mut self) -> i32 {
		let mut maxb:i32 = 0;
		for h in 0 .. self.height {
			if  self.wsum[h as usize] != self.wmax {
				continue;
			}
			for w in 0 .. self.width {
				if self.hsum[w as usize] != self.hmax {
					continue;
				}
				let mut nb = self.hsum[w as usize] + self.wsum[h as usize];
				if let Ok(_n) = self.pt.binary_search(&(h,w)) {
					nb -= 1;
				} else if self.hmax + self.wmax == nb {
					maxb = nb;
					break;
				}
				if nb > maxb {
					maxb = nb;
				}
			}
		}

		return maxb;
	}
}


fn main() {
    let s = stdin();
    let mut s = s.lock();
    let s = &mut s;

	let mut m = TargetMap {
		height : 0,
		width : 0,
		hsum : Vec::<i32>::new(),
		wsum : Vec::<i32>::new(),
   	    pt: Vec::<(i32,i32)>::new(),
		hmax : 0,
		wmax : 0,
	};

	m.read(s);
	
   println!("{}", m.solve());

	
}
//  [rust]
use std::io::*;
use std::str::*;

fn read<T: FromStr>(s: &mut StdinLock) -> T {
    let s = s.by_ref().bytes().map(|c| c.unwrap() as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect::<String>();
    s.parse::<T>().ok().unwrap()
}


struct TargetMap 
{
	height: i32,
	width:  i32,
	hsum : Vec::<i32>,
	wsum : Vec::<i32>,
	pt: Vec::<(i32,i32)>,
}

impl TargetMap {


	fn read(&mut self, s : &mut StdinLock) {
		self.height = read::<i32>(s);
		self.width = read::<i32>(s);
		self.hsum = vec![0; self.width as usize];
		self.wsum = vec![0; self.height as usize];
		self.pt = Vec::<(i32,i32)>::new();
		let m =  read::<usize>(s);
		for _i in 0..m {
			let ph =  read::<i32>(s)-1;
			let pw =  read::<i32>(s)-1;
			self.hsum[pw as usize] += 1;
			self.wsum[ph as usize] += 1;
			self.pt.push((ph,pw));
		
		}
		self.pt.sort();
	}

	fn solve(&mut self) -> i32 {
		let mut maxb:i32 = 0;
		for h in 0 .. self.height {
			for w in 0 .. self.width {
				let mut nb = self.hsum[w as usize] + self.wsum[h as usize];
				if let Ok(_n) = self.pt.binary_search(&(h,w)) {
					nb -= 1;
				}
				if nb > maxb {
					maxb = nb;
				}
			}
		}

		return maxb;
	}
}


fn main() {
    let s = stdin();
    let mut s = s.lock();
    let s = &mut s;

	let mut m = TargetMap {
		height : 0,
		width : 0,
		hsum : Vec::<i32>::new(),
		wsum : Vec::<i32>::new(),
   	    pt: Vec::<(i32,i32)>::new(),

	};

	m.read(s);
	
   println!("{}", m.solve());

	
}
//  [rust]
use std::io::*;
use std::str::*;

/*
fn read<T: FromStr>(s: &mut StdinLock) -> T {
    let s = s.by_ref().bytes().map(|c| c.unwrap() as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect::<String>();
    s.parse::<T>().ok().unwrap()
}
*/

fn read_vec<T: std::str::FromStr>(f: &mut StdinLock) -> Vec<T> {
    let mut s = String::new();
    f.read_line(&mut s).ok();
    s.trim().split_whitespace()
        .map(|e| e.parse().ok().unwrap()).collect()
}


struct BomberMap 
{
	height: i16,
	width:  i16,
	hsum : Vec::<i16>,
	wsum : Vec::<i16>,
	pt: Vec::<(i16,i16)>,
}

impl BomberMap {


	fn read(&mut self, s : &mut StdinLock) {

		let st = read_vec::<String>(s);

		self.height = st[0].parse().ok().unwrap();
		self.width =  st[1].parse().ok().unwrap();
		self.hsum = vec![0; self.width as usize];
		self.wsum = vec![0; self.height as usize];
		self.pt = Vec::<(i16,i16)>::new();
		let m = st[2].parse().ok().unwrap();
		for _i in 0..m {
			let st = read_vec::<String>(s);
			let ph =  st[0].parse::<i16>().ok().unwrap() - 1;
			let pw =  st[1].parse::<i16>().ok().unwrap() - 1;
			self.hsum[pw as usize] += 1;
			self.wsum[ph as usize] += 1;
			self.pt.push((ph,pw));
		
		}
		self.pt.sort();
	}

	fn solve(&mut self) -> i16 {
		let mut maxb:i16 = 0;
		for h in 0 .. self.height {
			for w in 0 .. self.width {
				let mut nb = self.hsum[w as usize] + self.wsum[h as usize];
				if let Ok(_n) = self.pt.binary_search(&(h,w)) {
					nb -= 1;
				}
				if nb > maxb {
					maxb = nb;
				}
			}
		}

		return maxb;
	}
}


fn main() {
    let s = stdin();
    let mut s = s.lock();
    let s = &mut s;


	let mut m = BomberMap {
		height : 0,
		width : 0,
		hsum : Vec::<i16>::new(),
		wsum : Vec::<i16>::new(),
   	    pt: Vec::<(i16,i16)>::new(),

	};

	m.read(s);
	
   println!("{}", m.solve());

	
}
//  [typescript]
import * as fs from 'fs';
// main
function main(input: string[]) {
    // param
    let h: number;
    let w: number;
    let m: number;
    let hm: number[];
    let wm: number[]
    let ans;
    // init
    [h, w, m] = input.shift().split(" ").map(x => Number(x));
    [hm, wm] = [[], []];
    let hw = new Map();
    for (let mx = 0; mx < m; mx++) {
        let wrk0 = input[mx].split(" ").map(x => Number(x) - 1);
        hm[mx] = wrk0[0];
        wm[mx] = wrk0[1];
        hw.set(hm[mx] * w + wm[mx], 1);
    }
    // solve
    let ha: number[] = new Array(h).fill(0);
    let wa: number[] = new Array(w).fill(0);
    for (let hv of hm) { ha[hv]++; }
    for (let wv of wm) { wa[wv]++; }
    let hb: number = Math_max(ha);
    let wb: number = Math_max(wa);
    let hc: number[] = [];
    let wc: number[] = [];
    ha.forEach((val, idx) => { if (val == hb) hc.push(idx) });
    wa.forEach((val, idx) => { if (val == wb) wc.push(idx) });
    let isfull;
    if (m < hc.length * wc.length) {
        isfull = false;
    } else {
        let cnt = 0;
        for (let hce of hc) {
            for (let wce of wc) {
                if (hw.get(hce * w + wce) == 1) cnt++;
            }
        }
        isfull = hc.length * wc.length == cnt;
    }
    ans = Math_max(ha) + Math_max(wa) + (isfull ? -1 : 0);
    // answer
    console.log(ans);
}
// math lib
function Math_max(arr: number[]): number { return arr.reduce((x, y) => Math.max(x, y)); }
// entrypoint
function entrypoint() {
    try {
        let input = fs.readFileSync("/dev/stdin", "utf8").trim().split("\n");
        console.debug = function () { };
        main(input);
    }
    catch (ex) {
        const lines: string[] = [];
        // @ts-ignore
        const reader = require('readline').createInterface({
            // @ts-ignore
            input: process.stdin,
            // @ts-ignore
            output: process.stdout
        });
        reader.on('line', function (line: string) {
            lines.push(line);
        });
        reader.on('close', function () {
            let input = lines;
            main(input);
        });
    }
}
entrypoint();
//  [typescript]
import * as fs from 'fs';
// main
function main(input: string[]) {
    // param
    let h: number;
    let w: number;
    let m: number;
    let hm: number[];
    let wm: number[]
    let ans;
    // init
    [h, w, m] = input.shift().split(" ").map(x => Number(x));
    [hm, wm] = [[], []];
    let map = new Map();
    for (let mx = 0; mx < m; mx++) {
        let wrk0 = input[mx].split(" ").map(x => Number(x) - 1);
        hm[mx] = wrk0[0];
        wm[mx] = wrk0[1];
        map.set(hm[mx] * 1000000 + wm[mx], 1);
    }
    // solve
    let hb: number[] = new Array(h).fill(0);
    let wb: number[] = new Array(w).fill(0);
    for (let hv of hm) { hb[hv]++; }
    for (let wv of wm) { wb[wv]++; }
    let hbmax: number = Math_max(hb);
    let wbmax: number = Math_max(wb);
    let hbarr: number[] = [];
    let wbarr: number[] = [];
    hb.forEach((val, idx) => { if (val == hbmax) hbarr.push(idx) });
    wb.forEach((val, idx) => { if (val == wbmax) wbarr.push(idx) });
    let cnt = 0;
    for (let hv of hbarr) {
        for (let wv of wbarr) {
            if (map.get(hv * 1000000 + wv) == 1) cnt++;
        }
    }
    let chk = hbarr.length * wbarr.length == cnt;
    ans = Math_max(hb) + Math_max(wb) + (chk ? -1 : 0);
    // answer
    console.log(ans);
}
// math lib
function Math_max(arr: number[]): number { return arr.reduce((x, y) => Math.max(x, y)); }
// entrypoint
function entrypoint() {
    try {
        let input = fs.readFileSync("/dev/stdin", "utf8").trim().split("\n");
        console.debug = function () { };
        main(input);
    }
    catch (ex) {
        const lines: string[] = [];
        // @ts-ignore
        const reader = require('readline').createInterface({
            // @ts-ignore
            input: process.stdin,
            // @ts-ignore
            output: process.stdout
        });
        reader.on('line', function (line: string) {
            lines.push(line);
        });
        reader.on('close', function () {
            let input = lines;
            main(input);
        });
    }
}
entrypoint();
//  [typescript]
import * as fs from 'fs';
// main
function main(input: string[]) {
    // param
    var h: number;
    var w: number;
    var m: number;
    var hm: number[];
    var wm: number[]
    var ans;
    // init
    [h, w, m] = input.shift().split(" ").map(x => Number(x));
    [hm, wm] = [[], []];
    var map = new Map();
    for (var mx = 0; mx < m; mx++) {
        var wrk0 = input[mx].split(" ").map(x => Number(x) - 1);
        hm[mx] = wrk0[0];
        wm[mx] = wrk0[1];
        map.set(hm[mx]* 1000000 + wm[mx], 1);
    }
    // solve
    var hb: number[] = new Array(h).fill(0);
    var wb: number[] = new Array(w).fill(0);
    for (var mx = 0; mx < hm.length; mx++) {
        hb[hm[mx]]++;
    }
    for (var mx = 0; mx < wm.length; mx++) {
        wb[wm[mx]]++;
    }
    var hbmax: number = Math_max(hb);
    var wbmax: number = Math_max(wb);
    var hbarr: number[] = [];
    var wbarr: number[] = [];
    hb.forEach((val, idx) => { if (val == hbmax) hbarr.push(idx) });
    wb.forEach((val, idx) => { if (val == wbmax) wbarr.push(idx) });
    var cnt = 0;
    for (var h of hbarr) {
        for (var w of wbarr) {
            if (map.get(h*1000000+ w) == 1) cnt++;
        }
    }
    var chk = hbarr.length * wbarr.length == cnt;
    ans = Math_max(hb) + Math_max(wb) + (chk ? -1 : 0);
    // answer
    console.log(ans);
}
// math lib
function Math_max(arr: number[]): number { return arr.reduce((x, y) => Math.max(x, y)); }
// entrypoint
function entrypoint() {
    try {
        var input = fs.readFileSync("/dev/stdin", "utf8").trim().split("\n");
        console.debug = function () { };
        main(input);
    }
    catch (ex) {
        const lines: string[] = [];
        // @ts-ignore
        const reader = require('readline').createInterface({
            // @ts-ignore
            input: process.stdin,
            // @ts-ignore
            output: process.stdout
        });
        reader.on('line', function (line: string) {
            lines.push(line);
        });
        reader.on('close', function () {
            input = lines;
            main(input);
        });
    }
}
entrypoint();
//  [typescript]
import * as fs from 'fs';

// main
function main(input: string[]) {
    // param
    var h: number;
    var w: number;
    var m: number;
    var hm: number[];
    var wm: number[]
    var ans;
    // init
    [h, w, m] = input.shift().split(" ").map(x => Number(x));
    [hm, wm] = [[], []];
    for (var mx = 0; mx < m; mx++) {
        var wrk0 = input[mx].split(" ").map(x => Number(x) - 1);
        hm[mx] = wrk0[0];
        wm[mx] = wrk0[1];
    }
    console.debug(h, w, m, hm, wm);
    // solve
    var hb: number[] = new Array(h).fill(0);
    var wb: number[] = new Array(w).fill(0);
    for (var mx = 0; mx < hm.length; mx++) {
        hb[hm[mx]]++;
    }
    for (var mx = 0; mx < wm.length; mx++) {
        wb[wm[mx]]++;
    }
    var hbmax: number = Math_max(hb);
    var wbmax: number = Math_max(wb);
    var hbarr: number[] = [];
    var wbarr: number[] = [];
    hb.forEach((val, idx) => { if (val == hbmax) hbarr.push(idx) });
    wb.forEach((val, idx) => { if (val == wbmax) wbarr.push(idx) });
    var cnt = 0;
    for (var mx = 0; mx < m; mx++) {
        if (0 <= hbarr.indexOf(hm[mx])) {
            if (0 <= wbarr.indexOf(wm[mx])) {
                cnt++;
            }
        }

    }
    var chk = hbarr.length * wbarr.length == cnt;
    ans = Math_max(hb) + Math_max(wb) + (chk ? -1 : 0);
    // answer
    console.log(ans);
}

// math lib
function Math_max(arr: number[]): number { return arr.reduce((x, y) => Math.max(x, y)); }

// graph lib
function GRAPH_enumPattern(cur: number[], pat: number[][]): number[][] {
    var arr = [];
    for (var patx = 0; patx < pat.length; patx++) {
        var pos = [cur[0] + pat[patx][0], cur[1] + pat[patx][1]];
        arr.push(pos);
    }
    return arr;
}

// entrypoint
function entrypoint() {
    try {
        var input = fs.readFileSync("/dev/stdin", "utf8").trim().split("\n");
        console.debug = function () { };
        main(input);
    }
    catch (ex) {
        console.log("file='%s'", __filename.split("\\").slice(-1)[0]);
        const lines: string[] = [];
        // @ts-ignore
        const reader = require('readline').createInterface({
            // @ts-ignore
            input: process.stdin,
            // @ts-ignore
            output: process.stdout
        });
        reader.on('line', function (line: string) {
            lines.push(line);
        });
        reader.on('close', function () {
            input = lines;
            console.log("input=%o", input);
            console.time();
            main(input);
            console.timeEnd();
        });
    }
}
entrypoint();
//  [python]
N,K = list(map(int,input().split()))

r = set()
for i in range(K):
  d = int(input())
  r |= set(map(int,input().split()))
print(N-len(r))
//  [python]
n, k = map(int, input().split())
check = [0 for i in range(n)]
for i in range(k):
    d = int(input())
    a = list(map(int, input().split()))
    for j in a:
        if check[j-1] == 0:
            check[j-1] = 1
ans = 0

for i in check:
    if i == 0:
        ans += 1
print(ans)
//  [python]
N, K = [int(x) for x in input().split(" ")]
A = [0 for i in range(N)]

for k in range(K):
    d_i = int(input())
    holder_list = [int(x) for x in input().split(" ")]

    for hi in holder_list:
        A[hi-1] += 1

count_non_holder = 0
for a in A:
    if a == 0:
        count_non_holder += 1

print(count_non_holder)
//  [python]
#ABC166
n,k=map(int,input().split())
cnt=[0]*(n+1)
for j in range(k):
  tmp = int(input())
  arr=list(map(int,input().split()))
  for val in arr:
    cnt[val]+=1
ans=0
for i in range(1,n+1):
  if cnt[i]==0:
    ans+=1
print('Anser is ' + str(ans))
//  [python]
n, k = map(int, input().split())
a = [1] * n
for i in range(k):
    tmp = map(int, input().split())
    for j in tmp:
        a[j - 1] = 0
print(sum(a[j]))
//  [python]
n, k = map(int, input().split())
a = [1] * n
for i in range(k):
    tmp = map(int, input().split())
    for j in range(tmp):
        a[j] = 0
print(sum(a[j]))