jiahuimbzuai/CoQuIR huggingface dataset:
//  [c]
#include <stdio.h>
#include <stdlib.h>

typedef struct List {
	struct List *next;
	long long value, num;
} list;

int main()
{
	int i, N;
	long long A[200001] = {};
	scanf("%d", &N);
	for (i = 1; i <= N; i++) scanf("%lld", &(A[i]));
	
	long long h;
	list *p, data[200001] = {}, *hash[100003] = {&(data[0])};
	for (i = 1; i <= N; i++) {
		data[i].value = data[i-1].value + A[i];
		for (h = llabs(data[i].value) % 100003, p = hash[h]; p != NULL; p = p->next) {
			if (data[i].value == p->value) break;
		}
		if (p != NULL) (p->num)++;
		else {
			data[i].next = hash[h];
			data[i].num = 0;
			hash[h] = &(data[i]);
		}
	}
	
	long long ans = 0;
	for (i = 0; i < 100003; i++) {
		for (p = hash[i]; p != NULL; p = p->next) ans += p->num * (p->num + 1) / 2;
	}
	
	printf("%lld\n", ans);
	fflush(stdout);
	return 0;
}
//  [c]
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define BUF_SIZE 2500000
#define HASH_SIZE 65536

struct list {
  struct list *next;
  long num;
  long cnt;
};
// create hash
struct list *create_hashtable(int size) {
  struct list *htable = malloc(size*sizeof(struct list));
  int i;
  for(i = 0; i < size; i++) {
    htable[i].next = &htable[i];
  }
  return htable;
}

int get_key(long num) {
  return num & (HASH_SIZE-1);
}

void insert(struct list *htable, long num) {
  int key = get_key(num);
  struct list *head = &htable[key];
  struct list *elem;
  for(elem = head->next; elem != head; elem = elem->next) {
    if(elem->num == num) {
      elem->cnt++;
      return;
    }
  }

  // create
  elem = malloc(sizeof(struct list));
  elem->next = head->next;
  elem->num = num;
  elem->cnt = 1;
  head->next = elem;
  return;
}


int main(void) {
  FILE *fp = stdin;
  char line[BUF_SIZE];
  int num;

  long prev = 0;
  struct list *htable = create_hashtable(HASH_SIZE);
  if(!fgets(line, BUF_SIZE, fp)) return 0;
  sscanf(line, "%d", &num);

  if(!fgets(line, BUF_SIZE, fp)) return 0;
  char *tmpbuf = line;
  int i, j;
  insert(htable, 0); // cum[0] = 0;
  for(i = 0; i < num; i++) {
    char *tmp = strtok(tmpbuf, " ");
    long n = strtol(tmp, NULL, 10);
    tmpbuf = NULL;
    prev = prev + n;
    insert(htable, prev);
  }

  long ans = 0;
  for(i = 0; i < HASH_SIZE; i++) {
    struct list *tmp;
    struct list *head = &htable[i];
    for(tmp = head->next; tmp != head; tmp = tmp->next) {
      ans += (tmp->cnt - 1) * tmp->cnt /2; // nC2
    }
  }
  printf("%ld\n", ans);
}
//  [c]
#include<stdio.h>

  void QSort(long long int x[ ],long long int left, long long int  right)
{
    long long int i, j;
    long long int pivot;

    i = left;                      /* ソートする配列の一番小さい要素の添字 */
    j = right;                     /* ソートする配列の一番大きい要素の添字 */

    pivot = x[(left + right) / 2]; /* 基準値を配列の中央付近にとる */

    while (1) {                    /* 無限ループ */

        while (x[i] < pivot)       /* pivot より大きい値が */
            i++;                   /* 出るまで i を増加させる */

        while (pivot < x[j])       /* pivot より小さい値が */
            j--;                   /*  出るまで j を減少させる */
        if (i >= j)                /* i >= j なら */
            break;                 /* 無限ループから抜ける */

        Swap(x, i, j);             /* x[i] と x[j]を交換 */
        i++;                       /* 次のデータ */
        j--;
    }
    if (left < i - 1)              /* 基準値の左に 2 以上要素があれば */
        QSort(x, left, i - 1);     /* 左の配列を Q ソートする */
    if (j + 1 <  right)            /* 基準値の右に 2 以上要素があれば */
        QSort(x, j + 1, right);    /* 右の配列を Q ソートする */
}

  /* 配列の要素を交換する */
void Swap(long long int x[ ], long long int i, long long int j)
{
    long long int temp;

    temp = x[i];
    x[i] = x[j];
    x[j] = temp;
}

int main(){
  long long int a,s[200001],i,n,cnt=0,sum=0,j;
  scanf("%ld",&n);
  s[0]=0;
  for(i=0;i<n;i++){
    scanf("%ld",&a);
    s[i+1]=s[i]+a;
    if(s[i+1]==0) sum++;
  }
  QSort(s, 1, n);
  for(i=1;i<n;i++){
    cnt=0;

    for(j=i+1;j<n+1;j++){
      if(s[i]==s[j]) cnt++;
      else break;
    }
    i+=cnt;
    sum+=cnt*(cnt+1)/2;

  }
  printf("%ld\n",sum);
}
//  [c]
#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
#include<inttypes.h>

typedef int32_t i32;
typedef int64_t i64;

#define ALLOC(size,type) ((type*)calloc((size),sizeof(type)))

typedef struct node {
  i64 val;
  i32 size;
  struct node *l, *r;
} node;

uint32_t xor(void) {
  static uint32_t y = 2463534242;
  y = y ^ (y << 13); y = y ^ (y >> 17);
  return y = y ^ (y << 5);
}

i32 get_size (node *t) {
  return t == NULL ? 0 : t->size;
}

void update (node *t) {
  if (t == NULL) return;
  t->size = 1 + get_size (t->l) + get_size (t->r);
}

node* merge (node *l, node *r) {
  if (l == NULL) return r;
  if (r == NULL) return l;
  if ((i32)(xor() % (l->size + r->size)) < l->size) {
    l->r = merge (l->r, r);
    update (l);
    return l;
  } else {
    r->l = merge (l, r->l);
    update (r);
    return r;
  }
}

void split (node *p, i64 v, node **x, node **y) {
  if (p == NULL) {
    *x = *y = NULL;
    return;
  }
  if (p->val <= v) {
    split (p->r, v, x, y);
    p->r = *x;
    *x = p;
  } else {
    split (p->l, v, x, y);
    p->l = *y;
    *y = p;
  }
  update (p);
}

node* insert (node *p, i64 v) {
  node *t = ALLOC (1, node);
  t->val = v;
  t->size = 1;
  t->l = t->r = NULL;
  node *a, *b;
  split (p, v, &a, &b);
  return merge (a, merge (t, b));
}

void run (void) {
  i32 n;
  scanf ("%" SCNi32, &n);
  node *p = NULL;
  p = insert (p, 0);
  i64 sum = 0;
  i64 ans = 0;
  for (i32 i = 0; i < n; ++i) {
    i32 x;
    scanf ("%" SCNi32, &x);
    sum += x;
    node *a, *b, *c, *d;
    split (p, sum, &a, &b);
    split (a, sum - 1, &c, &d);
    ans += get_size (d);
    p = merge (c, merge (d, b));
    p = insert (p, sum);
  }
  printf ("%" PRIi64 "\n", ans);
}

int main (void) {
  run();
  return 0;
}
//  [c]
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define BUF_SIZE 2500000
#define HASH_SIZE 2048

