local mma = math.max
local mfl, mce, mmi = math.floor, math.ceil, math.min
local MPM = {}
MPM.initialize = function(self, n, spos, tpos)
  self.n = n
  self.spos, self.tpos = spos, tpos
  -- edge_dst[src][i] := dst
  self.edge_dst = {}
  -- edge_cap[src][i] := capacity from src to edge_dst[src][i]
  self.edge_cap = {}
  -- edge_dst_invedge_idx[src][i] := "j" where edge_dst[dst][j] == src
  -- in this case, edge_dst_invedge_idx[dst][j] should be "i".
  self.edge_dst_invedge_idx = {}
  -- level[v] := length from spos. level[spos] := 1
  self.level = {}
  -- level_vertex_count[i] := count of vertexes that levels are i
  self.level_vertex_count = {}
  -- sub_graph_v[i] := list of vertexes that are contained in the sub-graph.
  self.sub_graph_v = {}
  -- sub_graph_size := the size of sub_graph_v.
  -- may not equal to #sub_graph_v (because not cleared).
  self.sub_graph_size = 0
  -- sub_graph_flag[v] := whether to contains the vertex v in the sub-graph or not
  self.sub_graph_flag = {}
  -- send[v] := sum of sendable amount from v to other vertexes in the sub-graph
  self.send = {}
  -- receive[v] := sum of receivable amount toward v from other vertexes in the sub-graph
  self.receive = {}
  -- sub_edge_idxes[src][i] := edge (from v) using in the sub-graph.
  -- for example, if sub_edge_idxes[src][i] is j,
  -- the edge from src to dst (= edge_dst[src][j]) contains in the sub-graph.
  self.sub_edge_idxes = {}
  -- sub_edge_cnt[src] := the size of sub_edge_idxes[src].
  -- may not equal to #sub_edge_idxes[src] (because not cleared).
  self.sub_edge_cnt = {}
  -- sub_invedge_idxes[dst] := edge (to dst) using in the sub-graph.
  -- for example, if sub_invedge_idxes[dst][i] is j,
  -- the src is edge_dst[dst][j], and the edge index (from src to dst) is k := edge_dst_invedge_idx[dst][j].
  -- so edge_dst[src][k] is the edge from src to dst using in the sub-graph.
  self.sub_invedge_idxes = {}
  -- sub_invedge_cnt[dst] := the size of sub_invedge_idxes[dst].
  -- may not equal to #sub_invedge_idxes[dst] (because not cleared).
  self.sub_invedge_cnt = {}
  -- flow_route[v] := [for "flowToT"] whether to contain in the route from weak_vertex to tpos.
  self.flow_route = {}
  -- actual_flow_amount[v] := [for "flowToT"] send amount from v
  self.actual_flow_amount = {}
  for i = 1, n do
    self.edge_dst[i] = {}
    self.edge_cap[i] = {}
    self.edge_dst_invedge_idx[i] = {}
    self.level[i] = 0
    self.level_vertex_count[i] = 0
    self.sub_graph_flag[i] = false
    self.send[i] = 0
    self.receive[i] = 0
    self.sub_edge_idxes[i] = {}
    self.sub_edge_cnt[i] = 0
    self.sub_invedge_idxes[i] = {}
    self.sub_invedge_cnt[i] = 0
    self.flow_route[i] = false
    self.actual_flow_amount[i] = 0
  end
end