struct list {
  struct list *next;
  long num;
  long cnt;
};
// create hash
struct list *create_hashtable(int size) {
  struct list *htable = malloc(size*sizeof(struct list));
  int i;
  for(i = 0; i < size; i++) {
    htable[i].next = &htable[i];
  }
  return htable;
}

int get_key(long num) {
  return num & (HASH_SIZE-1);
}

void insert(struct list *htable, long num) {
  int key = get_key(num);
  struct list *head = &htable[key];
  struct list *elem;
  for(elem = head->next; elem != head; elem = elem->next) {
    if(elem->num == num) {
      elem->cnt++;
      return;
    }
  }

  // create
  elem = malloc(sizeof(struct list));
  elem->next = head->next;
  elem->num = num;
  elem->cnt = 1;
  head->next = elem;
  return;
}


int main(void) {
  FILE *fp = stdin;
  char line[BUF_SIZE];
  int num;

  long prev = 0;
  struct list *htable = create_hashtable(HASH_SIZE);
  if(!fgets(line, BUF_SIZE, fp)) return 0;
  sscanf(line, "%d", &num);

  if(!fgets(line, BUF_SIZE, fp)) return 0;
  char *tmpbuf = line;
  int i, j;
  insert(htable, 0); // cum[0] = 0;
  for(i = 0; i < num; i++) {
    char *tmp = strtok(tmpbuf, " ");
    long n = strtol(tmp, NULL, 10);
    tmpbuf = NULL;
    prev = prev + n;
    insert(htable, prev);
  }

  long ans = 0;
  for(i = 0; i < HASH_SIZE; i++) {
    struct list *tmp;
    struct list *head = &htable[i];
    for(tmp = head->next; tmp != head; tmp = tmp->next) {
      ans += (tmp->cnt - 1) * tmp->cnt /2; // nP2
    }
  }
  printf("%ld\n", ans);
}
//  [javascript]
"use strict";
var input = require("fs").readFileSync("/dev/stdin", "utf8");
var cin = input.split(/ |\n/),
    cid = 0;

// number一個取得
// eslint-disable-next-line no-unused-vars
const next = () => +cin[cid++];

// 文字列一個取得
// eslint-disable-next-line no-unused-vars
const nextstr = () => cin[cid++];

// BigInteger一個取得
// eslint-disable-next-line no-unused-vars
const nextbig = () => BigInt(cin[cid++]);

// 長さnの配列として取得。aは文字列フラグ
// eslint-disable-next-line no-unused-vars
const nexts = (n, a) =>
    a ? cin.slice(cid, (cid += n)) : cin.slice(cid, (cid += n)).map((a) => +a);

// w個ずつを組にして長さhの配列。aは文字列フラグ。
// eslint-disable-next-line no-unused-vars
const 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;
};
// 多次元配列。v,a1,a2,a3 なら、3次元。[[値vで長さa3の配列]をa2個並べた配列]をa1個並べた配列。
// eslint-disable-next-line no-unused-vars
const xArray = (...args) => {
    var a = args,
        l = a.length,
        r = "Array(a[" + --l + "]).fill().map(x=>{return " + a[0] + ";})";
    while (--l) r = "Array(a[" + l + "]).fill().map(x=>" + r + ")";
    return eval(r);
};

console.log(main().toString());

function main() {
    let n = next();
    let a = nexts(n);

    let sum = xArray(0, n + 1);
    let map = new Map();
    map.set(0, 1);
    for (let i = 0; i < n; i++) {
        let t = sum[i] + a[i];
        sum[i + 1] = t;
        map.set(t, 1 + (map.has(t) ? map.get(t) : 0));
    }
    //console.log(map);
    let keys = map.keys();
    let ans = 0;
    for (let key of keys) {
        let v = map.get(key);
        ans += (v * (v - 1)) / 2;
    }
    return ans;
}
//  [javascript]
var GET=(function(){function f(s){return new g(s);}function g(s){this._s=s.trim().split("\n");this._y=0;}g.prototype.a=function(f){var s=this._s, y=this._y, r;if(typeof s[y]==="string")s[y]=s[y].split(" ").reverse();r=s[y].pop();if(!s[y].length)this._y++;return f?r:+r;};g.prototype.l=function(f){var s=this._s[this._y++].split(" ");return f?s:s.map(a=>+a);};g.prototype.m=function(n,f){var r=this._s.slice(this._y,this._y+=n).map(a=>a.split(" "));return f?r:r.map(a=>a.map(a=>+a));};g.prototype.r=function(n,f){var r=this._s.slice(this._y,this._y+=n);return f?r:r.map(a=>+a);};return f;})();
var o=GET(require("fs").readFileSync("/dev/stdin","utf8"));

console.log(main());
function main(){
  var n = o.a();
  var a = o.l();
  var b = new Map();
  b.set(0,1);
  var ans = 0;
  var t = 0;
  for(var i = 0; i < n; i++){
    t += a[i];
    if(b.get(t))b.set(t,b.get(t)+1); else b.set(t,1);
  }
  b.forEach(i=>ans += i * (i-1) / 2);
  return ans;
}
//  [javascript]
module.exports=function(e){var r={};function t(n){if(r[n])return r[n].exports;var o=r[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,t),o.l=!0,o.exports}return t.m=e,t.c=r,t.d=function(e,r,n){t.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:n})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,r){if(1&r&&(e=t(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(t.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var o in e)t.d(n,o,function(r){return e[r]}.bind(null,o));return n},t.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(r,"a",r),r},t.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},t.p="",t(t.s=0)}([function(e,r,t){t(1)(t(2).readFileSync("/dev/stdin","UTF-8").split("\n"))},function(e,r){e.exports=function(e){for(var r=Number(e[0]),t=e[1].split(" ").map(function(e){return Number(e)}),n=new Array(r+1).fill(0),o=1;o<r+1;o++)n[o]=n[o-1]+t[o-1];n.sort(function(e,r){return e-r});for(var u=0,i=1,f=0;f<r+1;f++)f==r||n[f]!=n[f+1]?(i>=2&&(u+=i*(i-1)/2),i=1):i++;console.log(u)}},function(e,r){e.exports=require("fs")}]);
//  [javascript]
function Main(input) {
	input = input.split("\n");
	var n = input[1].split(" ").map(Number);
	var arr = [];
  	var m = [100000000000001]
	for(var i=0;i<n.length;i++){
		m[i+1] = m[i]+n[i];
	}
	for(i=0;i<m.length;i++){
		if(arr[m[i]]){
			arr[m[i]]++;
		}else{
			arr[m[i]] = 1;
		}
	}
	var sum = 0;
 /* console.log(arr)
  console.log(m)*/
	Object.keys(arr).forEach(function(key){
		sum += arr[key]*(arr[key]-1)/2;
	});
	console.log(sum)
}Main(require("fs").readFileSync("/dev/stdin", "utf8").trim());
//  [javascript]
var input = require("fs").readFileSync("/dev/stdin", "utf8").trim().split("\n");
var obj = {
  "list" : input,
  "index" : 0,
  "max" : input.length,
  "next" : function(){
    if(!this.hasNext()){throw "NoSuchElementException:次に要素は無いよ";}
    var returnObj = this.list[this.index];
    this.index++;
    return returnObj;
  },
  "hasNext" : function(){return (this.index < this.max);}
}
Main();
function next(){return obj.next();}
function hasNext(){return obj.hasNext();}
function myout(t){console.log(t);}//standard output
function myerr(t){console.error(t);}//standard error
//[no]要素の扱い。数値型
//不明値、異常時:引数そのまま返す　1:数値へ変換
//2:半角SPで分割 4:半角SPで分割し、数値配列へ
//6:1文字で分割  7:1文字で分割し、数値配列へ
//8:半角SPで結合 9:改行で結合 0:文字なしで結合
function myconv(i,no){try{switch(no){case 1:return parseInt(i);case 2:return i.split(" ");case 4:return i.split(" ").map((a)=>Number(a));case 6:return i.split("");case 7:return i.split("").map((a)=>Number(a));case 8:return i.join(" ");case 9:return i.join("\n");case 0:return i.join("");default:return i;}}catch(e){return i;}}
function Main(){
  var N = myconv(next(),1);
  var list = myconv(next(),4);
  var s = new Array(N + 1);
  s[0] = 0;
  var set = {"0" : 0};
  var output = 0;
  for(var i = 0; i < N; i++){
    s[i + 1] = s[i] + list[i];
    if(set[s[i + 1]] == null){
       set[s[i + 1]] = 0;
    }else{
       set[s[i + 1]]++;
      output += set[s[i + 1]];
    }
  }
  
  myout(output);
}
//  [javascript]
var input = require("fs").readFileSync("/dev/stdin", "utf8");

var lines=input.split("\n");
var n=lines[0]|0;
var a=lines[1].split(" ");
var map=Object.create(null);
map[0]=0;
var sum=0;
var res=0;
for(var i=0;i<n;++i){
    sum+=a[i]|0;
    if(sum in map){
        res+=++map[sum];
    }else{
        map[sum]=0;
    }
}
console.log(res);
//  [go]
package main

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

func main() {
	scanInit()

	n := nextInt()
	a := make([]int, n)
	ru := make([]int, n+1)
	m := map[int]int{}

	ru[0] = 0
	m[0]++
	for i := 0; i < n; i++ {
		a[i] = nextInt()
		ru[i+1] = a[i] + ru[i]
		m[ru[i+1]]++
	}
	cnt := 0
	for _, v := range m {
		cnt += (v * (v - 1)) / 2
	}

	fmt.Println(cnt)

}

// ---- readfunc
var sc = bufio.NewScanner(os.Stdin)

func scanInit() {
	const cap = 200 * 1024 // default=64*1024
	var buf = make([]byte, cap)
	sc.Buffer(buf, cap)
	sc.Split(bufio.ScanWords)
	return
}
func nextInt() int {
	sc.Scan()
	i, _ := strconv.Atoi(sc.Text())
	return i
}
func nextStr() string {
	sc.Scan()
	return sc.Text()
}
//  [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 nextInt2() (int, int) {
	return nextInt(), nextInt()
}

func nextInt3() (int, int, int) {
	return nextInt(), nextInt(), nextInt()
}

func nextInt4() (int, int, int, int) {
	return nextInt(), nextInt(), nextInt(), nextInt()
}

func nextInts(n int) []int {
	slice := make([]int, n)
	for i := 0; i < n; i++ {
		slice[i] = nextInt()
	}
	return slice
}

func nextFloat64() float64 {
	f, _ := strconv.ParseFloat(next(), 64)
	return f
}

func nextFloat64s(n int) []float64 {
	slice := make([]float64, n)
	for i := 0; i < n; i++ {
		slice[i] = nextFloat64()
	}
	return slice
}

func putf(format string, a ...interface{}) {
	fmt.Fprintf(wt, format, a...)
}

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

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

	n := nextInt()
	a := nextInts(n)

	s := make([]int, n+1)
	for i := 1; i <= n; i++ {
		s[i] = s[i-1] + a[i-1]
	}

	mp := map[int]int{}
	ans := 0
	for i := range s {
		ans += mp[s[i]]
		mp[s[i]]++
	}

	puts(ans)
}
//  [go]
package main

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

var sc = bufio.NewScanner(os.Stdin)

func ri() int {
	sc.Scan()
	b := sc.Bytes()
	if b[0] == 45 {
		return -b2i(b[1:])
	} else {
		return b2i(b)
	}
}

func b2i(a []byte) (n int) {
	for _, v := range a {
		n = n*10 + int(v-48)
	}
	return
}

func main() {
	sc.Split(bufio.ScanWords)
	n := ri()

	cs := make([]int, n+1)
	cs[0] = 0
	sum := 0
	for i := 1; i < len(cs); i++ {
		sum += ri()
		cs[i] = sum
	}

	occurs := make(map[int]int)
	for _, v := range cs {
		occurs[v]++
	}

	ans := 0
	for _, v := range occurs {
		if v >= 2 {
			ans += v * (v - 1) / 2
		}
	}
	fmt.Println(ans)
}
//  [go]
package main

import "fmt"

func main() {
	var n int
	fmt.Scan(&n)

	aSum := make([]int, n+1)
	for i := 0; i < n; i++ {
		var a int
		fmt.Scan(&a)

		aSum[i+1] = a + aSum[i]
	}
	store := make(map[int]int, n+1)

	cnt := 0
	for i := 0; i < n+1; i++ {
		cnt+= store[aSum[i]]
		store[aSum[i]]++

	}
	fmt.Println(cnt)

}
//  [go]
package main

import (
	"fmt"
)

func main() {
	var n int
	fmt.Scan(&n)

	s := 0
	m := map[int]int{}
	m[0]++
	for i := 0; i < n; i++ {
		var a int
		fmt.Scan(&a)
		s += a
		m[s]++
	}

	ans := 0
	for _, i := range m {
		ans += combi(i, 2)
	}

	fmt.Println(ans)
}

func combi(n, r int) int {
	c := 1
	for i := 1; i <= r; i++ {
		c = c * (n - i + 1) / i
	}
	return c
}
//  [go]
package main

import "fmt"

const debug = true

func main() {
	var N int
	fmt.Scan(&N)
	nums := scanNums(N)
	var sumsFromZero []int

	var sumsMax int
	sameNums := map[int]int{}

	sumsFromZero = append(sumsFromZero, nums[0])
	sameNums[nums[0]]++
	sameNums[0]++
	for i := 1; i < N; i++ {
		k := sumsFromZero[i-1] + nums[i]
		sumsFromZero = append(sumsFromZero, k)
		if sumsMax < sumsFromZero[i] {
			sumsMax = sumsFromZero[i]
		}
		sameNums[k]++
	}

	sumsFromZero = append([]int{0}, sumsFromZero...)

	sum := 0
	for _, v := range sameNums {
		sum += combination(v, 2)
	}

	fmt.Println(sum)
}

func combination(n, r int) (cmb int) {
	a := 1
	b := 1
	for i := 0; i < r; i++ {
		a *= n - i
		b *= r - i
	}
	return (a / b)
}

func scanNums(length int) (nums []int) {
	var num int
	for i := 0; i < length; i++ {
		fmt.Scan(&num)
		nums = append(nums, num)
	}
	return
}
//  [ruby]
def conv(a,b)
  if b > a/2
    b = a - b
  end
  ans = 1
  div = 1
  b.times do |i|
    ans *= a - i
    div *= (i+1)
  end
  ans / div
end

n = gets.to_i
a = gets.chomp.split(" ").map(&:to_i)
hash = Hash.new(0)
sum = 0
n.times do |i|
  sum += a[i]
  hash[sum] += 1
end
cnt = hash[0] == 0 ? 0 : conv(hash[0]+1,2)
hash[0] = 0
hash.each_value do |x|
  if x >= 2
    cnt += conv(x,2)
  end