MPM.addEdge = function(self, src, dst, cap, invcap)
  if not invcap then invcap = 0 end
  table.insert(self.edge_dst[src], dst)
  table.insert(self.edge_cap[src], cap)
  table.insert(self.edge_dst_invedge_idx[src], 1 + #self.edge_dst[dst])
  table.insert(self.edge_dst[dst], src)
  table.insert(self.edge_cap[dst], invcap)
  table.insert(self.edge_dst_invedge_idx[dst], #self.edge_dst[src])
end
MPM.makeSubGraph = function(self)
  local inf = self.n + 2
  local level, sub_graph_flag = self.level, self.sub_graph_flag
  local edge_dst, edge_cap = self.edge_dst, self.edge_cap
  local edge_dst_invedge_idx = self.edge_dst_invedge_idx
  local send, receive = self.send, self.receive
  local sub_graph_v = self.sub_graph_v
  local sub_edge_idxes, sub_edge_cnt = self.sub_edge_idxes, self.sub_edge_cnt
  local sub_invedge_idxes, sub_invedge_cnt = self.sub_invedge_idxes, self.sub_invedge_cnt
  local level_vertex_count = self.level_vertex_count
  for i = 1, self.n do
    level[i] = inf
    sub_graph_flag[i] = false
    send[i], receive[i] = 0, 0
    sub_edge_cnt[i] = 0
    sub_invedge_cnt[i] = 0
    level_vertex_count[i] = 0
  end
  -- BFS
  level[self.spos] = 1
  local taskcnt, done = 1, 0
  sub_graph_v[1] = self.spos
  local reached = false
  while done < taskcnt do
    done = done + 1
    local src = sub_graph_v[done]
    if src == self.tpos then reached = true break end
    for i = 1, #edge_dst[src] do
      local cap = edge_cap[src][i]
      if 0 < cap then
        local dst = edge_dst[src][i]
        if level[dst] == inf then
          level[dst] = level[src] + 1
          taskcnt = taskcnt + 1
          sub_graph_v[taskcnt] = dst
        elseif level[dst] == level[src] + 1 then
        end
      end
    end
  end
  if not reached then
    self.sub_graph_size = 0
    return false
  end
  -- restore route
  sub_graph_flag[self.tpos] = true
  local curlevel = level[self.tpos]
  while curlevel == level[sub_graph_v[taskcnt]] do
    taskcnt = taskcnt - 1
  end
  for isrc = taskcnt, 1, -1 do
    local src = sub_graph_v[isrc]
    for i = 1, #edge_dst[src] do
      local dst, cap = edge_dst[src][i], edge_cap[src][i]
      if 0 < cap and sub_graph_flag[dst]
      and level[dst] == level[src] + 1 then
        sub_graph_flag[src] = true
        local edgecnt = sub_edge_cnt[src] + 1
        sub_edge_cnt[src] = edgecnt
        sub_edge_idxes[src][edgecnt] = i
        sub_invedge_cnt[dst] = sub_invedge_cnt[dst] + 1
        sub_invedge_idxes[dst][sub_invedge_cnt[dst]] = edge_dst_invedge_idx[src][i]
        send[src] = send[src] + cap
        receive[dst] = receive[dst] + cap
      end
    end
    if not sub_graph_flag[src] then
      for i = 1, #edge_dst[src] do
        local dst = edge_dst[src][i]
        local cap = edge_cap[src][i]
        if 0 < cap and level[dst] == level[src] + 1 then
          send[src] = send[src] - cap
          receive[dst] = receive[dst] - cap
        end
      end
    end
  end
  -- remove unused vertex from "taskcnt" and set as sub_graph_size
  local nodecnt = 1
  for i = 1, taskcnt do
    local v = sub_graph_v[i]
    if sub_graph_flag[v] then
      sub_graph_v[nodecnt] = v
      local lv = level[v]
      level_vertex_count[lv] = level_vertex_count[lv] + 1
      nodecnt = nodecnt + 1
    end
  end
  if sub_graph_v[nodecnt - 1] == self.tpos then
    nodecnt = nodecnt - 1
  else
    sub_graph_v[nodecnt] = self.tpos
    local lv = level[self.tpos]
    level_vertex_count[lv] = level_vertex_count[lv] + 1
  end
  self.sub_graph_size = nodecnt
  return true
end

MPM.subGraphConnected = function(self)
  local max_level = self.level[self.tpos]
  local level_vertex_count = self.level_vertex_count
  for i = 1, max_level do
    if level_vertex_count[i] <= 0 then return false end
  end
  return true
end

MPM.findWeakVertex = function(self)
  local sub_graph_v = self.sub_graph_v
  local sub_graph_size = self.sub_graph_size
  local send, receive = self.send, self.receive
  local min_vertex = self.spos
  local min_potential = send[min_vertex]
  if receive[self.tpos] < min_potential then
    min_vertex = self.tpos
    min_potential = receive[min_vertex]
  end
  for i = 2, sub_graph_size - 1 do
    local v = sub_graph_v[i]
    local min_v = mmi(send[v], receive[v])
    if min_v < min_potential then
      min_potential, min_vertex = min_v, v
    end
  end
  return min_vertex, min_potential
end

MPM.flowToT = function(self, weak_vertex, potential)
  if weak_vertex == self.tpos then return end
  local sub_graph_flag = self.sub_graph_flag
  local edge_dst, edge_cap = self.edge_dst, self.edge_cap
  local edge_dst_invedge_idx = self.edge_dst_invedge_idx
  local sub_graph_v = self.sub_graph_v
  local sub_graph_size = self.sub_graph_size
  local sub_edge_cnt = self.sub_edge_cnt
  local sub_edge_idxes = self.sub_edge_idxes
  local send, receive = self.send, self.receive
  local level = self.level
  local flow_route = self.flow_route
  local actual_flow_amount = self.actual_flow_amount
  local tpos = self.tpos
  for i = 1, sub_graph_size do
    local v = sub_graph_v[i]
    flow_route[v] = false
    actual_flow_amount[v] = 0
  end
  flow_route[weak_vertex] = true
  actual_flow_amount[weak_vertex] = potential
  local weak_vertex_level = level[weak_vertex]
  local max_level = level[tpos]
  for iv = 1, sub_graph_size do
    local src = sub_graph_v[iv]
    local lv = level[src]
    if lv == max_level then break end
    local need_to_send = actual_flow_amount[src]
    if flow_route[src] and 0 < need_to_send then
      send[src] = send[src] - need_to_send
      local sub_edge_idxes_src = sub_edge_idxes[src]
      local dsts, caps, invidxes = edge_dst[src], edge_cap[src], edge_dst_invedge_idx[src]
      local used = 0
      -- use edge in descending order, to remove used edges quickly
      for j = sub_edge_cnt[src], 1, -1 do
        local edgeidx = sub_edge_idxes_src[j]
        local dst, cap = dsts[edgeidx], caps[edgeidx]
        local actual_flow = mmi(cap, need_to_send)
        receive[dst] = receive[dst] - actual_flow
        caps[edgeidx] = caps[edgeidx] - actual_flow
        need_to_send = need_to_send - actual_flow
        flow_route[dst] = true
        actual_flow_amount[dst] = actual_flow_amount[dst] + actual_flow
        local inv_edge_idx = invidxes[edgeidx]
        edge_cap[dst][inv_edge_idx] = edge_cap[dst][inv_edge_idx] + actual_flow
        if caps[edgeidx] == 0 then
          used = used + 1
        end
        if need_to_send == 0 then
          break
        end
      end
      sub_edge_cnt[src] = sub_edge_cnt[src] - used
    end
  end
end

MPM.flowFromS = function(self, weak_vertex, potential)
  if weak_vertex == self.spos then return end
  local sub_graph_flag = self.sub_graph_flag
  local edge_dst, edge_cap = self.edge_dst, self.edge_cap
  local edge_dst_invedge_idx = self.edge_dst_invedge_idx
  local sub_graph_v = self.sub_graph_v
  local sub_graph_size = self.sub_graph_size
  local sub_edge_cnt = self.sub_edge_cnt
  local sub_edge_idxes = self.sub_edge_idxes
  local sub_invedge_idxes = self.sub_invedge_idxes
  local sub_invedge_cnt = self.sub_invedge_cnt
  local send, receive = self.send, self.receive
  local level = self.level
  local flow_route = self.flow_route
  local actual_flow_amount = self.actual_flow_amount
  local spos = self.spos
  for i = 1, sub_graph_size do
    local v = sub_graph_v[i]
    flow_route[v] = false
    actual_flow_amount[v] = 0
  end
  flow_route[weak_vertex] = true
  actual_flow_amount[weak_vertex] = potential
  local weak_vertex_level = level[weak_vertex]
  local max_level = level[tpos]
  for iv = sub_graph_size, 1, -1 do
    local dst = sub_graph_v[iv]
    local lv = level[dst]
    if lv == 1 then break end
    local need_to_receive = actual_flow_amount[dst]
    if flow_route[dst] and 0 < need_to_receive then
      receive[dst] = receive[dst] - need_to_receive
      local sub_invedge_idxes_dst = sub_invedge_idxes[dst]
      local srcs = edge_dst[dst]
      local inv_invidxes = edge_dst_invedge_idx[dst]
      -- local dsts, caps, invidxes = edge_dst[src], edge_cap[src], edge_dst_invedge_idx[src]
      local used = 0
      -- use edge in descending order, to remove used edges quickly
      for j = sub_invedge_cnt[dst], 1, -1 do
        local invedgeidx = sub_invedge_idxes_dst[j]
        local src = srcs[invedgeidx]
        local edgeidx = inv_invidxes[invedgeidx]
        assert(edge_dst[src][edgeidx] == dst)
        local cap = edge_cap[src][edgeidx]
        local actual_flow = mmi(cap, need_to_receive)

        send[src] = send[src] - actual_flow
        edge_cap[src][edgeidx] = edge_cap[src][edgeidx] - actual_flow
        need_to_receive = need_to_receive - actual_flow
        flow_route[src] = true
        actual_flow_amount[src] = actual_flow_amount[src] + actual_flow
        edge_cap[dst][invedgeidx] = edge_cap[dst][invedgeidx] + actual_flow
        if edge_cap[src][edgeidx] == 0 then
          used = used + 1
        end
        if need_to_receive == 0 then
          break
        end
      end
      sub_invedge_cnt[dst] = sub_invedge_cnt[dst] - used
    end
  end
end

MPM.updateSubGraph = function(self)
  local sub_graph_v = self.sub_graph_v
  local sub_graph_size = self.sub_graph_size
  local sub_graph_flag = self.sub_graph_flag
  local send, receive = self.send, self.receive
  local spos, tpos = self.spos, self.tpos
  local level = self.level
  local level_vertex_count = self.level_vertex_count
  local sub_edge_idxes = self.sub_edge_idxes
  local sub_edge_cnt = self.sub_edge_cnt
  local edge_dst = self.edge_dst
  local sub_invedge_idxes = self.sub_invedge_idxes
  local sub_invedge_cnt = self.sub_invedge_cnt
  local nodecnt = 0
  for i = 1, sub_graph_size do
    local v = sub_graph_v[i]
    local valid = true
    if v ~= spos and receive[v] <= 0 then valid = false end
    if v ~= tpos and send[v] <= 0 then valid = false end
    if valid then
      local sub_invedge_idxes_v = sub_invedge_idxes[v]
      valid = false
      for j = 1, sub_invedge_cnt[v] do
        local ei = sub_invedge_idxes_v[j]
        local src = edge_dst[v][ei]
        if sub_graph_flag[src] then valid = true break end
      end
    end
    if valid then
      nodecnt = nodecnt + 1
      sub_graph_v[nodecnt] = v
    else
      sub_graph_flag[v] = false
      local lv = level[v]
      level_vertex_count[lv] = level_vertex_count[lv] - 1
    end
  end
  sub_graph_size = nodecnt
  for i = sub_graph_size, 1, -1 do
    local v = sub_graph_v[i]
    local valid = false
    local sub_edge_idxes_v = sub_edge_idxes[v]
    for j = 1, sub_edge_cnt[v] do
      local ei = sub_edge_idxes_v[j]
      local dst = edge_dst[v][ei]
      if sub_graph_flag[dst] then valid = true break end
    end
    if not valid then
      sub_graph_flag[v] = false
      local lv = level[v]
      level_vertex_count[lv] = level_vertex_count[lv] - 1
    end
  end
  nodecnt = 0
  for i = 1, sub_graph_size do
    local v = sub_graph_v[i]
    if sub_graph_v[v] then
      nodecnt = nodecnt + 1
      sub_graph_v[nodecnt] = v
    end
  end
  self.sub_graph_size = nodecnt
end

MPM.partialwork = function(self)
  local sum = 0
  while(self:subGraphConnected()) do
    local weak_vertex, potential = self:findWeakVertex()
    self:flowToT(weak_vertex, potential)
    self:flowFromS(weak_vertex, potential)
    self:updateSubGraph()
    sum = sum + potential
  end
  return sum
end

MPM.getMaxFlow = function(self)
  local ret = 0
  while(self:makeSubGraph()) do
    ret = ret + self:partialwork()
  end
  return ret
end

local AvlTree = {}
AvlTree.makenode = function(self, val, parent)
  local i = self.box[#self.box]
  if not i then i = #self.v + 1
  else table.remove(self.box)
  end
  self.v[i], self.p[i] = val, parent
  self.lc[i], self.rc[i], self.l[i], self.r[i] = 0, 0, 1, 1
  return i
end
AvlTree.create = function(self, lessthan, n)
  self.lessthan = lessthan
  self.root = 1
  self.box = {}
  for i = n + 1, 2, -1 do table.insert(self.box, i) end
  -- value, leftCount, rightCount, left, right, parent
  self.v, self.lc, self.rc, self.l, self.r, self.p = {}, {}, {}, {}, {}, {}
  for i = 1, n + 1 do
    self.v[i], self.p[i] = 0, 1
    self.lc[i], self.rc[i], self.l[i], self.r[i] = 0, 0, 1, 1
  end
end

AvlTree.recalc = function(self, i)
  local kl, kr = self.l[i], self.r[i]
  if 1 < kl then self.lc[i] = 1 + mma(self.lc[kl], self.rc[kl])
  else self.lc[i] = 0
  end
  if 1 < kr then self.rc[i] = 1 + mma(self.lc[kr], self.rc[kr])
  else self.rc[i] = 0
  end
end
AvlTree.recalcAll = function(self, i)
  while 1 < i do
    self:recalc(i)
    i = self.p[i]
  end
end

AvlTree.rotR = function(self, parent)
  local granp, child = self.p[parent], self.l[parent]
  self.r[child], self.l[parent] = parent, self.r[child]
  self.p[child], self.p[parent] = granp, child
  self.p[self.l[parent]] = parent
  if 1 < granp then
    if self.l[granp] == parent then
      self.l[granp] = child
    else
      self.r[granp] = child
    end
  else
    self.root = child
  end
end

AvlTree.rotL = function(self, parent)
  local granp, child = self.p[parent], self.r[parent]
  self.l[child], self.r[parent] = parent, self.l[child]
  self.p[child], self.p[parent] = granp, child
  self.p[self.r[parent]] = parent
  if 1 < granp then
    if self.r[granp] == parent then
      self.r[granp] = child
    else
      self.l[granp] = child
    end
  else
    self.root = child
  end
end

AvlTree.rotLR = function(self, lparent, rparent)
  local sp, sl, sr = self.p, self.l, self.r
  local granp, d = sp[rparent], sr[lparent]
  sp[lparent], sr[lparent] = d, sl[d]
  sp[rparent], sl[rparent] = d, sr[d]
  sp[sl[d]], sp[sr[d]] = lparent, rparent
  sp[d], sl[d], sr[d] = granp, lparent, rparent
  if 1 < granp then
    if sr[granp] == rparent then sr[granp] = d
    else sl[granp] = d
    end
  else self.root = d
  end
end

AvlTree.rotRL = function(self, rparent, lparent)
  local sp, sl, sr = self.p, self.l, self.r
  local granp, d = sp[lparent], sl[rparent]
  sp[rparent], sl[rparent] = d, sr[d]
  sp[lparent], sr[lparent] = d, sl[d]
  sp[sr[d]], sp[sl[d]] = rparent, lparent
  sp[d], sr[d], sl[d] = granp, rparent, lparent
  if 1 < granp then
    if sl[granp] == lparent then sl[granp] = d
    else sr[granp] = d
    end
  else self.root = d
  end
end

AvlTree.empty = function(self) return self.root <= 1 end

AvlTree.push = function(self, val)
  if self.root <= 1 then self.root = self:makenode(val, 1) return end
  local pos = self.root
  while true do
    if self.lessthan(val, self.v[pos]) then
      if 1 < self.l[pos] then
        pos = self.l[pos]
      else
        self.l[pos] = self:makenode(val, pos)
        pos = self.l[pos]
        break
      end
    else
      if 1 < self.r[pos] then
        pos = self.r[pos]
      else
        self.r[pos] = self:makenode(val, pos)
        pos = self.r[pos]
        break
      end
    end
  end
  while 1 < pos do
    local child, parent = pos, self.p[pos]
    if parent <= 1 then
      break
    end
    self:recalc(parent)
    local lcp_m_rcp = self.lc[parent] - self.rc[parent]
    if lcp_m_rcp % 2 ~= 0 then -- 1 or -1
      pos = parent
    elseif lcp_m_rcp == 2 then
      if self.lc[child] - 1 == self.rc[child] then
        self:rotR(parent)
        self:recalcAll(parent)
      else
        self:rotLR(child, parent)
        self:recalc(child)
        self:recalcAll(parent)
      end
      break
    elseif lcp_m_rcp == -2 then
      if self.rc[child] - 1 == self.lc[child] then
        self:rotL(parent)
        self:recalcAll(parent)
      else
        self:rotRL(child, parent)
        self:recalc(child)
        self:recalcAll(parent)
      end
      break
    else
      break
    end
  end
end

AvlTree.rmsub = function(self, node)
  while 1 < node do
    self:recalc(node)
    if self.lc[node] == self.rc[node] then
      node = self.p[node]
    elseif self.lc[node] + 1 == self.rc[node] then
      self:recalcAll(self.p[node])
      break
    else
      if self.lc[self.r[node]] == self.rc[self.r[node]] then
        self:rotL(node)
        self:recalcAll(node)
        break
      elseif self.lc[self.r[node]] + 1 == self.rc[self.r[node]] then
        local nr = self.r[node]
        self:rotL(node)
        self:recalc(node)
        node = nr
      else
        local nr = self.r[node]
        local nrl = self.l[nr]
        self:rotRL(nr, node)
        self:recalc(nr)
        self:recalc(node)
        node = nrl
      end
    end
  end
end

AvlTree.pop = function(self)
  local node = self.root
  while 1 < self.l[node] do
    node = self.l[node]
  end
  local v = self.v[node]
  local kp = self.p[node]
  self.p[self.r[node]] = kp
  if 1 < kp then
    self.l[kp] = self.r[node]
    self:rmsub(kp)
  else
    self.root = self.r[node]
  end
  table.insert(self.box, node)
  return v
end

AvlTree.new = function(lessthan, n)
  local obj = {}
  setmetatable(obj, {__index = AvlTree})
  obj:create(lessthan, n)
  return obj
end

local n, m = io.read("*n", "*n")
local ls, rs = {}, {}
local used = {}
local r_list = {}
local l_list = {}
for i = 1, m do
  r_list[i] = {}
  l_list[i] = {}
end
for i = 1, n do
  ls[i], rs[i] = io.read("*n", "*n")
  used[i] = false
  if rs[i] <= m then
    table.insert(r_list[rs[i]], i)
  end
  if 0 < ls[i] then
    table.insert(l_list[ls[i]], i)
  end
end
local function small_l_is_fast(a, b)
  return ls[a] < ls[b]
end
local avl1 = AvlTree.new(small_l_is_fast, 1)
local sit = 0
local chair_used = {}
for i = 1, m do
  for j = 1, #r_list[i] do
    avl1:push(r_list[i][j])
  end
  if not avl1:empty() then
    local top = avl1:pop()
    sit = sit + 1
    used[top] = i
    chair_used[i] = 1
  else
    chair_used[i] = false
  end
end
local rems = {}
for i = m, 1, -1 do
  for j = 1, #l_list[i] do
    local v = l_list[i][j]
    if not used[v] then
      table.insert(rems, v)
    end
  end
  if 0 < #rems and not chair_used[i] then
    used[rems[#rems]] = m + i
    sit = sit + 1
    chair_used[i] = 2
    table.remove(rems)
  end
end
-- print(n - sit)

local spos = n + m * 3 + 1
local tpos = spos + 1
MPM:initialize(tpos, spos, tpos)
for i = 1, n do
  local v = used[i]
  if v then
    if v <= m then
      if 0 < ls[i] then MPM:addEdge(i, n + m + ls[i], 1) end
      -- inv
      if rs[i] <= m then MPM:addEdge(n + rs[i], i, 1) end
    else
      if rs[i] <= m then MPM:addEdge(i, n + rs[i], 1) end
      -- inv
      if 0 < ls[i] then MPM:addEdge(n + m + ls[i], i, 1) end
    end
  else
    MPM:addEdge(spos, i, 1)
    if 0 < ls[i] then MPM:addEdge(i, n + m + ls[i], 1) end
    if rs[i] <= m then MPM:addEdge(i, n + rs[i], 1) end
  end
end
local inf = 1000000007
for i = 1, m - 1 do
  MPM:addEdge(n + i, n + i + 1, inf)
  MPM:addEdge(n + m + i + 1, n + m + i, inf)
end
for i = 1, m do
  local v = chair_used[i]
  if v == 1 then
    MPM:addEdge(n + m * 2 + i, n + i, 1)
    MPM:addEdge(n + m + i, n + m * 2 + i, 1)
  elseif v == 2 then
    MPM:addEdge(n + i, n + m * 2 + i, 1)
    MPM:addEdge(n + m * 2 + i, n + m + i, 1)
  else
    MPM:addEdge(n + i, n + m * 2 + i, 1)
    MPM:addEdge(n + m + i, n + m * 2 + i, 1)
    MPM:addEdge(n + m * 2 + i, tpos, 1)
  end
end
sit = sit + MPM:getMaxFlow()
print(n - sit)