end
puts cnt
//  [ruby]
N,*as=$<.read.split.map(&:to_i)

ls = []
l = 0

h = Hash.new(0)
as.each do |a|
    l += a
    h[l] += 1
end

ret = h[0]
h.each do |k,v|
    ret += (v-1)*v / 2
end

puts ret
//  [ruby]
n=gets.to_i
a=gets.split.map(&:to_i)
b=[0]
a.each do |aa|
  b << b[-1]+aa
end
dd=nil
ans=0
c=0
b.sort.each do |d|
  if dd==d
    c+=1
  else
    ans+=c*(c-1)/2
    c=1
  end
  dd=d
end
ans+=c*(c-1)/2
puts ans
//  [ruby]
eval"N,*A="+`dd`.split*?,;p eval ([s=0]+A.map{|a|s+=a}).group_by{|n|n}.map{|k,v|[*1..v.size].combination(2).size}*?+
//  [ruby]
def nCr(n, r)
  [*1..n].combination(r).size
end

N = gets.to_i
A = gets.split.map &:to_i
cusum = [sum = 0] + A.map{|a|sum += a}
p cusum.group_by{|n|n}.map{|k, v|
  nCr(v.size, 2)
}.inject:+
//  [ruby]
"
長さNの整数列 a0,a1,…,aN−1a0,a1,…,aN−1 が与えられる。
この整数列の連続する区間であって、
その区間内の値の総和が0になるものが何個あるか答えよ。
"


def nC2(n)
  n*(n-1)/2
end

# 入力
N = gets.to_i
a = []
a = gets.split.map(&:to_i)

# aの累積和をsに入れる(sはaより1だけ長い)
sum = 0
s = []
s[0] = 0
N.times do |i|
  s[i+1] = s[i] + a[i] 
end

# a[i]からa[j]までの和(i<=j, i,j=0,,,N-1)はs[j+1]-s[i]で求まる
# s[j+1]-s[i] == 0となる組み合わせの数を求めればOK
ans = 0

#s内の出現回数を数えるためのハッシュ
count = {}

# 出現回数を数える
# sの各要素.to_sをキーとするハッシュの値を+1する
s.each do |t|
  if count[t.to_s].nil?
    count[t.to_s] = 1
  else
    count[t.to_s] = count[t.to_s] + 1
  end
end

#countの各要素についてnC2を計算し合計すると組み合わせが求まる
ans = count.map{ |key, val| nC2(val) }.inject(:+)
puts ans


# 下の方法だと2重ループでTLEなる
# N.times do |i|
#   i.upto(N-1) do |j|
#     if s[j+1] == s[i]
#       ans = ans + 1
#     end
#   end
# end
#puts ans
//  [rust]
use std::io::BufRead;

fn main() {
    let stdin = std::io::stdin();
    let n = stdin.lock().gets().parse::<usize>().unwrap();
    let a = stdin.lock().gets().split(' ').take(n)
        .map(|x| x.parse::<i64>().unwrap()).collect::<Vec<_>>();
    let mut acc = vec![0; n + 1];
    for i in 0..n {
        acc[i + 1] = acc[i] + a[i];
    }
    acc.sort();
    acc.push(std::i64::MAX);	// sentinel
    let mut prev = std::i64::MAX;
    let mut count = 0u64;
    let mut ans = 0;
    for x in acc {
        if x == prev {
            count += 1;
        } else {
            if count >= 2 {
                ans += count * (count - 1) / 2;
            }
            count = 1;
        }
        prev = x;
    }
    println!("{}", ans);
}

trait Gets { fn gets(&mut self) -> String; }
impl<T: std::io::BufRead> Gets for T {
    fn gets(&mut self) -> String { self.lines().next().unwrap().unwrap() } }
//  [rust]
use std::io::Read;

fn run() {
    let mut s = String::new();
    std::io::stdin().read_to_string(&mut s).unwrap();
    let mut it = s.trim().split_whitespace();
    let n: usize = it.next().unwrap().parse().unwrap();
    let mut map = std::collections::HashMap::<i64, u64>::with_capacity(n + 1);
    map.insert(0, 1);
    let mut ans = 0u64;
    let mut sum = 0;
    for s in it {
        let a: i64 = s.parse().unwrap();
        sum += a;
        let po = map.entry(sum).or_insert(0);
        ans += *po;
        *po += 1;
    }
    println!("{}", ans);
}

fn main() {
    run();
}
//  [rust]
#[allow(unused_imports)]
use std::cmp::{max, min, Ordering};
#[allow(unused_imports)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
#[allow(unused_imports)]
use std::io::{stdin, stdout, BufWriter, Read, StdoutLock, Write};
#[allow(unused_imports)]
use std::iter::FromIterator;
#[allow(unused_imports)]
use std::str::FromStr;

// zero-sum-ranges.rs --- Zero-Sum Ranges
// author: Seong Yong-ju <sei40kr@gmail.com>

#[allow(unused_macros)]
macro_rules! get {
    ($t:ty) => {
        {
            let mut line: String = String::new();
            stdin().read_line(&mut line).unwrap();
            line.trim().parse::<$t>().unwrap()
        }
    };
    ($($t:ty),*) => {
        {
            let mut line: String = String::new();
            stdin().read_line(&mut line).unwrap();
            let mut iter = line.split_whitespace();
            (
                $(iter.next().unwrap().parse::<$t>().unwrap(),)*
            )
        }
    };
    ($t:ty; $n:expr) => {
        (0..$n).map(|_|
                    get!($t)
        ).collect::<Vec<_>>()
    };
    ($($t:ty),*; $n:expr) => {
        (0..$n).map(|_|
                    get!($($t),*)
        ).collect::<Vec<_>>()
    };
    ($t:ty ;;) => {
        {
            let mut line: String = String::new();
            stdin().read_line(&mut line).unwrap();
            line.split_whitespace()
                .map(|t| t.parse::<$t>().unwrap())
                .collect::<Vec<_>>()
        }
    };
    ($t:ty ;; $n:expr) => {
        (0..$n).map(|_| get!($t ;;)).collect::<Vec<_>>()
    };
}

#[allow(unused_macros)]
macro_rules! debug {
    ($($a:expr),*) => {
        println!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);
    }
}

#[allow(dead_code)]
fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("Failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("Failed to parse token")
}

#[allow(dead_code)]
fn with_bufwriter<F: FnOnce(BufWriter<StdoutLock>) -> ()>(f: F) {
    let out = stdout();
    let writer = BufWriter::new(out.lock());
    f(writer);
}

fn main() {
    let n = get!(usize);
    let xs = (0..n).map(|_| read::<i32>()).collect::<Vec<_>>();

    let mut map = BTreeMap::<i64, u64>::new();
    map.insert(0, 1);
    let mut sum = 0i64;

    let ans = xs
        .iter()
        .map(|&x| {
            sum += x as i64;
            sum
        })
        .map(|s| {
            let v = map.get(&s).unwrap_or(&0) + 1;
            map.insert(s, v);

            if 1 < v {
                v - 1
            } else {
                0
            }
        })
        .fold(0, |ans, v| ans + v);

    with_bufwriter(|mut out| writeln!(out, "{}", ans).unwrap());
}
//  [rust]
use std::collections::BTreeMap;
use std::io::prelude::*;
use std::io::stdin;
use std::str::FromStr;

fn main() {
    let n: usize = read();
    let a: Vec<i64> = (0..n).map(|_| read()).collect();

    let mut map = BTreeMap::new();
    let mut sum = 0;
    map.insert(0, 1);

    for a_i in a {
        sum += a_i;
        *map.entry(sum).or_insert(0i64) += 1;
    }

    let ans: i64 = map.iter().map(|(_, v)| (v * (v - 1) / 2)).sum();

    println!("{}", ans);
}

#[allow(dead_code)]
fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let token: String = stdin
        .lock()
        .bytes()
        .map(|b| b.unwrap() as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().unwrap()
}
//  [swift]
let N = Int(readLine()!)!
let A = readLine()!.characters.split(" ").map{Int(String($0))!}
var S = [0]
for i in 0..<N {
  S += [S[i]+A[i]]
}
var s = [Int: Int]()
for i in S {
  s[i] = (s[i] ?? 0) + 1
}
print(s.values.reduce(0){$0+$1*($1-1)/2})
//  [typescript]
const input=require('fs').readFileSync('/dev/stdin','utf8').split(/[\s]/);let input_i=-1;const tn=():number=>{input_i++;return Number(input[input_i])};const tnn=(n:number):number[]=>{const a=[];for(let i=0;i<n;i++){a.push(tn())}return a};const ts=():string=>{input_i++;return String(input[input_i])};const tss=(n:number):string[]=>{const a=[];for(let i=0;i<n;i++){a.push(ts())}return a};const to=(...arg)=>{console.log(...arg)};const abs=(a)=>{return Math.abs(a)};const min=(...a)=>{return Math.min(...a)};const max=(...a)=>{return Math.max(...a)};const floor=(a)=>{return Math.floor(a)};const asc=(ar:number[])=>{const t=[...ar];return ar.sort((a,b)=>{return a-b})};const desc=(ar:number[])=>{const t=[...ar];return t.sort((a,b)=>{return b-a})};const sw=(a,arr:any[],op:'=='|'>='|'>'|'<='|'<'='==')=>{for(let i=0;i<arr.length-1;i+=2){if(eval(a+op+arr[i])){return arr[i+1]}}return arr[arr.length-1]};const near=(n:number,arr:number[]):number=>{let ne=arr[0],ni=0;for(let i=1;i<arr.length;i++){if(Math.abs(n-ne)>Math.abs(n-arr[i])){ne=arr[i];ni=i}}return ni};const deduplicate=(a:any[]):any[]=>{return Array.from(new Set(a))};const gcd=(x,y)=>{while(y){[x,y]=[y,x%y]}return x};
const main=()=>{
  let n=tn(),a=tnn(n),b=[0]
  for(let i=0;i<n;i++){
    b.push(a[i]+b[i])
  }
  b.sort()
  let s=b[0],c=1,ans=0
  for(let i=1;i<n+1;i++){
    if(s==b[i]){
      c++
    }else if(c>1){
      ans+=c*(c-1)/2
      c=1
    }
    s=b[i]
  }
  if(c>1){
    ans+=c*(c-1)/2
  }
  to(ans)
}
main()
//  [python]
from collections import deque

def solve():
    H,W = map(int,input().split())
    C = list(map(int,input().split()))
    D = list(map(int,input().split()))

    S = ["##" + input() + "##" for _ in range(H)]
    for i in range(2):
        S.insert(0,"#"*(W+4))
        S.append("#"*(W+4))

    INF = float("inf")
    cost = [[INF for _ in range(W+4)] for _ in range(H+4)]
    cost0 = deque()
    ans = -1

    cost0.append((C[0]+1, C[1]+1, 0))
    cost[C[0]+1][C[1]+1] = 0

    move = [(1,0), (0,1), (-1,0), (0,-1)]
    warp = [(i, j) for i in range(-2, 3) for j in range(-2, 3) if (i, j) not in [(0, 0)]+move]

    cost1 = deque()

    while cost0:
        h,w,c = cost0.popleft()
        cost1.append((h,w,c))

        for i, j in move:
            dh = h+i
            dw = w+j
            if S[dh][dw] == "." and c < cost[dh][dw]:
                cost[dh][dw] = c
                cost0.appendleft((dh, dw, cost[dh][dw]))
        
        if len(cost0) == 0:
            while cost1:
                h, w, c = cost1.popleft()
                for i, j in warp:
                    dh = h+i
                    dw = w+j
                    if S[dh][dw] == "." and c+1 < cost[dh][dw]:
                        cost[dh][dw] = c+1
                        cost0.append((dh,dw, cost[dh][dw]))
        
        if cost[D[0]+1][D[1]+1] != INF:
            ans = cost[D[0]+1][D[1]+1]

    print(ans)

if __name__ == "__main__":
    solve()
//  [python]
# -*- coding: utf-8 -*-
from collections import deque
#幅優先探索 BFS
H, W = [int(i) for i in input().split()]
ch, cw = [int(i)-1 for i in input().split()]
dh, dw = [int(i)-1 for i in input().split()]

S = [input() for i in range(H)]
cost = [[-1]*W for i in range(H)]

q = [[0,ch,cw]]
q = deque(q)

ans = -1
while(q):
    cnt, cx, cy = q.popleft()
    if cost[cx][cy]<0:
        cost[cx][cy]=cnt
        for dx in range(-2,3):
            for dy in range(-2,3):
                if 0<=cx+dx<H and 0<=cy+dy<W and S[cx+dx][cy+dy]=='.':
                    if cost[cx+dx][cy+dy]<0:
                        if [dx,dy] in [[1,0],[-1,0],[0,1],[0,-1]]:
                            q.appendleft([cnt,cx+dx,cy+dy])
                        else:
                            q.append([cnt+1,cx+dx,cy+dy])

print(cost[dh][dw])
//  [python]
import heapq
import sys


def input(): return sys.stdin.readline().rstrip()


H, W = map(int, input().split())
ch, cw = map(int, input().split())
dh, dw = map(int, input().split())
data = [[0]*W for i in range(H)]

for i in range(H):
    S = input()
    for j in range(W):
        if S[j] == ".":
            data[i][j] = 1
        else:
            data[i][j] = 0


def trans(h, w):
    return W*(h) + w


P = [(0, -1), (0, 1), (1, 0), (-1, 0)]
DXY = []
for i in range(0, 3):
    for j in range(-2, 3):
        if i==0 and j==0:
            pass
        else:
            DXY.append((i,j))
            
G = [[] for i in range(H*W)]
H_L = [i for i in range(H)]
W_L = [i for i in range(W)]
for i in H_L:
    for j in W_L:
        if data[i][j] == 1:
            for dx, dy in P:
                if 0 <= dx+i < H and 0 <= dy+j < W and data[dx+i][dy+j] == 1:
                        u, v = trans(i, j), trans(dx+i, dy+j)
                        G[u].append((v, 0))
                        G[v].append((u, 0))
            for dx, dy in DXY:
                if 0 <= dx+i < H and 0 <= dy+j < W and data[dx+i][dy+j] == 1:
                        u, v = trans(i, j), trans(dx+i, dy+j)
                        G[u].append((v, 1))
                        G[v].append((u, 1))


D = [10**6+100 for i in range(H*W)]
D[trans(ch-1, cw-1)] = 0
que = []
heapq.heapify(que)
heapq.heappush(que, (0, trans(ch-1, cw-1)))

while que:
    cost, v = heapq.heappop(que)
    if D[v] < cost:
        continue
    for node, cost in G[v]:
        if D[node] > D[v] + cost:
            D[node] = D[v] + cost
            heapq.heappush(que, (D[node], node))

ans = D[trans(dh-1, dw-1)]

if ans == 10**6+100:
    print(-1)
else:
    print(ans)
//  [c]
#include <stdio.h>

#define Q_LENGTH 200000

void show_maze(int S[][1000], int height, int width, FILE *fp) {
  int h, w;

  for(h = 0; h < height; h++) {
    for(w = 0; w < width; w++) {
      if(S[h][w] == 0) {
        fputc(' ', fp);
        fputc(' ', fp);
      }else
        fprintf(fp, "%2d", S[h][w]);
    }
    fputc('\n', fp);
  }
}

int main(void){
  typedef struct{
	int h;
	int w;
  } point;
  
  int height, width;
  point start;
  point goal;
  int S[1000][1000];
  point queue[Q_LENGTH];
  int qhead = 0, qtale = 0;
  int h, w;
  point current;
  int warp = 0;
 
  scanf("%d%d", &height, &width);
  scanf("%d%d", &start.h, &start.w);
  scanf("%d%d", &goal.h, &goal.w);
  start.h--;
  start.w--;
  goal.h--;
  goal.w--;
  getchar();
  for(h = 0; h < height; h++){
    for(w = 0; w < width; w++){
      S[h][w] = (getchar() == '#');
    }
    getchar();
  }
  
  queue[0] = start;
  qtale = 1;
  S[start.h][start.w] = 1;
  	
  while(qhead != qtale || current.h != goal.h || current.w != goal.w){
    point tmp[24] = {{0,1}, {1,0}, {0,-1}, {-1, 0}, {2, 2}, {2, 1}, {2, 0}, {2, -1}, {2, -2},{1, 2}, {1, 1}, {1, -1}, {1, -2}, {0, 2}, {0, -2}, {-1, 2}, {-1, 1}, {-1, -1}, {-1, -2}, {-2, 2}, {-2, 1}, {-2, 0}, {-2, -1}, {-2, -2}};
	int i = 0;
    current = queue[qhead];
	qhead = (qhead + 1) %Q_LENGTH;

	for(; i < 4; i++){
      point pt = {current.h + tmp[i].h, current.w + tmp[i].w};

      if(pt.h < 0 || pt.h >= height || pt.w < 0 || pt.w >= width)
        continue;

	  if((!S[pt.h][pt.w]) || S[pt.h][pt.w] > S[current.h][current.w]){
		S[pt.h][pt.w] = S[current.h][current.w];
		queue[qtale] = pt;
		qtale = (qtale + 1)%Q_LENGTH;
	  }
	}

	for(; i < 24; i++){
	  point pt = {current.h + tmp[i].h, current.w + tmp[i].w};
    
      if(pt.h < 0 || pt.h >= height || pt.w < 0 || pt.w >= width)
        continue;

	  if((!S[pt.h][pt.w]) || S[pt.h][pt.w] > S[current.h][current.w]+1){
		S[pt.h][pt.w] = S[current.h][current.w] + 1;
		queue[qtale] = pt;
		qtale = (qtale + 1)%Q_LENGTH;
	  }
	}
    if(qhead == qtale){
      if(S[goal.h][goal.w]) {
        break;
      } else {
        printf("-1\n");
        return 0;
      }
    }
  }

  printf("%d\n", S[goal.h][goal.w]-1);
  
  return 0;
}
//  [javascript]
const input = require("fs").readFileSync("/dev/stdin", "utf8")

;(input => {
    const lines = input.split('\n')
    const [H, W] = lines[0].split(' ').map(Number)
    const C = lines[1].split(' ').map(Number)
    const D = lines[2].split(' ').map(Number)

    const map = []
    for (let i = 0; i < H; i++) {
        map[i] = lines[i + 3].split('')
    }

    const wall = '#'

    const f = (h, w, score) => {
        let p = null
        if (map[h] && map[h][w]) {
            p = map[h][w]
        }
        if (p && p !== wall && dp[h][w] > score) {
            dp[h][w] = score
            return true
        } else {
            return false
        }
    }

    const dp = Array(H).fill().map(_ => Array(W).fill(Infinity))
    const stack = []
    let score = 0
    dp[C[0] - 1][C[1] - 1] = score
    let i = [C[0] - 1, C[1] - 1]
    stack.push(i)
do {
    let stamp = []
    while (i = stack.shift()) {
        stamp.push(i)
        score = dp[i[0]][i[1]]
        const walk = [
            [i[0] + 1, i[1]],
            [i[0] - 1, i[1]],
            [i[0], i[1] + 1],
            [i[0], i[1] - 1]
        ]
        let n =null
        while (n = walk.pop()) {
            if (f(n[0], n[1], score)) {
                stack.push([n[0], n[1]])
            }
        }
    }
    score++
    while (i = stamp.pop()) {
        const warp = [
            [i[0] + 2, i[1] + 2],
            [i[0] + 2, i[1] + 1],
            [i[0] + 2, i[1]],
            [i[0] + 2, i[1] - 1],
            [i[0] + 2, i[1] - 2],
            [i[0] + 1, i[1] + 2],
            [i[0] + 1, i[1] + 1],
            [i[0] + 1, i[1] - 1],
            [i[0] + 1, i[1] - 2],
            [i[0], i[1] + 2],
            [i[0], i[1] - 2],
            [i[0] - 1, i[1] + 2],
            [i[0] - 1, i[1] + 1],
            [i[0] - 1, i[1] - 1],
            [i[0] - 1, i[1] - 2],
            [i[0] - 2, i[1] + 2],
            [i[0] - 2, i[1] + 1],
            [i[0] - 2, i[1]],
            [i[0] - 2, i[1] - 1],
            [i[0] - 2, i[1] - 2]
        ]
        let n = null
        while (n = warp.pop()) {
            if (f(n[0], n[1], score)) {
                stack.push([n[0], n[1]])
            }
        }
    }
} while (stack.length)

    const ans = dp[D[0] - 1][D[1] - 1]
    console.log(ans === Infinity ? -1 : ans)

})(input)
//  [javascript]
function main(lines) {
  const [H, W] = na();
  const [Ch, Cw] = sa().map(v => v-1);
  const [Dh, Dw] = sa().map(v => v-1);
  const maze = getLines(H);
  
  let stack = [[Ch, Cw, 0]];
  let _stack = [];
  const done = Array(H).fill(0).map(_ => Array(W).fill(false));
  while (stack.length) {
    const [h, w, cost] = stack.pop();
    if (h == Dh && w == Dw) return cost;
    if (!done[h][w]) {
      done[h][w] = true;
      for (let _h = h-2; _h <= h+2; _h++) {
        if (!maze[_h]) continue;
        for (let _w = w-2; _w <= w+2; _w++) {
          if (maze[_h][_w] != '.' || done[_h][_w]) continue;
          if (Math.hypot(_h-h, _w-w) <= 1) {
            stack.push([_h, _w, cost]);
          } else {
            _stack.push([_h, _w, cost+1]);
          }
        }
      }
    }
    if (!stack.length) [stack, _stack] = [_stack, []];
  }
  return -1;
}



const lines = require("fs").readFileSync("/dev/stdin", "utf8").trim().split("\n");

let lineCount = 0;
const s = () => lines[lineCount++];
const n = () => Number(s());
const b = () => BigInt(s());
const sa = () => s().split(' ');
const na = () => sa().map(Number);
const ba = () => sa().map(BigInt);
const getLines = (n) => lines.slice(lineCount, lineCount += n);

const ans = main(lines);
console.log( ans );
//  [ruby]
require 'set'
h, w = gets.split.map(&:to_i)
ch, cw = gets.split.map(&:to_i)
ch += 1
cw += 1
dh, dw = gets.split.map(&:to_i)
dh += 1
dw += 1
s = Array.new(h+4)
h.times do |i|
  s[i+2] = ('##' + gets.chop + '##').chars
end
s[0] = ['#'] * (w+4)
s[1] = ['#'] * (w+4)
s[h+2] = ['#'] * (w+4)
s[h+3] = ['#'] * (w+4)

q = [[ch, cw]]
seek = [[ch, cw]]
current_cost = 0
checked = Array.new(h+4) { Array.new(w+4) }
checked[ch][cw] = true
loop do
  # 同コスト内のノード幅優先探索
  break if q.empty?
  until q.empty?
    nh, nw = q.shift

    if [nh, nw] == [dh, dw]
      puts current_cost
      exit 0
    end

    if s[nh-1][nw] == '.' && !checked[nh-1][nw]
      seek.push [nh-1, nw]
      checked[nh-1][nw] = true
      q.push [nh-1, nw]
    end
    if s[nh+1][nw] == '.' && !checked[nh+1][nw]
      seek.push [nh+1, nw]
      checked[nh+1][nw] = true
      q.push [nh+1, nw]
    end
    if s[nh][nw-1] == '.' && !checked[nh][nw-1]
      seek.push [nh, nw-1]
      checked[nh][nw-1] = true
      q.push [nh, nw-1]
    end
    if s[nh][nw+1] == '.' && !checked[nh][nw+1]
      seek.push [nh, nw+1]
      checked[nh][nw+1] = true
      q.push [nh, nw+1]
    end
  end
  tmp_seek = []

  # 次のコストのノードの発見とキューイング
  seek.each do |eh, ew|
    (eh-2..eh+2).each do |th|
      (ew-2..ew+2).each do |tw|
        next if s[th][tw] != '.' || checked[th][tw]

        if [th, tw] == [dh, dw]
          puts current_cost + 1
          exit 0
        end

        tmp_seek.push [th, tw]
        checked[th][tw] = true
        q.push [th, tw]
      end
    end
  end
  seek = tmp_seek
  current_cost += 1
end
puts -1
//  [ruby]
h, w = gets.split.map(&:to_i)
ch, cw = gets.split.map(&:to_i)
dh, dw = gets.split.map(&:to_i)

c = [?., ?#]
s = Array.new(h+3) {Array.new(w+3, c[1])}
h.times {|i| s[i+1][1,w+1] = gets.chars}

move = [[1,0], [-1,0], [0,1], [0,-1]]
warp = (-2..2).to_a.product((-2..2).to_a) - move - [[0,0]]

init = 1 << 20
d = Array.new(h+3) {Array.new(w+3, init)}
d[ch][cw] = 0
t = [[ch, cw]]

(0..).each do |k|
    break if t.empty? || d[dh][dw] < init
    u = []

    while (x,y = t.pop)
        move.each do |i,j|
            xx = x + i
            yy = y + j
            if s[xx][yy] == c[0] && d[xx][yy] > k
                d[xx][yy] = k
                t << [xx, yy]
            end
        end

        warp.each do |i,j|
            xx = x + i
            yy = y + j
            if s[xx][yy] == c[0] && d[xx][yy] > k + 1
                d[xx][yy] = k + 1
                u << [xx, yy]
            end
        end
    end

    t = u
end

p d[dh][dw] == init ? -1 : d[dh][dw]
//  [ruby]
h,w = gets.chomp.split(" ").map(&:to_i)
c = gets.chomp.split(" ").map(&:to_i)
d = gets.chomp.split(" ").map(&:to_i)
s = Array.new(h){Array.new}
h.times do |i|
  s[i] = gets.chomp.split("")
end
visited = Array.new(h){Array.new(w,-1)}
visited[c[0]-1][c[1]-1] = 0
queue = [c[0]-1,c[1]-1]
queue2 = []
cnt = 0
map1x = [-1,1,0,0]
map1y = [0,0,1,-1]
map2x = [-2,-2,-2,-2,-2,-1,-1,-1,-1,0,0,1,1,1,1,2,2,2,2,2,2]
map2y = [-2,-1,0,1,2,-2,-1,1,2,-2,2,-2,-1,1,2,-2,-1,0,1,2]
while !queue.empty? || !queue2.empty?
  while !queue.empty?
    a,b = queue[0],queue[1]
    queue.shift
    queue.shift
    queue2 << a
    queue2 << b
    4.times do |i|
      v0,v1 = a+map1x[i],b+map1y[i]
      if 0 <= v0 && v0 < h && 0 <= v1 && v1 < w
        if visited[v0][v1] == -1 && s[v0][v1] == "."
          visited[v0][v1] = cnt
          queue << v0
          queue << v1
        end
      end
    end
  end
  cnt += 1
  while !queue2.empty?
    a = queue2[0]
    b = queue2[1]
    queue2.shift
    queue2.shift
    20.times do |i|
      v0,v1 = a+map2x[i],b+map2y[i]
      if 0 <= v0 && v0 < h && 0 <= v1 && v1 < w
        if visited[v0][v1] == -1 && s[v0][v1] == "."
          visited[v0][v1] = cnt
          queue << v0
            queue << v1
        end
      end
    end
  end
end
puts visited[d[0]-1][d[1]-1]
//  [rust]
#![allow(non_snake_case)]
#![allow(unused_imports)]
#![allow(dead_code)]

use proconio::{input, fastout};
use proconio::marker::*;
use whiteread::parse_line;
use std::collections::*;
use num::*;
use num_traits::*;
use superslice::*;
use std::ops::*;

use itertools::Itertools;
use itertools_num::ItertoolsNum;

#[fastout]
fn solve() {
    const MOD: usize = 1_000_000_007;
    const INF: usize = std::usize::MAX;
    
    input!{
        h: usize, w: usize,
        sy: usize, sx: usize,
        gy: usize, gx: usize,
        graph: [Chars; h]
    }

    let mut dist = vec![vec![-1; w]; h];
    let directions = vec![(0, 1), (1, 0), (-1, 0), (0, -1)];
    let mut pq = BinaryHeap::new();
    pq.push((0, (sx-1, sy-1)));

    while let Some((dep, (x, y))) = pq.pop() {
        let dep = -dep;
        if dist[y][x] >= 0 { continue; }

        dist[y][x] = dep;

        for &(dx, dy) in directions.iter() {
            let (cx, cy) = (x as isize + dx, y as isize + dy);
            if cx < 0 || cy < 0 || cx >= w as isize || cy >= h as isize { continue; }

            let (cxu, cyu) = (cx as usize, cy as usize);
            if graph[cyu][cxu] == '#' { continue; }

            pq.push((-dep , (cxu, cyu)));
        }

        let left_bound = if x < 2 { 0 } else { x - 2 };
        let right_bound = if x + 3 >= w { w } else { x + 3 };
        let up_bound = if y < 2 { 0 } else { y - 2 };
        let down_bound = if y + 3 >= h { h } else { y + 3 };

        for wx in left_bound..right_bound {
            for wy in up_bound..down_bound {
                if graph[wy][wx] == '#' { continue; }
                pq.push((-(dep+1), (wx, wy)))
            }
        }
    }
    

    println!("{}", dist[gy-1][gx-1]);
}


fn main() {
    solve()
}

#[cfg(test)]
mod test {
    use super::solve;
}
//  [typescript]
import * as fs from 'fs';

const WALL = '#';
const ROAD = '.';

class Mazer {
  public warpRange = 2;
  public warpCount = 0;
  public expandableList: [number, number][] = [];
  constructor(public h: number, public w: number, public maze: (string | number)[][], public ch: number, public cw: number, public dh: number, public dw: number) {
    this.expandableList.push([ch, cw]);
  }

  solve(): number | null {
    while (this.expandableList.length > 0) {
      const expandableList = this.expandableList;
      this.expandableList = [];
      while (expandableList.length > 0) {
        const expandable = expandableList.pop();
        this.expand(expandable[0], expandable[1]);
        if (this.isSolved()) {
          const status = this.getMas(this.dh, this.dw);
          return status as number;
        }
      }
      this.warpCount++;

    }

    return null;
  }

  expand(i: number, j: number) {
    const openList: [number, number][] = [[i, j]];
    while (openList.length > 0) {
      const pos = openList.pop();
      if (!this.isRange(pos[0], pos[1])) {
        continue;
      }
      const masu = this.getMas(pos[0], pos[1]);
      if (masu !== ROAD) {
        continue;
      }
      this.setMas(pos[0], pos[1], this.warpCount);
      this.expandWarpable(pos[0], pos[1]);
      for (let [x, y] of [[1, 0], [0, 1], [-1, 0], [0, -1]]) {
        openList.push([x + pos[0], y + pos[1]]);
      }
    }
  }

  expandWarpable(i: number, j: number) {
    for (let x = -this.warpRange; x <= this.warpRange; x++) {
      for (let y = -this.warpRange; y <= this.warpRange; y++) {
        if (!this.isRange(i + x, j + y)) {
          continue;
        }
        const status = this.getMas(i + x, j + y);
        if (status === WALL) {
          continue;
        }
        if (status === ROAD || status > this.warpCount + 1) {
          // this.setMas(i + x, j + y, this.warpCount + 1);
          this.expandableList.push([i + x, j + y]);
        }
      }
    }
  }

  isSolved(): boolean {
    return this.getMas(this.dh, this.dw) !== ROAD;
  }

  isRange(i: number, j: number): boolean {
    return (1 <= i && i <= this.h && 1 <= j && j <= this.w);
  }

  getMas(i: number, j: number): string | number {
    if (!this.isRange(i, j)) {
      throw new Error('range error');
    }
    return this.maze[i - 1][j - 1];
  }

  setMas(i: number, j: number, status: string | number): void {
    if (!this.isRange(i, j)) {
      throw new Error('range error');
    }
    this.maze[i - 1][j - 1] = status;
  }
}


function main(input) {
  input = input.split("\n");
  const [h, w] = input[0].split(' ').map(i => parseInt(i));
  const [ch, cw] = input[1].split(' ').map(i => parseInt(i));
  const [dh, dw] = input[2].split(' ').map(i => parseInt(i));
  const maze: number[][] = [];
  for (let i = 0; i < h; i++) {
    maze.push(input[i + 3].split('').map(i => i));
  }
  const mazer = new Mazer(h, w, maze, ch, cw, dh, dw);
  const result = mazer.solve();
  console.log('%d', result !== null ? result : -1);
  return 0;
}

main(fs.readFileSync("/dev/stdin", "utf8"));
//  [python]
import numpy as np
i4 = np.int32

nin = np.fromstring(open(0).read(), i4, sep=' ')
N = nin[0]
ab = nin[1:].reshape(-1, 2).T
a = np.sort(ab[0])
b = np.sort(ab[1])
i = N // 2
if N % 2:
    print(b[i] - a[i] + 1)
else:
    nmin = a[i - 1] + a[i]
    nmax = b[i - 1] + b[i]
    print(nmax - nmin + 1)
//  [python]
#from collections import deque,defaultdict
from sys import stdin
input = stdin.readline
printn = lambda x: print(x,end='')
inn = lambda : int(input())
inl   = lambda: list(map(int, input().split()))
inm   = lambda:      map(int, input().split())
ins = lambda : input().strip()
DBG = True # and False
BIG = 10**18
R = 10**9 + 7

def ddprint(x):
  if DBG:
    print(x)

n = inn()
a = []
b = []
for i in range(n):
    aa,bb = inm()
    a.append(aa)
    b.append(bb)
a.sort()
b.sort()
if n%2==1:
    m = n//2
    print(b[m]-a[m]+1)
else:
    m = n//2 - 1
    print(b[m]+b[m+1]-a[m]-a[m+1]+1)
//  [python]
import sys

sys.setrecursionlimit(10 ** 7)
rl = sys.stdin.readline


def solve():
    N = int(rl())
    A, B = [0] * N, [0] * N
    for i in range(N):
        A[i], B[i] = map(int, rl().split())
    
    A.sort()
    B.sort()
    
    if N % 2 == 0:
        med_a = (A[N // 2 - 1] + A[N // 2]) / 2
        med_b = (B[N // 2 - 1] + B[N // 2]) / 2
        ans = int((med_b - med_a) // 0.5 + 1)
    else:
        med_a = A[N // 2]
        med_b = B[N // 2]
        ans = med_b - med_a + 1
    print(ans)


if __name__ == '__main__':
    solve()
//  [python]
n = int(input())
a = []
b = []
for i in range(n):
    x, y = map(int, input().split())
    a.append([x, y])
    b.append([y, x])
a = sorted(a)
b = sorted(b, reverse = True)

if n % 2 ==0:
    s = a[n//2 -1][0]
    e = b[n//2 -1][0]
    s2 = a[n//2][0]
    e2 = b[n//2][0]
    ans = e+ e2 -s-s2+1   
else:
    s = a[(n+1)//2 -1][0]
    e = b[(n+1)//2 -1][0]
    ans = e-s+1
print(ans)
//  [python]
import sys
from collections import defaultdict

sys.setrecursionlimit(10 ** 7)

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

N = int(readline())
AB = [list(map(int, readline().split())) for _ in range(N)]

LINE = defaultdict(lambda: [0, 0])
for a, b in AB:
    LINE[a][0] += 1
    LINE[b + 1][1] += 1

LINE = list(LINE.items())
LINE.sort()

ans = 0

small = 0
small_able = 0
prevx = -1


if N % 2 == 1:

    mn = 10 ** 10
    mx = 10 ** 10

    flg = False

    for x, p in LINE:
        small_able += p[0]
        small += p[1]

        if small < (N + 1) // 2 and ((N + 1) // 2) <= small_able:
            mn = min(x, mn)

        if (N + 1) // 2 <= small:
            mx = min(mx, x - 1)
            break


else:
    mn_0 = 10 ** 10
    mn_1 = 10 ** 10
    mx_0 = 10 ** 10
    mx_1 = 10 ** 10

    flg_0 = False
    flg_1 = False

    for x, p in LINE:
        small_able += p[0]
        small += p[1]

        if small < N // 2 and (N // 2) <= small_able:
            mn_0 = min(x, mn_0)

        if N // 2 <= small:
            mx_0 = min(mx_0, x - 1)

        if small < (N // 2) + 1 and (N // 2) + 1 <= small_able:
            mn_1 = min(x, mn_1)

        if (N // 2) + 1 <= small:
            mx_1 = min(mx_1, x - 1)
            break

    mn = mn_0 + mn_1
    mx = mx_0 + mx_1


print(mx - mn + 1)